소스 검색

update:freertos升级至10.4.1(修改较多需长时间测试,自编译用户需注意:有问题及时反馈)

Dozingfiretruck 3 년 전
부모
커밋
4d4537d16f
100개의 변경된 파일10255개의 추가작업 그리고 5370개의 파일을 삭제
  1. 12 26
      app/port/luat_msgbus_air101.c
  2. 1 1
      include/app/wm_http_client.h
  3. 1 1
      include/app/wm_netif.h
  4. 3 3
      include/app/wm_netif2.1.3.h
  5. 3 1
      include/app/wm_wifi_oneshot.h
  6. 38 0
      include/driver/wm_adc.h
  7. 17 1
      include/driver/wm_efuse.h
  8. 0 2
      include/driver/wm_flash_map.h
  9. 1 1
      include/driver/wm_internal_flash.h
  10. 22 0
      include/driver/wm_irq.h
  11. 1 1
      include/driver/wm_sdio_host.h
  12. 70 1
      include/os/wm_osal.h
  13. 1 1
      include/platform/wm_mem.h
  14. 205 15
      include/wifi/wm_wifi.h
  15. 1 0
      include/wm_ram_config.h
  16. 2 4
      include/wm_type_def.h
  17. 778 40
      platform/common/mem/wm_mem.c
  18. 1 1
      platform/common/params/wm_param.c
  19. 3 3
      platform/common/utils/utils.c
  20. 7 2
      platform/drivers/adc/wm_adc.c
  21. 5 5
      platform/drivers/adc/wm_polyfit.c
  22. 0 1
      platform/drivers/cpu/wm_cpu.c
  23. 1 1
      platform/drivers/dma/wm_dma.c
  24. 198 91
      platform/drivers/efuse/wm_efuse.c
  25. 59 24
      platform/drivers/internalflash/wm_internal_fls.c
  26. 12 2
      platform/drivers/io/wm_io.c
  27. 0 2
      platform/drivers/lcd/wm_lcd.c
  28. 30 20
      platform/drivers/sdio_host/wm_sdio_host.c
  29. 117 3
      platform/drivers/touchsensor/wm_touchsensor.c
  30. 1 0
      platform/inc/tls_wireless.h
  31. 2 0
      platform/inc/utils.h
  32. 457 356
      src/app/bleapp/wm_ble_client_api_demo.c
  33. 12 3
      src/app/bleapp/wm_ble_client_api_demo.h
  34. 319 373
      src/app/bleapp/wm_ble_client_api_multi_conn_demo.c
  35. 8 0
      src/app/bleapp/wm_ble_client_api_multi_conn_demo.h
  36. 171 177
      src/app/bleapp/wm_ble_client_peer_manager.c
  37. 33 27
      src/app/bleapp/wm_ble_client_util.c
  38. 149 283
      src/app/bleapp/wm_ble_gap.c
  39. 17 9
      src/app/bleapp/wm_ble_gap.h
  40. 1417 0
      src/app/bleapp/wm_ble_mesh.c
  41. 31 0
      src/app/bleapp/wm_ble_mesh.h
  42. 113 0
      src/app/bleapp/wm_ble_mesh_gen_level_server.c
  43. 15 0
      src/app/bleapp/wm_ble_mesh_gen_level_server.h
  44. 220 0
      src/app/bleapp/wm_ble_mesh_gen_onoff_client.c
  45. 19 0
      src/app/bleapp/wm_ble_mesh_gen_onoff_client.h
  46. 127 0
      src/app/bleapp/wm_ble_mesh_gen_onoff_server.c
  47. 16 0
      src/app/bleapp/wm_ble_mesh_gen_onoff_server.h
  48. 134 0
      src/app/bleapp/wm_ble_mesh_health_server.c
  49. 15 0
      src/app/bleapp/wm_ble_mesh_health_server.h
  50. 107 0
      src/app/bleapp/wm_ble_mesh_light_model.c
  51. 29 0
      src/app/bleapp/wm_ble_mesh_light_model.h
  52. 252 0
      src/app/bleapp/wm_ble_mesh_node_demo.c
  53. 20 0
      src/app/bleapp/wm_ble_mesh_node_demo.h
  54. 297 0
      src/app/bleapp/wm_ble_mesh_vnd_model.c
  55. 24 0
      src/app/bleapp/wm_ble_mesh_vnd_model.h
  56. 562 238
      src/app/bleapp/wm_ble_server_api_demo.c
  57. 11 1
      src/app/bleapp/wm_ble_server_api_demo.h
  58. 266 330
      src/app/bleapp/wm_ble_server_wifi_app.c
  59. 6 0
      src/app/bleapp/wm_ble_server_wifi_app.h
  60. 160 97
      src/app/bleapp/wm_ble_server_wifi_prof.c
  61. 9 2
      src/app/bleapp/wm_ble_server_wifi_prof.h
  62. 447 136
      src/app/bleapp/wm_ble_uart_if.c
  63. 9 6
      src/app/bleapp/wm_ble_uart_if.h
  64. 237 189
      src/app/bleapp/wm_bt_app.c
  65. 29 0
      src/app/bleapp/wm_bt_app.h
  66. 130 156
      src/app/bleapp/wm_bt_util.c
  67. 22 11
      src/app/bleapp/wm_bt_util.h
  68. 17 17
      src/bt/blehost/ext/tinycrypt/include/tinycrypt/cmac_mode.h
  69. 1 1
      src/bt/blehost/ext/tinycrypt/include/tinycrypt/ctr_mode.h
  70. 22 22
      src/bt/blehost/ext/tinycrypt/include/tinycrypt/ctr_prng.h
  71. 83 83
      src/bt/blehost/ext/tinycrypt/include/tinycrypt/ecc.h
  72. 2 2
      src/bt/blehost/ext/tinycrypt/include/tinycrypt/ecc_dh.h
  73. 5 5
      src/bt/blehost/ext/tinycrypt/include/tinycrypt/ecc_dsa.h
  74. 6 6
      src/bt/blehost/ext/tinycrypt/include/tinycrypt/hmac.h
  75. 13 13
      src/bt/blehost/ext/tinycrypt/include/tinycrypt/hmac_prng.h
  76. 5 5
      src/bt/blehost/ext/tinycrypt/include/tinycrypt/sha256.h
  77. 1 1
      src/bt/blehost/ext/tinycrypt/include/tinycrypt/utils.h
  78. 99 86
      src/bt/blehost/ext/tinycrypt/src/aes_decrypt.c
  79. 128 111
      src/bt/blehost/ext/tinycrypt/src/aes_encrypt.c
  80. 17 16
      src/bt/blehost/ext/tinycrypt/src/bleutils.c
  81. 63 62
      src/bt/blehost/ext/tinycrypt/src/cbc_mode.c
  82. 195 199
      src/bt/blehost/ext/tinycrypt/src/ccm_mode.c
  83. 144 150
      src/bt/blehost/ext/tinycrypt/src/cmac_mode.c
  84. 42 41
      src/bt/blehost/ext/tinycrypt/src/ctr_mode.c
  85. 197 200
      src/bt/blehost/ext/tinycrypt/src/ctr_prng.c
  86. 652 668
      src/bt/blehost/ext/tinycrypt/src/ecc.c
  87. 110 122
      src/bt/blehost/ext/tinycrypt/src/ecc_dh.c
  88. 204 210
      src/bt/blehost/ext/tinycrypt/src/ecc_dsa.c
  89. 28 23
      src/bt/blehost/ext/tinycrypt/src/ecc_platform_specific.c
  90. 84 92
      src/bt/blehost/ext/tinycrypt/src/hmac.c
  91. 107 120
      src/bt/blehost/ext/tinycrypt/src/hmac_prng.c
  92. 159 140
      src/bt/blehost/ext/tinycrypt/src/sha256.c
  93. 34 33
      src/bt/blehost/nimble/host/include/host/ble_gap.h
  94. 2 2
      src/bt/blehost/nimble/host/include/host/ble_gatt.h
  95. 12 6
      src/bt/blehost/nimble/host/include/host/ble_hs.h
  96. 9 9
      src/bt/blehost/nimble/host/include/host/ble_hs_adv.h
  97. 1 1
      src/bt/blehost/nimble/host/include/host/ble_hs_stop.h
  98. 10 7
      src/bt/blehost/nimble/host/include/host/ble_store.h
  99. 206 199
      src/bt/blehost/nimble/host/mesh/include/mesh/access.h
  100. 115 71
      src/bt/blehost/nimble/host/mesh/include/mesh/cfg_cli.h

+ 12 - 26
app/port/luat_msgbus_air101.c

@@ -5,38 +5,24 @@
 #include "FreeRTOS.h"
 #include "rtosqueue.h"
 
-#define QUEUE_MAX_SIZE (1024)
+static QueueHandle_t xQueue = {0};
 
-static xQueueHandle queue = NULL;
-static u8 queue_buff[sizeof(rtos_msg_t) * QUEUE_MAX_SIZE];
-
-void luat_msgbus_init(void)
-{
-    if (queue == NULL)
-    {
-        queue = xQueueCreateExt(queue_buff, QUEUE_MAX_SIZE, sizeof(rtos_msg_t));
+void luat_msgbus_init(void) {
+    if (!xQueue) {
+        xQueue = xQueueCreate(256, sizeof(rtos_msg_t));
     }
 }
-uint32_t luat_msgbus_put(rtos_msg_t *msg, size_t timeout)
-{
-    if (queue == NULL)
-    {
+uint32_t luat_msgbus_put(rtos_msg_t* msg, size_t timeout) {
+    if (xQueue == NULL)
         return 1;
-    }
-    portBASE_TYPE pxHigherPriorityTaskWoken = pdFALSE;
-    xQueueSendFromISR(queue, msg, &pxHigherPriorityTaskWoken);
-    return 0;
+    return xQueueSendFromISR(xQueue, msg, NULL) == pdTRUE ? 0 : 1;
 }
-uint32_t luat_msgbus_get(rtos_msg_t *msg, size_t timeout)
-{
-    if (queue == NULL)
-    {
+uint32_t luat_msgbus_get(rtos_msg_t* msg, size_t timeout) {
+    if (xQueue == NULL)
         return 1;
-    }
-    xQueueReceive(queue, msg, timeout);
-    return 0;
+    return xQueueReceive(xQueue, msg, timeout) == pdTRUE ? 0 : 1;
 }
-uint32_t luat_msgbus_freesize(void)
-{
+uint32_t luat_msgbus_freesize(void) {
     return 1;
 }
+

+ 1 - 1
include/app/wm_http_client.h

@@ -182,7 +182,7 @@ typedef struct _HTTP_CLIENT
     UINT32        HTTPStatusCode;                 // HTTP Status code (200 OK)
     UINT32		    RequestBodyLengthSent;          // Total bytes sent (body only)
     UINT32		    ResponseBodyLengthReceived;     // Total bytes received (body only)
-    UINT32		    TotalResponseBodyLength;        // as extracted from the “content-length" header
+    UINT32		    TotalResponseBodyLength;        // as extracted from the �ontent-length" header
     UINT32        HttpState;
 } HTTP_CLIENT;
 

+ 1 - 1
include/app/wm_netif.h

@@ -10,6 +10,6 @@
 #ifndef WM_NETIF_H
 #define WM_NETIF_H
 #include "wm_config.h"
-#include "wm_netif2.0.3.h"
+#include "wm_netif2.1.3.h"
 #endif /* WM_NETIF_H */
 

+ 3 - 3
include/app/wm_netif2.0.3.h → include/app/wm_netif2.1.3.h

@@ -1,9 +1,9 @@
 /**
- * @file    wm_netif2.0.3.h
+ * @file    wm_netif2.1.3.h
  *
- * @brief   netif203 module
+ * @brief   netif213 module
  *
- * @author  dave
+ * @author  WinnerMicro
  *
  * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
  */

+ 3 - 1
include/app/wm_wifi_oneshot.h

@@ -37,6 +37,8 @@ extern int tls_filter_module_srcmac(u8 *mac);
 
 /** WinnerMicro ONSHOT */
 #define TLS_CONFIG_UDP_LSD_SPECIAL	 	(ONESHOT_ON&& TLS_CONFIG_UDP_ONE_SHOT)
+/** Delay start plcp receive*/
+#define TLS_CONFIG_ONESHOT_DELAY_SPECIAL ONESHOT_ON
 
 /** AP ONESHOT */
 #define TLS_CONFIG_AP_MODE_ONESHOT      (ONESHOT_ON && TLS_CONFIG_AP)
@@ -45,7 +47,7 @@ extern int tls_filter_module_srcmac(u8 *mac);
 
 
 /** AIRKISS ONESHOT */
-#define TLS_CONFIG_AIRKISS_MODE_ONESHOT (ONESHOT_OFF && TLS_CONFIG_UDP_ONE_SHOT)
+#define TLS_CONFIG_AIRKISS_MODE_ONESHOT (ONESHOT_ON && TLS_CONFIG_UDP_ONE_SHOT)
 #define AIRKISS_USE_SELF_WRITE                 1
 
 

+ 38 - 0
include/driver/wm_adc.h

@@ -294,6 +294,41 @@ u32 adc_get_interVolt(void);
  */
 int adc_temp(void);
 
+/**
+ * @brief          This function is used to calibrate adc single-end voltage. offset after FT or multipoint calibration.
+ *
+ * @param[in]      chan: adc calibration channel to be used, ADC channel 0,1,2,3
+ * @param[in]      refvoltage: calibration reference voltage to be used, unit:mV
+ *                             input range[100,2300)mV, suggest reference voltage[500,2000]mV
+ *
+ * @return         0: success, < 0: failure
+ *
+ * @note           After FT calibration or mulitpoint calibration, adc curve is y=ax+b,
+ *                 y is real voltage(unit:mV), x is adc sample data
+ *                 a and b is the coefficient. This fuction only used to revise b value.
+ */ 
+int adc_offset_calibration(int chan, int refvoltage);
+
+/**
+ * @brief          This function can used to calibrate adc coefficient if not calibrated,
+ *                 or adc offset after FT or multipoint calibration.
+ *
+ * @param[in]      chanused: bitmap, specified calibration channel,only bit0-3 can be used
+ * @param[in]      refvoltage[]: array, calibration reference voltage to be used, unit:mV
+ *                               refvoltage keep the same position with chan bitmap
+ *                               input range[100,2300)mV, suggest reference voltage[500,2000]mV
+ *
+ * @return         0: success, < 0: failure
+ *
+ * @note           1)Adc curve is y=ax+b,y is real voltage(unit:mV), x is adc sample data.
+ *                 After calibration, we can get a and b, or only update b.
+ *                 2) Only used single-end adc
+ *                 3) For example, use chan 0,1,3, and refvoltage 500,1000,2000, 
+ * 		             then chanused is 0xB, refvoltage[] value is  {500,1000,0, 2000};
+ */
+int adc_multipoint_calibration(int chanused, int refvoltage[]);
+
+
 /**
  * @}
  */
@@ -311,6 +346,9 @@ void signedToUnsignedData(int *adcValue);
 void tls_adc_buffer_bypass_set(u8 isset);
 void tls_adc_cmp_start(int Channel, int cmp_data, int cmp_pol);
 u32  adc_get_offset(void);
+void tls_adc_set_pga(int gain1, int gain2);
+int  cal_voltage(double vol);
+
 
 #endif
 

+ 17 - 1
include/driver/wm_efuse.h

@@ -25,6 +25,8 @@ enum {
 	CMD_RX_IQ_PHASE,
 	CMD_TX_GAIN,
 	CMD_TX_ADC_CAL,
+	CMD_FREQ_ERR,
+	CMD_RF_CAL_FLAG,
 	CMD_ALL,
 };
 
@@ -45,7 +47,9 @@ typedef struct FT_ADC_CAL_UNIT
 typedef struct FT_ADC_CAL
 {
 	unsigned int       valid_cnt;
-	FT_ADC_CAL_UINT_ST units[8];
+	FT_ADC_CAL_UINT_ST units[6];
+	float              a;
+	float              b;
 }FT_ADC_CAL_ST;
 
 typedef struct FT_TEMP_CAL
@@ -303,6 +307,18 @@ int tls_rf_cal_finish_op(u8 *calflag, u8 flag);
 */
 int tls_get_adc_cal_param(FT_ADC_CAL_ST *adc_cal);
 
+
+/**
+* @brief 	This function is used to set adc cal param
+*
+* @param[out]	adc_cal		adc cal param
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			get success
+* @retval		TLS_EFUSE_STATUS_EIO		get failed
+*/
+int tls_set_adc_cal_param(FT_ADC_CAL_ST *adc_cal);
+
+
 /**
  * @}
  */

+ 0 - 2
include/driver/wm_flash_map.h

@@ -20,11 +20,9 @@
 
 /**Run-time image header area*/
 #define CODE_RUN_START_ADDR                 (0x80D0000UL)
-// #define CODE_RUN_START_ADDR                 (0x8010000UL)
 
 /**Area can be used by User*/
 #define USER_ADDR_START						(0x81E0000UL)
-// #define USER_ADDR_START						(0x81C0000UL)
 
 
 /**System parameter defined in wm_internal_fls.c*/

+ 1 - 1
include/driver/wm_internal_flash.h

@@ -42,7 +42,7 @@ enum TYPE_FLASH_ID{
 	SPIFLASH_MID_XMC		= 0x20,
 	SPIFLASH_MID_XTX        = 0x0B,
 	SPIFLASH_MID_TSINGTENG    = 0xEB, /*UNIGROUP TSINGTENG*/	
-	SPIFLASH_MID_TSINGTENG_1MB    = 0xCD, /*UNIGROUP TSINGTENG*/
+	SPIFLASH_MID_TSINGTENG_1MB_4MB    = 0xCD, /*UNIGROUP TSINGTENG*/
 };
 
 typedef union {

+ 22 - 0
include/driver/wm_irq.h

@@ -104,6 +104,28 @@ void tls_irq_disable(u8 vec_no);
  */
 u8 tls_get_isr_count(void);
 
+/**
+ * @brief          This function is used to enter interrupt.
+ *
+ * @param[in]      None
+ *
+ * @return         0:success
+ *
+ * @note           None
+ */
+int csi_kernel_intrpt_enter(void);
+
+/**
+ * @brief          This function is used to exit from interrupt.
+ *
+ * @param[in]      None
+ *
+ * @return         0:success
+ *
+ * @note           None
+ */
+int csi_kernel_intrpt_exit(void);
+
 void tls_irq_priority(u8 vec_no, u32 prio);
 
 

+ 1 - 1
include/driver/wm_sdio_host.h

@@ -34,7 +34,7 @@ typedef struct
   long long CardCapacity;
   u32 CardBlockSize;
   u16 RCA;
-  u8 CardType;
+  u8 CSDVer;
 } SD_CardInfo_t;
 extern SD_CardInfo_t SDCardInfo;
 /**

+ 70 - 1
include/os/wm_osal.h

@@ -232,6 +232,12 @@ tls_os_status_t tls_os_task_del(u8 prio, void (*freefun)(void));
  */
 tls_os_status_t tls_os_task_del_by_task_handle(void *handle, void (*freefun)(void));
 
+tls_os_task_t tls_os_task_id();
+
+u8 tls_os_task_schedule_state();
+
+
+
 /**
  * @brief          This function creates a mutual exclusion semaphore
  *
@@ -413,6 +419,8 @@ tls_os_status_t tls_os_sem_delete(tls_os_sem_t *sem);
  */
  tls_os_status_t tls_os_sem_set(tls_os_sem_t *sem, u16 cnt);
 
+ u16 tls_os_sem_get_count(tls_os_sem_t *sem);
+
 
 /**
  * @brief          This function creates a message queue if free event cont
@@ -460,6 +468,42 @@ tls_os_status_t tls_os_sem_delete(tls_os_sem_t *sem);
         void *msg,
         u32 msg_size);
 
+        
+/**
+ * @brief          This function sends a message to a head of the queue
+ *
+ * @param[in]      *queue     pointer to the event control block
+                              associated with the desired queue
+ * @param[in]      *msg       pointer to the message to send.
+ * @param[in]      msg_size   message size
+ *
+ * @retval         0     success
+ * @retval         other failed
+ *
+ * @note           None
+ */
+ tls_os_status_t tls_os_queue_send_to_front(tls_os_queue_t *queue,
+        void *msg,
+        u32 msg_size);
+
+        
+/**
+ * @brief          This function sends a message to a tail of the queue
+ *
+ * @param[in]      *queue     pointer to the event control block
+                              associated with the desired queue
+ * @param[in]      *msg       pointer to the message to send.
+ * @param[in]      msg_size   message size
+ *
+ * @retval         0     success
+ * @retval         other failed
+ *
+ * @note           None
+ */
+ tls_os_status_t tls_os_queue_send_to_back(tls_os_queue_t *queue,
+        void *msg,
+        u32 msg_size);
+
 /**
  * @brief          This function is used to flush the contents of the message
                    queue.
@@ -497,6 +541,23 @@ tls_os_status_t tls_os_queue_flush(tls_os_queue_t *queue);
         u32 msg_size,
         u32 wait_time);
 
+ u8 tls_os_queue_is_empty(tls_os_queue_t *queue);
+
+/**
+ * @brief Return the number of free spaces available in a queue.  This is equal to the
+ * number of items that can be sent to the queue before the queue becomes full
+ * if no items are removed.
+ *
+ * @param *queue       pointer to the event control block associated
+ 								with the desired queue
+ * @return The number of spaces available in the queue.
+ * @note           None
+ */
+ u32 tls_os_queue_space_available(tls_os_queue_t *queue);
+ 
+ tls_os_status_t tls_os_queue_remove(tls_os_queue_t *queue, void* msg, u32 msg_size);
+
+
 /**
  * @brief          This function creates a message mailbox if free event
                    control blocks are available.
@@ -686,7 +747,7 @@ tls_os_status_t tls_os_queue_flush(tls_os_queue_t *queue);
  *
  * @note           None
  */
-tls_os_status_t tls_os_timer_delete(tls_os_timer_t *timer);
+ tls_os_status_t tls_os_timer_delete(tls_os_timer_t *timer);
 
 /**
  * @brief          This function is called to delay execution of the currently
@@ -707,6 +768,11 @@ tls_os_status_t tls_os_timer_delete(tls_os_timer_t *timer);
  */
  void tls_os_time_delay(u32 ticks);
 
+ u8 tls_os_timer_active(tls_os_timer_t *timer);
+
+ u32 tls_os_timer_expirytime(tls_os_timer_t *timer);
+
+
 
 /**
  * @brief          This function is used to display all the tasks' detail status.
@@ -719,6 +785,9 @@ tls_os_status_t tls_os_timer_delete(tls_os_timer_t *timer);
  */
 void tls_os_disp_task_stat_info(void);
 
+u8 tls_get_isr_count(void);
+
+
 /**
  * @}
  */

+ 1 - 1
include/platform/wm_mem.h

@@ -24,7 +24,7 @@
 //#define WM_MEM_DEBUG 1
 #if WM_MEM_DEBUG
 
-#include "list.h"
+#include "../list.h"
 
 #define  MEM_HEADER_PATTERN          0x76028412
 #define  MEM_TAILER_PATTERN          0x83395627

+ 205 - 15
include/wifi/wm_wifi.h

@@ -113,6 +113,28 @@ enum tls_wifi_auth_mode {
     WM_WIFI_AUTH_MODE_UNKNOWN           = 128
 };
 
+/** Wi-Fi encryption enum */
+enum tls_wifi_encrypt_mode {
+    WM_WIFI_ECN_MODE_OPEN          = 0, /**< encrypt mode : open */
+    WM_WIFI_ECN_MODE_WEP           = 1, /**< encrypt mode : wep*/
+    WM_WIFI_ECN_MODE_WPA_PSK       = 2, /**< encrypt mode : wpa psk*/
+    WM_WIFI_ECN_MODE_WPA2_PSK      = 3, /**< encrypt mode : wpa2 psk*/
+    WM_WIFI_ECN_MODE_WPA_WPA2_PSK  = 4, /**< encrypt mode : wpa and wpa2 psk*/
+    WM_WIFI_ECN_MODE_UNKNOWN        = 5, /**< encrypt mode : unknown*/
+};
+
+/** Wi-Fi group/pairwise cipher enumu*/
+enum tls_wifi_cipher_mode{
+	WM_WIFI_CIPHER_NONE = 0,
+	WM_WIFI_CIPHER_WEP40 = 1,
+	WM_WIFI_CIPHER_WEP104 = 2,
+	WM_WIFI_CIPHER_TKIP = 3,
+	WM_WIFI_CIPHER_CCMP = 4,
+	WM_WIFI_CIPHER_TKIP_AND_CCMP = 5,
+	WM_WIFI_CIPHER_AES_CMAC_128 = 6,
+};
+
+
 /** Wi-Fi states */
 enum tls_wifi_states {
 	WM_WIFI_DISCONNECTED,      /**< Disconnected state */
@@ -270,6 +292,29 @@ struct tls_scan_bss_t {
     struct tls_bss_info_t bss[1];    /**< list of bss found*/
 };
 
+/** format2 bss information */
+struct tls_bss_info_format2_t {
+    u8 ecn;            /**< encryption type, @ref enum tls_wifi_encrypt_mode */
+    u8 rssi;               /**< signal strength of AP, real rssi = (signed char)rssi */
+    u8 ssid[32];           /**< SSID of AP */
+    u8 ssid_len;           /**< SSID length */
+    u8 bssid[ETH_ALEN];    /**< MAC address of AP */
+	u8 channel;            /**< channel of AP */
+    s16 freq_offset;	   /**< reserved do not support*/
+    s16 freqcal_val;       /**< reserved do not support*/
+    s8 pairwise_cipher;    /**< pairwise cipher. @ref enum tls_wifi_cipher_mode */
+    s8 group_cipher;       /**< group cipher. @ref enum tls_wifi_cipher_mode */
+    u8 bgn;                /**< bgnmode, bit0:b mode, bit1:g mode, bit2:n mode */
+    bool wps_support;      /**< is support WPS function */
+};
+
+/** format2 scan result */
+struct tls_scan_bss_format2_t {
+    u32     count;                   /**< total count */
+    u32     length;                  /**< bss info total length */
+    struct tls_bss_info_format2_t bss[1];    /**< list of bss found*/
+};
+
 /** station information */
 struct tls_sta_info_t {
     u8  mac_addr[ETH_ALEN];    /**< MAC address of station */
@@ -299,7 +344,8 @@ struct tls_wifi_tx_rate_t {
 
 /** scan param */
 struct tls_wifi_scan_param_t{
-    u32 scan_times;        /**< Scan times, >=0, if zero, only 1 times */
+    u16 scan_type;
+    u16 scan_times;        /**< Scan times, >=0, if zero, only 1 times */
     u16 scan_chanlist;     /**< Scan channel list ,[0,3FFF],per bit is one channel,if zero or above 0x3FFF, scan all channel*/
     u16 scan_chinterval;   /**< Scan channel switch time,>=0, if zero, use default value, unit:ms */
 };
@@ -632,6 +678,24 @@ void tls_wifi_scan_result_cb_register(void (*callback)(void));
 int tls_wifi_get_scan_rslt(u8* buf, u32 buffer_size);
 
 
+/*************************************************************************** 
+* Function: 	 tls_wifi_get_scan_rslt_format2 
+*
+* Description:   get result of last scan for format2 result
+* 
+* Input: 	  buffer: address to store returned BSS info
+* 			  buffer_size: the length of the buffer
+* Output: 	  BSS info got by last scan
+* 
+* Return: 	 WM_SUCCESS: return ok;
+*			 WM_FAILED: failed to get result;
+* Note:		 user need to memalloc a buffer in advance. size for one item of scan result is @ref struct tls_bss_info_format2_t
+*			 the buffer size depends how many items user wants.
+* Date : 		 2022-6-07 
+****************************************************************************/ 
+int tls_wifi_get_scan_rslt_format2(u8* buf, u32 buffer_size);
+
+
 /**
  * @brief          This function is used to create soft ap
  *
@@ -1014,20 +1078,6 @@ int tls_wifi_send_mgmt(enum tls_wifi_mgmt_type type, struct tls_wifi_hdr_mac_t *
  */
 int tls_wifi_send_data(struct tls_wifi_hdr_mac_t *mac, u8 *data, u16 data_len, struct tls_wifi_tx_rate_t *tx);
 
-#if TLS_CONFIG_AP
-/**
- * @brief          This function is used to get authed sta list
- *
- * @param[out]     *sta_num    authed's station number
- * @param[out]     *buf        address to store returned station list info, tls_sta_info_t
- * @param[in]      buf_size    buffer size
- *
- * @return         None
- *
- * @note           None
- */
-void tls_wifi_get_authed_sta_info(u32 *sta_num, u8 *buf, u32 buf_size);
-#endif
 /**
  * @brief          This function is used to get current Wi-Fi State
  *
@@ -1114,6 +1164,43 @@ int tls_wifi_softap_set_sta_num(unsigned char ap_sta_num);
  */ 
 int tls_wifi_softap_del_station(unsigned char* hwaddr);
 
+/**
+ * @brief	   This function used to add sta to black list for softap
+ *
+ * @param[out]	   hwaddr: sta's mac address to forbid
+ *
+ * @return		   None
+ *
+ * @note		   None
+ */
+int tls_wifi_softap_add_blacksta(unsigned char *hwaddr);
+
+
+/**
+ * @brief	   This function used to accept sta joining softap that sta in balck list
+ *
+ * @param[out]	   hwaddr: mac address to delete from black list
+ *
+ * @return		   None
+ *
+ * @note		   None
+ */
+int tls_wifi_softap_del_blacksta(unsigned char *hwaddr);
+
+/**
+ * @brief	   This function used to get stations from blacklist
+ *
+ * @param[out]	   sta_num: station's number in blacklist
+ * @param[out]	   buf: store stations to get from blacklist
+ * @param[in]  	   buf_size: memory size to store stations in blacklist
+ *
+ * @return		   None
+ *
+ * @note		   None
+ */
+int tls_wifi_softap_get_blackinfo(u32 *sta_num, u8 *buf, u32 buf_size);
+
+
 /**
  * @brief          This function is used to set some information display in the process of wifi networking
  *
@@ -1147,6 +1234,109 @@ void tls_wifi_set_tempcomp_flag(int flag);
  */
 u8 tls_wifi_get_tempcomp_flag(void);
 
+/**
+ * @brief          This function is used to get temperature compensation flag
+ *
+ * @param[in]      fixrateindex: 11b:0-3, 11g:4-11, 11n-ht20:12-19, 11n-ht40:20-27
+ * @param[in]	      retrycnt: retry count, range[1,15]
+ *
+ * @return         None
+ *
+ * @note           When use this function, data to be transfered will use fix rate.
+ */
+void tls_wifi_set_fixed_rate(u32 fixrateindex, u32 retrycnt);
+
+
+/**
+ * @brief          This function is used to set listen_interval (dummy interface)
+ *
+ * @param[in]      listen_interval: >=1
+ *
+ * @return         None
+ *
+ * @note           this is dummy interface. this value can used only in sta mode.
+ */
+int tls_wifi_cfg_listen_interval(u16 listen_interval);
+
+/**
+ * @brief          This function is used to set connect timeout
+ *
+ * @param[in]      timeout: to connect ap's time, >=5s
+ *
+ * @return         None
+ *
+ * @note           valid only when scan AP failed.
+ */
+int tls_wifi_cfg_connect_timeout(u16 timeout);
+
+/**
+ * @brief          This function is used to configure scan mode
+ *
+ * @param[in]      mode:0-find max RSSI AP, 1-find AP and immediately stop scan to start join
+ *
+ * @return         None
+ *
+ * @note           only used in STA mode.
+ */
+int tls_wifi_cfg_connect_scan_mode(u32 mode);
+
+/**
+ * @brief          This function is used to set pci flag
+ *
+ * @param[in]      pci flag:0-can join any supported AP(open,wep,wpa,wpa2)
+ *                          1-only join AP(WPA/WPA2 that supported)
+ *
+ * @return         None
+ *
+ * @note           none.
+ */
+int tls_wifi_cfg_connect_pci(u32 pci_en);
+
+/**
+ * @brief          This function is used to set 11b's digital gain
+ *
+ * @param[in]      value:gain value, <0x40
+ *
+ * @return         0:if value is valid,-1:if value is invalid
+ *
+ * @note           none.
+ */
+int tls_wifi_set_11b_digital_gain(u8 value);
+
+/**
+ * @brief          This function is used to get 11b's gain value
+ *
+ * @param[in]      None
+ *
+ * @return         gain value
+ *
+ * @note           none.
+ */
+u8 tls_wifi_get_11b_digital_gain(void);
+
+/**
+ * @brief          This function is used to set 11n's digital gain
+ *
+ * @param[in]      value:gain value, <0x40
+ *
+ * @return         0:if value is valid,-1:if value is invalid
+ *
+ * @note           none.
+ */
+int tls_wifi_set_11n_digital_gain(u8 value);
+
+/**
+ * @brief          This function is used to get 11n's gain value
+ *
+ * @param[in]      None
+ *
+ * @return         gain value
+ *
+ * @note           none.
+ */
+u8 tls_wifi_get_11n_digital_gain(void);
+
+
 
 /**
  * @}

+ 1 - 0
include/wm_ram_config.h

@@ -39,6 +39,7 @@ enum SYS_REBOOT_REASON
 	REBOOT_REASON_EXCEPTION    = 2,   /*exception reset*/
 	REBOOT_REASON_WDG_TIMEOUT  = 3,   /*watchdog timeout*/
 	REBOOT_REASON_ACTIVE       = 4,   /*user active reset*/
+	REBOOT_REASON_SLEEP       	  ,   
 	REBOOT_REASON_MAX
 };
 

+ 2 - 4
include/wm_type_def.h

@@ -9,10 +9,8 @@
  */
 #ifndef __WM_TYPE_DEF_H__
 #define __WM_TYPE_DEF_H__
+#include <stdbool.h>
 
-#ifdef bool
-#undef bool
-#endif
 #ifdef u8
 #undef u8
 #endif
@@ -53,7 +51,7 @@ typedef unsigned char INT8U;
 #endif
 typedef signed char INT8S;
 
-typedef unsigned char        bool;
+//typedef unsigned char        bool;
 typedef unsigned char        u8;
 typedef signed char          s8;
 typedef unsigned short       u16;

+ 778 - 40
platform/common/mem/wm_mem.c

@@ -16,41 +16,498 @@
 #include "wm_mem.h"
 #include "list.h"
 #include <string.h>
-#include "FreeRTOS.h"
+
+extern u8 tls_get_isr_count(void);
+/**
+ * This variable is set if the memory mananger has been initialized.
+ * This is available only for debug version of the driver
+ */
+bool         memory_manager_initialized = false;
+/**
+ * This mutex is used to synchronize the list of allocated
+ * memory blocks. This is a debug version only feature
+ */
+tls_os_sem_t    *mem_sem;
+#if WM_MEM_DEBUG
+
+
+struct dl_list memory_used_list;
+struct dl_list memory_free_list;
+#define MEM_BLOCK_SIZE           800
+MEMORY_BLOCK mem_blocks[MEM_BLOCK_SIZE];
 
 
-#if configUSE_HEAP3
+u32 alloc_heap_mem_bytes = 0; 
+u32 alloc_heap_mem_blk_cnt = 0;
+u32 alloc_heap_mem_max_size = 0;
 
-void *pvPortMalloc( u32 xWantedSize );
-void vPortFree( void *pv );
-void *vPortRealloc(void *pv, u32 size);
-void *vPortCalloc(u32 length, u32 size);
+#define PRE_OVERSIZE        0
+#define OVERSIZE        0
 
-void * mem_alloc_debug(u32 size) {
-    return pvPortMalloc(size);
+/**
+ * This is a debug only function that performs memory management operations for us.
+ * Memory allocated using this function is tracked, flagged when leaked, and caught for
+ * overflows and underflows.
+ *
+ * \param size            The size in bytes of memory to
+ *        allocate
+ *
+ * \param file            The full path of file where this
+ *        function is invoked from
+ * \param line            The line number in the file where this
+ *        method was called from
+ * \return Pointer to the allocated memory or NULL in case of a failure
+ */
+void * mem_alloc_debug(u32 size, char* file, int line)
+{
+    void *buf = NULL;
+    u32 pad_len;
+    int i =  0;
+    u32  cpu_sr;
+    //
+    // If the memory manager has not been initialized, do so now
+    //
+    cpu_sr = tls_os_set_critical();
+    if (!memory_manager_initialized) {
+        tls_os_status_t os_status;
+        memory_manager_initialized = true;
+        //
+        // NOTE: If two thread allocate the very first allocation simultaneously
+        // it could cause double initialization of the memory manager. This is a
+        // highly unlikely scenario and will occur in debug versions only.
+        //
+        os_status = tls_os_sem_create(&mem_sem, 1);
+        if(os_status != TLS_OS_SUCCESS)
+            printf("mem_alloc_debug: tls_os_sem_create mem_sem error\r\n");
+        dl_list_init(&memory_used_list);
+        dl_list_init(&memory_free_list);
+        for(i = 0; i < MEM_BLOCK_SIZE; i++)
+        {
+            dl_list_add_tail(&memory_free_list, &mem_blocks[i].list);
+        }
+    }
+    tls_os_release_critical(cpu_sr);
+
+    tls_os_sem_acquire(mem_sem, 0);
+    cpu_sr = tls_os_set_critical();
+    //
+    // Allocate the required memory chunk plus header and trailer bytes
+    //
+    pad_len = sizeof(u32) - (size & 0x3);
+    buf = malloc(sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + size + pad_len + OVERSIZE + sizeof(MEMORY_PATTERN));
+
+    if (buf) {
+        //
+        // Memory allocation succeeded. Add information about the allocated
+        // block in the list that tracks all allocations.
+        //
+        PMEMORY_PATTERN  mem_ptn_hd;
+        PMEMORY_PATTERN  mem_ptn_tl;
+        PMEMORY_BLOCK  mem_blk_hd1;
+
+	 if(dl_list_empty(&memory_free_list))
+	 {
+	     printf("Memory blocks empty!\r\n");
+            free(buf);
+            tls_os_release_critical(cpu_sr);
+            tls_os_sem_release(mem_sem);
+		 tls_mem_alloc_info();
+            return NULL;
+	 }
+	 mem_blk_hd1 = dl_list_first(&memory_free_list, MEMORY_BLOCK, list);
+	 dl_list_del(&mem_blk_hd1->list);
+	 dl_list_add_tail(&memory_used_list, &mem_blk_hd1->list);
+        alloc_heap_mem_bytes += size+sizeof(MEMORY_PATTERN)+sizeof(MEMORY_PATTERN)+pad_len + PRE_OVERSIZE + OVERSIZE;
+        alloc_heap_mem_blk_cnt++;
+        if (alloc_heap_mem_bytes > alloc_heap_mem_max_size)
+        {
+            alloc_heap_mem_max_size = alloc_heap_mem_bytes;
+            //printf("alloc_heap_mem_max_size=%d\n", alloc_heap_mem_max_size);
+        }
+		
+        mem_blk_hd1->pad = pad_len;
+        mem_blk_hd1->file = file;
+        mem_blk_hd1->line = line;
+        mem_blk_hd1->length = size;
+        mem_blk_hd1->header_pattern = (u32)buf;
+		
+        // Fill in the memory header and trailer
+        mem_ptn_hd = (PMEMORY_PATTERN)buf;
+        mem_ptn_hd->pattern0= MEM_HEADER_PATTERN;
+        /*mem_ptn_hd->pattern1= MEM_HEADER_PATTERN;
+        mem_ptn_hd->pattern2= MEM_HEADER_PATTERN;
+        mem_ptn_hd->pattern3= MEM_HEADER_PATTERN;*/
+
+        mem_ptn_tl = (PMEMORY_PATTERN)(((u8 *)(buf))+size + sizeof(MEMORY_PATTERN)+pad_len + PRE_OVERSIZE + OVERSIZE);
+        mem_ptn_tl->pattern0= MEM_TAILER_PATTERN;
+        /*mem_ptn_tl->pattern1= MEM_TAILER_PATTERN;
+        mem_ptn_tl->pattern2= MEM_TAILER_PATTERN;
+        mem_ptn_tl->pattern3= MEM_TAILER_PATTERN;*/
+
+        // Jump ahead by memory header so pointer returned to caller points at the right place
+        buf = ((u8 *)buf) + sizeof (MEMORY_PATTERN) + PRE_OVERSIZE;
+
+#if 0
+
+        printf("==>Memory was allocated from %s at line %d with length %d\n",
+                  mem_blk_hd1->file,
+                  mem_blk_hd1->line,               
+                  mem_blk_hd1->length);
+        printf("==>mem alloc ptr = 0x%x\n", buf);
+
+#endif
+    }
+    else
+    {
+        printf("==>Memory was allocated from %s at line %d with length %d, allocated size %d, count %d\r\n",
+                   file,
+                   line,               
+                   size, alloc_heap_mem_bytes, alloc_heap_mem_blk_cnt);
+		tls_os_release_critical(cpu_sr);
+    tls_os_sem_release(mem_sem);
+	 tls_mem_alloc_info();
+	 return buf;
+    }
+    tls_os_release_critical(cpu_sr);
+    tls_os_sem_release(mem_sem);
+    return buf;
 }
-void mem_free_debug(void *p) {
-    vPortFree(p);
+
+void * mem_calloc_debug(u32 n, u32 size, char* file, int line)
+{
+    void *buf = NULL;
+    u32 pad_len;
+    int i =  0;
+    u32  cpu_sr;
+    //
+    // If the memory manager has not been initialized, do so now
+    //
+    cpu_sr = tls_os_set_critical();
+    if (!memory_manager_initialized) {
+        tls_os_status_t os_status;
+        memory_manager_initialized = true;
+        //
+        // NOTE: If two thread allocate the very first allocation simultaneously
+        // it could cause double initialization of the memory manager. This is a
+        // highly unlikely scenario and will occur in debug versions only.
+        //
+        os_status = tls_os_sem_create(&mem_sem, 1);
+        if(os_status != TLS_OS_SUCCESS)
+            printf("mem_alloc_debug: tls_os_sem_create mem_sem error\r\n");
+        dl_list_init(&memory_used_list);
+        dl_list_init(&memory_free_list);
+        for(i = 0; i < MEM_BLOCK_SIZE; i++)
+        {
+            dl_list_add_tail(&memory_free_list, &mem_blocks[i].list);
+        }
+    }
+    tls_os_release_critical(cpu_sr);
+
+    tls_os_sem_acquire(mem_sem, 0);
+    cpu_sr = tls_os_set_critical();
+    //
+    // Allocate the required memory chunk plus header and trailer bytes
+    //
+    pad_len = sizeof(u32) - ((n*size) & 0x3);
+    buf = malloc(sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + n*size + pad_len + OVERSIZE + sizeof(MEMORY_PATTERN));
+
+    if (buf) {
+        //
+        // Memory allocation succeeded. Add information about the allocated
+        // block in the list that tracks all allocations.
+        //
+        PMEMORY_PATTERN  mem_ptn_hd;
+        PMEMORY_PATTERN  mem_ptn_tl;
+        PMEMORY_BLOCK  mem_blk_hd1;
+
+	 if(dl_list_empty(&memory_free_list))
+	 {
+	     printf("Memory blocks empty!\r\n");
+            free(buf);
+            tls_os_release_critical(cpu_sr);
+            tls_os_sem_release(mem_sem);
+		 	tls_mem_alloc_info();
+            return NULL;
+	 }
+	 mem_blk_hd1 = dl_list_first(&memory_free_list, MEMORY_BLOCK, list);
+	 dl_list_del(&mem_blk_hd1->list);
+	 dl_list_add_tail(&memory_used_list, &mem_blk_hd1->list);
+        alloc_heap_mem_bytes += n*size+sizeof(MEMORY_PATTERN)+sizeof(MEMORY_PATTERN)+pad_len + PRE_OVERSIZE + OVERSIZE;
+        alloc_heap_mem_blk_cnt++;
+        if (alloc_heap_mem_bytes > alloc_heap_mem_max_size)
+        {
+            alloc_heap_mem_max_size = alloc_heap_mem_bytes;
+            //printf("alloc_heap_mem_max_size=%d\n", alloc_heap_mem_max_size);
+        }
+		
+        mem_blk_hd1->pad = pad_len;
+        mem_blk_hd1->file = file;
+        mem_blk_hd1->line = line;
+        mem_blk_hd1->length = n*size;
+        mem_blk_hd1->header_pattern = (u32)buf;
+		
+        // Fill in the memory header and trailer
+        mem_ptn_hd = (PMEMORY_PATTERN)buf;
+        mem_ptn_hd->pattern0= MEM_HEADER_PATTERN;
+        /*mem_ptn_hd->pattern1= MEM_HEADER_PATTERN;
+        mem_ptn_hd->pattern2= MEM_HEADER_PATTERN;
+        mem_ptn_hd->pattern3= MEM_HEADER_PATTERN;*/
+
+        mem_ptn_tl = (PMEMORY_PATTERN)(((u8 *)(buf))+n*size + sizeof(MEMORY_PATTERN)+pad_len + PRE_OVERSIZE + OVERSIZE);
+        mem_ptn_tl->pattern0= MEM_TAILER_PATTERN;
+        /*mem_ptn_tl->pattern1= MEM_TAILER_PATTERN;
+        mem_ptn_tl->pattern2= MEM_TAILER_PATTERN;
+        mem_ptn_tl->pattern3= MEM_TAILER_PATTERN;*/
+
+        // Jump ahead by memory header so pointer returned to caller points at the right place
+        buf = ((u8 *)buf) + sizeof (MEMORY_PATTERN) + PRE_OVERSIZE;
+
+#if 0
+
+        printf("==>Memory was allocated from %s at line %d with length %d\r\n",
+                  mem_blk_hd1->file,
+                  mem_blk_hd1->line,               
+                  mem_blk_hd1->length);
+        printf("==>mem alloc ptr = 0x%x\n", buf);
+
+#endif
+    }
+    else
+    {
+        printf("==>Memory was allocated from %s at line %d with length %d, allocated size %d, count %d\r\n",
+                   file,
+                   line,               
+                   n*size, alloc_heap_mem_bytes, alloc_heap_mem_blk_cnt);
+		
+    tls_os_release_critical(cpu_sr);
+    tls_os_sem_release(mem_sem);
+	 tls_mem_alloc_info();
+	 return buf;
+    }
+    tls_os_release_critical(cpu_sr);
+    tls_os_sem_release(mem_sem);
+    return buf;
 }
-void * mem_realloc_debug(void *mem_address, u32 size) {
-    return vPortRealloc(mem_address, size);
+/**
+ * This routine is called to free memory which was previously allocated using MpAllocateMemory function.
+ * Before freeing the memory, this function checks and makes sure that no overflow or underflows have
+ * happened and will also try to detect multiple frees of the same memory chunk.
+ *
+ * \param p    Pointer to allocated memory
+ */
+void mem_free_debug(void *p,  char* file, int line)
+{
+    PMEMORY_PATTERN  mem_ptn_hd;
+    PMEMORY_PATTERN  mem_ptn_tl;
+    PMEMORY_BLOCK  mem_blk_hd1;
+    u8              needfree = 0;
+	u8  haserr = 0;
+    u32  cpu_sr;
+
+    // Jump back by memory header size so we can get to the header
+    mem_ptn_hd = (PMEMORY_PATTERN) (((u8 *)p) - sizeof(MEMORY_PATTERN)  - PRE_OVERSIZE);
+    tls_os_sem_acquire(mem_sem, 0);
+    cpu_sr = tls_os_set_critical();
+    dl_list_for_each(mem_blk_hd1, &memory_used_list, MEMORY_BLOCK, list){
+        if(mem_blk_hd1->header_pattern == (u32)mem_ptn_hd)
+        {
+            needfree = 1;
+            break;
+        }
+    }
+    if(needfree)
+    {
+        dl_list_del(&mem_blk_hd1->list);
+        dl_list_add_tail(&memory_free_list, &mem_blk_hd1->list);
+        alloc_heap_mem_bytes -= mem_blk_hd1->length + sizeof(MEMORY_PATTERN) + sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + OVERSIZE +
+            mem_blk_hd1->pad;
+        alloc_heap_mem_blk_cnt--;
+    }
+    if(needfree == 0)
+    {
+	 printf("Memory Block %p was deallocated from %s at line %d \r\n", mem_ptn_hd, file, line);
+	 printf("Memory %p has been deallocated!\r\n", p);
+	 dl_list_for_each_reverse(mem_blk_hd1, &memory_free_list, MEMORY_BLOCK, list){
+            if(mem_blk_hd1->header_pattern == (u32)mem_ptn_hd)
+            {
+                printf("Memory Block %p has been put free list!\r\n", mem_ptn_hd);
+                break;
+            }
+        }
+        tls_os_release_critical(cpu_sr);
+        tls_os_sem_release(mem_sem);
+        tls_mem_alloc_info();
+	 return;
+    }
+#if 0
+    if(mem_blk_hd1->line == 976 || mem_blk_hd1->line == 983)
+    {
+	 printf("Memory Block %p can not deallocated from %s at line %d \r\n", mem_ptn_hd, file, line);
+	 printf("Memory %p has been deallocated!\r\n", p);
+        tls_mem_alloc_info();
+    }
+#endif
+    mem_ptn_tl = (PMEMORY_PATTERN) ((u8 *)p + mem_blk_hd1->length + mem_blk_hd1->pad + OVERSIZE);
+    //
+    // Check that header was not corrupted
+    //
+    if (mem_ptn_hd->pattern0 != MEM_HEADER_PATTERN /*|| mem_ptn_hd->pattern1 != MEM_HEADER_PATTERN 
+		|| mem_ptn_hd->pattern2 != MEM_HEADER_PATTERN || mem_ptn_hd->pattern3 != MEM_HEADER_PATTERN*/) 
+    {
+        printf("Memory %p was deallocated from %s at line %d \r\n", p, file, line);
+        printf("Memory header corruption due to underflow detected at memory block %p\r\n",
+ 	            mem_ptn_hd);
+        printf("Header pattern 0(0x%x)\r\n",//, 1(0x%x), 2(0x%x), 3(0x%x)
+			mem_ptn_hd->pattern0/*,
+			mem_ptn_hd->pattern1,
+			mem_ptn_hd->pattern2,
+			mem_ptn_hd->pattern3*/);
+        //printf("Dumping information about memory block. "
+        //        "This information may itself have been "
+         //       "corrupted and could cause machine to bugcheck.\r\n");
+        printf("Memory was allocated from %s at line %d with length %d\r\n",
+                mem_blk_hd1->file,
+                mem_blk_hd1->line,
+                mem_blk_hd1->length);
+        haserr = 1;
+    }
+
+#if 0
+    printf("<==free memory allocated from %s at line %d with length %d\n",
+            mem_blk_hd->file,
+            mem_blk_hd->line,
+            mem_blk_hd->length);
+    printf("<==free memory 0x%x\n", (u8 *)mem_blk_hd+sizeof(*mem_blk_hd));
+#endif
+
+    //
+    // Check that trailer was not corrupted
+    //
+    if(mem_ptn_tl->pattern0 != MEM_TAILER_PATTERN /*|| mem_ptn_tl->pattern1 != MEM_TAILER_PATTERN 
+		|| mem_ptn_tl->pattern2 != MEM_TAILER_PATTERN || mem_ptn_tl->pattern3 != MEM_TAILER_PATTERN*/) {
+	 printf("Memory %p was deallocated from %s at line %d \r\n", p, file, line);
+        printf("Memory tailer corruption due to overflow detected at %p\r\n", mem_ptn_hd);
+        printf("Tailer pattern 0(0x%x)\r\n",//, 1(0x%x), 2(0x%x), 3(0x%x)
+			mem_ptn_tl->pattern0/*,
+			mem_ptn_tl->pattern1,
+			mem_ptn_tl->pattern2,
+			mem_ptn_tl->pattern3*/);
+        //printf("Dumping information about memory block. "
+        //       "This information may itself have been "
+        //        "corrupted and could cause machine to bugcheck.\r\n");
+        printf("Memory was allocated from %s at line %d with length %d\r\n",
+                mem_blk_hd1->file, mem_blk_hd1->line, mem_blk_hd1->length);
+		haserr = 1;
+    }
+    if(needfree){
+        free(mem_ptn_hd);
+    }
+    
+    tls_os_release_critical(cpu_sr);
+    tls_os_sem_release(mem_sem);
+
+	if(haserr)
+        tls_mem_alloc_info();
 }
-void *mem_calloc_debug(u32 length, u32 size) {
-    return vPortCalloc(length, size);
+
+void * mem_realloc_debug(void *mem_address, u32 size, char* file, int line)
+{
+	void * mem_re_addr;
+	u32 cpu_sr;
+
+	if ((mem_re_addr = mem_alloc_debug(size,  file, line)) == NULL){
+		printf("mem_realloc_debug failed(size=%d).\r\n", size);
+		return NULL;
+	}
+	if(mem_address != NULL)
+	{
+	    cpu_sr = tls_os_set_critical();
+		memcpy(mem_re_addr, mem_address, size);
+		tls_os_release_critical(cpu_sr);
+		mem_free_debug(mem_address, file, line);
+	}
+	//printf("mem_realloc_debug mem_address=%p, mem_re_addr=%p, size=%d, file=%s, line=%d\n", mem_address, mem_re_addr, size, file, line);
+	return mem_re_addr;
 }
 
-#else
+void tls_mem_alloc_info(void)
+{
+    int i;
+    MEMORY_BLOCK * pos;
+    u32 cpu_sr;
+	
+	tls_os_sem_acquire(mem_sem, 0);
+    cpu_sr = tls_os_set_critical();
+	printf("==>Memory was allocated size %d, count %d\r\n",
+		alloc_heap_mem_bytes, alloc_heap_mem_blk_cnt);
+    i = 1;
+    dl_list_for_each(pos, &memory_used_list, MEMORY_BLOCK, list){
+        printf("Block(%2d): addr<%p>, file<%s>, line<%d>, length<%d>\r\n",
+                i, (void *)pos->header_pattern, pos->file, pos->line, pos->length);
+        i++;
+    }
+	tls_os_release_critical(cpu_sr);
+    tls_os_sem_release(mem_sem);
+    
+}
 
-extern u8 tls_get_isr_count(void);
-bool         memory_manager_initialized = false;
-/**
- * This mutex is used to synchronize the list of allocated
- * memory blocks. This is a debug version only feature
- */
-tls_os_sem_t    *mem_sem;
+int is_safe_addr_debug(void* p, u32 len, char* file, int line)
+{
+    int i;
+    MEMORY_BLOCK * pos;
+    u32 cpu_sr;
 
+    if(((u32)p) >= (u32)0x64ae8 || ((u32)p) < (u32)0x54ae8)
+    {
+        return 1;
+    }
+    tls_os_sem_acquire(mem_sem, 0);
+    cpu_sr = tls_os_set_critical();
+    i = 1;
+    dl_list_for_each(pos, &memory_used_list, MEMORY_BLOCK, list){
+        if((pos->header_pattern + sizeof (MEMORY_PATTERN)  + PRE_OVERSIZE) <= ((u32)p) && ((u32)p) <= ((u32)(pos->header_pattern + sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + pos->length)))
+        {
+            if(((u32)p) + len > ((u32)(pos->header_pattern + sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + pos->length)))
+            {
+                printf("==>Memory oversize. Block(%2d): addr<%p>, file<%s>, line<%d>, length<%d>\r\n",
+                    i, (void *)pos->header_pattern, pos->file, pos->line, pos->length);
+                break;
+            }
+            else
+            {
+                tls_os_release_critical(cpu_sr);
+                tls_os_sem_release(mem_sem);
+                return 1;
+            }
+        }
+        //else if(((u32)p) < pos->header_pattern)
+        //{
+        //    //tls_os_release_critical(cpu_sr);
+        //    tls_os_sem_release(mem_sem);
+        //    return 1;
+       // }
+        i++;
+    }
+    tls_os_release_critical(cpu_sr);
+    tls_os_sem_release(mem_sem);
+    printf("==>Memory is not safe addr<%p>, file<%s>, line<%d>.\r\n",p, file, line);
+    return 0;
+}
+
+#else /* WM_MEM_DEBUG */
+#if TLS_OS_FREERTOS
+u32 alloc_heap_mem_bytes = 0; 
+u32 alloc_heap_mem_blk_cnt = 0;
+u32 alloc_heap_mem_max_size = 0;
+#define OS_MEM_FLAG  (0x5AA5A55A)
+#define NON_OS_MEM_FLAG (0xA55A5A5A)
+#define MEM_HEAD_FLAG (0xBB55B55B)
+#endif
+
+#define USING_ADD_HEADER   1
 extern u32 total_mem_size;
-void * mem_alloc_debug(u32 size) {
+void * mem_alloc_debug(u32 size)
+{
     u32 cpu_sr = 0;
     u32 *buffer = NULL;
 	u32 length = size;
@@ -59,6 +516,8 @@ void * mem_alloc_debug(u32 size) {
 	//printf("size:%d\n", size);
     if (!memory_manager_initialized) {
         tls_os_status_t os_status;
+
+		cpu_sr = tls_os_set_critical(); 	
         memory_manager_initialized = true;
         //
         // NOTE: If two thread allocate the very first allocation simultaneously
@@ -68,51 +527,330 @@ void * mem_alloc_debug(u32 size) {
         os_status = tls_os_sem_create(&mem_sem, 1);
         if(os_status != TLS_OS_SUCCESS)
             printf("mem_alloc_debug: tls_os_sem_create mem_sem error\r\n");
+		tls_os_release_critical(cpu_sr);
+    }
+
+#if USING_ADD_HEADER
+    length += 8;
+
+    if(tls_get_isr_count() > 0)
+    {
+        extern void *pvPortMalloc( size_t xWantedSize );
+        buffer = pvPortMalloc(length);
+		if(buffer) 
+		{
+			*buffer = OS_MEM_FLAG;
+			buffer++;
+			*buffer = length;
+			buffer++;
+		}
     }
+    else
+    {
+    	tls_os_sem_acquire(mem_sem, 0);
+        cpu_sr = tls_os_set_critical();
+        buffer = (u32*)malloc(length);
+	    if(buffer) 
+	    {
+	        *buffer = NON_OS_MEM_FLAG;
+	        buffer++;
+			*buffer = length;
+			buffer++;
+			total_mem_size -= length;
+	    }
+        tls_os_release_critical(cpu_sr);	
+		tls_os_sem_release(mem_sem);
+    }
+#else
 	tls_os_sem_acquire(mem_sem, 0);
     cpu_sr = tls_os_set_critical();
     buffer = (u32*)malloc(length);
     tls_os_release_critical(cpu_sr); 
 	tls_os_sem_release(mem_sem);
+#endif
 	return buffer;
+
 }
 
-extern const uint32_t __ram_end;
-void mem_free_debug(void *p) {
-    if (((uint32_t)p >= (uint32_t)(&__heap_start)) && ((uint32_t)p <= (uint32_t)(&__ram_end)))
-	{
-        u32 cpu_sr = 0;
-        tls_os_sem_acquire(mem_sem, 0);
-        cpu_sr = tls_os_set_critical();
-        free(p);
-        tls_os_release_critical(cpu_sr);	
-        tls_os_sem_release(mem_sem);
+void mem_free_debug(void *p)
+{
+    u32 cpu_sr = 0;
+//	u32 len = 0;
+#if USING_ADD_HEADER
+    u32* intMemPtr = NULL;
+	u8 isrstatus = 0;
+
+	isrstatus = tls_get_isr_count();
+    if(isrstatus == 0)
+    {
+    	tls_os_sem_acquire(mem_sem, 0);
+		cpu_sr = tls_os_set_critical();
+    }
+	
+	intMemPtr = (u32*)p;
+    if(p)
+    {
+		intMemPtr -= 2;    
+		if (*intMemPtr == OS_MEM_FLAG)
+        {
+			extern void vPortFree( void *pv );
+			vPortFree(intMemPtr);
+			intMemPtr = NULL;
+        }
+		else if (*intMemPtr == NON_OS_MEM_FLAG)
+        {
+			total_mem_size += *(intMemPtr + 1);
+			free(intMemPtr);
+			intMemPtr = NULL;
+        }
+        else
+        {
+			printf("mem_free_debug ptr error!!!!!\r\n");
+		}
+    }
+
+    if(isrstatus == 0)
+    {
+		tls_os_release_critical(cpu_sr);
+		tls_os_sem_release(mem_sem);
     }
+#else //UCOSII
+	tls_os_sem_acquire(mem_sem, 0);
+	cpu_sr = tls_os_set_critical();
+	free(p);
+	tls_os_release_critical(cpu_sr);	
+	tls_os_sem_release(mem_sem);
+#endif
 }
-void * mem_realloc_debug(void *mem_address, u32 size) {
+
+
+void * mem_realloc_debug(void *mem_address, u32 size)
+{
     u32 * mem_re_addr = NULL;
     u32 cpu_sr = 0;
 	u32 length = size;
+
+#if USING_ADD_HEADER
+    length = size + 2*4;
+
+    if(tls_get_isr_count() > 0)
+    {
+		extern void *pvPortMalloc( size_t xWantedSize );
+		mem_re_addr = pvPortMalloc(length);
+		if (mem_re_addr)
+		{
+			return NULL;
+		}
+		if(mem_address != NULL)
+		{
+			if (*((u32 *)mem_address-1)> size)
+			{
+				memcpy((u8 *)(mem_re_addr + 2), (u8 *)mem_address, size);
+			}
+			else
+			{
+				memcpy((u8 *)(mem_re_addr + 2), (u8 *)mem_address, *((u32 *)mem_address-1));
+			}
+			mem_free_debug(mem_address);
+			mem_address = NULL;
+    	}
+		if(mem_re_addr) 
+		{
+			*mem_re_addr = OS_MEM_FLAG;
+			mem_re_addr ++;
+			*mem_re_addr = length;
+			mem_re_addr ++;
+		}
+    }
+    else
+    {
+    	tls_os_sem_acquire(mem_sem, 0);
+        cpu_sr = tls_os_set_critical();
+		mem_re_addr = (u32*)malloc(length);
+		if(mem_re_addr && mem_address) 
+		{
+			if (*((u32 *)mem_address-1)> size)
+			{
+				memcpy((u8 *)(mem_re_addr + 2), (u8 *)mem_address, size);
+			}
+			else
+			{
+				memcpy((u8 *)(mem_re_addr + 2), (u8 *)mem_address, *((u32 *)mem_address-1));
+			}
+			*mem_re_addr = NON_OS_MEM_FLAG;
+			mem_re_addr ++;
+			*mem_re_addr = length;
+			mem_re_addr ++;
+			total_mem_size -= length;
+		}
+        tls_os_release_critical(cpu_sr);	
+		tls_os_sem_release(mem_sem);
+
+		mem_free_debug(mem_address);
+    }
+#else
 	tls_os_sem_acquire(mem_sem, 0);
 	cpu_sr = tls_os_set_critical();
 	mem_re_addr = realloc(mem_address, length);
 	tls_os_release_critical(cpu_sr);
 	tls_os_sem_release(mem_sem);
-    return mem_re_addr;
+#endif	
+	//if(mem_re_addr == NULL)
+	//{
+	//	printf("realloc error \r\n");
+	//}
+	return mem_re_addr;
 }
-void *mem_calloc_debug(u32 length, u32 size) {
+
+void *mem_calloc_debug(u32 n, u32 size)
+{
     u32 cpu_sr = 0;
     u32 *buffer = NULL;
-	//u32 length = 0;
+	u32 length = 0;
+
+#if USING_ADD_HEADER
+	length = n*size;
+    length += 2*4;
+
+    if(tls_get_isr_count() > 0)
+    {
+        extern void *pvPortMalloc( size_t xWantedSize );
+        buffer = pvPortMalloc(length);
+		if(buffer) 
+		{
+			memset(buffer, 0, length);
+			*buffer = OS_MEM_FLAG;
+			buffer ++;
+			*buffer = length;
+			buffer ++;
+		}
+    }
+    else
+    {
+    	tls_os_sem_acquire(mem_sem, 0);
+        cpu_sr = tls_os_set_critical();
+        buffer = (u32*)malloc(length);
+		if(buffer) 
+		{
+			memset(buffer, 0, length);
+			*buffer = NON_OS_MEM_FLAG;
+			buffer ++;
+			*buffer = length;
+			buffer ++;
+			total_mem_size -= length;
+		}
+
+        tls_os_release_critical(cpu_sr);	
+		tls_os_sem_release(mem_sem);
+    }
+#else   //UCOSII
 	tls_os_sem_acquire(mem_sem, 0);
     cpu_sr = tls_os_set_critical();
-    buffer = (u32*)calloc(length, size);
+    buffer = (u32*)calloc(n,size);
     tls_os_release_critical(cpu_sr); 
 	tls_os_sem_release(mem_sem);
-    return buffer;
+#endif
+	//if(buffer == NULL)
+	//{
+	//	printf("calloc error \r\n");
+	//}
+	return buffer;
 }
+#endif /* WM_MEM_DEBUG */
 
-#endif
+extern u32 __heap_end;
+extern u32 __heap_start;
+
+u32 tls_mem_get_avail_heapsize(void)
+{
+#if USING_ADD_HEADER
+	u32 availablemem = 0;
+	u32 cpu_sr;
+
+	tls_os_sem_acquire(mem_sem, 0);
+	cpu_sr = tls_os_set_critical();
+	availablemem = total_mem_size;
+    tls_os_release_critical(cpu_sr);	
+	tls_os_sem_release(mem_sem);
+
+	return availablemem;
+#else
+	u8 *p = NULL;
+	u32 startpos = 0;
+	u32 stoppos = 0;
+	u32 laststartpos = 0;
+	static u32 last_avail_heapsize = 0;
+	u32 cpu_sr = 0;
+
+    if (!memory_manager_initialized) {
+        tls_os_status_t os_status;
+        memory_manager_initialized = true;
+        //
+        // NOTE: If two thread allocate the very first allocation simultaneously
+        // it could cause double initialization of the memory manager. This is a
+        // highly unlikely scenario and will occur in debug versions only.
+        //
+        os_status = tls_os_sem_create(&mem_sem, 1);
+        if(os_status != TLS_OS_SUCCESS)
+            printf("mem_alloc_debug: tls_os_sem_create mem_sem error\n");
+    }
+
+	tls_os_sem_acquire(mem_sem, 0);
+    cpu_sr = tls_os_set_critical();	
+	if (last_avail_heapsize)
+	{
+		startpos = last_avail_heapsize;
+		stoppos = last_avail_heapsize*2;
+		if (startpos > ((u32)&__heap_end - (u32)&__heap_start))
+		{
+			startpos = (u32)&__heap_end - (u32)&__heap_start;
+		}
+	}
+	else
+	{
+		startpos = (u32)&__heap_end - (u32)&__heap_start;
+		stoppos = (u32)&__heap_end - (u32)&__heap_start;
+	}
+
+	for (;startpos <= stoppos;)
+	{
+		p = malloc(startpos);
+		if (p)
+		{
+			free(p);
+			if (startpos < 1024 || (stoppos - startpos) < 1024
+				|| (startpos == ((u32)&__heap_end - (u32)&__heap_start)))
+			{
+				last_avail_heapsize = startpos;
+				goto END;
+			}
+			laststartpos = startpos;
+			startpos = (stoppos + startpos)>>1;
+		}
+		else
+		{
+			stoppos = startpos;
+			if (laststartpos)
+			{
+				startpos = (laststartpos + stoppos)/2;
+			}
+			else
+			{
+				startpos = startpos>>1;
+			}
+			if (startpos < 1024 || (stoppos - startpos) < 1024)
+			{
+				last_avail_heapsize = startpos;
+				goto END;
+			}
+		}
+	}
+END:
+    tls_os_release_critical(cpu_sr); 
+	tls_os_sem_release(mem_sem);	
+	return startpos;
+#endif	
+}
 
 
 

+ 1 - 1
platform/common/params/wm_param.c

@@ -430,7 +430,7 @@ int tls_param_init(void)
 			TLS_DBGPRT_INFO("read parameter partition - %d.\n", i);
 			tls_fls_read((i == 0) ? TLS_FLASH_PARAM1_ADDR : TLS_FLASH_PARAM2_ADDR, (u8 *)flash, sizeof(*flash));
 			TLS_DBGPRT_INFO("patition %d magic - 0x%x, crc -0x%x .\n", i, flash->magic, flash->crc32);
-			
+
 			if (flash->magic == TLS_PARAM_MAGIC)
 			{
 				crckey = 0xFFFFFFFF;

+ 3 - 3
platform/common/utils/utils.c

@@ -17,7 +17,7 @@
 #include "wm_mem.h"
 #include "tls_common.h"
 #include "wm_debug.h"
-//#include "wm_sockets.h"
+#include "wm_sockets.h"
 #include "utils.h"
 
 
@@ -454,8 +454,8 @@ char * strndup(const char *s, size_t len)
 	memcpy(ret, s, len);
 	return ret;
 }
-#if 0
-int gettimeofday(struct timeval *tv, void *tz)
+#if 1
+int gettimeofday(struct timeval *tv, struct timezone *tz)
 {
 	int ret = 0;
 	u32 current_tick; 

+ 7 - 2
platform/drivers/adc/wm_adc.c

@@ -31,10 +31,14 @@ typedef struct
 	double a[3];
 }ST_ADC_POLYFIT_PARAM;
 
+/*f(x) = kx + b*/
+//#define ADC_CAL_K_POS   (6)
+//#define ADC_CAL_B_POS   (7)
+
+
 ST_ADC_POLYFIT_PARAM _polyfit_param = {0};
 extern void polyfit(int n,double x[],double y[],int poly_n,double a[]);
-//TODO
-#define HR_SD_ADC_CONFIG_REG 0
+
 static int adc_offset = 0;
 static int *adc_dma_buffer = NULL;
 volatile ST_ADC gst_adc;
@@ -655,3 +659,4 @@ int adc_temp(void)
 	return temperature;
 }
 
+

+ 5 - 5
platform/drivers/adc/wm_polyfit.c

@@ -8,7 +8,7 @@
 
 void polyfit_verify(double x, double* a)
 {
-	double y1 = a[2]*x*x + a[1]*x + a[0];
+	double y1 = a[1]*x + a[0];
 	printf("x=%d, y1=%d\n", (int)x, (int)(y1+0.5));
 }
 
@@ -95,9 +95,9 @@ x[i]-=A[i*n+j]*x[j];
 
 void polyfit_test(void)
 {
-	int i,n=4,poly_n=2;
-	double x[4]={4823, 9816, 14851, 19837},y[4]={5000, 9986, 15001, 19959};
-	double a[3];
+	int i,n=2,poly_n=1;
+	double x[2]={15174, 19196},y[2]={5000, 9986};
+	double a[2];
 	void polyfit(int n,double *x,double *y,int poly_n,double a[]);
 
 
@@ -110,4 +110,4 @@ void polyfit_test(void)
 	{
 		polyfit_verify(x[i], a);
 	}
-}
+}

+ 0 - 1
platform/drivers/cpu/wm_cpu.c

@@ -35,7 +35,6 @@ void tls_sys_clk_set(u32 clk)
 	{
 		return;
 	}
-	
 
 	RegValue = tls_reg_read32(HR_CLK_DIV_CTL);
 	wlanDiv = (RegValue>>8)&0xFF;

+ 1 - 1
platform/drivers/dma/wm_dma.c

@@ -259,7 +259,7 @@ unsigned char tls_dma_start_by_wrap(unsigned char ch, struct tls_dma_descriptor
     DMA_SRCWRAPADDR_REG(ch) = dma_desc->src_addr;
     DMA_DESTWRAPADDR_REG(ch) = dma_desc->dest_addr;
     DMA_WRAPSIZE_REG(ch) = (dest_zize << 16) | src_zize;
-    DMA_CTRL_REG(ch) = ((dma_desc->dma_ctrl & 0x1ffff) << 1) | (auto_reload ? 0x1: 0x0);
+    DMA_CTRL_REG(ch) = ((dma_desc->dma_ctrl & 0x7fffff) << 1) | (auto_reload ? 0x1: 0x0);
     DMA_CHNLCTRL_REG(ch) |= DMA_CHNL_CTRL_CHNL_ON;
 
     return 0;

+ 198 - 91
platform/drivers/efuse/wm_efuse.c

@@ -26,6 +26,7 @@
 
 
 #define FT_MAGICNUM_ADDR		(FLASH_BASE_ADDR)
+#define FT_PARAM_RUNTIME_ADDR	(FT_MAGICNUM_ADDR + 0x1000)
 #define MAGICNUM_LEN			(4)
 #define MAC_ADDR_LEN			(6)
 #define FT_GAIN_LEN				(84)
@@ -70,28 +71,23 @@ static u8 default_mac[6] = {0x00,0x25,0x08,0x09,0x01,0x0F};
 FT_PARAM_ST_VER1  gftParamVer1;
 
 FT_PARAM_ST *gftParam = (FT_PARAM_ST *)&gftParamVer1;
-int tls_ft_param_init(void)
+static int _ft_ext1_valid(FT_PARAM_ST *pft)
+{
+	//printf("version_no %d, ext_param_len %x\n", pft->version_no, pft->ext_param_len);
+	if (pft->version_no > 0 && pft->version_no < 0xFFFF && pft->ext_param_len >= sizeof(FT_PARAM_ST_EXT_1) && 
+				pft->ext_param_len <= (sizeof(FT_PARAM_ST_EXT_1) + FT_PARAM_EXT_REVERSED_LEN))
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+static int _ft_param_init(u32 ft_addr, FT_PARAM_ST *pft)
 {
 	u32 crcvalue = 0;
 	psCrcContext_t ctx;	
 	FT_PARAM_ST_VER1 *pft_ver1 = NULL;
-	FT_PARAM_ST *pft = NULL;
 	
-	if (gftParam->magic_no == SIGNATURE_WORD)
-	{
-		return TRUE;
-	}
-
-	pft = tls_mem_alloc(sizeof(FT_PARAM_ST_VER1));
-	if (pft == NULL)
-	{
-		return FALSE;
-	}
-
-	memset(pft, 0xFF, sizeof(FT_PARAM_ST_VER1));
-	memset(gftParam, 0xFF, sizeof(FT_PARAM_ST_VER1));
-
-	tls_fls_read(FT_MAGICNUM_ADDR, (unsigned char *)pft, sizeof(FT_PARAM_ST_VER1));
+	tls_fls_read(ft_addr, (unsigned char *)pft, sizeof(FT_PARAM_ST_VER1));
 	if (pft->magic_no == SIGNATURE_WORD)
 	{
 		tls_crypto_init();
@@ -100,14 +96,13 @@ int tls_ft_param_init(void)
 		tls_crypto_crc_final(&ctx, &crcvalue);		
 		if (pft->checksum != crcvalue)
 		{
-			tls_mem_free(pft);
+			//tls_mem_free(pft);
 			return FALSE;
 		}
 
 		do
 		{
-			if (pft->version_no > 0 && pft->version_no < 0xFFFF && pft->ext_param_len >= sizeof(FT_PARAM_ST_EXT_1) && 
-				pft->ext_param_len <= (sizeof(FT_PARAM_ST_EXT_1) + FT_PARAM_EXT_REVERSED_LEN))
+			if (_ft_ext1_valid(pft))
 			{
 				pft_ver1 = (FT_PARAM_ST_VER1 *)pft;
 				tls_crypto_crc_init(&ctx, 0xFFFFFFFF, CRYPTO_CRC_TYPE_32, INPUT_REFLECT | OUTPUT_REFLECT);
@@ -115,31 +110,100 @@ int tls_ft_param_init(void)
 				tls_crypto_crc_final(&ctx, &crcvalue);	
 				if(pft_ver1->ext_checksum == crcvalue)
 				{
-					memcpy((unsigned char *)gftParam, (unsigned char *)pft, sizeof(FT_PARAM_ST_VER1));
-					break;
+					return 1;
+				}
+				else
+				{
+					return FALSE;
 				}
 			}
 			pft->version_no = 0xFFFF;
 			pft->ext_param_len = 0xFFFF;
-			memcpy((unsigned char *)gftParam, (unsigned char *)pft, sizeof(FT_PARAM_ST));
 		}while(0);
+		return 2;
+	}
+	return FALSE;
+}
+int tls_ft_param_init(void)
+{
+	int ret = 0;
+	FT_PARAM_ST *pft = NULL;
+	
+	if (gftParam->magic_no == SIGNATURE_WORD)
+	{
+		return TRUE;
+	}
+	memset(gftParam, 0xFF, sizeof(FT_PARAM_ST_VER1));
+
+	pft = tls_mem_alloc(sizeof(FT_PARAM_ST_VER1));
+	if (pft == NULL)
+	{
+		return FALSE;
+	}
+	memset(pft, 0xFF, sizeof(FT_PARAM_ST_VER1));
+	ret = _ft_param_init(FT_PARAM_RUNTIME_ADDR, pft);
+	if(FALSE == ret)
+	{
+		memset(pft, 0xFF, sizeof(FT_PARAM_ST_VER1));
+		ret = _ft_param_init(FT_MAGICNUM_ADDR, pft);
+	}
+	if(1 == ret)
+	{
+		memcpy((unsigned char *)gftParam, (unsigned char *)pft, sizeof(FT_PARAM_ST_VER1));
+	}
+	else if(2 == ret)
+	{
+		memcpy((unsigned char *)gftParam, (unsigned char *)pft, sizeof(FT_PARAM_ST));	
 	}
 	tls_mem_free(pft);
 
 	/*lock parameter*/
 	tls_flash_unlock();
-	return TRUE;
+	return ret;
 }
 
 int tls_ft_param_get(unsigned int opnum, void *data, unsigned int rdlen)
 {
+	int ret = 0;
 	switch (opnum)
 	{
+		case CMD_FREQ_ERR:
+			if(_ft_ext1_valid(gftParam))
+			{
+				memcpy(data, (char *)&gftParamVer1.ft_ext1.rf_freq_err, FREQERR_LEN);
+			}
+			else
+			{
+				ret = tls_fls_read(FREQERR_ADDR, data, FREQERR_LEN);
+				if(ret)
+				{
+					return -1;
+				}
+			}
+			break;
+		case CMD_RF_CAL_FLAG:
+			if(_ft_ext1_valid(gftParam))
+			{
+				memcpy(data, (char *)&gftParamVer1.ft_ext1.rf_cal_flag, CAL_FLAG_LEN);
+			}
+			else
+			{
+				ret = tls_fls_read(CAL_FLAG_ADDR, data, CAL_FLAG_LEN);
+				if(ret)
+				{
+					return -1;
+				}
+			}
+			break;
 		case CMD_TX_ADC_CAL:
-			if(gftParam->version_no > 0 && gftParam->version_no < 0xFFFF)
+			if(_ft_ext1_valid(gftParam))
 			{
 				memcpy(data, (unsigned char *)&gftParamVer1.ft_ext1.adc_cal_param, rdlen);
 			}
+			else
+			{
+				return -1;
+			}
 			break;
 		case CMD_WIFI_MAC:	/*MAC*/
 			if ((gftParam->wifi_mac_addr[0]&0x1)
@@ -217,13 +281,57 @@ int tls_ft_param_set(unsigned int opnum, void *data, unsigned int len)
 {
 	psCrcContext_t ctx;
 	unsigned int writelen = 0;
+	FT_PARAM_ST *pft = NULL;
+	int ret = 0;
 
 	if (!data || !len)
 	{
 		return -1;
 	}
+	
+	pft = tls_mem_alloc(sizeof(FT_PARAM_ST_VER1));
+	if (pft == NULL)
+	{
+		return -1;
+	}
+	memset(pft, 0xFF, sizeof(FT_PARAM_ST_VER1));
+	ret = _ft_param_init(FT_PARAM_RUNTIME_ADDR, pft);
+	if(ret)
+	{
+		memset(pft, 0xFF, sizeof(FT_PARAM_ST_VER1));
+		ret = _ft_param_init(FT_MAGICNUM_ADDR, pft);
+		if(!ret || memcmp(pft, gftParam, sizeof(FT_PARAM_ST_VER1)))
+		{
+			tls_flash_unlock();
+			tls_fls_write(FT_MAGICNUM_ADDR, (unsigned char *)gftParam, sizeof(FT_PARAM_ST_VER1));
+			memset(pft, 0xFF, sizeof(FT_PARAM_ST_VER1));
+			ret = _ft_param_init(FT_MAGICNUM_ADDR, pft);
+			if(!ret || memcmp(pft, gftParam, sizeof(FT_PARAM_ST_VER1)))
+			{
+				memset(pft, 0xFF, sizeof(FT_PARAM_ST_VER1));
+				tls_mem_free(pft);
+				return -1;
+			}
+		}
+	}
+	if(!_ft_ext1_valid(gftParam))
+	{
+		gftParam->version_no = 1;
+		gftParam->ext_param_len = sizeof(FT_PARAM_ST_EXT_1);
+		memset((char *)&gftParamVer1.ft_ext1, 0xFF, gftParam->ext_param_len);
+	}
 	switch (opnum)
 	{
+		case CMD_FREQ_ERR:
+			memcpy((char *)&gftParamVer1.ft_ext1.rf_freq_err, (char *)data, FREQERR_LEN);
+			break;
+		case CMD_RF_CAL_FLAG:
+			memcpy((char *)&gftParamVer1.ft_ext1.rf_cal_flag, (char *)data, CAL_FLAG_LEN);
+			break;
+		case CMD_TX_ADC_CAL:
+			memcpy((unsigned char *)&gftParamVer1.ft_ext1.adc_cal_param, data, len);
+		break;
+		
 		case CMD_WIFI_MAC:	/*MAC*/
 			memcpy(gftParam->wifi_mac_addr, (unsigned char *)data, len);
 		break;
@@ -269,25 +377,44 @@ int tls_ft_param_set(unsigned int opnum, void *data, unsigned int len)
 		break;
 		
 		default:
-		return -1;
+			tls_mem_free(pft);
+			return -1;
 	}
 
 	tls_crypto_init();
+	/*len to write to flash*/
+	writelen = sizeof(FT_PARAM_ST_VER1);
 	tls_crypto_crc_init(&ctx, 0xFFFFFFFF, CRYPTO_CRC_TYPE_32, INPUT_REFLECT | OUTPUT_REFLECT);
+	tls_crypto_crc_update(&ctx, (unsigned char *)&gftParamVer1.ft_ext1, gftParam->ext_param_len);
+	tls_crypto_crc_final(&ctx, &gftParamVer1.ext_checksum);
+
 	gftParam->magic_no = SIGNATURE_WORD;
+	tls_crypto_crc_init(&ctx, 0xFFFFFFFF, CRYPTO_CRC_TYPE_32, INPUT_REFLECT | OUTPUT_REFLECT);
 	tls_crypto_crc_update(&ctx, (unsigned char *)gftParam + 8, sizeof(FT_PARAM_ST) -8);
 	tls_crypto_crc_final(&ctx, &gftParam->checksum);
-	writelen = sizeof(FT_PARAM_ST);
-	if(gftParam->version_no > 0 && gftParam->version_no < 0xFFFF)
+
+	tls_flash_unlock();
+	tls_fls_write(FT_PARAM_RUNTIME_ADDR, (unsigned char *)gftParam, writelen);
+	memset(pft, 0xFF, sizeof(FT_PARAM_ST_VER1));
+	ret = _ft_param_init(FT_PARAM_RUNTIME_ADDR, pft);
+	if(!ret || memcmp(pft, gftParam, sizeof(FT_PARAM_ST_VER1)))
 	{
-		writelen = sizeof(FT_PARAM_ST_VER1);
-		tls_crypto_crc_init(&ctx, 0xFFFFFFFF, CRYPTO_CRC_TYPE_32, INPUT_REFLECT | OUTPUT_REFLECT);
-		tls_crypto_crc_update(&ctx, (unsigned char *)&gftParamVer1.ft_ext1, gftParam->ext_param_len);
-		tls_crypto_crc_final(&ctx, &gftParamVer1.ext_checksum);
+		memset(pft, 0xFF, sizeof(FT_PARAM_ST_VER1));
+		tls_mem_free(pft);
+		return -1;
 	}
-	tls_flash_unlock();
 	tls_fls_write(FT_MAGICNUM_ADDR, (unsigned char *)gftParam, writelen);
-	tls_flash_lock();
+	memset(pft, 0xFF, sizeof(FT_PARAM_ST_VER1));
+	ret = _ft_param_init(FT_MAGICNUM_ADDR, pft);
+	if(!ret || memcmp(pft, gftParam, sizeof(FT_PARAM_ST_VER1)))
+	{
+		memset(pft, 0xFF, sizeof(FT_PARAM_ST_VER1));
+		tls_mem_free(pft);
+		return -1;
+	}
+	memset(pft, 0xFF, sizeof(FT_PARAM_ST_VER1));
+	tls_mem_free(pft);
+	//tls_flash_lock();
 	return 0;
 }
 
@@ -479,45 +606,26 @@ int tls_set_rx_iq_phase(u8 *rxPhase)
 int tls_freq_err_op(u8 *freqerr, u8 flag)
 {
 	int ret = 0;
-	psCrcContext_t ctx;
 	int value = 0;
 	if (flag){
-		tls_flash_unlock();
-		if(gftParam->version_no > 0 && gftParam->version_no < 0xFFFF)
-		{
-			memcpy((char *)&gftParamVer1.ft_ext1.rf_freq_err, (char *)freqerr, FREQERR_LEN);
-			tls_crypto_crc_init(&ctx, 0xFFFFFFFF, CRYPTO_CRC_TYPE_32, INPUT_REFLECT | OUTPUT_REFLECT);
-			tls_crypto_crc_update(&ctx, (unsigned char *)&gftParamVer1.ft_ext1, gftParam->ext_param_len);
-			tls_crypto_crc_final(&ctx, &gftParamVer1.ext_checksum);
-			ret = tls_fls_write(FT_MAGICNUM_ADDR, (unsigned char *)gftParam, sizeof(FT_PARAM_ST_VER1));
-		}
-		else
-		{
-			ret = tls_fls_write(FREQERR_ADDR, freqerr, FREQERR_LEN);
-		}
-		tls_flash_lock();
+		ret = tls_ft_param_set(CMD_FREQ_ERR, freqerr, FREQERR_LEN);
 	}
 	else
 	{
-		if(gftParam->version_no > 0 && gftParam->version_no < 0xFFFF)
-		{
-			memcpy((char *)freqerr, (char *)&gftParamVer1.ft_ext1.rf_freq_err, FREQERR_LEN);
-		}
-		else
+		ret = tls_ft_param_get(CMD_FREQ_ERR, freqerr, FREQERR_LEN);
+		if(!ret)
 		{
-			ret = tls_fls_read(FREQERR_ADDR, freqerr, FREQERR_LEN);
-		}
-		
-		memcpy(&value, freqerr, FREQERR_LEN);
-		if (value > 200000) /*when freq offset is out of range (-200KHz, 200KHz),do not use it*/
-		{
-			value = 200000;
-			memcpy((char *)freqerr, (char *)&value, FREQERR_LEN);
-		}
-		else if (value < -200000)
-		{
-			value = -200000;
-			memcpy((char *)freqerr, (char *)&value, FREQERR_LEN);
+			memcpy(&value, freqerr, FREQERR_LEN);
+			if (value > 200000) /*when freq offset is out of range (-200KHz, 200KHz),do not use it*/
+			{
+				value = 200000;
+				memcpy((char *)freqerr, (char *)&value, FREQERR_LEN);
+			}
+			else if (value < -200000)
+			{
+				value = -200000;
+				memcpy((char *)freqerr, (char *)&value, FREQERR_LEN);
+			}
 		}
 	}
 	if (ret == 0)
@@ -533,33 +641,12 @@ int tls_freq_err_op(u8 *freqerr, u8 flag)
 int tls_rf_cal_finish_op(u8 *calflag, u8 flag)
 {
 	int ret = 0;
-	psCrcContext_t ctx;
 	if (flag){
-		tls_flash_unlock();
-		if(gftParam->version_no > 0 && gftParam->version_no < 0xFFFF)
-		{
-			memcpy((char *)&gftParamVer1.ft_ext1.rf_cal_flag, (char *)calflag, CAL_FLAG_LEN);
-			tls_crypto_crc_init(&ctx, 0xFFFFFFFF, CRYPTO_CRC_TYPE_32, INPUT_REFLECT | OUTPUT_REFLECT);
-			tls_crypto_crc_update(&ctx, (unsigned char *)&gftParamVer1.ft_ext1, gftParam->ext_param_len);
-			tls_crypto_crc_final(&ctx, &gftParamVer1.ext_checksum);
-			ret = tls_fls_write(FT_MAGICNUM_ADDR, (unsigned char *)gftParam, sizeof(FT_PARAM_ST_VER1));
-		}
-		else
-		{
-			ret = tls_fls_write(CAL_FLAG_ADDR, calflag, CAL_FLAG_LEN);
-		}
-		tls_flash_lock();
+		ret = tls_ft_param_set(CMD_RF_CAL_FLAG, calflag, CAL_FLAG_LEN);
 	}
 	else
 	{
-		if(gftParam->version_no > 0 && gftParam->version_no < 0xFFFF)
-		{
-			memcpy((char *)calflag, (char *)&gftParamVer1.ft_ext1.rf_cal_flag, CAL_FLAG_LEN);
-		}
-		else
-		{
-			ret = tls_fls_read(CAL_FLAG_ADDR, calflag, CAL_FLAG_LEN);
-		}
+		ret = tls_ft_param_get(CMD_RF_CAL_FLAG, calflag, CAL_FLAG_LEN);
 	}
 
 	if (ret == 0)
@@ -600,11 +687,31 @@ int tls_set_tx_gain(u8 *txgain)
 	
 
 }
+
+/**
+* @brief 	This function is used to get adc cal param
+*
+* @param[out]	adc_cal		adc cal param
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			get success
+* @retval		TLS_EFUSE_STATUS_EIO		get failed
+*/
 int tls_get_adc_cal_param(FT_ADC_CAL_ST *adc_cal)
 {
 	return tls_ft_param_get(CMD_TX_ADC_CAL, adc_cal, sizeof(FT_ADC_CAL_ST));
 }
 
-
+/**
+* @brief 	This function is used to set adc cal param
+*
+* @param[out]	adc_cal		adc cal param
+*
+* @retval	 	TLS_EFUSE_STATUS_OK			get success
+* @retval		TLS_EFUSE_STATUS_EIO		get failed
+*/
+int tls_set_adc_cal_param(FT_ADC_CAL_ST *adc_cal)
+{
+	return tls_ft_param_set(CMD_TX_ADC_CAL, adc_cal, sizeof(FT_ADC_CAL_ST));
+}
 
 

+ 59 - 24
platform/drivers/internalflash/wm_internal_fls.c

@@ -23,6 +23,7 @@ static struct tls_inside_fls *inside_fls = NULL;
 static u8 tls_fls_cache[INSIDE_FLS_SECTOR_SIZE];
 
 /**System parameter, default for 2M flash*/
+unsigned int  TLS_FLASH_MESH_PARAM_ADDR      =        (0x81FA000UL);
 unsigned int  TLS_FLASH_PARAM_DEFAULT        =		  (0x81FB000UL);
 unsigned int  TLS_FLASH_PARAM1_ADDR          =		  (0x81FC000UL);
 unsigned int  TLS_FLASH_PARAM2_ADDR          =		  (0x81FD000UL);
@@ -61,17 +62,18 @@ static void writeBpBit_for_1wreg(char cmp, char bp4, char bp3, char bp2, char bp
     M32(HR_FLASH_CMD_ADDR) = 0x0C035;
     M32(HR_FLASH_CMD_START) = CMD_START_Msk;
     status  |=  (read_first_value() & 0xFF) << 8;
-
-    /*Write Enable*/
-    M32(HR_FLASH_CMD_ADDR) = 0x6;
-    M32(HR_FLASH_CMD_START) = CMD_START_Msk;
-
     bpstatus  = (bp4 << 6) | (bp3 << 5) | (bp2 << 4) | (bp1 << 3) | (bp0 << 2);
-    status      = (status & 0xBF83) | bpstatus | (cmp << 14);
-
-    M32(RSA_BASE_ADDRESS)  = status;
-    M32(HR_FLASH_CMD_ADDR) = 0x1A001;
-    M32(HR_FLASH_CMD_START) = CMD_START_Msk;
+	if ((status & 0x407C) != (bpstatus|(cmp<<14)))
+	{
+	    status      = (status & 0xBF83) | bpstatus | (cmp << 14);
+	    /*Write Enable*/
+	    M32(HR_FLASH_CMD_ADDR) = 0x6;
+	    M32(HR_FLASH_CMD_START) = CMD_START_Msk;
+
+	    M32(RSA_BASE_ADDRESS)  = status;
+	    M32(HR_FLASH_CMD_ADDR) = 0x1A001;
+	    M32(HR_FLASH_CMD_START) = CMD_START_Msk;
+	}
 }
 
 static void writeBpBit_for_2wreg(char cmp, char bp4, char bp3, char bp2, char bp1, char bp0)
@@ -88,24 +90,29 @@ static void writeBpBit_for_2wreg(char cmp, char bp4, char bp3, char bp2, char bp
     status  |=  (read_first_value() & 0xFF) << 8;
 
     /*Write Enable*/
-    M32(HR_FLASH_CMD_ADDR) = 0x6;
-    M32(HR_FLASH_CMD_START) = CMD_START_Msk;
-
     bpstatus  = (bp4 << 6) | (bp3 << 5) | (bp2 << 4) | (bp1 << 3) | (bp0 << 2);
-    bpstatus      = (status & 0x83) | bpstatus;
+	if ((bpstatus != (status & 0x7C)))
+	{
+	    bpstatus      = (status & 0x83) | bpstatus;
 
-    M32(RSA_BASE_ADDRESS)  = bpstatus;
-    M32(HR_FLASH_CMD_ADDR) = 0xA001;
-    M32(HR_FLASH_CMD_START) = CMD_START_Msk;
+	    M32(HR_FLASH_CMD_ADDR) = 0x6;
+	    M32(HR_FLASH_CMD_START) = CMD_START_Msk;
 
+	    M32(RSA_BASE_ADDRESS)  = bpstatus;
+	    M32(HR_FLASH_CMD_ADDR) = 0xA001;
+	    M32(HR_FLASH_CMD_START) = CMD_START_Msk;
+	}
 
-    M32(HR_FLASH_CMD_ADDR) = 0x6;
-    M32(HR_FLASH_CMD_START) = CMD_START_Msk;
+	if (((status & 0x4000)>>8) != (cmp << 6))
+	{
+	    M32(HR_FLASH_CMD_ADDR) = 0x6;
+	    M32(HR_FLASH_CMD_START) = CMD_START_Msk;
 
-    status      = ((status>>8) & 0xBF) | (cmp << 6);
-    M32(RSA_BASE_ADDRESS)   = status;
-    M32(HR_FLASH_CMD_ADDR)  = 0xA031;
-    M32(HR_FLASH_CMD_START) = CMD_START_Msk;	
+	    status      = ((status>>8) & 0xBF) | (cmp << 6);
+	    M32(RSA_BASE_ADDRESS)   = status;
+	    M32(HR_FLASH_CMD_ADDR)  = 0xA031;
+	    M32(HR_FLASH_CMD_START) = CMD_START_Msk;	
+	}
 }
 
 
@@ -155,6 +162,16 @@ static int flashunlock(void)
         writeBpBit_for_1wreg(0, 0, 0, 0, 0, 0);
         break;
     case SPIFLASH_MID_PUYA:
+	case SPIFLASH_MID_TSINGTENG_1MB_4MB:
+		if (inside_fls->density == 0x100000)/*PUYA 1M Flash use 1 register to set lock/unlock*/
+		{
+			writeBpBit_for_1wreg(0, 0, 0, 0, 0, 0);
+		}
+		else
+		{
+			writeBpBit_for_2wreg(0, 0, 0, 0, 0, 0);
+		}
+		break;
 	case SPIFLASH_MID_XTX:
 	case SPIFLASH_MID_BOYA:
 	case SPIFLASH_MID_FUDANMICRO:
@@ -175,10 +192,20 @@ static int flashlock(void)
     switch(readRID())
     {
     case SPIFLASH_MID_GD:
-	case SPIFLASH_MID_TSINGTENG:		
+	case SPIFLASH_MID_TSINGTENG:	
         writeBpBit_for_1wreg(0, 1, 1, 0, 1, 0);
 		break;
     case SPIFLASH_MID_PUYA:
+	case SPIFLASH_MID_TSINGTENG_1MB_4MB:
+		if (inside_fls->density == 0x100000) /*PUYA 1M Flash use 1 register to set lock/unlock*/
+		{
+			writeBpBit_for_1wreg(0, 1, 1, 0, 1, 0);
+		}
+		else
+		{
+			writeBpBit_for_2wreg(0, 1, 1, 0, 1, 0);
+		}
+        break;
 	case SPIFLASH_MID_XTX:
 	case SPIFLASH_MID_BOYA:
 	case SPIFLASH_MID_FUDANMICRO:
@@ -293,6 +320,14 @@ static int eraseSector (unsigned long adr)
 
     return (0);                                  				// Finished without Errors
 }
+#if 0
+/*only for XT806 c400 flash*/
+static int erasePage (unsigned long addr)
+{
+	eraseSR(0x80000881, addr);
+    return (0);                                  				// Finished without Errors
+}
+#endif
 
 static unsigned int getFlashDensity(void)
 {

+ 12 - 2
platform/drivers/io/wm_io.c

@@ -33,6 +33,8 @@ static void io_cfg_option1(enum tls_io_name name)
     tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) | BIT(pin));  /* gpio function */
     tls_reg_write32(HR_GPIO_AF_S1  + offset, tls_reg_read32(HR_GPIO_AF_S1  + offset) & (~BIT(pin)));
     tls_reg_write32(HR_GPIO_AF_S0  + offset, tls_reg_read32(HR_GPIO_AF_S0  + offset) & (~BIT(pin)));
+	tls_reg_write32(HR_GPIO_PULLUP_EN + offset, tls_reg_read32(HR_GPIO_PULLUP_EN + offset) | (BIT(pin))); /*disable pullup*/
+	tls_reg_write32(HR_GPIO_PULLDOWN_EN + offset, tls_reg_read32(HR_GPIO_PULLDOWN_EN + offset) & (~BIT(pin)));	/*disable pulldown*/
 }
 
 static void io_cfg_option2(enum tls_io_name name)
@@ -54,6 +56,8 @@ static void io_cfg_option2(enum tls_io_name name)
     tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) | BIT(pin));  /* gpio function */
     tls_reg_write32(HR_GPIO_AF_S1  + offset, tls_reg_read32(HR_GPIO_AF_S1  + offset) & (~BIT(pin)));
     tls_reg_write32(HR_GPIO_AF_S0  + offset, tls_reg_read32(HR_GPIO_AF_S0  + offset) | BIT(pin));
+	tls_reg_write32(HR_GPIO_PULLUP_EN + offset, tls_reg_read32(HR_GPIO_PULLUP_EN + offset) | (BIT(pin))); /*disable pullup*/
+	tls_reg_write32(HR_GPIO_PULLDOWN_EN + offset, tls_reg_read32(HR_GPIO_PULLDOWN_EN + offset) & (~BIT(pin)));	/*disable pulldown*/
 }
 
 static void io_cfg_option3(enum tls_io_name name)
@@ -75,6 +79,8 @@ static void io_cfg_option3(enum tls_io_name name)
     tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) | BIT(pin));  /* gpio function */
     tls_reg_write32(HR_GPIO_AF_S1  + offset, tls_reg_read32(HR_GPIO_AF_S1  + offset) | BIT(pin));
     tls_reg_write32(HR_GPIO_AF_S0  + offset, tls_reg_read32(HR_GPIO_AF_S0  + offset) & (~BIT(pin)));
+	tls_reg_write32(HR_GPIO_PULLUP_EN + offset, tls_reg_read32(HR_GPIO_PULLUP_EN + offset) | (BIT(pin))); /*disable pullup*/
+	tls_reg_write32(HR_GPIO_PULLDOWN_EN + offset, tls_reg_read32(HR_GPIO_PULLDOWN_EN + offset) & (~BIT(pin)));	/*disable pulldown*/
 }
 
 static void io_cfg_option4(enum tls_io_name name)
@@ -96,6 +102,8 @@ static void io_cfg_option4(enum tls_io_name name)
     tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) | BIT(pin));  /* gpio function */
     tls_reg_write32(HR_GPIO_AF_S1  + offset, tls_reg_read32(HR_GPIO_AF_S1  + offset) | BIT(pin));
     tls_reg_write32(HR_GPIO_AF_S0  + offset, tls_reg_read32(HR_GPIO_AF_S0  + offset) | BIT(pin));
+	tls_reg_write32(HR_GPIO_PULLUP_EN + offset, tls_reg_read32(HR_GPIO_PULLUP_EN + offset) | (BIT(pin))); /*disable pullup*/
+	tls_reg_write32(HR_GPIO_PULLDOWN_EN + offset, tls_reg_read32(HR_GPIO_PULLDOWN_EN + offset) & (~BIT(pin)));	/*disable pulldown*/
 }
 
 static void io_cfg_option5(enum tls_io_name name)
@@ -115,6 +123,8 @@ static void io_cfg_option5(enum tls_io_name name)
     }
 
     tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) & (~BIT(pin)));  /* disable gpio function */
+	tls_reg_write32(HR_GPIO_PULLUP_EN + offset, tls_reg_read32(HR_GPIO_PULLUP_EN + offset) | (BIT(pin))); /*disable pullup*/
+	tls_reg_write32(HR_GPIO_PULLDOWN_EN + offset, tls_reg_read32(HR_GPIO_PULLDOWN_EN + offset) & (~BIT(pin)));	/*disable pulldown*/
 }
 
 static u32 io_pa_option67 = 0;
@@ -139,8 +149,8 @@ static void io_cfg_option6(enum tls_io_name name)
 
     tls_reg_write32(HR_GPIO_AF_SEL  + offset, tls_reg_read32(HR_GPIO_AF_SEL  + offset) & (~BIT(pin)));  /* disable gpio function */
     tls_reg_write32(HR_GPIO_DIR     + offset, tls_reg_read32(HR_GPIO_DIR     + offset) & (~BIT(pin)));
-	tls_reg_write32(HR_GPIO_PULLUP_EN + offset, tls_reg_read32(HR_GPIO_PULLUP_EN + offset) | (BIT(pin)));
-	tls_reg_write32(HR_GPIO_PULLDOWN_EN + offset, tls_reg_read32(HR_GPIO_PULLDOWN_EN + offset) & (~BIT(pin)));	
+	tls_reg_write32(HR_GPIO_PULLUP_EN + offset, tls_reg_read32(HR_GPIO_PULLUP_EN + offset) | (BIT(pin))); /*disable pullup*/
+	tls_reg_write32(HR_GPIO_PULLDOWN_EN + offset, tls_reg_read32(HR_GPIO_PULLDOWN_EN + offset) & (~BIT(pin)));	/*disable pulldown*/
 }
 
 static void io_cfg_option7(enum tls_io_name name)

+ 0 - 2
platform/drivers/lcd/wm_lcd.c

@@ -93,5 +93,3 @@ void tls_lcd_init(tls_lcd_options_t *opts)
 	TLS_LCD_POWERDOWM(1);
 }
 
-
-

+ 30 - 20
platform/drivers/sdio_host/wm_sdio_host.c

@@ -88,10 +88,11 @@ int wm_sdh_config(void)
 
 	tls_sys_clk_get(&sysclk);
 	SDIO_HOST->MMC_CARDSEL = 0xC0 | (sysclk.cpuclk / 2 - 1);//0xd3; //enable module, enable mmcclk
-	SDIO_HOST->MMC_CTL = 0xD3;//0xC3; //4bits, low speed, 1/4 divider, auto transfer, mmc mode.
+	SDIO_HOST->MMC_CTL = 0x13;//0xC3; //4bits, low speed, 1/4 divider, auto transfer, mmc mode.
 	SDIO_HOST->MMC_INT_MASK = 0x100; //unmask sdio data interrupt.
 	SDIO_HOST->MMC_CRCCTL = 0xC0; //
 	SDIO_HOST->MMC_TIMEOUTCNT = 0xff;
+	SDIO_HOST->MMC_IO_MBCTL |= 0xf0;
 	return 0;
 }
 
@@ -113,10 +114,14 @@ int wm_sd_card_initialize(uint32_t *rca)
 	// CMD 3  Get RCA.
 	//======================================================
 begin:
-	wm_sdh_send_cmd(0, 0, 0x04); //Send CMD0
-	sm_sdh_wait_interrupt(0, -1);
+	//Send CMD0 + 8 null clock to reset and stablize
+	for (int i = 0; i < 7 - recnt; i++)
+	{
+		wm_sdh_send_cmd(0, 0, 0x84);
+		sm_sdh_wait_interrupt(0, -1);
+	}
 	delay_cnt(1000);
-	wm_sdh_send_cmd(8, 0x1AA, 0x44); //Send CMD8
+	wm_sdh_send_cmd(8, 0x1AA, 0xC4); //Send CMD8
 	sm_sdh_wait_interrupt(0, -1);
 	wm_sdh_get_response(respCmd, 2);
 	sh_dumpBuffer("CMD8 respCmd", (char *)respCmd, 5);
@@ -129,14 +134,14 @@ begin:
 	}
 	while(1)
 	{
-		wm_sdh_send_cmd(55, 0, 0x44); //Send CMD55
+		wm_sdh_send_cmd(55, 0, 0xC4); //Send CMD55
 		sm_sdh_wait_interrupt(0, -1);
 		wm_sdh_get_response(respCmd, 2);
 		sh_dumpBuffer("CMD55 respCmd", (char *)respCmd, 5);
 		if((respCmd[1] & 0xFF) != 55)
 			goto end;
 
-		wm_sdh_send_cmd(41, 0xC0100000, 0x44); //Send ACMD41
+		wm_sdh_send_cmd(41, 0xC0100000, 0xC4); //Send ACMD41
 		sm_sdh_wait_interrupt(0, -1);
 		sm_sdh_wait_interrupt(3, 1000); //由于sd规范中,Acmd41返回的crc永远是11111,也就是应该忽略crc;这里的crc错误应该忽略。
 		wm_sdh_get_response(respCmd, 2);
@@ -150,14 +155,14 @@ begin:
 		}
 	}
 
-	wm_sdh_send_cmd(2, 0, 0x54); //Send CMD2
+	wm_sdh_send_cmd(2, 0, 0xD4); //Send CMD2
 	sm_sdh_wait_interrupt(0, -1);
 	sm_sdh_wait_interrupt(3, 1000);
 	wm_sdh_get_response(respCmd, 4);
 	sh_dumpBuffer("CMD2 respCmd", (char *)respCmd, 16);
 	if((respCmd[3] >> 24 & 0xFF) != 0x3F) //sd规范定义固定为0x3F,所以导致crc错误
 		goto end;
-	wm_sdh_send_cmd(3, 0, 0x44); //Send CMD3
+	wm_sdh_send_cmd(3, 0, 0xC4); //Send CMD3
 	sm_sdh_wait_interrupt(0, -1);
 	wm_sdh_get_response(respCmd, 2);
 	sh_dumpBuffer("CMD3 respCmd", (char *)respCmd, 5);
@@ -179,6 +184,7 @@ static uint32_t SD_GetCapacity(uint8_t *csd, SD_CardInfo_t *SDCardInfo)
 
   if((csd[0]&0xC0)==0x40)//判断bit126是否为1
   { 
+	SDCardInfo->CSDVer = 2;
     csize = csd[9] + ((uint32_t)csd[8] << 8) + ((uint32_t)(csd[7] & 63) << 16) + 1;
     Capacity = csize << 9;
 	SDCardInfo->CardCapacity = (long long)Capacity*1024;
@@ -186,6 +192,7 @@ static uint32_t SD_GetCapacity(uint8_t *csd, SD_CardInfo_t *SDCardInfo)
   }
   else
   { 
+	SDCardInfo->CSDVer = 1;
     n = (csd[5] & 0x0F) + ((csd[10] & 0x80) >> 7) + ((csd[9] & 0x03) << 1) + 2;
     csize = (csd[8] >> 6) + ((uint16_t)csd[7] << 2) + ((uint16_t)(csd[6] & 0x03) << 10) + 1;
     Capacity = (uint32_t)csize << (n - 10);
@@ -219,7 +226,7 @@ int wm_sd_card_set_blocklen(uint32_t blocklen)
 {
 	int ret = -1;
 	uint32_t respCmd[2];
-	wm_sdh_send_cmd(16, blocklen, 0x44); //Send CMD16
+	wm_sdh_send_cmd(16, blocklen, 0xC4); //Send CMD16
 	sm_sdh_wait_interrupt(0, -1);
 	wm_sdh_get_response(respCmd, 2);
 	sh_dumpBuffer("CMD16 respCmd", (char *)respCmd, 5);
@@ -234,7 +241,7 @@ int wm_sd_card_select(uint32_t rca)
 {
 	int ret = -1;
 	uint32_t respCmd[2];
-	wm_sdh_send_cmd(7, rca<<16, 0x44); //Send CMD7
+	wm_sdh_send_cmd(7, rca<<16, 0xC4); //Send CMD7
 	sm_sdh_wait_interrupt(0, -1);
 	wm_sdh_get_response(respCmd, 2);
 	sh_dumpBuffer("CMD7 respCmd", (char *)respCmd, 5);
@@ -247,7 +254,7 @@ end:
 
 void wm_sd_card_deselect()
 {
-	wm_sdh_send_cmd(7, 0, 0x04); //Send CMD7
+	wm_sdh_send_cmd(7, 0, 0x84); //Send CMD7
 	sm_sdh_wait_interrupt(0, -1);
 }
 
@@ -259,7 +266,7 @@ int wm_sd_card_query_status(uint32_t rca, uint32_t *respCmd0)
 	uint8_t error_state = 0;
 #endif	
 	uint32_t respCmd[2];
-	wm_sdh_send_cmd(13, rca<<16, 0x44); //Send CMD13
+	wm_sdh_send_cmd(13, rca<<16, 0xC4); //Send CMD13
 	sm_sdh_wait_interrupt(0, -1);
 	wm_sdh_get_response(respCmd, 2);
 	sh_dumpBuffer("CMD13 respCmd", (char *)respCmd, 5);
@@ -288,7 +295,7 @@ int wm_sd_card_switch_func(uint8_t speed_mode)
 	int i;
 	uint32_t respCmd[2];
 
-	wm_sdh_send_cmd(6, 0x00fffff1, 0x44); //Send CMD6
+	wm_sdh_send_cmd(6, 0x00fffff1, 0xC4); //Send CMD6
 	sm_sdh_wait_interrupt(0, -1);
 	wm_sdh_get_response(respCmd, 2);
 	sh_dumpBuffer("CMD6 respCmd", (char *)respCmd, 5);
@@ -296,7 +303,7 @@ int wm_sd_card_switch_func(uint8_t speed_mode)
 		goto end;
 	SDIO_HOST->BUF_CTL = 0x4020; //disable dma, read sd card
 	SDIO_HOST->MMC_INT_SRC |= 0x7ff; // clear all firstly
-	SDIO_HOST->MMC_IO  = 0x3;   //!!!read data, auto transfer
+	SDIO_HOST->MMC_IO  = 0x83;   //!!!read data, auto transfer
 	sm_sdh_wait_interrupt(1, -1);
 	TEST_DEBUG("read complete\n");
 	for(i = 0; i < 128; i++)
@@ -315,7 +322,7 @@ int wm_sd_card_switch_func(uint8_t speed_mode)
 	TEST_DEBUG("the value of byte 17~20 is 0x%x\n", respCmd[1]);
 	if(respCmd[1] & 0xF) //support high speed
 	{
-		wm_sdh_send_cmd(6, 0x80fffff0 | speed_mode, 0x44); //Send CMD6
+		wm_sdh_send_cmd(6, 0x80fffff0 | speed_mode, 0xC4); //Send CMD6
 		sm_sdh_wait_interrupt(0, -1);
 		wm_sdh_get_response(respCmd, 2);
 		sh_dumpBuffer("CMD6 respCmd", (char *)respCmd, 5);
@@ -323,7 +330,7 @@ int wm_sd_card_switch_func(uint8_t speed_mode)
 			goto end;
 		SDIO_HOST->BUF_CTL = 0x4020; //disable dma, read sd card
 		SDIO_HOST->MMC_INT_SRC |= 0x7ff; // clear all firstly
-		SDIO_HOST->MMC_IO  = 0x3;   //!!!read data, auto transfer
+		SDIO_HOST->MMC_IO  = 0x83;   //!!!read data, auto transfer
 		sm_sdh_wait_interrupt(1, -1);
 		TEST_DEBUG("read complete\n");
 		for(i = 0; i < 128; i++)
@@ -378,13 +385,13 @@ int wm_sd_card_set_bus_width(uint32_t rca, uint8_t bus_width)
 	{
 		SDIO_HOST->MMC_CTL &= ~(1 << 7);
 	}
-	wm_sdh_send_cmd(55, rca<<16, 0x44); //Send CMD55
+	wm_sdh_send_cmd(55, rca<<16, 0xC4); //Send CMD55
 	sm_sdh_wait_interrupt(0, -1);
 	wm_sdh_get_response(respCmd, 2);
 	sh_dumpBuffer("CMD55 respCmd", (char *)respCmd, 5);
 	if((respCmd[1] & 0xFF) != 55)
 		goto end;
-	wm_sdh_send_cmd(6, bus_width, 0x44); //Send ACMD6
+	wm_sdh_send_cmd(6, bus_width, 0xC4); //Send ACMD6
 	sm_sdh_wait_interrupt(0, -1);
 	wm_sdh_get_response(respCmd, 2);
 	sh_dumpBuffer("ACMD6 respCmd", (char *)respCmd, 5);
@@ -399,7 +406,7 @@ int wm_sd_card_stop_trans(void)
 {
 	int ret = -1;
 	uint32_t respCmd[2];
-	wm_sdh_send_cmd(12, 0, 0x44); //Send CMD12
+	wm_sdh_send_cmd(12, 0, 0xC4); //Send CMD12
 	ret = sm_sdh_wait_interrupt(0, -1);
 	if(ret)
 		goto end;
@@ -415,7 +422,7 @@ end:
 static void sdio_host_reset(void)
 {
 	tls_bitband_write(HR_CLK_RST_CTL, 27, 0);
-
+	delay_cnt(1000);
 	tls_bitband_write(HR_CLK_RST_CTL, 27, 1);
 	while(tls_bitband_read(HR_CLK_RST_CTL, 27) == 0);
 }
@@ -431,6 +438,7 @@ int sdh_card_init(uint32_t *rca_ref)
 	ret = wm_sd_card_initialize(&rca);
 	if(ret)
 		goto end;
+	SDCardInfo.RCA = (u16)(rca & 0xFFFF);
 	ret = wm_sd_card_query_csd(rca);
 	if(ret)
 		goto end;
@@ -444,6 +452,8 @@ int sdh_card_init(uint32_t *rca_ref)
 	if(ret)
 		goto end;
 	*rca_ref = rca;
+
+	SDIO_HOST->MMC_CTL = 0xD3;
 	ret = 0;
 end:
 	TEST_DEBUG("ret %d\n", ret);

+ 117 - 3
platform/drivers/touchsensor/wm_touchsensor.c

@@ -32,9 +32,19 @@ touchsensor_cb tc_callback = NULL;
 int tls_touchsensor_init_config(u32 sensorno, u8 scan_period, u8 window, u32 enable)
 {
 	u32 regval = 0;
+#if 0
+	/*cfg touch bias*/
+	regval = tls_reg_read32(HR_PMU_WLAN_STTS);
+	regval &=~(0x70);
+	regval |=(0x20);
+	tls_reg_write32(HR_PMU_WLAN_STTS, regval);
+#endif
 
-	regval = tls_reg_read32(HR_TC_CONFIG);
-	if (scan_period >=0x3F)
+	regval = tls_reg_read32(HR_TC_CONFIG);	
+	/*firstly, disable scan function */
+	tls_reg_write32(HR_TC_CONFIG,regval&(~(1<<TOUCH_SENSOR_EN_BIT)));
+
+	if (scan_period <= 0x3F)
 	{
 		regval &= ~(0x3F<<SCAN_PERID_SHIFT_BIT);
 		regval |= (scan_period<<SCAN_PERID_SHIFT_BIT);
@@ -49,7 +59,6 @@ int tls_touchsensor_init_config(u32 sensorno, u8 scan_period, u8 window, u32 ena
 	if (sensorno && (sensorno <= 15))
 	{
 		regval |= (1<<(sensorno-1+TOUCH_SENSOR_SEL_SHIFT_BIT));
-
 	}
 
 	if (enable)
@@ -62,6 +71,111 @@ int tls_touchsensor_init_config(u32 sensorno, u8 scan_period, u8 window, u32 ena
 	return 0;
 }
 
+/**
+ * @brief          This function is used to initialize touch scan channel.
+ *
+ * @param[in]      sensorno    is the touch sensor number from 1-15
+ *
+ * @retval         0:success
+ *
+ * @note           if use touch sensor, user must configure the IO multiplex by API wm_touch_sensor_config.
+ */
+int tls_touchsensor_chan_config(u32 sensorno)
+{
+	u32 regval = 0;
+
+	regval = tls_reg_read32(HR_TC_CONFIG);	
+	if (sensorno && (sensorno <= 15))
+	{
+		regval |= (1<<(sensorno-1+TOUCH_SENSOR_SEL_SHIFT_BIT));
+	}
+	
+	tls_reg_write32(HR_TC_CONFIG,regval);
+
+	return 0;
+}
+
+/**
+ * @brief          This function is used to initialize touch general configuration.
+ *
+ * @param[in]      scanperiod  is scan period for per touch sensor ,unit:16ms, >0
+ * @param[in]      window      is count window, window must be greater than 2.Real count window is window - 2.
+ * @param[in]      bias        is touch sensor bias current
+ *
+ * @retval         0:success
+ *
+ * @note           if use touch sensor, user must configure the IO multiplex by API wm_touch_sensor_config.
+ */
+int tls_touchsensor_scan_config(u8 scanperiod, u8 window, u8 bias)
+{
+	u32 regval = 0;
+
+	regval = tls_reg_read32(HR_PMU_WLAN_STTS);
+	if (bias <= 7)
+	{
+		regval &=~(0x70);
+		regval |=(bias<<4);
+	}
+	else
+	{
+		regval &=~(0x70);
+		regval |=(0x4<<4);
+	}
+	tls_reg_write32(HR_PMU_WLAN_STTS, regval);
+	
+	regval = tls_reg_read32(HR_TC_CONFIG);	
+	if (scanperiod <= 0x3F)
+	{
+		regval &= ~(0x3F<<SCAN_PERID_SHIFT_BIT);
+		regval |= (scanperiod<<SCAN_PERID_SHIFT_BIT);
+	}
+
+	if (window)
+	{
+		regval &= ~(0x3F<<CAPDET_CNT_SHIFT_BIT);
+		regval |= (window<<CAPDET_CNT_SHIFT_BIT);
+	}
+	tls_reg_write32(HR_TC_CONFIG,regval);
+
+	return 0;
+}
+
+/**
+ * @brief          This function is used to start touch scan
+ *
+ * @retval         0:success
+ *
+ * @note           if use touch sensor, user must configure the IO multiplex by API wm_touch_sensor_config.
+ */
+int tls_touchsensor_scan_start(void)
+{
+	u32 regval = 0;
+
+	regval = tls_reg_read32(HR_TC_CONFIG);	
+	regval |= (1<<TOUCH_SENSOR_EN_BIT);
+	tls_reg_write32(HR_TC_CONFIG,regval);
+
+	return 0;
+}
+
+/**
+ * @brief          This function is used to stop touch scan
+ *
+ * @retval         0:success
+ *
+ * @note           if use touch sensor, user must configure the IO multiplex by API wm_touch_sensor_config.
+ */
+int tls_touchsensor_scan_stop(void)
+{
+	u32 regval = 0;
+
+	regval = tls_reg_read32(HR_TC_CONFIG);	
+	regval &= ~(1<<TOUCH_SENSOR_EN_BIT);
+	tls_reg_write32(HR_TC_CONFIG,regval);
+
+	return 0;
+}
+
 /**
  * @brief          This function is used to deinit touch sensor's selection and disable touch.
  *

+ 1 - 0
platform/inc/tls_wireless.h

@@ -419,6 +419,7 @@ int tls_wl_if_sta_add(struct tls_wif *wif,
 int tls_wl_if_sta_remove(struct tls_wif *wif, u8 *addr);
 int tls_wl_if_get_inact_sec(struct tls_wif *wif, const u8 *addr);
 int tls_wl_if_get_scan_res(struct tls_wif *wif, u8 *buf, u32 buf_size);
+int tls_wl_if_get_scan_res_format2(struct tls_wif *wif, u8 *buf, u32 buf_size);
 int tls_wl_if_disconnect(struct tls_wif *wif);
 int tls_wl_if_tx(struct tls_wif *wif,
         u8 *buf, u32 buflen, bool last_packet, bool is_apsta, bool not_delay);

+ 2 - 0
platform/inc/utils.h

@@ -35,5 +35,7 @@ char * strdup(const char *s);
 char * strndup(const char *s, size_t len);
 
 int sendchar(int ch);
+void dumpBuffer(char *name, char* buffer, int len);
+void dumpUint32(char *name, u32* buffer, int len);
 
 #endif /* UTILS_H */

+ 457 - 356
src/app/bleapp/wm_ble_client_api_demo.c

@@ -20,14 +20,16 @@
 #include "wm_ble_gap.h"
 #include "wm_ble_uart_if.h"
 #include "wm_ble_client_util.h"
+#include "wm_ble_client_api_demo.h"
 
 
 
 #define WM_BLE_SERVER_SVC_UUID              0xFFF0
 #define WM_BLE_SERVER_CHR_INDICATE          0xFFF1
 #define WM_BLE_SERVER_CHR_WRITE             0xFFF2
+#define WM_BLE_SERVER_CHR_READ              0xFFF3
 
-typedef enum{
+typedef enum {
     BLE_CLIENT_MODE_IDLE     = 0x00,
     BLE_CLIENT_MODE_SCANNING = 0x01,
     BLE_CLIENT_MODE_CONNECTING,
@@ -36,12 +38,13 @@ typedef enum{
     BLE_CLIENT_MODE_SUBSCRIBED,
     BLE_CLIENT_MODE_EXITING
 } ble_client_state_t;
-
+static struct ble_gap_event_listener ble_client_event_listener;
 static uint16_t g_ble_client_conn_handle = 0;
 static uint8_t g_ble_client_state = BLE_CLIENT_MODE_IDLE;
-static tls_ble_output_func_ptr g_ble_uart_output_fptr = NULL;
 static volatile uint8_t g_send_pending = 0;
 static int g_mtu = 20;
+static tls_ble_uart_output_ptr g_uart_output_ptr = NULL; 
+static tls_ble_uart_sent_ptr g_uart_in_and_sent_ptr = NULL;
 
 
 static int ble_gap_evt_cb(struct ble_gap_event *event, void *arg);
@@ -54,49 +57,29 @@ static int ble_gap_evt_cb(struct ble_gap_event *event, void *arg);
  */
 static int
 wm_ble_client_demo_on_write(uint16_t conn_handle,
-                 const struct ble_gatt_error *error,
-                 struct ble_gatt_attr *attr,
-                 void *arg)
+                            const struct ble_gatt_error *error,
+                            struct ble_gatt_attr *attr,
+                            void *arg)
 {
-#if 0
-    MODLOG_DFLT(INFO,
-                "Write complete; status=%d conn_handle=%d attr_handle=%d\n",
+#if 1
+    TLS_BT_APPL_TRACE_DEBUG("Write complete; status=%d conn_handle=%d attr_handle=%d\n",
                 error->status, conn_handle, attr->handle);
 #endif
-    int len = 0;
-    int rc;
-    uint8_t tmp_buf[256];
 
+    int rc = 0;
     g_send_pending = 0;
 
-    if(g_ble_uart_output_fptr)
-    {
-        len = tls_ble_uart_buffer_size();
+    if(error->status != 0) goto err;
 
-        len = MIN(len, g_mtu);
-
-        if(len)
-        {
-            tls_ble_uart_buffer_peek(tmp_buf, len);
-            
-            rc = ble_gattc_write_flat(conn_handle, attr->handle,
-                              tmp_buf, len, wm_ble_client_demo_on_write, NULL);
-            if(rc == 0)
-            {
-                g_send_pending = 1;
-                tls_ble_uart_buffer_delete(len);
-            }else
-            {
-                 TLS_BT_APPL_TRACE_ERROR("Error: Failed to subscribe to characteristic; rc=%d\n", rc);
-                 goto err;    
-            }
-        }
+    if(g_uart_in_and_sent_ptr) {
+        g_uart_in_and_sent_ptr(BLE_UART_CLIENT_MODE, error->status);
     }
 
     return 0;
 err:
     /* Terminate the connection. */
-    ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);    
+    ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
+    return rc;
 }
 
 /**
@@ -105,38 +88,33 @@ err:
  */
 static int
 wm_ble_client_demo_on_subscribe(uint16_t conn_handle,
-                     const struct ble_gatt_error *error,
-                     struct ble_gatt_attr *attr,
-                     void *arg)
+                                const struct ble_gatt_error *error,
+                                struct ble_gatt_attr *attr,
+                                void *arg)
 {
     TLS_BT_APPL_TRACE_DEBUG("Subscribe complete; status=%d conn_handle=%d attr_handle=%d\r\n",
-                error->status, conn_handle, attr->handle);
-    if(error->status == 0)
-    {
-        if(g_ble_client_state == BLE_CLIENT_MODE_SUBSCRIBING)
-        {
+                            error->status, conn_handle, attr->handle);
+
+    if(error->status == 0) {
+        if(g_ble_client_state == BLE_CLIENT_MODE_SUBSCRIBING) {
             g_ble_client_state = BLE_CLIENT_MODE_SUBSCRIBED;
-        }else if(g_ble_client_state == BLE_CLIENT_MODE_EXITING)
-        {
-            TLS_BT_APPL_TRACE_DEBUG("Terminate the connection now...\r\n");
+        } else if(g_ble_client_state == BLE_CLIENT_MODE_EXITING) {
+            TLS_BT_APPL_TRACE_DEBUG("Terminate the connection by closing client\r\n");
             ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
         }
-    }else
-    {
+    } else {
         TLS_BT_APPL_TRACE_DEBUG("Terminate the connection now by subscribe failed , next to disconnect and scanning...\r\n");
-        ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM); 
+        ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
     }
 
     return 0;
 }
-static void
+static int
 wm_ble_client_demo_cancel_subscribe(const struct peer *peer)
 {
-    const struct peer_chr *chr;
     const struct peer_dsc *dsc;
     uint8_t value[2];
-    int rc; 
-
+    int rc;
     /* Subscribe to indifications for the Specified characteristic[0xFFF1].
      * A central disables indications by writing two bytes (0, 0) to the
      * characteristic's client-characteristic-configuration-descriptor (CCCD).
@@ -145,7 +123,8 @@ wm_ble_client_demo_cancel_subscribe(const struct peer *peer)
                              BLE_UUID16_DECLARE(WM_BLE_SERVER_SVC_UUID),
                              BLE_UUID16_DECLARE(WM_BLE_SERVER_CHR_INDICATE),
                              BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_CFG_UUID16));
-    if (dsc == NULL) {
+
+    if(dsc == NULL) {
         TLS_BT_APPL_TRACE_ERROR("Error: Peer lacks a CCCD for the 0xFFF1 characteristic\n");
         goto err;
     }
@@ -154,16 +133,17 @@ wm_ble_client_demo_cancel_subscribe(const struct peer *peer)
     value[1] = 0;
     rc = ble_gattc_write_flat(peer->conn_handle, dsc->dsc.handle,
                               value, sizeof value, wm_ble_client_demo_on_subscribe, NULL);
-    if (rc != 0) {
+
+    if(rc != 0) {
         TLS_BT_APPL_TRACE_ERROR("Error: Failed to subscribe to characteristic;rc=%d\n", rc);
         goto err;
     }
 
-    return;
-
+    return rc;
 err:
     /* Terminate the connection. */
-    ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);    
+    ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
+    return rc;
 }
 /**
  * Performs three concurrent GATT operations against the specified peer:
@@ -176,31 +156,31 @@ err:
  * notification service!  When this happens, or if a GATT procedure fails,
  * this function immediately terminates the connection.
  */
+
 static void
 wm_ble_client_demo_read_write_subscribe(const struct peer *peer)
 {
     const struct peer_chr *chr;
     const struct peer_dsc *dsc;
-    uint8_t value[2];
+    uint8_t value[] = {'H','e', '1','l','o', ',', 'B', 'L', 'E', '!', 0x0A};
     int rc;
-    
-    /* Write two bytes (0xAA, 0xBB) tothe Specified characteristic[0xFFF2].
+    /* Write two bytes (0xAA, 0xBB) tothe Specified characteristic[WM_BLE_SERVER_CHR_WRITE].
      */
     chr = peer_chr_find_uuid(peer,
                              BLE_UUID16_DECLARE(WM_BLE_SERVER_SVC_UUID),
                              BLE_UUID16_DECLARE(WM_BLE_SERVER_CHR_WRITE));
-    if (chr == NULL) {
-        TLS_BT_APPL_TRACE_ERROR("Error: Peer doesn't support 0xFFF2 Control Point characteristic\n");
+
+    if(chr == NULL) {
+        TLS_BT_APPL_TRACE_ERROR("Error: Peer doesn't support 0x%04x Control Point characteristic\r\n",WM_BLE_SERVER_CHR_WRITE);
         goto err;
     }
 
-    value[0] = 0xAA;
-    value[1] = 0xBB;
     rc = ble_gattc_write_flat(peer->conn_handle, chr->chr.val_handle,
                               value, sizeof value, wm_ble_client_demo_on_write, NULL);
-    if (rc != 0) {
+
+    if(rc != 0) {
         TLS_BT_APPL_TRACE_ERROR("Error: Failed to write characteristic; rc=%d\n",
-                    rc);
+                                rc);
     }
 
     /* Subscribe to indifications for the Specified characteristic[0xFFF1].
@@ -211,25 +191,24 @@ wm_ble_client_demo_read_write_subscribe(const struct peer *peer)
                              BLE_UUID16_DECLARE(WM_BLE_SERVER_SVC_UUID),
                              BLE_UUID16_DECLARE(WM_BLE_SERVER_CHR_INDICATE),
                              BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_CFG_UUID16));
-    if (dsc == NULL) {
-        TLS_BT_APPL_TRACE_ERROR("Error: Peer lacks a CCCD for the 0xFFF1 characteristic\n");
+
+    if(dsc == NULL) {
+        TLS_BT_APPL_TRACE_ERROR("Error: Peer lacks a CCCD for the 0x%04x characteristic\r\n",WM_BLE_SERVER_CHR_INDICATE);
         goto err;
     }
-
     value[0] = 2;
     value[1] = 0;
     rc = ble_gattc_write_flat(peer->conn_handle, dsc->dsc.handle,
-                              value, sizeof value, wm_ble_client_demo_on_subscribe, NULL);
-    if (rc != 0) {
+                              value, 2, wm_ble_client_demo_on_subscribe, NULL);
+
+    if(rc != 0) {
         TLS_BT_APPL_TRACE_ERROR("Error: Failed to subscribe to characteristic;rc=%d\n", rc);
         goto err;
-    }else
-    {
+    } else {
         g_ble_client_state = BLE_CLIENT_MODE_SUBSCRIBING;
     }
 
     return;
-
 err:
     /* Terminate the connection. */
     ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
@@ -237,53 +216,50 @@ err:
 
 static int
 wm_ble_client_demo_on_mtu(uint16_t conn_handle, const struct ble_gatt_error *error,
-               uint16_t mtu, void *arg)
+                          uint16_t mtu, void *arg)
 {
-    switch (error->status) {
-    case 0:
-        TLS_BT_APPL_TRACE_DEBUG("mtu exchange complete: conn_handle=%d mtu=%d\r\n",
-                       conn_handle, mtu);
-        g_mtu = mtu -3;
-        break;
-
-    default:
-        TLS_BT_APPL_TRACE_ERROR("Update MTU failed...\r\n");
-        break;
+    switch(error->status) {
+        case 0:
+            TLS_BT_APPL_TRACE_DEBUG("mtu exchange complete: conn_handle=%d mtu=%d\r\n",
+                                    conn_handle, mtu);
+            g_mtu = mtu - 3;
+            break;
+
+        default:
+            TLS_BT_APPL_TRACE_ERROR("Update MTU failed...error->status=%d\r\n", error->status);
+            break;
     }
 
     return 0;
 }
 
 /**
- * Called when service discovery of the specified peer has completed.
- */
+* Called when service discovery of the specified peer has completed.
+*/
 static void
 wm_ble_client_demo_on_disc_complete(const struct peer *peer, int status, void *arg)
 {
-
-    if (status != 0) {
-        /* Service discovery failed.  Terminate the connection. */
-        TLS_BT_APPL_TRACE_ERROR("Error: Service discovery failed; status=%d conn_handle=%d,state=%d\n", status, peer->conn_handle,g_ble_client_state);
-        ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
-        return;
-    }
-
-    /* Service discovery has completed successfully.  Now we have a complete
-     * list of services, characteristics, and descriptors that the peer
-     * supports.
-     */
-    TLS_BT_APPL_TRACE_DEBUG("Service discovery complete; status=%d conn_handle=%d\n", status, peer->conn_handle);
-    ble_gattc_exchange_mtu(peer->conn_handle, wm_ble_client_demo_on_mtu, NULL);
-
-    /* Now perform three concurrent GATT procedures against the peer: read,
-     * write, and subscribe to notifications.
-     */
-    
-    wm_ble_client_demo_read_write_subscribe(peer);
+  if(status != 0) {
+      /* Service discovery failed.  Terminate the connection. */
+      TLS_BT_APPL_TRACE_ERROR("Error: Service discovery failed; status=%d conn_handle=%d,state=%d\n",
+                              status, peer->conn_handle, g_ble_client_state);
+      ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
+      return;
+  }
+  ble_gattc_exchange_mtu(g_ble_client_conn_handle, wm_ble_client_demo_on_mtu, NULL);
+
+  /* Service discovery has completed successfully.  Now we have a complete
+   * list of services, characteristics, and descriptors that the peer
+   * supports.
+   */
+  TLS_BT_APPL_TRACE_DEBUG("Service discovery complete; status=%d conn_handle=%d\n", status,
+                          peer->conn_handle);
+  /* Now perform three concurrent GATT procedures against the peer: read,
+   * write, and subscribe to notifications.
+   */
+  wm_ble_client_demo_read_write_subscribe(peer);
 }
 
-
-
 /**
  * Indicates whether we should tre to connect to the sender of the specified
  * advertisement.  The function returns a positive result if the device
@@ -297,22 +273,22 @@ wm_ble_client_demo_should_connect(const struct ble_gap_disc_desc *disc)
     int i;
 
     /* The device has to be advertising connectability. */
-    if (disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
-        disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
-
+    if(disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
+            disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
         return 0;
     }
 
     rc = ble_hs_adv_parse_fields(&fields, disc->data, disc->length_data);
-    if (rc != 0) {
+
+    if(rc != 0) {
         return rc;
     }
 
     /* The device has to advertise support for the Alert Notification
-     * service (0xFFF0).
+     * service (WM_BLE_SERVER_SVC_UUID).
      */
-    for (i = 0; i < fields.num_uuids16; i++) {
-        if (ble_uuid_u16(&fields.uuids16[i].u) == WM_BLE_SERVER_SVC_UUID) {
+    for(i = 0; i < fields.num_uuids16; i++) {
+        if(ble_uuid_u16(&fields.uuids16[i].u) == WM_BLE_SERVER_SVC_UUID) {
             return 1;
         }
     }
@@ -332,15 +308,15 @@ wm_ble_client_demo_connect_if_interesting(const struct ble_gap_disc_desc *disc)
     struct ble_gap_conn_params conn_params;
 
     /* Don't do anything if we don't care about this advertiser. */
-    if (!wm_ble_client_demo_should_connect(disc)) {
+    if(!wm_ble_client_demo_should_connect(disc)) {
         return;
     }
 
     g_ble_client_state = BLE_CLIENT_MODE_CONNECTING; //preset this flag
-    
     /* Scanning must be stopped before a connection can be initiated. */
     rc = tls_ble_gap_scan(WM_BLE_SCAN_STOP, 0);
-    if (rc != 0) {
+
+    if(rc != 0) {
         TLS_BT_APPL_TRACE_ERROR("Failed to cancel scan; rc=%d\n", rc);
         g_ble_client_state = BLE_CLIENT_MODE_SCANNING;
         return;
@@ -353,44 +329,80 @@ wm_ble_client_demo_connect_if_interesting(const struct ble_gap_disc_desc *disc)
     //conn_params.itvl_min = 0x08;
     //conn_params.itvl_max = 0x0C;
     rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &disc->addr, 30000, &conn_params,
-                         ble_gap_evt_cb, NULL);
-    if (rc != 0) {
+                         NULL, NULL);
+
+    if(rc != 0) {
         TLS_BT_APPL_TRACE_ERROR("Error: Failed to connect to device; addr_type=%d "
-                           "addr=%s, continue to scan\n",
-                    disc->addr.type, addr_str(disc->addr.val));
-        rc = tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, 0);
-        if (rc != 0) {
+                                "addr=%s, continue to scan\n",
+                                disc->addr.type, addr_str(disc->addr.val));
+        rc = tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, false);
+
+        if(rc != 0) {
             TLS_BT_APPL_TRACE_ERROR("Failed to start scan when ble_gap_connect failed; rc=%d\n", rc);
             g_ble_client_state = BLE_CLIENT_MODE_IDLE;
             return;
-        }else
-        {
+        } else {
             g_ble_client_state = BLE_CLIENT_MODE_SCANNING;
         }
-        
+
         return;
-    }else
-    {
+    } else {
         g_ble_client_state = BLE_CLIENT_MODE_CONNECTING;
     }
 }
+#define BLE_CLIENT_CONN_PARAM_UPDATE 0
 
+#if BLE_CLIENT_CONN_PARAM_UPDATE
 static void wm_ble_client_demo_conn_param_update_master(u16_t conn_handle)
 {
-	int rc;
-	struct ble_gap_upd_params params;
+    int rc;
+    struct ble_gap_upd_params params;
+    params.itvl_min = 0x0006;
+    params.itvl_max = 0x0016;
+    params.latency = 0;
+    params.supervision_timeout = 500;
+    params.min_ce_len = 16;
+    params.max_ce_len = 328;
+    rc = ble_gap_update_params(conn_handle, &params);
+    assert(rc == 0);
+}
+#endif
+
+
+//#define THROUGHTPUT_TEST
 
-	params.itvl_min = 0x0008;
-	params.itvl_max = 0x000c;
-	params.latency = 0;
-	params.supervision_timeout = 0x07d0;
-	params.min_ce_len = 0;
-	params.max_ce_len = 0;
+#ifdef THROUGHTPUT_TEST
 
-	rc = ble_gap_update_params(conn_handle, &params);
-	assert(rc == 0);
+static uint32_t g_recv_bytes = 0;
+static uint32_t g_time_last = 0;
+
+static uint32_t ticks_elapsed(uint32_t ticks)
+{
+    uint32_t diff_ticks = 0;
+    uint32_t curr_ticks = tls_os_get_time();
+
+    if(curr_ticks >= ticks) {
+        diff_ticks = curr_ticks - ticks;
+    } else {
+        diff_ticks = curr_ticks + (0xFFFFFFFF - ticks);
+    }
+
+    return diff_ticks;
 }
+#endif
 
+static void wm_ble_client_read_service(void *arg)
+{
+	int rc;
+    /* Perform service discovery. */
+    rc = peer_disc_all(g_ble_client_conn_handle,
+               wm_ble_client_demo_on_disc_complete, NULL);
+
+    if(rc != 0) {
+        TLS_BT_APPL_TRACE_ERROR("Failed to discover services; rc=%d\n", rc);
+        ble_gap_terminate(g_ble_client_conn_handle, BLE_ERR_REM_USER_CONN_TERM);
+    }    
+}
 
 /**
  * The nimble host executes this callback when a GAP event occurs.  The
@@ -414,159 +426,210 @@ ble_gap_evt_cb(struct ble_gap_event *event, void *arg)
     struct os_mbuf *om;
     int rc;
 
-    switch (event->type) {
-    case BLE_GAP_EVENT_DISC:
-        rc = ble_hs_adv_parse_fields(&fields, event->disc.data,
-                                     event->disc.length_data);
-        if (rc != 0) {
+    switch(event->type) {
+        case BLE_GAP_EVENT_DISC:
+            rc = ble_hs_adv_parse_fields(&fields, event->disc.data,
+                                         event->disc.length_data);
+
+            if(rc != 0) {
+                return 0;
+            }
+
+            /* Try to connect to the advertiser if it looks interesting. */
+            wm_ble_client_demo_connect_if_interesting(&event->disc);
             return 0;
-        }
 
-        /* Try to connect to the advertiser if it looks interesting. */
-        wm_ble_client_demo_connect_if_interesting(&event->disc);
-        return 0;
+        case BLE_GAP_EVENT_CONNECT:
+
+            /* A new connection was established or a connection attempt failed. */
+            if(event->connect.status == 0) {
+
+                rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
+                assert(rc == 0);
+                print_conn_desc(&desc);
+                MODLOG_DFLT(INFO, "\n");
+
+                if(desc.role != BLE_GAP_ROLE_MASTER)
+                {
+                    return 0;
+                }
+                /* Connection successfully established. */
+                TLS_BT_APPL_TRACE_API("Client Connection established ");                
+                g_ble_client_state = BLE_CLIENT_MODE_CONNECTED;
+                g_ble_client_conn_handle = event->connect.conn_handle;
+#ifdef THROUGHTPUT_TEST
+                g_recv_bytes = 0;
+                g_time_last = tls_os_get_time();
+#endif
+                rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
+                assert(rc == 0);
+                print_conn_desc(&desc);
+                MODLOG_DFLT(INFO, "\n");
+                /* Remember peer. */
+                rc = peer_add(event->connect.conn_handle);
+
+                if(rc != 0) {
+                    TLS_BT_APPL_TRACE_ERROR("Failed to add peer; rc=%d\n", rc);
+                    return 0;
+                }
+                //defer 100ticks, then find service;
+                tls_bt_async_proc_func(wm_ble_client_read_service, NULL, 100);
+
+                //ble_gattc_exchange_mtu(event->connect.conn_handle, wm_ble_client_demo_on_mtu, NULL);
+                #if BLE_CLIENT_CONN_PARAM_UPDATE
+                wm_ble_client_demo_conn_param_update_master(event->connect.conn_handle);
+                #endif
+            } else {
+                /* Connection attempt failed; resume scanning. */
+                TLS_BT_APPL_TRACE_ERROR("Error: Connection failed; status=%d\n",
+                                        event->connect.status);
+                //g_ble_client_state = BLE_CLIENT_MODE_IDLE;
+                rc = tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, false);
+
+                if(rc == 0) {
+                    g_ble_client_state = BLE_CLIENT_MODE_SCANNING;
+                }
+            }
 
-    case BLE_GAP_EVENT_CONNECT:
-        /* A new connection was established or a connection attempt failed. */
-        if (event->connect.status == 0) {
-            /* Connection successfully established. */
-            TLS_BT_APPL_TRACE_API("Connection established ");
-            g_ble_client_state = BLE_CLIENT_MODE_CONNECTED;
-            g_ble_client_conn_handle = event->connect.conn_handle;
+            return 0;
 
-            rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
-            assert(rc == 0);
-            print_conn_desc(&desc);
+        case BLE_GAP_EVENT_DISCONNECT:
+            
+            if(event->disconnect.conn.role != BLE_GAP_ROLE_MASTER) return 0;
+            /* Connection terminated. */
+            TLS_BT_APPL_TRACE_API("Client disconnect[state=%d]; reason=%d 0x%02x ", g_ble_client_state,event->disconnect.reason,event->disconnect.reason - 0x200);
+            print_conn_desc(&event->disconnect.conn);
             MODLOG_DFLT(INFO, "\n");
+            /* Forget about peer. */
+            rc = peer_delete(event->disconnect.conn.conn_handle);
 
-            /* Remember peer. */
-            rc = peer_add(event->connect.conn_handle);
-            if (rc != 0) {
-                TLS_BT_APPL_TRACE_ERROR("Failed to add peer; rc=%d\n", rc);
-                return 0;
+            if(rc != 0) {
+                TLS_BT_APPL_TRACE_WARNING("peer_delete (conn_handle=%d), rc=%d\r\n",
+                                        event->disconnect.conn.conn_handle,rc);
             }
 
-            /* Perform service discovery. */
-            rc = peer_disc_all(event->connect.conn_handle,
-                               wm_ble_client_demo_on_disc_complete, NULL);
-            if (rc != 0) {
-                TLS_BT_APPL_TRACE_ERROR("Failed to discover services; rc=%d\n", rc);
-                return 0;
-            }
-        } else {
-            /* Connection attempt failed; resume scanning. */
-            TLS_BT_APPL_TRACE_ERROR("Error: Connection failed; status=%d\n",
-                        event->connect.status);
-            //g_ble_client_state = BLE_CLIENT_MODE_IDLE;
-            
-            rc = tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, true);
-            if(rc == 0)
-            {
-               g_ble_client_state = BLE_CLIENT_MODE_SCANNING; 
+            /* Resume scanning. If the termination is not issued by local host */
+
+            if(g_ble_client_state == BLE_CLIENT_MODE_EXITING ) {
+                peer_deinit();
+                g_ble_client_state = BLE_CLIENT_MODE_IDLE;
+                g_uart_output_ptr = NULL;
+                g_uart_in_and_sent_ptr = NULL;
+                ble_gap_event_listener_unregister(&ble_client_event_listener);
+            } else {
+                /*check disconnect reason is not trigger by local host*/
+                if(event->disconnect.reason != 534)
+                {
+                    g_ble_client_state = BLE_CLIENT_MODE_SCANNING;
+                    tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, false);
+                }
             }
-        }
 
-        return 0;
-
-    case BLE_GAP_EVENT_DISCONNECT:
-        /* Connection terminated. */
-        TLS_BT_APPL_TRACE_API("disconnect; reason=%d ", event->disconnect.reason);
-        print_conn_desc(&event->disconnect.conn);
-        MODLOG_DFLT(INFO, "\n");
-        
-        /* Forget about peer. */
-        rc = peer_delete(event->disconnect.conn.conn_handle);
-        if(rc != 0)
-        {
-          TLS_BT_APPL_TRACE_ERROR("peer_delete (conn_handle=%d)failed\r\n", event->disconnect.conn.conn_handle);  
-        }
+            return 0;
 
-        /* Resume scanning. If the termination is not issued by local host */
+        case BLE_GAP_EVENT_DISC_COMPLETE:
+            TLS_BT_APPL_TRACE_DEBUG("discovery complete; reason=%d\n",
+                                    event->disc_complete.reason);
 
-        if(g_ble_client_state == BLE_CLIENT_MODE_EXITING)
-        {
-            peer_deinit();
-            g_ble_client_state = BLE_CLIENT_MODE_IDLE;
-            g_ble_uart_output_fptr = NULL;
-        }else
-        {
-            g_ble_client_state = BLE_CLIENT_MODE_SCANNING;
-            tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, true);
-        }
-        
-        return 0;
+            if(g_ble_client_state == BLE_CLIENT_MODE_SCANNING) {
+                g_uart_output_ptr = NULL;
+                g_uart_in_and_sent_ptr = NULL;
+                g_ble_client_state = BLE_CLIENT_MODE_IDLE;
+                TLS_BT_APPL_TRACE_ERROR("Occurs only when limited scanning\r\n");
+            }
 
-    case BLE_GAP_EVENT_DISC_COMPLETE:
-        TLS_BT_APPL_TRACE_DEBUG("discovery complete; reason=%d\n",
-                    event->disc_complete.reason);
-        if(g_ble_client_state == BLE_CLIENT_MODE_SCANNING)
-        {
-            g_ble_uart_output_fptr = NULL; 
-            g_ble_client_state = BLE_CLIENT_MODE_IDLE;
-            TLS_BT_APPL_TRACE_ERROR("Occurs only when limited scanning\r\n");
-        }
-        return 0;
+            return 0;
 
-    case BLE_GAP_EVENT_ENC_CHANGE:
-        /* Encryption has been enabled or disabled for this connection. */
-        TLS_BT_APPL_TRACE_DEBUG("encryption change event; status=%d ",
-                    event->enc_change.status);
-        rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc);
-        assert(rc == 0);
-        print_conn_desc(&desc);
-        return 0;
+        case BLE_GAP_EVENT_ENC_CHANGE:
+            rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc);
+            assert(rc == 0);
+            if(desc.role != BLE_GAP_ROLE_MASTER) return 0;
+            /* Encryption has been enabled or disabled for this connection. */
+            TLS_BT_APPL_TRACE_DEBUG("encryption change event; status=%d ",
+                                    event->enc_change.status);
+            print_conn_desc(&desc);
+            return 0;
 
-    case BLE_GAP_EVENT_NOTIFY_RX:
-        /* Peer sent us a notification or indication. */
-        TLS_BT_APPL_TRACE_DEBUG("received %s; conn_handle=%d attr_handle=%d "
-                          "attr_len=%d\n",
-                    event->notify_rx.indication ?
-                        "indication" :
-                        "notification",
-                    event->notify_rx.conn_handle,
-                    event->notify_rx.attr_handle,
-                    OS_MBUF_PKTLEN(event->notify_rx.om));
-
-        /* Attribute data is contained in event->notify_rx.attr_data. */
-        om = event->notify_rx.om;
-        while (om != NULL) {
-            if(g_ble_uart_output_fptr)
-            {
-                g_ble_uart_output_fptr(om->om_data, om->om_len);
-            }else
-            {
-                print_bytes(om->om_data, om->om_len);
+        case BLE_GAP_EVENT_NOTIFY_RX:
+            rc = ble_gap_conn_find(event->notify_rx.conn_handle, &desc);
+            assert(rc == 0);
+            if(desc.role != BLE_GAP_ROLE_MASTER) return 0;            
+            /* Peer sent us a notification or indication. */
+
+            TLS_BT_APPL_TRACE_VERBOSE("received %s; conn_handle=%d attr_handle=%d "
+                                    "attr_len=%d\n",
+                                    event->notify_rx.indication ?
+                                    "indication" :
+                                    "notification",
+                                    event->notify_rx.conn_handle,
+                                    event->notify_rx.attr_handle,
+                                    OS_MBUF_PKTLEN(event->notify_rx.om));                       
+            /* Attribute data is contained in event->notify_rx.attr_data. */
+            om = event->notify_rx.om;
+
+            while(om != NULL) {
+                if(g_uart_output_ptr) {
+                    g_uart_output_ptr(UART_OUTPUT_DATA, om->om_data, om->om_len);
+                } else {
+                    print_bytes(om->om_data, om->om_len);
+                }
+
+#ifdef THROUGHTPUT_TEST
+                g_recv_bytes += om->om_len;
+#endif
+                om = SLIST_NEXT(om, om_next);
             }
-            om = SLIST_NEXT(om, om_next);
-        }
-        return 0;
 
-    case BLE_GAP_EVENT_MTU:
-        TLS_BT_APPL_TRACE_DEBUG("mtu update event; conn_handle=%d cid=%d mtu=%d\n",
-                    event->mtu.conn_handle,
-                    event->mtu.channel_id,
-                    event->mtu.value);
-        return 0;
+#ifdef THROUGHTPUT_TEST
 
-    case BLE_GAP_EVENT_REPEAT_PAIRING:
-        /* We already have a bond with the peer, but it is attempting to
-         * establish a new secure link.  This app sacrifices security for
-         * convenience: just throw away the old bond and accept the new link.
-         */
+            if(ticks_elapsed(g_time_last) >= HZ) {
+                g_time_last = tls_os_get_time();
+                printf("BLE Recv(%d bytes)[%5.2f Kbps]/s\r\n", g_recv_bytes, (g_recv_bytes * 8.0 / 1024));
+                g_recv_bytes = 0;
+            }
 
-        /* Delete the old bond. */
-        rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
-        assert(rc == 0);
-        ble_store_util_delete_peer(&desc.peer_id_addr);
+#endif
+            return 0;
 
-        /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should
-         * continue with the pairing operation.
-         */
-        return BLE_GAP_REPEAT_PAIRING_RETRY;
+        case BLE_GAP_EVENT_MTU:
+            rc = ble_gap_conn_find(event->mtu.conn_handle, &desc);
+            assert(rc == 0);
+            if(desc.role != BLE_GAP_ROLE_MASTER) return 0;            
+            TLS_BT_APPL_TRACE_DEBUG("mtu update event; conn_handle=%d cid=%d mtu=%d\n",
+                                    event->mtu.conn_handle,
+                                    event->mtu.channel_id,
+                                    event->mtu.value);
+            return 0;
 
-    default:
-        return 0;
+        case BLE_GAP_EVENT_REPEAT_PAIRING:
+            /* We already have a bond with the peer, but it is attempting to
+             * establish a new secure link.  This app sacrifices security for
+             * convenience: just throw away the old bond and accept the new link.
+             */
+            /* Delete the old bond. */
+            rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
+            assert(rc == 0);
+            if(desc.role != BLE_GAP_ROLE_MASTER) return 0;   
+            ble_store_util_delete_peer(&desc.peer_id_addr);
+            /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should
+             * continue with the pairing operation.
+             */
+            return BLE_GAP_REPEAT_PAIRING_RETRY;
+        case BLE_GAP_EVENT_HOST_SHUTDOWN:
+            TLS_BT_APPL_TRACE_DEBUG("Client BLE_GAP_EVENT_HOST_SHUTDOWN:%d\r\n", event->type);
+            g_ble_client_state = BLE_CLIENT_MODE_IDLE;
+            g_send_pending = 0;
+            g_mtu = 20;
+            peer_deinit();
+            g_uart_output_ptr = NULL;
+            g_uart_in_and_sent_ptr = NULL;            
+            break;
+        default:
+            TLS_BT_APPL_TRACE_VERBOSE("Client Unhandled event:%d\r\n", event->type);
+            return 0;
     }
+
+    return 0;
 }
 
 /*
@@ -574,42 +637,35 @@ ble_gap_evt_cb(struct ble_gap_event *event, void *arg)
  ****************************************************************************************
  */
 
-int tls_ble_client_demo_api_init(tls_ble_output_func_ptr output_func_ptr)
+int tls_ble_client_demo_api_init(tls_ble_uart_output_ptr uart_output_ptr, tls_ble_uart_sent_ptr uart_in_and_sent_ptr)
 {
     int rc = BLE_HS_EAPP ;
-    
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
-        TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
-        return BLE_HS_EDISABLED;
-    }
-    
-    TLS_BT_APPL_TRACE_DEBUG("### %s state=%d\r\n", __FUNCTION__, g_ble_client_state);
 
-    if(g_ble_client_state == BLE_CLIENT_MODE_IDLE)
-    {
+    CHECK_SYSTEM_READY();
+
+    TLS_BT_APPL_TRACE_DEBUG("%s state=%d\r\n", __FUNCTION__, g_ble_client_state);
+
+    if(g_ble_client_state == BLE_CLIENT_MODE_IDLE) {
         rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64);
-    	if(rc == 0)
-    	{	
-    	    tls_ble_register_gap_evt(0xFFFFFFFF, ble_gap_evt_cb);
-    		TLS_BT_APPL_TRACE_DEBUG("### %s success\r\n", __FUNCTION__);
-            g_ble_uart_output_fptr = output_func_ptr;
-            
-            rc = tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, true);
-            if(rc == 0)
-            {
+
+        if(rc == 0) {
+            ble_gap_event_listener_register(&ble_client_event_listener,
+                                    ble_gap_evt_cb, NULL);
+            TLS_BT_APPL_TRACE_DEBUG("%s success\r\n", __FUNCTION__);
+            g_uart_output_ptr = uart_output_ptr;
+            g_uart_in_and_sent_ptr = uart_in_and_sent_ptr;
+            rc = tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, false);
+
+            if(rc == 0) {
                 g_ble_client_state = BLE_CLIENT_MODE_SCANNING;
-            }else
-            {
-                TLS_BT_APPL_TRACE_ERROR("### %s failed, tls_ble_gap_scan passive\r\n", __FUNCTION__);
+            } else {
+                TLS_BT_APPL_TRACE_ERROR("%s failed, tls_ble_gap_scan passive\r\n", __FUNCTION__);
             }
-            
-    	}
-    }else
-    {
-       return BLE_HS_EALREADY; 
+        }
+    } else {
+        return BLE_HS_EALREADY;
     }
-    
+
     return rc;
 }
 
@@ -618,100 +674,145 @@ int tls_ble_client_demo_api_deinit()
     int rc = BLE_HS_EAPP ;
     const struct peer *peer;
 
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
-        TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
-        return BLE_HS_EDISABLED;
-    }
-    
-    TLS_BT_APPL_TRACE_DEBUG("### %s state=%d\r\n", __FUNCTION__, g_ble_client_state);
+    CHECK_SYSTEM_READY();
 
+    TLS_BT_APPL_TRACE_DEBUG("%s state=%d\r\n", __FUNCTION__, g_ble_client_state);
 
-    if(g_ble_client_state == BLE_CLIENT_MODE_CONNECTING || g_ble_client_state == BLE_CLIENT_MODE_CONNECTED
-        ||g_ble_client_state == BLE_CLIENT_MODE_SUBSCRIBING || g_ble_client_state == BLE_CLIENT_MODE_SUBSCRIBED)
-    {
-         if(g_ble_client_state == BLE_CLIENT_MODE_SUBSCRIBED)
-         {
+    if(g_ble_client_state == BLE_CLIENT_MODE_CONNECTING
+            || g_ble_client_state == BLE_CLIENT_MODE_CONNECTED
+            || g_ble_client_state == BLE_CLIENT_MODE_SUBSCRIBING
+            || g_ble_client_state == BLE_CLIENT_MODE_SUBSCRIBED) {
+        if(g_ble_client_state == BLE_CLIENT_MODE_SUBSCRIBED) {
             g_ble_client_state = BLE_CLIENT_MODE_EXITING; //here I only preset the flag;
-            
             peer = get_peer_by_conn_handle(g_ble_client_conn_handle);
-            if(peer)
-            {
+
+            if(peer) {
                 TLS_BT_APPL_TRACE_DEBUG("cancel subsribe and terminate the connection\r\n");
                 //NOTE , The disconnect process will be issued after cancel subscribe complete;
-                wm_ble_client_demo_cancel_subscribe(peer);
-            }else
-            {   
-                rc = ble_gap_terminate(g_ble_client_conn_handle, BLE_ERR_REM_USER_CONN_TERM); 
+                rc = wm_ble_client_demo_cancel_subscribe(peer);
+            } else {
+                rc = ble_gap_terminate(g_ble_client_conn_handle, BLE_ERR_REM_USER_CONN_TERM);
             }
-         }else
-         {
+        } else {
             g_ble_client_state = BLE_CLIENT_MODE_EXITING; //here I only preset the flag;
-            rc = ble_gap_terminate(g_ble_client_conn_handle, BLE_ERR_REM_USER_CONN_TERM); 
-         }
-    }else if(g_ble_client_state == BLE_CLIENT_MODE_SCANNING)
-    {
-        
-        rc = tls_ble_gap_scan(WM_BLE_SCAN_STOP, true);
-        if(rc == 0)
-        {
-           g_ble_client_state = BLE_CLIENT_MODE_IDLE;
-           peer_deinit();
-           g_ble_uart_output_fptr = NULL;
+            rc = ble_gap_terminate(g_ble_client_conn_handle, BLE_ERR_REM_USER_CONN_TERM);
         }
+    } else if(g_ble_client_state == BLE_CLIENT_MODE_SCANNING) {
+        rc = tls_ble_gap_scan(WM_BLE_SCAN_STOP, 0);
 
-        TLS_BT_APPL_TRACE_DEBUG("!!!!!!!STOP SCAN...rc=%d\r\n", rc);
-    }else if(g_ble_client_state == BLE_CLIENT_MODE_IDLE)
-    {
+        if(rc == 0) {
+            g_ble_client_state = BLE_CLIENT_MODE_IDLE;
+            peer_deinit();
+            g_uart_output_ptr = NULL;
+            g_uart_in_and_sent_ptr = NULL;
+        }
+
+        TLS_BT_APPL_TRACE_DEBUG("tls_ble_gap_scan rc=%d\r\n", rc);
+        ble_gap_event_listener_unregister(&ble_client_event_listener);
+    } else if(g_ble_client_state == BLE_CLIENT_MODE_IDLE) {
         rc = 0;
-    }else
-    {
+        ble_gap_event_listener_unregister(&ble_client_event_listener);
+    } else {
         rc = BLE_HS_EALREADY;
-        TLS_BT_APPL_TRACE_DEBUG("### %s busy, state=%d\r\n", __FUNCTION__, g_ble_client_state);
+        TLS_BT_APPL_TRACE_DEBUG("%s busy, state=%d\r\n", __FUNCTION__, g_ble_client_state);
     }
-        
-
 
     return rc;
+}
+
+
+static int
+tls_ble_client_demo_on_read(uint16_t conn_handle,
+                const struct ble_gatt_error *error,
+                struct ble_gatt_attr *attr,
+                void *arg)
+{
+    TLS_BT_APPL_TRACE_DEBUG("Read complete; status=%d conn_handle=%d\r\n", error->status,
+                conn_handle);
+    const struct os_mbuf *om = attr->om;
     
+    if (error->status == 0) {
+        while(om != NULL) {
+
+            print_bytes(om->om_data, om->om_len);
+            om = SLIST_NEXT(om, om_next);
+        }        
+    }
+
+    return 0;
+}
+int tls_ble_client_demo_api_read_msg()
+{
+    const struct peer *peer;
+    const struct peer_chr *chr;
+    int rc = BLE_HS_ENOTCONN;
+
+    CHECK_SYSTEM_READY();
+    
+    if(g_ble_client_state) {
+        peer = get_peer_by_conn_handle(g_ble_client_conn_handle);
+
+        if(peer) {
+            chr = peer_chr_find_uuid(peer,
+                                     BLE_UUID16_DECLARE(WM_BLE_SERVER_SVC_UUID),
+                                     BLE_UUID16_DECLARE(WM_BLE_SERVER_CHR_READ));
+
+            if(chr == NULL) {
+                TLS_BT_APPL_TRACE_ERROR("Error: Peer doesn't Control Point characteristic[0xFFF3]\r\n");
+                return BLE_HS_EAPP;
+            }
+
+            rc = ble_gattc_read(peer->conn_handle, chr->chr.val_handle,
+                                tls_ble_client_demo_on_read, NULL);
+            if (rc != 0) {
+                TLS_BT_APPL_TRACE_ERROR("Error: Failed to read characteristic; rc=%d\r\n",rc);
+            }
+
+        }
+    } else {
+        return BLE_HS_ENOTCONN;
+    }    
+
+    return rc;
 }
 
 int tls_ble_client_demo_api_send_msg(uint8_t *ptr, int length)
 {
     const struct peer *peer;
     const struct peer_chr *chr;
-    const struct peer_dsc *dsc;
     int rc = 0;
+
+    TLS_BT_APPL_TRACE_VERBOSE("### %s len=%d\r\n", __FUNCTION__, length);
+
+    CHECK_SYSTEM_READY();
     
-    //TLS_BT_APPL_TRACE_DEBUG("### %s len=%d\r\n", __FUNCTION__, length);
-    if(g_send_pending) return BLE_HS_EBUSY;
-    
-    if(g_ble_client_state)
-    {    
+    if(g_send_pending) { return BLE_HS_EBUSY; }
+
+    if(g_ble_client_state) {
         peer = get_peer_by_conn_handle(g_ble_client_conn_handle);
-        if(peer)
-        {
+
+        if(peer) {
             chr = peer_chr_find_uuid(peer,
                                      BLE_UUID16_DECLARE(WM_BLE_SERVER_SVC_UUID),
                                      BLE_UUID16_DECLARE(WM_BLE_SERVER_CHR_WRITE));
-            if (chr == NULL) {
+
+            if(chr == NULL) {
                 TLS_BT_APPL_TRACE_ERROR("Error: Peer doesn't Control Point characteristic[0xFFF2]\n");
                 return BLE_HS_EAPP;
             }
+
             rc = ble_gattc_write_flat(peer->conn_handle, chr->chr.val_handle,
                                       ptr, length, wm_ble_client_demo_on_write, NULL);
-            if (rc != 0) {
+
+            if(rc != 0) {
                 TLS_BT_APPL_TRACE_ERROR("Error: Failed to write characteristic; rc=%d\r\n",
-                            rc);
+                                        rc);
                 return rc;
-            }else
-            {
+            } else {
                 g_send_pending = 1;
             }
-        
         }
-    }else
-    {
+    } else {
         return BLE_HS_ENOTCONN;
     }
 

+ 12 - 3
src/app/bleapp/wm_ble_client_api_demo.h

@@ -1,13 +1,22 @@
-#ifndef __WM_BLE_CLIENT_DEMO_HUAWEI_H__
-#define __WM_BLE_CLIENT_DEMO_HUAWEI_H__
+#ifndef __WM_BLE_CLIENT_DEMO_H__
+#define __WM_BLE_CLIENT_DEMO_H__
 
 #include "wm_bt_def.h"
 
-int tls_ble_client_demo_api_init(tls_ble_output_func_ptr output_func_ptr);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+int tls_ble_client_demo_api_init(tls_ble_uart_output_ptr uart_output_ptr, tls_ble_uart_sent_ptr uart_in_and_sent_ptr);
 
 int tls_ble_client_demo_api_deinit();
 
 int tls_ble_client_demo_api_send_msg(uint8_t *ptr, int length);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
 

+ 319 - 373
src/app/bleapp/wm_ble_client_api_multi_conn_demo.c

@@ -19,6 +19,7 @@
 #include "wm_ble_gap.h"
 #include "wm_bt_util.h"
 
+static struct ble_gap_event_listener ble_mclient_event_listener;
 
 /* BLE server srivces list*/
 #define WM_BLE_SERVER_SVC_UUID              0xFFF0
@@ -26,7 +27,7 @@
 #define WM_BLE_SERVER_CHR_WRITE             0xFFF2
 
 
-#define MAX_CONN_DEVCIE_COUNT    MYNEWT_VAL(BLE_MAX_CONNECTIONS)
+#define MAX_CONN_DEVCIE_COUNT    (MYNEWT_VAL(BLE_MAX_CONNECTIONS)-1)
 
 typedef enum {
     DEV_DISCONNCTED = 0,
@@ -40,14 +41,14 @@ typedef enum {
     DEV_TRANSFERING,
 } transfer_state_t;
 
-typedef enum{
+typedef enum {
     DEV_SCAN_IDLE,
     DEV_SCAN_RUNNING,
     DEV_SCAN_STOPPING,
 } conn_scan_t;
 
 
-typedef struct{   
+typedef struct {
     conn_state_t conn_state;
     transfer_state_t transfer_state;
     ble_addr_t addr;
@@ -56,7 +57,7 @@ typedef struct{
     uint8_t  remote_name[16];      /**parsed out from name filed in advertisement data, */
     uint8_t  subscribed;
     uint32_t write_counter;        /**indicate the notification counter*/
-    
+
 } connect_device_t;
 
 static connect_device_t conn_devices[MAX_CONN_DEVCIE_COUNT];
@@ -65,16 +66,16 @@ static uint8_t g_ble_client_inited = 0;
 
 static int ble_gap_evt_cb(struct ble_gap_event *event, void *arg);
 
-void wm_ble_dump_conn_status()
+static void wm_ble_dump_conn_status(void)
 {
     int i = 0;
     printf("          =========remote device info========\r\n");
-    printf("ID, STATE, HANDLE, MAC              ,  TRANSFER    \r\n");
-    for(i = 0; i<MAX_CONN_DEVCIE_COUNT; i++)
-    {
-        printf("%d,     %d,     %d,     %02x:%02x:%02x:%02x:%02x:%02x,      %d\r\n", i+1, conn_devices[i].conn_state, conn_devices[i].conn_handle, 
-            conn_devices[i].addr.val[0], conn_devices[i].addr.val[1],conn_devices[i].addr.val[2],conn_devices[i].addr.val[3],
-            conn_devices[i].addr.val[4],conn_devices[i].addr.val[5], conn_devices[i].write_counter);
+    printf("ID, STATE, HANDLE,       MAC          ,    TRANSFER    \r\n");
+
+    for(i = 0; i < MAX_CONN_DEVCIE_COUNT; i++) {
+        printf("%d,     %d,     %d,     %s,      %d\r\n", i + 1,
+               conn_devices[i].conn_state, conn_devices[i].conn_handle,
+               addr_str(conn_devices[i].addr.val),conn_devices[i].write_counter);
     }
 }
 
@@ -82,12 +83,11 @@ static void wm_ble_update_conn_params(struct ble_gap_conn_params *conn_params)
 {
     int i = 0;
 
-    for(i = 0; i<MAX_CONN_DEVCIE_COUNT; i++)
-    {
-        if(conn_devices[i].conn_state == DEV_DISCONNCTED)
-        {
-            conn_params->itvl_min = 0x20 + i*16;
-            conn_params->itvl_max = 0x22 + i*16;
+    for(i = 0; i < MAX_CONN_DEVCIE_COUNT; i++) {
+        if(conn_devices[i].conn_state == DEV_DISCONNCTED) {
+            conn_params->itvl_min += i ;
+            conn_params->itvl_max += i ;
+            conn_params->latency = 2;
             return;
         }
     }
@@ -96,25 +96,21 @@ static void wm_ble_update_notify_counter(uint16_t conn_handle)
 {
     int i = 0;
 
-    for(i = 0; i<MAX_CONN_DEVCIE_COUNT; i++)
-    {
-        if(conn_devices[i].conn_handle == conn_handle)
-        {
+    for(i = 0; i < MAX_CONN_DEVCIE_COUNT; i++) {
+        if(conn_devices[i].conn_handle == conn_handle) {
             conn_devices[i].write_counter++;
             return;
         }
     }
 }
 
-static bool wm_ble_check_all_connected()
+static bool wm_ble_check_all_connect_state(conn_state_t conn_state)
 {
     bool ret = true;
     int i = 0;
-    
-    for(i = 0; i<MAX_CONN_DEVCIE_COUNT; i++)
-    {
-        if(conn_devices[i].conn_state != DEV_CONNECTED)
-        {
+
+    for(i = 0; i < MAX_CONN_DEVCIE_COUNT; i++) {
+        if(conn_devices[i].conn_state != conn_state) {
             return false;
         }
     }
@@ -125,11 +121,9 @@ static bool wm_ble_check_any_connecting()
 {
     bool ret = true;
     int i = 0;
-    
-    for(i = 0; i<MAX_CONN_DEVCIE_COUNT; i++)
-    {
-        if(conn_devices[i].conn_state == DEV_CONNECTING)
-        {
+
+    for(i = 0; i < MAX_CONN_DEVCIE_COUNT; i++) {
+        if(conn_devices[i].conn_state == DEV_CONNECTING) {
             return ret;
         }
     }
@@ -141,69 +135,71 @@ static bool wm_ble_check_any_connecting()
 * update the connected devices table, and return true, if there is disconnected device. which means the client will do
 * ble scan and connect . otherwise all devcies connected , do nothing;
 */
-static bool wm_ble_update_conn_devices(uint16_t conn_handle, conn_state_t conn_state, ble_addr_t *p_addr)
+static bool wm_ble_update_conn_devices(uint16_t conn_handle, conn_state_t conn_state,
+                                       ble_addr_t *p_addr)
 {
     bool ret = false;
     int i = 0;
 
-    switch(conn_state)
-    {
+    switch(conn_state) {
         case DEV_CONNECTING:
-            for(i = 0; i<MAX_CONN_DEVCIE_COUNT; i++)
-            {
-               if(conn_devices[i].conn_state == DEV_DISCONNCTED) break; 
+            for(i = 0; i < MAX_CONN_DEVCIE_COUNT; i++) {
+                if(conn_devices[i].conn_state == DEV_DISCONNCTED) { break; }
             }
-            if(i<MAX_CONN_DEVCIE_COUNT)
-            {
+
+            if(i < MAX_CONN_DEVCIE_COUNT) {
                 conn_devices[i].conn_state = conn_state;
                 conn_devices[i].conn_handle = conn_handle;
                 memcpy(&conn_devices[i].addr, p_addr, sizeof(ble_addr_t));
-            }else
-            {
+            } else {
                 assert(0);
             }
+
             break;
-       case DEV_CONNECTED:
-            for(i = 0; i<MAX_CONN_DEVCIE_COUNT; i++)
-            {
-                if((conn_devices[i].conn_state == DEV_CONNECTING) && (conn_devices[i].conn_handle == conn_handle))
-                {
+
+        case DEV_CONNECTED:
+            for(i = 0; i < MAX_CONN_DEVCIE_COUNT; i++) {
+                if((conn_devices[i].conn_state == DEV_CONNECTING) && (conn_devices[i].conn_handle == conn_handle)) {
                     break;
                 }
             }
 
-            if(i<MAX_CONN_DEVCIE_COUNT)
-            {
+            if(i < MAX_CONN_DEVCIE_COUNT) {
                 conn_devices[i].conn_state = conn_state;
-                conn_devices[i].conn_handle = conn_handle;            
-            }else
-            {
+                conn_devices[i].conn_handle = conn_handle;
+            } else {
                 assert(0);
             }
+
             break;
-      case DEV_DISCONNCTED:
-            for(i = 0; i<MAX_CONN_DEVCIE_COUNT; i++)
-            {
-                if(((conn_devices[i].conn_state == DEV_CONNECTED)||(conn_devices[i].conn_state == DEV_CONNECTING)) && (conn_devices[i].conn_handle == conn_handle))
-                {
+
+        case DEV_DISCONNCTED:
+            for(i = 0; i < MAX_CONN_DEVCIE_COUNT; i++) {
+                #if 0
+                if(((conn_devices[i].conn_state == DEV_CONNECTED)
+                        || (conn_devices[i].conn_state == DEV_CONNECTING))
+                        && (conn_devices[i].conn_handle == conn_handle)) {
                     break;
                 }
+                #else
+                if(conn_devices[i].conn_handle == conn_handle) {
+                    break;
+                }
+                #endif
             }
 
-            if(i<MAX_CONN_DEVCIE_COUNT)
-            {
+            if(i < MAX_CONN_DEVCIE_COUNT) {
                 conn_devices[i].conn_state = DEV_DISCONNCTED;
-                conn_devices[i].conn_handle = 0xFFFF;            
-            }else
-            {
-                assert(0);
+                conn_devices[i].conn_handle = 0xFFFF;
+            } else {
+                //assert(0);
             }
+
             break;
     }
-    for(i=0; i<MAX_CONN_DEVCIE_COUNT; i++)
-    {
-        if(conn_devices[i].conn_state == DEV_DISCONNCTED)
-        {
+
+    for(i = 0; i < MAX_CONN_DEVCIE_COUNT; i++) {
+        if(conn_devices[i].conn_state == DEV_DISCONNCTED) {
             ret = true;
             break;
         }
@@ -220,19 +216,22 @@ static bool wm_ble_update_conn_devices(uint16_t conn_handle, conn_state_t conn_s
  */
 static int
 wm_ble_client_demo_on_write(uint16_t conn_handle,
-                 const struct ble_gatt_error *error,
-                 struct ble_gatt_attr *attr,
-                 void *arg)
+                            const struct ble_gatt_error *error,
+                            struct ble_gatt_attr *attr,
+                            void *arg)
 {
     TLS_BT_APPL_TRACE_DEBUG("Write complete; status=%d conn_handle=%d attr_handle=%d\r\n",
-                error->status, conn_handle, attr->handle);
-
+                            error->status, conn_handle, attr->handle);
+    if(error->status == 261 || error->status == 271)
+    {
+        return ble_gap_security_initiate(conn_handle);
+    }
     return 0;
 }
-static int
+static void
 wm_ble_client_async_gap_scan(void *app_arg)
 {
-    tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, true);    
+    tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, false);
 }
 
 /**
@@ -241,101 +240,34 @@ wm_ble_client_async_gap_scan(void *app_arg)
  */
 static int
 wm_ble_client_demo_on_subscribe(uint16_t conn_handle,
-                     const struct ble_gatt_error *error,
-                     struct ble_gatt_attr *attr,
-                     void *arg)
+                                const struct ble_gatt_error *error,
+                                struct ble_gatt_attr *attr,
+                                void *arg)
 {
     bool ret = false;
     struct ble_gap_conn_desc desc;
-    
     TLS_BT_APPL_TRACE_DEBUG("Subscribe complete; status=%d conn_handle=%d "
-                      "attr_handle=%d\r\n",
-                error->status, conn_handle, attr->handle);
-    if(error->status == 0)
-    {
+                            "attr_handle=%d\r\n",
+                            error->status, conn_handle, attr->handle);
+
+    if(error->status == 0) {
         int rc = ble_gap_conn_find(conn_handle, &desc);
         assert(rc == 0);
         ret = wm_ble_update_conn_devices(conn_handle, DEV_CONNECTED, &desc.peer_id_addr);
-    }else
-    {
-        assert(0);
+    } else {
+         ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
     }
 
-
     wm_ble_dump_conn_status();
 
-    if(ret)
-    {
-      TLS_BT_APPL_TRACE_API("Continue to scan next device to connect...\r\n");  
-      tls_bt_async_proc_func(wm_ble_client_async_gap_scan, NULL, 200);
-    }
-    return 0;
-}
-
-static int
-wm_ble_client_demo_on_unsubscribe(uint16_t conn_handle,
-                     const struct ble_gatt_error *error,
-                     struct ble_gatt_attr *attr,
-                     void *arg)
-{
-    struct ble_gap_conn_desc desc;
-    
-    TLS_BT_APPL_TRACE_DEBUG("unsubscribe complete; status=%d conn_handle=%d attr_handle=%d\n",
-                error->status, conn_handle, attr->handle);
-    if(error->status == 0)
-    {
-        int rc = ble_gap_conn_find(conn_handle, &desc);
-        assert(rc == 0);
-
-    }else
-    {
-        assert(0);
+    if(ret) {
+        TLS_BT_APPL_TRACE_API("Continue to scan next device to connect...\r\n");
+        tls_bt_async_proc_func(wm_ble_client_async_gap_scan, NULL, 200);
     }
 
-
-    wm_ble_dump_conn_status();
-
-    ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
-
     return 0;
 }
 
-static void
-wm_ble_client_demo_cancel_subscribe(const struct peer *peer)
-{
-    const struct peer_chr *chr;
-    const struct peer_dsc *dsc;
-    uint8_t value[2];
-    int rc; 
-
-    /* Subscribe to indifications for the Specified characteristic[0xFFF1].
-     * A central disables indications by writing two bytes (0, 0) to the
-     * characteristic's client-characteristic-configuration-descriptor (CCCD).
-     */
-    dsc = peer_dsc_find_uuid(peer,
-                             BLE_UUID16_DECLARE(WM_BLE_SERVER_SVC_UUID),
-                             BLE_UUID16_DECLARE(WM_BLE_SERVER_CHR_INDICATE),
-                             BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_CFG_UUID16));
-    if (dsc == NULL) {
-        TLS_BT_APPL_TRACE_ERROR("Error: Peer lacks a CCCD for the Unread Alert Status characteristic\r\n");
-        goto err;
-    }
-
-    value[0] = 0;
-    value[1] = 0;
-    rc = ble_gattc_write_flat(peer->conn_handle, dsc->dsc.handle,
-                              value, sizeof value, wm_ble_client_demo_on_unsubscribe, NULL);
-    if (rc != 0) {
-        TLS_BT_APPL_TRACE_ERROR("Error: Failed to unsubscribe to characteristic; rc=%d\r\n", rc);
-        goto err;
-    }
-
-    return;
-
-err:
-    /* Terminate the connection. */
-    ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);    
-}
 /**
  * Performs three concurrent GATT operations against the specified peer:
  * 1. Writes the 0xFFF2 characteristic.
@@ -355,14 +287,14 @@ wm_ble_client_demo_read_write_subscribe(const struct peer *peer)
     const struct peer_dsc *dsc;
     uint8_t value[2];
     int rc;
-    
     /* Write two bytes (0xAA, 0xBB) to the alert-notification-control-point
      * characteristic.
      */
     chr = peer_chr_find_uuid(peer,
                              BLE_UUID16_DECLARE(WM_BLE_SERVER_SVC_UUID),
                              BLE_UUID16_DECLARE(WM_BLE_SERVER_CHR_WRITE));
-    if (chr == NULL) {
+
+    if(chr == NULL) {
         TLS_BT_APPL_TRACE_ERROR("Error: Peer doesn't support 0xFFF2 characteristic\r\n");
         goto err;
     }
@@ -371,9 +303,10 @@ wm_ble_client_demo_read_write_subscribe(const struct peer *peer)
     value[1] = 0xBB;
     rc = ble_gattc_write_flat(peer->conn_handle, chr->chr.val_handle,
                               value, sizeof value, wm_ble_client_demo_on_write, NULL);
-    if (rc != 0) {
+
+    if(rc != 0) {
         TLS_BT_APPL_TRACE_ERROR("Error: Failed to write characteristic; rc=%d\r\n",
-                    rc);
+                                rc);
     }
 
     /* Subscribe to indifications for the Specified characteristic[0xFFF1].
@@ -384,7 +317,8 @@ wm_ble_client_demo_read_write_subscribe(const struct peer *peer)
                              BLE_UUID16_DECLARE(WM_BLE_SERVER_SVC_UUID),
                              BLE_UUID16_DECLARE(WM_BLE_SERVER_CHR_INDICATE),
                              BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_CFG_UUID16));
-    if (dsc == NULL) {
+
+    if(dsc == NULL) {
         TLS_BT_APPL_TRACE_ERROR("Error: Peer lacks a CCCD for the 0xFFF1 characteristic\r\n");
         goto err;
     }
@@ -393,34 +327,19 @@ wm_ble_client_demo_read_write_subscribe(const struct peer *peer)
     value[1] = 0;
     rc = ble_gattc_write_flat(peer->conn_handle, dsc->dsc.handle,
                               value, sizeof value, wm_ble_client_demo_on_subscribe, NULL);
-    if (rc != 0) {
+
+    if(rc != 0) {
         TLS_BT_APPL_TRACE_ERROR("Error: Failed to subscribe to characteristic,rc=%d\r\n", rc);
         goto err;
     }
 
     return;
-
 err:
     /* Terminate the connection. */
     ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
 }
 
-static int
-wm_ble_client_demo_on_mtu(uint16_t conn_handle, const struct ble_gatt_error *error,
-               uint16_t mtu, void *arg)
-{
-    switch (error->status) {
-    case 0:
-        TLS_BT_APPL_TRACE_API("mtu exchange complete: conn_handle=%d mtu=%d\n",conn_handle, mtu);
-        break;
-
-    default:
-        TLS_BT_APPL_TRACE_ERROR("Update MTU failed...\r\n");
-        break;
-    }
 
-    return 0;
-}
 
 /**
  * Called when service discovery of the specified peer has completed.
@@ -428,13 +347,13 @@ wm_ble_client_demo_on_mtu(uint16_t conn_handle, const struct ble_gatt_error *err
 static void
 wm_ble_client_demo_on_disc_complete(const struct peer *peer, int status, void *arg)
 {
-
-    if (status != 0) {
+    if(status != 0) {
         /* Service discovery failed.  Terminate the connection. */
         TLS_BT_APPL_TRACE_ERROR("Error: Service discovery failed; status=%d "
-                           "conn_handle=%d\r\n", status, peer->conn_handle);
+                                "conn_handle=%d\r\n", status, peer->conn_handle);
+        wm_ble_update_conn_devices(peer->conn_handle, DEV_DISCONNCTED, NULL);
         ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
-        tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, true);
+        tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, false);
         return;
     }
 
@@ -443,10 +362,7 @@ wm_ble_client_demo_on_disc_complete(const struct peer *peer, int status, void *a
      * supports.
      */
     TLS_BT_APPL_TRACE_API("Service discovery complete; status=%d "
-                       "conn_handle=%d\r\n", status, peer->conn_handle);
-
-    ble_gattc_exchange_mtu(peer->conn_handle, wm_ble_client_demo_on_mtu, NULL);
-
+                          "conn_handle=%d\r\n", status, peer->conn_handle);
     /* Now perform three concurrent GATT procedures against the peer: read,
      * write, and subscribe to notifications.
      */
@@ -454,6 +370,34 @@ wm_ble_client_demo_on_disc_complete(const struct peer *peer, int status, void *a
 }
 
 
+static int
+wm_ble_client_demo_on_mtu(uint16_t conn_handle, const struct ble_gatt_error *error,
+                          uint16_t mtu, void *arg)
+{
+    int rc;
+    
+    switch(error->status) {
+        case 0:
+            TLS_BT_APPL_TRACE_API("mtu exchange complete: conn_handle=%d mtu=%d\n", conn_handle, mtu);
+            break;
+
+        default:
+            TLS_BT_APPL_TRACE_ERROR("Update MTU failed...\r\n");
+            break;
+    }
+    
+    /* Perform service discovery. */
+    rc = peer_disc_all(conn_handle,
+               wm_ble_client_demo_on_disc_complete, NULL);
+
+    if(rc != 0) {
+        TLS_BT_APPL_TRACE_ERROR("Failed to discover services; rc=%d\n", rc);
+        ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
+        return 0;
+    }
+
+    return 0;
+}
 
 /**
  * Indicates whether we should tre to connect to the sender of the specified
@@ -468,22 +412,22 @@ wm_ble_client_demo_should_connect(const struct ble_gap_disc_desc *disc)
     int i;
 
     /* The device has to be advertising connectability. */
-    if (disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
-        disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
-
+    if(disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
+            disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
         return 0;
     }
 
     rc = ble_hs_adv_parse_fields(&fields, disc->data, disc->length_data);
-    if (rc != 0) {
+
+    if(rc != 0) {
         return rc;
     }
 
     /* The device has to advertise support for the Alert Notification
      * service (0xFFF0).
      */
-    for (i = 0; i < fields.num_uuids16; i++) {
-        if (ble_uuid_u16(&fields.uuids16[i].u) == WM_BLE_SERVER_SVC_UUID) {
+    for(i = 0; i < fields.num_uuids16; i++) {
+        if(ble_uuid_u16(&fields.uuids16[i].u) == WM_BLE_SERVER_SVC_UUID) {
             return 1;
         }
     }
@@ -503,13 +447,14 @@ wm_ble_client_demo_connect_if_interesting(const struct ble_gap_disc_desc *disc)
     struct ble_gap_conn_params conn_params;
 
     /* Don't do anything if we don't care about this advertiser. */
-    if (!wm_ble_client_demo_should_connect(disc)) {
+    if(!wm_ble_client_demo_should_connect(disc)) {
         return;
     }
 
     /* Scanning must be stopped before a connection can be initiated. */
     rc = tls_ble_gap_scan(WM_BLE_SCAN_STOP, 0);;
-    if (rc != 0) {
+
+    if(rc != 0) {
         TLS_BT_APPL_TRACE_ERROR("Failed to cancel scan; rc=%d\r\n", rc);
         return;
     }
@@ -517,26 +462,26 @@ wm_ble_client_demo_connect_if_interesting(const struct ble_gap_disc_desc *disc)
     /* Try to connect the the advertiser.  Allow 30 seconds (30000 ms) for
      * timeout.
      */
-     
     ble_gap_init_conn_params(&conn_params);
-    conn_params.scan_itvl = 0x20;
-    conn_params.scan_window = 0x20;
-    conn_params.supervision_timeout = 500;
-    conn_params.max_ce_len = 512;
-    conn_params.min_ce_len = 0;
-
+    //conn_params.scan_itvl = 0x20;
+    //conn_params.scan_window = 0x20;
+    //conn_params.supervision_timeout = 500;
+    //conn_params.max_ce_len = 512;
+    //conn_params.min_ce_len = 0;
     /*Update connection interval*/
     wm_ble_update_conn_params(&conn_params);
-    
     rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &disc->addr, 30000, &conn_params,
-                         ble_gap_evt_cb, NULL);
-    if (rc != 0) {
+                         NULL, NULL);
+
+    if(rc != 0) {
         TLS_BT_APPL_TRACE_ERROR("Error: Failed to connect to device; addr_type=%d "
-                           "addr=%s, rc=%d(0x%04x)\r\n",
-                    disc->addr.type, addr_str(disc->addr.val),rc,rc);
+                                "addr=%s, rc=%d(0x%04x)\r\n",
+                                disc->addr.type, addr_str(disc->addr.val), rc, rc);
         return;
+    }else
+    {
+        TLS_BT_APPL_TRACE_DEBUG("MC conntecting to %s\r\n", addr_str(disc->addr.val));
     }
-    
 }
 
 /**
@@ -560,139 +505,165 @@ ble_gap_evt_cb(struct ble_gap_event *event, void *arg)
     struct ble_hs_adv_fields fields;
     int rc;
 
-    switch (event->type) {
-    case BLE_GAP_EVENT_DISC:
-        rc = ble_hs_adv_parse_fields(&fields, event->disc.data,
-                                     event->disc.length_data);
-        if (rc != 0) {
+    switch(event->type) {
+        case BLE_GAP_EVENT_DISC:
+            rc = ble_hs_adv_parse_fields(&fields, event->disc.data,
+                                         event->disc.length_data);
+
+            if(rc != 0) {
+                return 0;
+            }
+
+            /* Try to connect to the advertiser if it looks interesting. */
+            wm_ble_client_demo_connect_if_interesting(&event->disc);
             return 0;
-        }
 
-        /* Try to connect to the advertiser if it looks interesting. */
-        wm_ble_client_demo_connect_if_interesting(&event->disc);
-        return 0;
+        case BLE_GAP_EVENT_CONNECT:
+
+            /* A new connection was established or a connection attempt failed. */
+            if(event->connect.status == 0) {
+
+                rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
+                assert(rc == 0);
+                if(desc.role != BLE_GAP_ROLE_MASTER) return 0;
+                /* Connection successfully established. */
+                TLS_BT_APPL_TRACE_API("MC Connection established \r\n");                
+                print_conn_desc(&desc);
+                TLS_BT_APPL_TRACE_DEBUG("\r\n");
+                
+                wm_ble_update_conn_devices(event->connect.conn_handle, DEV_CONNECTING, &desc.peer_id_addr);
+                wm_ble_dump_conn_status();
+                /* Remember peer. */
+                rc = peer_add(event->connect.conn_handle);
+
+                if(rc != 0) {
+                    TLS_BT_APPL_TRACE_ERROR("MC Failed to add peer; rc=%d\r\n", rc);
+                    return 0;
+                }
 
-    case BLE_GAP_EVENT_CONNECT:
-        /* A new connection was established or a connection attempt failed. */
-        if (event->connect.status == 0) {
-            /* Connection successfully established. */
-            TLS_BT_APPL_TRACE_API("Connection established \r\n");
+                ble_gattc_exchange_mtu(event->connect.conn_handle, wm_ble_client_demo_on_mtu, NULL);
+            } else {
+                /* Connection attempt failed; resume scanning. */
+                TLS_BT_APPL_TRACE_ERROR("Error:MC Connection failed; status=%d\r\n",
+                                        event->connect.status);
+                tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, false);
+            }
 
+            return 0;
 
-            rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
-            assert(rc == 0);
-            print_conn_desc(&desc);
+        case BLE_GAP_EVENT_DISCONNECT:
+            if(event->disconnect.conn.role != BLE_GAP_ROLE_MASTER) return 0;
+            /* Connection terminated. */
+            TLS_BT_APPL_TRACE_API("MC disconnect; handle=%d reason=%d \r\n", event->disconnect.conn.conn_handle, event->disconnect.reason);
+            print_conn_desc(&event->disconnect.conn);
             TLS_BT_APPL_TRACE_DEBUG("\r\n");
-            
-            wm_ble_update_conn_devices(event->connect.conn_handle, DEV_CONNECTING, &desc.peer_id_addr);
-            wm_ble_dump_conn_status();
+            /* Forget about peer. */
+            rc = peer_delete(event->disconnect.conn.conn_handle);
 
-            /* Remember peer. */
-            rc = peer_add(event->connect.conn_handle);
-            if (rc != 0) {
-                TLS_BT_APPL_TRACE_ERROR("Failed to add peer; rc=%d\r\n", rc);
-                return 0;
+            if(rc != 0) {
+                TLS_BT_APPL_TRACE_ERROR("MC peer_delete (conn_handle=%d)failed\r\n",
+                                        event->disconnect.conn.conn_handle);
             }
 
-            /* Perform service discovery. */
-            rc = peer_disc_all(event->connect.conn_handle,
-                               wm_ble_client_demo_on_disc_complete, NULL);
-            if (rc != 0) {
-                TLS_BT_APPL_TRACE_ERROR("Failed to discover services; rc=%d\r\n", rc);
-                tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, true);
-                return 0;
-            }
-        } else {
-            /* Connection attempt failed; resume scanning. */
-            TLS_BT_APPL_TRACE_ERROR("Error: Connection failed; status=%d\r\n",
-                        event->connect.status);
-            tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, true);
-        }
+            wm_ble_update_conn_devices(event->disconnect.conn.conn_handle, DEV_DISCONNCTED, NULL);
 
-        return 0;
+            /* Resume scanning. If the termination is not issued by local host */
+            if(g_ble_client_switching_off) {
+                //peer_deinit();
+            } else {
+                bool connecting = wm_ble_check_any_connecting();
 
-    case BLE_GAP_EVENT_DISCONNECT:
-        /* Connection terminated. */
-        TLS_BT_APPL_TRACE_API("disconnect; reason=%d \r\n", event->disconnect.reason);
-        print_conn_desc(&event->disconnect.conn);
-        TLS_BT_APPL_TRACE_DEBUG("\r\n");
-        
-        /* Forget about peer. */
-        rc = peer_delete(event->disconnect.conn.conn_handle);
-        if(rc != 0)
-        {
-          TLS_BT_APPL_TRACE_ERROR("peer_delete (conn_handle=%d)failed\r\n", event->disconnect.conn.conn_handle);  
-        }
+                if(!connecting) { tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, false); }
+            }
 
-        wm_ble_update_conn_devices(event->disconnect.conn.conn_handle, DEV_DISCONNCTED, NULL);
+            wm_ble_dump_conn_status();
 
-        /* Resume scanning. If the termination is not issued by local host */
-        if(g_ble_client_switching_off)
-        {
-            //peer_deinit();
-        }else
-        {
-            bool connecting = wm_ble_check_any_connecting();
-            if(!connecting)tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, true);
-        }
-        wm_ble_dump_conn_status();    
-        
-        return 0;
+            if(g_ble_client_switching_off)
+            {
+                bool ret = wm_ble_check_all_connect_state(DEV_DISCONNCTED);
+                if(ret)
+                {
+                    ble_gap_event_listener_unregister(&ble_mclient_event_listener);
+                    g_ble_client_switching_off = false;
+                    g_ble_client_inited = 0;
+                }
+                
+            }
+            return 0;
 
-    case BLE_GAP_EVENT_DISC_COMPLETE:
-        TLS_BT_APPL_TRACE_API("discovery complete; reason=%d\r\n",
-                    event->disc_complete.reason);
-        return 0;
+        case BLE_GAP_EVENT_DISC_COMPLETE:
+            TLS_BT_APPL_TRACE_API("MC discovery complete; reason=%d\r\n",
+                                  event->disc_complete.reason);
+            return 0;
 
-    case BLE_GAP_EVENT_ENC_CHANGE:
-        /* Encryption has been enabled or disabled for this connection. */
-        MODLOG_DFLT(INFO, "encryption change event; status=%d \r\n",
-                    event->enc_change.status);
-        rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc);
-        assert(rc == 0);
-        print_conn_desc(&desc);
-        return 0;
+        case BLE_GAP_EVENT_ENC_CHANGE:
+            /* Encryption has been enabled or disabled for this connection. */
+            rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc);
+            assert(rc == 0);
+            print_conn_desc(&desc);
+            if(desc.role != BLE_GAP_ROLE_MASTER) return 0;
+            TLS_BT_APPL_TRACE_API("MC encryption change event; status=%d \r\n",
+                        event->enc_change.status);            
+            return 0;
 
-    case BLE_GAP_EVENT_NOTIFY_RX:
-        /* Peer sent us a notification or indication. */
-
-        TLS_BT_APPL_TRACE_DEBUG("received %s; conn_handle=%d attr_handle=%d "
-                          "attr_len=%d\n",
-                    event->notify_rx.indication ?
-                        "indication" :
-                        "notification",
-                    event->notify_rx.conn_handle,
-                    event->notify_rx.attr_handle,
-                    OS_MBUF_PKTLEN(event->notify_rx.om));
-        /* Attribute data is contained in event->notify_rx.attr_data. */
-        wm_ble_update_notify_counter(event->notify_rx.conn_handle);
-        return 0;
+        case BLE_GAP_EVENT_NOTIFY_RX:
+            /* Peer sent us a notification or indication. */
+            rc = ble_gap_conn_find(event->notify_rx.conn_handle, &desc);
+            assert(rc == 0);
+            if(desc.role != BLE_GAP_ROLE_MASTER) return 0;  
+            TLS_BT_APPL_TRACE_VERBOSE("MC received %s; conn_handle=%d attr_handle=%d "
+                                    "attr_len=%d\n",
+                                    event->notify_rx.indication ?
+                                    "indication" :
+                                    "notification",
+                                    event->notify_rx.conn_handle,
+                                    event->notify_rx.attr_handle,
+                                    OS_MBUF_PKTLEN(event->notify_rx.om));                      
+            /* Attribute data is contained in event->notify_rx.attr_data. */
+            wm_ble_update_notify_counter(event->notify_rx.conn_handle);
+            return 0;
 
-    case BLE_GAP_EVENT_MTU:
-        TLS_BT_APPL_TRACE_API("mtu update event; conn_handle=%d cid=%d mtu=%d\r\n",
-                    event->mtu.conn_handle,
-                    event->mtu.channel_id,
-                    event->mtu.value);
-        return 0;
+        case BLE_GAP_EVENT_MTU:
+            TLS_BT_APPL_TRACE_API("MC mtu update event; conn_handle=%d cid=%d mtu=%d\r\n",
+                                  event->mtu.conn_handle,
+                                  event->mtu.channel_id,
+                                  event->mtu.value);
+            return 0;
 
-    case BLE_GAP_EVENT_REPEAT_PAIRING:
-        /* We already have a bond with the peer, but it is attempting to
-         * establish a new secure link.  This app sacrifices security for
-         * convenience: just throw away the old bond and accept the new link.
-         */
+        case BLE_GAP_EVENT_REPEAT_PAIRING:
+            /* We already have a bond with the peer, but it is attempting to
+             * establish a new secure link.  This app sacrifices security for
+             * convenience: just throw away the old bond and accept the new link.
+             */
+            /* Delete the old bond. */
+            rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
+            assert(rc == 0);
 
-        /* Delete the old bond. */
-        rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
-        assert(rc == 0);
-        ble_store_util_delete_peer(&desc.peer_id_addr);
+            if(desc.role != BLE_GAP_ROLE_MASTER) return 0;
 
-        /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should
-         * continue with the pairing operation.
-         */
-        return BLE_GAP_REPEAT_PAIRING_RETRY;
+            ble_store_util_delete_peer(&desc.peer_id_addr);
+            /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should
+             * continue with the pairing operation.
+             */
+            return BLE_GAP_REPEAT_PAIRING_RETRY;
+       case BLE_GAP_EVENT_CONN_UPDATE_REQ:
+       case BLE_GAP_EVENT_L2CAP_UPDATE_REQ:
+            
+            rc = ble_gap_conn_find(event->conn_update_req.conn_handle, &desc);
+            assert(rc == 0);
 
-    default:
-        return 0;
+            if(desc.role != BLE_GAP_ROLE_MASTER) return 0;
+
+            TLS_BT_APPL_TRACE_WARNING("MultiClient Decline:%d[handle=%d]\r\n", event->type,event->conn_update_req.conn_handle);            
+            return 1;
+        case BLE_GAP_EVENT_HOST_SHUTDOWN:
+            TLS_BT_APPL_TRACE_API("MC BLE_GAP_EVENT_HOST_SHUTDOWN\r\n");
+            g_ble_client_switching_off = false;
+            g_ble_client_inited = 0;
+            return 0;
+        default:
+            TLS_BT_APPL_TRACE_VERBOSE("MultiClient Unhandled event:%d\r\n", event->type);
+            return 0;
     }
 }
 
@@ -705,41 +676,34 @@ int tls_ble_client_multi_conn_demo_api_init()
 {
     int rc = 0;
     int i = 0;
-    
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
-        TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
-        return BLE_HS_EDISABLED;
-    }
 
-    if(g_ble_client_inited) return BLE_HS_EALREADY;
-    
+    CHECK_SYSTEM_READY();
+
+    if(g_ble_client_inited) { return BLE_HS_EALREADY; }
+
     rc = peer_init(MAX_CONN_DEVCIE_COUNT, 64, 64, 64);
-	if(rc == 0)
-	{	
-	    tls_ble_register_gap_evt(0xFFFFFFFF, ble_gap_evt_cb);
-		TLS_BT_APPL_TRACE_DEBUG("### %s success\r\n", __FUNCTION__);
 
-        memset(&conn_devices, 0 , sizeof(connect_device_t)*MAX_CONN_DEVCIE_COUNT);
+    if(rc == 0) {
+        ble_gap_event_listener_register(&ble_mclient_event_listener,
+                                    ble_gap_evt_cb, NULL);
+        TLS_BT_APPL_TRACE_DEBUG("### %s success\r\n", __FUNCTION__);
+        memset(&conn_devices, 0, sizeof(connect_device_t)*MAX_CONN_DEVCIE_COUNT);
 
-        for(i=0; i<MAX_CONN_DEVCIE_COUNT; i++)
-        {
+        for(i = 0; i < MAX_CONN_DEVCIE_COUNT; i++) {
             conn_devices[i].conn_state = DEV_DISCONNCTED;
             conn_devices[i].conn_handle = 0xFFFF;
         }
-        
-        rc = tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, true);
-        if(rc == 0)
-        {
+
+        rc = tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, false);
+
+        if(rc == 0) {
             g_ble_client_inited = 1;
         }
-        
-	}else
-	{
-	    g_ble_client_inited = 0;
-		TLS_BT_APPL_TRACE_ERROR("### %s failed\r\n", __FUNCTION__);
-	}
-    
+    } else {
+        g_ble_client_inited = 0;
+        TLS_BT_APPL_TRACE_ERROR("### %s failed\r\n", __FUNCTION__);
+    }
+
     g_ble_client_switching_off = false;
     return rc;
 }
@@ -748,45 +712,27 @@ int tls_ble_client_multi_conn_demo_api_deinit()
 {
     int rc = 0, i = 0;
     bool ret = false;
-    const struct peer *peer;
     TLS_BT_APPL_TRACE_DEBUG("### %s \r\n", __FUNCTION__);
-    
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
-        TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
-        return BLE_HS_EDISABLED;
-    }
 
-    if(g_ble_client_inited)
-    {
-        ret = wm_ble_check_all_connected();
-        if(!ret)
-        {
-            tls_ble_gap_scan(WM_BLE_SCAN_STOP , 0);
+    CHECK_SYSTEM_READY();
+
+    if(g_ble_client_inited) {
+        ret = wm_ble_check_all_connect_state(DEV_CONNECTED);
+
+        if(!ret) {
+            tls_ble_gap_scan(WM_BLE_SCAN_STOP, 0);
         }
+
         g_ble_client_switching_off = true;//indicating the demo is switching off;
-        
-        for(i = 0; i< MAX_CONN_DEVCIE_COUNT; i++)
-        {
-            if(conn_devices[i].conn_state == DEV_CONNECTED)
-            {
-                peer = get_peer_by_conn_handle(conn_devices[i].conn_handle);
 
-                if(peer)
-                {
-                    TLS_BT_APPL_TRACE_DEBUG("cancel subsribe and terminate the connection,idx=%d\r\n", i+1);
-                    wm_ble_client_demo_cancel_subscribe(peer);
-                }                
-            }else if(conn_devices[i].conn_state == DEV_CONNECTING)
-            {
+        for(i = 0; i < MAX_CONN_DEVCIE_COUNT; i++) {
+            if(conn_devices[i].conn_state == DEV_CONNECTED || conn_devices[i].conn_state == DEV_CONNECTING) {
                 ble_gap_terminate(conn_devices[i].conn_handle, BLE_ERR_REM_USER_CONN_TERM);
-            }
+            } 
         }
-        
+
         g_ble_client_inited = 0;
-        //peer_deinit();
-    }else
-    {
+    } else {
         rc = BLE_HS_EALREADY;
     }
 

+ 8 - 0
src/app/bleapp/wm_ble_client_api_multi_conn_demo.h

@@ -3,9 +3,17 @@
 
 #include "wm_bt_def.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 int tls_ble_client_multi_conn_demo_api_init();
 int tls_ble_client_multi_conn_demo_api_deinit();
 int tls_ble_client_multi_conn_demo_send_msg(uint8_t *ptr, int length);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
 

+ 171 - 177
src/app/bleapp/wm_ble_client_peer_manager.c

@@ -68,13 +68,11 @@ static struct peer *
 peer_find(uint16_t conn_handle)
 {
     struct peer *peer;
-
     SLIST_FOREACH(peer, &peers, next) {
-        if (peer->conn_handle == conn_handle) {
+        if(peer->conn_handle == conn_handle) {
             return peer;
         }
     }
-
     return NULL;
 }
 
@@ -84,7 +82,7 @@ peer_disc_complete(struct peer *peer, int rc)
     peer->disc_prev_chr_val = 0;
 
     /* Notify caller that discovery has completed. */
-    if (peer->disc_cb != NULL) {
+    if(peer->disc_cb != NULL) {
         peer->disc_cb(peer, rc, peer->disc_cb_arg);
     }
 }
@@ -94,16 +92,14 @@ peer_dsc_find_prev(const struct peer_chr *chr, uint16_t dsc_handle)
 {
     struct peer_dsc *prev;
     struct peer_dsc *dsc;
-
     prev = NULL;
     SLIST_FOREACH(dsc, &chr->dscs, next) {
-        if (dsc->dsc.handle >= dsc_handle) {
+        if(dsc->dsc.handle >= dsc_handle) {
             break;
         }
 
         prev = dsc;
     }
-
     return prev;
 }
 
@@ -113,21 +109,22 @@ peer_dsc_find(const struct peer_chr *chr, uint16_t dsc_handle,
 {
     struct peer_dsc *prev;
     struct peer_dsc *dsc;
-
     prev = peer_dsc_find_prev(chr, dsc_handle);
-    if (prev == NULL) {
+
+    if(prev == NULL) {
         dsc = SLIST_FIRST(&chr->dscs);
     } else {
         dsc = SLIST_NEXT(prev, next);
     }
 
-    if (dsc != NULL && dsc->dsc.handle != dsc_handle) {
+    if(dsc != NULL && dsc->dsc.handle != dsc_handle) {
         dsc = NULL;
     }
 
-    if (out_prev != NULL) {
+    if(out_prev != NULL) {
         *out_prev = prev;
     }
+
     return dsc;
 }
 
@@ -139,9 +136,9 @@ peer_dsc_add(struct peer *peer, uint16_t chr_val_handle,
     struct peer_dsc *dsc;
     struct peer_svc *svc;
     struct peer_chr *chr;
-
     svc = peer_svc_find_range(peer, chr_val_handle);
-    if (svc == NULL) {
+
+    if(svc == NULL) {
         /* Can't find service for discovered descriptor; this shouldn't
          * happen.
          */
@@ -150,7 +147,8 @@ peer_dsc_add(struct peer *peer, uint16_t chr_val_handle,
     }
 
     chr = peer_chr_find(svc, chr_val_handle, NULL);
-    if (chr == NULL) {
+
+    if(chr == NULL) {
         /* Can't find characteristic for discovered descriptor; this shouldn't
          * happen.
          */
@@ -159,21 +157,23 @@ peer_dsc_add(struct peer *peer, uint16_t chr_val_handle,
     }
 
     dsc = peer_dsc_find(chr, gatt_dsc->handle, &prev);
-    if (dsc != NULL) {
+
+    if(dsc != NULL) {
         /* Descriptor already discovered. */
         return 0;
     }
 
     dsc = os_memblock_get(&peer_dsc_pool);
-    if (dsc == NULL) {
+
+    if(dsc == NULL) {
         /* Out of memory. */
         return BLE_HS_ENOMEM;
     }
-    memset(dsc, 0, sizeof *dsc);
 
+    memset(dsc, 0, sizeof * dsc);
     dsc->dsc = *gatt_dsc;
 
-    if (prev == NULL) {
+    if(prev == NULL) {
         SLIST_INSERT_HEAD(&chr->dscs, dsc, next);
     } else {
         SLIST_NEXT(prev, next) = dsc;
@@ -188,22 +188,21 @@ peer_disc_dscs(struct peer *peer)
     struct peer_chr *chr;
     struct peer_svc *svc;
     int rc;
-
     /* Search through the list of discovered characteristics for the first
      * characteristic that contains undiscovered descriptors.  Then, discover
      * all descriptors belonging to that characteristic.
      */
     SLIST_FOREACH(svc, &peer->svcs, next) {
         SLIST_FOREACH(chr, &svc->chrs, next) {
-            if (!chr_is_empty(svc, chr) &&
-                SLIST_EMPTY(&chr->dscs) &&
-                peer->disc_prev_chr_val <= chr->chr.def_handle) {
-
+            if(!chr_is_empty(svc, chr) &&
+                    SLIST_EMPTY(&chr->dscs) &&
+                    peer->disc_prev_chr_val <= chr->chr.def_handle) {
                 rc = ble_gattc_disc_all_dscs(peer->conn_handle,
                                              chr->chr.val_handle,
                                              chr_end_handle(svc, chr),
                                              peer_dsc_disced, peer);
-                if (rc != 0) {
+
+                if(rc != 0) {
                     peer_disc_complete(peer, rc);
                 }
 
@@ -212,7 +211,6 @@ peer_disc_dscs(struct peer *peer)
             }
         }
     }
-
     /* All descriptors discovered. */
     peer_disc_complete(peer, 0);
 }
@@ -224,32 +222,33 @@ peer_dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
 {
     struct peer *peer;
     int rc;
-
     peer = arg;
     assert(peer->conn_handle == conn_handle);
 
-    switch (error->status) {
-    case 0:
-        rc = peer_dsc_add(peer, chr_val_handle, dsc);
-        break;
+    switch(error->status) {
+        case 0:
+            rc = peer_dsc_add(peer, chr_val_handle, dsc);
+            break;
 
-    case BLE_HS_EDONE:
-        /* All descriptors in this characteristic discovered; start discovering
-         * descriptors in the next characteristic.
-         */
-        if (peer->disc_prev_chr_val > 0) {
-            peer_disc_dscs(peer);
-        }
-        rc = 0;
-        break;
+        case BLE_HS_EDONE:
 
-    default:
-        /* Error; abort discovery. */
-        rc = error->status;
-        break;
+            /* All descriptors in this characteristic discovered; start discovering
+             * descriptors in the next characteristic.
+             */
+            if(peer->disc_prev_chr_val > 0) {
+                peer_disc_dscs(peer);
+            }
+
+            rc = 0;
+            break;
+
+        default:
+            /* Error; abort discovery. */
+            rc = error->status;
+            break;
     }
 
-    if (rc != 0) {
+    if(rc != 0) {
         /* Error; abort discovery. */
         peer_disc_complete(peer, rc);
     }
@@ -261,9 +260,9 @@ uint16_t
 chr_end_handle(const struct peer_svc *svc, const struct peer_chr *chr)
 {
     const struct peer_chr *next_chr;
-
     next_chr = SLIST_NEXT(chr, next);
-    if (next_chr != NULL) {
+
+    if(next_chr != NULL) {
         return next_chr->chr.def_handle - 1;
     } else {
         return svc->svc.end_handle;
@@ -281,16 +280,14 @@ peer_chr_find_prev(const struct peer_svc *svc, uint16_t chr_val_handle)
 {
     struct peer_chr *prev;
     struct peer_chr *chr;
-
     prev = NULL;
     SLIST_FOREACH(chr, &svc->chrs, next) {
-        if (chr->chr.val_handle >= chr_val_handle) {
+        if(chr->chr.val_handle >= chr_val_handle) {
             break;
         }
 
         prev = chr;
     }
-
     return prev;
 }
 
@@ -300,21 +297,22 @@ peer_chr_find(const struct peer_svc *svc, uint16_t chr_val_handle,
 {
     struct peer_chr *prev;
     struct peer_chr *chr;
-
     prev = peer_chr_find_prev(svc, chr_val_handle);
-    if (prev == NULL) {
+
+    if(prev == NULL) {
         chr = SLIST_FIRST(&svc->chrs);
     } else {
         chr = SLIST_NEXT(prev, next);
     }
 
-    if (chr != NULL && chr->chr.val_handle != chr_val_handle) {
+    if(chr != NULL && chr->chr.val_handle != chr_val_handle) {
         chr = NULL;
     }
 
-    if (out_prev != NULL) {
+    if(out_prev != NULL) {
         *out_prev = prev;
     }
+
     return chr;
 }
 
@@ -323,7 +321,7 @@ peer_chr_delete(struct peer_chr *chr)
 {
     struct peer_dsc *dsc;
 
-    while ((dsc = SLIST_FIRST(&chr->dscs)) != NULL) {
+    while((dsc = SLIST_FIRST(&chr->dscs)) != NULL) {
         SLIST_REMOVE_HEAD(&chr->dscs, next);
         os_memblock_put(&peer_dsc_pool, dsc);
     }
@@ -338,9 +336,9 @@ peer_chr_add(struct peer *peer,  uint16_t svc_start_handle,
     struct peer_chr *prev;
     struct peer_chr *chr;
     struct peer_svc *svc;
-
     svc = peer_svc_find(peer, svc_start_handle, NULL);
-    if (svc == NULL) {
+
+    if(svc == NULL) {
         /* Can't find service for discovered characteristic; this shouldn't
          * happen.
          */
@@ -349,21 +347,23 @@ peer_chr_add(struct peer *peer,  uint16_t svc_start_handle,
     }
 
     chr = peer_chr_find(svc, gatt_chr->def_handle, &prev);
-    if (chr != NULL) {
+
+    if(chr != NULL) {
         /* Characteristic already discovered. */
         return 0;
     }
 
     chr = os_memblock_get(&peer_chr_pool);
-    if (chr == NULL) {
+
+    if(chr == NULL) {
         /* Out of memory. */
         return BLE_HS_ENOMEM;
     }
-    memset(chr, 0, sizeof *chr);
 
+    memset(chr, 0, sizeof * chr);
     chr->chr = *gatt_chr;
 
-    if (prev == NULL) {
+    if(prev == NULL) {
         SLIST_INSERT_HEAD(&svc->chrs, chr, next);
     } else {
         SLIST_NEXT(prev, next) = chr;
@@ -378,31 +378,32 @@ peer_chr_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
 {
     struct peer *peer;
     int rc;
-
     peer = arg;
     assert(peer->conn_handle == conn_handle);
 
-    switch (error->status) {
-    case 0:
-        rc = peer_chr_add(peer, peer->cur_svc->svc.start_handle, chr);
-        break;
+    switch(error->status) {
+        case 0:
+            rc = peer_chr_add(peer, peer->cur_svc->svc.start_handle, chr);
+            break;
 
-    case BLE_HS_EDONE:
-        /* All characteristics in this service discovered; start discovering
-         * characteristics in the next service.
-         */
-        if (peer->disc_prev_chr_val > 0) {
-             peer_disc_chrs(peer);
-        }
-        rc = 0;
-        break;
+        case BLE_HS_EDONE:
 
-    default:
-        rc = error->status;
-        break;
+            /* All characteristics in this service discovered; start discovering
+             * characteristics in the next service.
+             */
+            if(peer->disc_prev_chr_val > 0) {
+                peer_disc_chrs(peer);
+            }
+
+            rc = 0;
+            break;
+
+        default:
+            rc = error->status;
+            break;
     }
 
-    if (rc != 0) {
+    if(rc != 0) {
         /* Error; abort discovery. */
         peer_disc_complete(peer, rc);
     }
@@ -415,25 +416,25 @@ peer_disc_chrs(struct peer *peer)
 {
     struct peer_svc *svc;
     int rc;
-
     /* Search through the list of discovered service for the first service that
      * contains undiscovered characteristics.  Then, discover all
      * characteristics belonging to that service.
      */
     SLIST_FOREACH(svc, &peer->svcs, next) {
-        if (!peer_svc_is_empty(svc) && SLIST_EMPTY(&svc->chrs)) {
+        if(!peer_svc_is_empty(svc) && SLIST_EMPTY(&svc->chrs)) {
             peer->cur_svc = svc;
             rc = ble_gattc_disc_all_chrs(peer->conn_handle,
                                          svc->svc.start_handle,
                                          svc->svc.end_handle,
                                          peer_chr_disced, peer);
-            if (rc != 0) {
+
+            if(rc != 0) {
                 peer_disc_complete(peer, rc);
             }
+
             return;
         }
     }
-
     /* All characteristics discovered. */
     peer_disc_dscs(peer);
 }
@@ -449,16 +450,14 @@ peer_svc_find_prev(struct peer *peer, uint16_t svc_start_handle)
 {
     struct peer_svc *prev;
     struct peer_svc *svc;
-
     prev = NULL;
     SLIST_FOREACH(svc, &peer->svcs, next) {
-        if (svc->svc.start_handle >= svc_start_handle) {
+        if(svc->svc.start_handle >= svc_start_handle) {
             break;
         }
 
         prev = svc;
     }
-
     return prev;
 }
 
@@ -468,21 +467,22 @@ peer_svc_find(struct peer *peer, uint16_t svc_start_handle,
 {
     struct peer_svc *prev;
     struct peer_svc *svc;
-
     prev = peer_svc_find_prev(peer, svc_start_handle);
-    if (prev == NULL) {
+
+    if(prev == NULL) {
         svc = SLIST_FIRST(&peer->svcs);
     } else {
         svc = SLIST_NEXT(prev, next);
     }
 
-    if (svc != NULL && svc->svc.start_handle != svc_start_handle) {
+    if(svc != NULL && svc->svc.start_handle != svc_start_handle) {
         svc = NULL;
     }
 
-    if (out_prev != NULL) {
+    if(out_prev != NULL) {
         *out_prev = prev;
     }
+
     return svc;
 }
 
@@ -490,15 +490,12 @@ static struct peer_svc *
 peer_svc_find_range(struct peer *peer, uint16_t attr_handle)
 {
     struct peer_svc *svc;
-
     SLIST_FOREACH(svc, &peer->svcs, next) {
-        if (svc->svc.start_handle <= attr_handle &&
-            svc->svc.end_handle >= attr_handle) {
-
+        if(svc->svc.start_handle <= attr_handle &&
+                svc->svc.end_handle >= attr_handle) {
             return svc;
         }
     }
-
     return NULL;
 }
 
@@ -506,13 +503,11 @@ const struct peer_svc *
 peer_svc_find_uuid(const struct peer *peer, const ble_uuid_t *uuid)
 {
     const struct peer_svc *svc;
-
     SLIST_FOREACH(svc, &peer->svcs, next) {
-        if (ble_uuid_cmp(&svc->svc.uuid.u, uuid) == 0) {
+        if(ble_uuid_cmp(&svc->svc.uuid.u, uuid) == 0) {
             return svc;
         }
     }
-
     return NULL;
 }
 
@@ -522,18 +517,17 @@ peer_chr_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid,
 {
     const struct peer_svc *svc;
     const struct peer_chr *chr;
-
     svc = peer_svc_find_uuid(peer, svc_uuid);
-    if (svc == NULL) {
+
+    if(svc == NULL) {
         return NULL;
     }
 
     SLIST_FOREACH(chr, &svc->chrs, next) {
-        if (ble_uuid_cmp(&chr->chr.uuid.u, chr_uuid) == 0) {
+        if(ble_uuid_cmp(&chr->chr.uuid.u, chr_uuid) == 0) {
             return chr;
         }
     }
-
     return NULL;
 }
 
@@ -543,18 +537,17 @@ peer_dsc_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid,
 {
     const struct peer_chr *chr;
     const struct peer_dsc *dsc;
-
     chr = peer_chr_find_uuid(peer, svc_uuid, chr_uuid);
-    if (chr == NULL) {
+
+    if(chr == NULL) {
         return NULL;
     }
 
     SLIST_FOREACH(dsc, &chr->dscs, next) {
-        if (ble_uuid_cmp(&dsc->dsc.uuid.u, dsc_uuid) == 0) {
+        if(ble_uuid_cmp(&dsc->dsc.uuid.u, dsc_uuid) == 0) {
             return dsc;
         }
     }
-
     return NULL;
 }
 
@@ -563,24 +556,25 @@ peer_svc_add(struct peer *peer, const struct ble_gatt_svc *gatt_svc)
 {
     struct peer_svc *prev;
     struct peer_svc *svc;
-
     svc = peer_svc_find(peer, gatt_svc->start_handle, &prev);
-    if (svc != NULL) {
+
+    if(svc != NULL) {
         /* Service already discovered. */
         return 0;
     }
 
     svc = os_memblock_get(&peer_svc_pool);
-    if (svc == NULL) {
+
+    if(svc == NULL) {
         /* Out of memory. */
         return BLE_HS_ENOMEM;
     }
-    memset(svc, 0, sizeof *svc);
 
+    memset(svc, 0, sizeof * svc);
     svc->svc = *gatt_svc;
     SLIST_INIT(&svc->chrs);
 
-    if (prev == NULL) {
+    if(prev == NULL) {
         SLIST_INSERT_HEAD(&peer->svcs, svc, next);
     } else {
         SLIST_INSERT_AFTER(prev, svc, next);
@@ -594,7 +588,7 @@ peer_svc_delete(struct peer_svc *svc)
 {
     struct peer_chr *chr;
 
-    while ((chr = SLIST_FIRST(&svc->chrs)) != NULL) {
+    while((chr = SLIST_FIRST(&svc->chrs)) != NULL) {
         SLIST_REMOVE_HEAD(&svc->chrs, next);
         peer_chr_delete(chr);
     }
@@ -608,31 +602,33 @@ peer_svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
 {
     struct peer *peer;
     int rc;
-
     peer = arg;
-    if(peer->conn_handle != conn_handle) return BLE_HS_EAPP;
-    
+
+    if(peer->conn_handle != conn_handle) { return BLE_HS_EAPP; }
+
     assert(peer->conn_handle == conn_handle);
 
-    switch (error->status) {
-    case 0:
-        rc = peer_svc_add(peer, service);
-        break;
+    switch(error->status) {
+        case 0:
+            rc = peer_svc_add(peer, service);
+            break;
 
-    case BLE_HS_EDONE:
-        /* All services discovered; start discovering characteristics. */
-        if (peer->disc_prev_chr_val > 0) {
-            peer_disc_chrs(peer);
-        }
-        rc = 0;
-        break;
+        case BLE_HS_EDONE:
 
-    default:
-        rc = error->status;
-        break;
+            /* All services discovered; start discovering characteristics. */
+            if(peer->disc_prev_chr_val > 0) {
+                peer_disc_chrs(peer);
+            }
+
+            rc = 0;
+            break;
+
+        default:
+            rc = error->status;
+            break;
     }
 
-    if (rc != 0) {
+    if(rc != 0) {
         /* Error; abort discovery. */
         peer_disc_complete(peer, rc);
     }
@@ -647,14 +643,14 @@ peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb, void *disc_cb_arg)
     struct peer_svc *svc;
     struct peer *peer;
     int rc;
-
     peer = peer_find(conn_handle);
-    if (peer == NULL) {
+
+    if(peer == NULL) {
         return BLE_HS_ENOTCONN;
     }
 
     /* Undiscover everything first. */
-    while ((svc = SLIST_FIRST(&peer->svcs)) != NULL) {
+    while((svc = SLIST_FIRST(&peer->svcs)) != NULL) {
         SLIST_REMOVE_HEAD(&peer->svcs, next);
         peer_svc_delete(svc);
     }
@@ -662,9 +658,9 @@ peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb, void *disc_cb_arg)
     peer->disc_prev_chr_val = 1;
     peer->disc_cb = disc_cb;
     peer->disc_cb_arg = disc_cb_arg;
-
     rc = ble_gattc_disc_all_svcs(conn_handle, peer_svc_disced, peer);
-    if (rc != 0) {
+
+    if(rc != 0) {
         return rc;
     }
 
@@ -677,21 +673,22 @@ peer_delete(uint16_t conn_handle)
     struct peer_svc *svc;
     struct peer *peer;
     int rc;
-
     peer = peer_find(conn_handle);
-    if (peer == NULL) {
+
+    if(peer == NULL) {
         return BLE_HS_ENOTCONN;
     }
 
     SLIST_REMOVE(&peers, peer, peer, next);
 
-    while ((svc = SLIST_FIRST(&peer->svcs)) != NULL) {
+    while((svc = SLIST_FIRST(&peer->svcs)) != NULL) {
         SLIST_REMOVE_HEAD(&peer->svcs, next);
         peer_svc_delete(svc);
     }
 
     rc = os_memblock_put(&peer_pool, peer);
-    if (rc != 0) {
+
+    if(rc != 0) {
         return BLE_HS_EOS;
     }
 
@@ -701,70 +698,62 @@ const struct peer *
 get_peer_by_conn_handle(uint16_t conn_handle)
 {
     struct peer *peer;
-
     peer = peer_find(conn_handle);
-
-    return peer;    
+    return peer;
 }
 
 int
 peer_add(uint16_t conn_handle)
 {
     struct peer *peer;
-
     /* Make sure the connection handle is unique. */
     peer = peer_find(conn_handle);
-    if (peer != NULL) {
+
+    if(peer != NULL) {
         return BLE_HS_EALREADY;
     }
 
     peer = os_memblock_get(&peer_pool);
-    if (peer == NULL) {
+
+    if(peer == NULL) {
         /* Out of memory. */
         return BLE_HS_ENOMEM;
     }
 
-    memset(peer, 0, sizeof *peer);
+    memset(peer, 0, sizeof * peer);
     peer->conn_handle = conn_handle;
-
     SLIST_INSERT_HEAD(&peers, peer, next);
-
     return 0;
 }
 
 static void
 peer_free_mem(void)
 {
-    if(peer_mem)
-    {
+    if(peer_mem) {
         tls_mem_free(peer_mem);
         peer_mem = NULL;
     }
-    
-    if(peer_svc_mem)
-    {
+
+    if(peer_svc_mem) {
         tls_mem_free(peer_svc_mem);
         peer_svc_mem = NULL;
     }
 
-    if(peer_chr_mem)
-    {
+    if(peer_chr_mem) {
         tls_mem_free(peer_chr_mem);
         peer_chr_mem = NULL;
     }
 
-    if(peer_dsc_mem)
-    {
+    if(peer_dsc_mem) {
         tls_mem_free(peer_dsc_mem);
         peer_dsc_mem = NULL;
     }
 }
 
-int 
+int
 peer_deinit()
 {
     peer_free_mem();
-
     return 0;
 }
 
@@ -772,72 +761,77 @@ int
 peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs)
 {
     int rc;
-
     /* Free memory first in case this function gets called more than once. */
     peer_free_mem();
-
     peer_mem = tls_mem_alloc(
-        OS_MEMPOOL_BYTES(max_peers, sizeof (struct peer)));
-    if (peer_mem == NULL) {
+                               OS_MEMPOOL_BYTES(max_peers, sizeof(struct peer)));
+
+    if(peer_mem == NULL) {
         rc = BLE_HS_ENOMEM;
         goto err;
     }
 
     rc = os_mempool_init(&peer_pool, max_peers,
-                         sizeof (struct peer), peer_mem,
+                         sizeof(struct peer), peer_mem,
                          "peer_pool");
-    if (rc != 0) {
+
+    if(rc != 0) {
         rc = BLE_HS_EOS;
         goto err;
     }
 
     peer_svc_mem = tls_mem_alloc(
-        OS_MEMPOOL_BYTES(max_svcs, sizeof (struct peer_svc)));
-    if (peer_svc_mem == NULL) {
+                                   OS_MEMPOOL_BYTES(max_svcs, sizeof(struct peer_svc)));
+
+    if(peer_svc_mem == NULL) {
         rc = BLE_HS_ENOMEM;
         goto err;
     }
 
     rc = os_mempool_init(&peer_svc_pool, max_svcs,
-                         sizeof (struct peer_svc), peer_svc_mem,
+                         sizeof(struct peer_svc), peer_svc_mem,
                          "peer_svc_pool");
-    if (rc != 0) {
+
+    if(rc != 0) {
         rc = BLE_HS_EOS;
         goto err;
     }
 
     peer_chr_mem = tls_mem_alloc(
-        OS_MEMPOOL_BYTES(max_chrs, sizeof (struct peer_chr)));
-    if (peer_chr_mem == NULL) {
+                                   OS_MEMPOOL_BYTES(max_chrs, sizeof(struct peer_chr)));
+
+    if(peer_chr_mem == NULL) {
         rc = BLE_HS_ENOMEM;
         goto err;
     }
 
     rc = os_mempool_init(&peer_chr_pool, max_chrs,
-                         sizeof (struct peer_chr), peer_chr_mem,
+                         sizeof(struct peer_chr), peer_chr_mem,
                          "peer_chr_pool");
-    if (rc != 0) {
+
+    if(rc != 0) {
         rc = BLE_HS_EOS;
         goto err;
     }
 
     peer_dsc_mem = tls_mem_alloc(
-        OS_MEMPOOL_BYTES(max_dscs, sizeof (struct peer_dsc)));
-    if (peer_dsc_mem == NULL) {
+                                   OS_MEMPOOL_BYTES(max_dscs, sizeof(struct peer_dsc)));
+
+    if(peer_dsc_mem == NULL) {
         rc = BLE_HS_ENOMEM;
         goto err;
     }
 
     rc = os_mempool_init(&peer_dsc_pool, max_dscs,
-                         sizeof (struct peer_dsc), peer_dsc_mem,
+                         sizeof(struct peer_dsc), peer_dsc_mem,
                          "peer_dsc_pool");
-    if (rc != 0) {
+
+    if(rc != 0) {
         rc = BLE_HS_EOS;
         goto err;
     }
 
     return 0;
-
 err:
     peer_free_mem();
     return rc;

+ 33 - 27
src/app/bleapp/wm_ble_client_util.c

@@ -37,7 +37,7 @@ print_bytes(const uint8_t *bytes, int len)
 {
     int i;
 
-    for (i = 0; i < len; i++) {
+    for(i = 0; i < len; i++) {
         MODLOG_DFLT(DEBUG, "%s0x%02x", i != 0 ? ":" : "", bytes[i]);
     }
 }
@@ -46,7 +46,7 @@ print_string(const int8_t *bytes, int len)
 {
     int i;
 
-    for (i = 0; i < len; i++) {
+    for(i = 0; i < len; i++) {
         MODLOG_DFLT(DEBUG, "%c", bytes[i]);
     }
 }
@@ -55,14 +55,15 @@ void
 print_mbuf(const struct os_mbuf *om)
 {
     int colon;
-
     colon = 0;
-    while (om != NULL) {
-        if (colon) {
+
+    while(om != NULL) {
+        if(colon) {
             MODLOG_DFLT(DEBUG, ":");
         } else {
             colon = 1;
         }
+
         print_bytes(om->om_data, om->om_len);
         om = SLIST_NEXT(om, om_next);
     }
@@ -73,11 +74,9 @@ addr_str(const void *addr)
 {
     static char buf[6 * 2 + 5 + 1];
     const uint8_t *u8p;
-
     u8p = addr;
     sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
             u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
-
     return buf;
 }
 
@@ -85,7 +84,6 @@ void
 print_uuid(const ble_uuid_t *uuid)
 {
     char buf[BLE_UUID_STR_LEN];
-
     MODLOG_DFLT(DEBUG, "%s", ble_uuid_to_str(uuid, buf));
 }
 
@@ -121,41 +119,47 @@ print_adv_fields(const struct ble_hs_adv_fields *fields)
     const uint8_t *u8p;
     int i;
 
-    if (fields->flags != 0) {
+    if(fields->flags != 0) {
         MODLOG_DFLT(DEBUG, "    flags=0x%02x\n", fields->flags);
     }
 
-    if (fields->uuids16 != NULL) {
+    if(fields->uuids16 != NULL) {
         MODLOG_DFLT(DEBUG, "    uuids16(%scomplete)=",
                     fields->uuids16_is_complete ? "" : "in");
-        for (i = 0; i < fields->num_uuids16; i++) {
+
+        for(i = 0; i < fields->num_uuids16; i++) {
             print_uuid(&fields->uuids16[i].u);
             MODLOG_DFLT(DEBUG, " ");
         }
+
         MODLOG_DFLT(DEBUG, "\n");
     }
 
-    if (fields->uuids32 != NULL) {
+    if(fields->uuids32 != NULL) {
         MODLOG_DFLT(DEBUG, "    uuids32(%scomplete)=",
                     fields->uuids32_is_complete ? "" : "in");
-        for (i = 0; i < fields->num_uuids32; i++) {
+
+        for(i = 0; i < fields->num_uuids32; i++) {
             print_uuid(&fields->uuids32[i].u);
             MODLOG_DFLT(DEBUG, " ");
         }
+
         MODLOG_DFLT(DEBUG, "\n");
     }
 
-    if (fields->uuids128 != NULL) {
+    if(fields->uuids128 != NULL) {
         MODLOG_DFLT(DEBUG, "    uuids128(%scomplete)=",
                     fields->uuids128_is_complete ? "" : "in");
-        for (i = 0; i < fields->num_uuids128; i++) {
+
+        for(i = 0; i < fields->num_uuids128; i++) {
             print_uuid(&fields->uuids128[i].u);
             MODLOG_DFLT(DEBUG, " ");
         }
+
         MODLOG_DFLT(DEBUG, "\n");
     }
 
-    if (fields->name != NULL) {
+    if(fields->name != NULL) {
         assert(fields->name_len < sizeof s - 1);
         memcpy(s, fields->name, fields->name_len);
         s[fields->name_len] = '\0';
@@ -163,59 +167,61 @@ print_adv_fields(const struct ble_hs_adv_fields *fields)
                     fields->name_is_complete ? "" : "in", s);
     }
 
-    if (fields->tx_pwr_lvl_is_present) {
+    if(fields->tx_pwr_lvl_is_present) {
         MODLOG_DFLT(DEBUG, "    tx_pwr_lvl=%d\n", fields->tx_pwr_lvl);
     }
 
-    if (fields->slave_itvl_range != NULL) {
+    if(fields->slave_itvl_range != NULL) {
         MODLOG_DFLT(DEBUG, "    slave_itvl_range=");
         print_bytes(fields->slave_itvl_range, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN);
         MODLOG_DFLT(DEBUG, "\n");
     }
 
-    if (fields->svc_data_uuid16 != NULL) {
+    if(fields->svc_data_uuid16 != NULL) {
         MODLOG_DFLT(DEBUG, "    svc_data_uuid16=");
         print_bytes(fields->svc_data_uuid16, fields->svc_data_uuid16_len);
         MODLOG_DFLT(DEBUG, "\n");
     }
 
-    if (fields->public_tgt_addr != NULL) {
+    if(fields->public_tgt_addr != NULL) {
         MODLOG_DFLT(DEBUG, "    public_tgt_addr=");
         u8p = fields->public_tgt_addr;
-        for (i = 0; i < fields->num_public_tgt_addrs; i++) {
+
+        for(i = 0; i < fields->num_public_tgt_addrs; i++) {
             MODLOG_DFLT(DEBUG, "public_tgt_addr=%s ", addr_str(u8p));
             u8p += BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN;
         }
+
         MODLOG_DFLT(DEBUG, "\n");
     }
 
-    if (fields->appearance_is_present) {
+    if(fields->appearance_is_present) {
         MODLOG_DFLT(DEBUG, "    appearance=0x%04x\n", fields->appearance);
     }
 
-    if (fields->adv_itvl_is_present) {
+    if(fields->adv_itvl_is_present) {
         MODLOG_DFLT(DEBUG, "    adv_itvl=0x%04x\n", fields->adv_itvl);
     }
 
-    if (fields->svc_data_uuid32 != NULL) {
+    if(fields->svc_data_uuid32 != NULL) {
         MODLOG_DFLT(DEBUG, "    svc_data_uuid32=");
         print_bytes(fields->svc_data_uuid32, fields->svc_data_uuid32_len);
         MODLOG_DFLT(DEBUG, "\n");
     }
 
-    if (fields->svc_data_uuid128 != NULL) {
+    if(fields->svc_data_uuid128 != NULL) {
         MODLOG_DFLT(DEBUG, "    svc_data_uuid128=");
         print_bytes(fields->svc_data_uuid128, fields->svc_data_uuid128_len);
         MODLOG_DFLT(DEBUG, "\n");
     }
 
-    if (fields->uri != NULL) {
+    if(fields->uri != NULL) {
         MODLOG_DFLT(DEBUG, "    uri=");
         print_bytes(fields->uri, fields->uri_len);
         MODLOG_DFLT(DEBUG, "\n");
     }
 
-    if (fields->mfg_data != NULL) {
+    if(fields->mfg_data != NULL) {
         MODLOG_DFLT(DEBUG, "    mfg_data=");
         print_bytes(fields->mfg_data, fields->mfg_data_len);
         MODLOG_DFLT(DEBUG, "\n");

+ 149 - 283
src/app/bleapp/wm_ble_gap.c

@@ -2,7 +2,7 @@
 **
 **  Name:           wm_ble_gap.c
 **
-**  Description:    This file contains the simply functions between nimble host and tuya hal layer
+**  Description:    This file contains the simply functions for GAP
 **
 *****************************************************************************/
 
@@ -25,7 +25,7 @@
 #include "host/util/util.h"
 #include "wm_ble_gap.h"
 #include "services/gap/ble_svc_gap.h"
-#include "wm_bt_storage.h"
+#include "store/config/wm_bt_storage.h"
 
 /*
  * STRUCTURE DEFINITIONS
@@ -33,9 +33,9 @@
  */
 
 typedef struct {
-	struct dl_list list;
-	uint32_t evt;
-	app_gap_evt_cback_t *reg_func_ptr;
+    struct dl_list list;
+    uint32_t evt;
+    app_gap_evt_cback_t *reg_func_ptr;
     struct ble_npl_mutex list_mutex;
 } report_evt_t;
 
@@ -43,8 +43,6 @@ typedef struct {
  * GLOBAL VARIABLE DEFINITIONS
  ****************************************************************************************
  */
-
-static report_evt_t report_evt_list;
 static struct ble_gap_disc_params disc_params_dft;
 static struct ble_gap_adv_params adv_params_dft;
 static ble_addr_t   direct_adv_addr;
@@ -64,33 +62,7 @@ static ble_addr_t   direct_adv_addr;
 static int
 gap_event(struct ble_gap_event *event, void *arg)
 {
-    int rc = 0;
-    uint32_t evt = (0x01)<<event->type;
-    report_evt_t *report_evt = NULL;
-    report_evt_t *report_evt_next = NULL;
-
-    TLS_BT_APPL_TRACE_EVENT("gap_event, [%s]\n",tls_bt_gap_evt_2_str(event->type));
-
-    /*Notify those who cares the event type*/
-    ble_npl_mutex_pend(&report_evt_list.list_mutex, 0);
-
-    if(!dl_list_empty(&report_evt_list.list))
-    {
-        dl_list_for_each_safe(report_evt,report_evt_next, &report_evt_list.list, report_evt_t, list)
-        {
-            ble_npl_mutex_release(&report_evt_list.list_mutex);
-
-            if((report_evt)&&(report_evt->evt&evt)&&(report_evt->reg_func_ptr))
-            {
-                rc = report_evt->reg_func_ptr(event, arg);
-            }
-
-            ble_npl_mutex_pend(&report_evt_list.list_mutex, 0);
-        }
-    }
-    ble_npl_mutex_release(&report_evt_list.list_mutex);
-
-    return rc;
+    return 0;
 }
 /**
  * Initiates the GAP general discovery procedure.
@@ -101,21 +73,20 @@ scan_enable(uint8_t type, bool filter_duplicate)
     uint8_t own_addr_type;
     struct ble_gap_disc_params disc_params;
     int rc;
-
     /* Figure out address to use while advertising (no privacy for now) */
     rc = ble_hs_id_infer_auto(0, &own_addr_type);
-    if (rc != 0) {
+
+    if(rc != 0) {
         TLS_BT_APPL_TRACE_ERROR("error determining address type; rc=%d\r\n", rc);
         return rc;
     }
+
     /* Tell the controller to filter duplicates; we don't want to process
      * repeated advertisements from the same device.
      */
-    if(filter_duplicate)
-    {
+    if(filter_duplicate) {
         disc_params.filter_duplicates = 1;
-    }else
-    {
+    } else {
         disc_params.filter_duplicates = 0;
     }
 
@@ -126,54 +97,31 @@ scan_enable(uint8_t type, bool filter_duplicate)
     disc_params.passive = type;
 
     /* Use defaults for the rest of the parameters. */
-    if(disc_params_dft.itvl)
-    {
+    if(disc_params_dft.itvl) {
         disc_params.itvl = disc_params_dft.itvl;
-    }else
-    {
+    } else {
         disc_params.itvl = 0x40;
     }
 
-    if(disc_params_dft.window)
-    {
+    if(disc_params_dft.window) {
         disc_params.window = disc_params_dft.window;
-    }else
-    {
+    } else {
         disc_params.window = 0x20;
     }
 
     disc_params.filter_policy = disc_params_dft.filter_policy;
     disc_params.limited = disc_params_dft.limited;
-
     rc = ble_gap_disc(own_addr_type, BLE_HS_FOREVER, &disc_params,
                       gap_event, NULL);
-    if (rc != 0) {
+
+    if(rc != 0) {
         TLS_BT_APPL_TRACE_ERROR("Error initiating GAP discovery procedure; rc=%d\n",
-                    rc);
+                                rc);
     }
 
     return rc;
 }
 
-static void tls_ble_gap_free_left_report_list()
-{
-	report_evt_t *evt = NULL;
-	report_evt_t *evt_next = NULL;
-
-	if(dl_list_empty(&report_evt_list.list))
-		return ;
-
-	ble_npl_mutex_pend(&report_evt_list.list_mutex, 0);
-
-	dl_list_for_each_safe(evt, evt_next,&report_evt_list.list, report_evt_t, list)
-	{
-		dl_list_del(&evt->list);
-		tls_mem_free(evt);
-	}
-
-	ble_npl_mutex_release(&report_evt_list.list_mutex);
-}
-
 /*
  * EXPORTED FUNCTION DEFINITIONS
  ****************************************************************************************
@@ -183,65 +131,95 @@ int tls_nimble_gap_adv(wm_ble_adv_type_t type, int duration)
 {
     int rc ;
 
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
+    if(bt_adapter_state == WM_BT_STATE_OFF || bt_system_action != WM_BT_SYSTEM_ACTION_IDLE) {
         TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
         return BLE_HS_EDISABLED;
     }
 
-    if(type)
-    {
+    if(type) {
         uint8_t own_addr_type;
         struct ble_gap_adv_params adv_params;
-
         /* Figure out address to use while advertising (no privacy for now) */
         rc = ble_hs_id_infer_auto(0, &own_addr_type);
-        if (rc != 0) {
+
+        if(rc != 0) {
             TLS_BT_APPL_TRACE_ERROR("error determining address type; rc=%d\r\n", rc);
             return rc;
         }
 
         /* set adv parameters */
         memset(&adv_params, 0, sizeof(adv_params));
-
-        adv_params.conn_mode = adv_params_dft.conn_mode;
-        adv_params.disc_mode = adv_params_dft.disc_mode;
+        
+        if(adv_params_dft.conn_mode == BLE_GAP_CONN_MODE_NON && adv_params_dft.disc_mode == BLE_GAP_DISC_MODE_NON)
+        {
+            switch(type) {
+                case WM_BLE_ADV_IND:
+                    adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
+                    adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
+                    break;
+            
+                case WM_BLE_ADV_NONCONN_IND:
+                    adv_params.conn_mode = BLE_GAP_CONN_MODE_NON;
+                    adv_params.disc_mode = BLE_GAP_DISC_MODE_NON;
+                    break;
+            
+                case WM_BLE_ADV_SCAN_IND:
+                    adv_params.conn_mode = BLE_GAP_CONN_MODE_NON;
+                    adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; // LTD same as GEN;
+                    break;
+            
+                case WM_BLE_ADV_DIRECT_IND_HDC:
+                    adv_params.high_duty_cycle = 1;
+            
+                //passthrough;
+                case WM_BLE_ADV_DIRECT_IND_LDC:
+                    adv_params.conn_mode = BLE_GAP_CONN_MODE_DIR;
+                    adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
+            
+                    if(ble_addr_cmp(&direct_adv_addr, BLE_ADDR_ANY) == 0) {
+                        return BLE_HS_EINVAL;
+                    }
+            
+                    break;
+            
+                default:
+                    /**/
+                    adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
+                    adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
+                    break;
+            }
+       }else
+       {
+            adv_params.conn_mode = adv_params_dft.conn_mode;
+            adv_params.disc_mode = adv_params_dft.disc_mode;
+       }
         adv_params.high_duty_cycle = adv_params_dft.high_duty_cycle;
         adv_params.channel_map = adv_params_dft.channel_map;
         adv_params.filter_policy = adv_params_dft.filter_policy;
 
-        if(adv_params_dft.itvl_min)
-        {
+        if(adv_params_dft.itvl_min) {
             adv_params.itvl_min = adv_params_dft.itvl_min;
-        }else
-        {
-            adv_params.itvl_min = 0x40;
+        } else {
+            adv_params.itvl_min = 160;
         }
 
-        if(adv_params_dft.itvl_max)
-        {
+        if(adv_params_dft.itvl_max) {
             adv_params.itvl_max = adv_params_dft.itvl_max;
-        }else
-        {
-            adv_params.itvl_max = 0x40;
+        } else {
+            adv_params.itvl_max = 160;
         }
 
-
         TLS_BT_APPL_TRACE_DEBUG("Starting advertising\r\n");
-
-
         /* As own address type we use hard-coded value, because we generate
               NRPA and by definition it's random */
-        rc = ble_gap_adv_start(own_addr_type, &direct_adv_addr, duration?duration:BLE_HS_FOREVER,
+        rc = ble_gap_adv_start(own_addr_type, &direct_adv_addr, duration ? duration : BLE_HS_FOREVER,
                                &adv_params, gap_event, NULL);
+
         //assert(rc == 0);
-        if(rc)
-        {
-           TLS_BT_APPL_TRACE_WARNING("Starting advertising failed, rc=%d\r\n", rc);
+        if(rc) {
+            TLS_BT_APPL_TRACE_WARNING("Starting advertising failed, rc=%d\r\n", rc);
         }
-
-    }else
-    {
+    } else {
         TLS_BT_APPL_TRACE_DEBUG("Stop advertising\r\n");
         rc = ble_gap_adv_stop();
     }
@@ -254,108 +232,42 @@ int tls_ble_gap_scan(wm_ble_scan_type_t type, bool filter_duplicate)
 {
     int rc = 1;
 
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
+    if(bt_adapter_state == WM_BT_STATE_OFF || bt_system_action != WM_BT_SYSTEM_ACTION_IDLE) {
         TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
         return BLE_HS_EDISABLED;
     }
 
-    if((type == WM_BLE_SCAN_STOP) && (g_scan_state != type))
-    {
+    if((type == WM_BLE_SCAN_STOP) && (g_scan_state != type)) {
         rc = ble_gap_disc_cancel();
-
-    }else if((type == WM_BLE_SCAN_PASSIVE)&&(g_scan_state == WM_BLE_SCAN_STOP))
-    {
+    } else if((type == WM_BLE_SCAN_PASSIVE) && (g_scan_state == WM_BLE_SCAN_STOP)) {
         /*passive scan*/
         rc = scan_enable(1, filter_duplicate);
-
-    }else if((type == WM_BLE_SCAN_ACTIVE) &&(g_scan_state == WM_BLE_SCAN_STOP))
-    {
+    } else if((type == WM_BLE_SCAN_ACTIVE) && (g_scan_state == WM_BLE_SCAN_STOP)) {
         /*active scan*/
-        rc = scan_enable(0,filter_duplicate);
+        rc = scan_enable(0, filter_duplicate);
     }
 
-    if(rc == 0)
-    {
+    if(rc == 0) {
         g_scan_state = type;
     }
 
     return rc;
 }
 
-
-
-int tls_ble_register_gap_evt(uint32_t evt_type, app_gap_evt_cback_t *evt_cback)
-{
-    int rc = 0;
-	report_evt_t *evt = NULL;
-
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
-        TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
-        return BLE_HS_EDISABLED;
-    }
-
-
-    ble_npl_mutex_pend(&report_evt_list.list_mutex, 0);
-
-	dl_list_for_each(evt, &report_evt_list.list, report_evt_t, list)
-	{
-		if(evt->reg_func_ptr == evt_cback)
-		{
-			if(evt->evt&evt_type)
-			{
-				/*Already in the list, do nothing*/
-                ble_npl_mutex_release(&report_evt_list.list_mutex);
-				return rc;
-			}else
-			{
-				/*Appending this evt to monitor list*/
-				evt->evt |= evt_type;
-                ble_npl_mutex_release(&report_evt_list.list_mutex);
-				return rc;
-			}
-		}
-	}
-    ble_npl_mutex_release(&report_evt_list.list_mutex);
-
-	evt = tls_mem_alloc(sizeof(report_evt_t));
-	if(evt == NULL)
-	{
-		return BLE_HS_ENOMEM;
-	}
-
-	memset(evt, 0, sizeof(report_evt_t));
-	evt->reg_func_ptr = evt_cback;
-	evt->evt = evt_type;
-
-    ble_npl_mutex_pend(&report_evt_list.list_mutex, 0);
-    dl_list_add_tail(&report_evt_list.list, &evt->list);
-    ble_npl_mutex_release(&report_evt_list.list_mutex);
-
-	return rc;
-
-}
-
 int tls_ble_gap_set_data(wm_ble_gap_data_t type, uint8_t *data, int data_len)
 {
     int rc;
 
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
+    if(bt_adapter_state == WM_BT_STATE_OFF || bt_system_action != WM_BT_SYSTEM_ACTION_IDLE) {
         TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
         return BLE_HS_EDISABLED;
     }
 
-
-    if(type == WM_BLE_ADV_DATA)
-    {
-        rc = ble_gap_adv_set_data(data,data_len);
-    }else if(type == WM_BLE_ADV_RSP_DATA)
-    {
-        rc = ble_gap_adv_rsp_set_data(data,data_len);
-    }else
-    {
+    if(type == WM_BLE_ADV_DATA) {
+        rc = ble_gap_adv_set_data(data, data_len);
+    } else if(type == WM_BLE_ADV_RSP_DATA) {
+        rc = ble_gap_adv_rsp_set_data(data, data_len);
+    } else {
         rc = -1;
     }
 
@@ -366,20 +278,19 @@ int tls_ble_gap_set_name(const char *dev_name, uint8_t update_flash)
 {
     int ret;
     assert(dev_name != NULL);
-
     /*config host stack device name*/
     ble_svc_gap_device_name_set(dev_name);
 
     /*Update ram information and flush it if needed*/
-    if(update_flash)
-    {
+    if(update_flash) {
         ret = btif_config_set_str("Local", "Adapter", "Name", dev_name);
-        if(ret)
-        {
+
+        if(ret) {
             ret = btif_config_flush(update_flash);
             return 0;
         }
     }
+
     return ret;
 }
 int tls_ble_gap_get_name(char *dev_name)
@@ -387,11 +298,10 @@ int tls_ble_gap_get_name(char *dev_name)
     int ret;
     int ret_size = 0;
     assert(dev_name != NULL);
-
     /*Update ram information and flush it if needed*/
     ret = btif_config_get_str("Local", "Adapter", "Name", dev_name, &ret_size);
-    if(!ret)
-    {
+
+    if(!ret) {
         memset(dev_name, 0, 16);
         const char *p = ble_svc_gap_device_name();
         strncpy(dev_name, p, 16);
@@ -402,178 +312,134 @@ int tls_ble_gap_get_name(char *dev_name)
 }
 #define BLE_ISVALID_PARAM(x, min, max)  ((x) >= (min) && (x) <= (max))
 
-int tls_ble_gap_set_adv_param(uint8_t adv_type, uint32_t min, uint32_t max, uint8_t chn_map, uint8_t filter_policy,uint8_t *dir_mac,uint8_t dir_mac_type)
+int tls_ble_gap_set_adv_param(uint8_t adv_type, uint32_t min, uint32_t max, uint8_t chn_map,
+                              uint8_t filter_policy, uint8_t *dir_mac, uint8_t dir_mac_type)
 {
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
+    if(bt_adapter_state == WM_BT_STATE_OFF || bt_system_action != WM_BT_SYSTEM_ACTION_IDLE) {
         TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
         return BLE_HS_EDISABLED;
     }
 
-
     /*!!!make sure the param is valid!!!*/
-    if(!BLE_ISVALID_PARAM(min, 0x20, 0x4000) || !BLE_ISVALID_PARAM(max, 0x20, 0x4000))
-    {
+    if(!BLE_ISVALID_PARAM(min, 0x20, 0x4000) || !BLE_ISVALID_PARAM(max, 0x20, 0x4000)) {
         return BLE_HS_EINVAL;
     }
-    if(min > max)
-    {
+
+    if(min > max) {
         return BLE_HS_EINVAL;
     }
 
-    if((chn_map&0x07) == 0x00)
-    {
+    if((chn_map & 0x07) == 0x00) {
         return BLE_HS_EINVAL;
     }
 
-    if(filter_policy > 0x03)
-    {
+    if(filter_policy > 0x03) {
         return BLE_HS_EINVAL;
     }
 
-    if(dir_mac_type > 0x01)
-    {
+    if(dir_mac_type > 0x01) {
         return BLE_HS_EINVAL;
     }
 
     memset(&adv_params_dft, 0, sizeof(adv_params_dft));
 
-
-    switch(adv_type)
-    {
+    switch(adv_type) {
         case WM_BLE_ADV_IND:
-                adv_params_dft.conn_mode = BLE_GAP_CONN_MODE_UND;
-                adv_params_dft.disc_mode = BLE_GAP_DISC_MODE_GEN;
+            adv_params_dft.conn_mode = BLE_GAP_CONN_MODE_UND;
+            adv_params_dft.disc_mode = BLE_GAP_DISC_MODE_GEN;
             break;
+
         case WM_BLE_ADV_NONCONN_IND:
-                adv_params_dft.conn_mode = BLE_GAP_CONN_MODE_NON;
-                adv_params_dft.disc_mode = BLE_GAP_DISC_MODE_NON;
+            adv_params_dft.conn_mode = BLE_GAP_CONN_MODE_NON;
+            adv_params_dft.disc_mode = BLE_GAP_DISC_MODE_NON;
             break;
+
         case WM_BLE_ADV_SCAN_IND:
-                adv_params_dft.conn_mode = BLE_GAP_CONN_MODE_NON;
-                adv_params_dft.disc_mode = BLE_GAP_DISC_MODE_GEN; // LTD same as GEN;
+            adv_params_dft.conn_mode = BLE_GAP_CONN_MODE_NON;
+            adv_params_dft.disc_mode = BLE_GAP_DISC_MODE_GEN; // LTD same as GEN;
             break;
+
         case WM_BLE_ADV_DIRECT_IND_HDC:
-                adv_params_dft.high_duty_cycle = 1;
-                //passthrough;
+            adv_params_dft.high_duty_cycle = 1;
+
+        //passthrough;
         case WM_BLE_ADV_DIRECT_IND_LDC:
-                adv_params_dft.conn_mode = BLE_GAP_CONN_MODE_DIR;
-                adv_params_dft.disc_mode = BLE_GAP_DISC_MODE_GEN;
+            adv_params_dft.conn_mode = BLE_GAP_CONN_MODE_DIR;
+            adv_params_dft.disc_mode = BLE_GAP_DISC_MODE_GEN;
+
+            if(ble_addr_cmp(&direct_adv_addr, BLE_ADDR_ANY) == 0) {
+                return BLE_HS_EINVAL;
+            }
 
-                if(ble_addr_cmp(&direct_adv_addr, BLE_ADDR_ANY) == 0)
-                {
-                    return BLE_HS_EINVAL;
-                }
             break;
-       default:
-                /**/
-                adv_params_dft.conn_mode = BLE_GAP_CONN_MODE_UND;
-                adv_params_dft.disc_mode = BLE_GAP_DISC_MODE_GEN;
+
+        default:
+            /**/
+            adv_params_dft.conn_mode = BLE_GAP_CONN_MODE_UND;
+            adv_params_dft.disc_mode = BLE_GAP_DISC_MODE_GEN;
             break;
     }
 
     adv_params_dft.itvl_min = min;
     adv_params_dft.itvl_max = max;
-    adv_params_dft.channel_map = chn_map&0x07;
+    adv_params_dft.channel_map = chn_map & 0x07;
     adv_params_dft.filter_policy = filter_policy;
 
-    if(dir_mac)
-    {
+    if(dir_mac) {
         direct_adv_addr.type = dir_mac_type;
         memcpy(direct_adv_addr.val, dir_mac, 6);
     }
 
     return 0;
 }
-int tls_ble_gap_set_scan_param(uint32_t window, uint32_t intv, uint8_t filter_policy, bool limited, bool passive, bool filter_duplicate)
+int tls_ble_gap_set_scan_param(uint32_t window, uint32_t intv, uint8_t filter_policy, bool limited,
+                               bool passive, bool filter_duplicate)
 {
     memset(&disc_params_dft, 0, sizeof(disc_params_dft));
-
     disc_params_dft.itvl = intv;
     disc_params_dft.window = window;
     disc_params_dft.filter_policy = filter_policy;
-    if(limited) disc_params_dft.limited = 1;
-    if(passive) disc_params_dft.passive = 1;
-    if(filter_duplicate) disc_params_dft.filter_duplicates = 1;
 
-    return 0;
-}
-
-int tls_ble_deregister_gap_evt(uint32_t evt_type, app_gap_evt_cback_t *evt_cback)
-{
-	report_evt_t *evt = NULL;
-	report_evt_t *evt_next = NULL;
+    if(limited) { disc_params_dft.limited = 1; }
 
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
-        TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
-        return BLE_HS_EDISABLED;
-    }
+    if(passive) { disc_params_dft.passive = 1; }
 
-	ble_npl_mutex_pend(&report_evt_list.list_mutex, 0);
-    if(!dl_list_empty(&report_evt_list.list))
-    {
-    	dl_list_for_each_safe(evt,evt_next, &report_evt_list.list, report_evt_t, list)
-    	{
-    	    ble_npl_mutex_release(&report_evt_list.list_mutex);
-    		if((evt->reg_func_ptr == evt_cback))
-    		{
-    			evt->evt &= ~evt_type; //clear monitor bit;
-
-    			if(evt->evt == 0)    //no evt left;
-    			{
-    				dl_list_del(&evt->list);
-    				tls_mem_free(evt);
-                    evt = NULL;
-    			}
-    		}
-            ble_npl_mutex_pend(&report_evt_list.list_mutex, 0);
-    	}
-    }
-	ble_npl_mutex_release(&report_evt_list.list_mutex);
+    if(filter_duplicate) { disc_params_dft.filter_duplicates = 1; }
 
-	return 0;
+    return 0;
 }
 
+
 int tls_ble_gap_deinit(void)
 {
     /*TODO how to release the character/service list?*/
     /**only be called when bluetooth system turning off, the character/service list is freed by ble_hs_stop() */
-
     /*Do not forget to release  report event list*/
-    tls_ble_gap_free_left_report_list();
-    ble_npl_mutex_deinit(&report_evt_list.list_mutex);
-
     return 0;
 }
 
-int tls_ble_gap_init(char * name)
+int tls_ble_gap_init(void)
 {
     char default_device_name[MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH)];
     uint8_t bt_mac[6];
     int ret_len = 0;
-
+    
     g_scan_state = WM_BLE_SCAN_STOP;
     memset(&adv_params_dft, 0, sizeof(adv_params_dft));
-    adv_params_dft.conn_mode = BLE_GAP_CONN_MODE_UND;  //default conn  mode;
-    adv_params_dft.disc_mode = BLE_GAP_DISC_MODE_GEN;  //default disc  mode;
+    //adv_params_dft.conn_mode = BLE_GAP_CONN_MODE_UND;  //default conn  mode;
+    //adv_params_dft.disc_mode = BLE_GAP_DISC_MODE_GEN;  //default disc  mode;
     memset(&disc_params_dft, 0, sizeof(disc_params_dft));
     memset(&direct_adv_addr, 0, sizeof(direct_adv_addr));
-    dl_list_init(&report_evt_list.list);
-    ble_npl_mutex_init(&report_evt_list.list_mutex);
-
-    // if(btif_config_get_str("Local", "Adapter", "Name", default_device_name, &ret_len))
-    // {
-    //     ble_svc_gap_device_name_set(default_device_name);
-    // }else
-    // {
+
+    if(btif_config_get_str("Local", "Adapter", "Name", default_device_name, &ret_len)) {
+        ble_svc_gap_device_name_set(default_device_name);
+    } else {
+        extern int tls_get_bt_mac_addr(u8 * mac);
         tls_get_bt_mac_addr(bt_mac);
-        if(name != NULL)
-            sprintf(default_device_name, "%s", name);
-        else
-            sprintf(default_device_name, "LOS-%02X%02X%02X", bt_mac[3], bt_mac[4], bt_mac[5]);
+        sprintf(default_device_name, "WM-%02X:%02X:%02X", bt_mac[3], bt_mac[4], bt_mac[5]);
         ble_svc_gap_device_name_set(default_device_name);
-    // }
+    }
+
     return 0;
 }
 #endif

+ 17 - 9
src/app/bleapp/wm_ble_gap.h

@@ -1,23 +1,31 @@
-#ifndef __WM_BLE_WIFI_INCLUDE_H__
-#define __WM_BLE_WIFI_INCLUDE_H__
+#ifndef __WM_BLE_GAP_INCLUDE_H__
+#define __WM_BLE_GAP_INCLUDE_H__
 
 #include "wm_bt.h"
 #include "host/ble_gap.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef int (app_gap_evt_cback_t)(struct ble_gap_event *event, void *arg);
 
-extern int tls_ble_gap_init(char * name);
+extern int tls_ble_gap_init(void);
 extern int tls_ble_gap_deinit(void);
-extern int tls_nimble_gap_adv(wm_ble_adv_type_t type , int duration);
-extern int tls_ble_gap_set_adv_param(uint8_t adv_type, uint32_t min, uint32_t max, uint8_t chn_map, uint8_t filter_policy,uint8_t *dir_mac, uint8_t dir_mac_type);
-extern int tls_ble_gap_set_scan_param(uint32_t window, uint32_t intv, uint8_t filter_policy, bool limited, bool passive, bool filter_duplicate);
-extern int tls_ble_gap_set_name(const char *dev_name,uint8_t update_flash);
+extern int tls_nimble_gap_adv(wm_ble_adv_type_t type, int duration);
+extern int tls_ble_gap_set_adv_param(uint8_t adv_type, uint32_t min, uint32_t max, uint8_t chn_map,
+                                     uint8_t filter_policy, uint8_t *dir_mac, uint8_t dir_mac_type);
+extern int tls_ble_gap_set_scan_param(uint32_t window, uint32_t intv, uint8_t filter_policy,
+                                      bool limited, bool passive, bool filter_duplicate);
+extern int tls_ble_gap_set_name(const char *dev_name, uint8_t update_flash);
 extern int tls_ble_gap_get_name(char *dev_name);
 extern int tls_ble_gap_set_data(wm_ble_gap_data_t type, uint8_t *data, int data_len);
 extern int tls_ble_gap_scan(wm_ble_scan_type_t type, bool filter_duplicate);
-extern int tls_ble_register_gap_evt(uint32_t evt_type, app_gap_evt_cback_t *evt_cback);
-extern int tls_ble_deregister_gap_evt(uint32_t evt_type, app_gap_evt_cback_t *evt_cback);
 
 
+#ifdef __cplusplus
+}
+#endif
+
 
 #endif

+ 1417 - 0
src/app/bleapp/wm_ble_mesh.c

@@ -0,0 +1,1417 @@
+/*****************************************************************************
+**
+**  Name:           wm_ble_mesh.c
+**
+**  Description:    This file contains the sample functions for mesh application
+**
+*****************************************************************************/
+
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "wm_bt_config.h"
+
+#if (WM_MESH_INCLUDED == CFG_ON)
+
+#include "mesh/mesh.h"
+
+/* BLE */
+#include "nimble/ble.h"
+#include "host/ble_hs.h"
+#include "mesh/glue.h"
+#include "wm_bt_util.h"
+#include "wm_ble_mesh.h"
+#include "wm_ble_gap.h"
+#include "wm_gpio.h"
+
+/*Mesh models*/
+#include "mesh/model_cli.h"
+#include "mesh/model_srv.h"
+#include "mesh/cfg_cli.h"
+#include "wm_ble_mesh_light_model.h"
+
+#include "wm_bt_app.h"
+#include "wm_efuse.h"
+
+#include "wm_ble_mesh_health_server.h"
+#include "wm_ble_mesh_vnd_model.h"
+
+#define CID_NVAL 0xFFFF
+
+/*
+ * GLOBAL VARIABLE DEFINITIONS
+ ****************************************************************************************
+ */
+ 
+#define MESH_LIGHT_GPIO_GREEN   WM_IO_PB_00
+#define MESH_LIGHT_GPIO_RED     WM_IO_PB_01
+#define MESH_LIGHT_GPIO_BLUE    WM_IO_PB_02
+
+static struct ble_gap_event_listener app_mesh_event_listener;
+static bool filter_unprov_adv_report = true;
+static tls_bt_mesh_at_callback_t at_cb_ptr = NULL;
+
+static uint16_t primary_addr;
+static uint16_t primary_net_idx;
+
+#if MYNEWT_VAL(BLE_MESH_CFG_CLI)
+
+static struct bt_mesh_cfg_cli cfg_cli = {
+};
+static struct bt_mesh_gen_model_cli gen_onoff_cli;
+/*predeclaration general on off client model publication update function*/
+static int gen_onoff_cli_pub_update(struct bt_mesh_model *mod);
+static struct bt_mesh_model_pub gen_onoff_cli_pub = {
+    .update = gen_onoff_cli_pub_update,
+};
+
+static struct bt_mesh_gen_onoff_srv gen_onoff_srv = {
+    .get = tls_light_model_gen_onoff_get,
+    .set = tls_light_model_gen_onoff_set,
+};
+static struct bt_mesh_model_pub gen_onoff_srv_pub;
+
+#endif /* MYNEWT_VAL(BLE_MESH_CFG_CLI) */
+
+static void cfg_heartbeat_sub_func(uint8_t hops, uint16_t feat)
+{
+    TLS_BT_APPL_TRACE_DEBUG("cfg_heartbeat_sub_func: %d, 0x%04x\r\n", hops, feat);
+    return;
+}
+
+static struct bt_mesh_cfg_srv cfg_srv = {
+    .relay = BT_MESH_RELAY_ENABLED,
+    .beacon = BT_MESH_BEACON_ENABLED,
+#if MYNEWT_VAL(BLE_MESH_FRIEND)
+    .frnd = BT_MESH_FRIEND_ENABLED,
+#else
+    .gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
+#endif
+#if MYNEWT_VAL(BLE_MESH_GATT_PROXY)
+    .gatt_proxy = BT_MESH_GATT_PROXY_ENABLED,
+#else
+    .gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
+#endif
+    .default_ttl = 7,
+
+    /* 3 transmissions with 20ms interval */
+    .net_transmit = BT_MESH_TRANSMIT(2, 20),
+    .relay_retransmit = BT_MESH_TRANSMIT(2, 20),
+    .hb_sub.func = cfg_heartbeat_sub_func,
+    .dist_map = {0},
+    
+};
+
+
+
+static struct bt_mesh_model node_root_models[] = {
+    BT_MESH_MODEL_CFG_SRV(&cfg_srv),
+#if MYNEWT_VAL(BLE_MESH_CFG_CLI)
+    BT_MESH_MODEL_CFG_CLI(&cfg_cli),
+#endif
+    BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
+};
+
+static struct bt_mesh_model node_sec_models[] = {
+
+    BT_MESH_MODEL_GEN_ONOFF_CLI(&gen_onoff_cli, &gen_onoff_cli_pub),    
+    BT_MESH_MODEL_GEN_ONOFF_SRV(&gen_onoff_srv, &gen_onoff_srv_pub),
+};
+
+
+static struct bt_mesh_model node_root_vnd_models[] = {
+    #if 0
+    BT_MESH_MODEL_VND(CID_VENDOR, BT_MESH_MODEL_ID_GEN_ONOFF_SRV, vnd_model_op,
+                      /*&vnd_model_pub*/NULL, NULL),
+    #endif
+    BT_MESH_MODEL_WM_VND(NULL),
+};
+
+static struct bt_mesh_model node_sec_vnd_models[] = {
+
+};
+
+
+static struct bt_mesh_elem node_elements[] = {
+    BT_MESH_ELEM(0, node_root_models, node_root_vnd_models),
+    BT_MESH_ELEM(1, node_sec_models,  node_sec_vnd_models),
+};
+
+static const struct bt_mesh_comp node_comp = {
+    .cid = CID_VENDOR,
+    .elem = node_elements,
+    .elem_count = ARRAY_SIZE(node_elements),
+};
+
+
+static struct bt_mesh_model provisioner_root_models[] = {
+    BT_MESH_MODEL_CFG_SRV(&cfg_srv),
+#if MYNEWT_VAL(BLE_MESH_CFG_CLI)
+    BT_MESH_MODEL_CFG_CLI(&cfg_cli),
+#endif
+
+    BT_MESH_MODEL_GEN_ONOFF_CLI(&gen_onoff_cli, &gen_onoff_cli_pub),
+
+#if MYNEWT_VAL(BLE_MESH_HEALTH_CLI)
+    BT_MESH_MODEL_HEALTH_CLI(&health_cli),
+#endif
+
+};
+
+static struct bt_mesh_model provisioner_vnd_models[] = {
+    BT_MESH_MODEL_VND(CID_VENDOR, BT_MESH_MODEL_ID_GEN_ONOFF_CLI, vnd_model_op,
+                      &vnd_model_pub, NULL),
+};
+
+static struct bt_mesh_elem provisioner_elements[] = {
+    BT_MESH_ELEM(0, provisioner_root_models, provisioner_vnd_models),
+};
+
+static const struct bt_mesh_comp provisioner_comp = {
+    .cid = CID_VENDOR,
+    .elem = provisioner_elements,
+    .elem_count = ARRAY_SIZE(provisioner_elements),
+};
+
+/*
+ * LOCAL FUNCTION DEFINITIONS
+ ****************************************************************************************
+ */
+
+static void
+pub_init(void)
+{
+    health_pub.msg  = BT_MESH_HEALTH_FAULT_MSG(0);
+    gen_onoff_cli_pub.msg = NET_BUF_SIMPLE(2 + 2);
+}
+static void
+pub_deinit(void)
+{
+    if(health_pub.msg) {
+        os_mbuf_free_chain(health_pub.msg);
+        health_pub.msg = NULL;
+    }
+    
+    if(gen_onoff_cli_pub.msg) {
+        os_mbuf_free_chain(gen_onoff_cli_pub.msg);
+        gen_onoff_cli_pub.msg = NULL;
+    }
+}
+
+static int output_number(bt_mesh_output_action_t action, uint32_t number)
+{
+    tls_mesh_event_t evt = WM_MESH_OOB_NUMBER_EVT;
+    tls_mesh_msg_t msg;
+    TLS_BT_APPL_TRACE_DEBUG("OOB Number: %lu\r\n", number);
+    msg.oob_output_number_msg.number = number;
+    TLS_HAL_AT_NOTIFY(at_cb_ptr, evt, &msg);
+    return 0;
+}
+static int output_string(const char *str)
+{
+    tls_mesh_event_t evt = WM_MESH_OOB_STRING_EVT;
+    tls_mesh_msg_t msg;
+    msg.oob_output_string_msg.str = (char*)str;
+    TLS_HAL_AT_NOTIFY(at_cb_ptr, evt, &msg);
+    return 0;
+}
+static int prov_input(bt_mesh_input_action_t act, u8_t size)
+{
+    tls_mesh_event_t evt = WM_MESH_OOB_INPUT_EVT;
+    tls_mesh_msg_t msg;
+    TLS_BT_APPL_TRACE_DEBUG("OOB input: act=0x%02x, size=%d\r\n", act, size);
+    msg.oob_input_msg.act = act;
+    TLS_HAL_AT_NOTIFY(at_cb_ptr, evt, &msg);
+    return 0;
+}
+static void prov_input_complete(void)
+{
+    TLS_BT_APPL_TRACE_DEBUG("prov_input_complete\r\n");
+}
+
+static void prov_complete(u16_t net_idx, u16_t addr)
+{
+    tls_mesh_event_t evt = WM_MESH_PROV_CMPLT_EVT;
+    tls_mesh_msg_t msg;
+    TLS_BT_APPL_TRACE_DEBUG("Local node provisioned, primary address 0x%04x, net_idx=%d\r\n", addr,
+                            net_idx);
+    primary_addr = addr;
+    primary_net_idx = net_idx;
+    msg.prov_cmplt_msg.addr = addr;
+    msg.prov_cmplt_msg.net_idx = net_idx;
+    TLS_HAL_AT_NOTIFY(at_cb_ptr, evt, &msg);
+}
+
+static uint16_t node_added_net_idx = 0;
+static uint16_t node_added_addr = 0;
+static uint8_t  node_added_num_elem = 0;
+
+static void prov_node_added(u16_t net_idx, u16_t addr, u8_t num_elem)
+{
+    //tls_mesh_event_t evt = WM_MESH_NODE_ADDED_EVT;
+    //tls_mesh_msg_t msg;
+    TLS_BT_APPL_TRACE_DEBUG("Prov node added, primary address 0x%04x, net_idx=%d, num_elem=%d\r\n",
+                            addr, net_idx, num_elem);
+    //msg.node_added_msg.net_idx = net_idx;
+    //msg.node_added_msg.addr = addr;
+    //msg.node_added_msg.num_elem = num_elem;
+    node_added_net_idx = net_idx;
+    node_added_addr = addr;
+    node_added_num_elem = num_elem;
+    //WM_MESH_PROV_END_EVT will report the prov result at last.
+    //TLS_HAL_AT_NOTIFY(at_cb_ptr, evt, &msg);
+}
+static void prov_link_close(bt_mesh_prov_bearer_t bearer, bool prov_success)
+{
+    tls_mesh_event_t evt = WM_MESH_PROV_END_EVT;
+    tls_mesh_msg_t msg;
+    TLS_BT_APPL_TRACE_DEBUG("prov_link_close: bearer=0x%02x, status:%s\r\n", bearer,
+                            prov_success ? "success" : "failed");
+    msg.prov_end_msg.success = prov_success;
+
+    if(prov_success) {
+        msg.prov_end_msg.net_idx = node_added_net_idx;
+        msg.prov_end_msg.addr =  node_added_addr;
+        msg.prov_end_msg.num_elem = node_added_num_elem;
+    } else {
+        msg.prov_end_msg.net_idx = 0xFFFF;
+        msg.prov_end_msg.addr =    0xFFFF;
+        msg.prov_end_msg.num_elem = 0xFF;
+    }
+
+    TLS_HAL_AT_NOTIFY(at_cb_ptr, evt, &msg);
+}
+
+static void prov_link_open(bt_mesh_prov_bearer_t bearer)
+{
+    TLS_BT_APPL_TRACE_DEBUG("prov_link_open: bearer=0x%02x\r\n", bearer);    
+}
+static void unprovisioned_beacon(const bt_addr_le_t *addr, u8_t uuid[16],
+                                 bt_mesh_prov_oob_info_t oob_info,
+                                 u32_t *uri_hash)
+{
+    tls_mesh_event_t evt = WM_MESH_UNPROVISION_BEACON_EVT;
+    tls_mesh_msg_t msg;
+
+    if(filter_unprov_adv_report) { return; }
+
+    TLS_BT_APPL_TRACE_DEBUG("unprovisioned_beacon: [%s][%s] oob_info:0x%04x, net_idx=%d\r\n",
+                            bt_hex(addr->val, 6), bt_hex(uuid, 16), oob_info, uri_hash[0]);
+
+    if(at_cb_ptr) {
+        memcpy(msg.unprov_msg.addr, addr->val, 6);
+        msg.unprov_msg.addr_type = addr->type;
+        memcpy(msg.unprov_msg.uuid, uuid, 16);
+        msg.unprov_msg.oob_info = oob_info;
+        msg.unprov_msg.uri_hash = uri_hash[0];
+        TLS_HAL_AT_NOTIFY(at_cb_ptr, evt, &msg);
+    }
+}
+
+static uint8_t dev_uuid[16] = MYNEWT_VAL(BLE_MESH_DEV_UUID);
+static char    dev_name[16] = CONFIG_BT_DEVICE_NAME;
+
+static const struct bt_mesh_prov prov = {
+    .name = dev_name,
+    .uuid = dev_uuid,
+    .output_size = 4,
+    .output_actions = BT_MESH_DISPLAY_NUMBER | BT_MESH_BEEP | BT_MESH_VIBRATE | BT_MESH_BLINK,
+    .output_number = output_number,
+    .output_string = output_string,
+    .input_size = 4,
+    .input_actions = BT_MESH_DISPLAY_NUMBER | BT_MESH_BEEP | BT_MESH_VIBRATE | BT_MESH_BLINK,
+    .input = prov_input,
+    .input_complete = prov_input_complete,
+    .complete = prov_complete,
+    .node_added = prov_node_added,
+    .unprovisioned_beacon = unprovisioned_beacon,
+    .link_close = prov_link_close,
+    .link_open = prov_link_open,
+};
+
+static int ble_gap_host_shutdown_cb(struct ble_gap_event *event, void *arg)
+{
+	if(BLE_GAP_EVENT_HOST_SHUTDOWN == event->type)
+	{
+        tls_bt_set_mesh_mode(0);
+        bt_mesh_deinit();
+        pub_deinit();
+        TLS_BT_APPL_TRACE_DEBUG("Mesh deinitialized\r\n");
+        at_cb_ptr = NULL;
+	}
+
+    return 0;
+}
+static uint8_t transaction_id = 0;
+
+static int gen_onoff_cli_pub_update(struct bt_mesh_model *mod)
+{
+    TLS_BT_APPL_TRACE_DEBUG("gen_onoff_cli_pub_update\r\n");
+    static bool general_onoff_state = false;
+    CHECK_SYSTEM_READY();
+    #define BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK      BT_MESH_MODEL_OP_2(0x82, 0x03)
+    #define BT_MESH_MODEL_OP_GEN_ONOFF_SET            BT_MESH_MODEL_OP_2(0x82, 0x02)
+
+    TLS_BT_APPL_TRACE_DEBUG("gen off client publish update to 0x%04x onoff 0x%04x \r\n", gen_onoff_cli_pub.addr, general_onoff_state);
+    
+    bt_mesh_model_msg_init(gen_onoff_cli_pub.msg,BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK);
+    net_buf_simple_add_u8(gen_onoff_cli_pub.msg, general_onoff_state);
+    net_buf_simple_add_u8(gen_onoff_cli_pub.msg, transaction_id++);
+    {
+        general_onoff_state = !general_onoff_state;
+    }
+
+    return 0;    
+}
+
+/*
+ * EXPORTED FUNCTION DEFINITIONS
+ ****************************************************************************************
+ */
+
+int
+tls_ble_mesh_deinit()
+{
+    CHECK_SYSTEM_READY();
+    TLS_BT_APPL_TRACE_DEBUG("Mesh freeing resouce\r\n");
+    if(at_cb_ptr == NULL) return 0;
+    tls_bt_set_mesh_mode(0);
+    bt_mesh_deinit();
+    pub_deinit();
+    TLS_BT_APPL_TRACE_DEBUG("Mesh deinitialized\r\n");
+    at_cb_ptr = NULL;
+    
+    ble_gap_event_listener_unregister(&app_mesh_event_listener);
+
+    return 0;
+}
+static void notify_flash_flush_available(void)
+{
+#if (MYNEWT_VAL(BLE_MESH_SETTINGS))
+    bt_mesh_settings_flush();
+#endif
+}
+
+
+/**
+ * mesh main entry.
+ *
+ * @tls_bt_mesh_at_callback_t  notify the mesh evt to AT level
+ * @param role             MESH_ROLE_NODE or MESH_ROLE_PROVISIONER.
+ * @param running       running the mesh after initializing
+ *
+ * @return 0 on success.
+ * @return -2 means the role mismatch.
+ */
+
+int
+tls_ble_mesh_init(tls_bt_mesh_at_callback_t at_cb, tls_bt_mesh_role_t role, bool running)
+{
+    int err = 0;
+    ble_addr_t addr = {0};
+    CHECK_SYSTEM_READY();
+    TLS_BT_APPL_TRACE_DEBUG("Mesh initializing...role=%d\r\n", role);
+    if(at_cb_ptr) return 0;
+    
+    tls_bt_set_mesh_mode(1);
+    at_cb_ptr = at_cb;
+    pub_init();
+#define NRPA   0 
+    /*default we use nrpa address*/
+    #if NRPA
+    /* Use NRPA */
+    err = ble_hs_id_gen_rnd(1, &addr);
+    assert(err == 0);
+    err = ble_hs_id_set_rnd(addr.val);
+    assert(err == 0);
+    #endif
+    tls_ble_gap_get_name(dev_name);
+    /*using BT MAC as device uuid high 6 bytes*/
+    tls_get_bt_mac_addr(&dev_uuid[10]);
+
+    if(role == MESH_ROLE_NODE) {
+        err = bt_mesh_init(addr.type, &prov, &node_comp);
+    } else {
+        err = bt_mesh_init(addr.type, &prov, &provisioner_comp);
+    }
+
+    if(err) {
+        TLS_BT_APPL_TRACE_DEBUG("Initializing mesh %s failed (err %d)\r\n",
+                                role == MESH_ROLE_NODE ? "Node" : "Provisioner", err);
+        return err;
+    }
+
+    TLS_BT_APPL_TRACE_DEBUG("Mesh(%s) initialized\r\n", dev_name);
+#if (MYNEWT_VAL(BLE_MESH_SETTINGS))
+    tls_bt_register_pending_process_callback(notify_flash_flush_available);
+    err = bt_mesh_settings_load((role == MESH_ROLE_NODE ? true : false));
+#endif
+
+    if(err == -2) {
+        TLS_BT_APPL_TRACE_DEBUG("Mesh nvram parameter mismatch with the prefered role, Please erase the nvram or change the role\r\n");
+        return err;
+    } else {
+        /**if invalid nvram area, return success*/
+        err = 0;
+    }
+
+    TLS_BT_APPL_TRACE_DEBUG("running role=%d, err=%d\r\n", role, err);
+
+    if(role == MESH_ROLE_NODE) {
+        TLS_BT_APPL_TRACE_DEBUG("node role enabled\r\n");
+        bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
+        bt_mesh_role_set(true);
+    } else {
+        /**For provisioner, start scan if necessary*/
+        TLS_BT_APPL_TRACE_DEBUG("provisioner role enabled\r\n");
+        if(running) { bt_mesh_scan_enable(); }
+    }
+
+    if(bt_mesh_is_provisioned()) {
+        TLS_BT_APPL_TRACE_DEBUG("Mesh network restored from flash\r\n");
+
+        if(bt_mesh_role_is_provisioner()) {
+            bt_mesh_comp_provision(1);
+        }
+    } else {
+        if((bt_mesh_get_role() == MESH_ROLE_PROVISIONER || bt_mesh_get_role() == MESH_ROLE_UNKNOWN)
+                && (role == MESH_ROLE_PROVISIONER)) {
+            TLS_BT_APPL_TRACE_DEBUG("provisioner role init\r\n");
+            bt_mesh_provision_init();
+        }
+    }
+    
+    ble_gap_event_listener_register(&app_mesh_event_listener,
+                                ble_gap_host_shutdown_cb, NULL);
+
+    return err;
+}
+
+static uint16_t mesh_uart_dst = 0x02;
+
+int tls_ble_mesh_vnd_send_msg(uint8_t *msg, int len)
+{
+    int rc;
+    
+ #if 1  
+    TLS_BT_APPL_TRACE_VERBOSE("bt_mesh_send %d/%d/%d/%d %s\r\n", 0, mesh_uart_dst, 0, len, bt_hex(msg, len));
+
+    rc = vnd_model_send(0, mesh_uart_dst, 0, msg, len);
+
+#else
+    int i = 0;
+    static uint8_t value = 0x01;
+    uint8_t test_buf[255];
+
+    for(i=0; i<sizeof(test_buf); i++) test_buf[i] = value;
+    value ++;
+    if(value == 0x00) value++;
+
+    TLS_BT_APPL_TRACE_DEBUG("bt_mesh_send %d/%d/%d/%d %s\r\n", 0, 4, 0, len, bt_hex(test_buf, 220));
+
+    rc = vnd_model_send(0, mesh_uart_dst, 0, test_buf, 200);    
+#endif
+    if(rc!= 0)
+    {
+       TLS_BT_APPL_TRACE_ERROR("rc=%d, upper layer will retry\r\n", rc) 
+    }
+    return rc;
+}
+
+
+int tls_ble_mesh_gen_level_get(uint16_t net_idx, uint16_t dst, uint16_t app_idx, int16_t *state)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+    err = bt_mesh_gen_level_get(net_idx, dst, app_idx, state);
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Failed to send Generic Level Get (err %d)\r\n", err);
+    } else {
+        TLS_BT_APPL_TRACE_DEBUG("Gen Level State 0x%04x\r\n", state[0]);
+    }
+
+    return err;
+}
+
+
+int tls_ble_mesh_gen_level_set(uint16_t net_idx, uint16_t dst, uint16_t app_idx, int16_t val,
+                               int16_t *state)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+    err = bt_mesh_gen_level_set(net_idx, dst, app_idx, val, state);
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Failed to send Generic Level Set (err %d)\r\n", err);
+    } else {
+        TLS_BT_APPL_TRACE_DEBUG("Gen Level State 0x%04x\r\n", state[0]);
+    }
+
+    return err;
+}
+
+int tls_ble_mesh_gen_off_publish(uint8_t onoff_state)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+    #define BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK      BT_MESH_MODEL_OP_2(0x82, 0x03)
+    #define BT_MESH_MODEL_OP_GEN_ONOFF_SET            BT_MESH_MODEL_OP_2(0x82, 0x02)
+
+    TLS_BT_APPL_TRACE_DEBUG("gen off client publish to 0x%04x onoff 0x%04x \r\n", gen_onoff_cli_pub.addr, onoff_state);
+    
+    bt_mesh_model_msg_init(gen_onoff_cli_pub.msg,BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK);
+    net_buf_simple_add_u8(gen_onoff_cli_pub.msg, onoff_state);
+    net_buf_simple_add_u8(gen_onoff_cli_pub.msg, transaction_id++);
+    err = bt_mesh_model_publish(gen_onoff_cli_pub.mod);
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("bt_mesh_model_publish err %d\r\n", err);
+    }
+
+    return err;
+    
+}
+
+int tls_ble_mesh_gen_onoff_get(uint16_t net_idx, uint16_t dst, uint16_t app_idx, uint8_t *state)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+    err = bt_mesh_gen_onoff_get(net_idx, dst, app_idx, state);
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Failed to send Generic OnOff Get (err %d)\r\n", err);
+    } else {
+        TLS_BT_APPL_TRACE_DEBUG("Gen OnOff State 0x%02x\r\n", state[0]);
+    }
+
+    return err;
+}
+#define SEND_WITH_ACK 0
+static int send_counter = 0, err_counter = 0;
+int tls_ble_mesh_gen_onoff_set(uint16_t net_idx, uint16_t dst, uint16_t app_idx, uint8_t val,
+                               uint8_t *state)
+{
+    int err;
+    TLS_BT_APPL_TRACE_DEBUG("tls_ble_mesh_gen_onoff_set, dst 0x%04x, val %d\r\n", dst, val);
+    CHECK_SYSTEM_READY();
+    send_counter++;
+    #if SEND_WITH_ACK
+    err = bt_mesh_gen_onoff_set(net_idx, dst, app_idx, val, state);
+    #else
+    err = bt_mesh_gen_onoff_set(net_idx, dst, app_idx, val, NULL);
+    #endif
+    if(err) {
+        err_counter++;
+        TLS_BT_APPL_TRACE_ERROR("Failed to send Generic OnOff Set (err %d)\r\n", err);
+    } else {
+    #if SEND_WITH_ACK
+        TLS_BT_APPL_TRACE_DEBUG("Gen OnOff State 0x%02x[%d,%d]\r\n", state[0],send_counter, err_counter);
+    #else
+        TLS_BT_APPL_TRACE_DEBUG("Gen OnOff State 0x%02x[%d,%d]\r\n", val,send_counter, err_counter);
+    #endif
+    }
+
+    return err;
+}
+                               
+int tls_ble_mesh_hb_sub_set(uint16_t net_idx, uint16_t dst, tls_bt_mesh_cfg_hb_sub *hb_sub, uint8_t *status)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+
+    err = bt_mesh_cfg_hb_sub_set(net_idx, dst, (struct bt_mesh_cfg_hb_sub *)hb_sub, status);
+    if(err)
+    {
+        TLS_BT_APPL_TRACE_ERROR("Model HeartBeat Sublication Set failed (err %d)\n", err);
+        return err;        
+    }
+
+    if(status[0]) {
+        TLS_BT_APPL_TRACE_ERROR("Model HeartBeat Sublication Set failed (status 0x%02x)\n",
+                                status[0]);
+    } else {
+        TLS_BT_APPL_TRACE_DEBUG("Model HeartBeat Sublication successfully set\n");
+    }
+
+    return err;    
+}
+
+int tls_ble_mesh_hb_sub_get(uint16_t net_idx, uint16_t dst, tls_bt_mesh_cfg_hb_sub *hb_sub, uint8_t *status)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+
+    err = bt_mesh_cfg_hb_sub_get(net_idx, dst, (struct bt_mesh_cfg_hb_sub *)hb_sub, status);
+    if(err)
+    {
+        TLS_BT_APPL_TRACE_ERROR("Model HeartBeat Sublication Get failed (err %d)\n", err);
+        return err;        
+    }
+
+    if(status[0]) {
+        TLS_BT_APPL_TRACE_ERROR("Model HeartBeat Sublication Get failed (status 0x%02x)\n",
+                                status[0]);
+    } else {
+        TLS_BT_APPL_TRACE_DEBUG("Model HeartBeat Sublication Get successfully \n");
+    }
+
+    return err;    
+}
+
+int tls_ble_mesh_hb_pub_set(uint16_t net_idx, uint16_t dst, const tls_bt_mesh_cfg_hb_pub *hb_pub, uint8_t *status)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+
+    err = bt_mesh_cfg_hb_pub_set(net_idx, dst, (const struct bt_mesh_cfg_hb_pub *)hb_pub, status);
+
+    if(err)
+    {
+        TLS_BT_APPL_TRACE_ERROR("Model HeartBeat Publication Set failed (err %d)\n", err);
+        return err;        
+    }
+    
+    if(status[0]) {
+        TLS_BT_APPL_TRACE_ERROR("Model HeartBeat Publication Set failed (status 0x%02x)\n",
+                                status[0]);
+    } else {
+        TLS_BT_APPL_TRACE_DEBUG("Model HeartBeat Publication successfully set\n");
+    }
+
+    return err;    
+}
+
+int tls_ble_mesh_hb_pub_get(uint16_t net_idx, uint16_t dst, tls_bt_mesh_cfg_hb_pub *hb_pub, uint8_t *status)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+
+    err = bt_mesh_cfg_hb_pub_get(net_idx, dst, (struct bt_mesh_cfg_hb_pub *)hb_pub, status);
+    if(err)
+    {
+        TLS_BT_APPL_TRACE_ERROR("Model HeartBeat Publication Get failed (err %d)\n", err);
+        return err;        
+    }
+    
+    if(status[0]) {
+        TLS_BT_APPL_TRACE_ERROR("Model HeartBeat Publication Get failed (status 0x%02x)\n",
+                                status[0]);
+    } else {
+        TLS_BT_APPL_TRACE_DEBUG("Model HeartBeat Publication Get successfully\n");
+    }
+
+    return err;  
+}
+
+int tls_ble_mesh_pub_set(uint16_t net_idx, uint16_t dst, uint16_t elem_addr, uint16_t mod_id,
+                         uint16_t cid,
+                         tls_bt_mesh_cfg_mod_pub *pub, uint8_t *status)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+
+    if(cid == CID_NVAL) {
+        err = bt_mesh_cfg_mod_pub_set(net_idx, dst, elem_addr,
+                                      mod_id, (struct bt_mesh_cfg_mod_pub *)pub, status);
+    } else {
+        err = bt_mesh_cfg_mod_pub_set_vnd(net_idx, dst, elem_addr,
+                                          mod_id, cid, (struct bt_mesh_cfg_mod_pub *)pub, status);
+    }
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Model Publication Set failed (err %d)\n", err);
+        return err;
+    }
+
+    if(status[0]) {
+        TLS_BT_APPL_TRACE_ERROR("Model Publication Set failed (status 0x%02x)\n",
+                                status[0]);
+    } else {
+        TLS_BT_APPL_TRACE_DEBUG("Model Publication successfully set\n");
+    }
+
+    return err;
+}
+int tls_ble_mesh_pub_get(uint16_t net_idx, uint16_t dst, uint16_t elem_addr, uint16_t mod_id,
+                         uint16_t cid, tls_bt_mesh_cfg_mod_pub *pub, uint8_t *status)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+
+    if(cid == CID_NVAL) {
+        err = bt_mesh_cfg_mod_pub_get(net_idx, dst, elem_addr,
+                                      mod_id, (struct bt_mesh_cfg_mod_pub *)pub, status);
+    } else {
+        err = bt_mesh_cfg_mod_pub_get_vnd(net_idx, dst, elem_addr,
+                                          mod_id, cid, (struct bt_mesh_cfg_mod_pub *)pub, status);
+    }
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Model Publication Get failed (err %d)\n", err);
+        return 0;
+    }
+
+    if(status[0]) {
+        TLS_BT_APPL_TRACE_ERROR("Model Publication Get failed (status 0x%02x)\n", status[0]);
+        return 0;
+    }
+
+    TLS_BT_APPL_TRACE_DEBUG("Model Publication for Element 0x%04x, Model 0x%04x:\r\n"
+                            "\tPublish Address:                0x%04x\r\n"
+                            "\tAppKeyIndex:                    0x%04x\r\n"
+                            "\tCredential Flag:                %u\r\n"
+                            "\tPublishTTL:                     %u\r\n"
+                            "\tPublishPeriod:                  0x%02x\r\n"
+                            "\tPublishRetransmitCount:         %u\r\n"
+                            "\tPublishRetransmitInterval:      %ums\r\n",
+                            elem_addr, mod_id, pub[0].addr, pub[0].app_idx, pub[0].cred_flag, pub[0].ttl,
+                            pub[0].period, BT_MESH_PUB_TRANSMIT_COUNT(pub[0].transmit),
+                            BT_MESH_PUB_TRANSMIT_INT(pub[0].transmit));
+    return 0;
+}
+int tls_ble_mesh_sub_get(uint16_t net_idx, uint16_t dst, uint16_t elem_addr, uint16_t mod_id,
+                         uint16_t cid,
+                         uint8_t *status, uint16_t *subs, uint32_t *sub_cnt)
+{
+    int err;
+    int i ;
+    CHECK_SYSTEM_READY();
+
+    if(cid == CID_NVAL) {
+        err = bt_mesh_cfg_mod_sub_get(net_idx, dst, elem_addr,
+                                      mod_id, status, subs, sub_cnt);
+    } else {
+        err = bt_mesh_cfg_mod_sub_get_vnd(net_idx, dst, elem_addr,
+                                          mod_id, cid, status, subs, sub_cnt);
+    }
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Unable to send Model Subscription Get(err %d)\r\n", err);
+        return 0;
+    }
+
+    if(status[0]) {
+        TLS_BT_APPL_TRACE_DEBUG("Model Subscription Get failed with status 0x%02x\r\n", status[0]);
+    } else {
+        TLS_BT_APPL_TRACE_DEBUG(
+                        "Model Subscriptions for Element 0x%04x, Model 0x%04x \r\n", elem_addr, mod_id);
+
+        if(!sub_cnt[0]) {
+            TLS_BT_APPL_TRACE_DEBUG("\tNone.\r\n");
+        }
+
+        for(i = 0; i < sub_cnt[0]; i++) {
+            TLS_BT_APPL_TRACE_DEBUG("\t0x%04x\r\n", subs[i]);
+        }
+    }
+
+    return 0;
+}
+int tls_ble_mesh_sub_add_va(uint16_t net_idx, uint16_t dst, uint16_t elem_addr, uint8_t label[16],
+                            uint16_t mod_id, uint16_t *sub_addr, uint8_t *status)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+    err = bt_mesh_cfg_mod_sub_va_add(net_idx, dst, elem_addr, label,
+                                     mod_id, sub_addr, status);
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Unable to send Mod Sub VA Add (err %d)\n", err);
+    }
+
+    if(status[0]) {
+        TLS_BT_APPL_TRACE_DEBUG("Mod Sub VA Add failed with status 0x%02x\n", status[0]);
+    } else {
+        TLS_BT_APPL_TRACE_DEBUG("0x%04x subscribed to Label UUID %s (va 0x%04x)\n",
+                                elem_addr, bt_hex(label, 16), sub_addr);
+    }
+
+    return err;
+}
+
+int tls_ble_mesh_sub_del_va(uint16_t net_idx, uint16_t dst, uint16_t elem_addr,
+                            uint8_t label[16], uint16_t mod_id, uint16_t *sub_addr, uint8_t *status)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+    err = bt_mesh_cfg_mod_sub_va_del(net_idx, dst, elem_addr,
+                                     label, mod_id, sub_addr, status);
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Unable to send Model Subscription Delete (err %d)\n", err);
+        return err;
+    }
+
+    if(status[0]) {
+        TLS_BT_APPL_TRACE_DEBUG("Model Subscription Delete failed with status 0x%02x\n", status[0]);
+    } else {
+        TLS_BT_APPL_TRACE_DEBUG("0x%04x unsubscribed from Label UUID %s (va 0x%04x)\n",
+                                elem_addr, bt_hex(label, 16), sub_addr);
+    }
+
+    return err;
+}
+
+
+int tls_ble_mesh_sub_del(uint16_t net_idx, uint16_t dst, uint16_t elem_addr, uint16_t sub_addr,
+                         uint16_t mod_id, uint16_t cid, uint8_t *status)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+
+    if(cid == CID_NVAL) {
+        err = bt_mesh_cfg_mod_sub_del(net_idx, dst, elem_addr,
+                                      sub_addr, mod_id, status);
+    } else {
+        err = bt_mesh_cfg_mod_sub_del_vnd(net_idx, dst, elem_addr,
+                                          sub_addr, mod_id, cid, status);
+    }
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Unable to send Model Subscription Del (err %d)\n", err);
+        return err;
+    }
+
+    if(status[0]) {
+        TLS_BT_APPL_TRACE_DEBUG("Model Subscription Del failed with status 0x%02x\n",
+                                status[0]);
+    } else {
+        TLS_BT_APPL_TRACE_DEBUG("Model subscription Del was successful\n");
+    }
+
+    return err;
+}
+
+int tls_ble_mesh_sub_add(uint16_t net_idx, uint16_t dst, uint16_t elem_addr, uint16_t sub_addr,
+                         uint16_t mod_id, uint16_t cid, uint8_t *status)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+
+    if(cid == CID_NVAL) {
+        err = bt_mesh_cfg_mod_sub_add(net_idx, dst, elem_addr,
+                                      sub_addr, mod_id, status);
+    } else {
+        err = bt_mesh_cfg_mod_sub_add_vnd(net_idx, dst, elem_addr,
+                                          sub_addr, mod_id, cid, status);
+    }
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Unable to send Model Subscription Add (err %d)\n", err);
+        return err;
+    }
+
+    if(status[0]) {
+        TLS_BT_APPL_TRACE_DEBUG("Model Subscription Add failed with status 0x%02x\n",
+                                status[0]);
+    } else {
+        TLS_BT_APPL_TRACE_DEBUG("Model subscription was successful\n");
+    }
+
+    return err;
+}
+
+int tls_ble_mesh_friend_set(uint16_t net_idx, uint16_t dst, uint8_t val, uint8_t *status)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+    err = bt_mesh_cfg_friend_set(net_idx, dst, val, status);
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Unable to Set Friend state (err %d)\r\n", err);
+        return err;
+    }
+
+    TLS_BT_APPL_TRACE_DEBUG("Friend state is 0x%02x\r\n", status[0]);
+    return 0;
+}
+
+int tls_ble_mesh_friend_get(uint16_t net_idx, uint16_t dst, uint8_t *val)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+    err = bt_mesh_cfg_friend_get(net_idx, dst, val);
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Unable to Get Friend state (err %d)\r\n", err);
+        return err;
+    }
+
+    TLS_BT_APPL_TRACE_DEBUG("Friend state is 0x%02x\r\n", val[0]);
+    return 0;
+}
+
+int tls_ble_mesh_proxy_get(uint16_t net_idx, uint16_t dst, uint8_t *proxy)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+    err = bt_mesh_cfg_gatt_proxy_get(net_idx, dst, proxy);
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Unable to Get Gatt proxy Set message (err %d)\r\n", err);
+        return err;
+    }
+
+    return err;
+}
+int tls_ble_mesh_proxy_set(uint16_t net_idx, uint16_t dst, uint8_t val, uint8_t *proxy)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+    err = bt_mesh_cfg_gatt_proxy_set(net_idx, dst, val, proxy);
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Unable to send Gatt proxy Set message (err %d)\r\n", err);
+        return err;
+    }
+
+    TLS_BT_APPL_TRACE_DEBUG("GATT Proxy is set to 0x%02x\n", proxy[0]);
+    return 0;
+}
+int tls_ble_mesh_relay_get(uint16_t net_idx, uint16_t dst, uint8_t *relay, uint8_t *transmit)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+    err = bt_mesh_cfg_relay_get(net_idx, dst, relay, transmit);
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Unable to send Relay Get (err %d)\n", err);
+        return err;
+    }
+
+    TLS_BT_APPL_TRACE_DEBUG("Transmit 0x%02x (count %u interval %u ms)\r\n",
+                            transmit[0], BT_MESH_TRANSMIT_COUNT(transmit[0]),
+                            BT_MESH_TRANSMIT_INT(transmit[0]));
+    return 0;
+}
+int tls_ble_mesh_relay_set(uint16_t net_idx, uint16_t dst, uint8_t relay, uint8_t count,
+                           uint8_t interval, uint8_t *status, uint8_t *transmit)
+{
+    int err;
+    uint8_t new_transmit;
+    CHECK_SYSTEM_READY();
+
+    if(relay) {
+        new_transmit = BT_MESH_TRANSMIT(count, interval);
+    } else {
+        new_transmit = 0;
+    }
+
+    err = bt_mesh_cfg_relay_set(net_idx, dst, relay, new_transmit, status, transmit);
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Unable to send Relay Set (err %d)\n", err);
+        return err;
+    }
+
+    TLS_BT_APPL_TRACE_DEBUG("Relay is 0x%02x, Transmit 0x%02x (count %u interval %ums)\n",
+                            relay, transmit[0], BT_MESH_TRANSMIT_COUNT(transmit[0]),
+                            BT_MESH_TRANSMIT_INT(transmit[0]));
+    return 0;
+}
+int tls_ble_mesh_unbind_app_key(uint16_t net_idx, uint16_t dst, uint16_t elem_addr,
+                                uint16_t mod_app_idx, uint16_t mod_id, uint16_t cid, uint8_t *status)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+
+    if(cid == CID_NVAL) {
+        err = bt_mesh_cfg_mod_app_unbind(net_idx, dst, elem_addr, mod_app_idx, mod_id, status);
+    } else {
+        err = bt_mesh_cfg_mod_app_unbind_vnd(net_idx, dst, elem_addr, mod_app_idx, mod_id, cid, status);
+    }
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Unable to send Model App UnBind (err %d)\r\n", err);
+        return err;
+    }
+
+    if(status[0]) {
+        TLS_BT_APPL_TRACE_ERROR("Model App UnBind failed with status 0x%02x\r\n", status[0]);
+    } else {
+        TLS_BT_APPL_TRACE_DEBUG("AppKey successfully unbound\r\n");
+    }
+
+    return err;
+}
+int tls_ble_mesh_bind_app_key(uint16_t net_idx, uint16_t dst, uint16_t elem_addr,
+                              uint16_t mod_app_idx, uint16_t mod_id, uint16_t cid, uint8_t *status)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+
+    if(dst == bt_mesh_primary_addr()) {
+        struct bt_mesh_model *found_model;
+        struct bt_mesh_elem *found_elem = bt_mesh_elem_find(elem_addr);
+        found_model = bt_mesh_model_find(found_elem, mod_id);
+
+        if(!found_model) {
+            return -2;
+        }
+
+        return mod_bind(found_model, mod_app_idx);
+    }
+
+    /**only cfg_server support bind msg, and cfg_server located on the primary element, so dst equal to elem_addr */
+    if(cid == CID_NVAL) {
+        err = bt_mesh_cfg_mod_app_bind(net_idx, dst, elem_addr,
+                                       mod_app_idx, mod_id, status);
+    } else {
+        err = bt_mesh_cfg_mod_app_bind_vnd(net_idx, dst, elem_addr,
+                                           mod_app_idx, mod_id, cid, status);
+    }
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Unable to send Model App Bind (err %d)\r\n", err);
+        return err;
+    }
+
+    if(status[0]) {
+        TLS_BT_APPL_TRACE_ERROR("Model App Bind failed with status 0x%02x\r\n", status[0]);
+    } else {
+        TLS_BT_APPL_TRACE_DEBUG("AppKey successfully bound\r\n");
+    }
+
+    return 0;
+}
+
+/**
+ * Add the network app key via cfg_cli.
+ *
+ * @param net_idx         network index.
+ * @param dst               addr of the node;
+ * @param key_net_idx  the related network index of the app key
+ * @param key_app_idx the related app key index
+ * @param app_key       key value
+ *
+ * @return 0 on success.  otherwise see error code
+ *
+ */
+
+int tls_ble_mesh_add_app_key(uint16_t net_idx, uint16_t dst, uint16_t key_net_idx,
+                             uint16_t key_app_idx, uint8_t app_key[16], uint8_t *status)
+{
+    int err;
+    CHECK_SYSTEM_READY();
+    err = bt_mesh_cfg_app_key_add(net_idx, dst, key_net_idx,
+                                  key_app_idx, app_key, status);
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Unable to send App Key Add (err %d)\r\n", err);
+        return err;
+    }
+
+    if(status[0]) {
+        TLS_BT_APPL_TRACE_ERROR("AppKeyAdd failed with status 0x%02x\r\n", status[0]);
+    } else {
+        TLS_BT_APPL_TRACE_DEBUG("AppKey added, NetKeyIndex 0x%04x AppKeyIndex 0x%04x\r\n",
+                                key_net_idx, key_app_idx);
+    }
+
+    return err;
+}
+
+/**
+ * Add the local network app key.
+ *
+ * @param net_idx         network index.
+ * @param app_idx        app key index;
+ * @param app_key       app key
+ *
+ * @return 0 on success.  otherwise see error code
+ *
+ */
+
+int tls_ble_mesh_add_local_app_key(uint16_t net_idx, uint16_t app_idx, uint8_t app_key[16])
+{
+    int rc;
+    CHECK_SYSTEM_READY();
+    TLS_BT_APPL_TRACE_DEBUG("tls_ble_mesh_set_app_key:net_idx[%d], addr[%d], app_key[%s]\r\n", net_idx,
+                            app_idx, bt_hex(app_key, 16));
+    rc = bt_mesh_app_key_add(net_idx, app_idx, app_key, false);
+
+    if(rc) {
+        TLS_BT_APPL_TRACE_ERROR("Unable to Add Local App Key (err %d)\r\n", rc);
+    }
+
+    return rc;
+}
+
+int tls_ble_mesh_input_oob_number(uint32_t number)
+{
+    int rc;
+    CHECK_SYSTEM_READY();
+    rc = bt_mesh_input_number(number);
+    return rc;
+}
+
+int tls_ble_mesh_input_oob_string(const char *string)
+{
+    int rc;
+    CHECK_SYSTEM_READY();
+    rc = bt_mesh_input_string(string);
+    return rc;
+}
+
+/**
+ * Remove a provisioned node from the network.
+ *
+ * @param net_idx         network index.
+ * @addr                       address of the node;
+ *
+ * @return 0 on success.
+ *
+ */
+
+int tls_ble_mesh_node_reset(uint16_t net_idx, uint16_t addr, uint8_t *status)
+{
+    int rc;
+    CHECK_SYSTEM_READY();
+    TLS_BT_APPL_TRACE_DEBUG("tls_ble_mesh_reset_node:net_idx[%d], addr[%d]\r\n", net_idx, addr);
+
+    if(addr == primary_addr) {
+        bt_mesh_reset();
+        rc = 0;
+        status[0] = 0;
+    } else {
+        bool result;
+        rc = bt_mesh_cfg_node_reset(net_idx, addr, &result);
+        status[0] = (uint8_t)result;
+        if(rc) {
+            TLS_BT_APPL_TRACE_ERROR("Unable to Reset node[%d] (err %d)\r\n", addr, rc);
+            return rc;
+        }
+    }
+
+    TLS_BT_APPL_TRACE_DEBUG("result:%s\r\n", status[0] ? "success" : "failed");
+    return rc;
+}
+
+/**
+ * Provision a device by PB-ADV.
+ *
+ * @param uuid             device uuid.
+ * @net_idx                   net index, default value 0 is primary network;
+ * @addr                       assigned device address for provision, 0 means the provisioner will choose the addr auto.
+ * @duration                  notify timer indicate which device is provisioning
+ *
+ * @return 0 on success. otherwise, see detailed error code
+ *
+ */
+
+int tls_ble_mesh_provisioner_prov_adv(uint8_t uuid[16], uint16_t net_idx, uint16_t addr,
+                                      uint8_t duration)
+{
+    int rc;
+    CHECK_SYSTEM_READY();
+    TLS_BT_APPL_TRACE_DEBUG("tls_ble_mesh_provisioner_prov_adv:uuid[%s],net_idx[%d],addr[%d],duration[%d] \r\n",
+                            bt_hex(uuid, 16), net_idx, addr, duration);
+    rc = bt_mesh_provision_adv(uuid, net_idx, addr, duration);
+    return rc;
+}
+
+int tls_ble_mesh_provisioner_scan(bool enable)
+{
+    CHECK_SYSTEM_READY();
+    TLS_BT_APPL_TRACE_DEBUG("tls_ble_mesh_provisioner_scan:%s\r\n", enable ? "start" : "stop");
+
+    if(enable) {
+        //bt_mesh_scan_enable();
+        filter_unprov_adv_report = false;
+    } else {
+        //bt_mesh_scan_disable();
+        filter_unprov_adv_report = true;
+    }
+
+    return 0;
+}
+int tls_ble_mesh_clear_local_rpl(void)
+{
+    CHECK_SYSTEM_READY();
+    TLS_BT_APPL_TRACE_DEBUG("tls_ble_mesh_clear_local_rpl\r\n");
+    bt_mesh_clear_rpl();
+    return 0;
+}
+int tls_ble_mesh_change_primary_addr(uint16_t primary_addr)
+{
+    CHECK_SYSTEM_READY();
+    TLS_BT_APPL_TRACE_DEBUG("tls_ble_mesh_change_primay_address old:%d, new:%d\r\n", bt_mesh_primary_addr(), primary_addr);
+    if(primary_addr == bt_mesh_primary_addr()){
+        return 0;
+    }
+    if(!bt_mesh_is_provisioned()) return BLE_HS_EREJECT;
+    bt_mesh_comp_provision(primary_addr);
+    bt_mesh_store_net();
+    return 0;    
+}
+int tls_ble_mesh_get_primary_addr(uint16_t *primary_addr)
+{
+    CHECK_SYSTEM_READY();
+    TLS_BT_APPL_TRACE_DEBUG("tls_ble_mesh_get_primary_address ret=%d\r\n", bt_mesh_primary_addr());
+
+    *primary_addr = bt_mesh_primary_addr();
+
+    return 0;    
+}
+int tls_ble_mesh_change_ttl(uint8_t ttl)
+{
+    CHECK_SYSTEM_READY();
+    struct bt_mesh_cfg_srv *cfg_srv = bt_mesh_cfg_get();
+    cfg_srv->default_ttl = ttl;
+    bt_mesh_store_cfg(true);
+    return 0;
+}
+int tls_ble_mesh_get_cfg(tls_mesh_primary_cfg_t *cfg)
+{
+    CHECK_SYSTEM_READY();
+    struct bt_mesh_cfg_srv *cfg_srv = bt_mesh_cfg_get();
+    cfg->net_transmit_count = TLS_BT_MESH_TRANSMIT_COUNT(cfg_srv->net_transmit);
+    cfg->net_transmit_intvl = TLS_BT_MESH_TRANSMIT_INT(cfg_srv->net_transmit);
+    cfg->relay = cfg_srv->relay;
+    cfg->relay_retransmit_count = TLS_BT_MESH_TRANSMIT_COUNT(cfg_srv->relay_retransmit);
+    cfg->relay_retransmit_intvl = TLS_BT_MESH_TRANSMIT_INT(cfg_srv->relay_retransmit);
+    cfg->beacon = cfg_srv->beacon;
+    cfg->gatt_proxy = cfg_srv->gatt_proxy;
+    cfg->frnd = cfg_srv->frnd;
+    cfg->default_ttl = cfg_srv->default_ttl;
+    
+    return 0;
+}
+
+int tls_ble_mesh_get_comp(uint16_t net_idx, uint16_t dst, uint8_t *status, char *rsp_data,
+                          uint32_t *data_len)
+{
+    struct os_mbuf *comp = NET_BUF_SIMPLE(32);
+    uint8_t page = 0x00;
+    int err = 0;
+    uint16_t val16;
+    int offset = 0;
+    uint32_t max_offset = data_len[0];
+    CHECK_SYSTEM_READY();
+    net_buf_simple_init(comp, 0);
+    page = 0;
+    err = bt_mesh_cfg_comp_data_get(net_idx, dst, page,
+                                    status, comp);
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("Getting composition failed (err %d)\r\n", err);
+        goto done;
+    }
+
+    if(status[0] != 0x00) {
+        TLS_BT_APPL_TRACE_ERROR("Got non-success status 0x%02x\r\n", status[0]);
+        goto done;
+    }
+
+    TLS_BT_APPL_TRACE_DEBUG("Got Composition Data for 0x%04x:\r\n", dst);
+    val16 = net_buf_simple_pull_le16(comp);
+    offset += sprintf(rsp_data + offset, "%04x,", val16);
+    TLS_BT_APPL_TRACE_DEBUG("\tCID      0x%04x\r\n", val16);
+    val16 = net_buf_simple_pull_le16(comp);
+    offset += sprintf(rsp_data + offset, "%04x,", val16);
+    TLS_BT_APPL_TRACE_DEBUG("\tPID      0x%04x\r\n", val16);
+    val16 = net_buf_simple_pull_le16(comp);
+    offset += sprintf(rsp_data + offset, "%04x,", val16);
+    TLS_BT_APPL_TRACE_DEBUG("\tVID      0x%04x\r\n", val16);
+    val16 = net_buf_simple_pull_le16(comp);
+    offset += sprintf(rsp_data + offset, "%04x,", val16);
+    TLS_BT_APPL_TRACE_DEBUG("\tCRPL     0x%04x\r\n", val16);
+    val16 = net_buf_simple_pull_le16(comp);
+    offset += sprintf(rsp_data + offset, "%04x,", val16);
+    TLS_BT_APPL_TRACE_DEBUG("\tFeatures 0x%04x\r\n", val16);
+
+    while(comp->om_len > 4) {
+        u8_t sig, vnd;
+        u16_t loc;
+        int i;
+        loc = net_buf_simple_pull_le16(comp);
+        sig = net_buf_simple_pull_u8(comp);
+        vnd = net_buf_simple_pull_u8(comp);
+        offset += sprintf(rsp_data + offset, "%04x,%02x,%02x,", loc, sig, vnd);
+        TLS_BT_APPL_TRACE_DEBUG("\n\tElement @ 0x%04x:\r\n", loc);
+
+        if(comp->om_len < ((sig * 2) + (vnd * 4))) {
+            TLS_BT_APPL_TRACE_DEBUG("\t\t...truncated data!\r\n");
+            break;
+        }
+
+        if(sig) {
+            TLS_BT_APPL_TRACE_DEBUG("\t\tSIG Models:\r\n");
+        } else {
+            TLS_BT_APPL_TRACE_DEBUG("\t\tNo SIG Models\r\n");
+        }
+
+        for(i = 0; i < sig; i++) {
+            u16_t mod_id = net_buf_simple_pull_le16(comp);
+            offset += sprintf(rsp_data + offset, "%04x,", mod_id);
+            TLS_BT_APPL_TRACE_DEBUG("\t\t\t0x%04x\r\n", mod_id);
+        }
+
+        if(vnd) {
+            TLS_BT_APPL_TRACE_DEBUG("\t\tVendor Models:\r\n");
+        } else {
+            TLS_BT_APPL_TRACE_DEBUG("\t\tNo Vendor Models\r\n");
+        }
+
+        for(i = 0; i < vnd; i++) {
+            u16_t cid = net_buf_simple_pull_le16(comp);
+            u16_t mod_id = net_buf_simple_pull_le16(comp);
+            offset += sprintf(rsp_data + offset, "%04x,%04x,", cid, mod_id);
+            TLS_BT_APPL_TRACE_DEBUG("\t\t\tCompany 0x%04x: 0x%04x\r\n", cid, mod_id);
+        }
+    }
+
+    assert(offset <= max_offset);
+    data_len[0] = offset;
+done:
+    os_mbuf_free_chain(comp);
+    return err;
+}
+
+int tls_ble_mesh_erase_cfg(void)
+{
+    TLS_BT_APPL_TRACE_DEBUG("erase mesh parameter\r\n");
+    return bt_mesh_settings_clear();
+}
+void tls_ble_mesh_led_init(void)
+{
+  tls_gpio_cfg(MESH_LIGHT_GPIO_RED, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
+  tls_gpio_cfg(MESH_LIGHT_GPIO_GREEN, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
+  tls_gpio_cfg(MESH_LIGHT_GPIO_BLUE, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
+  
+  tls_gpio_write(MESH_LIGHT_GPIO_RED, 1);
+  tls_gpio_write(MESH_LIGHT_GPIO_GREEN, 1);
+  tls_gpio_write(MESH_LIGHT_GPIO_BLUE, 1);
+}
+void tls_ble_mesh_led_update(uint8_t flag)
+{
+  if(flag&WM_MESH_LED_FLAG_BIT_GREEN)
+  {
+    tls_gpio_write(MESH_LIGHT_GPIO_GREEN, 0);
+  }else
+  {
+    tls_gpio_write(MESH_LIGHT_GPIO_GREEN, 1);
+  }
+
+  if(flag&WM_MESH_LED_FLAG_BIT_RED)
+  {
+    tls_gpio_write(MESH_LIGHT_GPIO_RED, 0);
+  }else
+  {
+    tls_gpio_write(MESH_LIGHT_GPIO_RED, 1);
+  }  
+
+  if(flag&WM_MESH_LED_FLAG_BIT_BLUE)
+  {
+    tls_gpio_write(MESH_LIGHT_GPIO_BLUE, 0);
+  }else
+  {
+    tls_gpio_write(MESH_LIGHT_GPIO_BLUE, 1);
+  }    
+}
+
+#endif
+

+ 31 - 0
src/app/bleapp/wm_ble_mesh.h

@@ -0,0 +1,31 @@
+#ifndef __WM_BLE_MESH_H__
+#define __WM_BLE_MESH_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Company ID */
+#ifndef CID_VENDOR
+#define CID_VENDOR 0x070c
+#endif
+
+#define WM_MESH_LED_FLAG_BIT_OFF          0x00
+#define WM_MESH_LED_FLAG_BIT_GREEN        0x01
+#define WM_MESH_LED_FLAG_BIT_RED          0x02
+#define WM_MESH_LED_FLAG_BIT_BLUE         0x04
+
+
+extern int tls_ble_mesh_init(tls_bt_mesh_at_callback_t at_cb, tls_bt_mesh_role_t role,
+                             bool running);
+extern int tls_ble_mesh_deinit();
+
+extern void tls_ble_mesh_led_init(void);
+
+extern void tls_ble_mesh_led_update(uint8_t flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 113 - 0
src/app/bleapp/wm_ble_mesh_gen_level_server.c

@@ -0,0 +1,113 @@
+#include "wm_bt_config.h"
+
+#if (WM_MESH_INCLUDED == CFG_ON)
+
+#include <assert.h>
+#include "mesh/mesh.h"
+
+/* BLE */
+#include "nimble/ble.h"
+#include "host/ble_hs.h"
+#include "mesh/glue.h"
+#include "wm_bt_util.h"
+#include "wm_ble_mesh.h"
+#include "wm_ble_mesh_gen_level_server.h"
+
+struct bt_mesh_model_pub gen_level_pub_srv;
+static int16_t gen_level_state;
+
+
+
+static void gen_level_status(struct bt_mesh_model *model,
+                             struct bt_mesh_msg_ctx *ctx)
+{
+    struct os_mbuf *msg = NET_BUF_SIMPLE(4);
+    TLS_BT_APPL_TRACE_DEBUG("#mesh-level STATUS\r\n");
+    bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x08));
+    net_buf_simple_add_le16(msg, gen_level_state);
+
+    if(bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
+        TLS_BT_APPL_TRACE_DEBUG("#mesh-level STATUS: send status failed\r\n");
+    }
+
+    os_mbuf_free_chain(msg);
+}
+
+static void gen_level_get(struct bt_mesh_model *model,
+                          struct bt_mesh_msg_ctx *ctx,
+                          struct os_mbuf *buf)
+{
+    TLS_BT_APPL_TRACE_DEBUG("#mesh-level GET\r\n");
+    gen_level_status(model, ctx);
+}
+
+static void gen_level_set(struct bt_mesh_model *model,
+                          struct bt_mesh_msg_ctx *ctx,
+                          struct os_mbuf *buf)
+{
+    int16_t level;
+    level = (int16_t) net_buf_simple_pull_le16(buf);
+    TLS_BT_APPL_TRACE_DEBUG("#mesh-level SET: level=%d\r\n", level);
+    gen_level_status(model, ctx);
+    gen_level_state = level;
+    TLS_BT_APPL_TRACE_DEBUG("#mesh-level: level=%d\r\n", gen_level_state);
+}
+
+static void gen_level_set_unack(struct bt_mesh_model *model,
+                                struct bt_mesh_msg_ctx *ctx,
+                                struct os_mbuf *buf)
+{
+    int16_t level;
+    level = (int16_t) net_buf_simple_pull_le16(buf);
+    TLS_BT_APPL_TRACE_DEBUG("#mesh-level SET-UNACK: level=%d\r\n", level);
+    gen_level_state = level;
+    TLS_BT_APPL_TRACE_DEBUG("#mesh-level: level=%d\r\n", gen_level_state);
+}
+
+static void gen_delta_set(struct bt_mesh_model *model,
+                          struct bt_mesh_msg_ctx *ctx,
+                          struct os_mbuf *buf)
+{
+    int16_t delta_level;
+    delta_level = (int16_t) net_buf_simple_pull_le16(buf);
+    TLS_BT_APPL_TRACE_DEBUG("#mesh-level DELTA-SET: delta_level=%d\r\n", delta_level);
+    gen_level_status(model, ctx);
+    gen_level_state += delta_level;
+    TLS_BT_APPL_TRACE_DEBUG("#mesh-level: level=%d\r\n", gen_level_state);
+}
+
+static void gen_delta_set_unack(struct bt_mesh_model *model,
+                                struct bt_mesh_msg_ctx *ctx,
+                                struct os_mbuf *buf)
+{
+    int16_t delta_level;
+    delta_level = (int16_t) net_buf_simple_pull_le16(buf);
+    TLS_BT_APPL_TRACE_DEBUG("#mesh-level DELTA-SET: delta_level=%d\r\n", delta_level);
+    gen_level_state += delta_level;
+    TLS_BT_APPL_TRACE_DEBUG("#mesh-level: level=%d\r\n", gen_level_state);
+}
+
+static void gen_move_set(struct bt_mesh_model *model,
+                         struct bt_mesh_msg_ctx *ctx,
+                         struct os_mbuf *buf)
+{
+}
+
+static void gen_move_set_unack(struct bt_mesh_model *model,
+                               struct bt_mesh_msg_ctx *ctx,
+                               struct os_mbuf *buf)
+{
+}
+
+const struct bt_mesh_model_op gen_level_op[] = {
+    { BT_MESH_MODEL_OP_2(0x82, 0x05), 0, gen_level_get },
+    { BT_MESH_MODEL_OP_2(0x82, 0x06), 3, gen_level_set },
+    { BT_MESH_MODEL_OP_2(0x82, 0x07), 3, gen_level_set_unack },
+    { BT_MESH_MODEL_OP_2(0x82, 0x09), 5, gen_delta_set },
+    { BT_MESH_MODEL_OP_2(0x82, 0x0a), 5, gen_delta_set_unack },
+    { BT_MESH_MODEL_OP_2(0x82, 0x0b), 3, gen_move_set },
+    { BT_MESH_MODEL_OP_2(0x82, 0x0c), 3, gen_move_set_unack },
+    BT_MESH_MODEL_OP_END,
+};
+
+#endif

+ 15 - 0
src/app/bleapp/wm_ble_mesh_gen_level_server.h

@@ -0,0 +1,15 @@
+#ifndef __WM_BLE_MESH_GEN_LEVEL_SERVER_H__
+#define __WM_BLE_MESH_GEN_LEVEL_SERVER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct bt_mesh_model_pub gen_level_pub_srv;
+extern const struct bt_mesh_model_op gen_level_op[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 220 - 0
src/app/bleapp/wm_ble_mesh_gen_onoff_client.c

@@ -0,0 +1,220 @@
+#include "wm_bt_config.h"
+
+#if (WM_MESH_INCLUDED == CFG_ON)
+
+#include <assert.h>
+#include "mesh/mesh.h"
+
+/* BLE */
+#include "nimble/ble.h"
+#include "host/ble_hs.h"
+#include "mesh/glue.h"
+#include "wm_gpio.h"
+#include "wm_bt_util.h"
+#include "wm_ble_mesh.h"
+#include "wm_ble_mesh_gen_onoff_client.h"
+
+#define MESH_GPIO_BUTTON WM_IO_PB_05
+#define BUTTON_DEBOUNCE_DELAY_MS 250
+#define BT_MESH_MODEL_OP_GEN_ONOFF_SET       BT_MESH_MODEL_OP_2(0x82, 0x02)
+#define BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x03)
+
+#define BT_MESH_MODEL_OP_GEN_ONOFF_STATUS    BT_MESH_MODEL_OP_2(0x82, 0x04)
+
+
+struct bt_mesh_model_pub gen_onoff_pub_cli;
+
+struct sw {
+    u8_t sw_num;
+    u8_t onoff_state;
+    struct ble_npl_callout button_work;
+    struct k_delayed_work button_timer;
+};
+
+static u8_t trans_id;
+static u8_t button_press_cnt;
+static struct sw sw;
+static u32_t time, last_time;
+
+/*
+ * OnOff Model Client Op Dispatch Table
+ */
+static void gen_onoff_client_status(struct bt_mesh_model *model,
+                                    struct bt_mesh_msg_ctx *ctx,
+                                    struct os_mbuf *buf)
+{
+    u8_t    state;
+    state = net_buf_simple_pull_u8(buf);
+    TLS_BT_APPL_TRACE_EVENT("Node 0x%04x OnOff status from 0x%04x with state 0x%02x\r\n",
+                            bt_mesh_model_elem(model)->addr, ctx->addr, state);
+}
+
+
+const struct bt_mesh_model_op gen_onoff_client_op[] = {
+    { BT_MESH_MODEL_OP_GEN_ONOFF_STATUS, 1, gen_onoff_client_status },
+    BT_MESH_MODEL_OP_END,
+};
+
+static void gen_onoff_set_unack(struct bt_mesh_model *model,
+                                struct bt_mesh_msg_ctx *ctx,
+                                struct os_mbuf *buf)
+{
+    TLS_BT_APPL_TRACE_DEBUG("#gen_onoff_client, mesh-onoff SET-UNACK, state=%d\r\n", buf->om_data[0]);
+    //gen_on_off_state = buf->om_data[0];
+    //hal_gpio_write(LED_2, !gen_on_off_state);
+}
+
+static void button_gpio_isr_callback(void *context)
+{
+    u16 ret;
+    enum tls_io_name io_index = (enum tls_io_name)context;
+    ret = tls_get_gpio_irq_status(io_index);
+    TLS_BT_APPL_TRACE_VERBOSE("button int flag =%d\r\n", ret);
+
+    if(ret) {
+        tls_clr_gpio_irq_status(io_index);
+        ret = tls_gpio_read(io_index);
+        TLS_BT_APPL_TRACE_VERBOSE("after int io =%d\r\n", ret);
+    }
+
+    /*
+     * One button press within a 1 second interval sends an on message
+     * More than one button press sends an off message
+     */
+    time = k_uptime_get_32();
+
+    /* debounce the switch */
+    if(time < last_time + BUTTON_DEBOUNCE_DELAY_MS) {
+        last_time = time;
+        return;
+    }
+
+    if(button_press_cnt == 0) {
+        k_delayed_work_submit(&sw.button_timer, K_MSEC(500));
+    }
+
+    TLS_BT_APPL_TRACE_DEBUG("button_press_cnt 0x%02x\r\n", button_press_cnt);
+    button_press_cnt++;
+    /* The variable pin_pos is the pin position in the GPIO register,
+     * not the pin number. It's assumed that only one bit is set.
+     */
+    sw.sw_num = io_index;//pin_to_sw(pin_pos);
+    last_time = time;
+}
+
+/*
+ * Button Count Timer Worker
+ */
+
+static void button_cnt_timer(struct ble_npl_event *work)
+{
+    struct bt_mesh_model *mod_cli = (struct bt_mesh_model *)work->arg;
+    struct sw *button_sw = (struct sw *)mod_cli->user_data;
+    button_sw->onoff_state = !button_sw->onoff_state;//button_press_cnt == 1 ? 1 : 0;
+    TLS_BT_APPL_TRACE_EVENT("button_press_cnt 0x%02x onoff_state 0x%02x\r\n",
+                            button_press_cnt, button_sw->onoff_state);
+    button_press_cnt = 0;
+    k_work_submit(&sw.button_work);
+}
+
+/*
+ * Button Pressed Worker Task
+ */
+
+static void button_pressed_worker(struct ble_npl_event *work)
+{
+    struct os_mbuf *msg = NET_BUF_SIMPLE(1);
+    struct bt_mesh_model *mod_cli, *mod_srv;
+    struct bt_mesh_model_pub *pub_cli;
+    struct sw *sw = NULL;
+    u8_t sw_idx = 0;
+    int err;
+    mod_cli = (struct bt_mesh_model *)work->arg;
+    pub_cli = mod_cli->pub;
+    sw = (struct sw *)mod_cli->user_data;
+    sw_idx = sw->sw_num;
+
+    /* If unprovisioned, just call the set function.
+     * The intent is to have switch-like behavior
+     * prior to provisioning. Once provisioned,
+     * the button and its corresponding led are no longer
+     * associated and act independently. So, if a button is to
+     * control its associated led after provisioning, the button
+     * must be configured to either publish to the led's unicast
+     * address or a group to which the led is subscribed.
+     */
+
+    if(node_primary_addr == BT_MESH_ADDR_UNASSIGNED) {
+        struct bt_mesh_msg_ctx ctx = {
+            .addr = sw_idx + node_primary_addr,
+        };
+        /* This is a dummy message sufficient
+        * for the led server
+        */
+        net_buf_simple_add_u8(msg, sw->onoff_state);
+        gen_onoff_set_unack(mod_srv, &ctx, msg);
+        goto done;
+    }
+
+    if(pub_cli->addr == BT_MESH_ADDR_UNASSIGNED) {
+        goto done;
+    }
+
+    TLS_BT_APPL_TRACE_DEBUG("publish to 0x%04x onoff 0x%04x sw_idx 0x%04x\r\n",
+                            pub_cli->addr, sw->onoff_state, sw_idx);
+    bt_mesh_model_msg_init(pub_cli->msg,
+                           BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK);
+    net_buf_simple_add_u8(pub_cli->msg, sw->onoff_state);
+    net_buf_simple_add_u8(pub_cli->msg, trans_id++);
+    err = bt_mesh_model_publish(mod_cli);
+
+    if(err) {
+        TLS_BT_APPL_TRACE_ERROR("bt_mesh_model_publish err %d\r\n", err);
+    }
+
+done:
+    os_mbuf_free_chain(msg);
+}
+
+static int gen_onoff_client_deinit(struct bt_mesh_model *model)
+{
+    TLS_BT_APPL_TRACE_DEBUG("gen_onoff_client_deinit\r\n");
+    /*Free timer*/
+    k_work_deinit(&sw.button_work);
+    k_delayed_work_deinit(&sw.button_timer);
+    /*Reset state*/
+    sw.onoff_state = 0;
+    /*Reset gpio interrupt*/
+    tls_gpio_irq_disable(MESH_GPIO_BUTTON);
+    tls_gpio_isr_register(MESH_GPIO_BUTTON, NULL, (void *)MESH_GPIO_BUTTON);
+    return 0;
+}
+
+static int gen_onoff_client_init(struct bt_mesh_model *model)
+{
+    TLS_BT_APPL_TRACE_DEBUG("gen_onoff_client_init\r\n");
+    model->user_data = &sw;
+
+    /* Initialize the button debouncer */
+    last_time = k_uptime_get_32();
+    sw.onoff_state = 0;
+    /* Initialize button worker task*/
+    k_work_init(&sw.button_work, button_pressed_worker);
+    k_work_add_arg(&sw.button_work, model);
+    /* Initialize button count timer */
+    k_delayed_work_init(&sw.button_timer, button_cnt_timer);
+    k_delayed_work_add_arg(&sw.button_timer, model);
+
+    /*Initialize the button input gpio settings*/
+    tls_gpio_cfg(MESH_GPIO_BUTTON, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_PULLHIGH);
+    tls_gpio_isr_register(MESH_GPIO_BUTTON, button_gpio_isr_callback, (void *)MESH_GPIO_BUTTON);
+    tls_gpio_irq_enable(MESH_GPIO_BUTTON, WM_GPIO_IRQ_TRIG_RISING_EDGE);    
+    return 0;
+}
+
+const struct bt_mesh_model_cb gen_onoff_client_cb = {
+    .init = gen_onoff_client_init,
+    .deinit = gen_onoff_client_deinit,
+};
+#endif
+

+ 19 - 0
src/app/bleapp/wm_ble_mesh_gen_onoff_client.h

@@ -0,0 +1,19 @@
+#ifndef __WM_BLE_MESH_GEN_ONOFF_CLIENT_H__
+#define __WM_BLE_MESH_GEN_ONOFF_CLIENT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct bt_mesh_model_pub gen_onoff_pub_cli;
+extern const struct bt_mesh_model_cb gen_onoff_client_cb;
+extern const struct bt_mesh_model_op gen_onoff_client_op[];
+extern u16_t node_primary_addr;
+extern u16_t node_primary_net_idx;
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif

+ 127 - 0
src/app/bleapp/wm_ble_mesh_gen_onoff_server.c

@@ -0,0 +1,127 @@
+#include "wm_bt_config.h"
+
+#if (WM_MESH_INCLUDED == CFG_ON)
+
+#include <assert.h>
+#include "mesh/mesh.h"
+
+/* BLE */
+#include "nimble/ble.h"
+#include "host/ble_hs.h"
+#include "mesh/glue.h"
+#include "wm_gpio.h"
+#include "wm_bt_util.h"
+#include "wm_ble_mesh.h"
+#include "wm_ble_mesh_gen_onoff_server.h"
+
+
+
+struct bt_mesh_model_pub gen_onoff_pub_srv;
+static uint8_t gen_on_off_state;
+
+static void gen_onoff_status(struct bt_mesh_model *model,
+                             struct bt_mesh_msg_ctx *ctx)
+{
+    struct os_mbuf *msg = NET_BUF_SIMPLE(3);
+    uint8_t *status;
+    TLS_BT_APPL_TRACE_DEBUG("#mesh-onoff STATUS\r\n");
+    bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x04));
+    status = net_buf_simple_add(msg, 1);
+    *status = gen_on_off_state;
+
+    if(bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
+        TLS_BT_APPL_TRACE_DEBUG("#mesh-onoff STATUS: send status failed\r\n");
+    }
+
+    os_mbuf_free_chain(msg);
+}
+
+static void gen_onoff_get(struct bt_mesh_model *model,
+                          struct bt_mesh_msg_ctx *ctx,
+                          struct os_mbuf *buf)
+{
+    TLS_BT_APPL_TRACE_DEBUG("#mesh-onoff GET\r\n");
+    gen_onoff_status(model, ctx);
+}
+
+static void gen_onoff_set(struct bt_mesh_model *model,
+                          struct bt_mesh_msg_ctx *ctx,
+                          struct os_mbuf *buf)
+{
+    int err;
+    struct os_mbuf *msg = model->pub->msg;
+    TLS_BT_APPL_TRACE_DEBUG("#mesh-onoff SET, %d\r\n", buf->om_data[0]);
+    gen_on_off_state = buf->om_data[0];
+    if(gen_on_off_state)
+    {
+        tls_ble_mesh_led_update(WM_MESH_LED_FLAG_BIT_RED|WM_MESH_LED_FLAG_BIT_GREEN|WM_MESH_LED_FLAG_BIT_BLUE);
+    }else
+    {
+        tls_ble_mesh_led_update(WM_MESH_LED_FLAG_BIT_OFF);
+    }
+
+    gen_onoff_status(model, ctx);
+    /*
+      * If a server has a publish address, it is required to
+      * publish status on a state change
+      *
+      * See Mesh Profile Specification 3.7.6.1.2
+      *
+      * Only publish if there is an assigned address
+      */
+#define BT_MESH_MODEL_OP_GEN_ONOFF_STATUS   BT_MESH_MODEL_OP_2(0x82, 0x04)
+
+    if(model->pub->addr != BT_MESH_ADDR_UNASSIGNED) {
+        TLS_BT_APPL_TRACE_DEBUG("Node:0x%04x publish addr:0x%04x cur 0x%02x\r\n",
+                                bt_mesh_model_elem(model)->addr, model->pub->addr, gen_on_off_state);
+        bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_ONOFF_STATUS);
+        net_buf_simple_add_u8(msg, gen_on_off_state);
+        err = bt_mesh_model_publish(model);
+
+        if(err) {
+            TLS_BT_APPL_TRACE_DEBUG("bt_mesh_model_publish err %d\r\n", err);
+        }
+    }
+}
+
+static void gen_onoff_set_unack(struct bt_mesh_model *model,
+                                struct bt_mesh_msg_ctx *ctx,
+                                struct os_mbuf *buf)
+{
+    TLS_BT_APPL_TRACE_DEBUG("#mesh-onoff SET-UNACK, %d\r\n", buf->om_data[0]);
+    gen_on_off_state = buf->om_data[0];
+    if(gen_on_off_state)
+    {
+        tls_ble_mesh_led_update(WM_MESH_LED_FLAG_BIT_RED|WM_MESH_LED_FLAG_BIT_GREEN|WM_MESH_LED_FLAG_BIT_BLUE);
+    }else
+    {
+        tls_ble_mesh_led_update(WM_MESH_LED_FLAG_BIT_OFF);
+    }
+}
+
+const struct bt_mesh_model_op gen_onoff_op[] = {
+    { BT_MESH_MODEL_OP_2(0x82, 0x01), 0, gen_onoff_get },
+    { BT_MESH_MODEL_OP_2(0x82, 0x02), 2, gen_onoff_set },
+    { BT_MESH_MODEL_OP_2(0x82, 0x03), 2, gen_onoff_set_unack },
+    BT_MESH_MODEL_OP_END,
+};
+
+static int gen_onoff_server_init(struct bt_mesh_model *model)
+{
+    TLS_BT_APPL_TRACE_DEBUG("gen_onoff_server_init\r\n");
+    /*Initialize the light gpio settings*/
+    tls_ble_mesh_led_init();
+    return 0;
+}
+static int gen_onoff_server_deinit(struct bt_mesh_model *model)
+{
+    TLS_BT_APPL_TRACE_DEBUG("gen_onoff_server_deinit\r\n");
+    return 0;
+}
+
+
+const struct bt_mesh_model_cb gen_onoff_server_cb = {
+    .init = gen_onoff_server_init,
+    .deinit = gen_onoff_server_deinit,
+};
+#endif

+ 16 - 0
src/app/bleapp/wm_ble_mesh_gen_onoff_server.h

@@ -0,0 +1,16 @@
+#ifndef __WM_BLE_MESH_GEN_ONOFF_SERVER_H__
+#define __WM_BLE_MESH_GEN_ONOFF_SERVER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const struct bt_mesh_model_cb gen_onoff_server_cb;
+extern struct bt_mesh_model_pub gen_onoff_pub_srv;
+extern const struct bt_mesh_model_op gen_onoff_op[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 134 - 0
src/app/bleapp/wm_ble_mesh_health_server.c

@@ -0,0 +1,134 @@
+#include "wm_bt_config.h"
+
+#if (WM_MESH_INCLUDED == CFG_ON)
+
+#include <assert.h>
+#include "mesh/mesh.h"
+
+/* BLE */
+#include "nimble/ble.h"
+#include "host/ble_hs.h"
+#include "mesh/glue.h"
+#include "wm_bt_util.h"
+#include "wm_ble_mesh.h"
+#include "wm_ble_mesh_health_server.h"
+
+#define STANDARD_TEST_ID 0x00
+#define TEST_ID 0x01
+static int recent_test_id = STANDARD_TEST_ID;
+
+#define FAULT_ARR_SIZE 2
+static bool has_reg_fault = true;
+
+struct bt_mesh_model_pub health_pub;
+
+static int
+fault_get_cur(struct bt_mesh_model *model,
+              uint8_t *test_id,
+              uint16_t *company_id,
+              uint8_t *faults,
+              uint8_t *fault_count)
+{
+    uint8_t reg_faults[FAULT_ARR_SIZE] = { [0 ... FAULT_ARR_SIZE - 1] = 0xff };
+    TLS_BT_APPL_TRACE_DEBUG("fault_get_cur() has_reg_fault %u\r\n", has_reg_fault);
+    *test_id = recent_test_id;
+    *company_id = CID_VENDOR;
+    *fault_count = min(*fault_count, sizeof(reg_faults));
+    memcpy(faults, reg_faults, *fault_count);
+    return 0;
+}
+
+static int
+fault_get_reg(struct bt_mesh_model *model,
+              uint16_t company_id,
+              uint8_t *test_id,
+              uint8_t *faults,
+              uint8_t *fault_count)
+{
+    if(company_id != CID_VENDOR) {
+        return -BLE_HS_EINVAL;
+    }
+
+    TLS_BT_APPL_TRACE_DEBUG("fault_get_reg() has_reg_fault %u\r\n", has_reg_fault);
+    *test_id = recent_test_id;
+
+    if(has_reg_fault) {
+        uint8_t reg_faults[FAULT_ARR_SIZE] = { [0 ... FAULT_ARR_SIZE - 1] = 0xff };
+        *fault_count = min(*fault_count, sizeof(reg_faults));
+        memcpy(faults, reg_faults, *fault_count);
+    } else {
+        *fault_count = 0;
+    }
+
+    return 0;
+}
+
+static int
+fault_clear(struct bt_mesh_model *model, uint16_t company_id)
+{
+    if(company_id != CID_VENDOR) {
+        return -BLE_HS_EINVAL;
+    }
+
+    has_reg_fault = false;
+    return 0;
+}
+
+static int
+fault_test(struct bt_mesh_model *model, uint8_t test_id, uint16_t company_id)
+{
+    if(company_id != CID_VENDOR) {
+        return -BLE_HS_EINVAL;
+    }
+
+    if(test_id != STANDARD_TEST_ID && test_id != TEST_ID) {
+        return -BLE_HS_EINVAL;
+    }
+
+    recent_test_id = test_id;
+    has_reg_fault = true;
+    bt_mesh_fault_update(bt_mesh_model_elem(model));
+    return 0;
+}
+static void
+attn_on(struct bt_mesh_model *model)
+{
+    TLS_BT_APPL_TRACE_DEBUG("attentation_on\r\n");
+    tls_ble_mesh_led_update(WM_MESH_LED_FLAG_BIT_RED); 
+}
+static void
+attn_off(struct bt_mesh_model *model)
+{
+    TLS_BT_APPL_TRACE_DEBUG("attentation_off\r\n");
+    tls_ble_mesh_led_update(WM_MESH_LED_FLAG_BIT_OFF);
+}
+static void
+init(struct bt_mesh_model *model)
+{
+    TLS_BT_APPL_TRACE_DEBUG("health model init\r\n");
+    tls_ble_mesh_led_init();  
+}
+static void
+deinit(struct bt_mesh_model *model)
+{
+    TLS_BT_APPL_TRACE_DEBUG("health model deinit\r\n");
+    tls_ble_mesh_led_update(WM_MESH_LED_FLAG_BIT_OFF); 
+}
+
+
+static const struct bt_mesh_health_srv_cb health_srv_cb = {
+    .init = &init,
+    .deinit = &deinit,
+    .fault_get_cur = &fault_get_cur,
+    .fault_get_reg = &fault_get_reg,
+    .fault_clear = &fault_clear,
+    .fault_test = &fault_test,
+    .attn_on = &attn_on,
+    .attn_off = &attn_off,
+};
+
+struct bt_mesh_health_srv health_srv = {
+    .cb = &health_srv_cb,
+};
+#endif
+

+ 15 - 0
src/app/bleapp/wm_ble_mesh_health_server.h

@@ -0,0 +1,15 @@
+#ifndef __WM_BLE_MESH_HEALTH_SERVER_H__
+#define __WM_BLE_MESH_HEALTH_SERVER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct bt_mesh_model_pub health_pub;
+extern struct bt_mesh_health_srv health_srv;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 107 - 0
src/app/bleapp/wm_ble_mesh_light_model.c

@@ -0,0 +1,107 @@
+
+#include "wm_bt_config.h"
+
+#if (WM_MESH_INCLUDED == CFG_ON)
+
+
+
+#include "mesh/mesh.h"
+#include "mesh/glue.h"
+#include "wm_bt_util.h"
+#include "wm_ble_mesh.h"
+
+#include "wm_ble_mesh_light_model.h"
+
+
+static uint8_t gen_onoff_state;
+static int16_t gen_level_state;
+static uint32_t onoff_counter = 0;
+static void update_light_state(void)
+{
+    TLS_BT_APPL_TRACE_DEBUG("Light state: onoff=%d lvl=0x%04x[%d]\r\n", gen_onoff_state,
+                            (u16_t)gen_level_state, onoff_counter++);
+
+
+    if(gen_onoff_state)
+    {
+        tls_ble_mesh_led_update(WM_MESH_LED_FLAG_BIT_RED|WM_MESH_LED_FLAG_BIT_GREEN|WM_MESH_LED_FLAG_BIT_BLUE);
+    }else
+    {
+        tls_ble_mesh_led_update(WM_MESH_LED_FLAG_BIT_OFF);
+    }
+
+}
+
+int tls_light_model_gen_onoff_get(struct bt_mesh_model *model, u8_t *state)
+{
+    *state = gen_onoff_state;
+    return 0;
+}
+
+int tls_light_model_gen_onoff_set(struct bt_mesh_model *model, u8_t state)
+{
+    gen_onoff_state = state;
+    update_light_state();
+    return 0;
+}
+int tls_light_model_gen_onoff_init(struct bt_mesh_model *model)
+{
+    return 0;
+}
+int tls_light_model_gen_onoff_deinit(struct bt_mesh_model *model)
+{
+    return 0;    
+}
+
+
+int tls_light_model_gen_level_get(struct bt_mesh_model *model, s16_t *level)
+{
+    *level = gen_level_state;
+    return 0;
+}
+
+int tls_light_model_gen_level_set(struct bt_mesh_model *model, s16_t level)
+{
+    gen_level_state = level;
+
+    if((u16_t)gen_level_state > 0x0000) {
+        gen_onoff_state = 1;
+    }
+
+    if((u16_t)gen_level_state == 0x0000) {
+        gen_onoff_state = 0;
+    }
+
+    update_light_state();
+    return 0;
+}
+int tls_light_model_gen_level_init(struct bt_mesh_model *model)
+{
+    return 0;    
+}
+int tls_light_model_gen_level_deinit(struct bt_mesh_model *model)
+{
+    return 0;    
+}
+
+
+
+int tls_light_model_light_lightness_get(struct bt_mesh_model *model, s16_t *lightness)
+{
+    return tls_light_model_gen_level_get(model, lightness);
+}
+
+int tls_light_model_light_lightness_set(struct bt_mesh_model *model, s16_t lightness)
+{
+    return tls_light_model_gen_level_set(model, lightness);
+}
+int tls_light_model_light_lightness_init(struct bt_mesh_model *model)
+{
+    return 0;    
+}
+int tls_light_model_light_lightness_deinit(struct bt_mesh_model *model)
+{
+    return 0;
+}
+
+#endif

+ 29 - 0
src/app/bleapp/wm_ble_mesh_light_model.h

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef __BT_MESH_LIGHT_MODEL_H
+#define __BT_MESH_LIGHT_MODEL_H
+
+#include "syscfg/syscfg.h"
+#include "mesh/mesh.h"
+
+int tls_light_model_gen_onoff_get(struct bt_mesh_model *model, u8_t *state);
+int tls_light_model_gen_onoff_set(struct bt_mesh_model *model, u8_t state);
+int tls_light_model_gen_onoff_init(struct bt_mesh_model *model);
+int tls_light_model_gen_onoff_deinit(struct bt_mesh_model *model);
+
+
+int tls_light_model_gen_level_get(struct bt_mesh_model *model, s16_t *level);
+int tls_light_model_gen_level_set(struct bt_mesh_model *model, s16_t level);
+int tls_light_model_gen_level_init(struct bt_mesh_model *model);
+int tls_light_model_gen_level_deinit(struct bt_mesh_model *model);
+
+int tls_light_model_light_lightness_get(struct bt_mesh_model *model, s16_t *lightness);
+int tls_light_model_light_lightness_set(struct bt_mesh_model *model, s16_t lightness);
+int tls_light_model_light_lightness_init(struct bt_mesh_model *model);
+int tls_light_model_light_lightness_deinit(struct bt_mesh_model *model);
+
+
+#endif

+ 252 - 0
src/app/bleapp/wm_ble_mesh_node_demo.c

@@ -0,0 +1,252 @@
+/*****************************************************************************
+**
+**  Name:           wm_ble_mesh_node_demo.c
+**
+**  Description:    This file contains the sample functions for mesh node application
+**
+*****************************************************************************/
+
+#include "wm_bt_config.h"
+
+#if (WM_MESH_INCLUDED == CFG_ON)
+
+#include <assert.h>
+#include "mesh/mesh.h"
+
+#include "wm_bt_app.h"
+#include "wm_efuse.h"
+
+
+/* BLE */
+#include "nimble/ble.h"
+#include "host/ble_hs.h"
+#include "mesh/glue.h"
+#include "wm_bt_util.h"
+#include "wm_ble_mesh_node_demo.h"
+#include "wm_ble_gap.h"
+
+
+/*Mesh models*/
+#include "wm_ble_mesh_health_server.h"
+#include "wm_ble_mesh_gen_onoff_server.h"
+#include "wm_ble_mesh_gen_onoff_client.h"
+#include "wm_ble_mesh_gen_level_server.h"
+#include "wm_ble_mesh_vnd_model.h"
+
+/*
+ * GLOBAL VARIABLE DEFINITIONS
+ ****************************************************************************************
+ */
+
+uint16_t node_primary_addr;
+uint16_t node_primary_net_idx;
+static bool node_enabled =false;
+static struct ble_gap_event_listener app_mesh_event_listener;
+
+static struct bt_mesh_cfg_srv cfg_srv = {
+    .relay = BT_MESH_RELAY_ENABLED,
+    .beacon = BT_MESH_BEACON_ENABLED,
+#if MYNEWT_VAL(BLE_MESH_FRIEND)
+    .frnd = BT_MESH_FRIEND_ENABLED,
+#else
+    .gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
+#endif
+#if MYNEWT_VAL(BLE_MESH_GATT_PROXY)
+    .gatt_proxy = BT_MESH_GATT_PROXY_ENABLED,
+#else
+    .gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
+#endif
+    .default_ttl = 7,
+
+    /* 3 transmissions with 20ms interval */
+    .net_transmit = BT_MESH_TRANSMIT(2, 20),
+    .relay_retransmit = BT_MESH_TRANSMIT(2, 20),
+};
+
+
+static struct bt_mesh_model root_models[] = {
+    BT_MESH_MODEL_CFG_SRV(&cfg_srv),
+    BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
+    BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_op,
+                     &gen_onoff_pub_srv, NULL, &gen_onoff_server_cb),
+    BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_SRV, gen_level_op,
+                  &gen_level_pub_srv, NULL),
+    BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_GEN_ONOFF_CLI, gen_onoff_client_op,
+                     &gen_onoff_pub_cli, NULL, &gen_onoff_client_cb),
+
+};
+
+static struct bt_mesh_model vnd_models[] = {
+    BT_MESH_MODEL_VND(CID_VENDOR, BT_MESH_MODEL_ID_GEN_ONOFF_SRV, vnd_model_op,
+                      &vnd_model_pub, NULL),
+};
+
+static struct bt_mesh_elem elements[] = {
+    BT_MESH_ELEM(0, root_models, vnd_models),
+};
+
+static const struct bt_mesh_comp node_comp = {
+    .cid = CID_VENDOR,
+    .elem = elements,
+    .elem_count = ARRAY_SIZE(elements),
+};
+
+/*
+ * LOCAL FUNCTION DEFINITIONS
+ ****************************************************************************************
+ */
+
+static void
+pub_init(void)
+{
+    health_pub.msg  = BT_MESH_HEALTH_FAULT_MSG(0);
+    gen_onoff_pub_srv.msg = NET_BUF_SIMPLE(2 + 2);
+    gen_onoff_pub_cli.msg = NET_BUF_SIMPLE(2 + 2);
+}
+static void
+pub_deinit(void)
+{
+    if(health_pub.msg) {
+        os_mbuf_free_chain(health_pub.msg);
+        health_pub.msg = NULL;
+    }
+
+    if(gen_onoff_pub_srv.msg) {
+        os_mbuf_free_chain(gen_onoff_pub_srv.msg);
+        gen_onoff_pub_srv.msg = NULL;
+    }
+
+    if(gen_onoff_pub_cli.msg) {
+        os_mbuf_free_chain(gen_onoff_pub_cli.msg);
+        gen_onoff_pub_cli.msg = NULL;
+    }
+}
+
+static int output_number(bt_mesh_output_action_t action, uint32_t number)
+{
+    TLS_BT_APPL_TRACE_DEBUG("OOB Number: %lu\r\n", number);
+    return 0;
+}
+
+static void prov_complete(u16_t net_idx, u16_t addr)
+{
+    TLS_BT_APPL_TRACE_DEBUG("Local node provisioned, primary address 0x%04x, net_idx=%d\r\n", addr,
+                            net_idx);
+    node_primary_addr = addr;
+    node_primary_net_idx = net_idx;
+}
+
+static uint8_t dev_uuid[16] = MYNEWT_VAL(BLE_MESH_DEV_UUID);
+static char    dev_name[16] = CONFIG_BT_DEVICE_NAME;
+
+static const struct bt_mesh_prov prov = {
+    .name = dev_name,
+    .uuid = dev_uuid,
+    .output_size = 4,
+    .output_actions = BT_MESH_DISPLAY_NUMBER | BT_MESH_BEEP | BT_MESH_VIBRATE | BT_MESH_BLINK,
+    .output_number = output_number,
+    .complete = prov_complete,
+};
+    
+static int ble_gap_host_shutdown_cb(struct ble_gap_event *event, void *arg)
+{
+    if(BLE_GAP_EVENT_HOST_SHUTDOWN == event->type)
+    {
+        tls_bt_set_mesh_mode(0);
+        bt_mesh_deinit();
+        pub_deinit();
+        node_enabled = false;
+        TLS_BT_APPL_TRACE_DEBUG("Mesh deinitialized\r\n");
+    }
+
+    return 0;
+}
+static void notify_flash_flush_available(void)
+{
+#if (MYNEWT_VAL(BLE_MESH_SETTINGS))
+    bt_mesh_settings_flush();
+#endif
+}
+
+
+/*
+ * EXPORTED FUNCTION DEFINITIONS
+ ****************************************************************************************
+ */
+
+int
+tls_ble_mesh_node_deinit(int reason)
+{
+    CHECK_SYSTEM_READY();
+    if(!node_enabled) return 0;
+    
+    TLS_BT_APPL_TRACE_DEBUG("Mesh freeing resouce\r\n");
+    tls_bt_set_mesh_mode(0);
+    bt_mesh_deinit();
+    pub_deinit();
+    TLS_BT_APPL_TRACE_DEBUG("Mesh deinitialized\r\n");
+    node_enabled = false;
+    ble_gap_event_listener_unregister(&app_mesh_event_listener);
+    return 0;
+}
+
+int
+tls_ble_mesh_node_init(void)
+{
+    int err = 0;
+    ble_addr_t addr;
+    CHECK_SYSTEM_READY();
+    if(node_enabled) return 0;
+    
+    TLS_BT_APPL_TRACE_DEBUG("Mesh Node initializing\r\n");
+    tls_bt_set_mesh_mode(1);
+    pub_init();
+    /* Use NRPA */
+    #if 1
+    err = ble_hs_id_gen_rnd(1, &addr);
+    assert(err == 0);
+    err = ble_hs_id_set_rnd(addr.val);
+    assert(err == 0);
+    #endif
+    tls_ble_gap_get_name(dev_name);
+    /*using BT MAC as device uuid high 6 bytes*/
+    tls_get_bt_mac_addr(&dev_uuid[10]);
+    
+    err = bt_mesh_init(addr.type, &prov, &node_comp);
+
+    if(err) {
+        TLS_BT_APPL_TRACE_DEBUG("Initializing mesh node failed (err %d)\r\n", err);
+        return err;
+    }
+
+    TLS_BT_APPL_TRACE_DEBUG("Mesh(%s) initialized\r\n", dev_name);
+#if (MYNEWT_VAL(BLE_MESH_SETTINGS))
+    tls_bt_register_pending_process_callback(notify_flash_flush_available);
+    err = bt_mesh_settings_load(true);
+#endif
+
+    if(err == -2) {
+        TLS_BT_APPL_TRACE_DEBUG("Mesh nvram parameter mismatch with the prefered role, Please erase the nvram or change the role\r\n");
+        return err;
+    } else {
+        /**if invalid nvram area, return success*/
+        err = 0;
+    }
+
+    TLS_BT_APPL_TRACE_DEBUG("node role enabled\r\n");
+    bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
+    bt_mesh_role_set(true);
+
+    if(bt_mesh_is_provisioned()) {
+        TLS_BT_APPL_TRACE_DEBUG("Mesh network restored from flash\r\n");
+    }
+    
+    ble_gap_event_listener_register(&app_mesh_event_listener,
+                                ble_gap_host_shutdown_cb, NULL);
+
+    TLS_BT_APPL_TRACE_DEBUG("node role running\r\n");
+    node_enabled = true;
+    return err;
+}
+#endif
+

+ 20 - 0
src/app/bleapp/wm_ble_mesh_node_demo.h

@@ -0,0 +1,20 @@
+#ifndef __WM_BLE_MESH_NODE_H__
+#define __WM_BLE_MESH_NODE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Company ID */
+#ifndef CID_VENDOR
+#define CID_VENDOR 0x070c
+#endif
+
+extern int tls_ble_mesh_node_init(void);
+extern int tls_ble_mesh_node_deinit(int reason);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 297 - 0
src/app/bleapp/wm_ble_mesh_vnd_model.c

@@ -0,0 +1,297 @@
+#include "wm_bt_config.h"
+
+#if (WM_MESH_INCLUDED == CFG_ON)
+
+#include <assert.h>
+#include "mesh/mesh.h"
+
+/* BLE */
+#include "nimble/ble.h"
+#include "host/ble_hs.h"
+#include "services/gap/ble_svc_gap.h"
+#include "mesh/glue.h"
+#include "wm_bt_util.h"
+#include "wm_ble_mesh.h"
+#include "wm_ble_mesh_vnd_model.h"
+
+static struct bt_mesh_model *g_vnd_model_ptr = NULL;
+
+struct bt_mesh_model_pub vnd_model_pub;
+
+//#define THROUGHTPUT_TEST
+//#define NAME_ADDR_BROADCASE_SUPPORT
+
+#ifdef THROUGHTPUT_TEST
+static uint32_t g_send_bytes = 0;
+static uint32_t g_recv_bytes = 0;
+static uint32_t g_time_last = 0;
+/* Attention Timer state */
+struct k_delayed_work ones_timer;
+
+static void ones_timer_cb(struct ble_npl_event *work);
+#endif
+
+#ifdef NAME_ADDR_BROADCASE_SUPPORT
+
+static void vnd_model_indicate_recv(struct bt_mesh_model *model,
+                          struct bt_mesh_msg_ctx *ctx,
+                          struct os_mbuf *buf);
+
+static void vnd_model_update_cb(struct ble_npl_event *work);
+static uint8_t update_tid = 0x80;
+static struct k_delayed_work update_timer;
+static uint8_t update_retry = 0;
+#endif
+
+static void vnd_model_recv(struct bt_mesh_model *model,
+                           struct bt_mesh_msg_ctx *ctx,
+                           struct os_mbuf *buf)
+{
+    struct os_mbuf *msg = NULL;
+    uint8_t ack[3] = {0x00, 0x00, 0x00}; 
+    TLS_BT_APPL_TRACE_DEBUG("#vendor-model-recv, send_rel:%s\r\n", ctx->send_rel?"true":"false");
+    TLS_BT_APPL_TRACE_VERBOSE("data:%s len:%d\r\n", bt_hex(buf->om_data, buf->om_len),buf->om_len);
+
+#ifdef THROUGHTPUT_TEST
+        g_recv_bytes += buf->om_len;
+#endif
+
+    /*send ack*/
+    msg = NET_BUF_SIMPLE(3);
+    bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_3(0x02, CID_VENDOR));
+    os_mbuf_append(msg, ack, sizeof(ack));
+
+    if(bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
+        TLS_BT_APPL_TRACE_DEBUG("#vendor-model-recv: send rsp failed\r\n");
+    }
+
+    os_mbuf_free_chain(msg);
+}
+
+static void vnd_model_ack_recv(struct bt_mesh_model *model,
+                          struct bt_mesh_msg_ctx *ctx,
+                          struct os_mbuf *buf)
+{
+   TLS_BT_APPL_TRACE_DEBUG("#vendor-model-ack-recv, send_rel:%s\r\n", ctx->send_rel?"true":"false");
+   TLS_BT_APPL_TRACE_DEBUG("data:%s len:%d\r\n", bt_hex(buf->om_data, buf->om_len),
+                           buf->om_len);
+}
+
+#ifdef NAME_ADDR_BROADCASE_SUPPORT 
+static void vnd_model_indicate_ack_recv(struct bt_mesh_model *model,
+                                        struct bt_mesh_msg_ctx *ctx,
+                                        struct os_mbuf *buf)
+{
+  TLS_BT_APPL_TRACE_DEBUG("#vnd_model_indicate_ack_recv, send_rel:%s\r\n", ctx->send_rel?"true":"false");
+  TLS_BT_APPL_TRACE_DEBUG("data:%s len:%d\r\n", bt_hex(buf->om_data, buf->om_len),
+                          buf->om_len);
+}
+#endif
+static int vnd_model_init(struct bt_mesh_model *model)
+{
+    //struct bt_mesh_cfg_srv *cfg = model->user_data;
+    TLS_BT_APPL_TRACE_DEBUG("vnd_model_init\r\n");
+    g_vnd_model_ptr = model;
+
+#ifdef NAME_ADDR_BROADCASE_SUPPORT    
+    k_delayed_work_init(&update_timer, vnd_model_update_cb);
+    k_delayed_work_add_arg(&update_timer, (void *)model);
+    k_delayed_work_submit(&update_timer, 1 * 3000);    
+    update_retry = 0;
+#endif    
+    
+#ifdef THROUGHTPUT_TEST
+    g_send_bytes = 0;
+    g_recv_bytes = 0;
+    g_time_last = tls_os_get_time();
+    k_delayed_work_init(&ones_timer, ones_timer_cb);
+    k_delayed_work_submit(&ones_timer, 1 * 1000);
+#endif
+    
+    return 0;
+}
+
+static int vnd_model_deinit(struct bt_mesh_model *model)
+{
+    TLS_BT_APPL_TRACE_DEBUG("vnd_model_deinit\r\n");
+#ifdef THROUGHTPUT_TEST    
+    k_delayed_work_deinit(&ones_timer);
+#endif
+#ifdef NAME_ADDR_BROADCASE_SUPPORT 
+    k_delayed_work_deinit(&update_timer);
+#endif
+    return 0;
+}
+
+
+const struct bt_mesh_model_op vnd_model_op[] = {
+    { BT_MESH_MODEL_OP_3(0x01, CID_VENDOR), 0, vnd_model_recv },
+    { BT_MESH_MODEL_OP_3(0x02, CID_VENDOR), 0, vnd_model_ack_recv },
+#ifdef NAME_ADDR_BROADCASE_SUPPORT    
+    { BT_MESH_MODEL_OP_3(0xCE, CID_VENDOR), 0, vnd_model_indicate_recv },
+    { BT_MESH_MODEL_OP_3(0xCD, CID_VENDOR), 0, vnd_model_indicate_ack_recv },
+#endif    
+    BT_MESH_MODEL_OP_END,
+};
+
+const struct bt_mesh_model_cb vnd_model_cb = {
+    .init = vnd_model_init,
+    .deinit = vnd_model_deinit,
+};
+
+
+static void vnd_send_start_cback(u16_t duration, int err, void *cb_data)
+{
+    TLS_BT_APPL_TRACE_VERBOSE("vnd_send_start_cback\r\n");
+}
+static void vnd_send_end_cback(int err, void *cb_data)
+{
+    TLS_BT_APPL_TRACE_VERBOSE("vnd_send_end_cback\r\n");
+}
+
+static struct bt_mesh_send_cb vnd_send_cb = { 
+    .start = vnd_send_start_cback,
+    .end = vnd_send_end_cback,
+};
+
+#ifdef NAME_ADDR_BROADCASE_SUPPORT
+
+static void vnd_model_indicate_recv(struct bt_mesh_model *model,
+                          struct bt_mesh_msg_ctx *ctx,
+                          struct os_mbuf *buf)
+{
+  struct os_mbuf *msg = NULL;
+  const struct bt_mesh_prov * prov = bt_mesh_prov_get();
+  int payload_length = 0;
+  int rc; 
+
+  TLS_BT_APPL_TRACE_DEBUG("#vnd_model_indicate_recv, send_rel:%s, app_idx=%d\r\n", ctx->send_rel?"true":"false", ctx->app_idx);
+  TLS_BT_APPL_TRACE_DEBUG("data:%s len:%d\r\n", bt_hex(buf->om_data, buf->om_len),
+                          buf->om_len);
+
+  if(ctx->addr == bt_mesh_primary_addr())
+  {
+    TLS_BT_APPL_TRACE_DEBUG("#vnd_model_indicate_recv, local report, return \r\n");
+    return;
+  }
+  /**Send indicate ack*/
+  /**build indicate message*/
+  payload_length = 3 + 1 + 2 + 1 + strlen(prov->name);
+  msg = NET_BUF_SIMPLE(payload_length);
+  bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_3(0xCD, CID_VENDOR));
+  net_buf_simple_add_u8(msg, update_tid++);
+  net_buf_simple_add_be16(msg, bt_mesh_primary_addr());
+  net_buf_simple_add_u8(msg, (uint8_t)strlen(prov->name));
+  os_mbuf_append(msg, prov->name, (uint8_t)strlen(prov->name));
+  rc = bt_mesh_model_send(model, ctx, msg, &vnd_send_cb, NULL);
+  if(rc) {
+      TLS_BT_APPL_TRACE_ERROR("#vendor-model-send: send indicate ack, rc=%d\r\n", rc);
+  } 
+  
+  os_mbuf_free_chain(msg);
+
+}
+#endif
+
+#ifdef THROUGHTPUT_TEST
+
+static void ones_timer_cb(struct ble_npl_event *work)
+{
+    BT_DBG("");
+
+    if(1) {
+        if(g_send_bytes)TLS_BT_APPL_TRACE_DEBUG("Mesh Send(%04d bytes)[%5.2f Kbps]/s\r\n", g_send_bytes, (g_send_bytes * 8.0 / 1000));
+        if(g_recv_bytes)TLS_BT_APPL_TRACE_DEBUG("Mesh Recv(%04d bytes)[%5.2f Kbps]/s\r\n", g_recv_bytes, (g_recv_bytes * 8.0 / 1000));
+        g_send_bytes = 0;
+        g_recv_bytes = 0;
+    }
+    k_delayed_work_submit(&ones_timer, 1 * 1000);
+}
+#endif
+
+#ifdef NAME_ADDR_BROADCASE_SUPPORT 
+static void vnd_model_update_cb(struct ble_npl_event *work)
+{
+    const struct bt_mesh_prov * prov = bt_mesh_prov_get();
+    struct bt_mesh_model *model = ble_npl_event_get_arg(work);
+    struct os_mbuf *msg = NULL;
+    struct bt_mesh_msg_ctx ctx;
+    int payload_length = 0;
+    int rc;
+    
+    if(model->pub->addr == 0)
+    {
+
+        //TLS_BT_APPL_TRACE_ERROR("vnd_model_update_cb, pub_addr 0x%04x, retry\r\n", model->pub->addr, rc);
+        k_delayed_work_submit(&update_timer, 3 * 1000);
+        return;
+    }
+    /**build indicate message*/
+    payload_length = 3 + 1 + 2 + 1 + strlen(prov->name);
+    msg = NET_BUF_SIMPLE(payload_length);
+    bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_3(0xCE, CID_VENDOR));
+    net_buf_simple_add_u8(msg, update_tid++);
+    net_buf_simple_add_be16(msg, bt_mesh_primary_addr());
+    net_buf_simple_add_u8(msg, (uint8_t)strlen(prov->name));
+    os_mbuf_append(msg, prov->name, (uint8_t)strlen(prov->name));
+    
+    ctx.net_idx = 0;
+    ctx.addr = model->pub->addr;
+    ctx.app_idx = 0;
+    ctx.send_ttl = bt_mesh_default_ttl_get();
+    ctx.send_rel = false;
+
+    rc = bt_mesh_model_send(model, &ctx, msg, &vnd_send_cb, NULL);
+    
+    os_mbuf_free_chain(msg);
+
+    if(rc)
+    {
+        TLS_BT_APPL_TRACE_ERROR("#vendor-model-send: send rsp failed, rc=%d, retry\r\n", rc);
+        k_delayed_work_submit(&update_timer, 3 * 1000);
+    }else{
+        update_retry++;
+        if(update_retry < 3)
+        {
+            k_delayed_work_submit(&update_timer, 3 * 1000);
+        }
+    }
+    
+}
+#endif
+int vnd_model_send(uint16_t net_idx, uint16_t dst, uint16_t app_idx, uint8_t *payload, int length)
+{
+    int rc = -1;
+    
+    if(!g_vnd_model_ptr) return rc;
+    struct bt_mesh_msg_ctx ctx;
+    
+    struct os_mbuf *msg = NET_BUF_SIMPLE(3);
+    bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_3(0x01, CID_VENDOR));
+    os_mbuf_append(msg, payload, length);
+
+    ctx.net_idx = 0;
+    ctx.addr = dst;
+    ctx.app_idx = app_idx;
+    ctx.send_ttl = bt_mesh_default_ttl_get();
+    ctx.send_rel = false;
+
+    rc = bt_mesh_model_send(g_vnd_model_ptr, &ctx, msg, &vnd_send_cb, NULL);
+    if(rc) {
+        TLS_BT_APPL_TRACE_ERROR("#vendor-model-send: send rsp failed, rc=%d\r\n", rc);
+    }
+    
+    os_mbuf_free_chain(msg);
+
+#ifdef THROUGHTPUT_TEST
+    if(rc == 0)
+    {
+        g_send_bytes += length;
+    }
+    
+#endif
+
+    return rc;
+}
+
+#endif

+ 24 - 0
src/app/bleapp/wm_ble_mesh_vnd_model.h

@@ -0,0 +1,24 @@
+#ifndef __WM_BLE_MESH_VND_MODEL_H__
+#define __WM_BLE_MESH_VND_MODEL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct bt_mesh_model_pub vnd_model_pub;
+extern const struct bt_mesh_model_op vnd_model_op[];
+extern const struct bt_mesh_model_cb vnd_model_cb;
+
+
+#define BT_MESH_MODEL_WM_VND(vnd_data)  \
+    BT_MESH_MODEL_VND_CB(CID_VENDOR, BT_MESH_MODEL_ID_GEN_ONOFF_SRV, vnd_model_op, &vnd_model_pub,   \
+            vnd_data, &vnd_model_cb)
+
+
+extern int vnd_model_send(uint16_t net_idx, uint16_t dst, uint16_t app_idx, uint8_t *payload, int length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 562 - 238
src/app/bleapp/wm_ble_server_api_demo.c

@@ -10,35 +10,45 @@
 #include "wm_bt_app.h"
 #include "wm_bt_util.h"
 #include "host/ble_hs.h"
+#include "services/gap/ble_svc_gap.h"
 #include "wm_ble_gap.h"
 #include "wm_ble_uart_if.h"
 #include "wm_ble_server_api_demo.h"
+#include "wm_ble_client_util.h"
+
 
 /*
  * GLOBAL VARIABLE DEFINITIONS
  ****************************************************************************************
  */
 
-typedef enum{
+typedef enum {
     BLE_SERVER_MODE_IDLE     = 0x00,
     BLE_SERVER_MODE_ADVERTISING = 0x01,
     BLE_SERVER_MODE_CONNECTED,
     BLE_SERVER_MODE_INDICATING,
     BLE_SERVER_MODE_EXITING
 } ble_server_state_t;
-
-static uint8_t g_ble_demo_prof_connected = 0;
+    
+static struct ble_gap_event_listener ble_server_event_listener;
 static uint8_t g_ble_demo_indicate_enable = 0;
-static tls_ble_output_func_ptr g_ble_uart_output_fptr = NULL;
+static uint8_t g_ble_demo_notify_enable = 0;
+
 static int g_mtu = 20;
-static uint8_t g_ind_data[255];
+static uint8_t g_ind_data[MYNEWT_VAL(BLE_ATT_PREFERRED_MTU)];
 static volatile uint8_t g_send_pending = 0;
 static volatile ble_server_state_t g_ble_server_state = BLE_SERVER_MODE_IDLE;
+static tls_ble_uart_output_ptr g_uart_output_ptr = NULL; 
+static tls_ble_uart_sent_ptr g_uart_in_and_sent_ptr = NULL;
 
 
 /* ble attr write/notify handle */
 uint16_t g_ble_demo_attr_indicate_handle;
+uint16_t g_ble_demo_attr_notify_handle;
+
 uint16_t g_ble_demo_attr_write_handle;
+uint16_t g_ble_demo_attr_read_handle;
+
 uint16_t g_ble_demo_conn_handle ;
 
 
@@ -46,11 +56,15 @@ uint16_t g_ble_demo_conn_handle ;
 #define WM_GATT_SVC_UUID      0xFFF0
 #define WM_GATT_INDICATE_UUID 0xFFF1
 #define WM_GATT_WRITE_UUID    0xFFF2
+#define WM_GATT_READ_UUID     0xFFF3
+#define WM_GATT_NOTIFICATION_UUID 0xFFF4
+
+#define WM_INDICATE_AUTO 1
 
 
 static int
 gatt_svr_chr_demo_access_func(uint16_t conn_handle, uint16_t attr_handle,
-                               struct ble_gatt_access_ctxt *ctxt, void *arg);
+                              struct ble_gatt_access_ctxt *ctxt, void *arg);
 
 
 /*
@@ -58,30 +72,38 @@ gatt_svr_chr_demo_access_func(uint16_t conn_handle, uint16_t attr_handle,
  ****************************************************************************************
  */
 
-static int
-gatt_svr_chr_demo_write_func(uint16_t conn_handle, uint16_t attr_handle,
-                              struct ble_gatt_access_ctxt *ctxt, void *arg);
-
 
 static const struct ble_gatt_svc_def gatt_demo_svr_svcs[] = {
     {
         /* Service: uart */
         .type = BLE_GATT_SVC_TYPE_PRIMARY,
         .uuid = BLE_UUID16_DECLARE(WM_GATT_SVC_UUID),
-        .characteristics = (struct ble_gatt_chr_def[]) { {
+        .characteristics = (struct ble_gatt_chr_def[])
+        { {
                 .uuid = BLE_UUID16_DECLARE(WM_GATT_WRITE_UUID),
                 .val_handle = &g_ble_demo_attr_write_handle,
                 .access_cb = gatt_svr_chr_demo_access_func,
                 .flags = BLE_GATT_CHR_F_WRITE,
+            }, {
+                .uuid = BLE_UUID16_DECLARE(WM_GATT_READ_UUID),
+                .val_handle = &g_ble_demo_attr_read_handle,
+                .access_cb = gatt_svr_chr_demo_access_func,
+                .flags = BLE_GATT_CHR_F_READ,
             },{
                 .uuid = BLE_UUID16_DECLARE(WM_GATT_INDICATE_UUID),
                 .val_handle = &g_ble_demo_attr_indicate_handle,
                 .access_cb = gatt_svr_chr_demo_access_func,
                 .flags = BLE_GATT_CHR_F_INDICATE,
-            },{
-              0, /* No more characteristics in this service */
-            } 
-         },
+            },
+            {
+                .uuid = BLE_UUID16_DECLARE(WM_GATT_NOTIFICATION_UUID),
+                .val_handle = &g_ble_demo_attr_notify_handle,
+                .access_cb = gatt_svr_chr_demo_access_func,
+                .flags = BLE_GATT_CHR_F_NOTIFY,
+            }, {
+                0, /* No more characteristics in this service */
+            }
+        },
     },
 
     {
@@ -92,54 +114,48 @@ static const struct ble_gatt_svc_def gatt_demo_svr_svcs[] = {
 int wm_ble_server_api_demo_adv(bool enable)
 {
     int rc;
-    
-    if(enable)
-    {
+
+    if(enable) {
         struct ble_hs_adv_fields fields;
         const char *name;
-        
         /**
          *  Set the advertisement data included in our advertisements:
          *     o Flags (indicates advertisement type and other general info).
          *     o Device name.
          *     o user specific field (winner micro).
          */
-        
         memset(&fields, 0, sizeof fields);
-        
         /* Advertise two flags:
          *     o Discoverability in forthcoming advertisement (general)
          *     o BLE-only (BR/EDR unsupported).
          */
         fields.flags = BLE_HS_ADV_F_DISC_GEN |
                        BLE_HS_ADV_F_BREDR_UNSUP;
-        
-        
         name = ble_svc_gap_device_name();
         fields.name = (uint8_t *)name;
         fields.name_len = strlen(name);
         fields.name_is_complete = 1;
-        
-        fields.uuids16 = (ble_uuid16_t[]){
-            BLE_UUID16_INIT(0xFFF0)
+        fields.uuids16 = (ble_uuid16_t[]) {
+            BLE_UUID16_INIT(WM_GATT_SVC_UUID)
         };
         fields.num_uuids16 = 1;
         fields.uuids16_is_complete = 1;
-
-        
         rc = ble_gap_adv_set_fields(&fields);
-        if (rc != 0) {
+
+        if(rc != 0) {
             TLS_BT_APPL_TRACE_ERROR("error setting advertisement data; rc=%d\r\n", rc);
             return rc;
         }
-        
+
         /* As own address type we use hard-coded value, because we generate
               NRPA and by definition it's random */
         rc = tls_nimble_gap_adv(WM_BLE_ADV_IND, 0);
-        assert(rc == 0);
 
-    }else
-    {
+        if(rc != 0) {
+            TLS_BT_APPL_TRACE_ERROR("tls_nimble_gap_adv; rc=%d\r\n", rc);
+            return rc;
+        }
+    } else {
         rc = tls_nimble_gap_adv(WM_BLE_ADV_STOP, 0);
     }
 
@@ -150,27 +166,52 @@ int wm_ble_server_api_demo_adv(bool enable)
  ****************************************************************************************
  */
 
+static uint8_t gatt_svc_test_read_value[200] = {0x01, 0x02, 0x03};
+
+static void tls_print_bytes(const char *desc, uint8_t *ptr, uint16_t len)
+{
+    int i = 0, j = 0;
+    printf("%s:", desc);
+    for(i = 0; i<len; i++)
+    {
+        printf("%02x", ptr[i]);
+        j++;
+
+        if(j == 16){
+            j = 0;
+            printf("\r\n");
+        }
+    }
+    printf("\r\n");
+}
+
 static int
 gatt_svr_chr_demo_access_func(uint16_t conn_handle, uint16_t attr_handle,
-                               struct ble_gatt_access_ctxt *ctxt, void *arg)
+                              struct ble_gatt_access_ctxt *ctxt, void *arg)
 {
-    int i = 0;
+    int rc;
     struct os_mbuf *om = ctxt->om;
-    
-    switch (ctxt->op) {
+
+    switch(ctxt->op) {
         case BLE_GATT_ACCESS_OP_WRITE_CHR:
-              while(om) {
-                  if(g_ble_uart_output_fptr)
-                  {
-                    g_ble_uart_output_fptr((uint8_t *)om->om_data, om->om_len);
-                    
-                  }else
-                  {
-                     print_bytes(om->om_data, om->om_len); 
-                  }
-                  om = SLIST_NEXT(om, om_next);
-              }
-              return 0;
+            while(om) {
+                if(g_uart_output_ptr) {
+                    TLS_BT_APPL_TRACE_VERBOSE("### %s len=%d\r\n", __FUNCTION__, om->om_len);
+                    g_uart_output_ptr(UART_OUTPUT_DATA, (uint8_t *)om->om_data, om->om_len);
+                } else {
+                    tls_print_bytes("op write", om->om_data, om->om_len);
+                }
+
+                om = SLIST_NEXT(om, om_next);
+            }
+
+            return 0;
+        case BLE_GATT_ACCESS_OP_READ_CHR:
+            rc = os_mbuf_append(ctxt->om, &gatt_svc_test_read_value,
+                                sizeof gatt_svc_test_read_value);
+            gatt_svc_test_read_value[0]++;
+            return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
+
         default:
             assert(0);
             return BLE_ATT_ERR_UNLIKELY;
@@ -181,14 +222,15 @@ int
 wm_ble_server_demo_gatt_svr_init(void)
 {
     int rc;
-
     rc = ble_gatts_count_cfg(gatt_demo_svr_svcs);
-    if (rc != 0) {
+
+    if(rc != 0) {
         goto err;
     }
 
     rc = ble_gatts_add_svcs(gatt_demo_svr_svcs);
-    if (rc != 0) {
+
+    if(rc != 0) {
         return rc;
     }
 
@@ -198,202 +240,314 @@ err:
 
 
 static uint8_t ss = 0x00;
+//#define THROUGHTPUT_TEST
 
-static void ble_server_indication_sent_cb(int conn_id, int status)
+#ifdef THROUGHTPUT_TEST
+
+static uint32_t g_send_bytes = 0;
+static uint32_t g_time_last = 0;
+
+static uint32_t ticks_elapsed(uint32_t ticks)
 {
-	int len = 0;
-    tls_bt_status_t ret;
+    uint32_t diff_ticks = 0;
+    uint32_t curr_ticks = tls_os_get_time();
+
+    if(curr_ticks >= ticks) {
+        diff_ticks = curr_ticks - ticks;
+    } else {
+        diff_ticks = curr_ticks + (0xFFFFFFFF - ticks);
+    }
+
+    return diff_ticks;
+}
+#endif
 
+static void ble_server_indication_sent_cb(int conn_id, int status)
+{
+#if WM_INDICATE_AUTO
+    int rc;
+#endif
     g_send_pending = 0;
-    if(!g_ble_demo_indicate_enable)
-    {
+
+    if(!g_ble_demo_indicate_enable) {
         TLS_BT_APPL_TRACE_DEBUG("Indicate disabled... when trying to send...\r\n");
         return;
     }
 
-    if(g_ble_uart_output_fptr == NULL)
-    {
+#if WM_INDICATE_AUTO
+
+    if(g_uart_output_ptr == NULL) {
         memset(g_ind_data, ss, sizeof(g_ind_data));
         ss++;
-        if(ss > 0xFE) ss = 0x00;
-    	tls_ble_server_demo_api_send_msg(g_ind_data, g_mtu); 
 
-    }else
-    {
-        len = tls_ble_uart_buffer_size();
-        len = MIN(len, g_mtu);
+        if(ss > 0xFE) { ss = 0x00; }
 
-        if(len)
+        rc = tls_ble_server_demo_api_send_msg(g_ind_data, g_mtu);
+		(void)rc;
+#ifdef THROUGHTPUT_TEST
+        if(rc == 0)
         {
-            tls_ble_uart_buffer_peek(g_ind_data, len);
-            ret = tls_ble_server_demo_api_send_msg(g_ind_data, len); 
-            if(ret == TLS_BT_STATUS_SUCCESS)
-            {
-                tls_ble_uart_buffer_delete(len);
-                g_send_pending = 1;
-            }else
-            {
-               TLS_BT_APPL_TRACE_DEBUG("server send via ble failed(%d), retry...\r\n", ret); 
-            }
+            g_send_bytes += g_mtu;
+        }else
+        {
+            printf("indicate failed rc=%d\r\n", rc);
         }
+
+        if(ticks_elapsed(g_time_last) >= HZ) {
+            g_time_last = tls_os_get_time();
+            printf("BLE Send(%d bytes)[%5.2f Kbps][mtu%d]/s\r\n", g_send_bytes, (g_send_bytes * 8.0 / 1024),g_mtu);
+            g_send_bytes = 0;
+        }
+
+#endif
+    } else {
+        if(g_uart_in_and_sent_ptr) g_uart_in_and_sent_ptr(BLE_UART_SERVER_MODE, status);
     }
+#endif
+
 }
 
 static void wm_ble_server_demo_start_indicate(void *arg)
 {
-    int len;
     int rc;
-    uint8_t *tmp_ptr = NULL;
-    tls_bt_status_t status;
-    
+
     /*No uart ble interface*/
-    if(g_ble_uart_output_fptr == NULL)
-    {
-	    rc = tls_ble_server_demo_api_send_msg(g_ind_data, g_mtu);
+    if(g_uart_in_and_sent_ptr == NULL) {
+        rc = tls_ble_server_demo_api_send_msg(g_ind_data, g_mtu);
         TLS_BT_APPL_TRACE_DEBUG("Indicating sending...rc=%d\r\n", rc);
-    }else
-    {
-        /*check and send*/
-        len = tls_ble_uart_buffer_size();
-        len = MIN(len, g_mtu);
+#ifdef THROUGHTPUT_TEST
+        g_time_last = tls_os_get_time();
+#endif
+    } else {
+        g_uart_in_and_sent_ptr(BLE_UART_SERVER_MODE, 0);
 
-        if(len)
-        {
-            tls_ble_uart_buffer_peek(g_ind_data, len);
-            status = tls_ble_server_demo_api_send_msg(g_ind_data, g_mtu);
-            if(status == TLS_BT_STATUS_SUCCESS)
-            {
-                tls_ble_uart_buffer_delete(len);
-            }else
-            {
-               TLS_BT_APPL_TRACE_DEBUG("Server send failed(%d), retry...\r\n", status); 
-               tls_bt_async_proc_func(wm_ble_server_demo_start_indicate,(void*)g_ble_demo_indicate_enable,1000);
-            }
-        }
-    }    
+    }
 }
 static void conn_param_update_cb(uint16_t conn_handle, int status, void *arg)
 {
-	TLS_BT_APPL_TRACE_DEBUG("conn param update complete; conn_handle=%d status=%d\n",
-		       conn_handle, status);
+    TLS_BT_APPL_TRACE_DEBUG("conn param update complete; conn_handle=%d status=%d\n",
+                            conn_handle, status);
+    if(status!=0)
+    {
+        
+    }
 }
 
 static void wm_ble_server_demo_conn_param_update_slave()
 {
-	int rc;
-	struct ble_l2cap_sig_update_params params;
+    int rc;
+    struct ble_l2cap_sig_update_params params;
+    params.itvl_min = 0x00016;
+    params.itvl_max = 0x00026;
+    params.slave_latency = 0;
+    params.timeout_multiplier = 500;
+    rc = ble_l2cap_sig_update(g_ble_demo_conn_handle, &params,
+                              conn_param_update_cb, NULL);
+    if(rc != 0)
+    {
+        TLS_BT_APPL_TRACE_ERROR("ERROR, ble_l2cap_sig_update rc=%d\r\n", rc);
+    }
+}
+#if 0
+static int
+wm_ble_server_demo_on_mtu(uint16_t conn_handle, const struct ble_gatt_error *error,
+                          uint16_t mtu, void *arg)
+{
+    switch(error->status) {
+        case 0:
+            TLS_BT_APPL_TRACE_DEBUG("mtu exchange complete: conn_handle=%d mtu=%d\r\n",
+                                    conn_handle, mtu);
+            g_mtu = mtu-3;
+            break;
 
-	params.itvl_min = 0x0006;
-	params.itvl_max = 0x0006;
-	params.slave_latency = 0;
-	params.timeout_multiplier = 0x07d0;
+        default:
+            TLS_BT_APPL_TRACE_DEBUG("Update MTU failed...error->status=%d\r\n", error->status);
+            break;
+    }
 
-	rc = ble_l2cap_sig_update(g_ble_demo_conn_handle, &params,
-		conn_param_update_cb, NULL);
-	assert(rc == 0);
+    return 0;
 }
-
+#endif                          
 static int ble_gap_evt_cb(struct ble_gap_event *event, void *arg)
 {
     int rc;
     struct ble_gap_conn_desc desc;
-    
-    switch(event->type)
-    {
+
+    switch(event->type) {
         case BLE_GAP_EVENT_CONNECT:
-            g_ble_demo_prof_connected = 1;
-            g_send_pending = 0;
             
-            TLS_BT_APPL_TRACE_DEBUG("connected status=%d handle=%d,g_ble_demo_attr_indicate_handle=%d\r\n",event->connect.status, g_ble_demo_conn_handle, g_ble_demo_attr_indicate_handle );
-            if (event->connect.status == 0) {
-                g_ble_server_state = BLE_SERVER_MODE_CONNECTED;
-                       //re set this flag, to prevent stop adv, but connected evt reported when deinit this demo
-                g_ble_demo_conn_handle = event->connect.conn_handle;
+            if(event->connect.status == 0) {
+
                 rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
                 assert(rc == 0);
+                if(desc.role != BLE_GAP_ROLE_SLAVE){
+                    return 0;
+                }
+                TLS_BT_APPL_TRACE_DEBUG("Server connected status=%d handle=%d,g_ble_demo_attr_indicate_handle=%d\r\n",
+                                    event->connect.status, g_ble_demo_conn_handle, g_ble_demo_attr_indicate_handle);                
                 print_conn_desc(&desc);
-
+                g_ble_server_state = BLE_SERVER_MODE_CONNECTED;
+                //re set this flag, to prevent stop adv, but connected evt reported when deinit this demo
+                g_ble_demo_conn_handle = event->connect.conn_handle;
+                if(g_uart_output_ptr)
+                {
+                    g_uart_output_ptr(UART_OUTPUT_CMD_CONNECTED, NULL, 0);
+                }
+                
 #if MYNEWT_VAL(BLEPRPH_LE_PHY_SUPPORT)
                 phy_conn_changed(event->connect.conn_handle);
 #endif
+#ifdef THROUGHTPUT_TEST
+                g_send_bytes = 0;
+                g_time_last = tls_os_get_time();
+#endif
+                tls_bt_async_proc_func(wm_ble_server_demo_conn_param_update_slave, NULL, 100);
+                g_send_pending = 0;
+
             }
+
             TLS_BT_APPL_TRACE_DEBUG("\r\n");
 
-            if (event->connect.status != 0) {
+            if(event->connect.status != 0) {
                 /* Connection failed; resume advertising. */
                 tls_nimble_gap_adv(WM_BLE_ADV_IND, 0);
             }
+
             break;
+
         case BLE_GAP_EVENT_DISCONNECT:
-            g_ble_demo_prof_connected = 0;
+
+            if(event->disconnect.conn.role != BLE_GAP_ROLE_SLAVE) return 0;
+
+            TLS_BT_APPL_TRACE_DEBUG("Server disconnect reason=%d[0x%02x],state=%d\r\n", event->disconnect.reason,event->disconnect.reason-0x200,
+                                    g_ble_server_state);
             g_ble_demo_indicate_enable = 0;
             g_send_pending = 0;
-            TLS_BT_APPL_TRACE_DEBUG("disconnect reason=%d,state=%d\r\n", event->disconnect.reason,g_ble_server_state);
-            if(g_ble_server_state == BLE_SERVER_MODE_EXITING)
+            g_mtu = 20;
+            uint8_t err_code[1];
+            if(g_uart_output_ptr)
             {
-                if(g_ble_uart_output_fptr)
-                {
-                    g_ble_uart_output_fptr = NULL;
+                err_code[0] = event->disconnect.reason - 0x200;
+                g_uart_output_ptr(UART_OUTPUT_CMD_DISCONNECTED, (uint8_t*)&err_code, 0);
+            }
+
+            if(g_ble_server_state == BLE_SERVER_MODE_EXITING) {
+                if(g_uart_output_ptr) {
+                    g_uart_output_ptr = NULL;
                 }
-                
+                if(g_uart_in_and_sent_ptr) {
+                    g_uart_in_and_sent_ptr = NULL;
+                }
+
                 g_ble_server_state = BLE_SERVER_MODE_IDLE;
-            }else
-            {
-                rc = tls_nimble_gap_adv(WM_BLE_ADV_IND, 0);
-                if(!rc)
+                ble_gap_event_listener_unregister(&ble_server_event_listener);
+            } else {
+
+                /**if connction is not closed by local host*/
+                /**Any reason, we will continue to do advertise*/
+                // 1, indicate timeout, host will terminate the connection, disconnect reason 0x16
+                // 2, host stack close, negative effection, no!
+                if(event->disconnect.reason != 534)
+                {
+                    rc = tls_nimble_gap_adv(WM_BLE_ADV_IND, 0);
+                    TLS_BT_APPL_TRACE_DEBUG("Disconnect evt, and continue to do adv, rc=%d\r\n", rc);
+
+                    if(!rc) {
+                        g_ble_server_state = BLE_SERVER_MODE_ADVERTISING;
+                    } else {
+                        g_ble_server_state = BLE_SERVER_MODE_IDLE;
+                    }
+                }else
                 {
-                  g_ble_server_state = BLE_SERVER_MODE_ADVERTISING;  
+                    g_ble_server_state = BLE_SERVER_MODE_IDLE;
                 }
             }
-            #if 0
-            if(event->disconnect.reason == 534)
-            {
-                //hci error code:  0x16 + 0x200 = 534; //local host terminate the connection;
-            }else
-            {
-                tls_nimble_gap_adv(WM_BLE_ADV_IND, 0);
-            }
-            #endif
-            
+
             break;
+
         case BLE_GAP_EVENT_NOTIFY_TX:
-            if(event->notify_tx.status == BLE_HS_EDONE)
+
+            rc = ble_gap_conn_find(event->notify_tx.conn_handle , &desc);
+            assert(rc == 0);
+            if(desc.role != BLE_GAP_ROLE_SLAVE) return 0;
+            if(event->notify_tx.attr_handle == g_ble_demo_attr_indicate_handle)
             {
+            if(event->notify_tx.status == BLE_HS_EDONE) {
                 ble_server_indication_sent_cb(event->notify_tx.attr_handle, event->notify_tx.status);
-            }else
-            {
+            } else {
                 /*Application will handle other cases*/
             }
+            }else if(event->notify_tx.attr_handle == g_ble_demo_attr_notify_handle)
+            {
+                g_send_pending = 0;
+            }
+
             break;
+
         case BLE_GAP_EVENT_SUBSCRIBE:
-            TLS_BT_APPL_TRACE_DEBUG("subscribe indicate(%d,%d)\r\n", event->subscribe.prev_indicate,event->subscribe.cur_indicate );
-            g_ble_demo_indicate_enable = event->subscribe.cur_indicate;
-            if(g_ble_demo_indicate_enable)
+            rc = ble_gap_conn_find(event->subscribe.conn_handle , &desc);
+            assert(rc == 0);
+            if(desc.role != BLE_GAP_ROLE_SLAVE) return 0;
+            
+            TLS_BT_APPL_TRACE_DEBUG("subscribe [%d]indicate(%d,%d)\r\n",event->subscribe.attr_handle,  event->subscribe.prev_indicate,
+                                    event->subscribe.cur_indicate);
+
+            if(event->subscribe.attr_handle == g_ble_demo_attr_indicate_handle)
             {
+            g_ble_demo_indicate_enable = event->subscribe.cur_indicate;
+
+            if(g_ble_demo_indicate_enable) {
                 g_ble_server_state = BLE_SERVER_MODE_INDICATING;
+
                 /*To reach the max passthrough,  in ble_uart mode, I conifg the min connection_interval*/
-                if(g_ble_uart_output_fptr)
-                {
+                if(g_uart_in_and_sent_ptr) {
+                    tls_bt_async_proc_func(wm_ble_server_demo_conn_param_update_slave, NULL, 30);
+                } else {
+#ifdef THROUGHTPUT_TEST
                     tls_bt_async_proc_func(wm_ble_server_demo_conn_param_update_slave, NULL, 30);
+#endif
                 }
-                tls_bt_async_proc_func(wm_ble_server_demo_start_indicate,(void*)g_ble_demo_indicate_enable, 30);
-            }else
-            {
-                if(g_ble_server_state != BLE_SERVER_MODE_EXITING)
+#if WM_INDICATE_AUTO
+                if(g_uart_output_ptr == NULL)
                 {
+                    tls_bt_async_proc_func(wm_ble_server_demo_start_indicate, NULL, 30);
+                }
+#endif
+                } else if(g_ble_demo_indicate_enable == 0){
+                if(g_ble_server_state != BLE_SERVER_MODE_EXITING) {
                     g_ble_server_state = BLE_SERVER_MODE_CONNECTED;
                 }
             }
+           }else
+           {
+                g_ble_demo_notify_enable = event->subscribe.cur_notify;
+                if(g_ble_demo_notify_enable)
+                {
+#ifdef THROUGHTPUT_TEST
+                    tls_bt_async_proc_func(wm_ble_server_demo_conn_param_update_slave, NULL, 30);
+#endif
+                }else
+                {
+                    ;
+                }
+           }
+
             break;
+
         case BLE_GAP_EVENT_MTU:
+            rc = ble_gap_conn_find(event->mtu.conn_handle , &desc);
+            assert(rc == 0);
+            if(desc.role != BLE_GAP_ROLE_SLAVE) return 0;
+
             TLS_BT_APPL_TRACE_DEBUG("wm ble dm mtu changed to(%d)\r\n", event->mtu.value);
             /*nimBLE config prefered ATT_MTU is 256. here 256-12 = 244. */
             /* preamble(1)+access address(4)+pdu(2~257)+crc*/
             /* ATT_MTU(247):pdu= pdu_header(2)+l2cap_len(2)+l2cap_chn(2)+mic(4)*/
             /* GATT MTU(244): ATT_MTU +opcode+chn*/
-            g_mtu = min(event->mtu.value - 12, 244);
-            
+            //g_mtu = min(event->mtu.value - 12, 244);
+            g_mtu = event->mtu.value-3;
             break;
+
         case BLE_GAP_EVENT_REPEAT_PAIRING:
             /* We already have a bond with the peer, but it is attempting to
              * establish a new secure link.  This app sacrifices security for
@@ -402,48 +556,70 @@ static int ble_gap_evt_cb(struct ble_gap_event *event, void *arg)
             /* Delete the old bond. */
             rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
             assert(rc == 0);
+            if(desc.role != BLE_GAP_ROLE_SLAVE) return 0;            
             ble_store_util_delete_peer(&desc.peer_id_addr);
-            
             TLS_BT_APPL_TRACE_DEBUG("!!!BLE_GAP_EVENT_REPEAT_PAIRING\r\n");
             return BLE_GAP_REPEAT_PAIRING_RETRY;
-        
+
         case BLE_GAP_EVENT_PASSKEY_ACTION:
             TLS_BT_APPL_TRACE_DEBUG(">>>BLE_GAP_EVENT_REPEAT_PAIRING\r\n");
             return 0;
-
-            
+        case BLE_GAP_EVENT_L2CAP_UPDATE_REQ:
+        case BLE_GAP_EVENT_CONN_UPDATE_REQ:
+            TLS_BT_APPL_TRACE_DEBUG("Server conn handle=%d,peer:[min=%d,max=%d,sup=%d],local[min=%d,max=%d,sup=%d]", event->conn_update_req.conn_handle, 
+                event->conn_update_req.peer_params->itvl_min, event->conn_update_req.peer_params->itvl_max,event->conn_update_req.peer_params->supervision_timeout,
+                event->conn_update_req.self_params->itvl_min, event->conn_update_req.self_params->itvl_max,event->conn_update_req.self_params->supervision_timeout);
+            break;
+        case BLE_GAP_EVENT_CONN_UPDATE:
+            if(event->conn_update.status == 0)
+            {
+                rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc);
+                assert(rc == 0);
+                TLS_BT_APPL_TRACE_DEBUG("Server con_handle=%d,conn update, interval=%d, supervision=%d\r\n", event->conn_update.conn_handle, desc.conn_itvl, desc.supervision_timeout);
+            }
+            break;
+        case BLE_GAP_EVENT_HOST_SHUTDOWN:
+            TLS_BT_APPL_TRACE_DEBUG("Server BLE_GAP_EVENT_HOST_SHUTDOWN:%d\r\n", event->type);
+            g_ble_server_state = BLE_SERVER_MODE_IDLE;
+            g_ble_demo_indicate_enable = 0;
+            g_ble_demo_notify_enable = 0;
+            g_send_pending = 0;
+            g_mtu = 20;
+            if(g_uart_output_ptr) {
+                g_uart_output_ptr = NULL;
+            }
+            if(g_uart_in_and_sent_ptr) {
+                g_uart_in_and_sent_ptr = NULL;
+            }              
+            break;
         default:
+            TLS_BT_APPL_TRACE_VERBOSE("Server Unhandled event:%d\r\n", event->type);
+  
             break;
     }
 
     return 0;
 }
 
+
 /*
  * EXPORTED FUNCTION DEFINITIONS
  ****************************************************************************************
  */
 
-int tls_ble_server_demo_api_init(tls_ble_output_func_ptr output_func_ptr)
+int tls_ble_server_demo_api_init(tls_ble_uart_output_ptr uart_output_ptr, tls_ble_uart_sent_ptr uart_in_and_sent_ptr)
 {
     int rc = BLE_HS_EAPP;
 
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
-        TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
-        return BLE_HS_EDISABLED;
-    }
-    
+    CHECK_SYSTEM_READY();
+
     TLS_BT_APPL_TRACE_DEBUG("%s, state=%d\r\n", __FUNCTION__, g_ble_server_state);
-    
-    if(g_ble_server_state == BLE_SERVER_MODE_IDLE)
-    {
-        g_ble_demo_prof_connected = 0;
-        
-        //step 0: reset other services. Note 
+
+    if(g_ble_server_state == BLE_SERVER_MODE_IDLE) {
+        //step 0: reset other services. Note
         rc = ble_gatts_reset();
-        if(rc != 0)
-        {
+
+        if(rc != 0) {
             TLS_BT_APPL_TRACE_ERROR("tls_ble_server_demo_api_init failed rc=%d\r\n", rc);
             return rc;
         }
@@ -451,107 +627,255 @@ int tls_ble_server_demo_api_init(tls_ble_output_func_ptr output_func_ptr)
         //step 1: config/adding  the services
         rc = wm_ble_server_demo_gatt_svr_init();
 
-		if(rc == 0)
-		{	
-		    tls_ble_register_gap_evt(WM_BLE_GAP_EVENT_CONNECT|WM_BLE_GAP_EVENT_DISCONNECT|WM_BLE_GAP_EVENT_NOTIFY_TX|WM_BLE_GAP_EVENT_SUBSCRIBE|WM_BLE_GAP_EVENT_MTU|WM_BLE_GAP_EVENT_REPEAT_PAIRING, ble_gap_evt_cb);
-			TLS_BT_APPL_TRACE_DEBUG("### wm_ble_server_api_demo_init \r\n");
-            
-            g_ble_uart_output_fptr = output_func_ptr;
+        if(rc == 0) {
+            ble_gap_event_listener_register(&ble_server_event_listener,
+                                            ble_gap_evt_cb, NULL);
+
+            TLS_BT_APPL_TRACE_DEBUG("tls_ble_server_demo_api_init register success\r\n");
+            g_uart_output_ptr = uart_output_ptr;
+            g_uart_in_and_sent_ptr = uart_in_and_sent_ptr;
             /*step 2: start the service*/
             rc = ble_gatts_start();
             assert(rc == 0);
-            
             /*step 3: start advertisement*/
-            rc = wm_ble_server_api_demo_adv(true); 
-            
-            if(rc == 0)
-            {
+            rc = wm_ble_server_api_demo_adv(true);
+
+            if(rc == 0) {
                 g_ble_server_state = BLE_SERVER_MODE_ADVERTISING;
+                if(g_uart_output_ptr)
+                {
+                    g_uart_output_ptr(UART_OUTPUT_CMD_ADVERTISING, NULL, 0);
+                }
             }
-		}else
-		{
-			TLS_BT_APPL_TRACE_ERROR("### wm_ble_server_api_demo_init failed(rc=%d)\r\n", rc);
-		}
-    }
-    else
-    {
-    	TLS_BT_APPL_TRACE_WARNING("wm_ble_server_api_demo_init registered\r\n");
+        } else {
+            TLS_BT_APPL_TRACE_ERROR("tls_ble_server_demo_api_init failed(rc=%d)\r\n", rc);
+        }
+    } else {
+        TLS_BT_APPL_TRACE_WARNING("tls_ble_server_demo_api_init registered\r\n");
         rc = BLE_HS_EALREADY;
     }
-	
-	return rc;
+
+    return rc;
 }
 int tls_ble_server_demo_api_deinit()
 {
-   int rc = BLE_HS_EAPP;
+    int rc = BLE_HS_EAPP;
 
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
-        TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
-        return BLE_HS_EDISABLED;
-    }
+    CHECK_SYSTEM_READY();
 
-   TLS_BT_APPL_TRACE_DEBUG("%s, state=%d\r\n", __FUNCTION__, g_ble_server_state);
-   
-   if(g_ble_server_state == BLE_SERVER_MODE_CONNECTED || g_ble_server_state == BLE_SERVER_MODE_INDICATING)
-   {
+    TLS_BT_APPL_TRACE_DEBUG("%s, state=%d\r\n", __FUNCTION__, g_ble_server_state);
+
+    if(g_ble_server_state == BLE_SERVER_MODE_CONNECTED
+            || g_ble_server_state == BLE_SERVER_MODE_INDICATING) {
         g_ble_demo_indicate_enable = 0;
-        
         rc = ble_gap_terminate(g_ble_demo_conn_handle, BLE_ERR_REM_USER_CONN_TERM);
-        if(rc == 0)
-        {
-           g_ble_server_state = BLE_SERVER_MODE_EXITING; 
+
+        if(rc == 0) {
+            g_ble_server_state = BLE_SERVER_MODE_EXITING;
+        } else if(rc == BLE_HS_EDISABLED || rc == BLE_HS_ENOTCONN) {
+            g_send_pending = 0;
+            g_ble_server_state = BLE_SERVER_MODE_IDLE;
+            ble_gap_event_listener_unregister(&ble_server_event_listener);
+        }else{
+            /**Force to clear state if unknown error happen*/
+            if(g_uart_output_ptr) {
+                g_uart_output_ptr = NULL;
+            }
+            if(g_uart_in_and_sent_ptr) {
+                g_uart_in_and_sent_ptr = NULL;
+            }
+
+            g_send_pending = 0;
+            g_ble_server_state = BLE_SERVER_MODE_IDLE;  
+            ble_gap_event_listener_unregister(&ble_server_event_listener);
         }
-   }else if(g_ble_server_state == BLE_SERVER_MODE_ADVERTISING)
-   {
+    } else if(g_ble_server_state == BLE_SERVER_MODE_ADVERTISING) {
         rc = tls_nimble_gap_adv(WM_BLE_ADV_STOP, 0);
-        if(rc == 0)
-        {
-            if(g_ble_uart_output_fptr)
-            {
-                g_ble_uart_output_fptr = NULL;
+
+        if(rc == 0 || rc == BLE_HS_EDISABLED || rc == BLE_HS_EALREADY) {
+            if(g_uart_output_ptr) {
+                g_uart_output_ptr = NULL;
+            }
+            if(g_uart_in_and_sent_ptr) {
+                g_uart_in_and_sent_ptr = NULL;
             }
+
             g_send_pending = 0;
             g_ble_server_state = BLE_SERVER_MODE_IDLE;
+            ble_gap_event_listener_unregister(&ble_server_event_listener);
         }
-   }else if(g_ble_server_state == BLE_SERVER_MODE_IDLE)
-   {
+    } else if(g_ble_server_state == BLE_SERVER_MODE_IDLE) {
         rc = 0;
-   }else
-   {
+    } else {
         rc = BLE_HS_EALREADY;
-   }
+    }
 
-   return rc;
+    return rc;
 }
 uint32_t tls_ble_server_demo_api_get_mtu()
 {
     return g_mtu;
 }
-int tls_ble_server_demo_api_send_msg(uint8_t *data, int data_len)
+
+int tls_ble_server_demo_api_send_msg_indicate()
 {
     int rc;
     struct os_mbuf *om;
     
-    //TLS_BT_APPL_TRACE_DEBUG("### %s len=%d\r\n", __FUNCTION__, data_len);
+    CHECK_SYSTEM_READY();
+
+    TLS_BT_APPL_TRACE_VERBOSE("### %s len=%d\r\n", __FUNCTION__, 4000);
+    
+
+    if(g_send_pending) { return BLE_HS_EBUSY; }
+
+    memset(g_ind_data, ss, sizeof(g_ind_data));
+    ss++;
+    
+    if(ss > 0xFE) { ss = 0x00; }
+
+
+    om = ble_hs_mbuf_from_flat(g_ind_data, 4000);
+
+    if(!om) {
+        return BLE_HS_ENOMEM;
+    }
 
-    if(g_send_pending) return BLE_HS_EBUSY;
+    rc = ble_gattc_indicate_custom(g_ble_demo_conn_handle, g_ble_demo_attr_indicate_handle, om);
 
-    if(data_len<=0 || data == NULL)
+    if(rc == 0) {
+        g_send_pending = 1;
+        
+    }else
     {
-        return BLE_HS_EINVAL;
+        printf("!!! tls_ble_server_demo_api_send_msg , rc=%d\r\n", rc);
     }
+
+    return rc;
+
+    
+    return 0;
+}
+int tls_ble_server_demo_api_send_msg(uint8_t *data, int data_len)
+{
+    int rc;
+    struct os_mbuf *om;
+    
+    CHECK_SYSTEM_READY();
+
+    TLS_BT_APPL_TRACE_VERBOSE("### %s len=%d\r\n", __FUNCTION__, data_len);
+    
+
+    if(g_send_pending) { return BLE_HS_EBUSY; }
+    if(g_ble_demo_indicate_enable == 0) { return BLE_HS_EDISABLED; }
     
+    if(data_len <= 0 || data == NULL) {
+        return BLE_HS_EINVAL;
+    }
+
     om = ble_hs_mbuf_from_flat(data, data_len);
-    if (!om) {
+
+    if(!om) {
+        return BLE_HS_ENOMEM;
+    }
+
+    rc = ble_gattc_indicate_custom(g_ble_demo_conn_handle, g_ble_demo_attr_indicate_handle, om);
+
+    if(rc == 0) {
+        g_send_pending = 1;
+    }else
+    {
+        TLS_BT_APPL_TRACE_ERROR("!!! tls_ble_server_demo_api_send_msg , rc=%d\r\n", rc)
+    }
+
+    return rc;
+}
+
+int tls_ble_server_demo_api_send_msg_notify(uint8_t *ptr, int length)
+{
+    int rc;
+    struct os_mbuf *om;
+    
+    CHECK_SYSTEM_READY();
+
+    TLS_BT_APPL_TRACE_VERBOSE("### %s len=%d\r\n", __FUNCTION__, g_mtu);
+    
+    if(g_ble_demo_notify_enable == 0) return BLE_HS_EAGAIN;
+    
+    if(g_send_pending) { return BLE_HS_EBUSY; }
+
+
+    om = ble_hs_mbuf_from_flat(ptr, length);
+
+    if(!om) {
         return BLE_HS_ENOMEM;
     }
+    g_send_pending = 1;
+
+    rc = ble_gattc_notify_custom(g_ble_demo_conn_handle, g_ble_demo_attr_notify_handle, om);
+
+    if(rc == 0) {
+#ifdef THROUGHTPUT_TEST
+
+        g_send_bytes += g_mtu;
+
+    if(ticks_elapsed(g_time_last) >= HZ) {
+        g_time_last = tls_os_get_time();
+        printf("BLE Send(%d bytes)[%5.2f Kbps][mtu%d]/s\r\n", g_send_bytes, (g_send_bytes * 8.0 / 1024),length);
+        g_send_bytes = 0;
+    }    
+#endif
+    
+    }else
+    {
+        TLS_BT_APPL_TRACE_DEBUG("!!! tls_ble_server_demo_api_send_msg_notify , rc=%d, err data[%02x%02x]\r\n", rc, g_ind_data[0], g_ind_data[1])
+        g_send_pending = 0;    
+    }
+
+    return rc;
+}
+
+int tls_ble_server_demo_api_set_work_mode(int work_mode)
+{
+    int rc;
+    int intv_min = 0x06;
+    int intv_max = 0x06;
+    struct ble_l2cap_sig_update_params params;
     
-    rc = ble_gattc_indicate_custom(g_ble_demo_conn_handle,g_ble_demo_attr_indicate_handle, om); 
-    if(rc == 0)
+#define PIC_TRANSFERING 1
+#define CONNECTING_KEEP 0
+#define CONNECTING_KEEP_AND_LOW_POWER 2
+
+    switch(work_mode)
     {
-        g_send_pending = 1;
+        case 0: 
+            intv_min = 100;
+            intv_max = 120;
+            break;
+        case 1:
+            intv_min = 6;
+            intv_max = 6;
+            break;      
+        case 2:
+            intv_min = 200;
+            intv_max = 240; 
+            break;
+        default:
+            TLS_BT_APPL_TRACE_DEBUG("Unspported work mode %d\r\n", work_mode);
+            return -1;
     }
+    
+    params.itvl_min = intv_min;
+    params.itvl_max = intv_max;
+    params.slave_latency = 0;
+    params.timeout_multiplier = 500;
+    rc = ble_l2cap_sig_update(g_ble_demo_conn_handle, &params,
+                              conn_param_update_cb, NULL);
+    if(rc != 0)
+    {
+        TLS_BT_APPL_TRACE_ERROR("ERROR, ble_l2cap_sig_update rc=%d\r\n", rc);
+    } 
+
     return rc;
 }
 

+ 11 - 1
src/app/bleapp/wm_ble_server_api_demo.h

@@ -2,11 +2,21 @@
 #define __WM_BLE_SERVER_DEMO_H__
 #include "wm_bt.h"
 
-int tls_ble_server_demo_api_init(tls_ble_output_func_ptr output_func_ptr);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+int tls_ble_server_demo_api_init(tls_ble_uart_output_ptr uart_output_ptr, tls_ble_uart_sent_ptr uart_in_and_sent_ptr);
 int tls_ble_server_demo_api_deinit();
 uint32_t tls_ble_server_demo_api_get_mtu();
 int tls_ble_server_demo_api_send_msg(uint8_t *data, int data_len);
+int tls_ble_server_demo_api_send_msg_notify(uint8_t *ptr, int length);
+int tls_ble_server_demo_api_set_work_mode(int work_mode);
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif
 

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 266 - 330
src/app/bleapp/wm_ble_server_wifi_app.c


+ 6 - 0
src/app/bleapp/wm_ble_server_wifi_app.h

@@ -2,9 +2,15 @@
 #define __WM_BT_WIFI_INCLUDED__
 #include "wm_bt_def.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 extern int tls_ble_wifi_cfg_init();
 extern int tls_ble_wifi_cfg_deinit(int reason);
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif

+ 160 - 97
src/app/bleapp/wm_ble_server_wifi_prof.c

@@ -10,6 +10,10 @@
 
 #include "wm_bt_util.h"
 #include "host/ble_hs.h"
+#include "services/gap/ble_svc_gap.h"
+#include "services/gatt/ble_svc_gatt.h"
+
+
 #include "wm_ble_gap.h"
 #include "wm_ble_server_wifi_app.h"
 #include "wm_ble_server_wifi_prof.h"
@@ -19,7 +23,7 @@
  * GLOBAL VARIABLE DEFINITIONS
  ****************************************************************************************
  */
-
+static struct ble_gap_event_listener ble_wifi_event_listener;
 static wm_ble_wifi_prof_callbacks_t  *ps_wifi_prof_callback = NULL;
 static uint8_t wm_ble_wifi_prof_connected = 0;
 
@@ -36,7 +40,7 @@ uint8_t g_blewifi_prof_disconect_reason;
 
 static int
 gatt_svr_chr_access_wifi_write_and_notify(uint16_t conn_handle, uint16_t attr_handle,
-                               struct ble_gatt_access_ctxt *ctxt, void *arg);
+        struct ble_gatt_access_ctxt *ctxt, void *arg);
 
 
 /*
@@ -44,24 +48,22 @@ gatt_svr_chr_access_wifi_write_and_notify(uint16_t conn_handle, uint16_t attr_ha
  ****************************************************************************************
  */
 
-static int
-gatt_svr_chr_access_wifi_write(uint16_t conn_handle, uint16_t attr_handle,
-                              struct ble_gatt_access_ctxt *ctxt, void *arg);
-
 
 static const struct ble_gatt_svc_def gatt_wifi_svr_svcs[] = {
     {
         /* Service: uart */
         .type = BLE_GATT_SVC_TYPE_PRIMARY,
         .uuid = BLE_UUID16_DECLARE(WM_BLE_WIFI_SERVICE_UUID),
-        .characteristics = (struct ble_gatt_chr_def[]) { {
-            .uuid = BLE_UUID16_DECLARE(WM_BLE_WIFI_WRITE_INDICATE_UUID),
-            .val_handle = &g_blewifi_attr_write_and_notify_handle,
-            .access_cb = gatt_svr_chr_access_wifi_write_and_notify,
-            .flags = BLE_GATT_CHR_F_INDICATE|BLE_GATT_CHR_F_WRITE,
-        },{
-            0, /* No more characteristics in this service */
-        } },
+        .characteristics = (struct ble_gatt_chr_def[])
+        { {
+                .uuid = BLE_UUID16_DECLARE(WM_BLE_WIFI_WRITE_INDICATE_UUID),
+                .val_handle = &g_blewifi_attr_write_and_notify_handle,
+                .access_cb = gatt_svr_chr_access_wifi_write_and_notify,
+                .flags = BLE_GATT_CHR_F_INDICATE | BLE_GATT_CHR_F_WRITE,
+            }, {
+                0, /* No more characteristics in this service */
+            }
+        },
     },
 
     {
@@ -76,16 +78,19 @@ static const struct ble_gatt_svc_def gatt_wifi_svr_svcs[] = {
 
 static int
 gatt_svr_chr_access_wifi_write_and_notify(uint16_t conn_handle, uint16_t attr_handle,
-                               struct ble_gatt_access_ctxt *ctxt, void *arg)
+        struct ble_gatt_access_ctxt *ctxt, void *arg)
 {
     struct os_mbuf *om = ctxt->om;
-    switch (ctxt->op) {
+
+    switch(ctxt->op) {
         case BLE_GATT_ACCESS_OP_WRITE_CHR:
-              while(om) {
-                  TLS_HAL_CBACK(ps_wifi_prof_callback, write_cb, 0, (uint8_t *)om->om_data, om->om_len, 0);
-                  om = SLIST_NEXT(om, om_next);
-              }
-              return 0;
+            while(om) {
+                TLS_HAL_CBACK(ps_wifi_prof_callback, write_cb, 0, (uint8_t *)om->om_data, om->om_len, 0);
+                om = SLIST_NEXT(om, om_next);
+            }
+
+            return 0;
+
         default:
             assert(0);
             return BLE_ATT_ERR_UNLIKELY;
@@ -96,61 +101,126 @@ int
 blewifi_gatt_svr_init(void)
 {
     int rc;
-
     rc = ble_gatts_count_cfg(gatt_wifi_svr_svcs);
-    if (rc != 0) {
+
+    if(rc != 0) {
         goto err;
     }
 
     rc = ble_gatts_add_svcs(gatt_wifi_svr_svcs);
-    if (rc != 0) {
+
+    if(rc != 0) {
         return rc;
     }
 
 err:
     return rc;
 }
-static void update_data_length(void *arg)
+
+static void conn_param_update_cb(uint16_t conn_handle, int status, void *arg)
 {
-    ble_gap_set_data_length(g_blewifi_conn_handle, BLE_HCI_SET_DATALEN_TX_OCTETS_MAX, 0x200);
+    TLS_BT_APPL_TRACE_DEBUG("conn param update complete; conn_handle=%d status=%d\n",
+                            conn_handle, status);
+    if(status!=0)
+    {
+        
+    }
 }
-static int ble_gap_evt_cb(struct ble_gap_event *event, void *arg)
+
+static void wm_ble_server_wifi_conn_param_update_slave()
 {
-    switch(event->type)
+    int rc;
+    struct ble_l2cap_sig_update_params params;
+    params.itvl_min = 16;
+    params.itvl_max = 32;
+    params.slave_latency = 0;
+    params.timeout_multiplier = 500;
+    rc = ble_l2cap_sig_update(g_blewifi_conn_handle, &params,
+                              conn_param_update_cb, NULL);
+    if(rc != 0)
     {
+        TLS_BT_APPL_TRACE_ERROR("ERROR, ble_l2cap_sig_update rc=%d\r\n", rc);
+    }
+}
+
+static int ble_gap_evt_cb(struct ble_gap_event *event, void *arg)
+{
+    int rc;
+    struct ble_gap_conn_desc desc;
+    switch(event->type) {
         case BLE_GAP_EVENT_CONNECT:
-            wm_ble_wifi_prof_connected = 1;
-            g_blewifi_prof_disconect_reason = 0;
-            g_blewifi_conn_handle = event->connect.conn_handle;
-            TLS_BT_APPL_TRACE_DEBUG("connected handle=%d,g_blewifi_attr_write_and_notify_handle=%d\r\n",g_blewifi_conn_handle, g_blewifi_attr_write_and_notify_handle );
-            TLS_HAL_CBACK(ps_wifi_prof_callback, connected_cb, 0);
-            //tls_bt_async_proc_func(update_data_length,NULL, 10);
+
+            if(event->connect.status == 0) {
+                rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
+                assert(rc == 0);
+                if(desc.role != BLE_GAP_ROLE_SLAVE) return 0;
+
+                TLS_BT_APPL_TRACE_DEBUG("connected handle=%d,g_blewifi_attr_write_and_notify_handle=%d\r\n",
+                                        g_blewifi_conn_handle, g_blewifi_attr_write_and_notify_handle);
+                wm_ble_wifi_prof_connected = 1;
+                g_blewifi_prof_disconect_reason = 0;
+                g_blewifi_conn_handle = event->connect.conn_handle;    
+                TLS_HAL_CBACK(ps_wifi_prof_callback, connected_cb, 0);
+                tls_bt_async_proc_func(wm_ble_server_wifi_conn_param_update_slave, NULL, 100);
+
+            }
             break;
+
         case BLE_GAP_EVENT_DISCONNECT:
+            
+            if(event->disconnect.conn.role != BLE_GAP_ROLE_SLAVE) return 0;
+            
+            TLS_BT_APPL_TRACE_DEBUG("disconnect reason=0x%02x(%d), app_reason=%d\r\n", (event->disconnect.reason - 0x200),
+                                    event->disconnect.reason,g_blewifi_prof_disconect_reason);
             wm_ble_wifi_prof_connected = 0;
-            TLS_BT_APPL_TRACE_DEBUG("disconnect reason=0x%02x(%d)\r\n", (event->disconnect.reason-0x200),event->disconnect.reason);
             TLS_HAL_CBACK(ps_wifi_prof_callback, disconnected_cb, event->disconnect.reason);
-            if(g_blewifi_prof_disconect_reason)
-            {
+
+            if(g_blewifi_prof_disconect_reason) {
                 //hci error code:  0x16 + 0x200 = 534; //local host terminate the connection;
-                tls_ble_deregister_gap_evt(WM_BLE_GAP_EVENT_CONNECT|WM_BLE_GAP_EVENT_DISCONNECT|WM_BLE_GAP_EVENT_NOTIFY_TX|WM_BLE_GAP_EVENT_MTU, ble_gap_evt_cb);
+                ble_gap_event_listener_unregister(&ble_wifi_event_listener);
                 ps_wifi_prof_callback = NULL;
                 g_blewifi_prof_disconect_reason = 0;
             }
+
             break;
+
         case BLE_GAP_EVENT_NOTIFY_TX:
-            if(event->notify_tx.status == BLE_HS_EDONE)
-            {
+
+            rc = ble_gap_conn_find(event->notify_tx.conn_handle , &desc);
+            assert(rc == 0);
+            if(desc.role != BLE_GAP_ROLE_SLAVE) return 0;
+            
+            if(event->notify_tx.status == BLE_HS_EDONE) {
                 TLS_HAL_CBACK(ps_wifi_prof_callback, indication_cb, 0);
-            }else
-            {
+            } else {
                 /*Application will handle other cases*/
             }
+
             break;
-       case BLE_GAP_EVENT_MTU:
+
+        case BLE_GAP_EVENT_MTU:
+
+            rc = ble_gap_conn_find(event->mtu.conn_handle , &desc);
+            assert(rc == 0);
+            if(desc.role != BLE_GAP_ROLE_SLAVE) return 0;
+            
             TLS_BT_APPL_TRACE_DEBUG("wm ble dm mtu changed to(%d)\r\n", event->mtu.value);
             TLS_HAL_CBACK(ps_wifi_prof_callback, mtu_changed_cb, event->mtu.value);
             break;
+            
+        case BLE_GAP_EVENT_SUBSCRIBE:
+            rc = ble_gap_conn_find(event->subscribe.conn_handle , &desc);
+            assert(rc == 0);
+            if(desc.role != BLE_GAP_ROLE_SLAVE) return 0;
+            
+            TLS_BT_APPL_TRACE_DEBUG("subscribe [%d]indicate(%d,%d)\r\n",event->subscribe.attr_handle,  event->subscribe.prev_indicate,
+                                    event->subscribe.cur_indicate);     
+            break;
+        case BLE_GAP_EVENT_HOST_SHUTDOWN:
+            TLS_BT_APPL_TRACE_DEBUG("Server[WiFi] BLE_GAP_EVENT_HOST_SHUTDOWN\r\n");
+            TLS_HAL_CBACK(ps_wifi_prof_callback, enabled_cb, 1);
+            ps_wifi_prof_callback =NULL;
+            break;
         default:
             break;
     }
@@ -166,9 +236,8 @@ static int ble_gap_evt_cb(struct ble_gap_event *event, void *arg)
 int tls_ble_wifi_adv(bool enable)
 {
     int rc;
-    
-    if(enable)
-    {
+
+    if(enable) {
         struct ble_hs_adv_fields fields;
         const char *name;
         uint8_t adv_ff_data[] = {0x0C, 0x07, 0x00, 0x10};
@@ -178,93 +247,87 @@ int tls_ble_wifi_adv(bool enable)
          *     o Device name.
          *     o user specific field (winner micro).
          */
-        
         memset(&fields, 0, sizeof fields);
-        
         /* Advertise two flags:
          *     o Discoverability in forthcoming advertisement (general)
          *     o BLE-only (BR/EDR unsupported).
          */
         fields.flags = BLE_HS_ADV_F_DISC_GEN |
                        BLE_HS_ADV_F_BREDR_UNSUP;
-        
         name = ble_svc_gap_device_name();
         fields.name = (uint8_t *)name;
         fields.name_len = strlen(name);
         fields.name_is_complete = 1;
-        
         fields.mfg_data = adv_ff_data;
         fields.mfg_data_len = 4;
-        
         rc = ble_gap_adv_set_fields(&fields);
-        if (rc != 0) {
+
+        if(rc != 0) {
             TLS_BT_APPL_TRACE_ERROR("error setting advertisement data; rc=%d\r\n", rc);
             return rc;
         }
 
-
-        
         /* As own address type we use hard-coded value, because we generate
               NRPA and by definition it's random */
         rc = tls_nimble_gap_adv(WM_BLE_ADV_IND, 0);
-
-    }else
-    {
+    } else {
         rc = ble_gap_adv_stop();
-
     }
+
     return rc;
 }
 
 int tls_ble_wifi_prof_init(wm_ble_wifi_prof_callbacks_t *callback)
 {
-	int rc = 0;
-    
-    if(ps_wifi_prof_callback == NULL)
-    {
+    int rc = 0;
+
+    if(ps_wifi_prof_callback == NULL) {
         wm_ble_wifi_prof_connected = 0;
-    	ps_wifi_prof_callback = callback;
         
+        //step 0: reset other services. Note
+        rc = ble_gatts_reset();
+        
+        if(rc != 0) {
+            TLS_BT_APPL_TRACE_ERROR("tls_ble_wifi_prof_init failed rc=%d\r\n", rc);
+            return rc;
+        }
+        
+        ps_wifi_prof_callback = callback;
+
         rc = blewifi_gatt_svr_init();
 
-		if(rc == 0)
-		{	
-		    tls_ble_register_gap_evt(WM_BLE_GAP_EVENT_CONNECT|WM_BLE_GAP_EVENT_DISCONNECT|WM_BLE_GAP_EVENT_NOTIFY_TX|WM_BLE_GAP_EVENT_MTU, ble_gap_evt_cb);
-			TLS_BT_APPL_TRACE_DEBUG("### wm_wifi_prof_init success\r\n");
+        if(rc == 0) {
+            ble_gap_event_listener_register(&ble_wifi_event_listener,
+                                            ble_gap_evt_cb, NULL);
+
             TLS_HAL_CBACK(ps_wifi_prof_callback, enabled_cb, rc);
-		}else
-		{
-			ps_wifi_prof_callback = NULL;
-			TLS_BT_APPL_TRACE_ERROR("### wm_ble_server_register_server failed\r\n");
-		}
-    }
-    else
-    {
-    	TLS_BT_APPL_TRACE_WARNING("wm_ble_server_register_server registered\r\n");
+        } else {
+            ps_wifi_prof_callback = NULL;
+            TLS_BT_APPL_TRACE_ERROR("### tls_ble_wifi_prof_init failed\r\n");
+        }
+    } else {
+        TLS_BT_APPL_TRACE_WARNING("tls_ble_wifi_prof_init registered\r\n");
         rc = BLE_HS_EALREADY;
     }
-	
-	return rc;
+
+    return rc;
 }
 int tls_ble_wifi_prof_deinit(int reason)
 {
-	int rc = 0;
-    
-    if(ps_wifi_prof_callback)
-    {
+    int rc = 0;
+
+    if(ps_wifi_prof_callback) {
         TLS_HAL_CBACK(ps_wifi_prof_callback, enabled_cb, reason);
-        if(wm_ble_wifi_prof_connected == 0)
-        {
-            tls_ble_deregister_gap_evt(WM_BLE_GAP_EVENT_CONNECT|WM_BLE_GAP_EVENT_DISCONNECT|WM_BLE_GAP_EVENT_NOTIFY_TX|WM_BLE_GAP_EVENT_MTU, ble_gap_evt_cb);
+
+        if(wm_ble_wifi_prof_connected == 0) {
+            ble_gap_event_listener_unregister(&ble_wifi_event_listener);
             ps_wifi_prof_callback = NULL;   //this ptr will be cleared, when got deregister event
-        }else
-        {
+        } else {
             //this ptr will be freed when disconected with remote device;
         }
-    }else
-    {
-    	TLS_BT_APPL_TRACE_WARNING("wm_wifi_prof_deinit deinited already\r\n");
-		rc = BLE_HS_EALREADY;
+    } else {
+        TLS_BT_APPL_TRACE_WARNING("tls_ble_wifi_prof_deinit deinited already\r\n");
+        rc = BLE_HS_EALREADY;
     }
 
     return rc;
@@ -281,18 +344,18 @@ int tls_ble_wifi_prof_send_msg(uint8_t *data, int data_len)
     int rc;
     struct os_mbuf *om;
 
-    if(data_len<=0 || data == NULL)
-    {
+    if(data_len <= 0 || data == NULL) {
         return BLE_HS_EINVAL;
     }
-    
+
     om = ble_hs_mbuf_from_flat(data, data_len);
-    if (!om) {
+
+    if(!om) {
         return BLE_HS_ENOMEM;
     }
-    
+
     rc = ble_gattc_indicate_custom(g_blewifi_conn_handle,
-                            g_blewifi_attr_write_and_notify_handle, om);    
+                                   g_blewifi_attr_write_and_notify_handle, om);
     return rc;
 }
 

+ 9 - 2
src/app/bleapp/wm_ble_server_wifi_prof.h

@@ -1,6 +1,10 @@
 #ifndef __WM_BLE_WIFI_PROF_H__
 #define __WM_BLE_WIFI_PROF_H__
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef int (*op_exec_write_callback)(int exec);
 typedef int (*op_write_callback)(int offset, uint8_t *ptr, int length, bool b_prep);
 typedef int (*op_read_callback)(int offset);
@@ -11,8 +15,7 @@ typedef int (*op_service_enabled_callback)(int status);
 typedef int (*op_mtu_changed_callback)(int mtu);
 
 
-typedef struct
-{
+typedef struct {
     size_t size;
 
     op_service_enabled_callback enabled_cb;
@@ -40,6 +43,10 @@ int tls_ble_wifi_prof_send_msg(uint8_t *ptr, int length);
 int tls_ble_wifi_prof_disable(int status);
 int tls_ble_wifi_adv(bool enable);
 
+#ifdef __cplusplus
+}
+#endif
+
 
 #endif
 

+ 447 - 136
src/app/bleapp/wm_ble_uart_if.c

@@ -6,223 +6,534 @@
 **
 *****************************************************************************/
 #include <assert.h>
+#include <string.h>
 
 #include "wm_bt_config.h"
 
 #if (WM_NIMBLE_INCLUDED == CFG_ON)
 
 #include "host/ble_hs.h"
+#include "nimble/nimble_port.h"
 #include "wm_bt_app.h"
+#include "wm_ble_gap.h"
 #include "wm_ble_uart_if.h"
 #include "wm_ble_server_api_demo.h"
 #include "wm_ble_client_api_demo.h"
 #include "wm_bt_util.h"
 #include "wm_mem.h"
+#include "wm_include.h"
+#include "wm_cpu.h"
+#include "wm_bt_util.h"
+
+#include "wm_gpio_afsel.h"
 
+/*
+ * GLOBAL VARIABLE DEFINITIONS
+ ****************************************************************************************
+ */
 
 
+#define WM_UART_TAST_STK_SIZE	      512
+#define WM_DISP_TAST_STK_SIZE	      1024
 
-static ringbuffer_t *g_rb_ptr = NULL;
-static uint8_t g_uart_id = -1;
-static tls_ble_uart_mode_t g_bum = BLE_UART_SERVER_MODE;
+#define WM_UART_RX_BUF_SIZE	        512
+#define WM_UART_TASK_PRIO           20
 
-static struct ble_npl_callout g_async_send_timer;
+#define WM_MSG_OPEN_UART            0x00
+#define WM_MSG_UART_RECEIVE_DATA    0x01
+#define WM_MSG_AVAILABLE            0x02
+#define WM_UART_DEFAULT_THRESH      244
 
-#define RING_BUFFER_SIZE (4096)
+#define WM_UART_RECV_QUEUE_SIZE     12
+static OS_STK   wm_uart_task_stk[WM_UART_TAST_STK_SIZE];
+static OS_STK   wm_disp_task_stk[WM_DISP_TAST_STK_SIZE];
+static struct ble_gap_event_listener ble_uart_event_listener;
 
 
-static void wm_uart_async_write(uint8_t *p_data, uint16_t length)
+/**
+ * @typedef struct WM_UART
+ */
+typedef struct WM_UART
 {
-    //TLS_BT_APPL_TRACE_API("%s , send to uart %d bytes\r\n", __FUNCTION__, length);
-    tls_uart_write_async(g_uart_id, p_data, length);    
-}
+    tls_os_task_t *uart_recv_task;
+    tls_os_task_t *uart_disp_task;
+    tls_os_queue_t *wm_uart_queue_recv;       //uart iterface recv queue;
+    tls_os_queue_t *wm_queue_msg_available;   //uart msg to mesh;
+    int8_t uart_idx;
+    uint16_t thresh;                            //
+    uint8_t *wm_buffer;
+    int bandrate;
+    TLS_UART_PMODE_T parity;
+    TLS_UART_STOPBITS_T stopbits;
+    char *rx_buf;
+    int rx_msg_num;
+    int rx_data_len;
+    ringbuffer_t *wm_msg_buffer_ptr;  //
+    int (*dispatch_func)(uint8_t *payload, int length);
+} WM_UART_ST;
+
+static WM_UART_ST *wm_uart = NULL;
+
+
+/*
+ * LOCAL FUNCTION DEFINITIONS
+ ****************************************************************************************
+ */
 
-static void wm_uart_async_send_cb(struct ble_npl_event *evt)
+/**
+ * Send payload to uart, the payload is from gatt notfification or gatt write.
+ *
+ *
+ */
+
+void wm_uart_send_notify(tls_uart_msg_out_t type, uint8_t *msg, int len)
 {
-    uint32_t cache_length = 0;
-    uint32_t gatt_mtu = 0;
-    uint32_t send_len = 0;
-    uint8_t send_buffer[256];
-    int rc;
-    
-    cache_length = bt_ringbuffer_size(g_rb_ptr);
-    gatt_mtu = tls_ble_server_demo_api_get_mtu();
+    if(wm_uart == NULL) return;
+    if(type != UART_OUTPUT_DATA) return;
+
+    tls_uart_write_async(wm_uart->uart_idx, (char *)msg, (uint16_t)len);
+}
+
+
+/**
+ * Payload sent out, and Continue to check if anything can be sent out
+ * 
+ * On Server: gatt notification tx E_DONE;
+ * On Client: Write to remote already;
+ *
+ */
 
-    send_len = MIN(cache_length, gatt_mtu);
+void wm_uart_sent_cb(tls_ble_uart_mode_t mode, int status)
+{
+    int ret;
+    int rx_len;
     
-    bt_ringbuffer_peek(g_rb_ptr,0,send_buffer,send_len);
+    TLS_BT_APPL_TRACE_DEBUG("UART Sent CBACK:%d, status=%d\r\n", mode, status);
     
-    if(g_bum == BLE_UART_SERVER_MODE)
+    if(wm_uart->thresh)
     {
-        rc = tls_ble_server_demo_api_send_msg(send_buffer, send_len);
+        rx_len = min(wm_uart->thresh, bt_ringbuffer_size(wm_uart->wm_msg_buffer_ptr));
+        if(rx_len < wm_uart->thresh)
+        {
+            rx_len = 0; //less than thresh 
+        }
     }else
     {
-        rc = tls_ble_client_demo_api_send_msg(send_buffer, send_len);
-    } 
-    
-    if(rc == 0)
-    {
-        bt_ringbuffer_delete(g_rb_ptr,send_len);
-    }else
+        rx_len = bt_ringbuffer_size(wm_uart->wm_msg_buffer_ptr);
+        rx_len = min(WM_UART_DEFAULT_THRESH, rx_len);
+    }
+
+    if(rx_len >0)
     {
-        //TLS_BT_APPL_TRACE_ERROR("Send to remote via ble failed, check reason=%d\r\n", bt_status);
-        ble_npl_callout_reset(&g_async_send_timer,ble_npl_time_ms_to_ticks32(10));
-    } 
+        bt_ringbuffer_peek(wm_uart->wm_msg_buffer_ptr, 0, wm_uart->wm_buffer, rx_len);
+    
+        ret = wm_uart->dispatch_func(wm_uart->wm_buffer, rx_len);
+
+        if(ret == 0)
+        {
+            bt_ringbuffer_delete(wm_uart->wm_msg_buffer_ptr, rx_len);
+        }else
+        {
+            TLS_BT_APPL_TRACE_WARNING("UART[%d] Send ret:%d\r\n", mode, ret);
+        }
+    }    
 }
-static void wm_uart_async_read_cb(int size, void *user_data)
-{
-    int read_out = 0;
-    uint32_t cache_length = 0;
 
-    if(size <= 0) return;
 
-    if(bt_ringbuffer_available(g_rb_ptr)< size)
+static s16 wm_uart_rx(u16 len)
+{
+    if (NULL == wm_uart)
     {
-        TLS_BT_APPL_TRACE_WARNING("ble uart cache buffer is full, mode[%d]\r\n", g_bum);
-        return;
+        return WM_FAILED;
     }
-    
-    uint8_t *tmp_ptr = tls_mem_alloc(size);
-    
-    cache_length = bt_ringbuffer_size(g_rb_ptr);
-    
-    read_out = tls_uart_read(g_uart_id, tmp_ptr, size);
 
-    bt_ringbuffer_insert(g_rb_ptr, tmp_ptr, read_out);  
-
-    /*if sending stopped or not started, triger to send immediatelly*/
-    if(cache_length == 0)
+    wm_uart->rx_data_len += len;
+    if (wm_uart->rx_msg_num < 3)
     {
-        ble_npl_callout_reset(&g_async_send_timer,ble_npl_time_ms_to_ticks32(5));
+        wm_uart->rx_msg_num++;
+        tls_os_queue_send(wm_uart->wm_uart_queue_recv, (void *) WM_MSG_UART_RECEIVE_DATA, 0);
     }
 
-    tls_mem_free(tmp_ptr);
+    return WM_SUCCESS;
 }
-/*
- * EXPORTED FUNCTION DEFINITIONS
- ****************************************************************************************
- */
 
-int tls_ble_uart_init(tls_ble_uart_mode_t mode, uint8_t uart_id, tls_uart_options_t *p_hci_if)
+static void wm_dispatch_task(void *sdata)
 {
-    int rc;
+    WM_UART_ST *uart = (WM_UART_ST *) sdata;
+    void *msg;
+    int ret = 0;
+    int rx_len = 0;
     
-    TLS_BT_APPL_TRACE_API("%s , uart_id=%d\r\n", __FUNCTION__, uart_id);
-
-    if(bt_adapter_state == WM_BT_STATE_OFF)
+    for (;;)
     {
-        TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
-        return BLE_HS_EDISABLED;
-    }    
-    
-    if(g_rb_ptr) return BLE_HS_EALREADY;
+        tls_os_queue_receive(uart->wm_queue_msg_available, (void **) &msg, 0, 0);
+        switch ((u32) msg)
+        {
 
-    if(mode == BLE_UART_SERVER_MODE)
-    {
-        rc = tls_ble_server_demo_api_init(wm_uart_async_write);
-    }else if(mode == BLE_UART_CLIENT_MODE)
-    {
-        rc = tls_ble_client_demo_api_init(wm_uart_async_write);
-    }else
-    {
-        return BLE_HS_EINVAL;
+            case WM_MSG_AVAILABLE:
+            {
+                if(uart->thresh)
+                {
+                    rx_len = min(uart->thresh, bt_ringbuffer_size(uart->wm_msg_buffer_ptr));
+                    if(rx_len < uart->thresh)
+                    {
+                        rx_len = 0; //less than thresh 
+                    }
+                }else
+                {
+                    rx_len = bt_ringbuffer_size(uart->wm_msg_buffer_ptr);
+                    rx_len = min(WM_UART_DEFAULT_THRESH, rx_len);
+                }
+
+                if(rx_len >0)
+                {
+                    bt_ringbuffer_peek(uart->wm_msg_buffer_ptr, 0, uart->wm_buffer, rx_len);
+                
+                    ret = uart->dispatch_func(uart->wm_buffer, rx_len);
+
+                    if(ret == 0)
+                    {
+                        bt_ringbuffer_delete(uart->wm_msg_buffer_ptr, rx_len);
+                    }
+                }
+            }
+            break;
+
+        default:
+            break;
+        }
     }
-    
-    if(rc != 0)
+}
+
+
+static void wm_uart_task(void *sdata)
+{
+    WM_UART_ST *uart = (WM_UART_ST *) sdata;
+    tls_uart_options_t opt;
+    void *msg;
+    int ret = 0;
+    int len = 0;
+    int rx_len = 0;
+
+    for (;;)
     {
-        return rc;
+        tls_os_queue_receive(uart->wm_uart_queue_recv, (void **) &msg, 0, 0);
+        switch ((u32) msg)
+        {
+        case WM_MSG_OPEN_UART:
+        {
+            opt.baudrate = uart->bandrate;
+            opt.paritytype = uart->parity;
+            opt.stopbits = uart->stopbits;
+            opt.charlength = TLS_UART_CHSIZE_8BIT;
+            opt.flow_ctrl = TLS_UART_FLOW_CTRL_NONE;
+
+            //选择待使用的引脚及具体的复用功能
+            /* UART1_RX-PB07  UART1_TX-PB06 */
+            if(uart->uart_idx == 1)
+            {
+                wm_uart1_rx_config(WM_IO_PB_07);
+                wm_uart1_tx_config(WM_IO_PB_06);
+            }
+
+            if (WM_SUCCESS != tls_uart_port_init(uart->uart_idx, &opt, 0))
+            {
+                TLS_BT_APPL_TRACE_ERROR("uart%d init error\r\n", uart->uart_idx);
+            }
+
+            tls_uart_rx_callback_register((u16) uart->uart_idx, (s16(*)(u16, void*))wm_uart_rx, NULL);			
+        }
+        break;
+
+        case WM_MSG_UART_RECEIVE_DATA:
+        {
+            rx_len = uart->rx_data_len;
+            while (rx_len > 0)
+            {
+                len = (rx_len > WM_UART_RX_BUF_SIZE) ? WM_UART_RX_BUF_SIZE : rx_len;
+                memset(uart->rx_buf, 0, (WM_UART_RX_BUF_SIZE + 1));
+                ret = tls_uart_read(uart->uart_idx, (u8 *) uart->rx_buf, len);  /* input */
+                if (ret <= 0)
+                {
+                    break;
+                }
+
+                rx_len -= ret;
+                uart->rx_data_len -= ret;
+
+                len = bt_ringbuffer_available(wm_uart->wm_msg_buffer_ptr);
+                if(ret > len)
+                {
+                    TLS_BT_APPL_TRACE_WARNING("Warning ,mesh cache buffer full...\r\n");
+                }
+                bt_ringbuffer_insert(wm_uart->wm_msg_buffer_ptr, (uint8_t *) uart->rx_buf, ret);
+                
+                tls_os_queue_send(wm_uart->wm_queue_msg_available, (void *) WM_MSG_AVAILABLE, 0);
+            }
+            if (uart->rx_msg_num > 0)
+            {
+                uart->rx_msg_num--;
+            }
+        }
+        break;
+
+        default:
+            break;
+        }
     }
+}
+
+
+
+static int ble_uart_init(int8_t uart_idx, int bandrate, int parity, int stopbits, uint16_t thresh, int (*dispatch_func)(uint8_t *payload, int length))
+{
+    tls_os_status_t status;
     
-    g_rb_ptr = bt_ringbuffer_init(RING_BUFFER_SIZE);
-    if(g_rb_ptr == NULL)
+    TLS_BT_APPL_TRACE_DEBUG("uart demo param=%d,%d, %d, %d, %d\r\n", uart_idx, bandrate, parity, stopbits, thresh);
+    if (NULL == wm_uart)
     {
-        
-        if(mode == BLE_UART_SERVER_MODE)
+        wm_uart = tls_mem_alloc(sizeof(WM_UART_ST));
+        if (NULL == wm_uart)
         {
-            tls_ble_server_demo_api_deinit();
-        }else if(mode == BLE_UART_CLIENT_MODE)
+            goto _error;
+        }
+        memset(wm_uart, 0, sizeof(WM_UART_ST));
+
+        wm_uart->rx_buf = tls_mem_alloc(WM_UART_RX_BUF_SIZE + 1);
+        if (NULL == wm_uart->rx_buf)
         {
-            tls_ble_client_demo_api_deinit();
+            goto _error1;
         }
-        return BLE_HS_ENOMEM;
+        wm_uart->thresh = thresh;
+
+        if(0 == thresh)
+        {
+            thresh = WM_UART_DEFAULT_THRESH;   //default thresh buffer size;
+        }
+        wm_uart->wm_buffer = (uint8_t *)tls_mem_alloc(thresh);
+        if(!wm_uart->wm_buffer){
+            goto _error1;
+        }
+
+        wm_uart->wm_msg_buffer_ptr = bt_ringbuffer_init(2048);
+        if (NULL == wm_uart->wm_msg_buffer_ptr)
+        {
+            goto _error1;
+        }        
+        
+        status = tls_os_queue_create(&(wm_uart->wm_uart_queue_recv), 6);
+        assert(status == 0);
+        status = tls_os_task_create(wm_uart->uart_recv_task, "buc",
+                           wm_uart_task,
+                           (void *) wm_uart,
+                           (void *) wm_uart_task_stk, /** 任务栈的起始地址 */
+                           WM_UART_TAST_STK_SIZE*4,                         /** 任务栈的大小     */
+                           WM_UART_TASK_PRIO, 0);
+        assert(status == 0);
+        status = tls_os_queue_create(&(wm_uart->wm_queue_msg_available), 6);
+        assert(status == 0);
+        status = tls_os_task_create(wm_uart->uart_disp_task, "bud",
+                   wm_dispatch_task,
+                   (void *) wm_uart,
+                   (void *) wm_disp_task_stk, /** 任务栈的起始地址 */
+                   WM_DISP_TAST_STK_SIZE*4,                         /** 任务栈的大小     */
+                   WM_UART_TASK_PRIO+1, 0);
+        assert(status == 0);
+    }
+    if (0 == bandrate)
+    {
+        bandrate = 115200;
+    }
+    if (-1 == parity)
+    {
+        parity = TLS_UART_PMODE_DISABLED;
     }
+    if (-1 == stopbits)
+    {
+        stopbits = TLS_UART_ONE_STOPBITS;
+    }
+    if(-1 == uart_idx)
+    {
+        uart_idx = TLS_UART_1;
+    }
+
+    wm_uart->dispatch_func = dispatch_func;
+    wm_uart->uart_idx = uart_idx;
+    wm_uart->bandrate = bandrate;
+    wm_uart->parity = (TLS_UART_PMODE_T) parity;
+    wm_uart->stopbits = (TLS_UART_STOPBITS_T) stopbits;
+    wm_uart->rx_msg_num = 0;
+    wm_uart->rx_data_len = 0;
+    tls_os_queue_send(wm_uart->wm_uart_queue_recv, (void *) WM_MSG_OPEN_UART, 0);
 
-    rc = tls_uart_port_init(uart_id, NULL, 0);
-    if(rc != WM_SUCCESS)
+    return WM_SUCCESS;
+
+_error1:
+    if(wm_uart)
     {
-        if(mode == BLE_UART_SERVER_MODE)
+        if(wm_uart->rx_buf)
         {
-            tls_ble_server_demo_api_deinit();
-        }else if(mode == BLE_UART_CLIENT_MODE)
+            tls_mem_free(wm_uart->rx_buf);
+            wm_uart->rx_buf = NULL;
+        }
+        if(wm_uart->wm_buffer)
         {
-            tls_ble_client_demo_api_deinit();
+            tls_mem_free(wm_uart->wm_buffer);
+            wm_uart->wm_buffer = NULL;
         }
-
-        bt_ringbuffer_free(g_rb_ptr);
-        g_rb_ptr = NULL;
-        return BLE_HS_EAPP;
     }
-    
-    g_uart_id = uart_id;
-    g_bum = mode;
+    tls_mem_free(wm_uart);
+    wm_uart = NULL;
+_error:
+    TLS_BT_APPL_TRACE_ERROR("ble_uart_init failed\n");
+    return WM_FAILED;
+}
 
-    ble_npl_callout_init(&g_async_send_timer, nimble_port_get_dflt_eventq(), wm_uart_async_send_cb, NULL);
-    tls_uart_rx_callback_register(uart_id, wm_uart_async_read_cb, (void *)NULL);
+static int ble_gap_evt_cb(struct ble_gap_event *event, void *arg)
+{
+    TLS_BT_APPL_TRACE_DEBUG("%s\r\n", __FUNCTION__);
+	if(event->type == BLE_GAP_EVENT_HOST_SHUTDOWN)
+	{
+        if(wm_uart)
+        {
+            if(wm_uart->rx_buf)
+            {
+                tls_mem_free(wm_uart->rx_buf);
+                wm_uart->rx_buf = NULL;
+            }
+            if(wm_uart->wm_buffer)
+            {
+                tls_mem_free(wm_uart->wm_buffer);
+                wm_uart->wm_buffer = NULL;
+            }
+            if(wm_uart->wm_msg_buffer_ptr)
+            {
+                bt_ringbuffer_free(wm_uart->wm_msg_buffer_ptr);
+                wm_uart->wm_msg_buffer_ptr = NULL;
+            }
+            if(wm_uart->uart_recv_task)
+            {
+                tls_os_task_del_by_task_handle(wm_uart->uart_recv_task, NULL);
+                wm_uart->uart_recv_task = NULL;
+            }
+            if(wm_uart->uart_disp_task)
+            {
+                tls_os_task_del_by_task_handle(wm_uart->uart_disp_task, NULL);
+                wm_uart->uart_disp_task = NULL;
+            }
+            tls_os_queue_delete(wm_uart->wm_uart_queue_recv);
+            tls_os_queue_delete(wm_uart->wm_queue_msg_available);
+            tls_uart_rx_callback_register((u16) wm_uart->uart_idx, NULL, NULL);
+            tls_mem_free(wm_uart);
+            wm_uart = NULL;
+
+        } 
+	}
 
     return 0;
 }
 
-int tls_ble_uart_deinit(tls_ble_uart_mode_t mode,uint8_t uart_id)
-{
-    int rc = 0;
+/*
+ * EXPORTED FUNCTION DEFINITIONS
+ ****************************************************************************************
+ */
 
-    //TODO deinit uart interface???
+int tls_ble_uart_init(tls_ble_uart_mode_t mode,uint8_t uart_idx, tls_uart_options_t *p_hci_if)
+{
+    int rc,rc1;
 
+    CHECK_SYSTEM_READY();
+    
     if(mode == BLE_UART_SERVER_MODE)
     {
-        rc = tls_ble_server_demo_api_deinit();
+        rc = tls_ble_server_demo_api_init(wm_uart_send_notify, wm_uart_sent_cb);
+        if(!p_hci_if)
+        {
+            rc1 = ble_uart_init(uart_idx, 0, 0, 0, 244, tls_ble_server_demo_api_send_msg);
+        }else
+        {
+            rc1 = ble_uart_init(uart_idx, p_hci_if->baudrate, p_hci_if->paritytype, p_hci_if->stopbits, 244, tls_ble_server_demo_api_send_msg);
+        }
     }else if(mode == BLE_UART_CLIENT_MODE)
     {
-        rc = tls_ble_client_demo_api_deinit();
+        rc = tls_ble_client_demo_api_init(wm_uart_send_notify,wm_uart_sent_cb);
+        if(!p_hci_if)
+        {
+            rc1 = ble_uart_init(uart_idx, 0, 0, 0, 244, tls_ble_client_demo_api_send_msg);
+        }else
+        {
+            rc1 = ble_uart_init(uart_idx, p_hci_if->baudrate, p_hci_if->paritytype, p_hci_if->stopbits, 244, tls_ble_server_demo_api_send_msg);
+        }
+    }else
+    {
+        return BLE_HS_EINVAL;
     }
 
-    if(rc != 0) return BLE_HS_EAPP;
+    if(rc != 0 || rc1 != 0)
+    {
+        
+    }
     
-    if(ble_npl_callout_is_active(&g_async_send_timer)) ble_npl_callout_stop(&g_async_send_timer);
-    ble_npl_callout_deinit(&g_async_send_timer);
+    ble_gap_event_listener_register(&ble_uart_event_listener,
+                                ble_gap_evt_cb, NULL);
+
+    return rc+rc1;
+}
+
 
-    /*clear the async recv function*/
-    tls_uart_rx_callback_register(uart_id, NULL, (void *)NULL);
 
+int tls_ble_uart_deinit(tls_ble_uart_mode_t mode, uint8_t uart_id)
+{
+    int rc = 0;
     
-    if(g_rb_ptr)
+    CHECK_SYSTEM_READY();
+
+    if(mode == BLE_UART_SERVER_MODE) {
+        rc = tls_ble_server_demo_api_deinit();
+    } else if(mode == BLE_UART_CLIENT_MODE) {
+        rc = tls_ble_client_demo_api_deinit();
+    }
+
+    if(wm_uart)
     {
-       bt_ringbuffer_free(g_rb_ptr); 
-       g_rb_ptr = NULL;
+        if(wm_uart->rx_buf)
+        {
+            tls_mem_free(wm_uart->rx_buf);
+            wm_uart->rx_buf = NULL;
+        }
+        if(wm_uart->wm_buffer)
+        {
+            tls_mem_free(wm_uart->wm_buffer);
+            wm_uart->wm_buffer = NULL;
+        }
+        if(wm_uart->wm_msg_buffer_ptr)
+        {
+            bt_ringbuffer_free(wm_uart->wm_msg_buffer_ptr);
+            wm_uart->wm_msg_buffer_ptr = NULL;
+        }
+        if(wm_uart->uart_recv_task)
+        {
+            tls_os_task_del_by_task_handle(wm_uart->uart_recv_task, NULL);
+            wm_uart->uart_recv_task = NULL;
+        }
+        if(wm_uart->uart_disp_task)
+        {
+            tls_os_task_del_by_task_handle(wm_uart->uart_disp_task, NULL);
+            wm_uart->uart_disp_task = NULL;
+        }
+        tls_os_queue_delete(wm_uart->wm_uart_queue_recv);
+        tls_os_queue_delete(wm_uart->wm_queue_msg_available);
+        tls_uart_rx_callback_register((u16) wm_uart->uart_idx, NULL, NULL);
+
+        tls_mem_free(wm_uart);
+        wm_uart = NULL;
+
     }
+ 
+    ble_gap_event_listener_unregister(&ble_uart_event_listener);
 
-    return 0;
-}
-uint32_t tls_ble_uart_buffer_size()
-{
-    return bt_ringbuffer_size(g_rb_ptr);
-}
-uint32_t tls_ble_uart_buffer_available()
-{
-    return bt_ringbuffer_available(g_rb_ptr);
+    return rc;
 }
 
-uint32_t tls_ble_uart_buffer_read(uint8_t *ptr, uint32_t length)
-{
-    return bt_ringbuffer_pop(g_rb_ptr, ptr, length);
-}
-uint32_t tls_ble_uart_buffer_peek(uint8_t *ptr, uint32_t length)
-{
-    return bt_ringbuffer_peek(g_rb_ptr,0,ptr,length);
-}
-uint32_t tls_ble_uart_buffer_delete(uint32_t length)
-{
-    return bt_ringbuffer_delete(g_rb_ptr,length);
-}
 
 #endif

+ 9 - 6
src/app/bleapp/wm_ble_uart_if.h

@@ -3,13 +3,16 @@
 #include "wm_uart.h"
 #include "wm_bt.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 int tls_ble_uart_init(tls_ble_uart_mode_t mode, uint8_t uart_id, tls_uart_options_t *p_hci_if);
-int tls_ble_uart_deinit(tls_ble_uart_mode_t mode,uint8_t uart_id);
+int tls_ble_uart_deinit(tls_ble_uart_mode_t mode, uint8_t uart_id);
+
+#ifdef __cplusplus
+}
+#endif
 
-uint32_t tls_ble_uart_buffer_size();
-uint32_t tls_ble_uart_buffer_available();
-uint32_t tls_ble_uart_buffer_read(uint8_t *ptr, uint32_t length);
-uint32_t tls_ble_uart_buffer_delete(uint32_t length);
-uint32_t tls_ble_uart_buffer_peek(uint8_t *ptr, uint32_t length);
 
 #endif

+ 237 - 189
src/app/bleapp/wm_bt_app.c

@@ -14,30 +14,36 @@
 
 #if ( WM_NIMBLE_INCLUDED == CFG_ON )
 #include "wm_bt.h"
+#include "wm_bt_app.h"
 #include "wm_bt_util.h"
 #include "host/ble_hs.h"
 #include "host/util/util.h"
-
+#include "wm_pmu.h"
 #include "wm_ble_gap.h"
+
+#if ( WM_MESH_INCLUDED == CFG_ON )
+#include "wm_ble_mesh.h"
+#endif
 #include "wm_ble_uart_if.h"
+#include "wm_ble_client_util.h"
 #include "wm_ble_server_wifi_app.h"
 #include "wm_ble_server_api_demo.h"
 #include "wm_ble_client_api_demo.h"
 #include "wm_ble_client_api_multi_conn_demo.h"
 
-static bool ble_system_state_on = false;
-
 /*
  * STRUCTURE DEFINITIONS
  ****************************************************************************************
  */
 
+
 /*
  * GLOBAL VARIABLE DEFINITIONS
  ****************************************************************************************
  */
 
 volatile tls_bt_state_t bt_adapter_state = WM_BT_STATE_OFF;
+volatile bt_system_action_t bt_system_action = WM_BT_SYSTEM_ACTION_IDLE;
 
 
 /*
@@ -52,52 +58,40 @@ volatile tls_bt_state_t bt_adapter_state = WM_BT_STATE_OFF;
  ****************************************************************************************
  */
 
-static void xxx_ble_income(uint8_t *p_data, uint32_t length) {
-    printf("ble income len=%d ", length);
-    for (size_t i = 0; i < length; i++)
-    {
-        printf("%02X ", p_data[i]);
-    }
-    printf("\n");
-}
-
 static void app_adapter_state_changed_callback(tls_bt_state_t status)
 {
-	TLS_BT_APPL_TRACE_DEBUG("adapter status = %s\r\n", status==WM_BT_STATE_ON?"bt_state_on":"bt_state_off");
+    TLS_BT_APPL_TRACE_DEBUG("adapter status = %s\r\n",
+                            status == WM_BT_STATE_ON ? "bt_state_on" : "bt_state_off");
+    bt_system_action = WM_BT_SYSTEM_ACTION_IDLE;
+#if (TLS_CONFIG_BLE == CFG_ON)
 
-    bt_adapter_state = status;
+    if(status == WM_BT_STATE_ON) {
+        TLS_BT_APPL_TRACE_VERBOSE("init base application\r\n");
+        bt_adapter_state = status;
+        //at here , user run their own applications;
 
-	#if (TLS_CONFIG_BLE == CFG_ON)
-
-    if(status == WM_BT_STATE_ON)
-    {
-    	TLS_BT_APPL_TRACE_VERBOSE("init base application\r\n");
-
-		//at here , user run their own applications;
-        #if 1
         //tls_ble_wifi_cfg_init();
-        tls_ble_server_demo_api_init(xxx_ble_income);
-        //tls_ble_client_demo_api_init(NULL);
+        //tls_ble_server_demo_api_init(NULL,NULL);
+        //tls_ble_client_demo_api_init(NULL, NULL);
         //tls_ble_server_demo_hid_init();
         //tls_ble_server_hid_uart_init();
         //tls_ble_client_multi_conn_demo_api_init();
-        #endif
+        //tls_ble_mesh_init(NULL, MESH_ROLE_NODE, true);
 
-    }else
-    {
+    } else {
         TLS_BT_APPL_TRACE_VERBOSE("deinit base application\r\n");
-
         //here, user may free their application;
-        #if 1
-        tls_ble_wifi_cfg_deinit(2);
-        tls_ble_server_demo_api_deinit();
-        tls_ble_client_demo_api_deinit();
-        tls_ble_client_multi_conn_demo_api_deinit();
-        #endif
-    }
 
-    #endif
+        //tls_ble_wifi_cfg_deinit(2);
+        //tls_ble_server_demo_api_deinit();
+        //tls_ble_client_demo_api_deinit();
+        //tls_ble_client_multi_conn_demo_api_deinit();
+        //tls_ble_mesh_deinit();
 
+        bt_adapter_state = status;
+    }
+
+#endif
 }
 
 
@@ -108,7 +102,6 @@ on_sync(void)
     /* Make sure we have proper identity address set (public preferred) */
     //rc = ble_hs_util_ensure_addr(1);
     //assert(rc == 0);
-
     app_adapter_state_changed_callback(WM_BT_STATE_ON);
 }
 static void
@@ -120,45 +113,45 @@ on_reset(int reason)
 static void
 on_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
 {
-
     char buf[BLE_UUID_STR_LEN];
 
-    switch (ctxt->op) {
+    switch(ctxt->op) {
         case BLE_GATT_REGISTER_OP_SVC:
-            TLS_BT_APPL_TRACE_DEBUG("service,uuid16 %s handle=%d (%04X)\r\n",ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),ctxt->svc.handle, ctxt->svc.handle);
+            TLS_BT_APPL_TRACE_DEBUG("service,uuid16 %s handle=%d (%04X)\r\n",
+                                    ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf), ctxt->svc.handle, ctxt->svc.handle);
             break;
 
         case BLE_GATT_REGISTER_OP_CHR:
             TLS_BT_APPL_TRACE_DEBUG("charact,uuid16 %s arg %d def_handle=%d (%04X) val_handle=%d (%04X)\r\n",
-                ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
-                (int)ctxt->chr.chr_def->arg,
-                ctxt->chr.def_handle, ctxt->chr.def_handle,
-                ctxt->chr.val_handle, ctxt->chr.val_handle);
+                                    ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
+                                    (int)ctxt->chr.chr_def->arg,
+                                    ctxt->chr.def_handle, ctxt->chr.def_handle,
+                                    ctxt->chr.val_handle, ctxt->chr.val_handle);
             break;
 
         case BLE_GATT_REGISTER_OP_DSC:
             TLS_BT_APPL_TRACE_DEBUG("descrip, uuid16 %s arg %d handle=%d (%04X)\r\n",
-                ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
-                (int)ctxt->dsc.dsc_def->arg,
-                ctxt->dsc.handle, ctxt->dsc.handle);
+                                    ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
+                                    (int)ctxt->dsc.dsc_def->arg,
+                                    ctxt->dsc.handle, ctxt->dsc.handle);
             break;
     }
 
     return;
-
 }
 
 
 int
 tls_bt_init(uint8_t uart_idx)
 {
-    if(ble_system_state_on)
-    {
+    if(bt_adapter_state == WM_BT_STATE_ON) {
         return BLE_HS_EALREADY;
     }
 
-    memset(&ble_hs_cfg, 0, sizeof(ble_hs_cfg));
+    if(bt_system_action != WM_BT_SYSTEM_ACTION_IDLE) { return BLE_HS_EBUSY; }
 
+    bt_system_action = WM_BT_SYSTEM_ACTION_ENABLING;
+    memset(&ble_hs_cfg, 0, sizeof(ble_hs_cfg));
     /** Security manager settings. */
     ble_hs_cfg.sm_io_cap = MYNEWT_VAL(BLE_SM_IO_CAP),
     ble_hs_cfg.sm_oob_data_flag = MYNEWT_VAL(BLE_SM_OOB_DATA_FLAG),
@@ -168,29 +161,24 @@ tls_bt_init(uint8_t uart_idx)
     ble_hs_cfg.sm_keypress = MYNEWT_VAL(BLE_SM_KEYPRESS),
     ble_hs_cfg.sm_our_key_dist = MYNEWT_VAL(BLE_SM_OUR_KEY_DIST),
     ble_hs_cfg.sm_their_key_dist = MYNEWT_VAL(BLE_SM_THEIR_KEY_DIST),
-
     ble_hs_cfg.sync_cb = on_sync;
     ble_hs_cfg.reset_cb = on_reset;
     ble_hs_cfg.shutdown_cb = on_reset; /*same callback as on_reset */
     ble_hs_cfg.gatts_register_cb = on_svr_register_cb;
     ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
-
     /* Initialize all packages. */
     nimble_port_init();
-
-
-
     /*Application levels code entry*/
-    tls_ble_gap_init(NULL);
+    tls_ble_gap_init();
     tls_bt_util_init();
-
     /*Initialize the vuart interface and enable controller*/
     ble_hci_vuart_init(uart_idx);
-
     /* As the last thing, process events from default event queue. */
     tls_nimble_start();
 
-    ble_system_state_on = true;
+    while(bt_adapter_state == WM_BT_STATE_OFF) {
+        tls_os_time_delay(10);
+    }
 
     return 0;
 }
@@ -201,43 +189,82 @@ tls_bt_deinit(void)
 {
     int rc = 0;
 
-    if(!ble_system_state_on)
-    {
+    if(bt_adapter_state == WM_BT_STATE_OFF) {
         return BLE_HS_EALREADY;
     }
+
+    if(bt_system_action != WM_BT_SYSTEM_ACTION_IDLE) { return BLE_HS_EBUSY; }
+
+    bt_system_action = WM_BT_SYSTEM_ACTION_DISABLING;
     /*Stop hs system*/
     rc = nimble_port_stop();
     assert(rc == 0);
-
     /*Stop controller and free vuart resource */
     rc = ble_hci_vuart_deinit();
     assert(rc == 0);
-
     /*Free hs system resource*/
     nimble_port_deinit();
-
     /*Free task stack ptr and free hs task*/
     tls_nimble_stop();
-
     /*Application levels resource cleanup*/
     tls_ble_gap_deinit();
     tls_bt_util_deinit();
 
-    ble_system_state_on = false;
+    while(bt_adapter_state == WM_BT_STATE_ON) {
+        tls_os_time_delay(10);
+    }
 
     return rc;
 }
 
+
+#define SYSTEM_SLEEP_ENABLE 0
+
+
+#if SYSTEM_SLEEP_ENABLE
+static void bt_pmu_timer1_irq(uint8_t *arg)
+{
+    tls_pmu_timer0_stop();
+    //tls_os_queue_send(app_schedule_queue, (void *)(uint32_t)APP_MSG_BLE_WAKEUPED, 4);
+}
+#endif
+
+
+void tls_bt_sleep_enter(uint32_t duration_ms)
+{
+    /**Do not do anything that blocking cpu running, eg. printf*/
+
+#if SYSTEM_SLEEP_ENABLE
+
+#define SLEEP_TO_WAKEUP_DELAY 7
+        /**Do not do printf here, blocking is forbidden*/ 
+    
+        if(duration_ms > 10)
+        {
+            tls_pmu_timer1_isr_register((tls_pmu_irq_callback)bt_pmu_timer1_irq, NULL);
+            tls_pmu_timer1_start((duration_ms-SLEEP_TO_WAKEUP_DELAY));
+            tls_pmu_sleep_start();
+        }
+#endif
+
+}
+
+void tls_bt_sleep_exit(void)
+{
+    /**Do not do anything that blocking cpu running, eg. printf*/
+}
+
 /*This function is called at wm_main.c*/
 void tls_bt_entry()
 {
-  //tls_bt_init(0x01);    //enable it if you want to turn on bluetooth after system booting
-  //tls_at_bt_enable(0xFF, 0);
+    //tls_bt_init(0xFF);    //enable it if you want to turn on bluetooth after system booting
+    //tls_bt_ctrl_sleep(true);
+    //tls_bt_register_sleep_callback(tls_bt_sleep_enter, tls_bt_sleep_exit);
 }
 
 void tls_bt_exit()
 {
-  //tls_bt_deinit();      //enable it if you want to turn off bluetooth when system reseting;
+    //tls_bt_deinit();      //enable it if you want to turn off bluetooth when system reseting;
 }
 
 
@@ -248,39 +275,34 @@ void tls_bt_exit()
 
 int tls_at_bt_enable(int uart_no, tls_bt_log_level_t log_level)
 {
-	int rc = 0;
-
-	tls_appl_trace_level = log_level;
-
-	TLS_BT_APPL_TRACE_VERBOSE("bt system running, uart_no=%d, log_level=%d\r\n", uart_no, log_level);
-
+    int rc = 0;
+    tls_appl_trace_level = log_level;
+    TLS_BT_APPL_TRACE_VERBOSE("bt system running, uart_no=%d, log_level=%d\r\n", uart_no, log_level);
     rc = tls_bt_init(uart_no);
 
-	if((rc != 0) &&(rc != BLE_HS_EALREADY) )
-	{
-		TLS_BT_APPL_TRACE_ERROR("tls_bt_enable, ret:%s,%d\r\n", tls_bt_rc_2_str(rc),rc);
-	}
+    if((rc != 0) && (rc != BLE_HS_EALREADY)) {
+        TLS_BT_APPL_TRACE_ERROR("tls_bt_enable, ret:%s,%d\r\n", tls_bt_rc_2_str(rc), rc);
+        return rc;
+    }
 
-	return rc;
+    return 0;
 }
 
 int tls_at_bt_destroy()
 {
-	int rc = 0;
-
-	TLS_BT_APPL_TRACE_VERBOSE("bt system destroy\r\n");
-
-	rc = tls_bt_deinit();
+    int rc = 0;
+    TLS_BT_APPL_TRACE_VERBOSE("bt system destroy\r\n");
+    rc = tls_bt_deinit();
 
-    if((rc != 0) && (rc != BLE_HS_EALREADY))
-	{
-		TLS_BT_APPL_TRACE_ERROR("tls_bt_disable, ret:%s,%d\r\n", tls_bt_rc_2_str(rc),rc);
-	}
+    if((rc != 0) && (rc != BLE_HS_EALREADY)) {
+        TLS_BT_APPL_TRACE_ERROR("tls_bt_disable, ret:%s,%d\r\n", tls_bt_rc_2_str(rc), rc);
+    }else
+    {
+        rc = 0;
+    }
 
-	return rc;
+    return rc;
 }
-
-
 /**
  * Called                        1) AT cmd; 2)demo show;
  *
@@ -295,63 +317,103 @@ int tls_ble_demo_adv(uint8_t type)
     int rc = 0;
     TLS_BT_APPL_TRACE_DEBUG("### %s type=%d\r\n", __FUNCTION__, type);
 
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
-        TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
-        return BLE_HS_EDISABLED;
-    }
-    if(type)
-    {
+    CHECK_SYSTEM_READY();
+
+    if(type) {
         uint8_t bt_mac[6] = {0};
-    	uint8_t adv_data[] = {
-               0x0C,0x09, 'W', 'M', '-', '0', '0', '0', '0', '0','0','0', '0',
-               0x02,0x01,0x05,
-               0x03,0x19,0xc1, 0x03};
+        uint8_t adv_data[] = {
+            0x0C, 0x09, 'W', 'M', '-', '0', '0', '0', '0', '0', '0', '0', '0',
+            0x02, 0x01, 0x05,
+            0x03, 0x19, 0xc1, 0x03
+        };
         extern int tls_get_bt_mac_addr(uint8_t *mac);
-
         tls_get_bt_mac_addr(bt_mac);
-        sprintf(adv_data+5,"%02X:%02X:%02X",bt_mac[3], bt_mac[4], bt_mac[5]);
+        sprintf((char *)adv_data + 5, "%02X:%02X:%02X", bt_mac[3], bt_mac[4], bt_mac[5]);
         adv_data[13] = 0x02;  //byte 13 was overwritten to zero by sprintf; recover it;
         rc = tls_ble_gap_set_data(WM_BLE_ADV_DATA, adv_data, 20);
-        switch(type)
-        {
+
+        switch(type) {
             case 1:
                 rc = tls_nimble_gap_adv(WM_BLE_ADV_IND, 0);
                 break;
+
             case 2:
+                rc = tls_nimble_gap_adv(WM_BLE_ADV_NONCONN_IND, 0);
+                break;
             default:
                 /*AT/DEMO cmd only support adv_ind mode*/
                 return BLE_HS_EINVAL;
         }
-
-    }else
-    {
+    } else {
         rc = tls_nimble_gap_adv(WM_BLE_ADV_STOP, 0);
     }
 
     return rc;
 }
 
+/**This funcation was used by at command at+blescan=1/0 only, */
+typedef void scan_resp_cb_fn(int type, int8_t rssi, uint8_t *addr, const uint8_t *name, int name_len, const uint8_t *raw_scan_resp, int raw_scan_resp_length);
+static scan_resp_cb_fn *p_scan_resp_cb = NULL;
+
+/**General gap event listener*/
+static struct ble_gap_event_listener ble_scan_event_listener;
+
 static int
 ble_gap_evt_cb(struct ble_gap_event *event, void *arg)
 {
-    struct ble_hs_adv_fields fields;
+    struct ble_hs_adv_fields fields = {0};
     int rc = 0;
-
-    switch (event->type) {
-    case BLE_GAP_EVENT_DISC:
-        rc = ble_hs_adv_parse_fields(&fields, event->disc.data,
-                                     event->disc.length_data);
-        if (rc != 0) {
+    int i = 0;
+    char adv_name[64];
+
+    switch(event->type) {
+        case BLE_GAP_EVENT_DISC:
+
+            rc = ble_hs_adv_parse_fields(&fields, event->disc.data,
+                                         event->disc.length_data);
+
+            if(rc != 0) {
+                return 0;
+            }
+#if 0
+
+            /* An advertisment report was received during GAP discovery. */
+            print_adv_fields(&fields);
+#endif 
+            /**check gap event triggered by at command first*/
+            if(p_scan_resp_cb)
+            {
+                p_scan_resp_cb(WM_BLE_GAP_EVENT_DISC, event->disc.rssi, event->disc.addr.val, fields.name, fields.name_len, event->disc.data,
+                                         event->disc.length_data);
+                return 0;
+            }
+
+            /**local gap event processing, only print the result*/
+            if(fields.name_len)
+            {
+                memcpy(adv_name, fields.name, fields.name_len);
+                adv_name[fields.name_len] = 0;
+                printf(">>>>>>name[%d]%s, rssi=%d\r\n", fields.name_len, adv_name, event->disc.rssi);
+            }
+            for(i = 0; i < event->disc.length_data; i++) {
+                printf("%02x", event->disc.data[i]);
+            }
+            printf("\r\n");
+            
             return 0;
-        }
-        /* An advertisment report was received during GAP discovery. */
-        print_adv_fields(&fields);
-        return 0;
-    case BLE_GAP_EVENT_DISC_COMPLETE:
-        break;
-    default:
-        break;
+
+        case BLE_GAP_EVENT_DISC_COMPLETE:
+            if(p_scan_resp_cb)
+            {
+                p_scan_resp_cb(WM_BLE_GAP_EVENT_DISC_COMPLETE, 0, NULL, NULL, 0, NULL,0);
+                return 0;
+            }            
+            break;
+        case BLE_GAP_EVENT_HOST_SHUTDOWN:
+            printf("Host is shutting down...\r\n");
+            break;
+        default:
+            break;
     }
 
     return rc;
@@ -369,120 +431,106 @@ ble_gap_evt_cb(struct ble_gap_event *event, void *arg)
 int tls_ble_demo_scan(uint8_t type)
 {
     int rc;
-
     TLS_BT_APPL_TRACE_DEBUG("### %s type=%d\r\n", __FUNCTION__, type);
 
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
-        TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
-        return BLE_HS_EDISABLED;
-    }
-    if(type)
-    {
-        tls_ble_register_gap_evt(WM_BLE_GAP_EVENT_DISC|WM_BLE_GAP_EVENT_DISC_COMPLETE, ble_gap_evt_cb);
+    CHECK_SYSTEM_READY();
+
+    if(type) {
+        ble_gap_event_listener_register(&ble_scan_event_listener,
+                            ble_gap_evt_cb, NULL);
         rc = tls_ble_gap_scan(WM_BLE_SCAN_PASSIVE, false);
-    }else
-    {
+    } else {
         rc = tls_ble_gap_scan(WM_BLE_SCAN_STOP, false);
-        tls_ble_deregister_gap_evt(WM_BLE_GAP_EVENT_DISC|WM_BLE_GAP_EVENT_DISC_COMPLETE,ble_gap_evt_cb );
+        ble_gap_event_listener_unregister(&ble_scan_event_listener);
     }
 
     return rc;
 }
 
+void tls_ble_demo_scan_at_cmd_register(scan_resp_cb_fn *cb)
+{
+    TLS_BT_APPL_TRACE_DEBUG("### %s type=%d\r\n", __FUNCTION__);
+    ble_gap_event_listener_register(&ble_scan_event_listener,
+                        ble_gap_evt_cb, NULL);    
+    p_scan_resp_cb = cb; 
+}
+void tls_ble_demo_scan_at_cmd_unregister()
+{
+    TLS_BT_APPL_TRACE_DEBUG("### %s type=%d\r\n", __FUNCTION__);
+    p_scan_resp_cb = NULL;
+    ble_gap_event_listener_unregister(&ble_scan_event_listener);
+}
 
 /*
 *bluetooth api demo
 */
 int demo_bt_enable()
 {
-	int rc;
+    int rc;
     uint8_t uart_no = 0xFF;
+    tls_appl_trace_level = TLS_BT_LOG_VERBOSE;
 
-	tls_appl_trace_level = TLS_BT_LOG_VERBOSE;
-
-    if(bt_adapter_state == WM_BT_STATE_ON)
-    {
-       TLS_BT_APPL_TRACE_VERBOSE("bt system enable already");
-       return TLS_BT_STATUS_SUCCESS;
+    if(bt_adapter_state == WM_BT_STATE_ON) {
+        TLS_BT_APPL_TRACE_VERBOSE("bt system enable already");
+        return TLS_BT_STATUS_SUCCESS;
     }
 
-	TLS_BT_APPL_TRACE_DEBUG("bt system running, uart_no=%d, log_level=%d\r\n", uart_no, tls_appl_trace_level);
-
+    TLS_BT_APPL_TRACE_DEBUG("bt system running, uart_no=%d, log_level=%d\r\n", uart_no,
+                            tls_appl_trace_level);
     rc = tls_bt_init(uart_no);
 
-	if((rc != 0) &&(rc != BLE_HS_EALREADY) )
-	{
-		TLS_BT_APPL_TRACE_ERROR("demo_bt_enable, ret:%s,%d\r\n", tls_bt_rc_2_str(rc),rc);
-	}
+    if((rc != 0) && (rc != BLE_HS_EALREADY)) {
+        TLS_BT_APPL_TRACE_ERROR("demo_bt_enable, ret:%s,%d\r\n", tls_bt_rc_2_str(rc), rc);
+    }
 
-	return rc;
+    return rc;
 }
 
 int demo_bt_destroy()
 {
-	int rc;
-
-	TLS_BT_APPL_TRACE_DEBUG("bt system destroy\r\n");
+    int rc;
+    TLS_BT_APPL_TRACE_DEBUG("bt system destroy\r\n");
 
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
-       TLS_BT_APPL_TRACE_VERBOSE("bt system destroyed already");
-       return TLS_BT_STATUS_SUCCESS;
+    if(bt_adapter_state == WM_BT_STATE_OFF) {
+        TLS_BT_APPL_TRACE_VERBOSE("bt system destroyed already");
+        return TLS_BT_STATUS_SUCCESS;
     }
 
-	rc = tls_bt_deinit();
+    rc = tls_bt_deinit();
 
-    if((rc != 0) && (rc != BLE_HS_EALREADY))
-	{
-		TLS_BT_APPL_TRACE_ERROR("demo_bt_destroy, ret:%s,%d\r\n", tls_bt_rc_2_str(rc),rc);
-	}
+    if((rc != 0) && (rc != BLE_HS_EALREADY)) {
+        TLS_BT_APPL_TRACE_ERROR("demo_bt_destroy, ret:%s,%d\r\n", tls_bt_rc_2_str(rc), rc);
+    }
 
-	return rc;
+    return rc;
 }
 
 int demo_ble_server_on()
 {
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
-       TLS_BT_APPL_TRACE_VERBOSE("please enable bluetooth system first\r\n");
-       return -1;
-    }
-    tls_ble_server_demo_api_init(NULL);
+    CHECK_SYSTEM_READY();
+
+    tls_ble_server_demo_api_init(NULL,NULL);
     return 0;
 }
 int demo_ble_server_off()
 {
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
-       TLS_BT_APPL_TRACE_VERBOSE("bluetooth system stopped\r\n");
-       return -1;
-    }
+    CHECK_SYSTEM_READY();
 
     tls_ble_server_demo_api_deinit();
-
     return 0;
 }
 int demo_ble_client_on()
 {
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
-       TLS_BT_APPL_TRACE_VERBOSE("please enable bluetooth system first\r\n");
-       return -1;
-    }
-    tls_ble_client_demo_api_init(NULL);
+    CHECK_SYSTEM_READY();
+
+    tls_ble_client_demo_api_init(NULL,NULL);
     return 0;
 }
 int demo_ble_client_off()
 {
-    if(bt_adapter_state == WM_BT_STATE_OFF)
-    {
-       TLS_BT_APPL_TRACE_VERBOSE("bluetooth system stopped\r\n");
-       return -1;
-    }
+    CHECK_SYSTEM_READY();
 
     tls_ble_client_demo_api_deinit();
-
     return 0;
 }
 

+ 29 - 0
src/app/bleapp/wm_bt_app.h

@@ -10,5 +10,34 @@
 *****************************************************************************/
 #include "wm_bt.h"
 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef enum {
+    WM_BT_SYSTEM_ACTION_IDLE,
+    WM_BT_SYSTEM_ACTION_ENABLING,
+    WM_BT_SYSTEM_ACTION_DISABLING
+} bt_system_action_t;
+
 extern volatile tls_bt_state_t bt_adapter_state;
+extern volatile bt_system_action_t bt_system_action;
+
+#define CHECK_SYSTEM_READY()    \
+    do{                         \
+        if(bt_adapter_state == WM_BT_STATE_OFF || bt_system_action != WM_BT_SYSTEM_ACTION_IDLE) \
+        {                                                                                       \
+            TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));    \
+            return BLE_HS_EDISABLED;                                                            \
+        }                                                                                       \
+      }while(0)
+
+#ifdef __cplusplus
+        }
+#endif
+
+        
+
 #endif

+ 130 - 156
src/app/bleapp/wm_bt_util.c

@@ -31,94 +31,82 @@ typedef struct {
     void *priv_data;
 } async_evt_t;
 
-typedef struct
-{
+typedef struct {
     async_evt_t *evt;
     app_async_func_t *func;
-    void *arg;    
+    void *arg;
 } ble_async_t;
 
 
 static async_evt_t  async_evt_list;
 
-tls_bt_log_level_t tls_appl_trace_level =  TLS_BT_LOG_VERBOSE;
+tls_bt_log_level_t tls_appl_trace_level =  TLS_BT_LOG_NONE;
 
 
 void tls_bt_log(uint32_t level, const char *fmt_str, ...)
 {
-
-	u32 time = tls_os_get_time();
-    u32 hour,min,second,ms = 0;
-
-    second = time/HZ;
-    ms = (time%HZ)*2;
-    hour = second/3600;
-    min = (second%3600)/60;
-    second = (second%3600)%60;
-
-    if(level==TLS_TRACE_TYPE_ERROR)
-    {
-    	printf("[WM_E] <%d:%02d:%02d.%03d> ",hour,min, second, ms);
-		
-    }else if(level==TLS_TRACE_TYPE_WARNING)
-    {
-    	printf("[WM_W] <%d:%02d:%02d.%03d> ",hour,min, second, ms);
-    }else
-    {
-    	printf("[WM_I] <%d:%02d:%02d.%03d> ",hour,min, second, ms);
+    u32 time = tls_os_get_time();
+    u32 hour, min, second, ms = 0;
+    second = time / HZ;
+    ms = (time % HZ) * 2;
+    hour = second / 3600;
+    min = (second % 3600) / 60;
+    second = (second % 3600) % 60;
+
+    if(level == TLS_TRACE_TYPE_ERROR) {
+        printf("[WM_E] <%d:%02d:%02d.%03d> ", hour, min, second, ms);
+    } else if(level == TLS_TRACE_TYPE_WARNING) {
+        printf("[WM_W] <%d:%02d:%02d.%03d> ", hour, min, second, ms);
+    } else {
+        printf("[WM_I] <%d:%02d:%02d.%03d> ", hour, min, second, ms);
     }
 
-    if(1)
-    {
+    if(1) {
         va_list args;
         /* printf args */
         va_start(args, fmt_str);
         vprintf(fmt_str, args);
         va_end(args);
-
-    }
-    else
-    {
+    } else {
         return;
     }
-
 }
 
 #ifndef CASE_RETURN_STR
-    #define CASE_RETURN_STR(const) case const: return #const;
+#define CASE_RETURN_STR(const) case const: return #const;
 #endif
 
 const char *tls_bt_gap_evt_2_str(uint32_t event)
 {
-	switch(event)
-	{
-		CASE_RETURN_STR(BLE_GAP_EVENT_CONNECT)
-		CASE_RETURN_STR(BLE_GAP_EVENT_DISCONNECT)
-		CASE_RETURN_STR(BLE_GAP_EVENT_CONN_UPDATE)
-		CASE_RETURN_STR(BLE_GAP_EVENT_CONN_UPDATE_REQ)
-		CASE_RETURN_STR(BLE_GAP_EVENT_L2CAP_UPDATE_REQ)
-		CASE_RETURN_STR(BLE_GAP_EVENT_TERM_FAILURE)
-		CASE_RETURN_STR(BLE_GAP_EVENT_DISC)
-		CASE_RETURN_STR(BLE_GAP_EVENT_DISC_COMPLETE)
-		CASE_RETURN_STR(BLE_GAP_EVENT_ADV_COMPLETE)
-		CASE_RETURN_STR(BLE_GAP_EVENT_ENC_CHANGE)
-		CASE_RETURN_STR(BLE_GAP_EVENT_PASSKEY_ACTION)
-		CASE_RETURN_STR(BLE_GAP_EVENT_NOTIFY_RX)
-        CASE_RETURN_STR(BLE_GAP_EVENT_NOTIFY_TX)
-        CASE_RETURN_STR(BLE_GAP_EVENT_SUBSCRIBE)
-        CASE_RETURN_STR(BLE_GAP_EVENT_MTU)
-        CASE_RETURN_STR(BLE_GAP_EVENT_IDENTITY_RESOLVED)
-        CASE_RETURN_STR(BLE_GAP_EVENT_REPEAT_PAIRING)
-        CASE_RETURN_STR(BLE_GAP_EVENT_PHY_UPDATE_COMPLETE)
-        CASE_RETURN_STR(BLE_GAP_EVENT_EXT_DISC)
-        CASE_RETURN_STR(BLE_GAP_EVENT_PERIODIC_SYNC)
-        CASE_RETURN_STR(BLE_GAP_EVENT_PERIODIC_REPORT)
-		CASE_RETURN_STR(BLE_GAP_EVENT_PERIODIC_SYNC_LOST)
-		CASE_RETURN_STR(BLE_GAP_EVENT_SCAN_REQ_RCVD)	
-	    CASE_RETURN_STR(BLE_GAP_EVENT_PERIODIC_TRANSFER)
-		default:
-			return "unkown bt host evt";
-	}
+    switch(event) {
+            CASE_RETURN_STR(BLE_GAP_EVENT_CONNECT)
+            CASE_RETURN_STR(BLE_GAP_EVENT_DISCONNECT)
+            CASE_RETURN_STR(BLE_GAP_EVENT_CONN_UPDATE)
+            CASE_RETURN_STR(BLE_GAP_EVENT_CONN_UPDATE_REQ)
+            CASE_RETURN_STR(BLE_GAP_EVENT_L2CAP_UPDATE_REQ)
+            CASE_RETURN_STR(BLE_GAP_EVENT_TERM_FAILURE)
+            CASE_RETURN_STR(BLE_GAP_EVENT_DISC)
+            CASE_RETURN_STR(BLE_GAP_EVENT_DISC_COMPLETE)
+            CASE_RETURN_STR(BLE_GAP_EVENT_ADV_COMPLETE)
+            CASE_RETURN_STR(BLE_GAP_EVENT_ENC_CHANGE)
+            CASE_RETURN_STR(BLE_GAP_EVENT_PASSKEY_ACTION)
+            CASE_RETURN_STR(BLE_GAP_EVENT_NOTIFY_RX)
+            CASE_RETURN_STR(BLE_GAP_EVENT_NOTIFY_TX)
+            CASE_RETURN_STR(BLE_GAP_EVENT_SUBSCRIBE)
+            CASE_RETURN_STR(BLE_GAP_EVENT_MTU)
+            CASE_RETURN_STR(BLE_GAP_EVENT_IDENTITY_RESOLVED)
+            CASE_RETURN_STR(BLE_GAP_EVENT_REPEAT_PAIRING)
+            CASE_RETURN_STR(BLE_GAP_EVENT_PHY_UPDATE_COMPLETE)
+            CASE_RETURN_STR(BLE_GAP_EVENT_EXT_DISC)
+            CASE_RETURN_STR(BLE_GAP_EVENT_PERIODIC_SYNC)
+            CASE_RETURN_STR(BLE_GAP_EVENT_PERIODIC_REPORT)
+            CASE_RETURN_STR(BLE_GAP_EVENT_PERIODIC_SYNC_LOST)
+            CASE_RETURN_STR(BLE_GAP_EVENT_SCAN_REQ_RCVD)
+            CASE_RETURN_STR(BLE_GAP_EVENT_PERIODIC_TRANSFER)
+
+        default:
+            return "unkown bt host evt";
+    }
 }
 
 
@@ -126,60 +114,56 @@ const char *tls_bt_gap_evt_2_str(uint32_t event)
 
 const char *tls_bt_rc_2_str(uint32_t event)
 {
-    switch(event)
-    {
-        CASE_RETURN_STR(BLE_HS_ENOERR)
-        CASE_RETURN_STR(BLE_HS_EAGAIN)
-        CASE_RETURN_STR(BLE_HS_EALREADY)
-        CASE_RETURN_STR(BLE_HS_EINVAL)
-        CASE_RETURN_STR(BLE_HS_EMSGSIZE)
-        CASE_RETURN_STR(BLE_HS_ENOENT)
-        CASE_RETURN_STR(BLE_HS_ENOMEM)
-        CASE_RETURN_STR(BLE_HS_ENOTCONN)
-        CASE_RETURN_STR(BLE_HS_ENOTSUP)
-		CASE_RETURN_STR(BLE_HS_EAPP)
-		CASE_RETURN_STR(BLE_HS_EBADDATA)
-		CASE_RETURN_STR(BLE_HS_EOS)
-		CASE_RETURN_STR(BLE_HS_ECONTROLLER)
-		CASE_RETURN_STR(BLE_HS_ETIMEOUT)
-		CASE_RETURN_STR(BLE_HS_EDONE)
-		CASE_RETURN_STR(BLE_HS_EBUSY)
-		CASE_RETURN_STR(BLE_HS_EREJECT)
-		CASE_RETURN_STR(BLE_HS_EUNKNOWN)
-		CASE_RETURN_STR(BLE_HS_EROLE)
-		CASE_RETURN_STR(BLE_HS_ETIMEOUT_HCI)
-		CASE_RETURN_STR(BLE_HS_ENOMEM_EVT)
-		CASE_RETURN_STR(BLE_HS_ENOADDR)
-		CASE_RETURN_STR(BLE_HS_ENOTSYNCED)
-		CASE_RETURN_STR(BLE_HS_EAUTHEN)
-		CASE_RETURN_STR(BLE_HS_EAUTHOR)
-		CASE_RETURN_STR(BLE_HS_EENCRYPT)
-		CASE_RETURN_STR(BLE_HS_EENCRYPT_KEY_SZ)
-		CASE_RETURN_STR(BLE_HS_ESTORE_CAP)
-		CASE_RETURN_STR(BLE_HS_ESTORE_FAIL)
-		CASE_RETURN_STR(BLE_HS_EPREEMPTED)
-		CASE_RETURN_STR(BLE_HS_EDISABLED)
-		CASE_RETURN_STR(BLE_HS_ESTALLED)
-        
+    switch(event) {
+            CASE_RETURN_STR(BLE_HS_ENOERR)
+            CASE_RETURN_STR(BLE_HS_EAGAIN)
+            CASE_RETURN_STR(BLE_HS_EALREADY)
+            CASE_RETURN_STR(BLE_HS_EINVAL)
+            CASE_RETURN_STR(BLE_HS_EMSGSIZE)
+            CASE_RETURN_STR(BLE_HS_ENOENT)
+            CASE_RETURN_STR(BLE_HS_ENOMEM)
+            CASE_RETURN_STR(BLE_HS_ENOTCONN)
+            CASE_RETURN_STR(BLE_HS_ENOTSUP)
+            CASE_RETURN_STR(BLE_HS_EAPP)
+            CASE_RETURN_STR(BLE_HS_EBADDATA)
+            CASE_RETURN_STR(BLE_HS_EOS)
+            CASE_RETURN_STR(BLE_HS_ECONTROLLER)
+            CASE_RETURN_STR(BLE_HS_ETIMEOUT)
+            CASE_RETURN_STR(BLE_HS_EDONE)
+            CASE_RETURN_STR(BLE_HS_EBUSY)
+            CASE_RETURN_STR(BLE_HS_EREJECT)
+            CASE_RETURN_STR(BLE_HS_EUNKNOWN)
+            CASE_RETURN_STR(BLE_HS_EROLE)
+            CASE_RETURN_STR(BLE_HS_ETIMEOUT_HCI)
+            CASE_RETURN_STR(BLE_HS_ENOMEM_EVT)
+            CASE_RETURN_STR(BLE_HS_ENOADDR)
+            CASE_RETURN_STR(BLE_HS_ENOTSYNCED)
+            CASE_RETURN_STR(BLE_HS_EAUTHEN)
+            CASE_RETURN_STR(BLE_HS_EAUTHOR)
+            CASE_RETURN_STR(BLE_HS_EENCRYPT)
+            CASE_RETURN_STR(BLE_HS_EENCRYPT_KEY_SZ)
+            CASE_RETURN_STR(BLE_HS_ESTORE_CAP)
+            CASE_RETURN_STR(BLE_HS_ESTORE_FAIL)
+            CASE_RETURN_STR(BLE_HS_EPREEMPTED)
+            CASE_RETURN_STR(BLE_HS_EDISABLED)
+            CASE_RETURN_STR(BLE_HS_ESTALLED)
+
         default:
-        	return "unknown tls_bt_status";
+            return "unknown tls_bt_status";
     }
 }
-	
+
 
 
 static void async_evt_func(struct ble_npl_event *ev)
 {
-    ble_async_t *bat = (ble_async_t*)ev->arg;
+    ble_async_t *bat = (ble_async_t *)ev->arg;
     async_evt_t *aet = (async_evt_t *)bat->evt;
-
     bat->func(bat->arg);
-
     //free timer;
     ble_npl_callout_deinit(&aet->co);
-
     //remove from list;
-    ble_npl_mutex_pend(&async_evt_list.list_mutex, 0);   
+    ble_npl_mutex_pend(&async_evt_list.list_mutex, 0);
     dl_list_del(&aet->list);
     ble_npl_mutex_release(&async_evt_list.list_mutex);
     //free aysnc_evt;
@@ -192,26 +176,24 @@ static void async_evt_func(struct ble_npl_event *ev)
 
 static void tls_ble_free_left_aysnc_list()
 {
-	async_evt_t *evt = NULL;
-	async_evt_t *evt_next = NULL;	
+    async_evt_t *evt = NULL;
+    async_evt_t *evt_next = NULL;
 
-	if(dl_list_empty(&async_evt_list.list))
-		return ;
-	
-	ble_npl_mutex_pend(&async_evt_list.list_mutex, 0);
+    if(dl_list_empty(&async_evt_list.list))
+    { return ; }
 
-	dl_list_for_each_safe(evt, evt_next,&async_evt_list.list, async_evt_t, list)
-	{
-	    if(ble_npl_callout_is_active(&evt->co)){
+    ble_npl_mutex_pend(&async_evt_list.list_mutex, 0);
+    dl_list_for_each_safe(evt, evt_next, &async_evt_list.list, async_evt_t, list) {
+        if(ble_npl_callout_is_active(&evt->co)) {
             ble_npl_callout_stop(&evt->co);
         }
+
         ble_npl_callout_deinit(&evt->co);
-		dl_list_del(&evt->list);
+        dl_list_del(&evt->list);
         tls_mem_free(evt->priv_data);
-		tls_mem_free(evt);
-	}
-
-	ble_npl_mutex_release(&async_evt_list.list_mutex);    
+        tls_mem_free(evt);
+    }
+    ble_npl_mutex_release(&async_evt_list.list_mutex);
 }
 
 int tls_bt_util_deinit(void)
@@ -219,17 +201,17 @@ int tls_bt_util_deinit(void)
     /*Do not forget to release  async event list*/
     tls_ble_free_left_aysnc_list();
     ble_npl_mutex_deinit(&async_evt_list.list_mutex);
-
     return 0;
 }
 
 int tls_bt_util_init(void)
 {
-    dl_list_init(&async_evt_list);
+    dl_list_init(&async_evt_list.list);
     ble_npl_mutex_init(&async_evt_list.list_mutex);
+    return 0;
 }
 
-tls_bt_status_t tls_bt_async_proc_func(app_async_func_t *app_cb, void *app_arg, int ticks)
+int tls_bt_async_proc_func(app_async_func_t *app_cb, void *app_arg, int ticks)
 {
     async_evt_t *aet = (async_evt_t *)tls_mem_alloc(sizeof(async_evt_t));
     assert(aet != NULL);
@@ -238,16 +220,14 @@ tls_bt_status_t tls_bt_async_proc_func(app_async_func_t *app_cb, void *app_arg,
     bat->evt = aet;
     bat->func = app_cb;
     bat->arg = app_arg;
-
     /*remember the ble_async ptr, in case the timer is running, when do all reset.we can free it, see ble_svc_deinit*/
-    aet->priv_data = (void*)bat;
-
+    aet->priv_data = (void *)bat;
     ble_npl_mutex_pend(&async_evt_list.list_mutex, 0);
     dl_list_add_tail(&async_evt_list.list, &aet->list);
     ble_npl_mutex_release(&async_evt_list.list_mutex);
-    
-    ble_npl_callout_init(&aet->co, nimble_port_get_dflt_eventq(), async_evt_func, (void*)bat);
-    ble_npl_callout_reset(&aet->co,ticks);
+    ble_npl_callout_init(&aet->co, nimble_port_get_dflt_eventq(), async_evt_func, (void *)bat);
+    ble_npl_callout_reset(&aet->co, ticks);
+    return 0;
 }
 
 
@@ -258,15 +238,16 @@ ringbuffer_t *bt_ringbuffer_init(const size_t size)
     p->base = tls_mem_alloc(size);
     p->head = p->tail = p->base;
     p->total = p->available = size;
+    ble_npl_mutex_init(&p->buffer_mutex);
     return p;
 }
 
 void bt_ringbuffer_free(ringbuffer_t *rb)
 {
-    if(rb != NULL)
-    {
+    if(rb != NULL) {
         tls_mem_free(rb->base);
     }
+    ble_npl_mutex_deinit(&rb->buffer_mutex);
 
     tls_mem_free(rb);
 }
@@ -285,47 +266,42 @@ uint32_t bt_ringbuffer_insert(ringbuffer_t *rb, const uint8_t *p, uint32_t lengt
 {
     assert(rb);
     assert(p);
-    uint32_t cpu_sr = tls_os_set_critical();
+    ble_npl_mutex_pend(&rb->buffer_mutex, 0);
 
-    if(length > bt_ringbuffer_available(rb))
-    {
+    if(length > bt_ringbuffer_available(rb)) {
         length = bt_ringbuffer_available(rb);
     }
 
-    for(size_t i = 0; i != length; ++i)
-    {
+    for(size_t i = 0; i != length; ++i) {
         *rb->tail++ = *p++;
 
-        if(rb->tail >= (rb->base + rb->total))
-        {
+        if(rb->tail >= (rb->base + rb->total)) {
             rb->tail = rb->base;
         }
     }
 
     rb->available -= length;
-    tls_os_release_critical(cpu_sr);
+    ble_npl_mutex_release(&rb->buffer_mutex);
     return length;
 }
 
 uint32_t bt_ringbuffer_delete(ringbuffer_t *rb, uint32_t length)
 {
     assert(rb);
-    uint32_t cpu_sr = tls_os_set_critical();
+    ble_npl_mutex_pend(&rb->buffer_mutex, 0);
 
-    if(length > bt_ringbuffer_size(rb))
-    {
+    if(length > bt_ringbuffer_size(rb)) {
         length = bt_ringbuffer_size(rb);
     }
 
     rb->head += length;
 
-    if(rb->head >= (rb->base + rb->total))
-    {
+    if(rb->head >= (rb->base + rb->total)) {
         rb->head -= rb->total;
     }
 
     rb->available += length;
-    tls_os_release_critical(cpu_sr);
+    ble_npl_mutex_release(&rb->buffer_mutex);
     return length;
 }
 
@@ -334,21 +310,21 @@ uint32_t bt_ringbuffer_peek(const ringbuffer_t *rb, int offset, uint8_t *p, uint
     assert(rb);
     assert(p);
     assert(offset >= 0);
-    uint32_t cpu_sr = tls_os_set_critical();
+    ble_npl_mutex_pend((struct ble_npl_mutex *)&rb->buffer_mutex, 0);
     assert((uint32_t)offset <= bt_ringbuffer_size(rb));
     uint8_t *b = ((rb->head - rb->base + offset) % rb->total) + rb->base;
-    const size_t bytes_to_copy = (offset + length > bt_ringbuffer_size(rb)) ? bt_ringbuffer_size(rb) - offset : length;
+    const size_t bytes_to_copy = (offset + length > bt_ringbuffer_size(rb)) ? bt_ringbuffer_size(
+            rb) - offset : length;
 
-    for(size_t copied = 0; copied < bytes_to_copy; ++copied)
-    {
+    for(size_t copied = 0; copied < bytes_to_copy; ++copied) {
         *p++ = *b++;
 
-        if(b >= (rb->base + rb->total))
-        {
+        if(b >= (rb->base + rb->total)) {
             b = rb->base;
         }
     }
-    tls_os_release_critical(cpu_sr);
+
+    ble_npl_mutex_release((struct ble_npl_mutex *)&rb->buffer_mutex);
     return bytes_to_copy;
 }
 
@@ -356,18 +332,17 @@ uint32_t bt_ringbuffer_pop(ringbuffer_t *rb, uint8_t *p, uint32_t length)
 {
     assert(rb);
     assert(p);
-    uint32_t cpu_sr = tls_os_set_critical();  
-    const uint32_t copied = bt_ringbuffer_peek(rb, 0, p, length);
     
+    const uint32_t copied = bt_ringbuffer_peek(rb, 0, p, length);
+    ble_npl_mutex_pend((struct ble_npl_mutex *)&rb->buffer_mutex, 0);
     rb->head += copied;
 
-    if(rb->head >= (rb->base + rb->total))
-    {
+    if(rb->head >= (rb->base + rb->total)) {
         rb->head -= rb->total;
     }
 
     rb->available += copied;
-    tls_os_release_critical(cpu_sr);
+    ble_npl_mutex_release((struct ble_npl_mutex *)&rb->buffer_mutex);
     return copied;
 }
 
@@ -381,8 +356,7 @@ uint8_t string_to_bdaddr(const char *string, tls_bt_addr_t *addr)
     uint8_t ret = sscanf(string, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
                          &ptr[0], &ptr[1], &ptr[2], &ptr[3], &ptr[4], &ptr[5]) == 6;
 
-    if(ret)
-    {
+    if(ret) {
         memcpy(addr, &new_addr, sizeof(tls_bt_addr_t));
     }
 

+ 22 - 11
src/app/bleapp/wm_bt_util.h

@@ -2,6 +2,11 @@
 #define __WM_BT_UTIL_H__
 #include <stdint.h>
 #include "wm_bt_def.h"
+#include "host/ble_hs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 #define TLS_TRACE_TYPE_ERROR            0x00000000
 #define TLS_TRACE_TYPE_WARNING          0x00000001
@@ -9,13 +14,13 @@
 #define TLS_TRACE_TYPE_EVENT            0x00000003
 #define TLS_TRACE_TYPE_DEBUG            0x00000004
 
-typedef struct 
-{
+typedef struct {
     uint32_t total;
     uint32_t available;
     uint8_t *base;
     uint8_t *head;
     uint8_t *tail;
+    struct ble_npl_mutex buffer_mutex;
 } ringbuffer_t;
 
 typedef void (app_async_func_t)(void *arg);
@@ -29,16 +34,16 @@ extern tls_bt_log_level_t tls_appl_trace_level;
 
 /* define log for application */
 #if 1
-#define TLS_BT_APPL_TRACE_ERROR(...)				 {if (tls_appl_trace_level >= TLS_BT_LOG_ERROR) tls_bt_log(TLS_TRACE_TYPE_ERROR, ##__VA_ARGS__);}
-#define TLS_BT_APPL_TRACE_WARNING(...) 				 {if (tls_appl_trace_level >= TLS_BT_LOG_WARNING) tls_bt_log(TLS_TRACE_TYPE_WARNING, ##__VA_ARGS__);}
-#define TLS_BT_APPL_TRACE_API(...) 					 {if (tls_appl_trace_level >= TLS_BT_LOG_API) tls_bt_log( TLS_TRACE_TYPE_API, ##__VA_ARGS__);}
-#define TLS_BT_APPL_TRACE_EVENT(...)			     {if (tls_appl_trace_level >= TLS_BT_LOG_EVENT) tls_bt_log(TLS_TRACE_TYPE_EVENT, ##__VA_ARGS__);}
-#define TLS_BT_APPL_TRACE_DEBUG(...)				 {if (tls_appl_trace_level >= TLS_BT_LOG_DEBUG) tls_bt_log(TLS_TRACE_TYPE_DEBUG, ##__VA_ARGS__);}
-#define TLS_BT_APPL_TRACE_VERBOSE(...) 				 {if (tls_appl_trace_level >= TLS_BT_LOG_VERBOSE) tls_bt_log(TLS_TRACE_TYPE_DEBUG, ##__VA_ARGS__);}
+#define TLS_BT_APPL_TRACE_ERROR(...)                 {if (tls_appl_trace_level >= TLS_BT_LOG_ERROR) tls_bt_log(TLS_TRACE_TYPE_ERROR, ##__VA_ARGS__);}
+#define TLS_BT_APPL_TRACE_WARNING(...)               {if (tls_appl_trace_level >= TLS_BT_LOG_WARNING) tls_bt_log(TLS_TRACE_TYPE_WARNING, ##__VA_ARGS__);}
+#define TLS_BT_APPL_TRACE_API(...)                   {if (tls_appl_trace_level >= TLS_BT_LOG_API) tls_bt_log( TLS_TRACE_TYPE_API, ##__VA_ARGS__);}
+#define TLS_BT_APPL_TRACE_EVENT(...)                 {if (tls_appl_trace_level >= TLS_BT_LOG_EVENT) tls_bt_log(TLS_TRACE_TYPE_EVENT, ##__VA_ARGS__);}
+#define TLS_BT_APPL_TRACE_DEBUG(...)                 {if (tls_appl_trace_level >= TLS_BT_LOG_DEBUG) tls_bt_log(TLS_TRACE_TYPE_DEBUG, ##__VA_ARGS__);}
+#define TLS_BT_APPL_TRACE_VERBOSE(...)               {if (tls_appl_trace_level >= TLS_BT_LOG_VERBOSE) tls_bt_log(TLS_TRACE_TYPE_DEBUG, ##__VA_ARGS__);}
 #else
 #define TLS_BT_APPL_TRACE_ERROR(...)
 #define TLS_BT_APPL_TRACE_WARNING(...)
-#define TLS_BT_APPL_TRACE_API(...) 
+#define TLS_BT_APPL_TRACE_API(...)
 #define TLS_BT_APPL_TRACE_EVENT(...)
 #define TLS_BT_APPL_TRACE_DEBUG(...)
 #define TLS_BT_APPL_TRACE_VERBOSE(...)
@@ -49,14 +54,20 @@ void tls_bt_log(uint32_t trace_set_mask, const char *fmt_str, ...);
 const char *tls_bt_gap_evt_2_str(uint32_t event);
 const char *tls_bt_rc_2_str(uint32_t event);
 
-extern tls_bt_status_t tls_bt_async_proc_func(app_async_func_t *app_cb, void *app_arg, int ticks);
+extern int tls_bt_util_init(void);
+extern int tls_bt_util_deinit(void);
+extern int tls_bt_async_proc_func(app_async_func_t *app_cb, void *app_arg, int ticks);
 extern ringbuffer_t *bt_ringbuffer_init(const size_t size);
 extern void bt_ringbuffer_free(ringbuffer_t *rb);
 extern uint32_t bt_ringbuffer_available(const ringbuffer_t *rb);
-extern uint32_t bt_bt_ringbuffer_size(const ringbuffer_t *rb);
+extern uint32_t bt_ringbuffer_size(const ringbuffer_t *rb);
 extern uint32_t bt_ringbuffer_insert(ringbuffer_t *rb, const uint8_t *p, uint32_t length);
 extern uint32_t bt_ringbuffer_delete(ringbuffer_t *rb, uint32_t length);
 extern uint32_t bt_ringbuffer_peek(const ringbuffer_t *rb, int offset, uint8_t *p, uint32_t length);
 extern uint32_t bt_ringbuffer_pop(ringbuffer_t *rb, uint8_t *p, uint32_t length);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif

+ 17 - 17
src/bt/blehost/ext/tinycrypt/include/tinycrypt/cmac_mode.h

@@ -110,22 +110,22 @@ extern "C" {
 
 /* struct tc_cmac_struct represents the state of a CMAC computation */
 typedef struct tc_cmac_struct {
-/* initialization vector */
-	uint8_t iv[TC_AES_BLOCK_SIZE];
-/* used if message length is a multiple of block_size bytes */
-	uint8_t K1[TC_AES_BLOCK_SIZE];
-/* used if message length isn't a multiple block_size bytes */
-	uint8_t K2[TC_AES_BLOCK_SIZE];
-/* where to put bytes that didn't fill a block */
-	uint8_t leftover[TC_AES_BLOCK_SIZE];
-/* identifies the encryption key */
-	unsigned int keyid;
-/* next available leftover location */
-	unsigned int leftover_offset;
-/* AES key schedule */
-	TCAesKeySched_t sched;
-/* calls to tc_cmac_update left before re-key */
-	uint64_t countdown;
+    /* initialization vector */
+    uint8_t iv[TC_AES_BLOCK_SIZE];
+    /* used if message length is a multiple of block_size bytes */
+    uint8_t K1[TC_AES_BLOCK_SIZE];
+    /* used if message length isn't a multiple block_size bytes */
+    uint8_t K2[TC_AES_BLOCK_SIZE];
+    /* where to put bytes that didn't fill a block */
+    uint8_t leftover[TC_AES_BLOCK_SIZE];
+    /* identifies the encryption key */
+    unsigned int keyid;
+    /* next available leftover location */
+    unsigned int leftover_offset;
+    /* AES key schedule */
+    TCAesKeySched_t sched;
+    /* calls to tc_cmac_update left before re-key */
+    uint64_t countdown;
 } *TCCmacState_t;
 
 /**
@@ -140,7 +140,7 @@ typedef struct tc_cmac_struct {
  * @param sched IN -- AES key schedule
  */
 int tc_cmac_setup(TCCmacState_t s, const uint8_t *key,
-		      TCAesKeySched_t sched);
+                  TCAesKeySched_t sched);
 
 /**
  * @brief Erases the CMAC state

+ 1 - 1
src/bt/blehost/ext/tinycrypt/include/tinycrypt/ctr_mode.h

@@ -99,7 +99,7 @@ extern "C" {
  * @param sched IN -- an initialized AES key schedule
  */
 int tc_ctr_mode(uint8_t *out, unsigned int outlen, const uint8_t *in,
-		unsigned int inlen, uint8_t *ctr, const TCAesKeySched_t sched);
+                unsigned int inlen, uint8_t *ctr, const TCAesKeySched_t sched);
 
 #ifdef __cplusplus
 }

+ 22 - 22
src/bt/blehost/ext/tinycrypt/include/tinycrypt/ctr_prng.h

@@ -68,14 +68,14 @@ extern "C" {
 #endif
 
 typedef struct {
-	/* updated each time another BLOCKLEN_BYTES bytes are produced */
-	uint8_t V[TC_AES_BLOCK_SIZE]; 
+    /* updated each time another BLOCKLEN_BYTES bytes are produced */
+    uint8_t V[TC_AES_BLOCK_SIZE];
 
-	/* updated whenever the PRNG is reseeded */
-	struct tc_aes_key_sched_struct key;
+    /* updated whenever the PRNG is reseeded */
+    struct tc_aes_key_sched_struct key;
 
-	/* number of requests since initialization/reseeding */
-	uint64_t reseedCount;
+    /* number of requests since initialization/reseeding */
+    uint64_t reseedCount;
 } TCCtrPrng_t;
 
 
@@ -98,11 +98,11 @@ typedef struct {
  *  @param plen IN -- personalization length in bytes
  *
  */
-int tc_ctr_prng_init(TCCtrPrng_t * const ctx, 
-		     uint8_t const * const entropy,
-		     unsigned int entropyLen, 
-		     uint8_t const * const personalization,
-		     unsigned int pLen);
+int tc_ctr_prng_init(TCCtrPrng_t *const ctx,
+                     uint8_t const *const entropy,
+                     unsigned int entropyLen,
+                     uint8_t const *const personalization,
+                     unsigned int pLen);
 
 /**
  *  @brief CTR-PRNG reseed procedure
@@ -123,11 +123,11 @@ int tc_ctr_prng_init(TCCtrPrng_t * const ctx,
  *  @param additional_input IN -- additional input to the prng (may be null)
  *  @param additionallen IN -- additional input length in bytes
  */
-int tc_ctr_prng_reseed(TCCtrPrng_t * const ctx, 
-		       uint8_t const * const entropy,
-		       unsigned int entropyLen,
-		       uint8_t const * const additional_input,
-		       unsigned int additionallen);
+int tc_ctr_prng_reseed(TCCtrPrng_t *const ctx,
+                       uint8_t const *const entropy,
+                       unsigned int entropyLen,
+                       uint8_t const *const additional_input,
+                       unsigned int additionallen);
 
 /**
  *  @brief CTR-PRNG generate procedure
@@ -145,11 +145,11 @@ int tc_ctr_prng_reseed(TCCtrPrng_t * const ctx,
  *  @param out IN/OUT -- buffer to receive output
  *  @param outlen IN -- size of out buffer in bytes
  */
-int tc_ctr_prng_generate(TCCtrPrng_t * const ctx,
-			 uint8_t const * const additional_input,
-			 unsigned int additionallen,
-			 uint8_t * const out,
-			 unsigned int outlen);
+int tc_ctr_prng_generate(TCCtrPrng_t *const ctx,
+                         uint8_t const *const additional_input,
+                         unsigned int additionallen,
+                         uint8_t *const out,
+                         unsigned int outlen);
 
 /**
  *  @brief CTR-PRNG uninstantiate procedure
@@ -157,7 +157,7 @@ int tc_ctr_prng_generate(TCCtrPrng_t * const ctx,
  *  @return none
  *  @param ctx IN/OUT -- the PRNG context
  */
-void tc_ctr_prng_uninstantiate(TCCtrPrng_t * const ctx);
+void tc_ctr_prng_uninstantiate(TCCtrPrng_t *const ctx);
 
 #ifdef __cplusplus
 }

+ 83 - 83
src/bt/blehost/ext/tinycrypt/include/tinycrypt/ecc.h

@@ -108,19 +108,19 @@ typedef uint64_t uECC_dword_t;
 
 /* structure that represents an elliptic curve (e.g. p256):*/
 struct uECC_Curve_t;
-typedef const struct uECC_Curve_t * uECC_Curve;
+typedef const struct uECC_Curve_t *uECC_Curve;
 struct uECC_Curve_t {
-  wordcount_t num_words;
-  wordcount_t num_bytes;
-  bitcount_t num_n_bits;
-  uECC_word_t p[NUM_ECC_WORDS];
-  uECC_word_t n[NUM_ECC_WORDS];
-  uECC_word_t G[NUM_ECC_WORDS * 2];
-  uECC_word_t b[NUM_ECC_WORDS];
-  void (*double_jacobian)(uECC_word_t * X1, uECC_word_t * Y1, uECC_word_t * Z1,
-	uECC_Curve curve);
-  void (*x_side)(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve);
-  void (*mmod_fast)(uECC_word_t *result, uECC_word_t *product);
+    wordcount_t num_words;
+    wordcount_t num_bytes;
+    bitcount_t num_n_bits;
+    uECC_word_t p[NUM_ECC_WORDS];
+    uECC_word_t n[NUM_ECC_WORDS];
+    uECC_word_t G[NUM_ECC_WORDS * 2];
+    uECC_word_t b[NUM_ECC_WORDS];
+    void (*double_jacobian)(uECC_word_t *X1, uECC_word_t *Y1, uECC_word_t *Z1,
+                            uECC_Curve curve);
+    void (*x_side)(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve);
+    void (*mmod_fast)(uECC_word_t *result, uECC_word_t *product);
 };
 
 /*
@@ -130,8 +130,8 @@ struct uECC_Curve_t {
  * @param Z1 IN/OUT -- z coordinate
  * @param curve IN -- elliptic curve
  */
-void double_jacobian_default(uECC_word_t * X1, uECC_word_t * Y1,
-			     uECC_word_t * Z1, uECC_Curve curve);
+void double_jacobian_default(uECC_word_t *X1, uECC_word_t *Y1,
+                             uECC_word_t *Z1, uECC_Curve curve);
 
 /*
  * @brief Computes x^3 + ax + b. result must not overlap x.
@@ -140,7 +140,7 @@ void double_jacobian_default(uECC_word_t * X1, uECC_word_t * Y1,
  * @param curve IN -- elliptic curve
  */
 void x_side_default(uECC_word_t *result, const uECC_word_t *x,
-		    uECC_Curve curve);
+                    uECC_Curve curve);
 
 /*
  * @brief Computes result = product % curve_p
@@ -154,42 +154,42 @@ void vli_mmod_fast_secp256r1(unsigned int *result, unsigned int *product);
 #define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##d##c##b##a, 0x##h##g##f##e
 #define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a
 #define BITS_TO_WORDS(num_bits) \
-	((num_bits + ((uECC_WORD_SIZE * 8) - 1)) / (uECC_WORD_SIZE * 8))
+    ((num_bits + ((uECC_WORD_SIZE * 8) - 1)) / (uECC_WORD_SIZE * 8))
 #define BITS_TO_BYTES(num_bits) ((num_bits + 7) / 8)
 
 /* definition of curve NIST p-256: */
 static const struct uECC_Curve_t curve_secp256r1 = {
-	NUM_ECC_WORDS,
-	NUM_ECC_BYTES,
-	256, /* num_n_bits */ {
-		BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
-		BYTES_TO_WORDS_8(FF, FF, FF, FF, 00, 00, 00, 00),
-        	BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00),
-        	BYTES_TO_WORDS_8(01, 00, 00, 00, FF, FF, FF, FF)
-	}, {
-		BYTES_TO_WORDS_8(51, 25, 63, FC, C2, CA, B9, F3),
-            	BYTES_TO_WORDS_8(84, 9E, 17, A7, AD, FA, E6, BC),
-            	BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
-            	BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF)
-	}, {
-		BYTES_TO_WORDS_8(96, C2, 98, D8, 45, 39, A1, F4),
-                BYTES_TO_WORDS_8(A0, 33, EB, 2D, 81, 7D, 03, 77),
-                BYTES_TO_WORDS_8(F2, 40, A4, 63, E5, E6, BC, F8),
-                BYTES_TO_WORDS_8(47, 42, 2C, E1, F2, D1, 17, 6B),
-
-                BYTES_TO_WORDS_8(F5, 51, BF, 37, 68, 40, B6, CB),
-                BYTES_TO_WORDS_8(CE, 5E, 31, 6B, 57, 33, CE, 2B),
-                BYTES_TO_WORDS_8(16, 9E, 0F, 7C, 4A, EB, E7, 8E),
-                BYTES_TO_WORDS_8(9B, 7F, 1A, FE, E2, 42, E3, 4F)
-	}, {
-		BYTES_TO_WORDS_8(4B, 60, D2, 27, 3E, 3C, CE, 3B),
-                BYTES_TO_WORDS_8(F6, B0, 53, CC, B0, 06, 1D, 65),
-                BYTES_TO_WORDS_8(BC, 86, 98, 76, 55, BD, EB, B3),
-                BYTES_TO_WORDS_8(E7, 93, 3A, AA, D8, 35, C6, 5A)
-	},
-        &double_jacobian_default,
-        &x_side_default,
-        &vli_mmod_fast_secp256r1
+    NUM_ECC_WORDS,
+    NUM_ECC_BYTES,
+    256, /* num_n_bits */ {
+        BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
+        BYTES_TO_WORDS_8(FF, FF, FF, FF, 00, 00, 00, 00),
+        BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00),
+        BYTES_TO_WORDS_8(01, 00, 00, 00, FF, FF, FF, FF)
+    }, {
+        BYTES_TO_WORDS_8(51, 25, 63, FC, C2, CA, B9, F3),
+        BYTES_TO_WORDS_8(84, 9E, 17, A7, AD, FA, E6, BC),
+        BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
+        BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF)
+    }, {
+        BYTES_TO_WORDS_8(96, C2, 98, D8, 45, 39, A1, F4),
+        BYTES_TO_WORDS_8(A0, 33, EB, 2D, 81, 7D, 03, 77),
+        BYTES_TO_WORDS_8(F2, 40, A4, 63, E5, E6, BC, F8),
+        BYTES_TO_WORDS_8(47, 42, 2C, E1, F2, D1, 17, 6B),
+
+        BYTES_TO_WORDS_8(F5, 51, BF, 37, 68, 40, B6, CB),
+        BYTES_TO_WORDS_8(CE, 5E, 31, 6B, 57, 33, CE, 2B),
+        BYTES_TO_WORDS_8(16, 9E, 0F, 7C, 4A, EB, E7, 8E),
+        BYTES_TO_WORDS_8(9B, 7F, 1A, FE, E2, 42, E3, 4F)
+    }, {
+        BYTES_TO_WORDS_8(4B, 60, D2, 27, 3E, 3C, CE, 3B),
+        BYTES_TO_WORDS_8(F6, B0, 53, CC, B0, 06, 1D, 65),
+        BYTES_TO_WORDS_8(BC, 86, 98, 76, 55, BD, EB, B3),
+        BYTES_TO_WORDS_8(E7, 93, 3A, AA, D8, 35, C6, 5A)
+    },
+    &double_jacobian_default,
+    &x_side_default,
+    &vli_mmod_fast_secp256r1
 };
 
 uECC_Curve uECC_secp256r1(void);
@@ -203,7 +203,7 @@ uECC_Curve uECC_secp256r1(void);
  * @return a random integer in the range 0 < random < top
  */
 int uECC_generate_random_int(uECC_word_t *random, const uECC_word_t *top,
-			     wordcount_t num_words);
+                             wordcount_t num_words);
 
 
 /* uECC_RNG_Function type
@@ -264,7 +264,7 @@ int uECC_curve_public_key_size(uECC_Curve curve);
  * @return Returns 1 if key was computed successfully, 0 if an error occurred.
  */
 int uECC_compute_public_key(const uint8_t *private_key,
-			    uint8_t *public_key, uECC_Curve curve);
+                            uint8_t *public_key, uECC_Curve curve);
 
 /*
  * @brief Compute public-key.
@@ -274,7 +274,7 @@ int uECC_compute_public_key(const uint8_t *private_key,
  * @param curve IN -- elliptic curve
  */
 uECC_word_t EccPoint_compute_public_key(uECC_word_t *result,
-					uECC_word_t *private_key, uECC_Curve curve);
+                                        uECC_word_t *private_key, uECC_Curve curve);
 
 /*
  * @brief Regularize the bitcount for the private key so that attackers cannot
@@ -285,8 +285,8 @@ uECC_word_t EccPoint_compute_public_key(uECC_word_t *result,
  * @param k1 IN/OUT -- regularized k
  * @param curve IN -- elliptic curve
  */
-uECC_word_t regularize_k(const uECC_word_t * const k, uECC_word_t *k0,
-			 uECC_word_t *k1, uECC_Curve curve);
+uECC_word_t regularize_k(const uECC_word_t *const k, uECC_word_t *k0,
+                         uECC_word_t *k1, uECC_Curve curve);
 
 /*
  * @brief Point multiplication algorithm using Montgomery's ladder with co-Z
@@ -299,9 +299,9 @@ uECC_word_t regularize_k(const uECC_word_t * const k, uECC_word_t *k0,
  * @param num_bits IN -- number of bits in scalar
  * @param curve IN -- elliptic curve
  */
-void EccPoint_mult(uECC_word_t * result, const uECC_word_t * point,
-		   const uECC_word_t * scalar, const uECC_word_t * initial_Z,
-		   bitcount_t num_bits, uECC_Curve curve);
+void EccPoint_mult(uECC_word_t *result, const uECC_word_t *point,
+                   const uECC_word_t *scalar, const uECC_word_t *initial_Z,
+                   bitcount_t num_bits, uECC_Curve curve);
 
 /*
  * @brief Constant-time comparison to zero - secure way to compare long integers
@@ -327,7 +327,7 @@ uECC_word_t EccPoint_isZero(const uECC_word_t *point, uECC_Curve curve);
  * @return the sign of left - right
  */
 cmpresult_t uECC_vli_cmp(const uECC_word_t *left, const uECC_word_t *right,
-			 wordcount_t num_words);
+                         wordcount_t num_words);
 
 /*
  * @brief computes sign of left - right, not in constant time.
@@ -338,7 +338,7 @@ cmpresult_t uECC_vli_cmp(const uECC_word_t *left, const uECC_word_t *right,
  * @return the sign of left - right
  */
 cmpresult_t uECC_vli_cmp_unsafe(const uECC_word_t *left, const uECC_word_t *right,
-				wordcount_t num_words);
+                                wordcount_t num_words);
 
 /*
  * @brief Computes result = (left - right) % mod.
@@ -351,8 +351,8 @@ cmpresult_t uECC_vli_cmp_unsafe(const uECC_word_t *left, const uECC_word_t *righ
  * @param num_words IN -- number of words
  */
 void uECC_vli_modSub(uECC_word_t *result, const uECC_word_t *left,
-		     const uECC_word_t *right, const uECC_word_t *mod,
-		     wordcount_t num_words);
+                     const uECC_word_t *right, const uECC_word_t *mod,
+                     wordcount_t num_words);
 
 /*
  * @brief Computes P' = (x1', y1', Z3), P + Q = (x3, y3, Z3) or
@@ -364,8 +364,8 @@ void uECC_vli_modSub(uECC_word_t *result, const uECC_word_t *left,
  * @param Y2 IN -- y coordinate of Q
  * @param curve IN -- elliptic curve
  */
-void XYcZ_add(uECC_word_t * X1, uECC_word_t * Y1, uECC_word_t * X2,
-	      uECC_word_t * Y2, uECC_Curve curve);
+void XYcZ_add(uECC_word_t *X1, uECC_word_t *Y1, uECC_word_t *X2,
+              uECC_word_t *Y2, uECC_Curve curve);
 
 /*
  * @brief Computes (x1 * z^2, y1 * z^3)
@@ -374,8 +374,8 @@ void XYcZ_add(uECC_word_t * X1, uECC_word_t * Y1, uECC_word_t * X2,
  * @param Z IN -- z value
  * @param curve IN -- elliptic curve
  */
-void apply_z(uECC_word_t * X1, uECC_word_t * Y1, const uECC_word_t * const Z,
-	     uECC_Curve curve);
+void apply_z(uECC_word_t *X1, uECC_word_t *Y1, const uECC_word_t *const Z,
+             uECC_Curve curve);
 
 /*
  * @brief Check if bit is set.
@@ -396,7 +396,7 @@ uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit);
  * @warning Currently only designed to work for curve_p or curve_n.
  */
 void uECC_vli_mmod(uECC_word_t *result, uECC_word_t *product,
-		   const uECC_word_t *mod, wordcount_t num_words);
+                   const uECC_word_t *mod, wordcount_t num_words);
 
 /*
  * @brief Computes modular product (using curve->mmod_fast)
@@ -406,7 +406,7 @@ void uECC_vli_mmod(uECC_word_t *result, uECC_word_t *product,
  * @param curve IN -- elliptic curve
  */
 void uECC_vli_modMult_fast(uECC_word_t *result, const uECC_word_t *left,
-			   const uECC_word_t *right, uECC_Curve curve);
+                           const uECC_word_t *right, uECC_Curve curve);
 
 /*
  * @brief Computes result = left - right.
@@ -418,7 +418,7 @@ void uECC_vli_modMult_fast(uECC_word_t *result, const uECC_word_t *left,
  * @return borrow
  */
 uECC_word_t uECC_vli_sub(uECC_word_t *result, const uECC_word_t *left,
-			 const uECC_word_t *right, wordcount_t num_words);
+                         const uECC_word_t *right, wordcount_t num_words);
 
 /*
  * @brief Constant-time comparison function(secure way to compare long ints)
@@ -428,7 +428,7 @@ uECC_word_t uECC_vli_sub(uECC_word_t *result, const uECC_word_t *left,
  * @return Returns 0 if left == right, 1 otherwise.
  */
 uECC_word_t uECC_vli_equal(const uECC_word_t *left, const uECC_word_t *right,
-			   wordcount_t num_words);
+                           wordcount_t num_words);
 
 /*
  * @brief Computes (left * right) % mod
@@ -439,8 +439,8 @@ uECC_word_t uECC_vli_equal(const uECC_word_t *left, const uECC_word_t *right,
  * @param num_words IN -- number of words
  */
 void uECC_vli_modMult(uECC_word_t *result, const uECC_word_t *left,
-		      const uECC_word_t *right, const uECC_word_t *mod,
-	              wordcount_t num_words);
+                      const uECC_word_t *right, const uECC_word_t *mod,
+                      wordcount_t num_words);
 
 /*
  * @brief Computes (1 / input) % mod
@@ -452,7 +452,7 @@ void uECC_vli_modMult(uECC_word_t *result, const uECC_word_t *left,
  * @param num_words -- number of words
  */
 void uECC_vli_modInv(uECC_word_t *result, const uECC_word_t *input,
-		     const uECC_word_t *mod, wordcount_t num_words);
+                     const uECC_word_t *mod, wordcount_t num_words);
 
 /*
  * @brief Sets dest = src.
@@ -461,7 +461,7 @@ void uECC_vli_modInv(uECC_word_t *result, const uECC_word_t *input,
  * @param num_words IN -- number of words
  */
 void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src,
-		  wordcount_t num_words);
+                  wordcount_t num_words);
 
 /*
  * @brief Computes (left + right) % mod.
@@ -474,8 +474,8 @@ void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src,
  * @param num_words IN -- number of words
  */
 void uECC_vli_modAdd(uECC_word_t *result,  const uECC_word_t *left,
-    		     const uECC_word_t *right, const uECC_word_t *mod,
-   		     wordcount_t num_words);
+                     const uECC_word_t *right, const uECC_word_t *mod,
+                     wordcount_t num_words);
 
 /*
  * @brief Counts the number of bits required to represent vli.
@@ -483,8 +483,8 @@ void uECC_vli_modAdd(uECC_word_t *result,  const uECC_word_t *left,
  * @param max_words IN -- number of words
  * @return number of bits in given vli
  */
-bitcount_t uECC_vli_numBits(const uECC_word_t *vli, 
-			    const wordcount_t max_words);
+bitcount_t uECC_vli_numBits(const uECC_word_t *vli,
+                            const wordcount_t max_words);
 
 /*
  * @brief Erases (set to 0) vli
@@ -520,14 +520,14 @@ int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve);
  */
 int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve);
 
- /*
-  * @brief Converts an integer in uECC native format to big-endian bytes.
-  * @param bytes OUT -- bytes representation
-  * @param num_bytes IN -- number of bytes
-  * @param native IN -- uECC native representation
-  */
+/*
+ * @brief Converts an integer in uECC native format to big-endian bytes.
+ * @param bytes OUT -- bytes representation
+ * @param num_bytes IN -- number of bytes
+ * @param native IN -- uECC native representation
+ */
 void uECC_vli_nativeToBytes(uint8_t *bytes, int num_bytes,
-    			    const unsigned int *native);
+                            const unsigned int *native);
 
 /*
  * @brief Converts big-endian bytes to an integer in uECC native format.
@@ -536,7 +536,7 @@ void uECC_vli_nativeToBytes(uint8_t *bytes, int num_bytes,
  * @param num_bytes IN -- number of bytes
  */
 void uECC_vli_bytesToNative(unsigned int *native, const uint8_t *bytes,
-			    int num_bytes);
+                            int num_bytes);
 
 #ifdef __cplusplus
 }

+ 2 - 2
src/bt/blehost/ext/tinycrypt/include/tinycrypt/ecc_dh.h

@@ -102,7 +102,7 @@ int uECC_make_key(uint8_t *p_public_key, uint8_t *p_private_key, uECC_Curve curv
  * uECC_make_key() function for real applications.
  */
 int uECC_make_key_with_d(uint8_t *p_public_key, uint8_t *p_private_key,
-    			 unsigned int *d, uECC_Curve curve);
+                         unsigned int *d, uECC_Curve curve);
 #endif
 
 /**
@@ -122,7 +122,7 @@ int uECC_make_key_with_d(uint8_t *p_public_key, uint8_t *p_private_key,
  * order to produce a cryptographically secure symmetric key.
  */
 int uECC_shared_secret(const uint8_t *p_public_key, const uint8_t *p_private_key,
-		       uint8_t *p_secret, uECC_Curve curve);
+                       uint8_t *p_secret, uECC_Curve curve);
 
 #ifdef __cplusplus
 }

+ 5 - 5
src/bt/blehost/ext/tinycrypt/include/tinycrypt/ecc_dsa.h

@@ -103,7 +103,7 @@ extern "C" {
  * attack.
  */
 int uECC_sign(const uint8_t *p_private_key, const uint8_t *p_message_hash,
-	      unsigned p_hash_size, uint8_t *p_signature, uECC_Curve curve);
+              unsigned p_hash_size, uint8_t *p_signature, uECC_Curve curve);
 
 #ifdef ENABLE_TESTS
 /*
@@ -111,14 +111,14 @@ int uECC_sign(const uint8_t *p_private_key, const uint8_t *p_message_hash,
  * Refer to uECC_sign() function for real applications.
  */
 int uECC_sign_with_k(const uint8_t *private_key, const uint8_t *message_hash,
-		     unsigned int hash_size, uECC_word_t *k, uint8_t *signature,
-		     uECC_Curve curve);
+                     unsigned int hash_size, uECC_word_t *k, uint8_t *signature,
+                     uECC_Curve curve);
 #endif
 
 /**
  * @brief Verify an ECDSA signature.
  * @return returns TC_SUCCESS (1) if the signature is valid
- * 	   returns TC_FAIL (0) if the signature is invalid.
+ *     returns TC_FAIL (0) if the signature is invalid.
  *
  * @param p_public_key IN -- The signer's public key.
  * @param p_message_hash IN -- The hash of the signed data.
@@ -130,7 +130,7 @@ int uECC_sign_with_k(const uint8_t *private_key, const uint8_t *message_hash,
  * the signature values (hash_size and signature).
  */
 int uECC_verify(const uint8_t *p_public_key, const uint8_t *p_message_hash,
-		unsigned int p_hash_size, const uint8_t *p_signature, uECC_Curve curve);
+                unsigned int p_hash_size, const uint8_t *p_signature, uECC_Curve curve);
 
 #ifdef __cplusplus
 }

+ 6 - 6
src/bt/blehost/ext/tinycrypt/include/tinycrypt/hmac.h

@@ -70,10 +70,10 @@ extern "C" {
 #endif
 
 struct tc_hmac_state_struct {
-	/* the internal state required by h */
-	struct tc_sha256_state_struct hash_state;
-	/* HMAC key schedule */
-	uint8_t key[2*TC_SHA256_BLOCK_SIZE];
+    /* the internal state required by h */
+    struct tc_sha256_state_struct hash_state;
+    /* HMAC key schedule */
+    uint8_t key[2 * TC_SHA256_BLOCK_SIZE];
 };
 typedef struct tc_hmac_state_struct *TCHmacState_t;
 
@@ -90,7 +90,7 @@ typedef struct tc_hmac_state_struct *TCHmacState_t;
  * @param key_size IN -- the HMAC key size
  */
 int tc_hmac_set_key(TCHmacState_t ctx, const uint8_t *key,
-		    unsigned int key_size);
+                    unsigned int key_size);
 
 /**
  * @brief HMAC init procedure
@@ -112,7 +112,7 @@ int tc_hmac_init(TCHmacState_t ctx);
  *  @param data_length IN -- size of data in bytes
  */
 int tc_hmac_update(TCHmacState_t ctx, const void *data,
-		   unsigned int data_length);
+                   unsigned int data_length);
 
 /**
  *  @brief HMAC final procedure

+ 13 - 13
src/bt/blehost/ext/tinycrypt/include/tinycrypt/hmac_prng.h

@@ -78,14 +78,14 @@ extern "C" {
 #define TC_HMAC_PRNG_RESEED_REQ -1
 
 struct tc_hmac_prng_struct {
-	/* the HMAC instance for this PRNG */
-	struct tc_hmac_state_struct h;
-	/* the PRNG key */
-	uint8_t key[TC_SHA256_DIGEST_SIZE];
-	/* PRNG state */
-	uint8_t v[TC_SHA256_DIGEST_SIZE];
-	/* calls to tc_hmac_prng_generate left before re-seed */
-	unsigned int countdown;
+    /* the HMAC instance for this PRNG */
+    struct tc_hmac_state_struct h;
+    /* the PRNG key */
+    uint8_t key[TC_SHA256_DIGEST_SIZE];
+    /* PRNG state */
+    uint8_t v[TC_SHA256_DIGEST_SIZE];
+    /* calls to tc_hmac_prng_generate left before re-seed */
+    unsigned int countdown;
 };
 
 typedef struct tc_hmac_prng_struct *TCHmacPrng_t;
@@ -113,14 +113,14 @@ typedef struct tc_hmac_prng_struct *TCHmacPrng_t;
  *  @param plen IN -- personalization length in bytes
  */
 int tc_hmac_prng_init(TCHmacPrng_t prng,
-		      const uint8_t *personalization,
-		      unsigned int plen);
+                      const uint8_t *personalization,
+                      unsigned int plen);
 
 /**
  *  @brief HMAC-PRNG reseed procedure
  *  Mixes seed into prng, enables tc_hmac_prng_generate
  *  @return returns  TC_CRYPTO_SUCCESS (1)
- *  	    returns TC_CRYPTO_FAIL (0) if:
+ *          returns TC_CRYPTO_FAIL (0) if:
  *          prng == NULL,
  *          seed == NULL,
  *          seedlen < MIN_SLEN,
@@ -137,8 +137,8 @@ int tc_hmac_prng_init(TCHmacPrng_t prng,
  *  @param additionallen IN -- additional input length in bytes
  */
 int tc_hmac_prng_reseed(TCHmacPrng_t prng, const uint8_t *seed,
-			unsigned int seedlen, const uint8_t *additional_input,
-			unsigned int additionallen);
+                        unsigned int seedlen, const uint8_t *additional_input,
+                        unsigned int additionallen);
 
 /**
  *  @brief HMAC-PRNG generate procedure

+ 5 - 5
src/bt/blehost/ext/tinycrypt/include/tinycrypt/sha256.h

@@ -69,10 +69,10 @@ extern "C" {
 #define TC_SHA256_STATE_BLOCKS (TC_SHA256_DIGEST_SIZE/4)
 
 struct tc_sha256_state_struct {
-	unsigned int iv[TC_SHA256_STATE_BLOCKS];
-	uint64_t bits_hashed;
-	uint8_t leftover[TC_SHA256_BLOCK_SIZE];
-	size_t leftover_offset;
+    unsigned int iv[TC_SHA256_STATE_BLOCKS];
+    uint64_t bits_hashed;
+    uint8_t leftover[TC_SHA256_BLOCK_SIZE];
+    size_t leftover_offset;
 };
 
 typedef struct tc_sha256_state_struct *TCSha256State_t;
@@ -102,7 +102,7 @@ int tc_sha256_init(TCSha256State_t s);
  *  @param data message to hash
  *  @param datalen length of message to hash
  */
-int tc_sha256_update (TCSha256State_t s, const uint8_t *data, size_t datalen);
+int tc_sha256_update(TCSha256State_t s, const uint8_t *data, size_t datalen);
 
 /**
  *  @brief SHA256 final procedure

+ 1 - 1
src/bt/blehost/ext/tinycrypt/include/tinycrypt/utils.h

@@ -58,7 +58,7 @@ extern "C" {
  * @param from_len IN -- length of origin buffer
  */
 unsigned int _copy(uint8_t *to, unsigned int to_len,
-	           const uint8_t *from, unsigned int from_len);
+                   const uint8_t *from, unsigned int from_len);
 
 /**
  * @brief Set the value 'val' into the buffer 'to', 'len' times.

+ 99 - 86
src/bt/blehost/ext/tinycrypt/src/aes_decrypt.c

@@ -35,33 +35,33 @@
 #include <tinycrypt/utils.h>
 
 static const uint8_t inv_sbox[256] = {
-	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e,
-	0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
-	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32,
-	0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
-	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49,
-	0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
-	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50,
-	0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
-	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05,
-	0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
-	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41,
-	0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
-	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8,
-	0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
-	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b,
-	0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
-	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59,
-	0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
-	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d,
-	0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
-	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63,
-	0x55, 0x21, 0x0c, 0x7d
+    0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e,
+    0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
+    0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32,
+    0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+    0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49,
+    0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
+    0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50,
+    0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+    0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05,
+    0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
+    0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41,
+    0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+    0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8,
+    0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
+    0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b,
+    0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+    0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59,
+    0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
+    0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d,
+    0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+    0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63,
+    0x55, 0x21, 0x0c, 0x7d
 };
 
 int tc_aes128_set_decrypt_key(TCAesKeySched_t s, const uint8_t *k)
 {
-	return tc_aes128_set_encrypt_key(s, k);
+    return tc_aes128_set_encrypt_key(s, k);
 }
 
 #define mult8(a)(_double_byte(_double_byte(_double_byte(a))))
@@ -72,42 +72,49 @@ int tc_aes128_set_decrypt_key(TCAesKeySched_t s, const uint8_t *k)
 
 static inline void mult_row_column(uint8_t *out, const uint8_t *in)
 {
-	out[0] = multe(in[0]) ^ multb(in[1]) ^ multd(in[2]) ^ mult9(in[3]);
-	out[1] = mult9(in[0]) ^ multe(in[1]) ^ multb(in[2]) ^ multd(in[3]);
-	out[2] = multd(in[0]) ^ mult9(in[1]) ^ multe(in[2]) ^ multb(in[3]);
-	out[3] = multb(in[0]) ^ multd(in[1]) ^ mult9(in[2]) ^ multe(in[3]);
+    out[0] = multe(in[0]) ^ multb(in[1]) ^ multd(in[2]) ^ mult9(in[3]);
+    out[1] = mult9(in[0]) ^ multe(in[1]) ^ multb(in[2]) ^ multd(in[3]);
+    out[2] = multd(in[0]) ^ mult9(in[1]) ^ multe(in[2]) ^ multb(in[3]);
+    out[3] = multb(in[0]) ^ multd(in[1]) ^ mult9(in[2]) ^ multe(in[3]);
 }
 
 static inline void inv_mix_columns(uint8_t *s)
 {
-	uint8_t t[Nb*Nk];
-
-	mult_row_column(t, s);
-	mult_row_column(&t[Nb], s+Nb);
-	mult_row_column(&t[2*Nb], s+(2*Nb));
-	mult_row_column(&t[3*Nb], s+(3*Nb));
-	(void)_copy(s, sizeof(t), t, sizeof(t));
+    uint8_t t[Nb * Nk];
+    mult_row_column(t, s);
+    mult_row_column(&t[Nb], s + Nb);
+    mult_row_column(&t[2 * Nb], s + (2 * Nb));
+    mult_row_column(&t[3 * Nb], s + (3 * Nb));
+    (void)_copy(s, sizeof(t), t, sizeof(t));
 }
 
 static inline void add_round_key(uint8_t *s, const unsigned int *k)
 {
-	s[0] ^= (uint8_t)(k[0] >> 24); s[1] ^= (uint8_t)(k[0] >> 16);
-	s[2] ^= (uint8_t)(k[0] >> 8); s[3] ^= (uint8_t)(k[0]);
-	s[4] ^= (uint8_t)(k[1] >> 24); s[5] ^= (uint8_t)(k[1] >> 16);
-	s[6] ^= (uint8_t)(k[1] >> 8); s[7] ^= (uint8_t)(k[1]);
-	s[8] ^= (uint8_t)(k[2] >> 24); s[9] ^= (uint8_t)(k[2] >> 16);
-	s[10] ^= (uint8_t)(k[2] >> 8); s[11] ^= (uint8_t)(k[2]);
-	s[12] ^= (uint8_t)(k[3] >> 24); s[13] ^= (uint8_t)(k[3] >> 16);
-	s[14] ^= (uint8_t)(k[3] >> 8); s[15] ^= (uint8_t)(k[3]);
+    s[0] ^= (uint8_t)(k[0] >> 24);
+    s[1] ^= (uint8_t)(k[0] >> 16);
+    s[2] ^= (uint8_t)(k[0] >> 8);
+    s[3] ^= (uint8_t)(k[0]);
+    s[4] ^= (uint8_t)(k[1] >> 24);
+    s[5] ^= (uint8_t)(k[1] >> 16);
+    s[6] ^= (uint8_t)(k[1] >> 8);
+    s[7] ^= (uint8_t)(k[1]);
+    s[8] ^= (uint8_t)(k[2] >> 24);
+    s[9] ^= (uint8_t)(k[2] >> 16);
+    s[10] ^= (uint8_t)(k[2] >> 8);
+    s[11] ^= (uint8_t)(k[2]);
+    s[12] ^= (uint8_t)(k[3] >> 24);
+    s[13] ^= (uint8_t)(k[3] >> 16);
+    s[14] ^= (uint8_t)(k[3] >> 8);
+    s[15] ^= (uint8_t)(k[3]);
 }
 
 static inline void inv_sub_bytes(uint8_t *s)
 {
-	unsigned int i;
+    unsigned int i;
 
-	for (i = 0; i < (Nb*Nk); ++i) {
-		s[i] = inv_sbox[s[i]];
-	}
+    for(i = 0; i < (Nb * Nk); ++i) {
+        s[i] = inv_sbox[s[i]];
+    }
 }
 
 /*
@@ -117,48 +124,54 @@ static inline void inv_sub_bytes(uint8_t *s)
  */
 static inline void inv_shift_rows(uint8_t *s)
 {
-	uint8_t t[Nb*Nk];
-
-	t[0]  = s[0]; t[1] = s[13]; t[2] = s[10]; t[3] = s[7];
-	t[4]  = s[4]; t[5] = s[1]; t[6] = s[14]; t[7] = s[11];
-	t[8]  = s[8]; t[9] = s[5]; t[10] = s[2]; t[11] = s[15];
-	t[12] = s[12]; t[13] = s[9]; t[14] = s[6]; t[15] = s[3];
-	(void)_copy(s, sizeof(t), t, sizeof(t));
+    uint8_t t[Nb * Nk];
+    t[0]  = s[0];
+    t[1] = s[13];
+    t[2] = s[10];
+    t[3] = s[7];
+    t[4]  = s[4];
+    t[5] = s[1];
+    t[6] = s[14];
+    t[7] = s[11];
+    t[8]  = s[8];
+    t[9] = s[5];
+    t[10] = s[2];
+    t[11] = s[15];
+    t[12] = s[12];
+    t[13] = s[9];
+    t[14] = s[6];
+    t[15] = s[3];
+    (void)_copy(s, sizeof(t), t, sizeof(t));
 }
 
 int tc_aes_decrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s)
 {
-	uint8_t state[Nk*Nb];
-	unsigned int i;
-
-	if (out == (uint8_t *) 0) {
-		return TC_CRYPTO_FAIL;
-	} else if (in == (const uint8_t *) 0) {
-		return TC_CRYPTO_FAIL;
-	} else if (s == (TCAesKeySched_t) 0) {
-		return TC_CRYPTO_FAIL;
-	}
-
-	(void)_copy(state, sizeof(state), in, sizeof(state));
-
-	add_round_key(state, s->words + Nb*Nr);
-
-	for (i = Nr - 1; i > 0; --i) {
-		inv_shift_rows(state);
-		inv_sub_bytes(state);
-		add_round_key(state, s->words + Nb*i);
-		inv_mix_columns(state);
-	}
-
-	inv_shift_rows(state);
-	inv_sub_bytes(state);
-	add_round_key(state, s->words);
-
-	(void)_copy(out, sizeof(state), state, sizeof(state));
-
-	/*zeroing out the state buffer */
-	_set(state, TC_ZERO_BYTE, sizeof(state));
-
-
-	return TC_CRYPTO_SUCCESS;
+    uint8_t state[Nk * Nb];
+    unsigned int i;
+
+    if(out == (uint8_t *) 0) {
+        return TC_CRYPTO_FAIL;
+    } else if(in == (const uint8_t *) 0) {
+        return TC_CRYPTO_FAIL;
+    } else if(s == (TCAesKeySched_t) 0) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    (void)_copy(state, sizeof(state), in, sizeof(state));
+    add_round_key(state, s->words + Nb * Nr);
+
+    for(i = Nr - 1; i > 0; --i) {
+        inv_shift_rows(state);
+        inv_sub_bytes(state);
+        add_round_key(state, s->words + Nb * i);
+        inv_mix_columns(state);
+    }
+
+    inv_shift_rows(state);
+    inv_sub_bytes(state);
+    add_round_key(state, s->words);
+    (void)_copy(out, sizeof(state), state, sizeof(state));
+    /*zeroing out the state buffer */
+    _set(state, TC_ZERO_BYTE, sizeof(state));
+    return TC_CRYPTO_SUCCESS;
 }

+ 128 - 111
src/bt/blehost/ext/tinycrypt/src/aes_encrypt.c

@@ -35,33 +35,33 @@
 #include <tinycrypt/constants.h>
 
 static const uint8_t sbox[256] = {
-	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
-	0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
-	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,
-	0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
-	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
-	0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
-	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed,
-	0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
-	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
-	0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
-	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
-	0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
-	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
-	0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
-	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
-	0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
-	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,
-	0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
-	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11,
-	0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
-	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
-	0xb0, 0x54, 0xbb, 0x16
+    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
+    0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+    0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,
+    0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
+    0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+    0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed,
+    0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
+    0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+    0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
+    0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
+    0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+    0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
+    0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,
+    0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+    0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11,
+    0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
+    0xb0, 0x54, 0xbb, 0x16
 };
 
 static inline unsigned int rotword(unsigned int a)
 {
-	return (((a) >> 24)|((a) << 8));
+    return (((a) >> 24) | ((a) << 8));
 }
 
 #define subbyte(a, o)(sbox[((a) >> (o))&0xff] << (o))
@@ -69,75 +69,84 @@ static inline unsigned int rotword(unsigned int a)
 
 int tc_aes128_set_encrypt_key(TCAesKeySched_t s, const uint8_t *k)
 {
-	const unsigned int rconst[11] = {
-		0x00000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
-		0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000
-	};
-	unsigned int i;
-	unsigned int t;
-
-	if (s == (TCAesKeySched_t) 0) {
-		return TC_CRYPTO_FAIL;
-	} else if (k == (const uint8_t *) 0) {
-		return TC_CRYPTO_FAIL;
-	}
-
-	for (i = 0; i < Nk; ++i) {
-		s->words[i] = (k[Nb*i]<<24) | (k[Nb*i+1]<<16) |
-			      (k[Nb*i+2]<<8) | (k[Nb*i+3]);
-	}
-
-	for (; i < (Nb * (Nr + 1)); ++i) {
-		t = s->words[i-1];
-		if ((i % Nk) == 0) {
-			t = subword(rotword(t)) ^ rconst[i/Nk];
-		}
-		s->words[i] = s->words[i-Nk] ^ t;
-	}
-
-	return TC_CRYPTO_SUCCESS;
+    const unsigned int rconst[11] = {
+        0x00000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
+        0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000
+    };
+    unsigned int i;
+    unsigned int t;
+
+    if(s == (TCAesKeySched_t) 0) {
+        return TC_CRYPTO_FAIL;
+    } else if(k == (const uint8_t *) 0) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    for(i = 0; i < Nk; ++i) {
+        s->words[i] = (k[Nb * i] << 24) | (k[Nb * i + 1] << 16) |
+                      (k[Nb * i + 2] << 8) | (k[Nb * i + 3]);
+    }
+
+    for(; i < (Nb * (Nr + 1)); ++i) {
+        t = s->words[i - 1];
+
+        if((i % Nk) == 0) {
+            t = subword(rotword(t)) ^ rconst[i / Nk];
+        }
+
+        s->words[i] = s->words[i - Nk] ^ t;
+    }
+
+    return TC_CRYPTO_SUCCESS;
 }
 
 static inline void add_round_key(uint8_t *s, const unsigned int *k)
 {
-	s[0] ^= (uint8_t)(k[0] >> 24); s[1] ^= (uint8_t)(k[0] >> 16);
-	s[2] ^= (uint8_t)(k[0] >> 8); s[3] ^= (uint8_t)(k[0]);
-	s[4] ^= (uint8_t)(k[1] >> 24); s[5] ^= (uint8_t)(k[1] >> 16);
-	s[6] ^= (uint8_t)(k[1] >> 8); s[7] ^= (uint8_t)(k[1]);
-	s[8] ^= (uint8_t)(k[2] >> 24); s[9] ^= (uint8_t)(k[2] >> 16);
-	s[10] ^= (uint8_t)(k[2] >> 8); s[11] ^= (uint8_t)(k[2]);
-	s[12] ^= (uint8_t)(k[3] >> 24); s[13] ^= (uint8_t)(k[3] >> 16);
-	s[14] ^= (uint8_t)(k[3] >> 8); s[15] ^= (uint8_t)(k[3]);
+    s[0] ^= (uint8_t)(k[0] >> 24);
+    s[1] ^= (uint8_t)(k[0] >> 16);
+    s[2] ^= (uint8_t)(k[0] >> 8);
+    s[3] ^= (uint8_t)(k[0]);
+    s[4] ^= (uint8_t)(k[1] >> 24);
+    s[5] ^= (uint8_t)(k[1] >> 16);
+    s[6] ^= (uint8_t)(k[1] >> 8);
+    s[7] ^= (uint8_t)(k[1]);
+    s[8] ^= (uint8_t)(k[2] >> 24);
+    s[9] ^= (uint8_t)(k[2] >> 16);
+    s[10] ^= (uint8_t)(k[2] >> 8);
+    s[11] ^= (uint8_t)(k[2]);
+    s[12] ^= (uint8_t)(k[3] >> 24);
+    s[13] ^= (uint8_t)(k[3] >> 16);
+    s[14] ^= (uint8_t)(k[3] >> 8);
+    s[15] ^= (uint8_t)(k[3]);
 }
 
 static inline void sub_bytes(uint8_t *s)
 {
-	unsigned int i;
+    unsigned int i;
 
-	for (i = 0; i < (Nb * Nk); ++i) {
-		s[i] = sbox[s[i]];
-	}
+    for(i = 0; i < (Nb * Nk); ++i) {
+        s[i] = sbox[s[i]];
+    }
 }
 
 #define triple(a)(_double_byte(a)^(a))
 
 static inline void mult_row_column(uint8_t *out, const uint8_t *in)
 {
-	out[0] = _double_byte(in[0]) ^ triple(in[1]) ^ in[2] ^ in[3];
-	out[1] = in[0] ^ _double_byte(in[1]) ^ triple(in[2]) ^ in[3];
-	out[2] = in[0] ^ in[1] ^ _double_byte(in[2]) ^ triple(in[3]);
-	out[3] = triple(in[0]) ^ in[1] ^ in[2] ^ _double_byte(in[3]);
+    out[0] = _double_byte(in[0]) ^ triple(in[1]) ^ in[2] ^ in[3];
+    out[1] = in[0] ^ _double_byte(in[1]) ^ triple(in[2]) ^ in[3];
+    out[2] = in[0] ^ in[1] ^ _double_byte(in[2]) ^ triple(in[3]);
+    out[3] = triple(in[0]) ^ in[1] ^ in[2] ^ _double_byte(in[3]);
 }
 
 static inline void mix_columns(uint8_t *s)
 {
-	uint8_t t[Nb*Nk];
-
-	mult_row_column(t, s);
-	mult_row_column(&t[Nb], s+Nb);
-	mult_row_column(&t[2 * Nb], s + (2 * Nb));
-	mult_row_column(&t[3 * Nb], s + (3 * Nb));
-	(void) _copy(s, sizeof(t), t, sizeof(t));
+    uint8_t t[Nb * Nk];
+    mult_row_column(t, s);
+    mult_row_column(&t[Nb], s + Nb);
+    mult_row_column(&t[2 * Nb], s + (2 * Nb));
+    mult_row_column(&t[3 * Nb], s + (3 * Nb));
+    (void) _copy(s, sizeof(t), t, sizeof(t));
 }
 
 /*
@@ -146,46 +155,54 @@ static inline void mix_columns(uint8_t *s)
  */
 static inline void shift_rows(uint8_t *s)
 {
-	uint8_t t[Nb * Nk];
-
-	t[0]  = s[0]; t[1] = s[5]; t[2] = s[10]; t[3] = s[15];
-	t[4]  = s[4]; t[5] = s[9]; t[6] = s[14]; t[7] = s[3];
-	t[8]  = s[8]; t[9] = s[13]; t[10] = s[2]; t[11] = s[7];
-	t[12] = s[12]; t[13] = s[1]; t[14] = s[6]; t[15] = s[11];
-	(void) _copy(s, sizeof(t), t, sizeof(t));
+    uint8_t t[Nb * Nk];
+    t[0]  = s[0];
+    t[1] = s[5];
+    t[2] = s[10];
+    t[3] = s[15];
+    t[4]  = s[4];
+    t[5] = s[9];
+    t[6] = s[14];
+    t[7] = s[3];
+    t[8]  = s[8];
+    t[9] = s[13];
+    t[10] = s[2];
+    t[11] = s[7];
+    t[12] = s[12];
+    t[13] = s[1];
+    t[14] = s[6];
+    t[15] = s[11];
+    (void) _copy(s, sizeof(t), t, sizeof(t));
 }
 
 int tc_aes_encrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s)
 {
-	uint8_t state[Nk*Nb];
-	unsigned int i;
-
-	if (out == (uint8_t *) 0) {
-		return TC_CRYPTO_FAIL;
-	} else if (in == (const uint8_t *) 0) {
-		return TC_CRYPTO_FAIL;
-	} else if (s == (TCAesKeySched_t) 0) {
-		return TC_CRYPTO_FAIL;
-	}
-
-	(void)_copy(state, sizeof(state), in, sizeof(state));
-	add_round_key(state, s->words);
-
-	for (i = 0; i < (Nr - 1); ++i) {
-		sub_bytes(state);
-		shift_rows(state);
-		mix_columns(state);
-		add_round_key(state, s->words + Nb*(i+1));
-	}
-
-	sub_bytes(state);
-	shift_rows(state);
-	add_round_key(state, s->words + Nb*(i+1));
-
-	(void)_copy(out, sizeof(state), state, sizeof(state));
-
-	/* zeroing out the state buffer */
-	_set(state, TC_ZERO_BYTE, sizeof(state));
-
-	return TC_CRYPTO_SUCCESS;
+    uint8_t state[Nk * Nb];
+    unsigned int i;
+
+    if(out == (uint8_t *) 0) {
+        return TC_CRYPTO_FAIL;
+    } else if(in == (const uint8_t *) 0) {
+        return TC_CRYPTO_FAIL;
+    } else if(s == (TCAesKeySched_t) 0) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    (void)_copy(state, sizeof(state), in, sizeof(state));
+    add_round_key(state, s->words);
+
+    for(i = 0; i < (Nr - 1); ++i) {
+        sub_bytes(state);
+        shift_rows(state);
+        mix_columns(state);
+        add_round_key(state, s->words + Nb * (i + 1));
+    }
+
+    sub_bytes(state);
+    shift_rows(state);
+    add_round_key(state, s->words + Nb * (i + 1));
+    (void)_copy(out, sizeof(state), state, sizeof(state));
+    /* zeroing out the state buffer */
+    _set(state, TC_ZERO_BYTE, sizeof(state));
+    return TC_CRYPTO_SUCCESS;
 }

+ 17 - 16
src/bt/blehost/ext/tinycrypt/src/bleutils.c

@@ -38,19 +38,19 @@
 #define MASK_TWENTY_SEVEN 0x1b
 
 unsigned int _copy(uint8_t *to, unsigned int to_len,
-		   const uint8_t *from, unsigned int from_len)
+                   const uint8_t *from, unsigned int from_len)
 {
-	if (from_len <= to_len) {
-		(void)memcpy(to, from, from_len);
-		return from_len;
-	} else {
-		return TC_CRYPTO_FAIL;
-	}
+    if(from_len <= to_len) {
+        (void)memcpy(to, from, from_len);
+        return from_len;
+    } else {
+        return TC_CRYPTO_FAIL;
+    }
 }
 
 void _set(void *to, uint8_t val, unsigned int len)
 {
-	(void)memset(to, val, len);
+    (void)memset(to, val, len);
 }
 
 /*
@@ -58,17 +58,18 @@ void _set(void *to, uint8_t val, unsigned int len)
  */
 uint8_t _double_byte(uint8_t a)
 {
-	return ((a<<1) ^ ((a>>7) * MASK_TWENTY_SEVEN));
+    return ((a << 1) ^ ((a >> 7) * MASK_TWENTY_SEVEN));
 }
 
 int _compare(const uint8_t *a, const uint8_t *b, size_t size)
 {
-	const uint8_t *tempa = a;
-	const uint8_t *tempb = b;
-	uint8_t result = 0;
+    const uint8_t *tempa = a;
+    const uint8_t *tempb = b;
+    uint8_t result = 0;
 
-	for (unsigned int i = 0; i < size; i++) {
-		result |= tempa[i] ^ tempb[i];
-	}
-	return result;
+    for(unsigned int i = 0; i < size; i++) {
+        result |= tempa[i] ^ tempb[i];
+    }
+
+    return result;
 }

+ 63 - 62
src/bt/blehost/ext/tinycrypt/src/cbc_mode.c

@@ -35,80 +35,81 @@
 #include <tinycrypt/utils.h>
 
 int tc_cbc_mode_encrypt(uint8_t *out, unsigned int outlen, const uint8_t *in,
-			    unsigned int inlen, const uint8_t *iv,
-			    const TCAesKeySched_t sched)
+                        unsigned int inlen, const uint8_t *iv,
+                        const TCAesKeySched_t sched)
 {
+    uint8_t buffer[TC_AES_BLOCK_SIZE];
+    unsigned int n, m;
 
-	uint8_t buffer[TC_AES_BLOCK_SIZE];
-	unsigned int n, m;
+    /* input sanity check: */
+    if(out == (uint8_t *) 0 ||
+            in == (const uint8_t *) 0 ||
+            sched == (TCAesKeySched_t) 0 ||
+            inlen == 0 ||
+            outlen == 0 ||
+            (inlen % TC_AES_BLOCK_SIZE) != 0 ||
+            (outlen % TC_AES_BLOCK_SIZE) != 0 ||
+            outlen != inlen + TC_AES_BLOCK_SIZE) {
+        return TC_CRYPTO_FAIL;
+    }
 
-	/* input sanity check: */
-	if (out == (uint8_t *) 0 ||
-	    in == (const uint8_t *) 0 ||
-	    sched == (TCAesKeySched_t) 0 ||
-	    inlen == 0 ||
-	    outlen == 0 ||
-	    (inlen % TC_AES_BLOCK_SIZE) != 0 ||
-	    (outlen % TC_AES_BLOCK_SIZE) != 0 ||
-	    outlen != inlen + TC_AES_BLOCK_SIZE) {
-		return TC_CRYPTO_FAIL;
-	}
+    /* copy iv to the buffer */
+    (void)_copy(buffer, TC_AES_BLOCK_SIZE, iv, TC_AES_BLOCK_SIZE);
+    /* copy iv to the output buffer */
+    (void)_copy(out, TC_AES_BLOCK_SIZE, iv, TC_AES_BLOCK_SIZE);
+    out += TC_AES_BLOCK_SIZE;
 
-	/* copy iv to the buffer */
-	(void)_copy(buffer, TC_AES_BLOCK_SIZE, iv, TC_AES_BLOCK_SIZE);
-	/* copy iv to the output buffer */
-	(void)_copy(out, TC_AES_BLOCK_SIZE, iv, TC_AES_BLOCK_SIZE);
-	out += TC_AES_BLOCK_SIZE;
+    for(n = m = 0; n < inlen; ++n) {
+        buffer[m++] ^= *in++;
 
-	for (n = m = 0; n < inlen; ++n) {
-		buffer[m++] ^= *in++;
-		if (m == TC_AES_BLOCK_SIZE) {
-			(void)tc_aes_encrypt(buffer, buffer, sched);
-			(void)_copy(out, TC_AES_BLOCK_SIZE,
-				    buffer, TC_AES_BLOCK_SIZE);
-			out += TC_AES_BLOCK_SIZE;
-			m = 0;
-		}
-	}
+        if(m == TC_AES_BLOCK_SIZE) {
+            (void)tc_aes_encrypt(buffer, buffer, sched);
+            (void)_copy(out, TC_AES_BLOCK_SIZE,
+                        buffer, TC_AES_BLOCK_SIZE);
+            out += TC_AES_BLOCK_SIZE;
+            m = 0;
+        }
+    }
 
-	return TC_CRYPTO_SUCCESS;
+    return TC_CRYPTO_SUCCESS;
 }
 
 int tc_cbc_mode_decrypt(uint8_t *out, unsigned int outlen, const uint8_t *in,
-			    unsigned int inlen, const uint8_t *iv,
-			    const TCAesKeySched_t sched)
+                        unsigned int inlen, const uint8_t *iv,
+                        const TCAesKeySched_t sched)
 {
+    uint8_t buffer[TC_AES_BLOCK_SIZE];
+    const uint8_t *p;
+    unsigned int n, m;
 
-	uint8_t buffer[TC_AES_BLOCK_SIZE];
-	const uint8_t *p;
-	unsigned int n, m;
+    /* sanity check the inputs */
+    if(out == (uint8_t *) 0 ||
+            in == (const uint8_t *) 0 ||
+            sched == (TCAesKeySched_t) 0 ||
+            inlen == 0 ||
+            outlen == 0 ||
+            (inlen % TC_AES_BLOCK_SIZE) != 0 ||
+            (outlen % TC_AES_BLOCK_SIZE) != 0 ||
+            outlen != inlen - TC_AES_BLOCK_SIZE) {
+        return TC_CRYPTO_FAIL;
+    }
 
-	/* sanity check the inputs */
-	if (out == (uint8_t *) 0 ||
-	    in == (const uint8_t *) 0 ||
-	    sched == (TCAesKeySched_t) 0 ||
-	    inlen == 0 ||
-	    outlen == 0 ||
-	    (inlen % TC_AES_BLOCK_SIZE) != 0 ||
-	    (outlen % TC_AES_BLOCK_SIZE) != 0 ||
-	    outlen != inlen - TC_AES_BLOCK_SIZE) {
-		return TC_CRYPTO_FAIL;
-	}
+    /*
+     * Note that in == iv + ciphertext, i.e. the iv and the ciphertext are
+     * contiguous. This allows for a very efficient decryption algorithm
+     * that would not otherwise be possible.
+     */
+    p = iv;
 
-	/*
-	 * Note that in == iv + ciphertext, i.e. the iv and the ciphertext are
-	 * contiguous. This allows for a very efficient decryption algorithm
-	 * that would not otherwise be possible.
-	 */
-	p = iv;
-	for (n = m = 0; n < inlen; ++n) {
-		if ((n % TC_AES_BLOCK_SIZE) == 0) {
-			(void)tc_aes_decrypt(buffer, in, sched);
-			in += TC_AES_BLOCK_SIZE;
-			m = 0;
-		}
-		*out++ = buffer[m++] ^ *p++;
-	}
+    for(n = m = 0; n < inlen; ++n) {
+        if((n % TC_AES_BLOCK_SIZE) == 0) {
+            (void)tc_aes_decrypt(buffer, in, sched);
+            in += TC_AES_BLOCK_SIZE;
+            m = 0;
+        }
 
-	return TC_CRYPTO_SUCCESS;
+        *out++ = buffer[m++] ^ *p++;
+    }
+
+    return TC_CRYPTO_SUCCESS;
 }

+ 195 - 199
src/bt/blehost/ext/tinycrypt/src/ccm_mode.c

@@ -37,50 +37,49 @@
 #include <stdio.h>
 
 int tc_ccm_config(TCCcmMode_t c, TCAesKeySched_t sched, uint8_t *nonce,
-		  unsigned int nlen, unsigned int mlen)
+                  unsigned int nlen, unsigned int mlen)
 {
-
-	/* input sanity check: */
-	if (c == (TCCcmMode_t) 0 ||
-	    sched == (TCAesKeySched_t) 0 ||
-	    nonce == (uint8_t *) 0) {
-		return TC_CRYPTO_FAIL;
-	} else if (nlen != 13) {
-		return TC_CRYPTO_FAIL; /* The allowed nonce size is: 13. See documentation.*/
-	} else if ((mlen < 4) || (mlen > 16) || (mlen & 1)) {
-		return TC_CRYPTO_FAIL; /* The allowed mac sizes are: 4, 6, 8, 10, 12, 14, 16.*/
-	}
-
-	c->mlen = mlen;
-	c->sched = sched;
-	c->nonce = nonce;
-
-	return TC_CRYPTO_SUCCESS;
+    /* input sanity check: */
+    if(c == (TCCcmMode_t) 0 ||
+            sched == (TCAesKeySched_t) 0 ||
+            nonce == (uint8_t *) 0) {
+        return TC_CRYPTO_FAIL;
+    } else if(nlen != 13) {
+        return TC_CRYPTO_FAIL; /* The allowed nonce size is: 13. See documentation.*/
+    } else if((mlen < 4) || (mlen > 16) || (mlen & 1)) {
+        return TC_CRYPTO_FAIL; /* The allowed mac sizes are: 4, 6, 8, 10, 12, 14, 16.*/
+    }
+
+    c->mlen = mlen;
+    c->sched = sched;
+    c->nonce = nonce;
+    return TC_CRYPTO_SUCCESS;
 }
 
 /**
  * Variation of CBC-MAC mode used in CCM.
  */
 static void ccm_cbc_mac(uint8_t *T, const uint8_t *data, unsigned int dlen,
-			unsigned int flag, TCAesKeySched_t sched)
+                        unsigned int flag, TCAesKeySched_t sched)
 {
-
-	unsigned int i;
-
-	if (flag > 0) {
-		T[0] ^= (uint8_t)(dlen >> 8);
-		T[1] ^= (uint8_t)(dlen);
-		dlen += 2; i = 2;
-	} else {
-		i = 0;
-	}
-
-	while (i < dlen) {
-		T[i++ % (Nb * Nk)] ^= *data++;
-		if (((i % (Nb * Nk)) == 0) || dlen == i) {
-			(void) tc_aes_encrypt(T, T, sched);
-		}
-	}
+    unsigned int i;
+
+    if(flag > 0) {
+        T[0] ^= (uint8_t)(dlen >> 8);
+        T[1] ^= (uint8_t)(dlen);
+        dlen += 2;
+        i = 2;
+    } else {
+        i = 0;
+    }
+
+    while(i < dlen) {
+        T[i++ % (Nb * Nk)] ^= *data++;
+
+        if(((i % (Nb * Nk)) == 0) || dlen == i) {
+            (void) tc_aes_encrypt(T, T, sched);
+        }
+    }
 }
 
 /**
@@ -91,176 +90,173 @@ static void ccm_cbc_mac(uint8_t *T, const uint8_t *data, unsigned int dlen,
  * 2 bytes of the nonce.
  */
 static int ccm_ctr_mode(uint8_t *out, unsigned int outlen, const uint8_t *in,
-			unsigned int inlen, uint8_t *ctr, const TCAesKeySched_t sched)
+                        unsigned int inlen, uint8_t *ctr, const TCAesKeySched_t sched)
 {
-
-	uint8_t buffer[TC_AES_BLOCK_SIZE];
-	uint8_t nonce[TC_AES_BLOCK_SIZE];
-	uint16_t block_num;
-	unsigned int i;
-
-	/* input sanity check: */
-	if (out == (uint8_t *) 0 ||
-	    in == (uint8_t *) 0 ||
-	    ctr == (uint8_t *) 0 ||
-	    sched == (TCAesKeySched_t) 0 ||
-	    inlen == 0 ||
-	    outlen == 0 ||
-	    outlen != inlen) {
-		return TC_CRYPTO_FAIL;
-	}
-
-	/* copy the counter to the nonce */
-	(void) _copy(nonce, sizeof(nonce), ctr, sizeof(nonce));
-
-	/* select the last 2 bytes of the nonce to be incremented */
-	block_num = (uint16_t) ((nonce[14] << 8)|(nonce[15]));
-	for (i = 0; i < inlen; ++i) {
-		if ((i % (TC_AES_BLOCK_SIZE)) == 0) {
-			block_num++;
-			nonce[14] = (uint8_t)(block_num >> 8);
-			nonce[15] = (uint8_t)(block_num);
-			if (!tc_aes_encrypt(buffer, nonce, sched)) {
-				return TC_CRYPTO_FAIL;
-			}
-		}
-		/* update the output */
-		*out++ = buffer[i % (TC_AES_BLOCK_SIZE)] ^ *in++;
-	}
-
-	/* update the counter */
-	ctr[14] = nonce[14]; ctr[15] = nonce[15];
-
-	return TC_CRYPTO_SUCCESS;
+    uint8_t buffer[TC_AES_BLOCK_SIZE];
+    uint8_t nonce[TC_AES_BLOCK_SIZE];
+    uint16_t block_num;
+    unsigned int i;
+
+    /* input sanity check: */
+    if(out == (uint8_t *) 0 ||
+            in == (uint8_t *) 0 ||
+            ctr == (uint8_t *) 0 ||
+            sched == (TCAesKeySched_t) 0 ||
+            inlen == 0 ||
+            outlen == 0 ||
+            outlen != inlen) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    /* copy the counter to the nonce */
+    (void) _copy(nonce, sizeof(nonce), ctr, sizeof(nonce));
+    /* select the last 2 bytes of the nonce to be incremented */
+    block_num = (uint16_t)((nonce[14] << 8) | (nonce[15]));
+
+    for(i = 0; i < inlen; ++i) {
+        if((i % (TC_AES_BLOCK_SIZE)) == 0) {
+            block_num++;
+            nonce[14] = (uint8_t)(block_num >> 8);
+            nonce[15] = (uint8_t)(block_num);
+
+            if(!tc_aes_encrypt(buffer, nonce, sched)) {
+                return TC_CRYPTO_FAIL;
+            }
+        }
+
+        /* update the output */
+        *out++ = buffer[i % (TC_AES_BLOCK_SIZE)] ^ *in++;
+    }
+
+    /* update the counter */
+    ctr[14] = nonce[14];
+    ctr[15] = nonce[15];
+    return TC_CRYPTO_SUCCESS;
 }
 
 int tc_ccm_generation_encryption(uint8_t *out, unsigned int olen,
-				 const uint8_t *associated_data,
-				 unsigned int alen, const uint8_t *payload,
-				 unsigned int plen, TCCcmMode_t c)
+                                 const uint8_t *associated_data,
+                                 unsigned int alen, const uint8_t *payload,
+                                 unsigned int plen, TCCcmMode_t c)
 {
-
-	/* input sanity check: */
-	if ((out == (uint8_t *) 0) ||
-		(c == (TCCcmMode_t) 0) ||
-		((plen > 0) && (payload == (uint8_t *) 0)) ||
-		((alen > 0) && (associated_data == (uint8_t *) 0)) ||
-		(alen >= TC_CCM_AAD_MAX_BYTES) || /* associated data size unsupported */
-		(plen >= TC_CCM_PAYLOAD_MAX_BYTES) || /* payload size unsupported */
-		(olen < (plen + c->mlen))) {  /* invalid output buffer size */
-		return TC_CRYPTO_FAIL;
-	}
-
-	uint8_t b[Nb * Nk];
-	uint8_t tag[Nb * Nk];
-	unsigned int i;
-
-	/* GENERATING THE AUTHENTICATION TAG: */
-
-	/* formatting the sequence b for authentication: */
-	b[0] = ((alen > 0) ? 0x40:0) | (((c->mlen - 2) / 2 << 3)) | (1);
-	for (i = 1; i <= 13; ++i) {
-		b[i] = c->nonce[i - 1];
-	}
-	b[14] = (uint8_t)(plen >> 8);
-	b[15] = (uint8_t)(plen);
-
-	/* computing the authentication tag using cbc-mac: */
-	(void) tc_aes_encrypt(tag, b, c->sched);
-	if (alen > 0) {
-		ccm_cbc_mac(tag, associated_data, alen, 1, c->sched);
-	}
-	if (plen > 0) {
-		ccm_cbc_mac(tag, payload, plen, 0, c->sched);
-	}
-
-	/* ENCRYPTION: */
-
-	/* formatting the sequence b for encryption: */
-	b[0] = 1; /* q - 1 = 2 - 1 = 1 */
-	b[14] = b[15] = TC_ZERO_BYTE;
-
-	/* encrypting payload using ctr mode: */
-	ccm_ctr_mode(out, plen, payload, plen, b, c->sched);
-
-	b[14] = b[15] = TC_ZERO_BYTE; /* restoring initial counter for ctr_mode (0):*/
-
-	/* encrypting b and adding the tag to the output: */
-	(void) tc_aes_encrypt(b, b, c->sched);
-	out += plen;
-	for (i = 0; i < c->mlen; ++i) {
-		*out++ = tag[i] ^ b[i];
-	}
-
-	return TC_CRYPTO_SUCCESS;
+    /* input sanity check: */
+    if((out == (uint8_t *) 0) ||
+            (c == (TCCcmMode_t) 0) ||
+            ((plen > 0) && (payload == (uint8_t *) 0)) ||
+            ((alen > 0) && (associated_data == (uint8_t *) 0)) ||
+            (alen >= TC_CCM_AAD_MAX_BYTES) || /* associated data size unsupported */
+            (plen >= TC_CCM_PAYLOAD_MAX_BYTES) || /* payload size unsupported */
+            (olen < (plen + c->mlen))) {  /* invalid output buffer size */
+        return TC_CRYPTO_FAIL;
+    }
+
+    uint8_t b[Nb * Nk];
+    uint8_t tag[Nb * Nk];
+    unsigned int i;
+    /* GENERATING THE AUTHENTICATION TAG: */
+    /* formatting the sequence b for authentication: */
+    b[0] = ((alen > 0) ? 0x40 : 0) | (((c->mlen - 2) / 2 << 3)) | (1);
+
+    for(i = 1; i <= 13; ++i) {
+        b[i] = c->nonce[i - 1];
+    }
+
+    b[14] = (uint8_t)(plen >> 8);
+    b[15] = (uint8_t)(plen);
+    /* computing the authentication tag using cbc-mac: */
+    (void) tc_aes_encrypt(tag, b, c->sched);
+
+    if(alen > 0) {
+        ccm_cbc_mac(tag, associated_data, alen, 1, c->sched);
+    }
+
+    if(plen > 0) {
+        ccm_cbc_mac(tag, payload, plen, 0, c->sched);
+    }
+
+    /* ENCRYPTION: */
+    /* formatting the sequence b for encryption: */
+    b[0] = 1; /* q - 1 = 2 - 1 = 1 */
+    b[14] = b[15] = TC_ZERO_BYTE;
+    /* encrypting payload using ctr mode: */
+    ccm_ctr_mode(out, plen, payload, plen, b, c->sched);
+    b[14] = b[15] = TC_ZERO_BYTE; /* restoring initial counter for ctr_mode (0):*/
+    /* encrypting b and adding the tag to the output: */
+    (void) tc_aes_encrypt(b, b, c->sched);
+    out += plen;
+
+    for(i = 0; i < c->mlen; ++i) {
+        *out++ = tag[i] ^ b[i];
+    }
+
+    return TC_CRYPTO_SUCCESS;
 }
 
 int tc_ccm_decryption_verification(uint8_t *out, unsigned int olen,
-				   const uint8_t *associated_data,
-				   unsigned int alen, const uint8_t *payload,
-				   unsigned int plen, TCCcmMode_t c)
+                                   const uint8_t *associated_data,
+                                   unsigned int alen, const uint8_t *payload,
+                                   unsigned int plen, TCCcmMode_t c)
 {
-
-	/* input sanity check: */
-	if ((out == (uint8_t *) 0) ||
-	    (c == (TCCcmMode_t) 0) ||
-	    ((plen > 0) && (payload == (uint8_t *) 0)) ||
-	    ((alen > 0) && (associated_data == (uint8_t *) 0)) ||
-	    (alen >= TC_CCM_AAD_MAX_BYTES) || /* associated data size unsupported */
-	    (plen >= TC_CCM_PAYLOAD_MAX_BYTES) || /* payload size unsupported */
-	    (olen < plen - c->mlen)) { /* invalid output buffer size */
-		return TC_CRYPTO_FAIL;
-  }
-
-	uint8_t b[Nb * Nk];
-	uint8_t tag[Nb * Nk];
-	unsigned int i;
-
-	/* DECRYPTION: */
-
-	/* formatting the sequence b for decryption: */
-	b[0] = 1; /* q - 1 = 2 - 1 = 1 */
-	for (i = 1; i < 14; ++i) {
-		b[i] = c->nonce[i - 1];
-	}
-	b[14] = b[15] = TC_ZERO_BYTE; /* initial counter value is 0 */
-
-	/* decrypting payload using ctr mode: */
-	ccm_ctr_mode(out, plen - c->mlen, payload, plen - c->mlen, b, c->sched);
-
-	b[14] = b[15] = TC_ZERO_BYTE; /* restoring initial counter value (0) */
-
-	/* encrypting b and restoring the tag from input: */
-	(void) tc_aes_encrypt(b, b, c->sched);
-	for (i = 0; i < c->mlen; ++i) {
-		tag[i] = *(payload + plen - c->mlen + i) ^ b[i];
-	}
-
-	/* VERIFYING THE AUTHENTICATION TAG: */
-
-	/* formatting the sequence b for authentication: */
-	b[0] = ((alen > 0) ? 0x40:0)|(((c->mlen - 2) / 2 << 3)) | (1);
-	for (i = 1; i < 14; ++i) {
-		b[i] = c->nonce[i - 1];
-	}
-	b[14] = (uint8_t)((plen - c->mlen) >> 8);
-	b[15] = (uint8_t)(plen - c->mlen);
-
-	/* computing the authentication tag using cbc-mac: */
-	(void) tc_aes_encrypt(b, b, c->sched);
-	if (alen > 0) {
-		ccm_cbc_mac(b, associated_data, alen, 1, c->sched);
-	}
-	if (plen > 0) {
-		ccm_cbc_mac(b, out, plen - c->mlen, 0, c->sched);
-	}
-
-	/* comparing the received tag and the computed one: */
-	if (_compare(b, tag, c->mlen) == 0) {
-		return TC_CRYPTO_SUCCESS;
-  	} else {
-		/* erase the decrypted buffer in case of mac validation failure: */
-		_set(out, 0, plen - c->mlen);
-		return TC_CRYPTO_FAIL;
-	}
+    /* input sanity check: */
+    if((out == (uint8_t *) 0) ||
+            (c == (TCCcmMode_t) 0) ||
+            ((plen > 0) && (payload == (uint8_t *) 0)) ||
+            ((alen > 0) && (associated_data == (uint8_t *) 0)) ||
+            (alen >= TC_CCM_AAD_MAX_BYTES) || /* associated data size unsupported */
+            (plen >= TC_CCM_PAYLOAD_MAX_BYTES) || /* payload size unsupported */
+            (olen < plen - c->mlen)) { /* invalid output buffer size */
+        return TC_CRYPTO_FAIL;
+    }
+
+    uint8_t b[Nb * Nk];
+    uint8_t tag[Nb * Nk];
+    unsigned int i;
+    /* DECRYPTION: */
+    /* formatting the sequence b for decryption: */
+    b[0] = 1; /* q - 1 = 2 - 1 = 1 */
+
+    for(i = 1; i < 14; ++i) {
+        b[i] = c->nonce[i - 1];
+    }
+
+    b[14] = b[15] = TC_ZERO_BYTE; /* initial counter value is 0 */
+    /* decrypting payload using ctr mode: */
+    ccm_ctr_mode(out, plen - c->mlen, payload, plen - c->mlen, b, c->sched);
+    b[14] = b[15] = TC_ZERO_BYTE; /* restoring initial counter value (0) */
+    /* encrypting b and restoring the tag from input: */
+    (void) tc_aes_encrypt(b, b, c->sched);
+
+    for(i = 0; i < c->mlen; ++i) {
+        tag[i] = *(payload + plen - c->mlen + i) ^ b[i];
+    }
+
+    /* VERIFYING THE AUTHENTICATION TAG: */
+    /* formatting the sequence b for authentication: */
+    b[0] = ((alen > 0) ? 0x40 : 0) | (((c->mlen - 2) / 2 << 3)) | (1);
+
+    for(i = 1; i < 14; ++i) {
+        b[i] = c->nonce[i - 1];
+    }
+
+    b[14] = (uint8_t)((plen - c->mlen) >> 8);
+    b[15] = (uint8_t)(plen - c->mlen);
+    /* computing the authentication tag using cbc-mac: */
+    (void) tc_aes_encrypt(b, b, c->sched);
+
+    if(alen > 0) {
+        ccm_cbc_mac(b, associated_data, alen, 1, c->sched);
+    }
+
+    if(plen > 0) {
+        ccm_cbc_mac(b, out, plen - c->mlen, 0, c->sched);
+    }
+
+    /* comparing the received tag and the computed one: */
+    if(_compare(b, tag, c->mlen) == 0) {
+        return TC_CRYPTO_SUCCESS;
+    } else {
+        /* erase the decrypted buffer in case of mac validation failure: */
+        _set(out, 0, plen - c->mlen);
+        return TC_CRYPTO_FAIL;
+    }
 }

+ 144 - 150
src/bt/blehost/ext/tinycrypt/src/cmac_mode.c

@@ -77,178 +77,172 @@ const unsigned char gf_wrap = 0x87;
  */
 void gf_double(uint8_t *out, uint8_t *in)
 {
+    /* start with low order byte */
+    uint8_t *x = in + (TC_AES_BLOCK_SIZE - 1);
+    /* if msb == 1, we need to add the gf_wrap value, otherwise add 0 */
+    uint8_t carry = (in[0] >> 7) ? gf_wrap : 0;
+    out += (TC_AES_BLOCK_SIZE - 1);
 
-	/* start with low order byte */
-	uint8_t *x = in + (TC_AES_BLOCK_SIZE - 1);
+    for(;;) {
+        *out-- = (*x << 1) ^ carry;
 
-	/* if msb == 1, we need to add the gf_wrap value, otherwise add 0 */
-	uint8_t carry = (in[0] >> 7) ? gf_wrap : 0;
+        if(x == in) {
+            break;
+        }
 
-	out += (TC_AES_BLOCK_SIZE - 1);
-	for (;;) {
-		*out-- = (*x << 1) ^ carry;
-		if (x == in) {
-			break;
-		}
-		carry = *x-- >> 7;
-	}
+        carry = *x-- >> 7;
+    }
 }
 
 int tc_cmac_setup(TCCmacState_t s, const uint8_t *key, TCAesKeySched_t sched)
 {
-
-	/* input sanity check: */
-	if (s == (TCCmacState_t) 0 ||
-	    key == (const uint8_t *) 0) {
-		return TC_CRYPTO_FAIL;
-	}
-
-	/* put s into a known state */
-	_set(s, 0, sizeof(*s));
-	s->sched = sched;
-
-	/* configure the encryption key used by the underlying block cipher */
-	tc_aes128_set_encrypt_key(s->sched, key);
-
-	/* compute s->K1 and s->K2 from s->iv using s->keyid */
-	_set(s->iv, 0, TC_AES_BLOCK_SIZE);
-	tc_aes_encrypt(s->iv, s->iv, s->sched);
-	gf_double (s->K1, s->iv);
-	gf_double (s->K2, s->K1);
-
-	/* reset s->iv to 0 in case someone wants to compute now */
-	tc_cmac_init(s);
-
-	return TC_CRYPTO_SUCCESS;
+    /* input sanity check: */
+    if(s == (TCCmacState_t) 0 ||
+            key == (const uint8_t *) 0) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    /* put s into a known state */
+    _set(s, 0, sizeof(*s));
+    s->sched = sched;
+    /* configure the encryption key used by the underlying block cipher */
+    tc_aes128_set_encrypt_key(s->sched, key);
+    /* compute s->K1 and s->K2 from s->iv using s->keyid */
+    _set(s->iv, 0, TC_AES_BLOCK_SIZE);
+    tc_aes_encrypt(s->iv, s->iv, s->sched);
+    gf_double(s->K1, s->iv);
+    gf_double(s->K2, s->K1);
+    /* reset s->iv to 0 in case someone wants to compute now */
+    tc_cmac_init(s);
+    return TC_CRYPTO_SUCCESS;
 }
 
 int tc_cmac_erase(TCCmacState_t s)
 {
-	if (s == (TCCmacState_t) 0) {
-		return TC_CRYPTO_FAIL;
-	}
+    if(s == (TCCmacState_t) 0) {
+        return TC_CRYPTO_FAIL;
+    }
 
-	/* destroy the current state */
-	_set(s, 0, sizeof(*s));
-
-	return TC_CRYPTO_SUCCESS;
+    /* destroy the current state */
+    _set(s, 0, sizeof(*s));
+    return TC_CRYPTO_SUCCESS;
 }
 
 int tc_cmac_init(TCCmacState_t s)
 {
-	/* input sanity check: */
-	if (s == (TCCmacState_t) 0) {
-		return TC_CRYPTO_FAIL;
-	}
-
-	/* CMAC starts with an all zero initialization vector */
-	_set(s->iv, 0, TC_AES_BLOCK_SIZE);
-
-	/* and the leftover buffer is empty */
-	_set(s->leftover, 0, TC_AES_BLOCK_SIZE);
-	s->leftover_offset = 0;
-
-	/* Set countdown to max number of calls allowed before re-keying: */
-	s->countdown = MAX_CALLS;
-
-	return TC_CRYPTO_SUCCESS;
+    /* input sanity check: */
+    if(s == (TCCmacState_t) 0) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    /* CMAC starts with an all zero initialization vector */
+    _set(s->iv, 0, TC_AES_BLOCK_SIZE);
+    /* and the leftover buffer is empty */
+    _set(s->leftover, 0, TC_AES_BLOCK_SIZE);
+    s->leftover_offset = 0;
+    /* Set countdown to max number of calls allowed before re-keying: */
+    s->countdown = MAX_CALLS;
+    return TC_CRYPTO_SUCCESS;
 }
 
 int tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t data_length)
 {
-	unsigned int i;
-
-	/* input sanity check: */
-	if (s == (TCCmacState_t) 0) {
-		return TC_CRYPTO_FAIL;
-	}
-	if (data_length == 0) {
-		return  TC_CRYPTO_SUCCESS;
-	}
-	if (data == (const uint8_t *) 0) {
-		return TC_CRYPTO_FAIL;
-	}
-
-	if (s->countdown == 0) {
-		return TC_CRYPTO_FAIL;
-	}
-
-	s->countdown--;
-
-	if (s->leftover_offset > 0) {
-		/* last data added to s didn't end on a TC_AES_BLOCK_SIZE byte boundary */
-		size_t remaining_space = TC_AES_BLOCK_SIZE - s->leftover_offset;
-
-		if (data_length < remaining_space) {
-			/* still not enough data to encrypt this time either */
-			_copy(&s->leftover[s->leftover_offset], data_length, data, data_length);
-			s->leftover_offset += data_length;
-			return TC_CRYPTO_SUCCESS;
-		}
-		/* leftover block is now full; encrypt it first */
-		_copy(&s->leftover[s->leftover_offset],
-		      remaining_space,
-		      data,
-		      remaining_space);
-		data_length -= remaining_space;
-		data += remaining_space;
-		s->leftover_offset = 0;
-
-		for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
-			s->iv[i] ^= s->leftover[i];
-		}
-		tc_aes_encrypt(s->iv, s->iv, s->sched);
-	}
-
-	/* CBC encrypt each (except the last) of the data blocks */
-	while (data_length > TC_AES_BLOCK_SIZE) {
-		for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
-			s->iv[i] ^= data[i];
-		}
-		tc_aes_encrypt(s->iv, s->iv, s->sched);
-		data += TC_AES_BLOCK_SIZE;
-		data_length  -= TC_AES_BLOCK_SIZE;
-	}
-
-	if (data_length > 0) {
-		/* save leftover data for next time */
-		_copy(s->leftover, data_length, data, data_length);
-		s->leftover_offset = data_length;
-	}
-
-	return TC_CRYPTO_SUCCESS;
+    unsigned int i;
+
+    /* input sanity check: */
+    if(s == (TCCmacState_t) 0) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    if(data_length == 0) {
+        return  TC_CRYPTO_SUCCESS;
+    }
+
+    if(data == (const uint8_t *) 0) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    if(s->countdown == 0) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    s->countdown--;
+
+    if(s->leftover_offset > 0) {
+        /* last data added to s didn't end on a TC_AES_BLOCK_SIZE byte boundary */
+        size_t remaining_space = TC_AES_BLOCK_SIZE - s->leftover_offset;
+
+        if(data_length < remaining_space) {
+            /* still not enough data to encrypt this time either */
+            _copy(&s->leftover[s->leftover_offset], data_length, data, data_length);
+            s->leftover_offset += data_length;
+            return TC_CRYPTO_SUCCESS;
+        }
+
+        /* leftover block is now full; encrypt it first */
+        _copy(&s->leftover[s->leftover_offset],
+              remaining_space,
+              data,
+              remaining_space);
+        data_length -= remaining_space;
+        data += remaining_space;
+        s->leftover_offset = 0;
+
+        for(i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
+            s->iv[i] ^= s->leftover[i];
+        }
+
+        tc_aes_encrypt(s->iv, s->iv, s->sched);
+    }
+
+    /* CBC encrypt each (except the last) of the data blocks */
+    while(data_length > TC_AES_BLOCK_SIZE) {
+        for(i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
+            s->iv[i] ^= data[i];
+        }
+
+        tc_aes_encrypt(s->iv, s->iv, s->sched);
+        data += TC_AES_BLOCK_SIZE;
+        data_length  -= TC_AES_BLOCK_SIZE;
+    }
+
+    if(data_length > 0) {
+        /* save leftover data for next time */
+        _copy(s->leftover, data_length, data, data_length);
+        s->leftover_offset = data_length;
+    }
+
+    return TC_CRYPTO_SUCCESS;
 }
 
 int tc_cmac_final(uint8_t *tag, TCCmacState_t s)
 {
-	uint8_t *k;
-	unsigned int i;
-
-	/* input sanity check: */
-	if (tag == (uint8_t *) 0 ||
-	    s == (TCCmacState_t) 0) {
-		return TC_CRYPTO_FAIL;
-	}
-
-	if (s->leftover_offset == TC_AES_BLOCK_SIZE) {
-		/* the last message block is a full-sized block */
-		k = (uint8_t *) s->K1;
-	} else {
-		/* the final message block is not a full-sized  block */
-		size_t remaining = TC_AES_BLOCK_SIZE - s->leftover_offset;
-
-		_set(&s->leftover[s->leftover_offset], 0, remaining);
-		s->leftover[s->leftover_offset] = TC_CMAC_PADDING;
-		k = (uint8_t *) s->K2;
-	}
-	for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
-		s->iv[i] ^= s->leftover[i] ^ k[i];
-	}
-
-	tc_aes_encrypt(tag, s->iv, s->sched);
-
-	/* erasing state: */
-	tc_cmac_erase(s);
-
-	return TC_CRYPTO_SUCCESS;
+    uint8_t *k;
+    unsigned int i;
+
+    /* input sanity check: */
+    if(tag == (uint8_t *) 0 ||
+            s == (TCCmacState_t) 0) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    if(s->leftover_offset == TC_AES_BLOCK_SIZE) {
+        /* the last message block is a full-sized block */
+        k = (uint8_t *) s->K1;
+    } else {
+        /* the final message block is not a full-sized  block */
+        size_t remaining = TC_AES_BLOCK_SIZE - s->leftover_offset;
+        _set(&s->leftover[s->leftover_offset], 0, remaining);
+        s->leftover[s->leftover_offset] = TC_CMAC_PADDING;
+        k = (uint8_t *) s->K2;
+    }
+
+    for(i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
+        s->iv[i] ^= s->leftover[i] ^ k[i];
+    }
+
+    tc_aes_encrypt(tag, s->iv, s->sched);
+    /* erasing state: */
+    tc_cmac_erase(s);
+    return TC_CRYPTO_SUCCESS;
 }

+ 42 - 41
src/bt/blehost/ext/tinycrypt/src/ctr_mode.c

@@ -35,51 +35,52 @@
 #include <tinycrypt/utils.h>
 
 int tc_ctr_mode(uint8_t *out, unsigned int outlen, const uint8_t *in,
-		unsigned int inlen, uint8_t *ctr, const TCAesKeySched_t sched)
+                unsigned int inlen, uint8_t *ctr, const TCAesKeySched_t sched)
 {
+    uint8_t buffer[TC_AES_BLOCK_SIZE];
+    uint8_t nonce[TC_AES_BLOCK_SIZE];
+    unsigned int block_num;
+    unsigned int i;
 
-	uint8_t buffer[TC_AES_BLOCK_SIZE];
-	uint8_t nonce[TC_AES_BLOCK_SIZE];
-	unsigned int block_num;
-	unsigned int i;
+    /* input sanity check: */
+    if(out == (uint8_t *) 0 ||
+            in == (uint8_t *) 0 ||
+            ctr == (uint8_t *) 0 ||
+            sched == (TCAesKeySched_t) 0 ||
+            inlen == 0 ||
+            outlen == 0 ||
+            outlen != inlen) {
+        return TC_CRYPTO_FAIL;
+    }
 
-	/* input sanity check: */
-	if (out == (uint8_t *) 0 ||
-	    in == (uint8_t *) 0 ||
-	    ctr == (uint8_t *) 0 ||
-	    sched == (TCAesKeySched_t) 0 ||
-	    inlen == 0 ||
-	    outlen == 0 ||
-	    outlen != inlen) {
-		return TC_CRYPTO_FAIL;
-	}
+    /* copy the ctr to the nonce */
+    (void)_copy(nonce, sizeof(nonce), ctr, sizeof(nonce));
+    /* select the last 4 bytes of the nonce to be incremented */
+    block_num = (nonce[12] << 24) | (nonce[13] << 16) |
+                (nonce[14] << 8) | (nonce[15]);
 
-	/* copy the ctr to the nonce */
-	(void)_copy(nonce, sizeof(nonce), ctr, sizeof(nonce));
+    for(i = 0; i < inlen; ++i) {
+        if((i % (TC_AES_BLOCK_SIZE)) == 0) {
+            /* encrypt data using the current nonce */
+            if(tc_aes_encrypt(buffer, nonce, sched)) {
+                block_num++;
+                nonce[12] = (uint8_t)(block_num >> 24);
+                nonce[13] = (uint8_t)(block_num >> 16);
+                nonce[14] = (uint8_t)(block_num >> 8);
+                nonce[15] = (uint8_t)(block_num);
+            } else {
+                return TC_CRYPTO_FAIL;
+            }
+        }
 
-	/* select the last 4 bytes of the nonce to be incremented */
-	block_num = (nonce[12] << 24) | (nonce[13] << 16) |
-		    (nonce[14] << 8) | (nonce[15]);
-	for (i = 0; i < inlen; ++i) {
-		if ((i % (TC_AES_BLOCK_SIZE)) == 0) {
-			/* encrypt data using the current nonce */
-			if (tc_aes_encrypt(buffer, nonce, sched)) {
-				block_num++;
-				nonce[12] = (uint8_t)(block_num >> 24);
-				nonce[13] = (uint8_t)(block_num >> 16);
-				nonce[14] = (uint8_t)(block_num >> 8);
-				nonce[15] = (uint8_t)(block_num);
-			} else {
-				return TC_CRYPTO_FAIL;
-			}
-		}
-		/* update the output */
-		*out++ = buffer[i%(TC_AES_BLOCK_SIZE)] ^ *in++;
-	}
+        /* update the output */
+        *out++ = buffer[i % (TC_AES_BLOCK_SIZE)] ^ *in++;
+    }
 
-	/* update the counter */
-	ctr[12] = nonce[12]; ctr[13] = nonce[13];
-	ctr[14] = nonce[14]; ctr[15] = nonce[15];
-
-	return TC_CRYPTO_SUCCESS;
+    /* update the counter */
+    ctr[12] = nonce[12];
+    ctr[13] = nonce[13];
+    ctr[14] = nonce[14];
+    ctr[15] = nonce[15];
+    return TC_CRYPTO_SUCCESS;
 }

+ 197 - 200
src/bt/blehost/ext/tinycrypt/src/ctr_prng.c

@@ -52,14 +52,15 @@
  */
 static void arrInc(uint8_t arr[], unsigned int len)
 {
-	unsigned int i;
-	if (0 != arr) {
-		for (i = len; i > 0U; i--) {
-			if (++arr[i-1] != 0U) {
-				break;
-			}
-		}
-	}
+    unsigned int i;
+
+    if(0 != arr) {
+        for(i = len; i > 0U; i--) {
+            if(++arr[i - 1] != 0U) {
+                break;
+            }
+        }
+    }
 }
 
 /**
@@ -71,211 +72,207 @@ static void arrInc(uint8_t arr[], unsigned int len)
  *  @param ctx IN/OUT -- CTR PRNG state
  *  @param providedData IN -- data used when updating the internal state
  */
-static void tc_ctr_prng_update(TCCtrPrng_t * const ctx, uint8_t const * const providedData)
+static void tc_ctr_prng_update(TCCtrPrng_t *const ctx, uint8_t const *const providedData)
 {
-	if (0 != ctx) {
-		/* 10.2.1.2 step 1 */
-		uint8_t temp[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE];
-		unsigned int len = 0U;
-
-		/* 10.2.1.2 step 2 */
-		while (len < sizeof temp) {
-			unsigned int blocklen = sizeof(temp) - len;
-			uint8_t output_block[TC_AES_BLOCK_SIZE];
-
-			/* 10.2.1.2 step 2.1 */
-			arrInc(ctx->V, sizeof ctx->V);
-
-			/* 10.2.1.2 step 2.2 */
-			if (blocklen > TC_AES_BLOCK_SIZE) {
-				blocklen = TC_AES_BLOCK_SIZE;
-			}
-			(void)tc_aes_encrypt(output_block, ctx->V, &ctx->key);
-
-			/* 10.2.1.2 step 2.3/step 3 */
-			memcpy(&(temp[len]), output_block, blocklen);
-
-			len += blocklen;
-		}
-
-		/* 10.2.1.2 step 4 */
-		if (0 != providedData) {
-			unsigned int i;
-			for (i = 0U; i < sizeof temp; i++) {
-				temp[i] ^= providedData[i];
-			}
-		}
-
-		/* 10.2.1.2 step 5 */
-		(void)tc_aes128_set_encrypt_key(&ctx->key, temp);
-    
-		/* 10.2.1.2 step 6 */
-		memcpy(ctx->V, &(temp[TC_AES_KEY_SIZE]), TC_AES_BLOCK_SIZE);
-	}
+    if(0 != ctx) {
+        /* 10.2.1.2 step 1 */
+        uint8_t temp[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE];
+        unsigned int len = 0U;
+
+        /* 10.2.1.2 step 2 */
+        while(len < sizeof temp) {
+            unsigned int blocklen = sizeof(temp) - len;
+            uint8_t output_block[TC_AES_BLOCK_SIZE];
+            /* 10.2.1.2 step 2.1 */
+            arrInc(ctx->V, sizeof ctx->V);
+
+            /* 10.2.1.2 step 2.2 */
+            if(blocklen > TC_AES_BLOCK_SIZE) {
+                blocklen = TC_AES_BLOCK_SIZE;
+            }
+
+            (void)tc_aes_encrypt(output_block, ctx->V, &ctx->key);
+            /* 10.2.1.2 step 2.3/step 3 */
+            memcpy(&(temp[len]), output_block, blocklen);
+            len += blocklen;
+        }
+
+        /* 10.2.1.2 step 4 */
+        if(0 != providedData) {
+            unsigned int i;
+
+            for(i = 0U; i < sizeof temp; i++) {
+                temp[i] ^= providedData[i];
+            }
+        }
+
+        /* 10.2.1.2 step 5 */
+        (void)tc_aes128_set_encrypt_key(&ctx->key, temp);
+        /* 10.2.1.2 step 6 */
+        memcpy(ctx->V, &(temp[TC_AES_KEY_SIZE]), TC_AES_BLOCK_SIZE);
+    }
 }
 
-int tc_ctr_prng_init(TCCtrPrng_t * const ctx, 
-		     uint8_t const * const entropy,
-		     unsigned int entropyLen, 
-		     uint8_t const * const personalization,
-		     unsigned int pLen)
+int tc_ctr_prng_init(TCCtrPrng_t *const ctx,
+                     uint8_t const *const entropy,
+                     unsigned int entropyLen,
+                     uint8_t const *const personalization,
+                     unsigned int pLen)
 {
-	int result = TC_CRYPTO_FAIL;	
-	unsigned int i;
-	uint8_t personalization_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U};
-	uint8_t seed_material[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE];
-	uint8_t zeroArr[TC_AES_BLOCK_SIZE] = {0U};
-  
-	if (0 != personalization) {
-		/* 10.2.1.3.1 step 1 */
-		unsigned int len = pLen;
-		if (len > sizeof personalization_buf) {
-			len = sizeof personalization_buf;
-		}
-
-		/* 10.2.1.3.1 step 2 */
-		memcpy(personalization_buf, personalization, len);
-	}
-
-	if ((0 != ctx) && (0 != entropy) && (entropyLen >= sizeof seed_material)) {
-		/* 10.2.1.3.1 step 3 */
-		memcpy(seed_material, entropy, sizeof seed_material);
-		for (i = 0U; i < sizeof seed_material; i++) {
-			seed_material[i] ^= personalization_buf[i];
-		}
-
-		/* 10.2.1.3.1 step 4 */
-		(void)tc_aes128_set_encrypt_key(&ctx->key, zeroArr);
-
-		/* 10.2.1.3.1 step 5 */
-		memset(ctx->V,   0x00, sizeof ctx->V);
-    
-		/* 10.2.1.3.1 step 6 */    
-		tc_ctr_prng_update(ctx, seed_material);
-
-		/* 10.2.1.3.1 step 7 */
-		ctx->reseedCount = 1U;
-
-		result = TC_CRYPTO_SUCCESS;
-	}
-	return result;
+    int result = TC_CRYPTO_FAIL;
+    unsigned int i;
+    uint8_t personalization_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U};
+    uint8_t seed_material[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE];
+    uint8_t zeroArr[TC_AES_BLOCK_SIZE] = {0U};
+
+    if(0 != personalization) {
+        /* 10.2.1.3.1 step 1 */
+        unsigned int len = pLen;
+
+        if(len > sizeof personalization_buf) {
+            len = sizeof personalization_buf;
+        }
+
+        /* 10.2.1.3.1 step 2 */
+        memcpy(personalization_buf, personalization, len);
+    }
+
+    if((0 != ctx) && (0 != entropy) && (entropyLen >= sizeof seed_material)) {
+        /* 10.2.1.3.1 step 3 */
+        memcpy(seed_material, entropy, sizeof seed_material);
+
+        for(i = 0U; i < sizeof seed_material; i++) {
+            seed_material[i] ^= personalization_buf[i];
+        }
+
+        /* 10.2.1.3.1 step 4 */
+        (void)tc_aes128_set_encrypt_key(&ctx->key, zeroArr);
+        /* 10.2.1.3.1 step 5 */
+        memset(ctx->V,   0x00, sizeof ctx->V);
+        /* 10.2.1.3.1 step 6 */
+        tc_ctr_prng_update(ctx, seed_material);
+        /* 10.2.1.3.1 step 7 */
+        ctx->reseedCount = 1U;
+        result = TC_CRYPTO_SUCCESS;
+    }
+
+    return result;
 }
 
-int tc_ctr_prng_reseed(TCCtrPrng_t * const ctx, 
-			uint8_t const * const entropy,
-			unsigned int entropyLen,
-			uint8_t const * const additional_input,
-			unsigned int additionallen)
+int tc_ctr_prng_reseed(TCCtrPrng_t *const ctx,
+                       uint8_t const *const entropy,
+                       unsigned int entropyLen,
+                       uint8_t const *const additional_input,
+                       unsigned int additionallen)
 {
-	unsigned int i;
-	int result = TC_CRYPTO_FAIL;
-	uint8_t additional_input_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U};
-	uint8_t seed_material[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE];
-
-	if (0 != additional_input) {
-		/* 10.2.1.4.1 step 1 */
-		unsigned int len = additionallen;
-		if (len > sizeof additional_input_buf) {
-			len = sizeof additional_input_buf;
-		}
-
-		/* 10.2.1.4.1 step 2 */
-		memcpy(additional_input_buf, additional_input, len);
-	}
-	
-	unsigned int seedlen = (unsigned int)TC_AES_KEY_SIZE + (unsigned int)TC_AES_BLOCK_SIZE;
-	if ((0 != ctx) && (entropyLen >= seedlen)) {
-		/* 10.2.1.4.1 step 3 */
-		memcpy(seed_material, entropy, sizeof seed_material);
-		for (i = 0U; i < sizeof seed_material; i++) {
-			seed_material[i] ^= additional_input_buf[i];
-		}
-
-		/* 10.2.1.4.1 step 4 */
-		tc_ctr_prng_update(ctx, seed_material);
-
-		/* 10.2.1.4.1 step 5 */
-		ctx->reseedCount = 1U;
-
-		result = TC_CRYPTO_SUCCESS;
-	}
-	return result;
+    unsigned int i;
+    int result = TC_CRYPTO_FAIL;
+    uint8_t additional_input_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U};
+    uint8_t seed_material[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE];
+
+    if(0 != additional_input) {
+        /* 10.2.1.4.1 step 1 */
+        unsigned int len = additionallen;
+
+        if(len > sizeof additional_input_buf) {
+            len = sizeof additional_input_buf;
+        }
+
+        /* 10.2.1.4.1 step 2 */
+        memcpy(additional_input_buf, additional_input, len);
+    }
+
+    unsigned int seedlen = (unsigned int)TC_AES_KEY_SIZE + (unsigned int)TC_AES_BLOCK_SIZE;
+
+    if((0 != ctx) && (entropyLen >= seedlen)) {
+        /* 10.2.1.4.1 step 3 */
+        memcpy(seed_material, entropy, sizeof seed_material);
+
+        for(i = 0U; i < sizeof seed_material; i++) {
+            seed_material[i] ^= additional_input_buf[i];
+        }
+
+        /* 10.2.1.4.1 step 4 */
+        tc_ctr_prng_update(ctx, seed_material);
+        /* 10.2.1.4.1 step 5 */
+        ctx->reseedCount = 1U;
+        result = TC_CRYPTO_SUCCESS;
+    }
+
+    return result;
 }
 
-int tc_ctr_prng_generate(TCCtrPrng_t * const ctx,
-			uint8_t const * const additional_input,
-			unsigned int additionallen,
-			uint8_t * const out,
-			unsigned int outlen)
+int tc_ctr_prng_generate(TCCtrPrng_t *const ctx,
+                         uint8_t const *const additional_input,
+                         unsigned int additionallen,
+                         uint8_t *const out,
+                         unsigned int outlen)
 {
-	/* 2^48 - see section 10.2.1 */
-	static const uint64_t MAX_REQS_BEFORE_RESEED = 0x1000000000000ULL; 
-
-	/* 2^19 bits - see section 10.2.1 */ 
-	static const unsigned int MAX_BYTES_PER_REQ = 65536U; 
-
-	unsigned int result = TC_CRYPTO_FAIL;
-
-	if ((0 != ctx) && (0 != out) && (outlen < MAX_BYTES_PER_REQ)) {
-		/* 10.2.1.5.1 step 1 */
-		if (ctx->reseedCount > MAX_REQS_BEFORE_RESEED) {
-			result = TC_CTR_PRNG_RESEED_REQ;
-		} else {
-			uint8_t additional_input_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U};
-			if (0 != additional_input) {
-				/* 10.2.1.5.1 step 2  */
-				unsigned int len = additionallen;
-				if (len > sizeof additional_input_buf) {
-					len = sizeof additional_input_buf;
-				}
-				memcpy(additional_input_buf, additional_input, len);
-				tc_ctr_prng_update(ctx, additional_input_buf);
-			}
-      
-			/* 10.2.1.5.1 step 3 - implicit */
-
-			/* 10.2.1.5.1 step 4 */
-			unsigned int len = 0U;      
-			while (len < outlen) {
-				unsigned int blocklen = outlen - len;
-				uint8_t output_block[TC_AES_BLOCK_SIZE];
-
-				/* 10.2.1.5.1 step 4.1 */
-				arrInc(ctx->V, sizeof ctx->V);
-
-				/* 10.2.1.5.1 step 4.2 */
-				(void)tc_aes_encrypt(output_block, ctx->V, &ctx->key);
-      
-				/* 10.2.1.5.1 step 4.3/step 5 */
-				if (blocklen > TC_AES_BLOCK_SIZE) {
-					blocklen = TC_AES_BLOCK_SIZE;
-				}
-				memcpy(&(out[len]), output_block, blocklen);
-
-				len += blocklen;
-			}
-      
-			/* 10.2.1.5.1 step 6 */
-			tc_ctr_prng_update(ctx, additional_input_buf);
-
-			/* 10.2.1.5.1 step 7 */
-			ctx->reseedCount++;
-
-			/* 10.2.1.5.1 step 8 */
-			result = TC_CRYPTO_SUCCESS;
-		}
-	}
-
-	return result;
+    /* 2^48 - see section 10.2.1 */
+    static const uint64_t MAX_REQS_BEFORE_RESEED = 0x1000000000000ULL;
+    /* 2^19 bits - see section 10.2.1 */
+    static const unsigned int MAX_BYTES_PER_REQ = 65536U;
+    unsigned int result = TC_CRYPTO_FAIL;
+
+    if((0 != ctx) && (0 != out) && (outlen < MAX_BYTES_PER_REQ)) {
+        /* 10.2.1.5.1 step 1 */
+        if(ctx->reseedCount > MAX_REQS_BEFORE_RESEED) {
+            result = TC_CTR_PRNG_RESEED_REQ;
+        } else {
+            uint8_t additional_input_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U};
+
+            if(0 != additional_input) {
+                /* 10.2.1.5.1 step 2  */
+                unsigned int len = additionallen;
+
+                if(len > sizeof additional_input_buf) {
+                    len = sizeof additional_input_buf;
+                }
+
+                memcpy(additional_input_buf, additional_input, len);
+                tc_ctr_prng_update(ctx, additional_input_buf);
+            }
+
+            /* 10.2.1.5.1 step 3 - implicit */
+            /* 10.2.1.5.1 step 4 */
+            unsigned int len = 0U;
+
+            while(len < outlen) {
+                unsigned int blocklen = outlen - len;
+                uint8_t output_block[TC_AES_BLOCK_SIZE];
+                /* 10.2.1.5.1 step 4.1 */
+                arrInc(ctx->V, sizeof ctx->V);
+                /* 10.2.1.5.1 step 4.2 */
+                (void)tc_aes_encrypt(output_block, ctx->V, &ctx->key);
+
+                /* 10.2.1.5.1 step 4.3/step 5 */
+                if(blocklen > TC_AES_BLOCK_SIZE) {
+                    blocklen = TC_AES_BLOCK_SIZE;
+                }
+
+                memcpy(&(out[len]), output_block, blocklen);
+                len += blocklen;
+            }
+
+            /* 10.2.1.5.1 step 6 */
+            tc_ctr_prng_update(ctx, additional_input_buf);
+            /* 10.2.1.5.1 step 7 */
+            ctx->reseedCount++;
+            /* 10.2.1.5.1 step 8 */
+            result = TC_CRYPTO_SUCCESS;
+        }
+    }
+
+    return result;
 }
 
-void tc_ctr_prng_uninstantiate(TCCtrPrng_t * const ctx)
+void tc_ctr_prng_uninstantiate(TCCtrPrng_t *const ctx)
 {
-	if (0 != ctx) {
-		memset(ctx->key.words, 0x00, sizeof ctx->key.words);
-		memset(ctx->V,         0x00, sizeof ctx->V);
-		ctx->reseedCount = 0U;
-	}
+    if(0 != ctx) {
+        memset(ctx->key.words, 0x00, sizeof ctx->key.words);
+        memset(ctx->V,         0x00, sizeof ctx->V);
+        ctx->reseedCount = 0U;
+    }
 }
 
 

+ 652 - 668
src/bt/blehost/ext/tinycrypt/src/ecc.c

@@ -66,876 +66,860 @@ static uECC_RNG_Function g_rng_function = 0;
 
 void uECC_set_rng(uECC_RNG_Function rng_function)
 {
-	g_rng_function = rng_function;
+    g_rng_function = rng_function;
 }
 
 uECC_RNG_Function uECC_get_rng(void)
 {
-	return g_rng_function;
+    return g_rng_function;
 }
 
 int uECC_curve_private_key_size(uECC_Curve curve)
 {
-	return BITS_TO_BYTES(curve->num_n_bits);
+    return BITS_TO_BYTES(curve->num_n_bits);
 }
 
 int uECC_curve_public_key_size(uECC_Curve curve)
 {
-	return 2 * curve->num_bytes;
+    return 2 * curve->num_bytes;
 }
 
 void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words)
 {
-	wordcount_t i;
-	for (i = 0; i < num_words; ++i) {
-		 vli[i] = 0;
-	}
+    wordcount_t i;
+
+    for(i = 0; i < num_words; ++i) {
+        vli[i] = 0;
+    }
 }
 
 uECC_word_t uECC_vli_isZero(const uECC_word_t *vli, wordcount_t num_words)
 {
-	uECC_word_t bits = 0;
-	wordcount_t i;
-	for (i = 0; i < num_words; ++i) {
-		bits |= vli[i];
-	}
-	return (bits == 0);
+    uECC_word_t bits = 0;
+    wordcount_t i;
+
+    for(i = 0; i < num_words; ++i) {
+        bits |= vli[i];
+    }
+
+    return (bits == 0);
 }
 
 uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit)
 {
-	return (vli[bit >> uECC_WORD_BITS_SHIFT] &
-		((uECC_word_t)1 << (bit & uECC_WORD_BITS_MASK)));
+    return (vli[bit >> uECC_WORD_BITS_SHIFT] &
+            ((uECC_word_t)1 << (bit & uECC_WORD_BITS_MASK)));
 }
 
 /* Counts the number of words in vli. */
 static wordcount_t vli_numDigits(const uECC_word_t *vli,
-				 const wordcount_t max_words)
+                                 const wordcount_t max_words)
 {
+    wordcount_t i;
 
-	wordcount_t i;
-	/* Search from the end until we find a non-zero digit. We do it in reverse
-	 * because we expect that most digits will be nonzero. */
-	for (i = max_words - 1; i >= 0 && vli[i] == 0; --i) {
-	}
+    /* Search from the end until we find a non-zero digit. We do it in reverse
+     * because we expect that most digits will be nonzero. */
+    for(i = max_words - 1; i >= 0 && vli[i] == 0; --i) {
+    }
 
-	return (i + 1);
+    return (i + 1);
 }
 
 bitcount_t uECC_vli_numBits(const uECC_word_t *vli,
-			    const wordcount_t max_words)
+                            const wordcount_t max_words)
 {
+    uECC_word_t i;
+    uECC_word_t digit;
+    wordcount_t num_digits = vli_numDigits(vli, max_words);
 
-	uECC_word_t i;
-	uECC_word_t digit;
+    if(num_digits == 0) {
+        return 0;
+    }
 
-	wordcount_t num_digits = vli_numDigits(vli, max_words);
-	if (num_digits == 0) {
-		return 0;
-	}
+    digit = vli[num_digits - 1];
 
-	digit = vli[num_digits - 1];
-	for (i = 0; digit; ++i) {
-		digit >>= 1;
-	}
+    for(i = 0; digit; ++i) {
+        digit >>= 1;
+    }
 
-	return (((bitcount_t)(num_digits - 1) << uECC_WORD_BITS_SHIFT) + i);
+    return (((bitcount_t)(num_digits - 1) << uECC_WORD_BITS_SHIFT) + i);
 }
 
 void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src,
-		  wordcount_t num_words)
+                  wordcount_t num_words)
 {
-	wordcount_t i;
+    wordcount_t i;
 
-	for (i = 0; i < num_words; ++i) {
-		dest[i] = src[i];
-  	}
+    for(i = 0; i < num_words; ++i) {
+        dest[i] = src[i];
+    }
 }
 
 cmpresult_t uECC_vli_cmp_unsafe(const uECC_word_t *left,
-				const uECC_word_t *right,
-				wordcount_t num_words)
+                                const uECC_word_t *right,
+                                wordcount_t num_words)
 {
-	wordcount_t i;
+    wordcount_t i;
+
+    for(i = num_words - 1; i >= 0; --i) {
+        if(left[i] > right[i]) {
+            return 1;
+        } else if(left[i] < right[i]) {
+            return -1;
+        }
+    }
 
-	for (i = num_words - 1; i >= 0; --i) {
-		if (left[i] > right[i]) {
-			return 1;
-		} else if (left[i] < right[i]) {
-			return -1;
-		}
-	}
-	return 0;
+    return 0;
 }
 
 uECC_word_t uECC_vli_equal(const uECC_word_t *left, const uECC_word_t *right,
-			   wordcount_t num_words)
+                           wordcount_t num_words)
 {
+    uECC_word_t diff = 0;
+    wordcount_t i;
 
-	uECC_word_t diff = 0;
-	wordcount_t i;
+    for(i = num_words - 1; i >= 0; --i) {
+        diff |= (left[i] ^ right[i]);
+    }
 
-	for (i = num_words - 1; i >= 0; --i) {
-		diff |= (left[i] ^ right[i]);
-	}
-	return !(diff == 0);
+    return !(diff == 0);
 }
 
 uECC_word_t cond_set(uECC_word_t p_true, uECC_word_t p_false, unsigned int cond)
 {
-	return (p_true*(cond)) | (p_false*(!cond));
+    return (p_true * (cond)) | (p_false * (!cond));
 }
 
 /* Computes result = left - right, returning borrow, in constant time.
  * Can modify in place. */
 uECC_word_t uECC_vli_sub(uECC_word_t *result, const uECC_word_t *left,
-			 const uECC_word_t *right, wordcount_t num_words)
+                         const uECC_word_t *right, wordcount_t num_words)
 {
-	uECC_word_t borrow = 0;
-	wordcount_t i;
-	for (i = 0; i < num_words; ++i) {
-		uECC_word_t diff = left[i] - right[i] - borrow;
-		uECC_word_t val = (diff > left[i]);
-		borrow = cond_set(val, borrow, (diff != left[i]));
+    uECC_word_t borrow = 0;
+    wordcount_t i;
 
-		result[i] = diff;
-	}
-	return borrow;
+    for(i = 0; i < num_words; ++i) {
+        uECC_word_t diff = left[i] - right[i] - borrow;
+        uECC_word_t val = (diff > left[i]);
+        borrow = cond_set(val, borrow, (diff != left[i]));
+        result[i] = diff;
+    }
+
+    return borrow;
 }
 
 /* Computes result = left + right, returning carry, in constant time.
  * Can modify in place. */
 static uECC_word_t uECC_vli_add(uECC_word_t *result, const uECC_word_t *left,
-				const uECC_word_t *right, wordcount_t num_words)
+                                const uECC_word_t *right, wordcount_t num_words)
 {
-	uECC_word_t carry = 0;
-	wordcount_t i;
-	for (i = 0; i < num_words; ++i) {
-		uECC_word_t sum = left[i] + right[i] + carry;
-		uECC_word_t val = (sum < left[i]);
-		carry = cond_set(val, carry, (sum != left[i]));
-		result[i] = sum;
-	}
-	return carry;
+    uECC_word_t carry = 0;
+    wordcount_t i;
+
+    for(i = 0; i < num_words; ++i) {
+        uECC_word_t sum = left[i] + right[i] + carry;
+        uECC_word_t val = (sum < left[i]);
+        carry = cond_set(val, carry, (sum != left[i]));
+        result[i] = sum;
+    }
+
+    return carry;
 }
 
 cmpresult_t uECC_vli_cmp(const uECC_word_t *left, const uECC_word_t *right,
-			 wordcount_t num_words)
+                         wordcount_t num_words)
 {
-	uECC_word_t tmp[NUM_ECC_WORDS];
-	uECC_word_t neg = !!uECC_vli_sub(tmp, left, right, num_words);
-	uECC_word_t equal = uECC_vli_isZero(tmp, num_words);
-	return (!equal - 2 * neg);
+    uECC_word_t tmp[NUM_ECC_WORDS];
+    uECC_word_t neg = !!uECC_vli_sub(tmp, left, right, num_words);
+    uECC_word_t equal = uECC_vli_isZero(tmp, num_words);
+    return (!equal - 2 * neg);
 }
 
 /* Computes vli = vli >> 1. */
 static void uECC_vli_rshift1(uECC_word_t *vli, wordcount_t num_words)
 {
-	uECC_word_t *end = vli;
-	uECC_word_t carry = 0;
+    uECC_word_t *end = vli;
+    uECC_word_t carry = 0;
+    vli += num_words;
 
-	vli += num_words;
-	while (vli-- > end) {
-		uECC_word_t temp = *vli;
-		*vli = (temp >> 1) | carry;
-		carry = temp << (uECC_WORD_BITS - 1);
-	}
+    while(vli-- > end) {
+        uECC_word_t temp = *vli;
+        *vli = (temp >> 1) | carry;
+        carry = temp << (uECC_WORD_BITS - 1);
+    }
 }
 
 static void muladd(uECC_word_t a, uECC_word_t b, uECC_word_t *r0,
-		   uECC_word_t *r1, uECC_word_t *r2)
+                   uECC_word_t *r1, uECC_word_t *r2)
 {
-
-	uECC_dword_t p = (uECC_dword_t)a * b;
-	uECC_dword_t r01 = ((uECC_dword_t)(*r1) << uECC_WORD_BITS) | *r0;
-	r01 += p;
-	*r2 += (r01 < p);
-	*r1 = r01 >> uECC_WORD_BITS;
-	*r0 = (uECC_word_t)r01;
-
+    uECC_dword_t p = (uECC_dword_t)a * b;
+    uECC_dword_t r01 = ((uECC_dword_t)(*r1) << uECC_WORD_BITS) | *r0;
+    r01 += p;
+    *r2 += (r01 < p);
+    *r1 = r01 >> uECC_WORD_BITS;
+    *r0 = (uECC_word_t)r01;
 }
 
 /* Computes result = left * right. Result must be 2 * num_words long. */
 static void uECC_vli_mult(uECC_word_t *result, const uECC_word_t *left,
-			  const uECC_word_t *right, wordcount_t num_words)
+                          const uECC_word_t *right, wordcount_t num_words)
 {
+    uECC_word_t r0 = 0;
+    uECC_word_t r1 = 0;
+    uECC_word_t r2 = 0;
+    wordcount_t i, k;
 
-	uECC_word_t r0 = 0;
-	uECC_word_t r1 = 0;
-	uECC_word_t r2 = 0;
-	wordcount_t i, k;
+    /* Compute each digit of result in sequence, maintaining the carries. */
+    for(k = 0; k < num_words; ++k) {
+        for(i = 0; i <= k; ++i) {
+            muladd(left[i], right[k - i], &r0, &r1, &r2);
+        }
 
-	/* Compute each digit of result in sequence, maintaining the carries. */
-	for (k = 0; k < num_words; ++k) {
+        result[k] = r0;
+        r0 = r1;
+        r1 = r2;
+        r2 = 0;
+    }
 
-		for (i = 0; i <= k; ++i) {
-			muladd(left[i], right[k - i], &r0, &r1, &r2);
-		}
+    for(k = num_words; k < num_words * 2 - 1; ++k) {
+        for(i = (k + 1) - num_words; i < num_words; ++i) {
+            muladd(left[i], right[k - i], &r0, &r1, &r2);
+        }
 
-		result[k] = r0;
-		r0 = r1;
-		r1 = r2;
-		r2 = 0;
-	}
+        result[k] = r0;
+        r0 = r1;
+        r1 = r2;
+        r2 = 0;
+    }
 
-	for (k = num_words; k < num_words * 2 - 1; ++k) {
-
-		for (i = (k + 1) - num_words; i < num_words; ++i) {
-			muladd(left[i], right[k - i], &r0, &r1, &r2);
-		}
-		result[k] = r0;
-		r0 = r1;
-		r1 = r2;
-		r2 = 0;
-	}
-	result[num_words * 2 - 1] = r0;
+    result[num_words * 2 - 1] = r0;
 }
 
 void uECC_vli_modAdd(uECC_word_t *result, const uECC_word_t *left,
-		     const uECC_word_t *right, const uECC_word_t *mod,
-		     wordcount_t num_words)
+                     const uECC_word_t *right, const uECC_word_t *mod,
+                     wordcount_t num_words)
 {
-	uECC_word_t carry = uECC_vli_add(result, left, right, num_words);
-	if (carry || uECC_vli_cmp_unsafe(mod, result, num_words) != 1) {
-	/* result > mod (result = mod + remainder), so subtract mod to get
-	 * remainder. */
-		uECC_vli_sub(result, result, mod, num_words);
-	}
+    uECC_word_t carry = uECC_vli_add(result, left, right, num_words);
+
+    if(carry || uECC_vli_cmp_unsafe(mod, result, num_words) != 1) {
+        /* result > mod (result = mod + remainder), so subtract mod to get
+         * remainder. */
+        uECC_vli_sub(result, result, mod, num_words);
+    }
 }
 
 void uECC_vli_modSub(uECC_word_t *result, const uECC_word_t *left,
-		     const uECC_word_t *right, const uECC_word_t *mod,
-		     wordcount_t num_words)
+                     const uECC_word_t *right, const uECC_word_t *mod,
+                     wordcount_t num_words)
 {
-	uECC_word_t l_borrow = uECC_vli_sub(result, left, right, num_words);
-	if (l_borrow) {
-		/* In this case, result == -diff == (max int) - diff. Since -x % d == d - x,
-		 * we can get the correct result from result + mod (with overflow). */
-		uECC_vli_add(result, result, mod, num_words);
-	}
+    uECC_word_t l_borrow = uECC_vli_sub(result, left, right, num_words);
+
+    if(l_borrow) {
+        /* In this case, result == -diff == (max int) - diff. Since -x % d == d - x,
+         * we can get the correct result from result + mod (with overflow). */
+        uECC_vli_add(result, result, mod, num_words);
+    }
 }
 
 /* Computes result = product % mod, where product is 2N words long. */
 /* Currently only designed to work for curve_p or curve_n. */
 void uECC_vli_mmod(uECC_word_t *result, uECC_word_t *product,
-    		   const uECC_word_t *mod, wordcount_t num_words)
-{
-	uECC_word_t mod_multiple[2 * NUM_ECC_WORDS];
-	uECC_word_t tmp[2 * NUM_ECC_WORDS];
-	uECC_word_t *v[2] = {tmp, product};
-	uECC_word_t index;
-
-	/* Shift mod so its highest set bit is at the maximum position. */
-	bitcount_t shift = (num_words * 2 * uECC_WORD_BITS) -
-			   uECC_vli_numBits(mod, num_words);
-	wordcount_t word_shift = shift / uECC_WORD_BITS;
-	wordcount_t bit_shift = shift % uECC_WORD_BITS;
-	uECC_word_t carry = 0;
-	uECC_vli_clear(mod_multiple, word_shift);
-	if (bit_shift > 0) {
-		for(index = 0; index < (uECC_word_t)num_words; ++index) {
-			mod_multiple[word_shift + index] = (mod[index] << bit_shift) | carry;
-			carry = mod[index] >> (uECC_WORD_BITS - bit_shift);
-		}
-	} else {
-		uECC_vli_set(mod_multiple + word_shift, mod, num_words);
-	}
-
-	for (index = 1; shift >= 0; --shift) {
-		uECC_word_t borrow = 0;
-		wordcount_t i;
-		for (i = 0; i < num_words * 2; ++i) {
-			uECC_word_t diff = v[index][i] - mod_multiple[i] - borrow;
-			if (diff != v[index][i]) {
-				borrow = (diff > v[index][i]);
-			}
-			v[1 - index][i] = diff;
-		}
-		/* Swap the index if there was no borrow */
-		index = !(index ^ borrow);
-		uECC_vli_rshift1(mod_multiple, num_words);
-		mod_multiple[num_words - 1] |= mod_multiple[num_words] <<
-					       (uECC_WORD_BITS - 1);
-		uECC_vli_rshift1(mod_multiple + num_words, num_words);
-	}
-	uECC_vli_set(result, v[index], num_words);
+                   const uECC_word_t *mod, wordcount_t num_words)
+{
+    uECC_word_t mod_multiple[2 * NUM_ECC_WORDS];
+    uECC_word_t tmp[2 * NUM_ECC_WORDS];
+    uECC_word_t *v[2] = {tmp, product};
+    uECC_word_t index;
+    /* Shift mod so its highest set bit is at the maximum position. */
+    bitcount_t shift = (num_words * 2 * uECC_WORD_BITS) -
+                       uECC_vli_numBits(mod, num_words);
+    wordcount_t word_shift = shift / uECC_WORD_BITS;
+    wordcount_t bit_shift = shift % uECC_WORD_BITS;
+    uECC_word_t carry = 0;
+    uECC_vli_clear(mod_multiple, word_shift);
+
+    if(bit_shift > 0) {
+        for(index = 0; index < (uECC_word_t)num_words; ++index) {
+            mod_multiple[word_shift + index] = (mod[index] << bit_shift) | carry;
+            carry = mod[index] >> (uECC_WORD_BITS - bit_shift);
+        }
+    } else {
+        uECC_vli_set(mod_multiple + word_shift, mod, num_words);
+    }
+
+    for(index = 1; shift >= 0; --shift) {
+        uECC_word_t borrow = 0;
+        wordcount_t i;
+
+        for(i = 0; i < num_words * 2; ++i) {
+            uECC_word_t diff = v[index][i] - mod_multiple[i] - borrow;
+
+            if(diff != v[index][i]) {
+                borrow = (diff > v[index][i]);
+            }
+
+            v[1 - index][i] = diff;
+        }
+
+        /* Swap the index if there was no borrow */
+        index = !(index ^ borrow);
+        uECC_vli_rshift1(mod_multiple, num_words);
+        mod_multiple[num_words - 1] |= mod_multiple[num_words] <<
+                                       (uECC_WORD_BITS - 1);
+        uECC_vli_rshift1(mod_multiple + num_words, num_words);
+    }
+
+    uECC_vli_set(result, v[index], num_words);
 }
 
 void uECC_vli_modMult(uECC_word_t *result, const uECC_word_t *left,
-		      const uECC_word_t *right, const uECC_word_t *mod,
-		      wordcount_t num_words)
+                      const uECC_word_t *right, const uECC_word_t *mod,
+                      wordcount_t num_words)
 {
-	uECC_word_t product[2 * NUM_ECC_WORDS];
-	uECC_vli_mult(product, left, right, num_words);
-	uECC_vli_mmod(result, product, mod, num_words);
+    uECC_word_t product[2 * NUM_ECC_WORDS];
+    uECC_vli_mult(product, left, right, num_words);
+    uECC_vli_mmod(result, product, mod, num_words);
 }
 
 void uECC_vli_modMult_fast(uECC_word_t *result, const uECC_word_t *left,
-			   const uECC_word_t *right, uECC_Curve curve)
+                           const uECC_word_t *right, uECC_Curve curve)
 {
-	uECC_word_t product[2 * NUM_ECC_WORDS];
-	uECC_vli_mult(product, left, right, curve->num_words);
-
-	curve->mmod_fast(result, product);
+    uECC_word_t product[2 * NUM_ECC_WORDS];
+    uECC_vli_mult(product, left, right, curve->num_words);
+    curve->mmod_fast(result, product);
 }
 
 static void uECC_vli_modSquare_fast(uECC_word_t *result,
-				    const uECC_word_t *left,
-				    uECC_Curve curve)
+                                    const uECC_word_t *left,
+                                    uECC_Curve curve)
 {
-	uECC_vli_modMult_fast(result, left, left, curve);
+    uECC_vli_modMult_fast(result, left, left, curve);
 }
 
 
 #define EVEN(vli) (!(vli[0] & 1))
 
 static void vli_modInv_update(uECC_word_t *uv,
-			      const uECC_word_t *mod,
-			      wordcount_t num_words)
+                              const uECC_word_t *mod,
+                              wordcount_t num_words)
 {
+    uECC_word_t carry = 0;
+
+    if(!EVEN(uv)) {
+        carry = uECC_vli_add(uv, uv, mod, num_words);
+    }
 
-	uECC_word_t carry = 0;
+    uECC_vli_rshift1(uv, num_words);
 
-	if (!EVEN(uv)) {
-		carry = uECC_vli_add(uv, uv, mod, num_words);
-	}
-	uECC_vli_rshift1(uv, num_words);
-	if (carry) {
-		uv[num_words - 1] |= HIGH_BIT_SET;
-	}
+    if(carry) {
+        uv[num_words - 1] |= HIGH_BIT_SET;
+    }
 }
 
 void uECC_vli_modInv(uECC_word_t *result, const uECC_word_t *input,
-		     const uECC_word_t *mod, wordcount_t num_words)
-{
-	uECC_word_t a[NUM_ECC_WORDS], b[NUM_ECC_WORDS];
-	uECC_word_t u[NUM_ECC_WORDS], v[NUM_ECC_WORDS];
-	cmpresult_t cmpResult;
-
-	if (uECC_vli_isZero(input, num_words)) {
-		uECC_vli_clear(result, num_words);
-		return;
-	}
-
-	uECC_vli_set(a, input, num_words);
-	uECC_vli_set(b, mod, num_words);
-	uECC_vli_clear(u, num_words);
-	u[0] = 1;
-	uECC_vli_clear(v, num_words);
-	while ((cmpResult = uECC_vli_cmp_unsafe(a, b, num_words)) != 0) {
-		if (EVEN(a)) {
-			uECC_vli_rshift1(a, num_words);
-      			vli_modInv_update(u, mod, num_words);
-    		} else if (EVEN(b)) {
-			uECC_vli_rshift1(b, num_words);
-			vli_modInv_update(v, mod, num_words);
-		} else if (cmpResult > 0) {
-			uECC_vli_sub(a, a, b, num_words);
-			uECC_vli_rshift1(a, num_words);
-			if (uECC_vli_cmp_unsafe(u, v, num_words) < 0) {
-        			uECC_vli_add(u, u, mod, num_words);
-      			}
-      			uECC_vli_sub(u, u, v, num_words);
-      			vli_modInv_update(u, mod, num_words);
-    		} else {
-      			uECC_vli_sub(b, b, a, num_words);
-      			uECC_vli_rshift1(b, num_words);
-      			if (uECC_vli_cmp_unsafe(v, u, num_words) < 0) {
-        			uECC_vli_add(v, v, mod, num_words);
-      			}
-      			uECC_vli_sub(v, v, u, num_words);
-      			vli_modInv_update(v, mod, num_words);
-    		}
-  	}
-  	uECC_vli_set(result, u, num_words);
+                     const uECC_word_t *mod, wordcount_t num_words)
+{
+    uECC_word_t a[NUM_ECC_WORDS], b[NUM_ECC_WORDS];
+    uECC_word_t u[NUM_ECC_WORDS], v[NUM_ECC_WORDS];
+    cmpresult_t cmpResult;
+
+    if(uECC_vli_isZero(input, num_words)) {
+        uECC_vli_clear(result, num_words);
+        return;
+    }
+
+    uECC_vli_set(a, input, num_words);
+    uECC_vli_set(b, mod, num_words);
+    uECC_vli_clear(u, num_words);
+    u[0] = 1;
+    uECC_vli_clear(v, num_words);
+
+    while((cmpResult = uECC_vli_cmp_unsafe(a, b, num_words)) != 0) {
+        if(EVEN(a)) {
+            uECC_vli_rshift1(a, num_words);
+            vli_modInv_update(u, mod, num_words);
+        } else if(EVEN(b)) {
+            uECC_vli_rshift1(b, num_words);
+            vli_modInv_update(v, mod, num_words);
+        } else if(cmpResult > 0) {
+            uECC_vli_sub(a, a, b, num_words);
+            uECC_vli_rshift1(a, num_words);
+
+            if(uECC_vli_cmp_unsafe(u, v, num_words) < 0) {
+                uECC_vli_add(u, u, mod, num_words);
+            }
+
+            uECC_vli_sub(u, u, v, num_words);
+            vli_modInv_update(u, mod, num_words);
+        } else {
+            uECC_vli_sub(b, b, a, num_words);
+            uECC_vli_rshift1(b, num_words);
+
+            if(uECC_vli_cmp_unsafe(v, u, num_words) < 0) {
+                uECC_vli_add(v, v, mod, num_words);
+            }
+
+            uECC_vli_sub(v, v, u, num_words);
+            vli_modInv_update(v, mod, num_words);
+        }
+    }
+
+    uECC_vli_set(result, u, num_words);
 }
 
 /* ------ Point operations ------ */
 
-void double_jacobian_default(uECC_word_t * X1, uECC_word_t * Y1,
-			     uECC_word_t * Z1, uECC_Curve curve)
-{
-	/* t1 = X, t2 = Y, t3 = Z */
-	uECC_word_t t4[NUM_ECC_WORDS];
-	uECC_word_t t5[NUM_ECC_WORDS];
-	wordcount_t num_words = curve->num_words;
-
-	if (uECC_vli_isZero(Z1, num_words)) {
-		return;
-	}
-
-	uECC_vli_modSquare_fast(t4, Y1, curve);   /* t4 = y1^2 */
-	uECC_vli_modMult_fast(t5, X1, t4, curve); /* t5 = x1*y1^2 = A */
-	uECC_vli_modSquare_fast(t4, t4, curve);   /* t4 = y1^4 */
-	uECC_vli_modMult_fast(Y1, Y1, Z1, curve); /* t2 = y1*z1 = z3 */
-	uECC_vli_modSquare_fast(Z1, Z1, curve);   /* t3 = z1^2 */
-
-	uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = x1 + z1^2 */
-	uECC_vli_modAdd(Z1, Z1, Z1, curve->p, num_words); /* t3 = 2*z1^2 */
-	uECC_vli_modSub(Z1, X1, Z1, curve->p, num_words); /* t3 = x1 - z1^2 */
-	uECC_vli_modMult_fast(X1, X1, Z1, curve); /* t1 = x1^2 - z1^4 */
-
-	uECC_vli_modAdd(Z1, X1, X1, curve->p, num_words); /* t3 = 2*(x1^2 - z1^4) */
-	uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = 3*(x1^2 - z1^4) */
-	if (uECC_vli_testBit(X1, 0)) {
-		uECC_word_t l_carry = uECC_vli_add(X1, X1, curve->p, num_words);
-		uECC_vli_rshift1(X1, num_words);
-		X1[num_words - 1] |= l_carry << (uECC_WORD_BITS - 1);
-	} else {
-		uECC_vli_rshift1(X1, num_words);
-	}
-
-	/* t1 = 3/2*(x1^2 - z1^4) = B */
-	uECC_vli_modSquare_fast(Z1, X1, curve); /* t3 = B^2 */
-	uECC_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - A */
-	uECC_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - 2A = x3 */
-	uECC_vli_modSub(t5, t5, Z1, curve->p, num_words); /* t5 = A - x3 */
-	uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = B * (A - x3) */
-	/* t4 = B * (A - x3) - y1^4 = y3: */
-	uECC_vli_modSub(t4, X1, t4, curve->p, num_words);
-
-	uECC_vli_set(X1, Z1, num_words);
-	uECC_vli_set(Z1, Y1, num_words);
-	uECC_vli_set(Y1, t4, num_words);
+void double_jacobian_default(uECC_word_t *X1, uECC_word_t *Y1,
+                             uECC_word_t *Z1, uECC_Curve curve)
+{
+    /* t1 = X, t2 = Y, t3 = Z */
+    uECC_word_t t4[NUM_ECC_WORDS];
+    uECC_word_t t5[NUM_ECC_WORDS];
+    wordcount_t num_words = curve->num_words;
+
+    if(uECC_vli_isZero(Z1, num_words)) {
+        return;
+    }
+
+    uECC_vli_modSquare_fast(t4, Y1, curve);   /* t4 = y1^2 */
+    uECC_vli_modMult_fast(t5, X1, t4, curve); /* t5 = x1*y1^2 = A */
+    uECC_vli_modSquare_fast(t4, t4, curve);   /* t4 = y1^4 */
+    uECC_vli_modMult_fast(Y1, Y1, Z1, curve); /* t2 = y1*z1 = z3 */
+    uECC_vli_modSquare_fast(Z1, Z1, curve);   /* t3 = z1^2 */
+    uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = x1 + z1^2 */
+    uECC_vli_modAdd(Z1, Z1, Z1, curve->p, num_words); /* t3 = 2*z1^2 */
+    uECC_vli_modSub(Z1, X1, Z1, curve->p, num_words); /* t3 = x1 - z1^2 */
+    uECC_vli_modMult_fast(X1, X1, Z1, curve); /* t1 = x1^2 - z1^4 */
+    uECC_vli_modAdd(Z1, X1, X1, curve->p, num_words); /* t3 = 2*(x1^2 - z1^4) */
+    uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = 3*(x1^2 - z1^4) */
+
+    if(uECC_vli_testBit(X1, 0)) {
+        uECC_word_t l_carry = uECC_vli_add(X1, X1, curve->p, num_words);
+        uECC_vli_rshift1(X1, num_words);
+        X1[num_words - 1] |= l_carry << (uECC_WORD_BITS - 1);
+    } else {
+        uECC_vli_rshift1(X1, num_words);
+    }
+
+    /* t1 = 3/2*(x1^2 - z1^4) = B */
+    uECC_vli_modSquare_fast(Z1, X1, curve); /* t3 = B^2 */
+    uECC_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - A */
+    uECC_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - 2A = x3 */
+    uECC_vli_modSub(t5, t5, Z1, curve->p, num_words); /* t5 = A - x3 */
+    uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = B * (A - x3) */
+    /* t4 = B * (A - x3) - y1^4 = y3: */
+    uECC_vli_modSub(t4, X1, t4, curve->p, num_words);
+    uECC_vli_set(X1, Z1, num_words);
+    uECC_vli_set(Z1, Y1, num_words);
+    uECC_vli_set(Y1, t4, num_words);
 }
 
 void x_side_default(uECC_word_t *result,
-		    const uECC_word_t *x,
-		    uECC_Curve curve)
+                    const uECC_word_t *x,
+                    uECC_Curve curve)
 {
-	uECC_word_t _3[NUM_ECC_WORDS] = {3}; /* -a = 3 */
-	wordcount_t num_words = curve->num_words;
-
-	uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */
-	uECC_vli_modSub(result, result, _3, curve->p, num_words); /* r = x^2 - 3 */
-	uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 - 3x */
-	/* r = x^3 - 3x + b: */
-	uECC_vli_modAdd(result, result, curve->b, curve->p, num_words);
+    uECC_word_t _3[NUM_ECC_WORDS] = {3}; /* -a = 3 */
+    wordcount_t num_words = curve->num_words;
+    uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */
+    uECC_vli_modSub(result, result, _3, curve->p, num_words); /* r = x^2 - 3 */
+    uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 - 3x */
+    /* r = x^3 - 3x + b: */
+    uECC_vli_modAdd(result, result, curve->b, curve->p, num_words);
 }
 
 uECC_Curve uECC_secp256r1(void)
 {
-	return &curve_secp256r1;
-}
-
-void vli_mmod_fast_secp256r1(unsigned int *result, unsigned int*product)
-{
-	unsigned int tmp[NUM_ECC_WORDS];
-	int carry;
-
-	/* t */
-	uECC_vli_set(result, product, NUM_ECC_WORDS);
-
-	/* s1 */
-	tmp[0] = tmp[1] = tmp[2] = 0;
-	tmp[3] = product[11];
-	tmp[4] = product[12];
-	tmp[5] = product[13];
-	tmp[6] = product[14];
-	tmp[7] = product[15];
-	carry = uECC_vli_add(tmp, tmp, tmp, NUM_ECC_WORDS);
-	carry += uECC_vli_add(result, result, tmp, NUM_ECC_WORDS);
-
-	/* s2 */
-	tmp[3] = product[12];
-	tmp[4] = product[13];
-	tmp[5] = product[14];
-	tmp[6] = product[15];
-	tmp[7] = 0;
-	carry += uECC_vli_add(tmp, tmp, tmp, NUM_ECC_WORDS);
-	carry += uECC_vli_add(result, result, tmp, NUM_ECC_WORDS);
-
-	/* s3 */
-	tmp[0] = product[8];
-	tmp[1] = product[9];
-	tmp[2] = product[10];
-	tmp[3] = tmp[4] = tmp[5] = 0;
-	tmp[6] = product[14];
-	tmp[7] = product[15];
-  	carry += uECC_vli_add(result, result, tmp, NUM_ECC_WORDS);
-
-	/* s4 */
-	tmp[0] = product[9];
-	tmp[1] = product[10];
-	tmp[2] = product[11];
-	tmp[3] = product[13];
-	tmp[4] = product[14];
-	tmp[5] = product[15];
-	tmp[6] = product[13];
-	tmp[7] = product[8];
-	carry += uECC_vli_add(result, result, tmp, NUM_ECC_WORDS);
-
-	/* d1 */
-	tmp[0] = product[11];
-	tmp[1] = product[12];
-	tmp[2] = product[13];
-	tmp[3] = tmp[4] = tmp[5] = 0;
-	tmp[6] = product[8];
-	tmp[7] = product[10];
-	carry -= uECC_vli_sub(result, result, tmp, NUM_ECC_WORDS);
-
-	/* d2 */
-	tmp[0] = product[12];
-	tmp[1] = product[13];
-	tmp[2] = product[14];
-	tmp[3] = product[15];
-	tmp[4] = tmp[5] = 0;
-	tmp[6] = product[9];
-	tmp[7] = product[11];
-	carry -= uECC_vli_sub(result, result, tmp, NUM_ECC_WORDS);
-
-	/* d3 */
-	tmp[0] = product[13];
-	tmp[1] = product[14];
-	tmp[2] = product[15];
-	tmp[3] = product[8];
-	tmp[4] = product[9];
-	tmp[5] = product[10];
-	tmp[6] = 0;
-	tmp[7] = product[12];
-	carry -= uECC_vli_sub(result, result, tmp, NUM_ECC_WORDS);
-
-	/* d4 */
-	tmp[0] = product[14];
-	tmp[1] = product[15];
-	tmp[2] = 0;
-	tmp[3] = product[9];
-	tmp[4] = product[10];
-	tmp[5] = product[11];
-	tmp[6] = 0;
-	tmp[7] = product[13];
-	carry -= uECC_vli_sub(result, result, tmp, NUM_ECC_WORDS);
-
-	if (carry < 0) {
-		do {
-			carry += uECC_vli_add(result, result, curve_secp256r1.p, NUM_ECC_WORDS);
-		}
-		while (carry < 0);
-	} else  {
-		while (carry || 
-		       uECC_vli_cmp_unsafe(curve_secp256r1.p, result, NUM_ECC_WORDS) != 1) {
-			carry -= uECC_vli_sub(result, result, curve_secp256r1.p, NUM_ECC_WORDS);
-		}
-	}
+    return &curve_secp256r1;
+}
+
+void vli_mmod_fast_secp256r1(unsigned int *result, unsigned int *product)
+{
+    unsigned int tmp[NUM_ECC_WORDS];
+    int carry;
+    /* t */
+    uECC_vli_set(result, product, NUM_ECC_WORDS);
+    /* s1 */
+    tmp[0] = tmp[1] = tmp[2] = 0;
+    tmp[3] = product[11];
+    tmp[4] = product[12];
+    tmp[5] = product[13];
+    tmp[6] = product[14];
+    tmp[7] = product[15];
+    carry = uECC_vli_add(tmp, tmp, tmp, NUM_ECC_WORDS);
+    carry += uECC_vli_add(result, result, tmp, NUM_ECC_WORDS);
+    /* s2 */
+    tmp[3] = product[12];
+    tmp[4] = product[13];
+    tmp[5] = product[14];
+    tmp[6] = product[15];
+    tmp[7] = 0;
+    carry += uECC_vli_add(tmp, tmp, tmp, NUM_ECC_WORDS);
+    carry += uECC_vli_add(result, result, tmp, NUM_ECC_WORDS);
+    /* s3 */
+    tmp[0] = product[8];
+    tmp[1] = product[9];
+    tmp[2] = product[10];
+    tmp[3] = tmp[4] = tmp[5] = 0;
+    tmp[6] = product[14];
+    tmp[7] = product[15];
+    carry += uECC_vli_add(result, result, tmp, NUM_ECC_WORDS);
+    /* s4 */
+    tmp[0] = product[9];
+    tmp[1] = product[10];
+    tmp[2] = product[11];
+    tmp[3] = product[13];
+    tmp[4] = product[14];
+    tmp[5] = product[15];
+    tmp[6] = product[13];
+    tmp[7] = product[8];
+    carry += uECC_vli_add(result, result, tmp, NUM_ECC_WORDS);
+    /* d1 */
+    tmp[0] = product[11];
+    tmp[1] = product[12];
+    tmp[2] = product[13];
+    tmp[3] = tmp[4] = tmp[5] = 0;
+    tmp[6] = product[8];
+    tmp[7] = product[10];
+    carry -= uECC_vli_sub(result, result, tmp, NUM_ECC_WORDS);
+    /* d2 */
+    tmp[0] = product[12];
+    tmp[1] = product[13];
+    tmp[2] = product[14];
+    tmp[3] = product[15];
+    tmp[4] = tmp[5] = 0;
+    tmp[6] = product[9];
+    tmp[7] = product[11];
+    carry -= uECC_vli_sub(result, result, tmp, NUM_ECC_WORDS);
+    /* d3 */
+    tmp[0] = product[13];
+    tmp[1] = product[14];
+    tmp[2] = product[15];
+    tmp[3] = product[8];
+    tmp[4] = product[9];
+    tmp[5] = product[10];
+    tmp[6] = 0;
+    tmp[7] = product[12];
+    carry -= uECC_vli_sub(result, result, tmp, NUM_ECC_WORDS);
+    /* d4 */
+    tmp[0] = product[14];
+    tmp[1] = product[15];
+    tmp[2] = 0;
+    tmp[3] = product[9];
+    tmp[4] = product[10];
+    tmp[5] = product[11];
+    tmp[6] = 0;
+    tmp[7] = product[13];
+    carry -= uECC_vli_sub(result, result, tmp, NUM_ECC_WORDS);
+
+    if(carry < 0) {
+        do {
+            carry += uECC_vli_add(result, result, curve_secp256r1.p, NUM_ECC_WORDS);
+        } while(carry < 0);
+    } else  {
+        while(carry ||
+                uECC_vli_cmp_unsafe(curve_secp256r1.p, result, NUM_ECC_WORDS) != 1) {
+            carry -= uECC_vli_sub(result, result, curve_secp256r1.p, NUM_ECC_WORDS);
+        }
+    }
 }
 
 uECC_word_t EccPoint_isZero(const uECC_word_t *point, uECC_Curve curve)
 {
-	return uECC_vli_isZero(point, curve->num_words * 2);
+    return uECC_vli_isZero(point, curve->num_words * 2);
 }
 
-void apply_z(uECC_word_t * X1, uECC_word_t * Y1, const uECC_word_t * const Z,
-	     uECC_Curve curve)
+void apply_z(uECC_word_t *X1, uECC_word_t *Y1, const uECC_word_t *const Z,
+             uECC_Curve curve)
 {
-	uECC_word_t t1[NUM_ECC_WORDS];
-
-	uECC_vli_modSquare_fast(t1, Z, curve);    /* z^2 */
-	uECC_vli_modMult_fast(X1, X1, t1, curve); /* x1 * z^2 */
-	uECC_vli_modMult_fast(t1, t1, Z, curve);  /* z^3 */
-	uECC_vli_modMult_fast(Y1, Y1, t1, curve); /* y1 * z^3 */
+    uECC_word_t t1[NUM_ECC_WORDS];
+    uECC_vli_modSquare_fast(t1, Z, curve);    /* z^2 */
+    uECC_vli_modMult_fast(X1, X1, t1, curve); /* x1 * z^2 */
+    uECC_vli_modMult_fast(t1, t1, Z, curve);  /* z^3 */
+    uECC_vli_modMult_fast(Y1, Y1, t1, curve); /* y1 * z^3 */
 }
 
 /* P = (x1, y1) => 2P, (x2, y2) => P' */
-static void XYcZ_initial_double(uECC_word_t * X1, uECC_word_t * Y1,
-				uECC_word_t * X2, uECC_word_t * Y2,
-				const uECC_word_t * const initial_Z,
-				uECC_Curve curve)
-{
-	uECC_word_t z[NUM_ECC_WORDS];
-	wordcount_t num_words = curve->num_words;
-	if (initial_Z) {
-		uECC_vli_set(z, initial_Z, num_words);
-	} else {
-		uECC_vli_clear(z, num_words);
-		z[0] = 1;
-	}
-
-	uECC_vli_set(X2, X1, num_words);
-	uECC_vli_set(Y2, Y1, num_words);
-
-	apply_z(X1, Y1, z, curve);
-	curve->double_jacobian(X1, Y1, z, curve);
-	apply_z(X2, Y2, z, curve);
-}
-
-void XYcZ_add(uECC_word_t * X1, uECC_word_t * Y1,
-	      uECC_word_t * X2, uECC_word_t * Y2,
-	      uECC_Curve curve)
-{
-	/* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */
-	uECC_word_t t5[NUM_ECC_WORDS];
-	wordcount_t num_words = curve->num_words;
-
-	uECC_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */
-	uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */
-	uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */
-	uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */
-	uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */
-	uECC_vli_modSquare_fast(t5, Y2, curve); /* t5 = (y2 - y1)^2 = D */
-
-	uECC_vli_modSub(t5, t5, X1, curve->p, num_words); /* t5 = D - B */
-	uECC_vli_modSub(t5, t5, X2, curve->p, num_words); /* t5 = D - B - C = x3 */
-	uECC_vli_modSub(X2, X2, X1, curve->p, num_words); /* t3 = C - B */
-	uECC_vli_modMult_fast(Y1, Y1, X2, curve); /* t2 = y1*(C - B) */
-	uECC_vli_modSub(X2, X1, t5, curve->p, num_words); /* t3 = B - x3 */
-	uECC_vli_modMult_fast(Y2, Y2, X2, curve); /* t4 = (y2 - y1)*(B - x3) */
-	uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y3 */
-
-	uECC_vli_set(X2, t5, num_words);
+static void XYcZ_initial_double(uECC_word_t *X1, uECC_word_t *Y1,
+                                uECC_word_t *X2, uECC_word_t *Y2,
+                                const uECC_word_t *const initial_Z,
+                                uECC_Curve curve)
+{
+    uECC_word_t z[NUM_ECC_WORDS];
+    wordcount_t num_words = curve->num_words;
+
+    if(initial_Z) {
+        uECC_vli_set(z, initial_Z, num_words);
+    } else {
+        uECC_vli_clear(z, num_words);
+        z[0] = 1;
+    }
+
+    uECC_vli_set(X2, X1, num_words);
+    uECC_vli_set(Y2, Y1, num_words);
+    apply_z(X1, Y1, z, curve);
+    curve->double_jacobian(X1, Y1, z, curve);
+    apply_z(X2, Y2, z, curve);
+}
+
+void XYcZ_add(uECC_word_t *X1, uECC_word_t *Y1,
+              uECC_word_t *X2, uECC_word_t *Y2,
+              uECC_Curve curve)
+{
+    /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */
+    uECC_word_t t5[NUM_ECC_WORDS];
+    wordcount_t num_words = curve->num_words;
+    uECC_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */
+    uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */
+    uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */
+    uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */
+    uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */
+    uECC_vli_modSquare_fast(t5, Y2, curve); /* t5 = (y2 - y1)^2 = D */
+    uECC_vli_modSub(t5, t5, X1, curve->p, num_words); /* t5 = D - B */
+    uECC_vli_modSub(t5, t5, X2, curve->p, num_words); /* t5 = D - B - C = x3 */
+    uECC_vli_modSub(X2, X2, X1, curve->p, num_words); /* t3 = C - B */
+    uECC_vli_modMult_fast(Y1, Y1, X2, curve); /* t2 = y1*(C - B) */
+    uECC_vli_modSub(X2, X1, t5, curve->p, num_words); /* t3 = B - x3 */
+    uECC_vli_modMult_fast(Y2, Y2, X2, curve); /* t4 = (y2 - y1)*(B - x3) */
+    uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y3 */
+    uECC_vli_set(X2, t5, num_words);
 }
 
 /* Input P = (x1, y1, Z), Q = (x2, y2, Z)
    Output P + Q = (x3, y3, Z3), P - Q = (x3', y3', Z3)
    or P => P - Q, Q => P + Q
  */
-static void XYcZ_addC(uECC_word_t * X1, uECC_word_t * Y1,
-		      uECC_word_t * X2, uECC_word_t * Y2,
-		      uECC_Curve curve)
-{
-	/* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */
-	uECC_word_t t5[NUM_ECC_WORDS];
-	uECC_word_t t6[NUM_ECC_WORDS];
-	uECC_word_t t7[NUM_ECC_WORDS];
-	wordcount_t num_words = curve->num_words;
-
-	uECC_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */
-	uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */
-	uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */
-	uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */
-	uECC_vli_modAdd(t5, Y2, Y1, curve->p, num_words); /* t5 = y2 + y1 */
-	uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */
-
-	uECC_vli_modSub(t6, X2, X1, curve->p, num_words); /* t6 = C - B */
-	uECC_vli_modMult_fast(Y1, Y1, t6, curve); /* t2 = y1 * (C - B) = E */
-	uECC_vli_modAdd(t6, X1, X2, curve->p, num_words); /* t6 = B + C */
-	uECC_vli_modSquare_fast(X2, Y2, curve); /* t3 = (y2 - y1)^2 = D */
-	uECC_vli_modSub(X2, X2, t6, curve->p, num_words); /* t3 = D - (B + C) = x3 */
-
-	uECC_vli_modSub(t7, X1, X2, curve->p, num_words); /* t7 = B - x3 */
-	uECC_vli_modMult_fast(Y2, Y2, t7, curve); /* t4 = (y2 - y1)*(B - x3) */
-	/* t4 = (y2 - y1)*(B - x3) - E = y3: */
-	uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words);
-
-	uECC_vli_modSquare_fast(t7, t5, curve); /* t7 = (y2 + y1)^2 = F */
-	uECC_vli_modSub(t7, t7, t6, curve->p, num_words); /* t7 = F - (B + C) = x3' */
-	uECC_vli_modSub(t6, t7, X1, curve->p, num_words); /* t6 = x3' - B */
-	uECC_vli_modMult_fast(t6, t6, t5, curve); /* t6 = (y2+y1)*(x3' - B) */
-	/* t2 = (y2+y1)*(x3' - B) - E = y3': */
-	uECC_vli_modSub(Y1, t6, Y1, curve->p, num_words);
-
-	uECC_vli_set(X1, t7, num_words);
-}
-
-void EccPoint_mult(uECC_word_t * result, const uECC_word_t * point,
-		   const uECC_word_t * scalar,
-		   const uECC_word_t * initial_Z,
-		   bitcount_t num_bits, uECC_Curve curve) 
-{
-	/* R0 and R1 */
-	uECC_word_t Rx[2][NUM_ECC_WORDS];
-	uECC_word_t Ry[2][NUM_ECC_WORDS];
-	uECC_word_t z[NUM_ECC_WORDS];
-	bitcount_t i;
-	uECC_word_t nb;
-	wordcount_t num_words = curve->num_words;
-
-	uECC_vli_set(Rx[1], point, num_words);
-  	uECC_vli_set(Ry[1], point + num_words, num_words);
-
-	XYcZ_initial_double(Rx[1], Ry[1], Rx[0], Ry[0], initial_Z, curve);
-
-	for (i = num_bits - 2; i > 0; --i) {
-		nb = !uECC_vli_testBit(scalar, i);
-		XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve);
-		XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve);
-	}
-
-	nb = !uECC_vli_testBit(scalar, 0);
-	XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve);
-
-	/* Find final 1/Z value. */
-	uECC_vli_modSub(z, Rx[1], Rx[0], curve->p, num_words); /* X1 - X0 */
-	uECC_vli_modMult_fast(z, z, Ry[1 - nb], curve); /* Yb * (X1 - X0) */
-	uECC_vli_modMult_fast(z, z, point, curve); /* xP * Yb * (X1 - X0) */
-	uECC_vli_modInv(z, z, curve->p, num_words); /* 1 / (xP * Yb * (X1 - X0))*/
-	/* yP / (xP * Yb * (X1 - X0)) */
-	uECC_vli_modMult_fast(z, z, point + num_words, curve);
-	/* Xb * yP / (xP * Yb * (X1 - X0)) */
-	uECC_vli_modMult_fast(z, z, Rx[1 - nb], curve);
-	/* End 1/Z calculation */
-
-	XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve);
-	apply_z(Rx[0], Ry[0], z, curve);
-
-	uECC_vli_set(result, Rx[0], num_words);
-	uECC_vli_set(result + num_words, Ry[0], num_words);
-}
-
-uECC_word_t regularize_k(const uECC_word_t * const k, uECC_word_t *k0,
-			 uECC_word_t *k1, uECC_Curve curve)
-{
-
-	wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
-
-	bitcount_t num_n_bits = curve->num_n_bits;
-
-	uECC_word_t carry = uECC_vli_add(k0, k, curve->n, num_n_words) ||
-			     (num_n_bits < ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8) &&
-			     uECC_vli_testBit(k0, num_n_bits));
-
-	uECC_vli_add(k1, k0, curve->n, num_n_words);
-
-	return carry;
+static void XYcZ_addC(uECC_word_t *X1, uECC_word_t *Y1,
+                      uECC_word_t *X2, uECC_word_t *Y2,
+                      uECC_Curve curve)
+{
+    /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */
+    uECC_word_t t5[NUM_ECC_WORDS];
+    uECC_word_t t6[NUM_ECC_WORDS];
+    uECC_word_t t7[NUM_ECC_WORDS];
+    wordcount_t num_words = curve->num_words;
+    uECC_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */
+    uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */
+    uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */
+    uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */
+    uECC_vli_modAdd(t5, Y2, Y1, curve->p, num_words); /* t5 = y2 + y1 */
+    uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */
+    uECC_vli_modSub(t6, X2, X1, curve->p, num_words); /* t6 = C - B */
+    uECC_vli_modMult_fast(Y1, Y1, t6, curve); /* t2 = y1 * (C - B) = E */
+    uECC_vli_modAdd(t6, X1, X2, curve->p, num_words); /* t6 = B + C */
+    uECC_vli_modSquare_fast(X2, Y2, curve); /* t3 = (y2 - y1)^2 = D */
+    uECC_vli_modSub(X2, X2, t6, curve->p, num_words); /* t3 = D - (B + C) = x3 */
+    uECC_vli_modSub(t7, X1, X2, curve->p, num_words); /* t7 = B - x3 */
+    uECC_vli_modMult_fast(Y2, Y2, t7, curve); /* t4 = (y2 - y1)*(B - x3) */
+    /* t4 = (y2 - y1)*(B - x3) - E = y3: */
+    uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words);
+    uECC_vli_modSquare_fast(t7, t5, curve); /* t7 = (y2 + y1)^2 = F */
+    uECC_vli_modSub(t7, t7, t6, curve->p, num_words); /* t7 = F - (B + C) = x3' */
+    uECC_vli_modSub(t6, t7, X1, curve->p, num_words); /* t6 = x3' - B */
+    uECC_vli_modMult_fast(t6, t6, t5, curve); /* t6 = (y2+y1)*(x3' - B) */
+    /* t2 = (y2+y1)*(x3' - B) - E = y3': */
+    uECC_vli_modSub(Y1, t6, Y1, curve->p, num_words);
+    uECC_vli_set(X1, t7, num_words);
+}
+
+void EccPoint_mult(uECC_word_t *result, const uECC_word_t *point,
+                   const uECC_word_t *scalar,
+                   const uECC_word_t *initial_Z,
+                   bitcount_t num_bits, uECC_Curve curve)
+{
+    /* R0 and R1 */
+    uECC_word_t Rx[2][NUM_ECC_WORDS];
+    uECC_word_t Ry[2][NUM_ECC_WORDS];
+    uECC_word_t z[NUM_ECC_WORDS];
+    bitcount_t i;
+    uECC_word_t nb;
+    wordcount_t num_words = curve->num_words;
+    uECC_vli_set(Rx[1], point, num_words);
+    uECC_vli_set(Ry[1], point + num_words, num_words);
+    XYcZ_initial_double(Rx[1], Ry[1], Rx[0], Ry[0], initial_Z, curve);
+
+    for(i = num_bits - 2; i > 0; --i) {
+        nb = !uECC_vli_testBit(scalar, i);
+        XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve);
+        XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve);
+    }
+
+    nb = !uECC_vli_testBit(scalar, 0);
+    XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve);
+    /* Find final 1/Z value. */
+    uECC_vli_modSub(z, Rx[1], Rx[0], curve->p, num_words); /* X1 - X0 */
+    uECC_vli_modMult_fast(z, z, Ry[1 - nb], curve); /* Yb * (X1 - X0) */
+    uECC_vli_modMult_fast(z, z, point, curve); /* xP * Yb * (X1 - X0) */
+    uECC_vli_modInv(z, z, curve->p, num_words); /* 1 / (xP * Yb * (X1 - X0))*/
+    /* yP / (xP * Yb * (X1 - X0)) */
+    uECC_vli_modMult_fast(z, z, point + num_words, curve);
+    /* Xb * yP / (xP * Yb * (X1 - X0)) */
+    uECC_vli_modMult_fast(z, z, Rx[1 - nb], curve);
+    /* End 1/Z calculation */
+    XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve);
+    apply_z(Rx[0], Ry[0], z, curve);
+    uECC_vli_set(result, Rx[0], num_words);
+    uECC_vli_set(result + num_words, Ry[0], num_words);
+}
+
+uECC_word_t regularize_k(const uECC_word_t *const k, uECC_word_t *k0,
+                         uECC_word_t *k1, uECC_Curve curve)
+{
+    wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
+    bitcount_t num_n_bits = curve->num_n_bits;
+    uECC_word_t carry = uECC_vli_add(k0, k, curve->n, num_n_words) ||
+                        (num_n_bits < ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8) &&
+                         uECC_vli_testBit(k0, num_n_bits));
+    uECC_vli_add(k1, k0, curve->n, num_n_words);
+    return carry;
 }
 
 uECC_word_t EccPoint_compute_public_key(uECC_word_t *result,
-					uECC_word_t *private_key,
-					uECC_Curve curve)
+                                        uECC_word_t *private_key,
+                                        uECC_Curve curve)
 {
+    uECC_word_t tmp1[NUM_ECC_WORDS];
+    uECC_word_t tmp2[NUM_ECC_WORDS];
+    uECC_word_t *p2[2] = {tmp1, tmp2};
+    uECC_word_t carry;
+    /* Regularize the bitcount for the private key so that attackers cannot
+     * use a side channel attack to learn the number of leading zeros. */
+    carry = regularize_k(private_key, tmp1, tmp2, curve);
+    EccPoint_mult(result, curve->G, p2[!carry], 0, curve->num_n_bits + 1, curve);
 
-	uECC_word_t tmp1[NUM_ECC_WORDS];
- 	uECC_word_t tmp2[NUM_ECC_WORDS];
-	uECC_word_t *p2[2] = {tmp1, tmp2};
-	uECC_word_t carry;
-
-	/* Regularize the bitcount for the private key so that attackers cannot
-	 * use a side channel attack to learn the number of leading zeros. */
-	carry = regularize_k(private_key, tmp1, tmp2, curve);
-
-	EccPoint_mult(result, curve->G, p2[!carry], 0, curve->num_n_bits + 1, curve);
+    if(EccPoint_isZero(result, curve)) {
+        return 0;
+    }
 
-	if (EccPoint_isZero(result, curve)) {
-		return 0;
-	}
-	return 1;
+    return 1;
 }
 
 /* Converts an integer in uECC native format to big-endian bytes. */
 void uECC_vli_nativeToBytes(uint8_t *bytes, int num_bytes,
-			    const unsigned int *native)
+                            const unsigned int *native)
 {
-	wordcount_t i;
-	for (i = 0; i < num_bytes; ++i) {
-		unsigned b = num_bytes - 1 - i;
-		bytes[i] = native[b / uECC_WORD_SIZE] >> (8 * (b % uECC_WORD_SIZE));
-	}
+    wordcount_t i;
+
+    for(i = 0; i < num_bytes; ++i) {
+        unsigned b = num_bytes - 1 - i;
+        bytes[i] = native[b / uECC_WORD_SIZE] >> (8 * (b % uECC_WORD_SIZE));
+    }
 }
 
 /* Converts big-endian bytes to an integer in uECC native format. */
 void uECC_vli_bytesToNative(unsigned int *native, const uint8_t *bytes,
-			    int num_bytes)
+                            int num_bytes)
 {
-	wordcount_t i;
-	uECC_vli_clear(native, (num_bytes + (uECC_WORD_SIZE - 1)) / uECC_WORD_SIZE);
-	for (i = 0; i < num_bytes; ++i) {
-		unsigned b = num_bytes - 1 - i;
-		native[b / uECC_WORD_SIZE] |=
-			(uECC_word_t)bytes[i] << (8 * (b % uECC_WORD_SIZE));
-  	}
+    wordcount_t i;
+    uECC_vli_clear(native, (num_bytes + (uECC_WORD_SIZE - 1)) / uECC_WORD_SIZE);
+
+    for(i = 0; i < num_bytes; ++i) {
+        unsigned b = num_bytes - 1 - i;
+        native[b / uECC_WORD_SIZE] |=
+                        (uECC_word_t)bytes[i] << (8 * (b % uECC_WORD_SIZE));
+    }
 }
 
 int uECC_generate_random_int(uECC_word_t *random, const uECC_word_t *top,
-			     wordcount_t num_words)
+                             wordcount_t num_words)
 {
-	uECC_word_t mask = (uECC_word_t)-1;
-	uECC_word_t tries;
-	bitcount_t num_bits = uECC_vli_numBits(top, num_words);
+    uECC_word_t mask = (uECC_word_t) -1;
+    uECC_word_t tries;
+    bitcount_t num_bits = uECC_vli_numBits(top, num_words);
+
+    if(!g_rng_function) {
+        return 0;
+    }
+
+    for(tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
+        if(!g_rng_function((uint8_t *)random, num_words * uECC_WORD_SIZE)) {
+            return 0;
+        }
 
-	if (!g_rng_function) {
-		return 0;
-	}
+        random[num_words - 1] &=
+                        mask >> ((bitcount_t)(num_words * uECC_WORD_SIZE * 8 - num_bits));
 
-	for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
-		if (!g_rng_function((uint8_t *)random, num_words * uECC_WORD_SIZE)) {
-      			return 0;
-    		}
-		random[num_words - 1] &=
-        		mask >> ((bitcount_t)(num_words * uECC_WORD_SIZE * 8 - num_bits));
-		if (!uECC_vli_isZero(random, num_words) &&
-			uECC_vli_cmp(top, random, num_words) == 1) {
-			return 1;
-		}
-	}
-	return 0;
+        if(!uECC_vli_isZero(random, num_words) &&
+                uECC_vli_cmp(top, random, num_words) == 1) {
+            return 1;
+        }
+    }
+
+    return 0;
 }
 
 
 int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve)
 {
-	uECC_word_t tmp1[NUM_ECC_WORDS];
-	uECC_word_t tmp2[NUM_ECC_WORDS];
-	wordcount_t num_words = curve->num_words;
+    uECC_word_t tmp1[NUM_ECC_WORDS];
+    uECC_word_t tmp2[NUM_ECC_WORDS];
+    wordcount_t num_words = curve->num_words;
 
-	/* The point at infinity is invalid. */
-	if (EccPoint_isZero(point, curve)) {
-		return -1;
-	}
+    /* The point at infinity is invalid. */
+    if(EccPoint_isZero(point, curve)) {
+        return -1;
+    }
 
-	/* x and y must be smaller than p. */
-	if (uECC_vli_cmp_unsafe(curve->p, point, num_words) != 1 ||
-		uECC_vli_cmp_unsafe(curve->p, point + num_words, num_words) != 1) {
-		return -2;
-	}
+    /* x and y must be smaller than p. */
+    if(uECC_vli_cmp_unsafe(curve->p, point, num_words) != 1 ||
+            uECC_vli_cmp_unsafe(curve->p, point + num_words, num_words) != 1) {
+        return -2;
+    }
 
-	uECC_vli_modSquare_fast(tmp1, point + num_words, curve);
-	curve->x_side(tmp2, point, curve); /* tmp2 = x^3 + ax + b */
+    uECC_vli_modSquare_fast(tmp1, point + num_words, curve);
+    curve->x_side(tmp2, point, curve); /* tmp2 = x^3 + ax + b */
 
-	/* Make sure that y^2 == x^3 + ax + b */
-	if (uECC_vli_equal(tmp1, tmp2, num_words) != 0)
-		return -3;
+    /* Make sure that y^2 == x^3 + ax + b */
+    if(uECC_vli_equal(tmp1, tmp2, num_words) != 0)
+    { return -3; }
 
-	return 0;
+    return 0;
 }
 
 int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve)
 {
+    uECC_word_t _public[NUM_ECC_WORDS * 2];
+    uECC_vli_bytesToNative(_public, public_key, curve->num_bytes);
+    uECC_vli_bytesToNative(
+                    _public + curve->num_words,
+                    public_key + curve->num_bytes,
+                    curve->num_bytes);
 
-	uECC_word_t _public[NUM_ECC_WORDS * 2];
-
-	uECC_vli_bytesToNative(_public, public_key, curve->num_bytes);
-	uECC_vli_bytesToNative(
-	_public + curve->num_words,
-	public_key + curve->num_bytes,
-	curve->num_bytes);
-
-	if (uECC_vli_cmp_unsafe(_public, curve->G, NUM_ECC_WORDS * 2) == 0) {
-		return -4;
-	}
+    if(uECC_vli_cmp_unsafe(_public, curve->G, NUM_ECC_WORDS * 2) == 0) {
+        return -4;
+    }
 
-	return uECC_valid_point(_public, curve);
+    return uECC_valid_point(_public, curve);
 }
 
 int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key,
-			    uECC_Curve curve)
-{
-
-	uECC_word_t _private[NUM_ECC_WORDS];
-	uECC_word_t _public[NUM_ECC_WORDS * 2];
-
-	uECC_vli_bytesToNative(
-	_private,
-	private_key,
-	BITS_TO_BYTES(curve->num_n_bits));
-
-	/* Make sure the private key is in the range [1, n-1]. */
-	if (uECC_vli_isZero(_private, BITS_TO_WORDS(curve->num_n_bits))) {
-		return 0;
-	}
-
-	if (uECC_vli_cmp(curve->n, _private, BITS_TO_WORDS(curve->num_n_bits)) != 1) {
-		return 0;
-	}
-
-	/* Compute public key. */
-	if (!EccPoint_compute_public_key(_public, _private, curve)) {
-		return 0;
-	}
-
-	uECC_vli_nativeToBytes(public_key, curve->num_bytes, _public);
-	uECC_vli_nativeToBytes(
-	public_key +
-	curve->num_bytes, curve->num_bytes, _public + curve->num_words);
-	return 1;
+                            uECC_Curve curve)
+{
+    uECC_word_t _private[NUM_ECC_WORDS];
+    uECC_word_t _public[NUM_ECC_WORDS * 2];
+    uECC_vli_bytesToNative(
+                    _private,
+                    private_key,
+                    BITS_TO_BYTES(curve->num_n_bits));
+
+    /* Make sure the private key is in the range [1, n-1]. */
+    if(uECC_vli_isZero(_private, BITS_TO_WORDS(curve->num_n_bits))) {
+        return 0;
+    }
+
+    if(uECC_vli_cmp(curve->n, _private, BITS_TO_WORDS(curve->num_n_bits)) != 1) {
+        return 0;
+    }
+
+    /* Compute public key. */
+    if(!EccPoint_compute_public_key(_public, _private, curve)) {
+        return 0;
+    }
+
+    uECC_vli_nativeToBytes(public_key, curve->num_bytes, _public);
+    uECC_vli_nativeToBytes(
+                    public_key +
+                    curve->num_bytes, curve->num_bytes, _public + curve->num_words);
+    return 1;
 }
 
 

+ 110 - 122
src/bt/blehost/ext/tinycrypt/src/ecc_dh.c

@@ -1,6 +1,6 @@
 /* ec_dh.c - TinyCrypt implementation of EC-DH */
 
-/* 
+/*
  * Copyright (c) 2014, Kenneth MacKay
  * All rights reserved.
  *
@@ -66,135 +66,123 @@ static uECC_RNG_Function g_rng_function = 0;
 #endif
 
 int uECC_make_key_with_d(uint8_t *public_key, uint8_t *private_key,
-			 unsigned int *d, uECC_Curve curve)
+                         unsigned int *d, uECC_Curve curve)
 {
-
-	uECC_word_t _private[NUM_ECC_WORDS];
-	uECC_word_t _public[NUM_ECC_WORDS * 2];
-
-	/* This function is designed for test purposes-only (such as validating NIST
-	 * test vectors) as it uses a provided value for d instead of generating
-	 * it uniformly at random. */
-	memcpy (_private, d, NUM_ECC_BYTES);
-
-	/* Computing public-key from private: */
-	if (EccPoint_compute_public_key(_public, _private, curve)) {
-
-		/* Converting buffers to correct bit order: */
-		uECC_vli_nativeToBytes(private_key,
-				       BITS_TO_BYTES(curve->num_n_bits),
-				       _private);
-		uECC_vli_nativeToBytes(public_key,
-				       curve->num_bytes,
-				       _public);
-		uECC_vli_nativeToBytes(public_key + curve->num_bytes,
-				       curve->num_bytes,
-				       _public + curve->num_words);
-
-		/* erasing temporary buffer used to store secret: */
-		memset(_private, 0, NUM_ECC_BYTES);
-
-		return 1;
-	}
-	return 0;
+    uECC_word_t _private[NUM_ECC_WORDS];
+    uECC_word_t _public[NUM_ECC_WORDS * 2];
+    /* This function is designed for test purposes-only (such as validating NIST
+     * test vectors) as it uses a provided value for d instead of generating
+     * it uniformly at random. */
+    memcpy(_private, d, NUM_ECC_BYTES);
+
+    /* Computing public-key from private: */
+    if(EccPoint_compute_public_key(_public, _private, curve)) {
+        /* Converting buffers to correct bit order: */
+        uECC_vli_nativeToBytes(private_key,
+                               BITS_TO_BYTES(curve->num_n_bits),
+                               _private);
+        uECC_vli_nativeToBytes(public_key,
+                               curve->num_bytes,
+                               _public);
+        uECC_vli_nativeToBytes(public_key + curve->num_bytes,
+                               curve->num_bytes,
+                               _public + curve->num_words);
+        /* erasing temporary buffer used to store secret: */
+        memset(_private, 0, NUM_ECC_BYTES);
+        return 1;
+    }
+
+    return 0;
 }
 
 int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve)
 {
-
-	uECC_word_t _random[NUM_ECC_WORDS * 2];
-	uECC_word_t _private[NUM_ECC_WORDS];
-	uECC_word_t _public[NUM_ECC_WORDS * 2];
-	uECC_word_t tries;
-
-	for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
-		/* Generating _private uniformly at random: */
-		uECC_RNG_Function rng_function = uECC_get_rng();
-		if (!rng_function ||
-			!rng_function((uint8_t *)_random, 2 * NUM_ECC_WORDS*uECC_WORD_SIZE)) {
-        		return 0;
-		}
-
-		/* computing modular reduction of _random (see FIPS 186.4 B.4.1): */
-		uECC_vli_mmod(_private, _random, curve->n, BITS_TO_WORDS(curve->num_n_bits));
-
-		/* Computing public-key from private: */
-		if (EccPoint_compute_public_key(_public, _private, curve)) {
-
-			/* Converting buffers to correct bit order: */
-			uECC_vli_nativeToBytes(private_key,
-					       BITS_TO_BYTES(curve->num_n_bits),
-					       _private);
-			uECC_vli_nativeToBytes(public_key,
-					       curve->num_bytes,
-					       _public);
-			uECC_vli_nativeToBytes(public_key + curve->num_bytes,
- 					       curve->num_bytes,
-					       _public + curve->num_words);
-
-			/* erasing temporary buffer that stored secret: */
-			memset(_private, 0, NUM_ECC_BYTES);
-
-      			return 1;
-    		}
-  	}
-	return 0;
+    uECC_word_t _random[NUM_ECC_WORDS * 2];
+    uECC_word_t _private[NUM_ECC_WORDS];
+    uECC_word_t _public[NUM_ECC_WORDS * 2];
+    uECC_word_t tries;
+
+    for(tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
+        /* Generating _private uniformly at random: */
+        uECC_RNG_Function rng_function = uECC_get_rng();
+
+        if(!rng_function ||
+                !rng_function((uint8_t *)_random, 2 * NUM_ECC_WORDS * uECC_WORD_SIZE)) {
+            return 0;
+        }
+
+        /* computing modular reduction of _random (see FIPS 186.4 B.4.1): */
+        uECC_vli_mmod(_private, _random, curve->n, BITS_TO_WORDS(curve->num_n_bits));
+
+        /* Computing public-key from private: */
+        if(EccPoint_compute_public_key(_public, _private, curve)) {
+            /* Converting buffers to correct bit order: */
+            uECC_vli_nativeToBytes(private_key,
+                                   BITS_TO_BYTES(curve->num_n_bits),
+                                   _private);
+            uECC_vli_nativeToBytes(public_key,
+                                   curve->num_bytes,
+                                   _public);
+            uECC_vli_nativeToBytes(public_key + curve->num_bytes,
+                                   curve->num_bytes,
+                                   _public + curve->num_words);
+            /* erasing temporary buffer that stored secret: */
+            memset(_private, 0, NUM_ECC_BYTES);
+            return 1;
+        }
+    }
+
+    return 0;
 }
 
 int uECC_shared_secret(const uint8_t *public_key, const uint8_t *private_key,
-		       uint8_t *secret, uECC_Curve curve)
+                       uint8_t *secret, uECC_Curve curve)
 {
-
-	uECC_word_t _public[NUM_ECC_WORDS * 2];
-	uECC_word_t _private[NUM_ECC_WORDS];
-
-	uECC_word_t tmp[NUM_ECC_WORDS];
-	uECC_word_t *p2[2] = {_private, tmp};
-	uECC_word_t *initial_Z = 0;
-	uECC_word_t carry;
-	wordcount_t num_words = curve->num_words;
-	wordcount_t num_bytes = curve->num_bytes;
-	int r;
-
-	/* Converting buffers to correct bit order: */
-	uECC_vli_bytesToNative(_private,
-      			       private_key,
-			       BITS_TO_BYTES(curve->num_n_bits));
-	uECC_vli_bytesToNative(_public,
-      			       public_key,
-			       num_bytes);
-	uECC_vli_bytesToNative(_public + num_words,
-			       public_key + num_bytes,
-			       num_bytes);
-
-	/* Regularize the bitcount for the private key so that attackers cannot use a
-	 * side channel attack to learn the number of leading zeros. */
-	carry = regularize_k(_private, _private, tmp, curve);
-
-	/* If an RNG function was specified, try to get a random initial Z value to
-	 * improve protection against side-channel attacks. */
-	if (g_rng_function) {
-		if (!uECC_generate_random_int(p2[carry], curve->p, num_words)) {
-			r = 0;
-			goto clear_and_out;
-    		}
-    		initial_Z = p2[carry];
-  	}
-
-	EccPoint_mult(_public, _public, p2[!carry], initial_Z, curve->num_n_bits + 1,
-		      curve);
-
-	uECC_vli_nativeToBytes(secret, num_bytes, _public);
-	r = !EccPoint_isZero(_public, curve);
-
+    uECC_word_t _public[NUM_ECC_WORDS * 2];
+    uECC_word_t _private[NUM_ECC_WORDS];
+    uECC_word_t tmp[NUM_ECC_WORDS];
+    uECC_word_t *p2[2] = {_private, tmp};
+    uECC_word_t *initial_Z = 0;
+    uECC_word_t carry;
+    wordcount_t num_words = curve->num_words;
+    wordcount_t num_bytes = curve->num_bytes;
+    int r;
+    /* Converting buffers to correct bit order: */
+    uECC_vli_bytesToNative(_private,
+                           private_key,
+                           BITS_TO_BYTES(curve->num_n_bits));
+    uECC_vli_bytesToNative(_public,
+                           public_key,
+                           num_bytes);
+    uECC_vli_bytesToNative(_public + num_words,
+                           public_key + num_bytes,
+                           num_bytes);
+    /* Regularize the bitcount for the private key so that attackers cannot use a
+     * side channel attack to learn the number of leading zeros. */
+    carry = regularize_k(_private, _private, tmp, curve);
+
+    /* If an RNG function was specified, try to get a random initial Z value to
+     * improve protection against side-channel attacks. */
+    if(g_rng_function) {
+        if(!uECC_generate_random_int(p2[carry], curve->p, num_words)) {
+            r = 0;
+            goto clear_and_out;
+        }
+
+        initial_Z = p2[carry];
+    }
+
+    EccPoint_mult(_public, _public, p2[!carry], initial_Z, curve->num_n_bits + 1,
+                  curve);
+    uECC_vli_nativeToBytes(secret, num_bytes, _public);
+    r = !EccPoint_isZero(_public, curve);
 clear_and_out:
-	/* erasing temporary buffer used to store secret: */
-	memset(p2, 0, sizeof(p2));
-	__asm__ __volatile__("" :: "g"(p2) : "memory");
-	memset(tmp, 0, sizeof(tmp));
-	__asm__ __volatile__("" :: "g"(tmp) : "memory");
-	memset(_private, 0, sizeof(_private));
-	__asm__ __volatile__("" :: "g"(_private) : "memory");
-
-	return r;
+    /* erasing temporary buffer used to store secret: */
+    memset(p2, 0, sizeof(p2));
+    __asm__ __volatile__("" :: "g"(p2) : "memory");
+    memset(tmp, 0, sizeof(tmp));
+    __asm__ __volatile__("" :: "g"(tmp) : "memory");
+    memset(_private, 0, sizeof(_private));
+    __asm__ __volatile__("" :: "g"(_private) : "memory");
+    return r;
 }

+ 204 - 210
src/bt/blehost/ext/tinycrypt/src/ecc_dsa.c

@@ -64,232 +64,226 @@ static uECC_RNG_Function g_rng_function = 0;
 #endif
 
 static void bits2int(uECC_word_t *native, const uint8_t *bits,
-		     unsigned bits_size, uECC_Curve curve)
+                     unsigned bits_size, uECC_Curve curve)
 {
-	unsigned num_n_bytes = BITS_TO_BYTES(curve->num_n_bits);
-	unsigned num_n_words = BITS_TO_WORDS(curve->num_n_bits);
-	int shift;
-	uECC_word_t carry;
-	uECC_word_t *ptr;
-
-	if (bits_size > num_n_bytes) {
-		bits_size = num_n_bytes;
-	}
-
-	uECC_vli_clear(native, num_n_words);
-	uECC_vli_bytesToNative(native, bits, bits_size);
-	if (bits_size * 8 <= (unsigned)curve->num_n_bits) {
-		return;
-	}
-	shift = bits_size * 8 - curve->num_n_bits;
-	carry = 0;
-	ptr = native + num_n_words;
-	while (ptr-- > native) {
-		uECC_word_t temp = *ptr;
-		*ptr = (temp >> shift) | carry;
-		carry = temp << (uECC_WORD_BITS - shift);
-	}
-
-	/* Reduce mod curve_n */
-	if (uECC_vli_cmp_unsafe(curve->n, native, num_n_words) != 1) {
-		uECC_vli_sub(native, native, curve->n, num_n_words);
-	}
+    unsigned num_n_bytes = BITS_TO_BYTES(curve->num_n_bits);
+    unsigned num_n_words = BITS_TO_WORDS(curve->num_n_bits);
+    int shift;
+    uECC_word_t carry;
+    uECC_word_t *ptr;
+
+    if(bits_size > num_n_bytes) {
+        bits_size = num_n_bytes;
+    }
+
+    uECC_vli_clear(native, num_n_words);
+    uECC_vli_bytesToNative(native, bits, bits_size);
+
+    if(bits_size * 8 <= (unsigned)curve->num_n_bits) {
+        return;
+    }
+
+    shift = bits_size * 8 - curve->num_n_bits;
+    carry = 0;
+    ptr = native + num_n_words;
+
+    while(ptr-- > native) {
+        uECC_word_t temp = *ptr;
+        *ptr = (temp >> shift) | carry;
+        carry = temp << (uECC_WORD_BITS - shift);
+    }
+
+    /* Reduce mod curve_n */
+    if(uECC_vli_cmp_unsafe(curve->n, native, num_n_words) != 1) {
+        uECC_vli_sub(native, native, curve->n, num_n_words);
+    }
 }
 
 int uECC_sign_with_k(const uint8_t *private_key, const uint8_t *message_hash,
-		     unsigned hash_size, uECC_word_t *k, uint8_t *signature,
-		     uECC_Curve curve)
+                     unsigned hash_size, uECC_word_t *k, uint8_t *signature,
+                     uECC_Curve curve)
 {
-
-	uECC_word_t tmp[NUM_ECC_WORDS];
-	uECC_word_t s[NUM_ECC_WORDS];
-	uECC_word_t *k2[2] = {tmp, s};
-	uECC_word_t p[NUM_ECC_WORDS * 2];
-	uECC_word_t carry;
-	wordcount_t num_words = curve->num_words;
-	wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
-	bitcount_t num_n_bits = curve->num_n_bits;
-
-	/* Make sure 0 < k < curve_n */
-  	if (uECC_vli_isZero(k, num_words) ||
-	    uECC_vli_cmp(curve->n, k, num_n_words) != 1) {
-		return 0;
-	}
-
-	carry = regularize_k(k, tmp, s, curve);
-	EccPoint_mult(p, curve->G, k2[!carry], 0, num_n_bits + 1, curve);
-	if (uECC_vli_isZero(p, num_words)) {
-		return 0;
-	}
-
-	/* If an RNG function was specified, get a random number
-	to prevent side channel analysis of k. */
-	if (!g_rng_function) {
-		uECC_vli_clear(tmp, num_n_words);
-		tmp[0] = 1;
-	}
-	else if (!uECC_generate_random_int(tmp, curve->n, num_n_words)) {
-		return 0;
-	}
-
-	/* Prevent side channel analysis of uECC_vli_modInv() to determine
-	bits of k / the private key by premultiplying by a random number */
-	uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k' = rand * k */
-	uECC_vli_modInv(k, k, curve->n, num_n_words);       /* k = 1 / k' */
-	uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k = 1 / k */
-
-	uECC_vli_nativeToBytes(signature, curve->num_bytes, p); /* store r */
-
-	/* tmp = d: */
-	uECC_vli_bytesToNative(tmp, private_key, BITS_TO_BYTES(curve->num_n_bits));
-
-	s[num_n_words - 1] = 0;
-	uECC_vli_set(s, p, num_words);
-	uECC_vli_modMult(s, tmp, s, curve->n, num_n_words); /* s = r*d */
-
-	bits2int(tmp, message_hash, hash_size, curve);
-	uECC_vli_modAdd(s, tmp, s, curve->n, num_n_words); /* s = e + r*d */
-	uECC_vli_modMult(s, s, k, curve->n, num_n_words);  /* s = (e + r*d) / k */
-	if (uECC_vli_numBits(s, num_n_words) > (bitcount_t)curve->num_bytes * 8) {
-		return 0;
-	}
-
-	uECC_vli_nativeToBytes(signature + curve->num_bytes, curve->num_bytes, s);
-	return 1;
+    uECC_word_t tmp[NUM_ECC_WORDS];
+    uECC_word_t s[NUM_ECC_WORDS];
+    uECC_word_t *k2[2] = {tmp, s};
+    uECC_word_t p[NUM_ECC_WORDS * 2];
+    uECC_word_t carry;
+    wordcount_t num_words = curve->num_words;
+    wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
+    bitcount_t num_n_bits = curve->num_n_bits;
+
+    /* Make sure 0 < k < curve_n */
+    if(uECC_vli_isZero(k, num_words) ||
+            uECC_vli_cmp(curve->n, k, num_n_words) != 1) {
+        return 0;
+    }
+
+    carry = regularize_k(k, tmp, s, curve);
+    EccPoint_mult(p, curve->G, k2[!carry], 0, num_n_bits + 1, curve);
+
+    if(uECC_vli_isZero(p, num_words)) {
+        return 0;
+    }
+
+    /* If an RNG function was specified, get a random number
+    to prevent side channel analysis of k. */
+    if(!g_rng_function) {
+        uECC_vli_clear(tmp, num_n_words);
+        tmp[0] = 1;
+    } else if(!uECC_generate_random_int(tmp, curve->n, num_n_words)) {
+        return 0;
+    }
+
+    /* Prevent side channel analysis of uECC_vli_modInv() to determine
+    bits of k / the private key by premultiplying by a random number */
+    uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k' = rand * k */
+    uECC_vli_modInv(k, k, curve->n, num_n_words);       /* k = 1 / k' */
+    uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k = 1 / k */
+    uECC_vli_nativeToBytes(signature, curve->num_bytes, p); /* store r */
+    /* tmp = d: */
+    uECC_vli_bytesToNative(tmp, private_key, BITS_TO_BYTES(curve->num_n_bits));
+    s[num_n_words - 1] = 0;
+    uECC_vli_set(s, p, num_words);
+    uECC_vli_modMult(s, tmp, s, curve->n, num_n_words); /* s = r*d */
+    bits2int(tmp, message_hash, hash_size, curve);
+    uECC_vli_modAdd(s, tmp, s, curve->n, num_n_words); /* s = e + r*d */
+    uECC_vli_modMult(s, s, k, curve->n, num_n_words);  /* s = (e + r*d) / k */
+
+    if(uECC_vli_numBits(s, num_n_words) > (bitcount_t)curve->num_bytes * 8) {
+        return 0;
+    }
+
+    uECC_vli_nativeToBytes(signature + curve->num_bytes, curve->num_bytes, s);
+    return 1;
 }
 
 int uECC_sign(const uint8_t *private_key, const uint8_t *message_hash,
-	      unsigned hash_size, uint8_t *signature, uECC_Curve curve)
+              unsigned hash_size, uint8_t *signature, uECC_Curve curve)
 {
-	      uECC_word_t _random[2*NUM_ECC_WORDS];
-	      uECC_word_t k[NUM_ECC_WORDS];
-	      uECC_word_t tries;
-
-	for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
-		/* Generating _random uniformly at random: */
-		uECC_RNG_Function rng_function = uECC_get_rng();
-		if (!rng_function ||
-		    !rng_function((uint8_t *)_random, 2*NUM_ECC_WORDS*uECC_WORD_SIZE)) {
-			return 0;
-		}
-
-		// computing k as modular reduction of _random (see FIPS 186.4 B.5.1):
-		uECC_vli_mmod(k, _random, curve->n, BITS_TO_WORDS(curve->num_n_bits));
-
-		if (uECC_sign_with_k(private_key, message_hash, hash_size, k, signature, 
-		    curve)) {
-			return 1;
-		}
-	}
-	return 0;
+    uECC_word_t _random[2 * NUM_ECC_WORDS];
+    uECC_word_t k[NUM_ECC_WORDS];
+    uECC_word_t tries;
+
+    for(tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
+        /* Generating _random uniformly at random: */
+        uECC_RNG_Function rng_function = uECC_get_rng();
+
+        if(!rng_function ||
+                !rng_function((uint8_t *)_random, 2 * NUM_ECC_WORDS * uECC_WORD_SIZE)) {
+            return 0;
+        }
+
+        // computing k as modular reduction of _random (see FIPS 186.4 B.5.1):
+        uECC_vli_mmod(k, _random, curve->n, BITS_TO_WORDS(curve->num_n_bits));
+
+        if(uECC_sign_with_k(private_key, message_hash, hash_size, k, signature,
+                            curve)) {
+            return 1;
+        }
+    }
+
+    return 0;
 }
 
 static bitcount_t smax(bitcount_t a, bitcount_t b)
 {
-	return (a > b ? a : b);
+    return (a > b ? a : b);
 }
 
 int uECC_verify(const uint8_t *public_key, const uint8_t *message_hash,
-		unsigned hash_size, const uint8_t *signature,
-	        uECC_Curve curve)
+                unsigned hash_size, const uint8_t *signature,
+                uECC_Curve curve)
 {
-
-	uECC_word_t u1[NUM_ECC_WORDS], u2[NUM_ECC_WORDS];
-	uECC_word_t z[NUM_ECC_WORDS];
-	uECC_word_t sum[NUM_ECC_WORDS * 2];
-	uECC_word_t rx[NUM_ECC_WORDS];
-	uECC_word_t ry[NUM_ECC_WORDS];
-	uECC_word_t tx[NUM_ECC_WORDS];
-	uECC_word_t ty[NUM_ECC_WORDS];
-	uECC_word_t tz[NUM_ECC_WORDS];
-	const uECC_word_t *points[4];
-	const uECC_word_t *point;
-	bitcount_t num_bits;
-	bitcount_t i;
-
-	uECC_word_t _public[NUM_ECC_WORDS * 2];
-	uECC_word_t r[NUM_ECC_WORDS], s[NUM_ECC_WORDS];
-	wordcount_t num_words = curve->num_words;
-	wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
-
-	rx[num_n_words - 1] = 0;
-	r[num_n_words - 1] = 0;
-	s[num_n_words - 1] = 0;
-
-	uECC_vli_bytesToNative(_public, public_key, curve->num_bytes);
-	uECC_vli_bytesToNative(_public + num_words, public_key + curve->num_bytes,
-			       curve->num_bytes);
-	uECC_vli_bytesToNative(r, signature, curve->num_bytes);
-	uECC_vli_bytesToNative(s, signature + curve->num_bytes, curve->num_bytes);
-
-	/* r, s must not be 0. */
-	if (uECC_vli_isZero(r, num_words) || uECC_vli_isZero(s, num_words)) {
-		return 0;
-	}
-
-	/* r, s must be < n. */
-	if (uECC_vli_cmp_unsafe(curve->n, r, num_n_words) != 1 ||
-	    uECC_vli_cmp_unsafe(curve->n, s, num_n_words) != 1) {
-		return 0;
-	}
-
-	/* Calculate u1 and u2. */
-	uECC_vli_modInv(z, s, curve->n, num_n_words); /* z = 1/s */
-	u1[num_n_words - 1] = 0;
-	bits2int(u1, message_hash, hash_size, curve);
-	uECC_vli_modMult(u1, u1, z, curve->n, num_n_words); /* u1 = e/s */
-	uECC_vli_modMult(u2, r, z, curve->n, num_n_words); /* u2 = r/s */
-
-	/* Calculate sum = G + Q. */
-	uECC_vli_set(sum, _public, num_words);
-	uECC_vli_set(sum + num_words, _public + num_words, num_words);
-	uECC_vli_set(tx, curve->G, num_words);
-	uECC_vli_set(ty, curve->G + num_words, num_words);
-	uECC_vli_modSub(z, sum, tx, curve->p, num_words); /* z = x2 - x1 */
-	XYcZ_add(tx, ty, sum, sum + num_words, curve);
-	uECC_vli_modInv(z, z, curve->p, num_words); /* z = 1/z */
-	apply_z(sum, sum + num_words, z, curve);
-
-	/* Use Shamir's trick to calculate u1*G + u2*Q */
-	points[0] = 0;
-	points[1] = curve->G;
-	points[2] = _public;
-	points[3] = sum;
-	num_bits = smax(uECC_vli_numBits(u1, num_n_words),
-	uECC_vli_numBits(u2, num_n_words));
-
-	point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) |
-                       ((!!uECC_vli_testBit(u2, num_bits - 1)) << 1)];
-	uECC_vli_set(rx, point, num_words);
-	uECC_vli_set(ry, point + num_words, num_words);
-	uECC_vli_clear(z, num_words);
-	z[0] = 1;
-
-	for (i = num_bits - 2; i >= 0; --i) {
-		uECC_word_t index;
-		curve->double_jacobian(rx, ry, z, curve);
-
-		index = (!!uECC_vli_testBit(u1, i)) | ((!!uECC_vli_testBit(u2, i)) << 1);
-		point = points[index];
-		if (point) {
-			uECC_vli_set(tx, point, num_words);
-			uECC_vli_set(ty, point + num_words, num_words);
-			apply_z(tx, ty, z, curve);
-			uECC_vli_modSub(tz, rx, tx, curve->p, num_words); /* Z = x2 - x1 */
-			XYcZ_add(tx, ty, rx, ry, curve);
-			uECC_vli_modMult_fast(z, z, tz, curve);
-		}
-  	}
-
-	uECC_vli_modInv(z, z, curve->p, num_words); /* Z = 1/Z */
-	apply_z(rx, ry, z, curve);
-
-	/* v = x1 (mod n) */
-	if (uECC_vli_cmp_unsafe(curve->n, rx, num_n_words) != 1) {
-		uECC_vli_sub(rx, rx, curve->n, num_n_words);
-	}
-
-	/* Accept only if v == r. */
-	return (int)(uECC_vli_equal(rx, r, num_words) == 0);
+    uECC_word_t u1[NUM_ECC_WORDS], u2[NUM_ECC_WORDS];
+    uECC_word_t z[NUM_ECC_WORDS];
+    uECC_word_t sum[NUM_ECC_WORDS * 2];
+    uECC_word_t rx[NUM_ECC_WORDS];
+    uECC_word_t ry[NUM_ECC_WORDS];
+    uECC_word_t tx[NUM_ECC_WORDS];
+    uECC_word_t ty[NUM_ECC_WORDS];
+    uECC_word_t tz[NUM_ECC_WORDS];
+    const uECC_word_t *points[4];
+    const uECC_word_t *point;
+    bitcount_t num_bits;
+    bitcount_t i;
+    uECC_word_t _public[NUM_ECC_WORDS * 2];
+    uECC_word_t r[NUM_ECC_WORDS], s[NUM_ECC_WORDS];
+    wordcount_t num_words = curve->num_words;
+    wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
+    rx[num_n_words - 1] = 0;
+    r[num_n_words - 1] = 0;
+    s[num_n_words - 1] = 0;
+    uECC_vli_bytesToNative(_public, public_key, curve->num_bytes);
+    uECC_vli_bytesToNative(_public + num_words, public_key + curve->num_bytes,
+                           curve->num_bytes);
+    uECC_vli_bytesToNative(r, signature, curve->num_bytes);
+    uECC_vli_bytesToNative(s, signature + curve->num_bytes, curve->num_bytes);
+
+    /* r, s must not be 0. */
+    if(uECC_vli_isZero(r, num_words) || uECC_vli_isZero(s, num_words)) {
+        return 0;
+    }
+
+    /* r, s must be < n. */
+    if(uECC_vli_cmp_unsafe(curve->n, r, num_n_words) != 1 ||
+            uECC_vli_cmp_unsafe(curve->n, s, num_n_words) != 1) {
+        return 0;
+    }
+
+    /* Calculate u1 and u2. */
+    uECC_vli_modInv(z, s, curve->n, num_n_words); /* z = 1/s */
+    u1[num_n_words - 1] = 0;
+    bits2int(u1, message_hash, hash_size, curve);
+    uECC_vli_modMult(u1, u1, z, curve->n, num_n_words); /* u1 = e/s */
+    uECC_vli_modMult(u2, r, z, curve->n, num_n_words); /* u2 = r/s */
+    /* Calculate sum = G + Q. */
+    uECC_vli_set(sum, _public, num_words);
+    uECC_vli_set(sum + num_words, _public + num_words, num_words);
+    uECC_vli_set(tx, curve->G, num_words);
+    uECC_vli_set(ty, curve->G + num_words, num_words);
+    uECC_vli_modSub(z, sum, tx, curve->p, num_words); /* z = x2 - x1 */
+    XYcZ_add(tx, ty, sum, sum + num_words, curve);
+    uECC_vli_modInv(z, z, curve->p, num_words); /* z = 1/z */
+    apply_z(sum, sum + num_words, z, curve);
+    /* Use Shamir's trick to calculate u1*G + u2*Q */
+    points[0] = 0;
+    points[1] = curve->G;
+    points[2] = _public;
+    points[3] = sum;
+    num_bits = smax(uECC_vli_numBits(u1, num_n_words),
+                    uECC_vli_numBits(u2, num_n_words));
+    point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) |
+                                                          ((!!uECC_vli_testBit(u2, num_bits - 1)) << 1)];
+    uECC_vli_set(rx, point, num_words);
+    uECC_vli_set(ry, point + num_words, num_words);
+    uECC_vli_clear(z, num_words);
+    z[0] = 1;
+
+    for(i = num_bits - 2; i >= 0; --i) {
+        uECC_word_t index;
+        curve->double_jacobian(rx, ry, z, curve);
+        index = (!!uECC_vli_testBit(u1, i)) | ((!!uECC_vli_testBit(u2, i)) << 1);
+        point = points[index];
+
+        if(point) {
+            uECC_vli_set(tx, point, num_words);
+            uECC_vli_set(ty, point + num_words, num_words);
+            apply_z(tx, ty, z, curve);
+            uECC_vli_modSub(tz, rx, tx, curve->p, num_words); /* Z = x2 - x1 */
+            XYcZ_add(tx, ty, rx, ry, curve);
+            uECC_vli_modMult_fast(z, z, tz, curve);
+        }
+    }
+
+    uECC_vli_modInv(z, z, curve->p, num_words); /* Z = 1/Z */
+    apply_z(rx, ry, z, curve);
+
+    /* v = x1 (mod n) */
+    if(uECC_vli_cmp_unsafe(curve->n, rx, num_n_words) != 1) {
+        uECC_vli_sub(rx, rx, curve->n, num_n_words);
+    }
+
+    /* Accept only if v == r. */
+    return (int)(uECC_vli_equal(rx, r, num_words) == 0);
 }
 

+ 28 - 23
src/bt/blehost/ext/tinycrypt/src/ecc_platform_specific.c

@@ -71,34 +71,39 @@
 #define O_CLOEXEC 0
 #endif
 
-int default_CSPRNG(uint8_t *dest, unsigned int size) {
+int default_CSPRNG(uint8_t *dest, unsigned int size)
+{
+    /* input sanity check: */
+    if(dest == (uint8_t *) 0 || (size <= 0))
+    { return 0; }
 
-  /* input sanity check: */
-  if (dest == (uint8_t *) 0 || (size <= 0))
-    return 0;
+    int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
 
-  int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
-  if (fd == -1) {
-    fd = open("/dev/random", O_RDONLY | O_CLOEXEC);
-    if (fd == -1) {
-      return 0;
+    if(fd == -1) {
+        fd = open("/dev/random", O_RDONLY | O_CLOEXEC);
+
+        if(fd == -1) {
+            return 0;
+        }
     }
-  }
-
-  char *ptr = (char *)dest;
-  size_t left = (size_t) size;
-  while (left > 0) {
-    ssize_t bytes_read = read(fd, ptr, left);
-    if (bytes_read <= 0) { // read failed
-      close(fd);
-      return 0;
+
+    char *ptr = (char *)dest;
+    size_t left = (size_t) size;
+
+    while(left > 0) {
+        ssize_t bytes_read = read(fd, ptr, left);
+
+        if(bytes_read <= 0) {  // read failed
+            close(fd);
+            return 0;
+        }
+
+        left -= bytes_read;
+        ptr += bytes_read;
     }
-    left -= bytes_read;
-    ptr += bytes_read;
-  }
 
-  close(fd);
-  return 1;
+    close(fd);
+    return 1;
 }
 
 #endif /* platform */

+ 84 - 92
src/bt/blehost/ext/tinycrypt/src/hmac.c

@@ -36,113 +36,105 @@
 
 static void rekey(uint8_t *key, const uint8_t *new_key, unsigned int key_size)
 {
-	const uint8_t inner_pad = (uint8_t) 0x36;
-	const uint8_t outer_pad = (uint8_t) 0x5c;
-	unsigned int i;
-
-	for (i = 0; i < key_size; ++i) {
-		key[i] = inner_pad ^ new_key[i];
-		key[i + TC_SHA256_BLOCK_SIZE] = outer_pad ^ new_key[i];
-	}
-	for (; i < TC_SHA256_BLOCK_SIZE; ++i) {
-		key[i] = inner_pad; key[i + TC_SHA256_BLOCK_SIZE] = outer_pad;
-	}
+    const uint8_t inner_pad = (uint8_t) 0x36;
+    const uint8_t outer_pad = (uint8_t) 0x5c;
+    unsigned int i;
+
+    for(i = 0; i < key_size; ++i) {
+        key[i] = inner_pad ^ new_key[i];
+        key[i + TC_SHA256_BLOCK_SIZE] = outer_pad ^ new_key[i];
+    }
+
+    for(; i < TC_SHA256_BLOCK_SIZE; ++i) {
+        key[i] = inner_pad;
+        key[i + TC_SHA256_BLOCK_SIZE] = outer_pad;
+    }
 }
 
 int tc_hmac_set_key(TCHmacState_t ctx, const uint8_t *key,
-		    unsigned int key_size)
+                    unsigned int key_size)
 {
-
-	/* input sanity check: */
-	if (ctx == (TCHmacState_t) 0 ||
-	    key == (const uint8_t *) 0 ||
-	    key_size == 0) {
-		return TC_CRYPTO_FAIL;
-	}
-
-	const uint8_t dummy_key[key_size];
-	struct tc_hmac_state_struct dummy_state;
-
-	if (key_size <= TC_SHA256_BLOCK_SIZE) {
-		/*
-		 * The next three lines consist of dummy calls just to avoid
-		 * certain timing attacks. Without these dummy calls,
-		 * adversaries would be able to learn whether the key_size is
-		 * greater than TC_SHA256_BLOCK_SIZE by measuring the time
-		 * consumed in this process.
-		 */
-		(void)tc_sha256_init(&dummy_state.hash_state);
-		(void)tc_sha256_update(&dummy_state.hash_state,
-				       dummy_key,
-				       key_size);
-		(void)tc_sha256_final(&dummy_state.key[TC_SHA256_DIGEST_SIZE],
-				      &dummy_state.hash_state);
-
-		/* Actual code for when key_size <= TC_SHA256_BLOCK_SIZE: */
-		rekey(ctx->key, key, key_size);
-	} else {
-		(void)tc_sha256_init(&ctx->hash_state);
-		(void)tc_sha256_update(&ctx->hash_state, key, key_size);
-		(void)tc_sha256_final(&ctx->key[TC_SHA256_DIGEST_SIZE],
-				      &ctx->hash_state);
-		rekey(ctx->key,
-		      &ctx->key[TC_SHA256_DIGEST_SIZE],
-		      TC_SHA256_DIGEST_SIZE);
-	}
-
-	return TC_CRYPTO_SUCCESS;
+    /* input sanity check: */
+    if(ctx == (TCHmacState_t) 0 ||
+            key == (const uint8_t *) 0 ||
+            key_size == 0) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    const uint8_t dummy_key[key_size];
+    struct tc_hmac_state_struct dummy_state;
+
+    if(key_size <= TC_SHA256_BLOCK_SIZE) {
+        /*
+         * The next three lines consist of dummy calls just to avoid
+         * certain timing attacks. Without these dummy calls,
+         * adversaries would be able to learn whether the key_size is
+         * greater than TC_SHA256_BLOCK_SIZE by measuring the time
+         * consumed in this process.
+         */
+        (void)tc_sha256_init(&dummy_state.hash_state);
+        (void)tc_sha256_update(&dummy_state.hash_state,
+                               dummy_key,
+                               key_size);
+        (void)tc_sha256_final(&dummy_state.key[TC_SHA256_DIGEST_SIZE],
+                              &dummy_state.hash_state);
+        /* Actual code for when key_size <= TC_SHA256_BLOCK_SIZE: */
+        rekey(ctx->key, key, key_size);
+    } else {
+        (void)tc_sha256_init(&ctx->hash_state);
+        (void)tc_sha256_update(&ctx->hash_state, key, key_size);
+        (void)tc_sha256_final(&ctx->key[TC_SHA256_DIGEST_SIZE],
+                              &ctx->hash_state);
+        rekey(ctx->key,
+              &ctx->key[TC_SHA256_DIGEST_SIZE],
+              TC_SHA256_DIGEST_SIZE);
+    }
+
+    return TC_CRYPTO_SUCCESS;
 }
 
 int tc_hmac_init(TCHmacState_t ctx)
 {
-
-	/* input sanity check: */
-	if (ctx == (TCHmacState_t) 0) {
-		return TC_CRYPTO_FAIL;
-	}
-
-  (void) tc_sha256_init(&ctx->hash_state);
-  (void) tc_sha256_update(&ctx->hash_state, ctx->key, TC_SHA256_BLOCK_SIZE);
-
-	return TC_CRYPTO_SUCCESS;
+    /* input sanity check: */
+    if(ctx == (TCHmacState_t) 0) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    (void) tc_sha256_init(&ctx->hash_state);
+    (void) tc_sha256_update(&ctx->hash_state, ctx->key, TC_SHA256_BLOCK_SIZE);
+    return TC_CRYPTO_SUCCESS;
 }
 
 int tc_hmac_update(TCHmacState_t ctx,
-		   const void *data,
-		   unsigned int data_length)
+                   const void *data,
+                   unsigned int data_length)
 {
+    /* input sanity check: */
+    if(ctx == (TCHmacState_t) 0) {
+        return TC_CRYPTO_FAIL;
+    }
 
-	/* input sanity check: */
-	if (ctx == (TCHmacState_t) 0) {
-		return TC_CRYPTO_FAIL;
-	}
-
-	(void)tc_sha256_update(&ctx->hash_state, data, data_length);
-
-	return TC_CRYPTO_SUCCESS;
+    (void)tc_sha256_update(&ctx->hash_state, data, data_length);
+    return TC_CRYPTO_SUCCESS;
 }
 
 int tc_hmac_final(uint8_t *tag, unsigned int taglen, TCHmacState_t ctx)
 {
-
-	/* input sanity check: */
-	if (tag == (uint8_t *) 0 ||
-	    taglen != TC_SHA256_DIGEST_SIZE ||
-	    ctx == (TCHmacState_t) 0) {
-		return TC_CRYPTO_FAIL;
-	}
-
-	(void) tc_sha256_final(tag, &ctx->hash_state);
-
-	(void)tc_sha256_init(&ctx->hash_state);
-	(void)tc_sha256_update(&ctx->hash_state,
-			       &ctx->key[TC_SHA256_BLOCK_SIZE],
-				TC_SHA256_BLOCK_SIZE);
-	(void)tc_sha256_update(&ctx->hash_state, tag, TC_SHA256_DIGEST_SIZE);
-	(void)tc_sha256_final(tag, &ctx->hash_state);
-
-	/* destroy the current state */
-	_set(ctx, 0, sizeof(*ctx));
-
-	return TC_CRYPTO_SUCCESS;
+    /* input sanity check: */
+    if(tag == (uint8_t *) 0 ||
+            taglen != TC_SHA256_DIGEST_SIZE ||
+            ctx == (TCHmacState_t) 0) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    (void) tc_sha256_final(tag, &ctx->hash_state);
+    (void)tc_sha256_init(&ctx->hash_state);
+    (void)tc_sha256_update(&ctx->hash_state,
+                           &ctx->key[TC_SHA256_BLOCK_SIZE],
+                           TC_SHA256_BLOCK_SIZE);
+    (void)tc_sha256_update(&ctx->hash_state, tag, TC_SHA256_DIGEST_SIZE);
+    (void)tc_sha256_final(tag, &ctx->hash_state);
+    /* destroy the current state */
+    _set(ctx, 0, sizeof(*ctx));
+    return TC_CRYPTO_SUCCESS;
 }

+ 107 - 120
src/bt/blehost/ext/tinycrypt/src/hmac_prng.c

@@ -77,136 +77,123 @@ static const unsigned int  MAX_OUT = (1 << 19);
  */
 static void update(TCHmacPrng_t prng, const uint8_t *e, unsigned int len)
 {
-	const uint8_t separator0 = 0x00;
-	const uint8_t separator1 = 0x01;
-
-	/* use current state, e and separator 0 to compute a new prng key: */
-	(void)tc_hmac_init(&prng->h);
-	(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
-	(void)tc_hmac_update(&prng->h, &separator0, sizeof(separator0));
-	(void)tc_hmac_update(&prng->h, e, len);
-	(void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h);
-	/* configure the new prng key into the prng's instance of hmac */
-	(void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
-
-	/* use the new key to compute a new state variable v */
-	(void)tc_hmac_init(&prng->h);
-	(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
-	(void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h);
-
-	/* use current state, e and separator 1 to compute a new prng key: */
-	(void)tc_hmac_init(&prng->h);
-	(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
-	(void)tc_hmac_update(&prng->h, &separator1, sizeof(separator1));
-	(void)tc_hmac_update(&prng->h, e, len);
-	(void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h);
-	/* configure the new prng key into the prng's instance of hmac */
-	(void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
-
-	/* use the new key to compute a new state variable v */
-	(void)tc_hmac_init(&prng->h);
-	(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
-	(void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h);
+    const uint8_t separator0 = 0x00;
+    const uint8_t separator1 = 0x01;
+    /* use current state, e and separator 0 to compute a new prng key: */
+    (void)tc_hmac_init(&prng->h);
+    (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
+    (void)tc_hmac_update(&prng->h, &separator0, sizeof(separator0));
+    (void)tc_hmac_update(&prng->h, e, len);
+    (void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h);
+    /* configure the new prng key into the prng's instance of hmac */
+    (void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
+    /* use the new key to compute a new state variable v */
+    (void)tc_hmac_init(&prng->h);
+    (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
+    (void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h);
+    /* use current state, e and separator 1 to compute a new prng key: */
+    (void)tc_hmac_init(&prng->h);
+    (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
+    (void)tc_hmac_update(&prng->h, &separator1, sizeof(separator1));
+    (void)tc_hmac_update(&prng->h, e, len);
+    (void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h);
+    /* configure the new prng key into the prng's instance of hmac */
+    (void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
+    /* use the new key to compute a new state variable v */
+    (void)tc_hmac_init(&prng->h);
+    (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
+    (void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h);
 }
 
 int tc_hmac_prng_init(TCHmacPrng_t prng,
-		      const uint8_t *personalization,
-		      unsigned int plen)
+                      const uint8_t *personalization,
+                      unsigned int plen)
 {
-
-	/* input sanity check: */
-	if (prng == (TCHmacPrng_t) 0 ||
-	    personalization == (uint8_t *) 0 ||
-	    plen > MAX_PLEN) {
-		return TC_CRYPTO_FAIL;
-	}
-
-	/* put the generator into a known state: */
-	_set(prng->key, 0x00, sizeof(prng->key));
-	_set(prng->v, 0x01, sizeof(prng->v));
-	tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
-	/* update assumes SOME key has been configured into HMAC */
-
-	update(prng, personalization, plen);
-
-	/* force a reseed before allowing tc_hmac_prng_generate to succeed: */
-	prng->countdown = 0;
-
-	return TC_CRYPTO_SUCCESS;
+    /* input sanity check: */
+    if(prng == (TCHmacPrng_t) 0 ||
+            personalization == (uint8_t *) 0 ||
+            plen > MAX_PLEN) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    /* put the generator into a known state: */
+    _set(prng->key, 0x00, sizeof(prng->key));
+    _set(prng->v, 0x01, sizeof(prng->v));
+    tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
+    /* update assumes SOME key has been configured into HMAC */
+    update(prng, personalization, plen);
+    /* force a reseed before allowing tc_hmac_prng_generate to succeed: */
+    prng->countdown = 0;
+    return TC_CRYPTO_SUCCESS;
 }
 
 int tc_hmac_prng_reseed(TCHmacPrng_t prng,
-			const uint8_t *seed,
-			unsigned int seedlen,
-			const uint8_t *additional_input,
-			unsigned int additionallen)
+                        const uint8_t *seed,
+                        unsigned int seedlen,
+                        const uint8_t *additional_input,
+                        unsigned int additionallen)
 {
-
-	/* input sanity check: */
-	if (prng == (TCHmacPrng_t) 0 ||
-	    seed == (const uint8_t *) 0 ||
-	    seedlen < MIN_SLEN ||
-	    seedlen > MAX_SLEN) {
-		return TC_CRYPTO_FAIL;
-	}
-
-	if (additional_input != (const uint8_t *) 0) {
-		/*
-		 * Abort if additional_input is provided but has inappropriate
-		 * length
-		 */
-		if (additionallen == 0 ||
-		    additionallen > MAX_ALEN) {
-			return TC_CRYPTO_FAIL;
-		} else {
-		/* call update for the seed and additional_input */
-		update(prng, seed, seedlen);
-		update(prng, additional_input, additionallen);
-		}
-	} else {
-		/* call update only for the seed */
-		update(prng, seed, seedlen);
-	}
-
-	/* ... and enable hmac_prng_generate */
-	prng->countdown = MAX_GENS;
-
-	return TC_CRYPTO_SUCCESS;
+    /* input sanity check: */
+    if(prng == (TCHmacPrng_t) 0 ||
+            seed == (const uint8_t *) 0 ||
+            seedlen < MIN_SLEN ||
+            seedlen > MAX_SLEN) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    if(additional_input != (const uint8_t *) 0) {
+        /*
+         * Abort if additional_input is provided but has inappropriate
+         * length
+         */
+        if(additionallen == 0 ||
+                additionallen > MAX_ALEN) {
+            return TC_CRYPTO_FAIL;
+        } else {
+            /* call update for the seed and additional_input */
+            update(prng, seed, seedlen);
+            update(prng, additional_input, additionallen);
+        }
+    } else {
+        /* call update only for the seed */
+        update(prng, seed, seedlen);
+    }
+
+    /* ... and enable hmac_prng_generate */
+    prng->countdown = MAX_GENS;
+    return TC_CRYPTO_SUCCESS;
 }
 
 int tc_hmac_prng_generate(uint8_t *out, unsigned int outlen, TCHmacPrng_t prng)
 {
-	unsigned int bufferlen;
-
-	/* input sanity check: */
-	if (out == (uint8_t *) 0 ||
-	    prng == (TCHmacPrng_t) 0 ||
-	    outlen == 0 ||
-	    outlen > MAX_OUT) {
-		return TC_CRYPTO_FAIL;
-	} else if (prng->countdown == 0) {
-		return TC_HMAC_PRNG_RESEED_REQ;
-	}
-
-	prng->countdown--;
-
-	while (outlen != 0) {
-		/* operate HMAC in OFB mode to create "random" outputs */
-		(void)tc_hmac_init(&prng->h);
-		(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
-		(void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h);
-
-		bufferlen = (TC_SHA256_DIGEST_SIZE > outlen) ?
-			outlen : TC_SHA256_DIGEST_SIZE;
-		(void)_copy(out, bufferlen, prng->v, bufferlen);
-
-		out += bufferlen;
-		outlen = (outlen > TC_SHA256_DIGEST_SIZE) ?
-			(outlen - TC_SHA256_DIGEST_SIZE) : 0;
-	}
-
-	/* block future PRNG compromises from revealing past state */
-	update(prng, prng->v, TC_SHA256_DIGEST_SIZE);
-
-	return TC_CRYPTO_SUCCESS;
+    unsigned int bufferlen;
+
+    /* input sanity check: */
+    if(out == (uint8_t *) 0 ||
+            prng == (TCHmacPrng_t) 0 ||
+            outlen == 0 ||
+            outlen > MAX_OUT) {
+        return TC_CRYPTO_FAIL;
+    } else if(prng->countdown == 0) {
+        return TC_HMAC_PRNG_RESEED_REQ;
+    }
+
+    prng->countdown--;
+
+    while(outlen != 0) {
+        /* operate HMAC in OFB mode to create "random" outputs */
+        (void)tc_hmac_init(&prng->h);
+        (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
+        (void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h);
+        bufferlen = (TC_SHA256_DIGEST_SIZE > outlen) ?
+                    outlen : TC_SHA256_DIGEST_SIZE;
+        (void)_copy(out, bufferlen, prng->v, bufferlen);
+        out += bufferlen;
+        outlen = (outlen > TC_SHA256_DIGEST_SIZE) ?
+                 (outlen - TC_SHA256_DIGEST_SIZE) : 0;
+    }
+
+    /* block future PRNG compromises from revealing past state */
+    update(prng, prng->v, TC_SHA256_DIGEST_SIZE);
+    return TC_CRYPTO_SUCCESS;
 }

+ 159 - 140
src/bt/blehost/ext/tinycrypt/src/sha256.c

@@ -38,101 +38,99 @@ static void compress(unsigned int *iv, const uint8_t *data);
 
 int tc_sha256_init(TCSha256State_t s)
 {
-	/* input sanity check: */
-	if (s == (TCSha256State_t) 0) {
-		return TC_CRYPTO_FAIL;
-	}
-
-	/*
-	 * Setting the initial state values.
-	 * These values correspond to the first 32 bits of the fractional parts
-	 * of the square roots of the first 8 primes: 2, 3, 5, 7, 11, 13, 17
-	 * and 19.
-	 */
-	_set((uint8_t *) s, 0x00, sizeof(*s));
-	s->iv[0] = 0x6a09e667;
-	s->iv[1] = 0xbb67ae85;
-	s->iv[2] = 0x3c6ef372;
-	s->iv[3] = 0xa54ff53a;
-	s->iv[4] = 0x510e527f;
-	s->iv[5] = 0x9b05688c;
-	s->iv[6] = 0x1f83d9ab;
-	s->iv[7] = 0x5be0cd19;
-
-	return TC_CRYPTO_SUCCESS;
+    /* input sanity check: */
+    if(s == (TCSha256State_t) 0) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    /*
+     * Setting the initial state values.
+     * These values correspond to the first 32 bits of the fractional parts
+     * of the square roots of the first 8 primes: 2, 3, 5, 7, 11, 13, 17
+     * and 19.
+     */
+    _set((uint8_t *) s, 0x00, sizeof(*s));
+    s->iv[0] = 0x6a09e667;
+    s->iv[1] = 0xbb67ae85;
+    s->iv[2] = 0x3c6ef372;
+    s->iv[3] = 0xa54ff53a;
+    s->iv[4] = 0x510e527f;
+    s->iv[5] = 0x9b05688c;
+    s->iv[6] = 0x1f83d9ab;
+    s->iv[7] = 0x5be0cd19;
+    return TC_CRYPTO_SUCCESS;
 }
 
 int tc_sha256_update(TCSha256State_t s, const uint8_t *data, size_t datalen)
 {
-	/* input sanity check: */
-	if (s == (TCSha256State_t) 0 ||
-	    data == (void *) 0) {
-		return TC_CRYPTO_FAIL;
-	} else if (datalen == 0) {
-		return TC_CRYPTO_SUCCESS;
-	}
-
-	while (datalen-- > 0) {
-		s->leftover[s->leftover_offset++] = *(data++);
-		if (s->leftover_offset >= TC_SHA256_BLOCK_SIZE) {
-			compress(s->iv, s->leftover);
-			s->leftover_offset = 0;
-			s->bits_hashed += (TC_SHA256_BLOCK_SIZE << 3);
-		}
-	}
-
-	return TC_CRYPTO_SUCCESS;
+    /* input sanity check: */
+    if(s == (TCSha256State_t) 0 ||
+            data == (void *) 0) {
+        return TC_CRYPTO_FAIL;
+    } else if(datalen == 0) {
+        return TC_CRYPTO_SUCCESS;
+    }
+
+    while(datalen-- > 0) {
+        s->leftover[s->leftover_offset++] = *(data++);
+
+        if(s->leftover_offset >= TC_SHA256_BLOCK_SIZE) {
+            compress(s->iv, s->leftover);
+            s->leftover_offset = 0;
+            s->bits_hashed += (TC_SHA256_BLOCK_SIZE << 3);
+        }
+    }
+
+    return TC_CRYPTO_SUCCESS;
 }
 
 int tc_sha256_final(uint8_t *digest, TCSha256State_t s)
 {
-	unsigned int i;
-
-	/* input sanity check: */
-	if (digest == (uint8_t *) 0 ||
-	    s == (TCSha256State_t) 0) {
-		return TC_CRYPTO_FAIL;
-	}
-
-	s->bits_hashed += (s->leftover_offset << 3);
-
-	s->leftover[s->leftover_offset++] = 0x80; /* always room for one byte */
-	if (s->leftover_offset > (sizeof(s->leftover) - 8)) {
-		/* there is not room for all the padding in this block */
-		_set(s->leftover + s->leftover_offset, 0x00,
-		     sizeof(s->leftover) - s->leftover_offset);
-		compress(s->iv, s->leftover);
-		s->leftover_offset = 0;
-	}
-
-	/* add the padding and the length in big-Endian format */
-	_set(s->leftover + s->leftover_offset, 0x00,
-	     sizeof(s->leftover) - 8 - s->leftover_offset);
-	s->leftover[sizeof(s->leftover) - 1] = (uint8_t)(s->bits_hashed);
-	s->leftover[sizeof(s->leftover) - 2] = (uint8_t)(s->bits_hashed >> 8);
-	s->leftover[sizeof(s->leftover) - 3] = (uint8_t)(s->bits_hashed >> 16);
-	s->leftover[sizeof(s->leftover) - 4] = (uint8_t)(s->bits_hashed >> 24);
-	s->leftover[sizeof(s->leftover) - 5] = (uint8_t)(s->bits_hashed >> 32);
-	s->leftover[sizeof(s->leftover) - 6] = (uint8_t)(s->bits_hashed >> 40);
-	s->leftover[sizeof(s->leftover) - 7] = (uint8_t)(s->bits_hashed >> 48);
-	s->leftover[sizeof(s->leftover) - 8] = (uint8_t)(s->bits_hashed >> 56);
-
-	/* hash the padding and length */
-	compress(s->iv, s->leftover);
-
-	/* copy the iv out to digest */
-	for (i = 0; i < TC_SHA256_STATE_BLOCKS; ++i) {
-		unsigned int t = *((unsigned int *) &s->iv[i]);
-		*digest++ = (uint8_t)(t >> 24);
-		*digest++ = (uint8_t)(t >> 16);
-		*digest++ = (uint8_t)(t >> 8);
-		*digest++ = (uint8_t)(t);
-	}
-
-	/* destroy the current state */
-	_set(s, 0, sizeof(*s));
-
-	return TC_CRYPTO_SUCCESS;
+    unsigned int i;
+
+    /* input sanity check: */
+    if(digest == (uint8_t *) 0 ||
+            s == (TCSha256State_t) 0) {
+        return TC_CRYPTO_FAIL;
+    }
+
+    s->bits_hashed += (s->leftover_offset << 3);
+    s->leftover[s->leftover_offset++] = 0x80; /* always room for one byte */
+
+    if(s->leftover_offset > (sizeof(s->leftover) - 8)) {
+        /* there is not room for all the padding in this block */
+        _set(s->leftover + s->leftover_offset, 0x00,
+             sizeof(s->leftover) - s->leftover_offset);
+        compress(s->iv, s->leftover);
+        s->leftover_offset = 0;
+    }
+
+    /* add the padding and the length in big-Endian format */
+    _set(s->leftover + s->leftover_offset, 0x00,
+         sizeof(s->leftover) - 8 - s->leftover_offset);
+    s->leftover[sizeof(s->leftover) - 1] = (uint8_t)(s->bits_hashed);
+    s->leftover[sizeof(s->leftover) - 2] = (uint8_t)(s->bits_hashed >> 8);
+    s->leftover[sizeof(s->leftover) - 3] = (uint8_t)(s->bits_hashed >> 16);
+    s->leftover[sizeof(s->leftover) - 4] = (uint8_t)(s->bits_hashed >> 24);
+    s->leftover[sizeof(s->leftover) - 5] = (uint8_t)(s->bits_hashed >> 32);
+    s->leftover[sizeof(s->leftover) - 6] = (uint8_t)(s->bits_hashed >> 40);
+    s->leftover[sizeof(s->leftover) - 7] = (uint8_t)(s->bits_hashed >> 48);
+    s->leftover[sizeof(s->leftover) - 8] = (uint8_t)(s->bits_hashed >> 56);
+    /* hash the padding and length */
+    compress(s->iv, s->leftover);
+
+    /* copy the iv out to digest */
+    for(i = 0; i < TC_SHA256_STATE_BLOCKS; ++i) {
+        unsigned int t = *((unsigned int *) &s->iv[i]);
+        *digest++ = (uint8_t)(t >> 24);
+        *digest++ = (uint8_t)(t >> 16);
+        *digest++ = (uint8_t)(t >> 8);
+        *digest++ = (uint8_t)(t);
+    }
+
+    /* destroy the current state */
+    _set(s, 0, sizeof(*s));
+    return TC_CRYPTO_SUCCESS;
 }
 
 /*
@@ -141,22 +139,22 @@ int tc_sha256_final(uint8_t *digest, TCSha256State_t s)
  * cube roots of the first 64 primes between 2 and 311.
  */
 static const unsigned int k256[64] = {
-	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
-	0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
-	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
-	0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
-	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
-	0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
-	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
-	0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
-	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
-	0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
-	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
+    0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
+    0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
+    0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
+    0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
+    0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
 };
 
 static inline unsigned int ROTR(unsigned int a, unsigned int n)
 {
-	return (((a) >> n) | ((a) << (32 - n)));
+    return (((a) >> n) | ((a) << (32 - n)));
 }
 
 #define Sigma0(a)(ROTR((a), 2) ^ ROTR((a), 13) ^ ROTR((a), 22))
@@ -169,49 +167,70 @@ static inline unsigned int ROTR(unsigned int a, unsigned int n)
 
 static inline unsigned int BigEndian(const uint8_t **c)
 {
-	unsigned int n = 0;
-
-	n = (((unsigned int)(*((*c)++))) << 24);
-	n |= ((unsigned int)(*((*c)++)) << 16);
-	n |= ((unsigned int)(*((*c)++)) << 8);
-	n |= ((unsigned int)(*((*c)++)));
-	return n;
+    unsigned int n = 0;
+    n = (((unsigned int)(*((*c)++))) << 24);
+    n |= ((unsigned int)(*((*c)++)) << 16);
+    n |= ((unsigned int)(*((*c)++)) << 8);
+    n |= ((unsigned int)(*((*c)++)));
+    return n;
 }
 
 static void compress(unsigned int *iv, const uint8_t *data)
 {
-	unsigned int a, b, c, d, e, f, g, h;
-	unsigned int s0, s1;
-	unsigned int t1, t2;
-	unsigned int work_space[16];
-	unsigned int n;
-	unsigned int i;
-
-	a = iv[0]; b = iv[1]; c = iv[2]; d = iv[3];
-	e = iv[4]; f = iv[5]; g = iv[6]; h = iv[7];
-
-	for (i = 0; i < 16; ++i) {
-		n = BigEndian(&data);
-		t1 = work_space[i] = n;
-		t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i];
-		t2 = Sigma0(a) + Maj(a, b, c);
-		h = g; g = f; f = e; e = d + t1;
-		d = c; c = b; b = a; a = t1 + t2;
-	}
-
-	for ( ; i < 64; ++i) {
-		s0 = work_space[(i+1)&0x0f];
-		s0 = sigma0(s0);
-		s1 = work_space[(i+14)&0x0f];
-		s1 = sigma1(s1);
-
-		t1 = work_space[i&0xf] += s0 + s1 + work_space[(i+9)&0xf];
-		t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i];
-		t2 = Sigma0(a) + Maj(a, b, c);
-		h = g; g = f; f = e; e = d + t1;
-		d = c; c = b; b = a; a = t1 + t2;
-	}
-
-	iv[0] += a; iv[1] += b; iv[2] += c; iv[3] += d;
-	iv[4] += e; iv[5] += f; iv[6] += g; iv[7] += h;
+    unsigned int a, b, c, d, e, f, g, h;
+    unsigned int s0, s1;
+    unsigned int t1, t2;
+    unsigned int work_space[16];
+    unsigned int n;
+    unsigned int i;
+    a = iv[0];
+    b = iv[1];
+    c = iv[2];
+    d = iv[3];
+    e = iv[4];
+    f = iv[5];
+    g = iv[6];
+    h = iv[7];
+
+    for(i = 0; i < 16; ++i) {
+        n = BigEndian(&data);
+        t1 = work_space[i] = n;
+        t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i];
+        t2 = Sigma0(a) + Maj(a, b, c);
+        h = g;
+        g = f;
+        f = e;
+        e = d + t1;
+        d = c;
+        c = b;
+        b = a;
+        a = t1 + t2;
+    }
+
+    for(; i < 64; ++i) {
+        s0 = work_space[(i + 1) & 0x0f];
+        s0 = sigma0(s0);
+        s1 = work_space[(i + 14) & 0x0f];
+        s1 = sigma1(s1);
+        t1 = work_space[i & 0xf] += s0 + s1 + work_space[(i + 9) & 0xf];
+        t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i];
+        t2 = Sigma0(a) + Maj(a, b, c);
+        h = g;
+        g = f;
+        f = e;
+        e = d + t1;
+        d = c;
+        c = b;
+        b = a;
+        a = t1 + t2;
+    }
+
+    iv[0] += a;
+    iv[1] += b;
+    iv[2] += c;
+    iv[3] += d;
+    iv[4] += e;
+    iv[5] += f;
+    iv[6] += g;
+    iv[7] += h;
 }

+ 34 - 33
src/bt/blehost/nimble/host/include/host/ble_gap.h

@@ -129,6 +129,7 @@ struct hci_conn_update;
 #define BLE_GAP_EVENT_PERIODIC_SYNC_LOST    22
 #define BLE_GAP_EVENT_SCAN_REQ_RCVD         23
 #define BLE_GAP_EVENT_PERIODIC_TRANSFER     24
+#define BLE_GAP_EVENT_HOST_SHUTDOWN         31
 
 /*** Reason codes for the subscribe GAP event. */
 
@@ -150,16 +151,16 @@ struct hci_conn_update;
 /** Connection security state */
 struct ble_gap_sec_state {
     /** If connection is encrypted */
-    unsigned encrypted:1;
+    unsigned encrypted: 1;
 
     /** If connection is authenticated */
-    unsigned authenticated:1;
+    unsigned authenticated: 1;
 
     /** If connection is bonded (security information is stored)  */
-    unsigned bonded:1;
+    unsigned bonded: 1;
 
     /** Size of a key used for encryption */
-    unsigned key_size:5;
+    unsigned key_size: 5;
 };
 
 /** Advertising parameters */
@@ -188,7 +189,7 @@ struct ble_gap_adv_params {
     uint8_t filter_policy;
 
     /** If do High Duty cycle for Directed Advertising */
-    uint8_t high_duty_cycle:1;
+    uint8_t high_duty_cycle: 1;
 };
 
 /** @brief Connection descriptor */
@@ -265,7 +266,7 @@ struct ble_gap_ext_disc_params {
     uint16_t window;
 
     /** If passive scan should be used */
-    uint8_t passive:1;
+    uint8_t passive: 1;
 };
 
 /** @brief Discovery parameters */
@@ -280,13 +281,13 @@ struct ble_gap_disc_params {
     uint8_t filter_policy;
 
     /** If limited discovery procedure should be used */
-    uint8_t limited:1;
+    uint8_t limited: 1;
 
     /** If passive scan should be used */
-    uint8_t passive:1;
+    uint8_t passive: 1;
 
     /** If enable duplicates filtering */
-    uint8_t filter_duplicates:1;
+    uint8_t filter_duplicates: 1;
 };
 
 /** @brief Connection parameters update parameters */
@@ -435,17 +436,17 @@ struct ble_gap_repeat_pairing {
 
     /** Properties of the existing bond. */
     uint8_t cur_key_size;
-    uint8_t cur_authenticated:1;
-    uint8_t cur_sc:1;
+    uint8_t cur_authenticated: 1;
+    uint8_t cur_sc: 1;
 
     /**
      * Properties of the imminent secure link if the pairing procedure is
      * allowed to continue.
      */
     uint8_t new_key_size;
-    uint8_t new_authenticated:1;
-    uint8_t new_sc:1;
-    uint8_t new_bonding:1;
+    uint8_t new_authenticated: 1;
+    uint8_t new_sc: 1;
+    uint8_t new_bonding: 1;
 };
 
 /**
@@ -693,7 +694,7 @@ struct ble_gap_event {
              *     o 0: Notification;
              *     o 1: Indication.
              */
-            uint8_t indication:1;
+            uint8_t indication: 1;
         } notify_rx;
 
         /**
@@ -726,7 +727,7 @@ struct ble_gap_event {
              *     o 0: Notification;
              *     o 1: Indication.
              */
-            uint8_t indication:1;
+            uint8_t indication: 1;
         } notify_tx;
 
         /**
@@ -754,16 +755,16 @@ struct ble_gap_event {
             uint8_t reason;
 
             /** Whether the peer was previously subscribed to notifications. */
-            uint8_t prev_notify:1;
+            uint8_t prev_notify: 1;
 
             /** Whether the peer is currently subscribed to notifications. */
-            uint8_t cur_notify:1;
+            uint8_t cur_notify: 1;
 
             /** Whether the peer was previously subscribed to indications. */
-            uint8_t prev_indicate:1;
+            uint8_t prev_indicate: 1;
 
             /** Whether the peer is currently subscribed to indications. */
-            uint8_t cur_indicate:1;
+            uint8_t cur_indicate: 1;
         } subscribe;
 
         /**
@@ -1143,28 +1144,28 @@ int ble_gap_adv_rsp_set_fields(const struct ble_hs_adv_fields *rsp_fields);
 /** @brief Extended advertising parameters  */
 struct ble_gap_ext_adv_params {
     /** If perform connectable advertising */
-    unsigned int connectable:1;
+    unsigned int connectable: 1;
 
     /** If perform scannable advertising */
-    unsigned int scannable:1;
+    unsigned int scannable: 1;
 
     /** If perform directed advertising */
-    unsigned int directed:1;
+    unsigned int directed: 1;
 
     /** If perform high-duty directed advertising */
-    unsigned int high_duty_directed:1;
+    unsigned int high_duty_directed: 1;
 
     /** If use legacy PDUs for advertising */
-    unsigned int legacy_pdu:1;
+    unsigned int legacy_pdu: 1;
 
     /** If perform anonymous advertising */
-    unsigned int anonymous:1;
+    unsigned int anonymous: 1;
 
     /** If include TX power in advertising PDU */
-    unsigned int include_tx_power:1;
+    unsigned int include_tx_power: 1;
 
     /** If enable scan request notification  */
-    unsigned int scan_req_notif:1;
+    unsigned int scan_req_notif: 1;
 
     /** Minimum advertising interval in 0.625ms units, if 0 stack use sane
      *  defaults
@@ -1316,7 +1317,7 @@ int ble_gap_ext_adv_clear(void);
 /** @brief Periodic advertising parameters  */
 struct ble_gap_periodic_adv_params {
     /** If include TX power in advertising PDU */
-    unsigned int include_tx_power:1;
+    unsigned int include_tx_power: 1;
 
     /** Minimum advertising interval in 0.625ms units, if 0 stack use sane
      *  defaults
@@ -1341,7 +1342,7 @@ struct ble_gap_periodic_sync_params {
     uint16_t sync_timeout;
 
     /** If reports should be initially disabled when sync is created */
-    unsigned int reports_disabled:1;
+    unsigned int reports_disabled: 1;
 };
 
 /**
@@ -1500,7 +1501,7 @@ int ble_gap_periodic_adv_sync_receive(uint16_t conn_handle,
  * @return                   0 on success; nonzero on failure.
  */
 int ble_gap_add_dev_to_periodic_adv_list(const ble_addr_t *peer_addr,
-                                         uint8_t adv_sid);
+        uint8_t adv_sid);
 
 /**
  * Remove peer device from periodic synchronization list.
@@ -1511,7 +1512,7 @@ int ble_gap_add_dev_to_periodic_adv_list(const ble_addr_t *peer_addr,
  * @return                   0 on success; nonzero on failure.
  */
 int ble_gap_rem_dev_from_periodic_adv_list(const ble_addr_t *peer_addr,
-                                           uint8_t adv_sid);
+        uint8_t adv_sid);
 
 /**
  * Clear periodic synchrnization list.
@@ -2034,7 +2035,7 @@ int ble_gap_event_listener_unregister(struct ble_gap_event_listener *listener);
  * @conn_params address of connection parameters
  *
  * @return              void
- *                      
+ *
  */
 
 void

+ 2 - 2
src/bt/blehost/nimble/host/include/host/ble_gatt.h

@@ -250,8 +250,8 @@ int ble_gattc_disc_all_chrs(uint16_t conn_handle, uint16_t start_handle,
  * @return                      0 on success; nonzero on failure.
  */
 int ble_gattc_disc_chrs_by_uuid(uint16_t conn_handle, uint16_t start_handle,
-                               uint16_t end_handle, const ble_uuid_t *uuid,
-                               ble_gatt_chr_fn *cb, void *cb_arg);
+                                uint16_t end_handle, const ble_uuid_t *uuid,
+                                ble_gatt_chr_fn *cb, void *cb_arg);
 
 /**
  * Initiates GATT procedure: Discover All Characteristic Descriptors.

+ 12 - 6
src/bt/blehost/nimble/host/include/host/ble_hs.h

@@ -44,6 +44,10 @@
 #include "host/ble_store.h"
 #include "host/ble_uuid.h"
 #include "nimble/nimble_npl.h"
+#include "nimble/nimble_port.h"
+#include "nimble/tls_nimble.h"
+#include "transport/uart/ble_hci_uart.h"
+
 #include "wm_mem.h"
 
 #ifdef __cplusplus
@@ -214,21 +218,21 @@ struct ble_hs_cfg {
      *
      * If set proper flag in Pairing Request/Response will be set.
      */
-    unsigned sm_oob_data_flag:1;
+    unsigned sm_oob_data_flag: 1;
 
     /** @brief Security Manager Bond flag
      *
      * If set proper flag in Pairing Request/Response will be set. This results
      * in storing keys distributed during bonding.
      */
-    unsigned sm_bonding:1;
+    unsigned sm_bonding: 1;
 
     /** @brief Security Manager MITM flag
      *
      * If set proper flag in Pairing Request/Response will be set. This results
      * in requiring Man-In-The-Middle protection when pairing.
      */
-    unsigned sm_mitm:1;
+    unsigned sm_mitm: 1;
 
     /** @brief Security Manager Secure Connections flag
      *
@@ -236,13 +240,13 @@ struct ble_hs_cfg {
      * in using LE Secure Connections for pairing if also supported by remote
      * device. Fallback to legacy pairing if not supported by remote.
      */
-    unsigned sm_sc:1;
+    unsigned sm_sc: 1;
 
     /** @brief Security Manager Key Press Notification flag
      *
      * Currently unsupported and should not be set.
      */
-    unsigned sm_keypress:1;
+    unsigned sm_keypress: 1;
 
     /** @brief Security Manager Local Key Distribution Mask */
     uint8_t sm_our_key_dist;
@@ -283,6 +287,8 @@ struct ble_hs_cfg {
     /** Storage Delete callback handles deletion of security material */
     ble_store_delete_fn *store_delete_cb;
 
+    ble_store_flush_fn *store_flush_cb;
+
     /** @brief Storage Status callback.
      *
      * This callback gets executed when a persistence operation cannot be
@@ -387,7 +393,7 @@ void ble_hs_deinit(void);
  *                                  HAL_RESET_[...] codes or an
  *                                  implementation-defined value.
  *
- * @return                      SYSDOWN_IN_PROGRESS. 
+ * @return                      SYSDOWN_IN_PROGRESS.
  */
 int ble_hs_shutdown(int reason);
 

+ 9 - 9
src/bt/blehost/nimble/host/include/host/ble_hs_adv.h

@@ -38,8 +38,8 @@ struct ble_hs_adv_field {
     uint8_t value[0];
 };
 
-typedef int (* ble_hs_adv_parse_func_t) (const struct ble_hs_adv_field *,
-                                         void *);
+typedef int (* ble_hs_adv_parse_func_t)(const struct ble_hs_adv_field *,
+                                        void *);
 
 struct ble_hs_adv_fields {
     /*** 0x01 - Flags. */
@@ -48,26 +48,26 @@ struct ble_hs_adv_fields {
     /*** 0x02,0x03 - 16-bit service class UUIDs. */
     const ble_uuid16_t *uuids16;
     uint8_t num_uuids16;
-    unsigned uuids16_is_complete:1;
+    unsigned uuids16_is_complete: 1;
 
     /*** 0x04,0x05 - 32-bit service class UUIDs. */
     const ble_uuid32_t *uuids32;
     uint8_t num_uuids32;
-    unsigned uuids32_is_complete:1;
+    unsigned uuids32_is_complete: 1;
 
     /*** 0x06,0x07 - 128-bit service class UUIDs. */
     const ble_uuid128_t *uuids128;
     uint8_t num_uuids128;
-    unsigned uuids128_is_complete:1;
+    unsigned uuids128_is_complete: 1;
 
     /*** 0x08,0x09 - Local name. */
     const uint8_t *name;
     uint8_t name_len;
-    unsigned name_is_complete:1;
+    unsigned name_is_complete: 1;
 
     /*** 0x0a - Tx power level. */
     int8_t tx_pwr_lvl;
-    unsigned tx_pwr_lvl_is_present:1;
+    unsigned tx_pwr_lvl_is_present: 1;
 
     /*** 0x0d - Slave connection interval range. */
     const uint8_t *slave_itvl_range;
@@ -82,11 +82,11 @@ struct ble_hs_adv_fields {
 
     /*** 0x19 - Appearance. */
     uint16_t appearance;
-    unsigned appearance_is_present:1;
+    unsigned appearance_is_present: 1;
 
     /*** 0x1a - Advertising interval. */
     uint16_t adv_itvl;
-    unsigned adv_itvl_is_present:1;
+    unsigned adv_itvl_is_present: 1;
 
     /*** 0x20 - Service data - 32-bit UUID. */
     const uint8_t *svc_data_uuid32;

+ 1 - 1
src/bt/blehost/nimble/host/include/host/ble_hs_stop.h

@@ -64,7 +64,7 @@ struct ble_hs_stop_listener {
  *                              BLE_HS_EALREADY: Host already stopped; the
  *                                  provided callback does *not* get called.
  */
-int ble_hs_stop(struct ble_hs_stop_listener *listener, 
+int ble_hs_stop(struct ble_hs_stop_listener *listener,
                 ble_hs_stop_fn *fn, void *arg);
 
 #endif

+ 10 - 7
src/bt/blehost/nimble/host/include/host/ble_store.h

@@ -56,7 +56,7 @@ struct ble_store_key_sec {
     /** Key by rand_num; ediv_rand_present=0 means don't key off rand_num. */
     uint64_t rand_num;
 
-    unsigned ediv_rand_present:1;
+    unsigned ediv_rand_present: 1;
 
     /** Number of results to skip; 0 means retrieve the first match. */
     uint8_t idx;
@@ -75,16 +75,16 @@ struct ble_store_value_sec {
     uint16_t ediv;
     uint64_t rand_num;
     uint8_t ltk[16];
-    uint8_t ltk_present:1;
+    uint8_t ltk_present: 1;
 
     uint8_t irk[16];
-    uint8_t irk_present:1;
+    uint8_t irk_present: 1;
 
     uint8_t csrk[16];
-    uint8_t csrk_present:1;
+    uint8_t csrk_present: 1;
 
-    unsigned authenticated:1;
-    uint8_t sc:1;
+    unsigned authenticated: 1;
+    uint8_t sc: 1;
 };
 
 /**
@@ -117,7 +117,7 @@ struct ble_store_value_cccd {
     ble_addr_t peer_addr;
     uint16_t chr_val_handle;
     uint16_t flags;
-    unsigned value_changed:1;
+    unsigned value_changed: 1;
 };
 
 /**
@@ -245,6 +245,8 @@ typedef int ble_store_delete_fn(int obj_type, const union ble_store_key *key);
 typedef int ble_store_status_fn(struct ble_store_status_event *event,
                                 void *arg);
 
+typedef int ble_store_flush_fn(void);
+
 int ble_store_read(int obj_type, const union ble_store_key *key,
                    union ble_store_value *val);
 int ble_store_write(int obj_type, const union ble_store_value *val);
@@ -297,6 +299,7 @@ int ble_store_util_get_peer_by_index(int idex, ble_addr_t *peer_id_addrs);
 
 int ble_store_util_count(int type, int *out_count);
 int ble_store_util_status_rr(struct ble_store_status_event *event, void *arg);
+int ble_store_flush(void);
 
 #ifdef __cplusplus
 }

+ 206 - 199
src/bt/blehost/nimble/host/mesh/include/mesh/access.h

@@ -34,7 +34,7 @@ extern "C" {
 #define BT_MESH_KEY_DEV_ANY       0xfffc
 
 #define BT_MESH_IS_DEV_KEY(key) (key == BT_MESH_KEY_DEV_LOCAL || \
-				 key == BT_MESH_KEY_DEV_REMOTE)
+                 key == BT_MESH_KEY_DEV_REMOTE)
 
 /** Helper to define a mesh element within an array.
  *
@@ -47,26 +47,26 @@ extern "C" {
  */
 #define BT_MESH_ELEM(_loc, _mods, _vnd_mods)        \
 {                                                   \
-	.loc              = (_loc),                 \
-	.model_count      = ARRAY_SIZE(_mods),      \
-	.models           = (_mods),                \
-	.vnd_model_count  = ARRAY_SIZE(_vnd_mods),  \
-	.vnd_models       = (_vnd_mods),            \
+    .loc              = (_loc),                 \
+    .model_count      = ARRAY_SIZE(_mods),      \
+    .models           = (_mods),                \
+    .vnd_model_count  = ARRAY_SIZE(_vnd_mods),  \
+    .vnd_models       = (_vnd_mods),            \
 }
 
 /** Abstraction that describes a Mesh Element */
 struct bt_mesh_elem {
-	/* Unicast Address. Set at runtime during provisioning. */
-	u16_t addr;
+    /* Unicast Address. Set at runtime during provisioning. */
+    u16_t addr;
 
-	/* Location Descriptor (GATT Bluetooth Namespace Descriptors) */
-	const u16_t loc;
+    /* Location Descriptor (GATT Bluetooth Namespace Descriptors) */
+    const u16_t loc;
 
-	const u8_t model_count;
-	const u8_t vnd_model_count;
+    const u8_t model_count;
+    const u8_t vnd_model_count;
 
-	struct bt_mesh_model * const models;
-	struct bt_mesh_model * const vnd_models;
+    struct bt_mesh_model *const models;
+    struct bt_mesh_model *const vnd_models;
 };
 
 /* Foundation Models */
@@ -131,42 +131,42 @@ struct bt_mesh_elem {
 
 /** Message sending context. */
 struct bt_mesh_msg_ctx {
-	/** NetKey Index of the subnet to send the message on. */
-	u16_t net_idx;
+    /** NetKey Index of the subnet to send the message on. */
+    u16_t net_idx;
 
-	/** AppKey Index to encrypt the message with. */
-	u16_t app_idx;
+    /** AppKey Index to encrypt the message with. */
+    u16_t app_idx;
 
-	/** Remote address. */
-	u16_t addr;
+    /** Remote address. */
+    u16_t addr;
 
-	/** Destination address of a received message. Not used for sending. */
-	u16_t recv_dst;
+    /** Destination address of a received message. Not used for sending. */
+    u16_t recv_dst;
 
-	/** RSSI of received packet. Not used for sending. */
-	s8_t  recv_rssi;
+    /** RSSI of received packet. Not used for sending. */
+    s8_t  recv_rssi;
 
-	/** Received TTL value. Not used for sending. */
-	u8_t  recv_ttl;
+    /** Received TTL value. Not used for sending. */
+    u8_t  recv_ttl;
 
-	/** Force sending reliably by using segment acknowledgement */
-	bool  send_rel;
+    /** Force sending reliably by using segment acknowledgement */
+    bool  send_rel;
 
-	/** TTL, or BT_MESH_TTL_DEFAULT for default TTL. */
-	u8_t  send_ttl;
+    /** TTL, or BT_MESH_TTL_DEFAULT for default TTL. */
+    u8_t  send_ttl;
 };
 
 struct bt_mesh_model_op {
-	/* OpCode encoded using the BT_MESH_MODEL_OP_* macros */
-	const u32_t  opcode;
+    /* OpCode encoded using the BT_MESH_MODEL_OP_* macros */
+    const u32_t  opcode;
 
-	/* Minimum required message length */
-	const size_t min_len;
+    /* Minimum required message length */
+    const size_t min_len;
 
-	/* Message handler for the opcode */
-	void (*const func)(struct bt_mesh_model *model,
-			   struct bt_mesh_msg_ctx *ctx,
-			   struct os_mbuf *buf);
+    /* Message handler for the opcode */
+    void (*const func)(struct bt_mesh_model *model,
+                       struct bt_mesh_msg_ctx *ctx,
+                       struct os_mbuf *buf);
 };
 
 #define BT_MESH_MODEL_OP_1(b0) (b0)
@@ -175,7 +175,7 @@ struct bt_mesh_model_op {
 
 #define BT_MESH_MODEL_OP_END { 0, 0, NULL }
 #define BT_MESH_MODEL_NO_OPS ((struct bt_mesh_model_op []) \
-			      { BT_MESH_MODEL_OP_END })
+                  { BT_MESH_MODEL_OP_END })
 
 /** Helper to define an empty model array */
 #define BT_MESH_MODEL_NONE ((struct bt_mesh_model []){})
@@ -204,7 +204,7 @@ struct bt_mesh_model_op {
  * @param _payload_len Length of the model payload.
  */
 #define BT_MESH_MODEL_BUF_LEN(_op, _payload_len)                               \
-	(BT_MESH_MODEL_OP_LEN(_op) + (_payload_len) + BT_MESH_MIC_SHORT)
+    (BT_MESH_MODEL_OP_LEN(_op) + (_payload_len) + BT_MESH_MIC_SHORT)
 
 /** @def BT_MESH_MODEL_BUF_LEN_LONG_MIC
  *
@@ -217,7 +217,7 @@ struct bt_mesh_model_op {
  * @param _payload_len Length of the model payload.
  */
 #define BT_MESH_MODEL_BUF_LEN_LONG_MIC(_op, _payload_len)                      \
-	(BT_MESH_MODEL_OP_LEN(_op) + (_payload_len) + BT_MESH_MIC_LONG)
+    (BT_MESH_MODEL_OP_LEN(_op) + (_payload_len) + BT_MESH_MIC_LONG)
 
 /** @def BT_MESH_MODEL_BUF_DEFINE
  *
@@ -227,7 +227,7 @@ struct bt_mesh_model_op {
  * @param _payload_len Length of the model message payload.
  */
 #define BT_MESH_MODEL_BUF(_op, _payload_len)                      \
-	NET_BUF_SIMPLE(BT_MESH_MODEL_BUF_LEN(_op, (_payload_len)))
+    NET_BUF_SIMPLE(BT_MESH_MODEL_BUF_LEN(_op, (_payload_len)))
 
 /** @def BT_MESH_MODEL_CB
  *
@@ -241,15 +241,15 @@ struct bt_mesh_model_op {
  */
 #define BT_MESH_MODEL_CB(_id, _op, _pub, _user_data, _cb)                    \
 {                                                                            \
-	.id = (_id),                                                         \
-	.op = _op,                                                           \
-	.keys = { [0 ... (CONFIG_BT_MESH_MODEL_KEY_COUNT - 1)] =             \
-			BT_MESH_KEY_UNUSED },                                \
-	.pub = _pub,                                                         \
-	.groups = { [0 ... (CONFIG_BT_MESH_MODEL_GROUP_COUNT - 1)] =         \
-			BT_MESH_ADDR_UNASSIGNED },                           \
-	.user_data = _user_data,                                             \
-	.cb = _cb,                                                           \
+    .id = (_id),                                                         \
+    .op = _op,                                                           \
+    .keys = { [0 ... (CONFIG_BT_MESH_MODEL_KEY_COUNT - 1)] =             \
+            BT_MESH_KEY_UNUSED },                                \
+    .pub = _pub,                                                         \
+    .groups = { [0 ... (CONFIG_BT_MESH_MODEL_GROUP_COUNT - 1)] =         \
+            BT_MESH_ADDR_UNASSIGNED },                           \
+    .user_data = _user_data,                                             \
+    .cb = _cb,                                                           \
 }
 
 /** @def BT_MESH_MODEL_VND_CB
@@ -265,16 +265,16 @@ struct bt_mesh_model_op {
  */
 #define BT_MESH_MODEL_VND_CB(_company, _id, _op, _pub, _user_data, _cb)      \
 {                                                                            \
-	.vnd.company = (_company),                                           \
-	.vnd.id = (_id),                                                     \
-	.op = _op,                                                           \
-	.pub = _pub,                                                         \
-	.keys = { [0 ... (CONFIG_BT_MESH_MODEL_KEY_COUNT - 1)] =             \
-			BT_MESH_KEY_UNUSED },                                \
-	.groups = { [0 ... (CONFIG_BT_MESH_MODEL_GROUP_COUNT - 1)] =         \
-			BT_MESH_ADDR_UNASSIGNED },                           \
-	.user_data = _user_data,                                             \
-	.cb = _cb,                                                           \
+    .vnd.company = (_company),                                           \
+    .vnd.id = (_id),                                                     \
+    .op = _op,                                                           \
+    .pub = _pub,                                                         \
+    .keys = { [0 ... (CONFIG_BT_MESH_MODEL_KEY_COUNT - 1)] =             \
+            BT_MESH_KEY_UNUSED },                                \
+    .groups = { [0 ... (CONFIG_BT_MESH_MODEL_GROUP_COUNT - 1)] =         \
+            BT_MESH_ADDR_UNASSIGNED },                           \
+    .user_data = _user_data,                                             \
+    .cb = _cb,                                                           \
 }
 
 
@@ -288,7 +288,7 @@ struct bt_mesh_model_op {
  * @param _user_data User data for the model.
  */
 #define BT_MESH_MODEL(_id, _op, _pub, _user_data)                              \
-	BT_MESH_MODEL_CB(_id, _op, _pub, _user_data, NULL)
+    BT_MESH_MODEL_CB(_id, _op, _pub, _user_data, NULL)
 
 /** @def BT_MESH_MODEL_VND
  *
@@ -301,7 +301,7 @@ struct bt_mesh_model_op {
  * @param _user_data User data for the model.
  */
 #define BT_MESH_MODEL_VND(_company, _id, _op, _pub, _user_data)                \
-	BT_MESH_MODEL_VND_CB(_company, _id, _op, _pub, _user_data, NULL)
+    BT_MESH_MODEL_VND_CB(_company, _id, _op, _pub, _user_data, NULL)
 
 /** @def BT_MESH_TRANSMIT
  *
@@ -348,7 +348,7 @@ struct bt_mesh_model_op {
  *          values of the configuration model data.
  */
 #define BT_MESH_PUB_TRANSMIT(count, int_ms) BT_MESH_TRANSMIT(count,           \
-							     (int_ms) / 5)
+                                 (int_ms) / 5)
 
 /** @def BT_MESH_PUB_TRANSMIT_COUNT
  *
@@ -372,147 +372,154 @@ struct bt_mesh_model_op {
 
 /** Model publication context. */
 struct bt_mesh_model_pub {
-	/** The model the context belongs to. Initialized by the stack. */
-	struct bt_mesh_model *mod;
-
-	u16_t addr;         /**< Publish Address. */
-	u16_t key;          /**< Publish AppKey Index. */
-
-	u8_t  ttl;          /**< Publish Time to Live. */
-	u8_t  retransmit;   /**< Retransmit Count & Interval Steps. */
-	u8_t  period;       /**< Publish Period. */
-	u8_t  period_div:4, /**< Divisor for the Period. */
-	      cred:1,       /**< Friendship Credentials Flag. */
-	      fast_period:1,/**< Use FastPeriodDivisor */
-	      count:3;      /**< Retransmissions left. */
-
-	u32_t period_start; /**< Start of the current period. */
-
-	/** @brief Publication buffer, containing the publication message.
-	 *
-	 *  The application is expected to initialize this with
-	 *  a valid net_buf_simple pointer, with the help of e.g.
-	 *  the NET_BUF_SIMPLE() macro. The publication buffer must
-	 *  contain a valid publication message before calling the
-	 *  bt_mesh_model_publish() API or after the publication's
-	 *  @ref bt_mesh_model_pub.update callback has been called
-	 *  and returned success. The buffer must be created outside
-	 *  of function context, i.e. it must not be on the stack.
-	 *  This is most conveniently acheived by creating it inline
-	 *  when declaring the publication context:
-	 *
-	 *      static struct bt_mesh_model_pub my_pub = {
-	 *              .msg = NET_BUF_SIMPLE(size),
-	 *      };
-	 */
-	struct os_mbuf *msg;
-
-	/** @brief Callback for updating the publication buffer.
-	 *
-	 *  When set to NULL, the model is assumed not to support
-	 *  periodic publishing. When set to non-NULL the callback
-	 *  will be called periodically and is expected to update
-	 *  @ref bt_mesh_model_pub.msg with a valid publication
-	 *  message.
-	 *
-	 *  @param mod The Model the Publication Context belogs to.
-	 *
-	 *  @return Zero on success or (negative) error code otherwise.
-	 */
-	int (*update)(struct bt_mesh_model *mod);
-
-	/** Publish Period Timer. Only for stack-internal use. */
-	struct k_delayed_work timer;
+    /** The model the context belongs to. Initialized by the stack. */
+    struct bt_mesh_model *mod;
+
+    u16_t addr;         /**< Publish Address. */
+    u16_t key;          /**< Publish AppKey Index. */
+
+    u8_t  ttl;          /**< Publish Time to Live. */
+    u8_t  retransmit;   /**< Retransmit Count & Interval Steps. */
+    u8_t  period;       /**< Publish Period. */
+    u8_t  period_div: 4, /**< Divisor for the Period. */
+          cred: 1,      /**< Friendship Credentials Flag. */
+          fast_period: 1, /**< Use FastPeriodDivisor */
+          count: 3;     /**< Retransmissions left. */
+
+    u32_t period_start; /**< Start of the current period. */
+
+    /** @brief Publication buffer, containing the publication message.
+     *
+     *  The application is expected to initialize this with
+     *  a valid net_buf_simple pointer, with the help of e.g.
+     *  the NET_BUF_SIMPLE() macro. The publication buffer must
+     *  contain a valid publication message before calling the
+     *  bt_mesh_model_publish() API or after the publication's
+     *  @ref bt_mesh_model_pub.update callback has been called
+     *  and returned success. The buffer must be created outside
+     *  of function context, i.e. it must not be on the stack.
+     *  This is most conveniently acheived by creating it inline
+     *  when declaring the publication context:
+     *
+     *      static struct bt_mesh_model_pub my_pub = {
+     *              .msg = NET_BUF_SIMPLE(size),
+     *      };
+     */
+    struct os_mbuf *msg;
+
+    /** @brief Callback for updating the publication buffer.
+     *
+     *  When set to NULL, the model is assumed not to support
+     *  periodic publishing. When set to non-NULL the callback
+     *  will be called periodically and is expected to update
+     *  @ref bt_mesh_model_pub.msg with a valid publication
+     *  message.
+     *
+     *  @param mod The Model the Publication Context belogs to.
+     *
+     *  @return Zero on success or (negative) error code otherwise.
+     */
+    int (*update)(struct bt_mesh_model *mod);
+
+    /** Publish Period Timer. Only for stack-internal use. */
+    struct k_delayed_work timer;
 };
 
 /** Model callback functions. */
 struct bt_mesh_model_cb {
-	/** @brief Set value handler of user data tied to the model.
-	 *
-	 * @sa settings_handler::h_set
-	 *
-	 * @param model Model to set the persistent data of.
-	 * @param val Data from the backend.
-	 *
-	 * @return 0 on success, error otherwise.
-	 */
-	int (*const settings_set)(struct bt_mesh_model *model, char *val);
-
-	/** @brief Callback called when all settings have been loaded.
-	 *
-	 * This handler gets called after the settings have been loaded in
-	 * full.
-	 *
-	 * @sa settings_handler::h_commit
-	 *
-	 * @param model Model this callback belongs to.
-	 *
-	 * @return 0 on success, error otherwise.
-	 */
-	int (*const settings_commit)(struct bt_mesh_model *model);
-
-	/** @brief Model init callback.
-	 *
-	 * Called on every model instance during mesh initialization.
-	 *
-	 * @param model Model to be initialized.
-	 *
-	 * @return 0 on success, error otherwise.
-	 */
-	int (*const init)(struct bt_mesh_model *model);
-
-	/** @brief Model reset callback.
-	 *
-	 * Called when the mesh node is reset. All model data is deleted on
-	 * reset, and the model should clear its state.
-	 *
-	 * @param model Model this callback belongs to.
-	 */
-	void (*const reset)(struct bt_mesh_model *model);
+    /** @brief Set value handler of user data tied to the model.
+     *
+     * @sa settings_handler::h_set
+     *
+     * @param model Model to set the persistent data of.
+     * @param val Data from the backend.
+     *
+     * @return 0 on success, error otherwise.
+     */
+    int (*const settings_set)(struct bt_mesh_model *model, char *val);
+
+    /** @brief Callback called when all settings have been loaded.
+     *
+     * This handler gets called after the settings have been loaded in
+     * full.
+     *
+     * @sa settings_handler::h_commit
+     *
+     * @param model Model this callback belongs to.
+     *
+     * @return 0 on success, error otherwise.
+     */
+    int (*const settings_commit)(struct bt_mesh_model *model);
+
+    /** @brief Model init callback.
+     *
+     * Called on every model instance during mesh initialization.
+     *
+     * @param model Model to be initialized.
+     *
+     * @return 0 on success, error otherwise.
+     */
+    int (*const init)(struct bt_mesh_model *model);
+
+    /** @brief Model reset callback.
+     *
+     * Called when the mesh node is reset. All model data is deleted on
+     * reset, and the model should clear its state.
+     *
+     * @param model Model this callback belongs to.
+     */
+    void (*const reset)(struct bt_mesh_model *model);
+
+    /**Called when the mesh node is deinitialized, All the model resouce
+        * will be freed, and the model should clear its state.
+     *
+     * @param model Model this callback belongs to.
+     */
+    int (*const deinit)(struct bt_mesh_model *model);
 };
 
 /** Abstraction that describes a Mesh Model instance */
 struct bt_mesh_model {
-	union {
-		const u16_t id;
-		struct {
-			u16_t company;
-			u16_t id;
-		} vnd;
-	};
+    union {
+        const u16_t id;
+        struct {
+            u16_t company;
+            u16_t id;
+        } vnd;
+    };
 
-	/* Internal information, mainly for persistent storage */
-	u8_t  elem_idx;   /* Belongs to Nth element */
-	u8_t  mod_idx;    /* Is the Nth model in the element */
-	u16_t flags;      /* Model flags for internal bookkeeping */
+    /* Internal information, mainly for persistent storage */
+    u8_t  elem_idx;   /* Belongs to Nth element */
+    u8_t  mod_idx;    /* Is the Nth model in the element */
+    u16_t flags;      /* Model flags for internal bookkeeping */
 
-	/* Model Publication */
-	struct bt_mesh_model_pub * const pub;
+    /* Model Publication */
+    struct bt_mesh_model_pub *const pub;
 
-	/* AppKey List */
-	u16_t keys[CONFIG_BT_MESH_MODEL_KEY_COUNT];
+    /* AppKey List */
+    u16_t keys[CONFIG_BT_MESH_MODEL_KEY_COUNT];
 
-	/* Subscription List (group or virtual addresses) */
-	u16_t groups[CONFIG_BT_MESH_MODEL_GROUP_COUNT];
+    /* Subscription List (group or virtual addresses) */
+    u16_t groups[CONFIG_BT_MESH_MODEL_GROUP_COUNT];
 
-	const struct bt_mesh_model_op * const op;
+    const struct bt_mesh_model_op *const op;
 
-	/* Model callback structure. */
-	const struct bt_mesh_model_cb * const cb;
+    /* Model callback structure. */
+    const struct bt_mesh_model_cb *const cb;
 
 #if MYNEWT_VAL(BLE_MESH_MODEL_EXTENSIONS)
-	/* Pointer to the next model in a model extension tree. */
-	struct bt_mesh_model *next;
-	/* Pointer to the first model this model extends. */
-	struct bt_mesh_model *extends;
+    /* Pointer to the next model in a model extension tree. */
+    struct bt_mesh_model *next;
+    /* Pointer to the first model this model extends. */
+    struct bt_mesh_model *extends;
 #endif
-	/* Model-specific user data */
-	void *user_data;
+    /* Model-specific user data */
+    void *user_data;
 };
 
 struct bt_mesh_send_cb {
-	void (*start)(u16_t duration, int err, void *cb_data);
-	void (*end)(int err, void *cb_data);
+    void (*start)(u16_t duration, int err, void *cb_data);
+    void (*end)(int err, void *cb_data);
 };
 
 void bt_mesh_model_msg_init(struct os_mbuf *msg, u32_t opcode);
@@ -535,10 +542,10 @@ void bt_mesh_model_msg_init(struct os_mbuf *msg, u32_t opcode);
  * @return 0 on success, or (negative) error code on failure.
  */
 int bt_mesh_model_send(struct bt_mesh_model *model,
-		       struct bt_mesh_msg_ctx *ctx,
-		       struct os_mbuf *msg,
-		       const struct bt_mesh_send_cb *cb,
-		       void *cb_data);
+                       struct bt_mesh_msg_ctx *ctx,
+                       struct os_mbuf *msg,
+                       const struct bt_mesh_send_cb *cb,
+                       void *cb_data);
 
 /**
  * @brief Send a model publication message.
@@ -574,7 +581,7 @@ struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod);
  * if no SIG model with the given ID exists in the given element.
  */
 struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem,
-					 u16_t id);
+        u16_t id);
 
 /** @brief Find a vendor model.
  *
@@ -586,7 +593,7 @@ struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem,
  * if no vendor model with the given ID exists in the given element.
  */
 struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem,
-					     u16_t company, u16_t id);
+        u16_t company, u16_t id);
 
 /** @brief Get whether the model is in the primary element of the device.
  *
@@ -596,7 +603,7 @@ struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem,
  */
 static inline bool bt_mesh_model_in_primary(const struct bt_mesh_model *mod)
 {
-	return (mod->elem_idx == 0);
+    return (mod->elem_idx == 0);
 }
 
 /** @brief Immediately store the model's user data in persistent storage.
@@ -609,7 +616,7 @@ static inline bool bt_mesh_model_in_primary(const struct bt_mesh_model *mod)
  * @return 0 on success, or (negative) error code on failure.
  */
 int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd,
-			     const void *data, size_t data_len);
+                             const void *data, size_t data_len);
 
 /** @brief Let a model extend another.
  *
@@ -633,16 +640,16 @@ int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd,
  * @retval -EALREADY The base_mod model is already extended.
  */
 int bt_mesh_model_extend(struct bt_mesh_model *mod,
-			 struct bt_mesh_model *base_mod);
+                         struct bt_mesh_model *base_mod);
 
 /** Node Composition */
 struct bt_mesh_comp {
-	u16_t cid;
-	u16_t pid;
-	u16_t vid;
+    u16_t cid;
+    u16_t pid;
+    u16_t vid;
 
-	size_t elem_count;
-	struct bt_mesh_elem *elem;
+    size_t elem_count;
+    struct bt_mesh_elem *elem;
 };
 
 #ifdef __cplusplus

+ 115 - 71
src/bt/blehost/nimble/host/mesh/include/mesh/cfg_cli.h

@@ -23,22 +23,24 @@ extern "C" {
 
 /** Mesh Configuration Client Model Context */
 struct bt_mesh_cfg_cli {
-	struct bt_mesh_model *model;
+    struct bt_mesh_model *model;
 
-	struct k_sem          op_sync;
-	u32_t                 op_pending;
-	void                 *op_param;
+    struct k_sem          op_sync;
+    u32_t                 op_pending;
+    void                 *op_param;
 };
 
 extern const struct bt_mesh_model_op bt_mesh_cfg_cli_op[];
 extern const struct bt_mesh_model_cb bt_mesh_cfg_cli_cb;
 
 #define BT_MESH_MODEL_CFG_CLI(cli_data)                                        \
-	BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_CFG_CLI, bt_mesh_cfg_cli_op, NULL,   \
-			 cli_data, &bt_mesh_cfg_cli_cb)
+    BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_CFG_CLI, bt_mesh_cfg_cli_op, NULL,   \
+             cli_data, &bt_mesh_cfg_cli_cb)
+
+int bt_mesh_cfg_node_reset(uint16_t net_idx, uint16_t addr, bool *status);
 
 int bt_mesh_cfg_comp_data_get(u16_t net_idx, u16_t addr, u8_t page,
-			      u8_t *status, struct os_mbuf *comp);
+                              u8_t *status, struct os_mbuf *comp);
 
 int bt_mesh_cfg_beacon_get(u16_t net_idx, u16_t addr, u8_t *status);
 
@@ -55,28 +57,61 @@ int bt_mesh_cfg_friend_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *status);
 int bt_mesh_cfg_gatt_proxy_get(u16_t net_idx, u16_t addr, u8_t *status);
 
 int bt_mesh_cfg_gatt_proxy_set(u16_t net_idx, u16_t addr, u8_t val,
-			       u8_t *status);
+                               u8_t *status);
+
+int bt_mesh_cfg_net_transmit_get(uint16_t net_idx, uint16_t addr,
+                                 uint8_t *transmit);
+
+int bt_mesh_cfg_net_transmit_set(uint16_t net_idx, uint16_t addr,
+                                 uint8_t val, uint8_t *transmit);
 
 int bt_mesh_cfg_relay_get(u16_t net_idx, u16_t addr, u8_t *status,
-			  u8_t *transmit);
+                          u8_t *transmit);
 
 int bt_mesh_cfg_relay_set(u16_t net_idx, u16_t addr, u8_t new_relay,
-			  u8_t new_transmit, u8_t *status, u8_t *transmit);
+                          u8_t new_transmit, u8_t *status, u8_t *transmit);
+
+int bt_mesh_cfg_net_key_add(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
+                            const uint8_t net_key[16], uint8_t *status);
+
+int bt_mesh_cfg_net_key_get(uint16_t net_idx, uint16_t addr, uint16_t *keys,
+                            size_t *key_cnt);
+
+int bt_mesh_cfg_net_key_del(uint16_t net_idx, uint16_t addr,
+                            uint16_t key_net_idx, uint8_t *status);
+
+int bt_mesh_cfg_app_key_add(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
+                            uint16_t key_app_idx, const uint8_t app_key[16],
+                            uint8_t *status);
 
-int bt_mesh_cfg_net_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx,
-			    const u8_t net_key[16], u8_t *status);
+int bt_mesh_cfg_app_key_get(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx,
+                            uint8_t *status, uint16_t *keys, size_t *key_cnt);
 
-int bt_mesh_cfg_app_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx,
-			    u16_t key_app_idx, const u8_t app_key[16],
-			    u8_t *status);
+int bt_mesh_cfg_app_key_del(uint16_t net_idx, uint16_t addr,
+                            uint16_t key_net_idx, uint16_t key_app_idx, uint8_t *status);
 
 int bt_mesh_cfg_mod_app_bind(u16_t net_idx, u16_t addr, u16_t elem_addr,
-			     u16_t mod_app_idx, u16_t mod_id, u8_t *status);
+                             u16_t mod_app_idx, u16_t mod_id, u8_t *status);
+
+int bt_mesh_cfg_mod_app_unbind(uint16_t net_idx, uint16_t addr,
+                               uint16_t elem_addr, uint16_t mod_app_idx,
+                               uint16_t mod_id, uint8_t *status);
 
 int bt_mesh_cfg_mod_app_bind_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
-				 u16_t mod_app_idx, u16_t mod_id, u16_t cid,
-				 u8_t *status);
+                                 u16_t mod_app_idx, u16_t mod_id, u16_t cid,
+                                 u8_t *status);
+
+int bt_mesh_cfg_mod_app_unbind_vnd(uint16_t net_idx, uint16_t addr,
+                                   uint16_t elem_addr, uint16_t mod_app_idx, uint16_t mod_id,
+                                   uint16_t cid, uint8_t *status);
+
+int bt_mesh_cfg_mod_app_get(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
+                            uint16_t mod_id, uint8_t *status, uint16_t *apps,
+                            size_t *app_cnt);
 
+int bt_mesh_cfg_mod_app_get_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
+                                uint16_t mod_id, uint16_t cid, uint8_t *status,
+                                uint16_t *apps, size_t *app_cnt);
 /** @def BT_MESH_PUB_PERIOD_100MS
  *
  *  @brief Helper macro to encode model publication period in units of 100ms
@@ -120,106 +155,115 @@ int bt_mesh_cfg_mod_app_bind_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
 #define BT_MESH_PUB_PERIOD_10MIN(steps) (((steps) & BIT_MASK(6)) | (3 << 6))
 
 struct bt_mesh_cfg_mod_pub {
-	u16_t  addr;
-	u16_t  app_idx;
-	bool   cred_flag;
-	u8_t   ttl;
-	u8_t   period;
-	u8_t   transmit;
+    u16_t  addr;
+    u16_t  app_idx;
+    bool   cred_flag;
+    u8_t   ttl;
+    u8_t   period;
+    u8_t   transmit;
 };
 
 int bt_mesh_cfg_mod_pub_get(u16_t net_idx, u16_t addr, u16_t elem_addr,
-			    u16_t mod_id, struct bt_mesh_cfg_mod_pub *pub,
-			    u8_t *status);
+                            u16_t mod_id, struct bt_mesh_cfg_mod_pub *pub,
+                            u8_t *status);
 
 int bt_mesh_cfg_mod_pub_get_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
-				u16_t mod_id, u16_t cid,
-				struct bt_mesh_cfg_mod_pub *pub, u8_t *status);
+                                u16_t mod_id, u16_t cid,
+                                struct bt_mesh_cfg_mod_pub *pub, u8_t *status);
 
 int bt_mesh_cfg_mod_pub_set(u16_t net_idx, u16_t addr, u16_t elem_addr,
-			    u16_t mod_id, struct bt_mesh_cfg_mod_pub *pub,
-			    u8_t *status);
+                            u16_t mod_id, struct bt_mesh_cfg_mod_pub *pub,
+                            u8_t *status);
 
 int bt_mesh_cfg_mod_pub_set_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
-				u16_t mod_id, u16_t cid,
-				struct bt_mesh_cfg_mod_pub *pub, u8_t *status);
+                                u16_t mod_id, u16_t cid,
+                                struct bt_mesh_cfg_mod_pub *pub, u8_t *status);
 
 int bt_mesh_cfg_mod_sub_add(u16_t net_idx, u16_t addr, u16_t elem_addr,
-			    u16_t sub_addr, u16_t mod_id, u8_t *status);
+                            u16_t sub_addr, u16_t mod_id, u8_t *status);
 
 int bt_mesh_cfg_mod_sub_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
-				 u16_t sub_addr, u16_t mod_id, u16_t cid,
-				 u8_t *status);
+                                u16_t sub_addr, u16_t mod_id, u16_t cid,
+                                u8_t *status);
 
 int bt_mesh_cfg_mod_sub_del(u16_t net_idx, u16_t addr, u16_t elem_addr,
-			    u16_t sub_addr, u16_t mod_id, u8_t *status);
+                            u16_t sub_addr, u16_t mod_id, u8_t *status);
 
 int bt_mesh_cfg_mod_sub_del_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
-				 u16_t sub_addr, u16_t mod_id, u16_t cid,
-				 u8_t *status);
+                                u16_t sub_addr, u16_t mod_id, u16_t cid,
+                                u8_t *status);
 
 int bt_mesh_cfg_mod_sub_overwrite(u16_t net_idx, u16_t addr, u16_t elem_addr,
-				  u16_t sub_addr, u16_t mod_id, u8_t *status);
+                                  u16_t sub_addr, u16_t mod_id, u8_t *status);
 
 int bt_mesh_cfg_mod_sub_overwrite_vnd(u16_t net_idx, u16_t addr,
-				      u16_t elem_addr, u16_t sub_addr,
-				      u16_t mod_id, u16_t cid, u8_t *status);
+                                      u16_t elem_addr, u16_t sub_addr,
+                                      u16_t mod_id, u16_t cid, u8_t *status);
 
 int bt_mesh_cfg_mod_sub_va_add(u16_t net_idx, u16_t addr, u16_t elem_addr,
-			       const u8_t label[16], u16_t mod_id,
-			       u16_t *virt_addr, u8_t *status);
+                               const u8_t label[16], u16_t mod_id,
+                               u16_t *virt_addr, u8_t *status);
 
 int bt_mesh_cfg_mod_sub_va_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
-				   const u8_t label[16], u16_t mod_id,
-				   u16_t cid, u16_t *virt_addr, u8_t *status);
+                                   const u8_t label[16], u16_t mod_id,
+                                   u16_t cid, u16_t *virt_addr, u8_t *status);
 
 int bt_mesh_cfg_mod_sub_va_del(u16_t net_idx, u16_t addr, u16_t elem_addr,
-			       const u8_t label[16], u16_t mod_id,
-			       u16_t *virt_addr, u8_t *status);
+                               const u8_t label[16], u16_t mod_id,
+                               u16_t *virt_addr, u8_t *status);
 
 int bt_mesh_cfg_mod_sub_va_del_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr,
-				   const u8_t label[16], u16_t mod_id,
-				   u16_t cid, u16_t *virt_addr, u8_t *status);
+                                   const u8_t label[16], u16_t mod_id,
+                                   u16_t cid, u16_t *virt_addr, u8_t *status);
 
 int bt_mesh_cfg_mod_sub_va_overwrite(u16_t net_idx, u16_t addr,
-				     u16_t elem_addr, const u8_t label[16],
-				     u16_t mod_id, u16_t *virt_addr,
-				     u8_t *status);
+                                     u16_t elem_addr, const u8_t label[16],
+                                     u16_t mod_id, u16_t *virt_addr,
+                                     u8_t *status);
 
 int bt_mesh_cfg_mod_sub_va_overwrite_vnd(u16_t net_idx, u16_t addr,
-					 u16_t elem_addr, const u8_t label[16],
-					 u16_t mod_id, u16_t cid,
-					 u16_t *virt_addr, u8_t *status);
+        u16_t elem_addr, const u8_t label[16],
+        u16_t mod_id, u16_t cid,
+        u16_t *virt_addr, u8_t *status);
+
+int bt_mesh_cfg_mod_sub_get(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
+                            uint16_t mod_id, uint8_t *status, uint16_t *subs,
+                            size_t *sub_cnt);
+
+int bt_mesh_cfg_mod_sub_get_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr,
+                                uint16_t mod_id, uint16_t cid, uint8_t *status,
+                                uint16_t *subs, size_t *sub_cnt);
+
 
 struct bt_mesh_cfg_hb_sub {
-	u16_t src;
-	u16_t dst;
-	u8_t  period;
-	u8_t  count;
-	u8_t  min;
-	u8_t  max;
+    u16_t src;
+    u16_t dst;
+    u8_t  period;
+    u8_t  count;
+    u8_t  min;
+    u8_t  max;
 };
 
 int bt_mesh_cfg_hb_sub_set(u16_t net_idx, u16_t addr,
-			   struct bt_mesh_cfg_hb_sub *sub, u8_t *status);
+                           struct bt_mesh_cfg_hb_sub *sub, u8_t *status);
 
 int bt_mesh_cfg_hb_sub_get(u16_t net_idx, u16_t addr,
-			   struct bt_mesh_cfg_hb_sub *sub, u8_t *status);
+                           struct bt_mesh_cfg_hb_sub *sub, u8_t *status);
 
 struct bt_mesh_cfg_hb_pub {
-	u16_t dst;
-	u8_t  count;
-	u8_t  period;
-	u8_t  ttl;
-	u16_t feat;
-	u16_t net_idx;
+    u16_t dst;
+    u8_t  count;
+    u8_t  period;
+    u8_t  ttl;
+    u16_t feat;
+    u16_t net_idx;
 };
 
 int bt_mesh_cfg_hb_pub_set(u16_t net_idx, u16_t addr,
-			   const struct bt_mesh_cfg_hb_pub *pub, u8_t *status);
+                           const struct bt_mesh_cfg_hb_pub *pub, u8_t *status);
 
 int bt_mesh_cfg_hb_pub_get(u16_t net_idx, u16_t addr,
-			   struct bt_mesh_cfg_hb_pub *pub, u8_t *status);
+                           struct bt_mesh_cfg_hb_pub *pub, u8_t *status);
 
 s32_t bt_mesh_cfg_cli_timeout_get(void);
 void bt_mesh_cfg_cli_timeout_set(s32_t timeout);

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.