ble_ota.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117
  1. /*
  2. * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <string.h>
  7. #include "freertos/FreeRTOS.h"
  8. #include "esp_log.h"
  9. #include "ble_ota.h"
  10. #ifdef CONFIG_BT_BLUEDROID_ENABLED
  11. #include "esp_bt.h"
  12. #include "esp_gap_ble_api.h"
  13. #include "esp_gatts_api.h"
  14. #include "esp_bt_main.h"
  15. #endif
  16. #define TAG "ESP_BLE_OTA"
  17. #define DEVICE_NAME "ESP-C919"
  18. #ifdef CONFIG_BT_BLUEDROID_ENABLED
  19. #define OTA_PROFILE_NUM 2
  20. #define OTA_PROFILE_APP_IDX 0
  21. #define DIS_PROFILE_APP_IDX 1
  22. #define BUF_LENGTH 4098
  23. #define BLE_OTA_MAX_CHAR_VAL_LEN 600
  24. #define BLE_OTA_START_CMD 0x0001
  25. #define BLE_OTA_STOP_CMD 0x0002
  26. #define BLE_OTA_ACK_CMD 0x0003
  27. #define CHAR_DECLARATION_SIZE (sizeof(uint8_t))
  28. typedef enum {
  29. BLE_OTA_CMD_ACK = 0, /*!< Command Ack */
  30. BLE_OTA_FW_ACK = 1, /*!< Firmware Ack */
  31. } ble_ota_ack_type_t;
  32. typedef enum {
  33. BLE_OTA_CMD_SUCCESS = 0x0000, /*!< Success Ack */
  34. BLE_OTA_REJECT = 0x0001, /*!< Reject Cmd Ack */
  35. } ble_ota_cmd_ack_status_t;
  36. typedef enum {
  37. BLE_OTA_FW_SUCCESS = 0x0000, /*!< Success */
  38. BLE_OTA_FW_CRC_ERR = 0x0001, /*!< CRC error */
  39. BLE_OTA_FW_IND_ERR = 0x0002, /*!< Sector Index error*/
  40. BLE_OTA_FW_LEN_ERR = 0x0003, /*!< Payload length error*/
  41. } ble_ota_fw_ack_statuc_t;
  42. struct gatts_profile_inst {
  43. esp_gatts_cb_t gatts_cb;
  44. uint16_t gatts_if;
  45. uint16_t conn_id;
  46. uint16_t mtu_size;
  47. };
  48. #ifdef CONFIG_BT_BLE_50_FEATURES_SUPPORTED
  49. #define EXT_ADV_HANDLE 0
  50. #define NUM_EXT_ADV_SET 1
  51. #define EXT_ADV_DURATION 0
  52. #define EXT_ADV_MAX_EVENTS 0
  53. static uint8_t ext_ota_adv_data[] = {
  54. 0x02, 0x01, 0x06,
  55. 0x03, 0x03, 0x18, 0x80, //UUID
  56. 0x09, 0x09, 0x45, 0x53, 0x50, 0x26, 0x43, 0x39, 0x31, 0x39, //ESP-C919
  57. 0x0d, 0xff, 0xe5, 0x02, 0x01, 0x01, 0x27, 0x95, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff
  58. };
  59. static esp_ble_gap_ext_adv_t ext_adv[1] = {
  60. [0] = {EXT_ADV_HANDLE, EXT_ADV_DURATION, EXT_ADV_MAX_EVENTS},
  61. };
  62. esp_ble_gap_ext_adv_params_t ext_ota_adv_params = {
  63. .type = ESP_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE,
  64. .interval_min = 0x20,
  65. .interval_max = 0x20,
  66. .channel_map = ADV_CHNL_ALL,
  67. .filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
  68. .primary_phy = ESP_BLE_GAP_PHY_1M,
  69. .max_skip = 0,
  70. .secondary_phy = ESP_BLE_GAP_PHY_2M,
  71. .sid = 0,
  72. .scan_req_notif = false,
  73. .own_addr_type = BLE_ADDR_TYPE_PUBLIC,
  74. .tx_power = EXT_ADV_TX_PWR_NO_PREFERENCE,
  75. };
  76. #else
  77. static esp_ble_adv_params_t ota_adv_params = {
  78. .adv_int_min = 0x20,
  79. .adv_int_max = 0x40,
  80. .adv_type = ADV_TYPE_IND,
  81. .own_addr_type = BLE_ADDR_TYPE_PUBLIC,
  82. .channel_map = ADV_CHNL_ALL,
  83. .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
  84. };
  85. static const uint8_t ota_adv_data[31] = {
  86. 0x02, 0x01, 0x06,
  87. 0x03, 0x03, 0x18, 0x80, //UUID
  88. 0x09, 0x09, 0x45, 0x53, 0x50, 0x26, 0x43, 0x39, 0x31, 0x39, //ESP-C919
  89. 0x0d, 0xff, 0xe5, 0x02, 0x01, 0x01, 0x27, 0x95, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff
  90. };
  91. static const uint8_t ota_scan_rsp_data[31] = {
  92. 0x02, 0x01, 0x06,
  93. 0x03, 0x03, 0x18, 0x80, //UUID
  94. 0x09, 0x09, 0x45, 0x53, 0x50, 0x26, 0x43, 0x39, 0x31, 0x39, //ESP-C919
  95. 0x0d, 0xff, 0xe5, 0x02, 0x01, 0x01, 0x27, 0x95, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff
  96. };
  97. #endif
  98. esp_ble_ota_callback_funs_t ota_cb_fun_t = {
  99. .recv_fw_cb = NULL
  100. };
  101. esp_ble_ota_notification_check_t ota_notification = {
  102. .recv_fw_ntf_enable = false,
  103. .process_bar_ntf_enable = false,
  104. .command_ntf_enable = false,
  105. .customer_ntf_enable = false,
  106. };
  107. static void gatts_ota_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
  108. static void gatts_dis_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
  109. /**
  110. * @brief This function is called to send notification to remote device
  111. *
  112. * @param[in] ota_char: the characteristic index which to be send
  113. * @param[in] value: the pointer to the send value
  114. * @param[in] length: the value length
  115. *
  116. * @return
  117. * - ESP_OK : success
  118. * - other : failed
  119. */
  120. esp_err_t esp_ble_ota_notification_data(esp_ble_ota_char_t ota_char, uint8_t *value, uint8_t length);
  121. /**
  122. * @brief This function is called to set the attribute value by the application
  123. *
  124. * @param[in] ota_char: the characteristic index which to be set
  125. * @param[in] value: the pointer to the attribute value
  126. * @param[in] length: the value length
  127. *
  128. * @return
  129. * - ESP_OK : success
  130. * - other : failed
  131. */
  132. esp_err_t esp_ble_ota_set_value(esp_ble_ota_char_t ota_char, uint8_t *value, uint8_t length);
  133. static struct gatts_profile_inst ota_profile_tab[OTA_PROFILE_NUM] = {
  134. [OTA_PROFILE_APP_IDX] = {
  135. .gatts_cb = gatts_ota_profile_event_handler,
  136. .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
  137. .conn_id = 0xff,
  138. .mtu_size = 23,
  139. },
  140. [DIS_PROFILE_APP_IDX] = {
  141. .gatts_cb = gatts_dis_profile_event_handler,
  142. .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
  143. .conn_id = 0xff,
  144. .mtu_size = 23,
  145. },
  146. };
  147. static bool start_ota = false;
  148. static unsigned int ota_total_len = 0;
  149. static unsigned int cur_sector = 0;
  150. static unsigned int cur_packet = 0;
  151. static uint8_t *fw_buf = NULL;
  152. static unsigned int fw_buf_offset = 0;
  153. static uint8_t *temp_prep_write_buf = NULL;
  154. static unsigned int temp_buf_len = 0;
  155. static const uint16_t primary_service_uuid = ESP_GATT_UUID_PRI_SERVICE;
  156. static const uint16_t character_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE;
  157. static const uint16_t character_client_config_uuid = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
  158. static const uint8_t char_prop_read = ESP_GATT_CHAR_PROP_BIT_READ;
  159. static const uint8_t char_prop_read_indicate = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_INDICATE;
  160. static const uint8_t char_prop_write_indicate = ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_INDICATE;
  161. static const uint16_t BLE_OTA_SERVICE_UUID = 0x8018;
  162. static const uint16_t RECV_FW_UUID = 0x8020;
  163. static const uint16_t OTA_BAR_UUID = 0x8021;
  164. static const uint16_t COMMAND_UUID = 0x8022;
  165. static const uint16_t CUSTOMER_UUID = 0x8023;
  166. static uint8_t receive_fw_val[BLE_OTA_MAX_CHAR_VAL_LEN] = {0};
  167. static uint8_t receive_fw_val_ccc[2] = {0x00, 0x00};
  168. static uint8_t ota_status_val[20] = {0};
  169. static uint8_t ota_status_val_ccc[2] = {0x00, 0x00};
  170. static uint8_t command_val[20] = {0};
  171. static uint8_t command_val_ccc[2] = {0x00, 0x00};
  172. static uint8_t custom_val[20] = {0};
  173. static uint8_t custom_val_ccc[2] = {0x00, 0x00};
  174. static uint16_t ota_handle_table[OTA_IDX_NB];
  175. /* OTA Full Database Description - Used to add attributes into the database */
  176. static const esp_gatts_attr_db_t ota_gatt_db[OTA_IDX_NB] = {
  177. // Service Declaration
  178. [OTA_SVC_IDX] =
  179. { {ESP_GATT_AUTO_RSP}, {
  180. ESP_UUID_LEN_16, (uint8_t *) &primary_service_uuid, ESP_GATT_PERM_READ,
  181. sizeof(BLE_OTA_SERVICE_UUID), sizeof(BLE_OTA_SERVICE_UUID), (uint8_t *) &BLE_OTA_SERVICE_UUID
  182. }
  183. },
  184. /* Characteristic Declaration */
  185. [RECV_FW_CHAR_IDX] =
  186. { {ESP_GATT_AUTO_RSP}, {
  187. ESP_UUID_LEN_16, (uint8_t *) &character_declaration_uuid, ESP_GATT_PERM_READ,
  188. CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *) &char_prop_write_indicate
  189. }
  190. },
  191. /* Characteristic Value */
  192. [RECV_FW_CHAR_VAL_IDX] =
  193. { {ESP_GATT_AUTO_RSP}, {
  194. ESP_UUID_LEN_16, (uint8_t *) &RECV_FW_UUID, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
  195. sizeof(receive_fw_val), sizeof(receive_fw_val), (uint8_t *)receive_fw_val
  196. }
  197. },
  198. //data notify characteristic Declaration
  199. [RECV_FW_CHAR_NTF_CFG] =
  200. { {ESP_GATT_AUTO_RSP}, {
  201. ESP_UUID_LEN_16, (uint8_t *) &character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
  202. sizeof(receive_fw_val_ccc), sizeof(receive_fw_val_ccc), (uint8_t *)receive_fw_val_ccc
  203. }
  204. },
  205. //data receive characteristic Declaration
  206. [OTA_STATUS_CHAR_IDX] =
  207. { {ESP_GATT_AUTO_RSP}, {
  208. ESP_UUID_LEN_16, (uint8_t *) &character_declaration_uuid, ESP_GATT_PERM_READ,
  209. CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *) &char_prop_read_indicate
  210. }
  211. },
  212. //data receive characteristic Value
  213. [OTA_STATUS_CHAR_VAL_IDX] =
  214. { {ESP_GATT_AUTO_RSP}, {
  215. ESP_UUID_LEN_16, (uint8_t *) &OTA_BAR_UUID, ESP_GATT_PERM_READ,
  216. sizeof(ota_status_val), sizeof(ota_status_val), (uint8_t *)ota_status_val
  217. }
  218. },
  219. //data notify characteristic Declaration
  220. [OTA_STATUS_NTF_CFG] =
  221. { {ESP_GATT_AUTO_RSP}, {
  222. ESP_UUID_LEN_16, (uint8_t *) &character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
  223. sizeof(ota_status_val_ccc), sizeof(ota_status_val_ccc), (uint8_t *)ota_status_val_ccc
  224. }
  225. },
  226. //data receive characteristic Declaration
  227. [CMD_CHAR_IDX] =
  228. { {ESP_GATT_AUTO_RSP}, {
  229. ESP_UUID_LEN_16, (uint8_t *) &character_declaration_uuid, ESP_GATT_PERM_READ,
  230. CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *) &char_prop_write_indicate
  231. }
  232. },
  233. //data receive characteristic Value
  234. [CMD_CHAR_VAL_IDX] =
  235. { {ESP_GATT_AUTO_RSP}, {
  236. ESP_UUID_LEN_16, (uint8_t *) &COMMAND_UUID, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
  237. sizeof(command_val), sizeof(command_val), (uint8_t *)command_val
  238. }
  239. },
  240. //data notify characteristic Declaration
  241. [CMD_CHAR_NTF_CFG] =
  242. { {ESP_GATT_AUTO_RSP}, {
  243. ESP_UUID_LEN_16, (uint8_t *) &character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
  244. sizeof(command_val_ccc), sizeof(command_val_ccc), (uint8_t *)command_val_ccc
  245. }
  246. },
  247. //data receive characteristic Declaration
  248. [CUS_CHAR_IDX] =
  249. { {ESP_GATT_AUTO_RSP}, {
  250. ESP_UUID_LEN_16, (uint8_t *) &character_declaration_uuid, ESP_GATT_PERM_READ,
  251. CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *) &char_prop_write_indicate
  252. }
  253. },
  254. //data receive characteristic Value
  255. [CUS_CHAR_VAL_IDX] =
  256. { {ESP_GATT_AUTO_RSP}, {
  257. ESP_UUID_LEN_16, (uint8_t *) &CUSTOMER_UUID, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
  258. sizeof(custom_val), sizeof(custom_val), (uint8_t *)custom_val
  259. }
  260. },
  261. //data notify characteristic Declaration
  262. [CUS_CHAR_NTF_CFG] =
  263. { {ESP_GATT_AUTO_RSP}, {
  264. ESP_UUID_LEN_16, (uint8_t *) &character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
  265. sizeof(custom_val_ccc), sizeof(custom_val_ccc), (uint8_t *)custom_val_ccc
  266. }
  267. },
  268. };
  269. static const uint16_t DIS_SERVICE_UUID = 0x180A;
  270. static const uint16_t DIS_MODEL_CHAR_UUID = 0x2A24;
  271. static const uint16_t DIS_SN_CHAR_UUID = 0x2A25;
  272. static const uint16_t DIS_FW_CHAR_UUID = 0x2A26;
  273. static uint8_t dis_model_value[] = "Espressif";
  274. static uint8_t dis_sn_value[] = "esp-ota";
  275. static uint8_t dis_fw_value[] = "1.0";
  276. static uint16_t dis_handle_table[DIS_IDX_NB];
  277. /* DIS Full Database Description - Used to add attributes into the database */
  278. static const esp_gatts_attr_db_t dis_gatt_db[DIS_IDX_NB] = {
  279. // Service Declaration
  280. [DIS_SVC_IDX] =
  281. { {ESP_GATT_AUTO_RSP}, {
  282. ESP_UUID_LEN_16, (uint8_t *) &primary_service_uuid, ESP_GATT_PERM_READ,
  283. sizeof(DIS_SERVICE_UUID), sizeof(DIS_SERVICE_UUID), (uint8_t *) &DIS_SERVICE_UUID
  284. }
  285. },
  286. /* Characteristic Declaration */
  287. [DIS_MODEL_CHAR_IDX] =
  288. { {ESP_GATT_AUTO_RSP}, {
  289. ESP_UUID_LEN_16, (uint8_t *) &character_declaration_uuid, ESP_GATT_PERM_READ,
  290. CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *) &char_prop_read
  291. }
  292. },
  293. /* Characteristic Value */
  294. [DIS_MODEL_CHAR_VAL_IDX] =
  295. { {ESP_GATT_AUTO_RSP}, {
  296. ESP_UUID_LEN_16, (uint8_t *) &DIS_MODEL_CHAR_UUID, ESP_GATT_PERM_READ,
  297. sizeof(dis_model_value), sizeof(dis_model_value), (uint8_t *)dis_model_value
  298. }
  299. },
  300. /* Characteristic Declaration */
  301. [DIS_SN_CHAR_IDX] =
  302. { {ESP_GATT_AUTO_RSP}, {
  303. ESP_UUID_LEN_16, (uint8_t *) &character_declaration_uuid, ESP_GATT_PERM_READ,
  304. CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *) &char_prop_read
  305. }
  306. },
  307. /* Characteristic Value */
  308. [DIS_SN_CHAR_VAL_IDX] =
  309. { {ESP_GATT_AUTO_RSP}, {
  310. ESP_UUID_LEN_16, (uint8_t *) &DIS_SN_CHAR_UUID, ESP_GATT_PERM_READ,
  311. sizeof(dis_sn_value), sizeof(dis_sn_value), (uint8_t *)dis_sn_value
  312. }
  313. },
  314. /* Characteristic Declaration */
  315. [DIS_FW_CHAR_IDX] =
  316. { {ESP_GATT_AUTO_RSP}, {
  317. ESP_UUID_LEN_16, (uint8_t *) &character_declaration_uuid, ESP_GATT_PERM_READ,
  318. CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *) &char_prop_read
  319. }
  320. },
  321. /* Characteristic Value */
  322. [DIS_FW_CHAR_VAL_IDX] =
  323. { {ESP_GATT_AUTO_RSP}, {
  324. ESP_UUID_LEN_16, (uint8_t *) &DIS_FW_CHAR_UUID, ESP_GATT_PERM_READ,
  325. sizeof(dis_fw_value), sizeof(dis_fw_value), (uint8_t *)dis_fw_value
  326. }
  327. },
  328. };
  329. static uint16_t crc16_ccitt(const unsigned char *buf, int len)
  330. {
  331. uint16_t crc16 = 0;
  332. int32_t i;
  333. while (len--) {
  334. crc16 ^= *buf++ << 8;
  335. for (i = 0; i < 8; i++) {
  336. if (crc16 & 0x8000) {
  337. crc16 = (crc16 << 1) ^ 0x1021;
  338. } else {
  339. crc16 = crc16 << 1;
  340. }
  341. }
  342. }
  343. return crc16;
  344. }
  345. void esp_ble_ota_set_fw_length(unsigned int length)
  346. {
  347. ota_total_len = length;
  348. }
  349. unsigned int esp_ble_ota_get_fw_length(void)
  350. {
  351. return ota_total_len;
  352. }
  353. static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
  354. {
  355. esp_bd_addr_t bd_addr;
  356. ESP_LOGD(TAG, "GAP_EVT, event %d\n", event);
  357. switch (event) {
  358. #ifdef CONFIG_BT_BLE_50_FEATURES_SUPPORTED
  359. case ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT:
  360. esp_ble_gap_config_ext_adv_data_raw(EXT_ADV_HANDLE, sizeof(ext_ota_adv_data), &ext_ota_adv_data[0]);
  361. break;
  362. case ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT:
  363. esp_ble_gap_ext_adv_start(NUM_EXT_ADV_SET, &ext_adv[0]);
  364. break;
  365. case ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT:
  366. ESP_LOGI(TAG, "Ext adv start, status = %d", param->ext_adv_data_set.status);
  367. break;
  368. #else
  369. case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
  370. esp_ble_gap_start_advertising(&ota_adv_params);
  371. break;
  372. case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
  373. //advertising start complete event to indicate advertising start successfully or failed
  374. if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
  375. ESP_LOGE(TAG, "Advertising start failed\n");
  376. }
  377. break;
  378. #endif
  379. case ESP_GAP_BLE_SEC_REQ_EVT:
  380. for (int i = 0; i < ESP_BD_ADDR_LEN; i++) {
  381. ESP_LOGI(TAG, "%x:", param->ble_security.ble_req.bd_addr[i]);
  382. }
  383. esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true);
  384. break;
  385. case ESP_GAP_BLE_AUTH_CMPL_EVT:
  386. memcpy(bd_addr, param->ble_security.auth_cmpl.bd_addr, sizeof(esp_bd_addr_t));
  387. ESP_LOGI(TAG, "remote BD_ADDR: %08x%04x", \
  388. (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3],
  389. (bd_addr[4] << 8) + bd_addr[5]);
  390. ESP_LOGI(TAG, "address type = %d", param->ble_security.auth_cmpl.addr_type);
  391. ESP_LOGI(TAG, "pair status = %s", param->ble_security.auth_cmpl.success ? "success" : "fail");
  392. if (!param->ble_security.auth_cmpl.success) {
  393. ESP_LOGE(TAG, "fail reason = 0x%x", param->ble_security.auth_cmpl.fail_reason);
  394. }
  395. break;
  396. case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
  397. ESP_LOGI(TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d",
  398. param->update_conn_params.status,
  399. param->update_conn_params.min_int,
  400. param->update_conn_params.max_int,
  401. param->update_conn_params.conn_int,
  402. param->update_conn_params.latency,
  403. param->update_conn_params.timeout);
  404. break;
  405. default:
  406. break;
  407. }
  408. }
  409. static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
  410. {
  411. // ESP_LOGI(TAG, "EVT %d, gatts if %d\n", event, gatts_if);
  412. /* If event is register event, store the gatts_if for each profile */
  413. if (event == ESP_GATTS_REG_EVT) {
  414. if (param->reg.status == ESP_GATT_OK) {
  415. ota_profile_tab[param->reg.app_id].gatts_if = gatts_if;
  416. } else {
  417. ESP_LOGE(TAG, "Reg app failed, app_id %04x, status %d\n", param->reg.app_id, param->reg.status);
  418. return;
  419. }
  420. }
  421. do {
  422. int idx;
  423. for (idx = 0; idx < OTA_PROFILE_NUM; idx++) {
  424. if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
  425. gatts_if == ota_profile_tab[idx].gatts_if) {
  426. if (ota_profile_tab[idx].gatts_cb) {
  427. ota_profile_tab[idx].gatts_cb(event, gatts_if, param);
  428. }
  429. }
  430. }
  431. } while (0);
  432. }
  433. static void gatts_dis_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
  434. {
  435. esp_err_t ret;
  436. ESP_LOGD(TAG, "%s - event: %d", __func__, event);
  437. switch (event) {
  438. case ESP_GATTS_REG_EVT:
  439. ret = esp_ble_gatts_create_attr_tab(dis_gatt_db, gatts_if, DIS_IDX_NB, DIS_PROFILE_APP_IDX);
  440. if (ret) {
  441. ESP_LOGE(TAG, "%s - create attr table failed, error code = %x", __func__, ret);
  442. }
  443. break;
  444. case ESP_GATTS_READ_EVT:
  445. ESP_LOGI(TAG, "DIS ESP_GATTS_READ_EVT");
  446. break;
  447. case ESP_GATTS_WRITE_EVT:
  448. ESP_LOGI(TAG, "DIS ESP_GATTS_WRITE_EVT");
  449. break;
  450. case ESP_GATTS_EXEC_WRITE_EVT:
  451. ESP_LOGI(TAG, "DIS ESP_GATTS_EXEC_WRITE_EVT");
  452. break;
  453. case ESP_GATTS_MTU_EVT:
  454. ESP_LOGI(TAG, "DIS ESP_GATTS_MTU_EVT mtu = %d", param->mtu.mtu);
  455. break;
  456. case ESP_GATTS_CONF_EVT:
  457. break;
  458. case ESP_GATTS_START_EVT:
  459. ESP_LOGI(TAG, "DIS SERVICE_START_EVT, status %d, service_handle %d", param->start.status, param->start.service_handle);
  460. if (param->start.status != ESP_GATT_OK) {
  461. ESP_LOGE(TAG, "SERVICE START FAIL, status %d", param->start.status);
  462. break;
  463. }
  464. break;
  465. case ESP_GATTS_CONNECT_EVT:
  466. break;
  467. case ESP_GATTS_DISCONNECT_EVT:
  468. break;
  469. case ESP_GATTS_CREAT_ATTR_TAB_EVT:
  470. if (param->add_attr_tab.status != ESP_GATT_OK) {
  471. ESP_LOGE(TAG, "dis create attribute table failed, error code=0x%x", param->add_attr_tab.status);
  472. } else if (param->add_attr_tab.num_handle != DIS_IDX_NB) {
  473. ESP_LOGE(TAG, "dis create attribute table abnormally, num_handle (%d) doesn't equal to DIS_IDX_NB(%d)", param->add_attr_tab.num_handle, DIS_IDX_NB);
  474. } else {
  475. ESP_LOGI(TAG, "dis create attribute table successfully, the number handle = %d\n", param->add_attr_tab.num_handle);
  476. memcpy(dis_handle_table, param->add_attr_tab.handles, sizeof(dis_handle_table));
  477. esp_ble_gatts_start_service(dis_handle_table[DIS_SVC_IDX]);
  478. }
  479. break;
  480. case ESP_GATTS_STOP_EVT:
  481. break;
  482. case ESP_GATTS_OPEN_EVT:
  483. break;
  484. case ESP_GATTS_CANCEL_OPEN_EVT:
  485. break;
  486. case ESP_GATTS_CLOSE_EVT:
  487. break;
  488. case ESP_GATTS_LISTEN_EVT:
  489. break;
  490. case ESP_GATTS_CONGEST_EVT:
  491. break;
  492. case ESP_GATTS_UNREG_EVT:
  493. break;
  494. case ESP_GATTS_DELETE_EVT:
  495. break;
  496. default:
  497. break;
  498. }
  499. }
  500. static esp_ble_ota_char_t find_ota_char_and_desr_by_handle(uint16_t handle)
  501. {
  502. esp_ble_ota_char_t ret = INVALID_CHAR;
  503. for (int i = 0; i < OTA_IDX_NB ; i++) {
  504. if (handle == ota_handle_table[i]) {
  505. switch (i) {
  506. case RECV_FW_CHAR_VAL_IDX:
  507. ret = RECV_FW_CHAR;
  508. break;
  509. case RECV_FW_CHAR_NTF_CFG:
  510. ret = RECV_FW_CHAR_CCC;
  511. break;
  512. case OTA_STATUS_CHAR_VAL_IDX:
  513. ret = OTA_STATUS_CHAR;
  514. break;
  515. case OTA_STATUS_NTF_CFG:
  516. ret = OTA_STATUS_CHAR_CCC;
  517. break;
  518. case CMD_CHAR_VAL_IDX:
  519. ret = CMD_CHAR;
  520. break;
  521. case CMD_CHAR_NTF_CFG:
  522. ret = CMD_CHAR_CCC;
  523. break;
  524. case CUS_CHAR_VAL_IDX:
  525. ret = CUS_CHAR;
  526. break;
  527. case CUS_CHAR_NTF_CFG:
  528. ret = CUS_CHAR_CCC;
  529. break;
  530. default:
  531. ret = INVALID_CHAR;
  532. break;
  533. }
  534. }
  535. }
  536. return ret;
  537. }
  538. esp_err_t esp_ble_ota_recv_fw_handler(uint8_t *buf, unsigned int length)
  539. {
  540. if (ota_cb_fun_t.recv_fw_cb) {
  541. ota_cb_fun_t.recv_fw_cb(buf, length);
  542. }
  543. return ESP_OK;
  544. }
  545. void esp_ble_ota_send_ack_data(ble_ota_ack_type_t ack_type, uint16_t ack_status, uint16_t ack_param)
  546. {
  547. uint8_t cmd_ack[20] = {0};
  548. uint16_t crc16 = 0;
  549. switch (ack_type) {
  550. case BLE_OTA_CMD_ACK:
  551. cmd_ack[0] = (BLE_OTA_ACK_CMD & 0xff);
  552. cmd_ack[1] = (BLE_OTA_ACK_CMD & 0xff) >> 8;
  553. cmd_ack[2] = (ack_param & 0xff);
  554. cmd_ack[3] = (ack_param & 0xff00) >> 8;
  555. cmd_ack[4] = (ack_status & 0xff);
  556. cmd_ack[5] = (ack_status & 0xff00) >> 8;
  557. crc16 = crc16_ccitt(cmd_ack, 18);
  558. cmd_ack[18] = crc16 & 0xff;
  559. cmd_ack[19] = (crc16 & 0xff00) >> 8;
  560. esp_ble_ota_notification_data(CMD_CHAR, cmd_ack, 20);
  561. break;
  562. case BLE_OTA_FW_ACK:
  563. cmd_ack[0] = (ack_param & 0xff);
  564. cmd_ack[1] = (ack_param & 0xff) >> 8;
  565. cmd_ack[2] = (ack_status & 0xff);
  566. cmd_ack[3] = (ack_status & 0xff00) >> 8;
  567. cmd_ack[4] = (cur_sector & 0xff);
  568. cmd_ack[5] = (cur_sector & 0xff) >> 8;
  569. crc16 = crc16_ccitt(cmd_ack, 18);
  570. cmd_ack[18] = crc16 & 0xff;
  571. cmd_ack[19] = (crc16 & 0xff00) >> 8;
  572. esp_ble_ota_notification_data(RECV_FW_CHAR, cmd_ack, 20);
  573. break;
  574. default:
  575. break;
  576. }
  577. }
  578. void esp_ble_ota_process_recv_data(esp_ble_ota_char_t ota_char, uint8_t *val, uint16_t val_len)
  579. {
  580. unsigned int recv_sector = 0;
  581. switch (ota_char) {
  582. case CMD_CHAR:
  583. // Start BLE OTA Process
  584. if ((val[0] == 0x01) && (val[1] == 0x00)) {
  585. if (start_ota) {
  586. esp_ble_ota_send_ack_data(BLE_OTA_CMD_ACK, BLE_OTA_REJECT, BLE_OTA_START_CMD);
  587. } else {
  588. start_ota = true;
  589. // Calculating Firmware Length
  590. ota_total_len = (val[2]) +
  591. (val[3] * 256) +
  592. (val[4] * 256 * 256) +
  593. (val[5] * 256 * 256 * 256);
  594. esp_ble_ota_set_fw_length(ota_total_len);
  595. ESP_LOGI(TAG, "Recv ota start cmd, fw_length = %d", ota_total_len);
  596. // Malloc buffer to store receive Firmware
  597. fw_buf = (uint8_t *)malloc(BUF_LENGTH * sizeof(uint8_t));
  598. if (fw_buf == NULL) {
  599. ESP_LOGE(TAG, "Malloc fail");
  600. break;
  601. } else {
  602. memset(fw_buf, 0x0, BUF_LENGTH);
  603. }
  604. esp_ble_ota_send_ack_data(BLE_OTA_CMD_ACK, BLE_OTA_CMD_SUCCESS, BLE_OTA_START_CMD);
  605. }
  606. }
  607. // Stop BLE OTA Process
  608. else if ((val[0] == 0x02) && (val[1] == 0x00)) {
  609. if (start_ota) {
  610. start_ota = false;
  611. esp_ble_ota_set_fw_length(0);
  612. ESP_LOGI(TAG, "recv ota stop cmd");
  613. esp_ble_ota_send_ack_data(BLE_OTA_CMD_ACK, BLE_OTA_CMD_SUCCESS, BLE_OTA_STOP_CMD);
  614. if (fw_buf) {
  615. free(fw_buf);
  616. fw_buf = NULL;
  617. }
  618. } else {
  619. esp_ble_ota_send_ack_data(BLE_OTA_CMD_ACK, BLE_OTA_REJECT, BLE_OTA_STOP_CMD);
  620. }
  621. } else {
  622. ESP_LOGE(TAG, "Unknow Command [0x%02x%02x]", val[1], val[0]);
  623. }
  624. break;
  625. case RECV_FW_CHAR:
  626. if (start_ota) {
  627. // Calculating the received sector index
  628. recv_sector = (val[0] + (val[1] * 256));
  629. if (recv_sector != cur_sector) { // sector error
  630. if (recv_sector == 0xffff) { // last sector
  631. ESP_LOGI(TAG, "Laster sector");
  632. } else { // sector error
  633. ESP_LOGE(TAG, "Sector index error, cur: %d, recv: %d", cur_sector, recv_sector);
  634. esp_ble_ota_send_ack_data(BLE_OTA_FW_ACK, BLE_OTA_FW_IND_ERR, recv_sector);
  635. }
  636. }
  637. if (val[2] != cur_packet) { // packet seq error
  638. if (val[2] == 0xff) { // last packet
  639. ESP_LOGI(TAG, "laster packet");
  640. goto write_ota_data;
  641. } else { // packet seq error
  642. ESP_LOGE(TAG, "Packet index error, cur: %d, recv: %d", cur_packet, val[2]);
  643. }
  644. }
  645. write_ota_data:
  646. memcpy(fw_buf + fw_buf_offset, val + 3, val_len - 3);
  647. fw_buf_offset += val_len - 3;
  648. ESP_LOGI(TAG, "DEBUG: Sector:%d, total length:%d, length:%d", cur_sector, fw_buf_offset, val_len - 3);
  649. if (val[2] == 0xff) {
  650. cur_packet = 0;
  651. cur_sector++;
  652. ESP_LOGD(TAG, "DEBUG: recv %d sector", cur_sector);
  653. goto sector_end;
  654. } else {
  655. cur_packet++;
  656. }
  657. break;
  658. sector_end:
  659. esp_ble_ota_recv_fw_handler(fw_buf, 4096);
  660. memset(fw_buf, 0x0, 4096);
  661. fw_buf_offset = 0;
  662. esp_ble_ota_send_ack_data(BLE_OTA_FW_ACK, BLE_OTA_FW_SUCCESS, recv_sector);
  663. } else {
  664. ESP_LOGE(TAG, "BLE OTA hasn't started yet");
  665. }
  666. break;
  667. case OTA_STATUS_CHAR:
  668. break;
  669. case CUS_CHAR:
  670. break;
  671. default:
  672. ESP_LOGW(TAG, "Invalid data was received, char[%d]", ota_char);
  673. break;
  674. }
  675. }
  676. static void gatts_ota_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
  677. {
  678. esp_err_t ret;
  679. esp_ble_ota_char_t ota_char;
  680. ESP_LOGI(TAG, "%s - event: %d", __func__, event);
  681. switch (event) {
  682. case ESP_GATTS_REG_EVT:
  683. ret = esp_ble_gap_set_device_name(DEVICE_NAME);
  684. if (ret) {
  685. ESP_LOGE(TAG, "set device name failed, error code = %x", ret);
  686. }
  687. #ifdef CONFIG_BT_BLE_50_FEATURES_SUPPORTED
  688. ret = esp_ble_gap_ext_adv_set_params(EXT_ADV_HANDLE, &ext_ota_adv_params);
  689. if (ret) {
  690. ESP_LOGE(TAG, "set ext adv params failed, error code = %x", ret);
  691. }
  692. #else
  693. ret = esp_ble_gap_config_adv_data_raw((uint8_t *)ota_adv_data, sizeof(ota_adv_data));
  694. if (ret) {
  695. ESP_LOGE(TAG, "set adv data failed, error code = %x", ret);
  696. }
  697. ret = esp_ble_gap_config_scan_rsp_data_raw((uint8_t *)ota_scan_rsp_data, sizeof(ota_scan_rsp_data));
  698. if (ret) {
  699. ESP_LOGE(TAG, "set scan rsp data failed, error code = %x", ret);
  700. }
  701. #endif
  702. ret = esp_ble_gatts_create_attr_tab(ota_gatt_db, gatts_if, OTA_IDX_NB, OTA_PROFILE_APP_IDX);
  703. if (ret) {
  704. ESP_LOGE(TAG, "Create attr table failed, error code = %x", ret);
  705. }
  706. break;
  707. case ESP_GATTS_READ_EVT:
  708. ota_char = find_ota_char_and_desr_by_handle(param->read.handle);
  709. ESP_LOGI(TAG, "Read event - ota_char: %d", ota_char);
  710. break;
  711. case ESP_GATTS_WRITE_EVT:
  712. ota_char = find_ota_char_and_desr_by_handle(param->write.handle);
  713. ESP_LOGD(TAG, "Write event - ota_char: %d", ota_char);
  714. // Enable indication
  715. if ((param->write.len == 2) && (param->write.value[0] == 0x02) && (param->write.value[1] == 0x00)) {
  716. if (ota_char == OTA_STATUS_CHAR_CCC) {
  717. ota_notification.process_bar_ntf_enable = true;
  718. }
  719. if (ota_char == RECV_FW_CHAR_CCC) {
  720. ota_notification.recv_fw_ntf_enable = true;
  721. }
  722. if (ota_char == CMD_CHAR_CCC) {
  723. ota_notification.command_ntf_enable = true;
  724. }
  725. if (ota_char == CUS_CHAR_CCC) {
  726. ota_notification.customer_ntf_enable = true;
  727. }
  728. }
  729. // Disable indication
  730. else if ((param->write.len == 2) && (param->write.value[0] == 0x00) && (param->write.value[1] == 0x00)) {
  731. if (ota_char == OTA_STATUS_CHAR_CCC) {
  732. ota_notification.process_bar_ntf_enable = false;
  733. }
  734. if (ota_char == RECV_FW_CHAR_CCC) {
  735. ota_notification.recv_fw_ntf_enable = false;
  736. }
  737. if (ota_char == CMD_CHAR_CCC) {
  738. ota_notification.command_ntf_enable = false;
  739. }
  740. if (ota_char == CUS_CHAR_CCC) {
  741. ota_notification.customer_ntf_enable = false;
  742. }
  743. }
  744. if (param->write.is_prep == false) {
  745. esp_ble_ota_process_recv_data(ota_char, param->write.value, param->write.len);
  746. } else {
  747. if (temp_prep_write_buf == NULL) {
  748. temp_prep_write_buf = (uint8_t *)malloc(BLE_OTA_MAX_CHAR_VAL_LEN * sizeof(uint8_t));
  749. if (temp_prep_write_buf == NULL) {
  750. ESP_LOGE(TAG, "Malloc buffer for prep write fail");
  751. break;
  752. }
  753. memset(temp_prep_write_buf, 0x0, BLE_OTA_MAX_CHAR_VAL_LEN);
  754. temp_buf_len = 0;
  755. }
  756. memcpy(temp_prep_write_buf + temp_buf_len, param->write.value, param->write.len);
  757. temp_buf_len += param->write.len;
  758. }
  759. break;
  760. case ESP_GATTS_EXEC_WRITE_EVT:
  761. if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) {
  762. if (temp_prep_write_buf) {
  763. esp_ble_ota_process_recv_data(RECV_FW_CHAR, temp_prep_write_buf, temp_buf_len);
  764. }
  765. } else {
  766. if (temp_prep_write_buf) {
  767. free(temp_prep_write_buf);
  768. temp_prep_write_buf = NULL;
  769. }
  770. temp_buf_len = 0;
  771. }
  772. break;
  773. case ESP_GATTS_MTU_EVT:
  774. ESP_LOGI(TAG, "ESP_GATTS_MTU_EVT - mtu = %d", param->mtu.mtu);
  775. ota_profile_tab[OTA_PROFILE_APP_IDX].mtu_size = param->mtu.mtu;
  776. break;
  777. case ESP_GATTS_CONF_EVT:
  778. break;
  779. case ESP_GATTS_START_EVT:
  780. ESP_LOGI(TAG, "SERVICE_START_EVT, status %d, service_handle %d", param->start.status, param->start.service_handle);
  781. if (param->start.status != ESP_GATT_OK) {
  782. ESP_LOGE(TAG, "SERVICE START FAIL, status %d", param->start.status);
  783. break;
  784. }
  785. break;
  786. case ESP_GATTS_CONNECT_EVT:
  787. ota_profile_tab[OTA_PROFILE_APP_IDX].conn_id = param->connect.conn_id;
  788. esp_ble_conn_update_params_t conn_params = {0};
  789. memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
  790. /* For the IOS system, please reference the apple official documents about the ble connection parameters restrictions. */
  791. conn_params.latency = 0;
  792. conn_params.max_int = 0x06; // max_int = 0x6*1.25ms = 7.5ms
  793. conn_params.min_int = 0x06; // min_int = 0x6*1.25ms = 7.5ms
  794. conn_params.timeout = 400; // timeout = 400*10ms = 4000ms
  795. ESP_LOGI(TAG, "ESP_GATTS_CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:",
  796. param->connect.conn_id,
  797. param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2],
  798. param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5]);
  799. //start sent the update connection parameters to the peer device.
  800. esp_ble_gap_update_conn_params(&conn_params);
  801. break;
  802. case ESP_GATTS_DISCONNECT_EVT:
  803. #ifdef CONFIG_BT_BLE_50_FEATURES_SUPPORTED
  804. esp_ble_gap_ext_adv_start(NUM_EXT_ADV_SET, &ext_adv[0]);
  805. #else
  806. esp_ble_gap_start_advertising(&ota_adv_params);
  807. #endif
  808. ota_profile_tab[OTA_PROFILE_APP_IDX].mtu_size = 23;
  809. break;
  810. case ESP_GATTS_CREAT_ATTR_TAB_EVT:
  811. if (param->add_attr_tab.status != ESP_GATT_OK) {
  812. ESP_LOGE(TAG, "create attribute table failed, error code=0x%x", param->add_attr_tab.status);
  813. } else if (param->add_attr_tab.num_handle != OTA_IDX_NB) {
  814. ESP_LOGE(TAG, "create attribute table abnormally, num_handle (%d) doesn't equal to OTA_IDX_NB(%d)", param->add_attr_tab.num_handle, OTA_IDX_NB);
  815. } else {
  816. ESP_LOGI(TAG, "create attribute table successfully, the number handle = %d\n", param->add_attr_tab.num_handle);
  817. memcpy(ota_handle_table, param->add_attr_tab.handles, sizeof(ota_handle_table));
  818. esp_ble_gatts_start_service(ota_handle_table[OTA_SVC_IDX]);
  819. }
  820. break;
  821. case ESP_GATTS_STOP_EVT:
  822. break;
  823. case ESP_GATTS_OPEN_EVT:
  824. break;
  825. case ESP_GATTS_CANCEL_OPEN_EVT:
  826. break;
  827. case ESP_GATTS_CLOSE_EVT:
  828. break;
  829. case ESP_GATTS_LISTEN_EVT:
  830. break;
  831. case ESP_GATTS_CONGEST_EVT:
  832. break;
  833. case ESP_GATTS_UNREG_EVT:
  834. break;
  835. case ESP_GATTS_DELETE_EVT:
  836. break;
  837. default:
  838. break;
  839. }
  840. }
  841. static esp_err_t esp_ble_ota_set_characteristic_value(esp_ble_ota_service_index_t index, uint8_t *value, uint8_t length)
  842. {
  843. esp_err_t ret;
  844. ret = esp_ble_gatts_set_attr_value(ota_handle_table[index], length, value);
  845. if (ret) {
  846. ESP_LOGE(TAG, "%s set attribute value fail: %s\n", __func__, esp_err_to_name(ret));
  847. return ESP_FAIL;
  848. }
  849. return ESP_OK;
  850. }
  851. esp_err_t esp_ble_ota_set_value(esp_ble_ota_char_t ota_char, uint8_t *value, uint8_t length)
  852. {
  853. esp_err_t ret;
  854. switch (ota_char) {
  855. case RECV_FW_CHAR:
  856. ret = esp_ble_ota_set_characteristic_value(RECV_FW_CHAR_VAL_IDX, value, length);
  857. break;
  858. case OTA_STATUS_CHAR:
  859. ret = esp_ble_ota_set_characteristic_value(OTA_STATUS_CHAR_VAL_IDX, value, length);
  860. break;
  861. case CMD_CHAR:
  862. ret = esp_ble_ota_set_characteristic_value(CMD_CHAR_VAL_IDX, value, length);
  863. break;
  864. case CUS_CHAR:
  865. ret = esp_ble_ota_set_characteristic_value(CUS_CHAR_VAL_IDX, value, length);
  866. break;
  867. default:
  868. ret = ESP_FAIL;
  869. break;
  870. }
  871. if (ret) {
  872. ESP_LOGE(TAG, "%s set characteristic value fail: %s\n", __func__, esp_err_to_name(ret));
  873. return ESP_FAIL;
  874. }
  875. return ESP_OK;
  876. }
  877. static esp_err_t esp_ble_ota_send_indication(esp_ble_ota_service_index_t index, uint8_t *value, uint8_t length, bool need_ack)
  878. {
  879. esp_err_t ret;
  880. uint16_t offset = 0;
  881. if (length <= (ota_profile_tab[OTA_PROFILE_APP_IDX].mtu_size - 3)) {
  882. ret = esp_ble_gatts_send_indicate(ota_profile_tab[OTA_PROFILE_APP_IDX].gatts_if, ota_profile_tab[OTA_PROFILE_APP_IDX].conn_id, ota_handle_table[index], length, value, need_ack);
  883. if (ret) {
  884. ESP_LOGE(TAG, "%s send notification fail: %s\n", __func__, esp_err_to_name(ret));
  885. return ESP_FAIL;
  886. }
  887. } else {
  888. while ((length - offset) > (ota_profile_tab[OTA_PROFILE_APP_IDX].mtu_size - 3)) {
  889. ret = esp_ble_gatts_send_indicate(ota_profile_tab[OTA_PROFILE_APP_IDX].gatts_if, ota_profile_tab[OTA_PROFILE_APP_IDX].conn_id, ota_handle_table[index], (ota_profile_tab[OTA_PROFILE_APP_IDX].mtu_size - 3), value + offset, need_ack);
  890. if (ret) {
  891. ESP_LOGE(TAG, "%s send notification fail: %s\n", __func__, esp_err_to_name(ret));
  892. return ESP_FAIL;
  893. }
  894. offset += (ota_profile_tab[OTA_PROFILE_APP_IDX].mtu_size - 3);
  895. }
  896. if ((length - offset) > 0) {
  897. ret = esp_ble_gatts_send_indicate(ota_profile_tab[OTA_PROFILE_APP_IDX].gatts_if, ota_profile_tab[OTA_PROFILE_APP_IDX].conn_id, ota_handle_table[index], (length - offset), value + offset, need_ack);
  898. if (ret) {
  899. ESP_LOGE(TAG, "%s send notification fail: %s\n", __func__, esp_err_to_name(ret));
  900. return ESP_FAIL;
  901. }
  902. }
  903. }
  904. return ESP_OK;
  905. }
  906. esp_err_t esp_ble_ota_notification_data(esp_ble_ota_char_t ota_char, uint8_t *value, uint8_t length)
  907. {
  908. esp_err_t ret = ESP_FAIL;
  909. switch (ota_char) {
  910. case RECV_FW_CHAR:
  911. if (ota_notification.recv_fw_ntf_enable) {
  912. ret = esp_ble_ota_send_indication(RECV_FW_CHAR_VAL_IDX, value, length, false);
  913. } else {
  914. ESP_LOGE(TAG, "notify isn't enable");
  915. }
  916. break;
  917. case OTA_STATUS_CHAR:
  918. if (ota_notification.process_bar_ntf_enable) {
  919. ret = esp_ble_ota_send_indication(OTA_STATUS_CHAR_VAL_IDX, value, length, false);
  920. } else {
  921. ESP_LOGE(TAG, "notify isn't enable");
  922. }
  923. break;
  924. case CMD_CHAR:
  925. if (ota_notification.command_ntf_enable) {
  926. ret = esp_ble_ota_send_indication(CMD_CHAR_VAL_IDX, value, length, false);
  927. } else {
  928. ESP_LOGE(TAG, "notify isn't enable");
  929. }
  930. break;
  931. case CUS_CHAR:
  932. if (ota_notification.customer_ntf_enable) {
  933. ret = esp_ble_ota_send_indication(CUS_CHAR_VAL_IDX, value, length, false);
  934. } else {
  935. ESP_LOGE(TAG, "notify isn't enable");
  936. }
  937. break;
  938. default:
  939. ret = ESP_FAIL;
  940. break;
  941. }
  942. if (ret) {
  943. ESP_LOGE(TAG, "%s notification fail: %s\n", __func__, esp_err_to_name(ret));
  944. return ESP_FAIL;
  945. }
  946. return ESP_OK;
  947. }
  948. esp_err_t esp_ble_ota_recv_fw_data_callback(esp_ble_ota_recv_fw_cb_t callback)
  949. {
  950. ota_cb_fun_t.recv_fw_cb = callback;
  951. return ESP_OK;
  952. }
  953. esp_err_t esp_ble_ota_host_init(void)
  954. {
  955. esp_err_t ret;
  956. ret = esp_bluedroid_init();
  957. if (ret) {
  958. ESP_LOGE(TAG, "%s init bluetooth failed: %s\n", __func__, esp_err_to_name(ret));
  959. return ret;
  960. }
  961. ret = esp_bluedroid_enable();
  962. if (ret) {
  963. ESP_LOGE(TAG, "%s enable bluetooth failed: %s\n", __func__, esp_err_to_name(ret));
  964. return ret;
  965. }
  966. // ESP_LOGI(TAG, "ble ota Version[%d.%d.%d]\n", BLE_OTA_VER_MAJOR, BLE_OTA_VER_MINOR, BLE_OTA_VER_PATCH);
  967. esp_ble_gatts_register_callback(gatts_event_handler);
  968. esp_ble_gap_register_callback(gap_event_handler);
  969. esp_ble_gatts_app_register(OTA_PROFILE_APP_IDX);
  970. esp_ble_gatts_app_register(DIS_PROFILE_APP_IDX);
  971. /* set the security iocap & auth_req & key size & init key response key parameters to the stack*/
  972. esp_ble_auth_req_t auth_req = ESP_LE_AUTH_BOND; //bonding with peer device after authentication
  973. esp_ble_io_cap_t iocap = ESP_IO_CAP_NONE; //set the IO capability to No output No input
  974. uint8_t key_size = 16; //the key size should be 7~16 bytes
  975. uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
  976. uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
  977. esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t));
  978. esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t));
  979. esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t));
  980. /* If your BLE device act as a Slave, the init_key means you hope which types of key of the master should distribute to you,
  981. and the response key means which key you can distribute to the Master;
  982. If your BLE device act as a master, the response key means you hope which types of key of the slave should distribute to you,
  983. and the init key means which key you can distribute to the slave. */
  984. esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t));
  985. esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t));
  986. return ESP_OK;
  987. }
  988. #endif