44 */
55
66#include <stdio.h>
7+ #include <esp_ota_ops.h>
8+ #include <esp_system.h>
9+ #include <esp_timer.h>
710#include "host.h"
811#include "att.h"
912#include "zephyr/uuid.h"
1316
1417#define ATT_MAX_LEN 512
1518#define BR_API_VER 1
19+ #define OTA_START 0xA5
20+ #define OTA_ABORT 0xDE
21+ #define OTA_END 0x5A
1622
1723enum {
1824 GATT_GRP_HDL = 0x0001 ,
@@ -43,17 +49,28 @@ enum {
4349 BR_IN_CFG_DATA_CHRC_HDL ,
4450 BR_API_VER_ATT_HDL ,
4551 BR_API_VER_CHRC_HDL ,
52+ BR_OTA_FW_CTRL_ATT_HDL ,
53+ BR_OTA_FW_CTRL_CHRC_HDL ,
54+ BR_OTA_FW_DATA_ATT_HDL ,
55+ BR_OTA_FW_DATA_CHRC_HDL ,
56+ LAST_HDL = BR_OTA_FW_DATA_CHRC_HDL ,
4657 MAX_HDL ,
4758};
4859
4960static uint8_t br_grp_base_uuid [] = {0x00 , 0x9a , 0x79 , 0x76 , 0xa1 , 0x2f , 0x4b , 0x31 , 0xb0 , 0xfa , 0x80 , 0x51 , 0x56 , 0x0f , 0x83 , 0x56 };
5061
62+ static esp_ota_handle_t ota_hdl = 0 ;
63+ static const esp_partition_t * update_partition = NULL ;
5164static uint16_t max_mtu = 23 ;
5265static uint16_t mtu = 23 ;
5366static uint8_t power = 0 ;
54- static uint16_t out_ctrl_cfg_id = 0 ;
55- static uint16_t ctrl_offset = 0 ;
56- static uint16_t ctrl_cfg_id = 0 ;
67+ static uint16_t out_cfg_id = 0 ;
68+ static uint16_t in_cfg_offset = 0 ;
69+ static uint16_t in_cfg_id = 0 ;
70+
71+ static void bt_att_restart (void * arg ) {
72+ esp_restart ();
73+ }
5774
5875static void bt_att_cmd (uint16_t handle , uint8_t code , uint16_t len ) {
5976 uint16_t packet_len = (BT_HCI_H4_HDR_SIZE + BT_HCI_ACL_HDR_SIZE
@@ -206,8 +223,20 @@ static void bt_att_cmd_blueretro_char_read_type_rsp(uint16_t handle, uint16_t st
206223 else {
207224 rd_type_rsp -> data -> handle = start ;
208225 }
209- * data = BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE ;
210- data ++ ;
226+
227+ switch (rd_type_rsp -> data -> handle + 1 ) {
228+ case BR_API_VER_CHRC_HDL :
229+ * data ++ = BT_GATT_CHRC_READ ;
230+ break ;
231+ case BR_OTA_FW_CTRL_CHRC_HDL :
232+ case BR_OTA_FW_DATA_CHRC_HDL :
233+ * data ++ = BT_GATT_CHRC_WRITE ;
234+ break ;
235+ default :
236+ * data ++ = BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE ;
237+ break ;
238+ }
239+
211240 * (uint16_t * )data = rd_type_rsp -> data -> handle + 1 ;
212241 data += 2 ;
213242 memcpy (data , br_grp_base_uuid , sizeof (br_grp_base_uuid ));
@@ -270,12 +299,12 @@ static void bt_att_cmd_config_rd_rsp(uint16_t handle, uint8_t config_id, uint16_
270299 len = mtu - 1 ;
271300 }
272301
273- memcpy (bt_hci_pkt_tmp .att_data , (void * )& config .out_cfg [out_ctrl_cfg_id ] + offset , len );
302+ memcpy (bt_hci_pkt_tmp .att_data , (void * )& config .out_cfg [out_cfg_id ] + offset , len );
274303 }
275304 }
276305 else if (config_id == 4 ) {
277- uint32_t cfg_len = (sizeof (config .in_cfg [0 ]) - (ADAPTER_MAPPING_MAX * sizeof (config .in_cfg [0 ].map_cfg [0 ]) - config .in_cfg [ctrl_cfg_id ].map_size * sizeof (config .in_cfg [0 ].map_cfg [0 ])));
278- uint32_t sum_offset = ctrl_offset + offset ;
306+ uint32_t cfg_len = (sizeof (config .in_cfg [0 ]) - (ADAPTER_MAPPING_MAX * sizeof (config .in_cfg [0 ].map_cfg [0 ]) - config .in_cfg [in_cfg_id ].map_size * sizeof (config .in_cfg [0 ].map_cfg [0 ])));
307+ uint32_t sum_offset = in_cfg_offset + offset ;
279308 printf ("# Input config %d\n" , cfg_len );
280309 if (sum_offset > cfg_len || offset > ATT_MAX_LEN ) {
281310 len = 0 ;
@@ -291,7 +320,7 @@ static void bt_att_cmd_config_rd_rsp(uint16_t handle, uint8_t config_id, uint16_
291320 len = ATT_MAX_LEN - offset ;
292321 }
293322
294- memcpy (bt_hci_pkt_tmp .att_data , (void * )& config .in_cfg [ctrl_cfg_id ] + sum_offset , len );
323+ memcpy (bt_hci_pkt_tmp .att_data , (void * )& config .in_cfg [in_cfg_id ] + sum_offset , len );
295324 }
296325 }
297326 else {
@@ -347,9 +376,9 @@ static void bt_att_cmd_read_group_rsp(uint16_t handle, uint16_t start, uint16_t
347376 else {
348377 rd_grp_rsp -> len = 20 ;
349378
350- if (start <= BR_GRP_HDL && end >= BR_API_VER_CHRC_HDL ) {
379+ if (start <= BR_GRP_HDL && end >= LAST_HDL ) {
351380 gatt_data -> start_handle = BR_GRP_HDL ;
352- gatt_data -> end_handle = BR_API_VER_CHRC_HDL ;
381+ gatt_data -> end_handle = LAST_HDL ;
353382 memcpy (gatt_data -> value , br_grp_base_uuid , sizeof (br_grp_base_uuid ));
354383 len += rd_grp_rsp -> len ;
355384 }
@@ -380,6 +409,7 @@ static void bt_att_cmd_exec_wr_rsp(uint16_t handle) {
380409
381410void bt_att_set_le_max_mtu (uint16_t le_max_mtu ) {
382411 max_mtu = le_max_mtu ;
412+ printf ("# %s %d\n" , __FUNCTION__ , max_mtu );
383413}
384414
385415void bt_att_hdlr (struct bt_dev * device , struct bt_hci_pkt * bt_hci_acl_pkt , uint32_t len ) {
@@ -394,6 +424,7 @@ void bt_att_hdlr(struct bt_dev *device, struct bt_hci_pkt *bt_hci_acl_pkt, uint3
394424 else {
395425 mtu = max_mtu ;
396426 }
427+ printf ("# Set mtu %d\n" , mtu );
397428 bt_att_cmd_mtu_rsp (device -> acl_handle , mtu );
398429 break ;
399430 }
@@ -437,7 +468,7 @@ void bt_att_hdlr(struct bt_dev *device, struct bt_hci_pkt *bt_hci_acl_pkt, uint3
437468 bt_att_cmd_batt_char_read_type_rsp (device -> acl_handle );
438469 }
439470 /* BLUERETRO */
440- else if (start >= BATT_CHRC_HDL && start < BR_API_VER_CHRC_HDL && end >= BR_API_VER_CHRC_HDL ) {
471+ else if (start >= BATT_CHRC_HDL && start < LAST_HDL && end >= LAST_HDL ) {
441472 bt_att_cmd_blueretro_char_read_type_rsp (device -> acl_handle , start );
442473 }
443474 else {
@@ -521,8 +552,9 @@ void bt_att_hdlr(struct bt_dev *device, struct bt_hci_pkt *bt_hci_acl_pkt, uint3
521552 {
522553 struct bt_att_write_req * wr_req = (struct bt_att_write_req * )bt_hci_acl_pkt -> att_data ;
523554 uint16_t * data = (uint16_t * )wr_req -> value ;
524- uint32_t data_len = len - (BT_HCI_H4_HDR_SIZE + BT_HCI_ACL_HDR_SIZE + sizeof (struct bt_l2cap_hdr ) + sizeof (struct bt_att_hdr ));
525- printf ("# BT_ATT_OP_WRITE_REQ\n" );
555+ uint32_t att_len = len - (BT_HCI_H4_HDR_SIZE + BT_HCI_ACL_HDR_SIZE + sizeof (struct bt_l2cap_hdr ) + sizeof (struct bt_att_hdr ));
556+ uint32_t data_len = att_len - sizeof (wr_req -> handle );
557+ printf ("# BT_ATT_OP_WRITE_REQ len: %d\n" , data_len );
526558 switch (wr_req -> handle ) {
527559 case BR_GLBL_CFG_CHRC_HDL :
528560 printf ("# BR_GLBL_CFG_CHRC_HDL %04X\n" , wr_req -> handle );
@@ -531,23 +563,72 @@ void bt_att_hdlr(struct bt_dev *device, struct bt_hci_pkt *bt_hci_acl_pkt, uint3
531563 bt_att_cmd_wr_rsp (device -> acl_handle );
532564 break ;
533565 case BR_OUT_CFG_DATA_CHRC_HDL :
534- memcpy ((void * )& config .out_cfg [out_ctrl_cfg_id ], wr_req -> value , sizeof (config .out_cfg [0 ]));
566+ memcpy ((void * )& config .out_cfg [out_cfg_id ], wr_req -> value , sizeof (config .out_cfg [0 ]));
535567 config_update ();
536568 bt_att_cmd_wr_rsp (device -> acl_handle );
537569 break ;
538570 case BR_IN_CFG_DATA_CHRC_HDL :
539- memcpy ((void * )& config .in_cfg [ctrl_cfg_id ] , wr_req -> value , data_len );
571+ memcpy ((void * )& config .in_cfg [in_cfg_id ] + in_cfg_offset , wr_req -> value , data_len );
540572 config_update ();
541573 bt_att_cmd_wr_rsp (device -> acl_handle );
542574 break ;
543575 case BR_OUT_CFG_CTRL_CHRC_HDL :
544- out_ctrl_cfg_id = * data ;
576+ out_cfg_id = * data ;
545577 bt_att_cmd_wr_rsp (device -> acl_handle );
546578 break ;
547579 case BR_IN_CFG_CTRL_CHRC_HDL :
548- ctrl_cfg_id = * data ;
549- data ++ ;
550- ctrl_offset = * data ;
580+ in_cfg_id = * data ++ ;
581+ in_cfg_offset = * data ;
582+ bt_att_cmd_wr_rsp (device -> acl_handle );
583+ break ;
584+ case BR_OTA_FW_CTRL_CHRC_HDL :
585+ switch (wr_req -> value [0 ]) {
586+ case OTA_START :
587+ update_partition = esp_ota_get_next_update_partition (NULL );
588+ if (esp_ota_begin (update_partition , OTA_SIZE_UNKNOWN , & ota_hdl ) == 0 ) {
589+ printf ("# OTA FW Update started...\n" );
590+ }
591+ else {
592+ esp_ota_abort (ota_hdl );
593+ ota_hdl = 0 ;
594+ printf ("# OTA FW Update start fail\n" );
595+ }
596+ break ;
597+ case OTA_END :
598+ if (esp_ota_end (ota_hdl ) == 0 ) {
599+ if (esp_ota_set_boot_partition (update_partition ) == 0 ) {
600+ ota_hdl = 0 ;
601+ const esp_timer_create_args_t ota_restart_args = {
602+ .callback = & bt_att_restart ,
603+ .arg = (void * )device ,
604+ .name = "ota_restart"
605+ };
606+ esp_timer_handle_t timer_hdl ;
607+
608+ esp_timer_create (& ota_restart_args , & timer_hdl );
609+ esp_timer_start_once (timer_hdl , 1000000 );
610+ printf ("# OTA FW Update sucessfull! Restarting...\n" );
611+ }
612+ else {
613+ printf ("# OTA FW Update set partition fail\n" );
614+ }
615+ }
616+ else {
617+ printf ("# OTA FW Update end fail\n" );
618+ }
619+ break ;
620+ default :
621+ if (ota_hdl ) {
622+ esp_ota_abort (ota_hdl );
623+ ota_hdl = 0 ;
624+ printf ("# OTA FW Update abort from WebUI\n" );
625+ }
626+ break ;
627+ }
628+ bt_att_cmd_wr_rsp (device -> acl_handle );
629+ break ;
630+ case BR_OTA_FW_DATA_CHRC_HDL :
631+ esp_ota_write (ota_hdl , wr_req -> value , data_len );
551632 bt_att_cmd_wr_rsp (device -> acl_handle );
552633 break ;
553634 default :
@@ -559,12 +640,17 @@ void bt_att_hdlr(struct bt_dev *device, struct bt_hci_pkt *bt_hci_acl_pkt, uint3
559640 case BT_ATT_OP_PREPARE_WRITE_REQ :
560641 {
561642 struct bt_att_prepare_write_req * prep_wr_req = (struct bt_att_prepare_write_req * )bt_hci_acl_pkt -> att_data ;
562- uint32_t data_len = len - (BT_HCI_H4_HDR_SIZE + BT_HCI_ACL_HDR_SIZE + sizeof (struct bt_l2cap_hdr ) + sizeof (struct bt_att_hdr ));
563- printf ("# BT_ATT_OP_PREPARE_WRITE_REQ %d %d\n" , len , data_len );
643+ uint32_t att_len = len - (BT_HCI_H4_HDR_SIZE + BT_HCI_ACL_HDR_SIZE + sizeof (struct bt_l2cap_hdr ) + sizeof (struct bt_att_hdr ));
644+ uint32_t data_len = att_len - (sizeof (prep_wr_req -> handle ) + sizeof (prep_wr_req -> offset ));
645+ printf ("# BT_ATT_OP_PREPARE_WRITE_REQ len: %d offset: %d\n" , data_len , prep_wr_req -> offset );
564646 switch (prep_wr_req -> handle ) {
565647 case BR_IN_CFG_DATA_CHRC_HDL :
566- memcpy ((void * )& config .in_cfg [ctrl_cfg_id ] + ctrl_offset + prep_wr_req -> offset , prep_wr_req -> value , data_len );
567- bt_att_cmd_prep_wr_rsp (device -> acl_handle , bt_hci_acl_pkt -> att_data , data_len );
648+ memcpy ((void * )& config .in_cfg [in_cfg_id ] + in_cfg_offset + prep_wr_req -> offset , prep_wr_req -> value , data_len );
649+ bt_att_cmd_prep_wr_rsp (device -> acl_handle , bt_hci_acl_pkt -> att_data , att_len );
650+ break ;
651+ case BR_OTA_FW_DATA_CHRC_HDL :
652+ esp_ota_write (ota_hdl , prep_wr_req -> value , data_len );
653+ bt_att_cmd_prep_wr_rsp (device -> acl_handle , bt_hci_acl_pkt -> att_data , att_len );
568654 break ;
569655 default :
570656 bt_att_cmd_error_rsp (device -> acl_handle , BT_ATT_OP_PREPARE_WRITE_REQ , prep_wr_req -> handle , BT_ATT_ERR_INVALID_HANDLE );
@@ -576,7 +662,7 @@ void bt_att_hdlr(struct bt_dev *device, struct bt_hci_pkt *bt_hci_acl_pkt, uint3
576662 {
577663 struct bt_att_exec_write_req * exec_wr_req = (struct bt_att_exec_write_req * )bt_hci_acl_pkt -> att_data ;
578664 printf ("# BT_ATT_OP_EXEC_WRITE_REQ\n" );
579- if (exec_wr_req -> flags == BT_ATT_FLAG_EXEC ) {
665+ if (! ota_hdl && exec_wr_req -> flags == BT_ATT_FLAG_EXEC ) {
580666 config_update ();
581667 }
582668 bt_att_cmd_exec_wr_rsp (device -> acl_handle );
0 commit comments