7272#define MOD_BT_GATTC_NOTIFY_EVT (0x0020)
7373#define MOD_BT_GATTC_INDICATE_EVT (0x0040)
7474#define MOD_BT_GATTS_SUBSCRIBE_EVT (0x0080)
75+ #define MOD_BT_GATTC_MTU_EVT (0x0100)
76+ #define MOD_BT_GATTS_MTU_EVT (0x0200)
7577
7678/******************************************************************************
7779 DEFINE PRIVATE TYPES
7880 ******************************************************************************/
7981typedef struct {
8082 mp_obj_base_t base ;
8183 int32_t scan_duration ;
84+ uint8_t gatts_mtu ;
8285 mp_obj_t handler ;
8386 mp_obj_t handler_arg ;
8487 esp_bd_addr_t client_bda ;
@@ -100,6 +103,7 @@ typedef struct {
100103 mp_obj_list_t srv_list ;
101104 esp_bd_addr_t srv_bda ;
102105 int32_t conn_id ;
106+ uint16_t mtu ;
103107 esp_gatt_if_t gatt_if ;
104108} bt_connection_obj_t ;
105109
@@ -245,7 +249,8 @@ static bool mod_bt_is_deinit;
245249static bool mod_bt_is_conn_restore_available ;
246250
247251static uint8_t tx_pwr_level_to_dbm [] = {-12 , -9 , -6 , -3 , 0 , 3 , 6 , 9 };
248-
252+ static EventGroupHandle_t bt_event_group ;
253+ static uint16_t bt_conn_mtu = 0 ;
249254/******************************************************************************
250255 DECLARE PRIVATE FUNCTIONS
251256 ******************************************************************************/
@@ -276,6 +281,16 @@ void modbt_init0(void) {
276281 } else {
277282 xQueueReset (xGattsQueue );
278283 }
284+ if (!bt_event_group )
285+ {
286+ bt_event_group = xEventGroupCreate ();
287+ }
288+ else
289+ {
290+ //Using only MTU event in group for now
291+ xEventGroupClearBits (bt_event_group , MOD_BT_GATTC_MTU_EVT | MOD_BT_GATTS_MTU_EVT );
292+ }
293+ bt_event_group = xEventGroupCreate ();
279294
280295 if (bt_obj .init ) {
281296 esp_ble_gattc_app_unregister (MOD_BT_CLIENT_APP_ID );
@@ -538,6 +553,8 @@ static void gattc_events_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc
538553 case ESP_GATTC_CFG_MTU_EVT :
539554 // connection process and MTU request complete
540555 bt_obj .busy = false;
556+ bt_conn_mtu = p_data -> cfg_mtu .mtu ;
557+ xEventGroupSetBits (bt_event_group , MOD_BT_GATTC_MTU_EVT );
541558 break ;
542559 case ESP_GATTC_READ_CHAR_EVT :
543560 if (p_data -> read .status == ESP_GATT_OK ) {
@@ -595,10 +612,9 @@ static void gattc_events_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc
595612 break ;
596613 }
597614 case ESP_GATTC_SEARCH_CMPL_EVT :
598- bt_obj .busy = false;
599- break ;
600615 case ESP_GATTC_CANCEL_OPEN_EVT :
601616 bt_obj .busy = false;
617+ break ;
602618 // intentional fall through
603619 case ESP_GATTC_CLOSE_EVT :
604620 case ESP_GATTC_DISCONNECT_EVT :
@@ -743,8 +759,11 @@ static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_
743759 }
744760 break ;
745761 }
746- case ESP_GATTS_EXEC_WRITE_EVT :
747762 case ESP_GATTS_MTU_EVT :
763+ bt_obj .gatts_mtu = p -> mtu .mtu ;
764+ xEventGroupSetBits (bt_event_group , MOD_BT_GATTS_MTU_EVT );
765+ break ;
766+ case ESP_GATTS_EXEC_WRITE_EVT :
748767 case ESP_GATTS_CONF_EVT :
749768 case ESP_GATTS_UNREG_EVT :
750769 break ;
@@ -792,6 +811,7 @@ static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_
792811 break ;
793812 case ESP_GATTS_DISCONNECT_EVT :
794813 bt_obj .gatts_conn_id = -1 ;
814+ xEventGroupClearBits (bt_event_group , MOD_BT_GATTS_MTU_EVT );
795815 if (bt_obj .advertising ) {
796816 if (!bt_obj .secure ){
797817 esp_ble_gap_start_advertising (& bt_adv_params );
@@ -845,7 +865,16 @@ static mp_obj_t bt_init_helper(bt_obj_t *self, const mp_arg_val_t *args) {
845865 esp_ble_gattc_app_register (MOD_BT_CLIENT_APP_ID );
846866 esp_ble_gatts_app_register (MOD_BT_SERVER_APP_ID );
847867
848- esp_ble_gatt_set_local_mtu (BT_MTU_SIZE_MAX );
868+ //set MTU
869+ uint16_t mtu = args [5 ].u_int ;
870+ if (mtu > BT_MTU_SIZE_MAX )
871+ {
872+ esp_ble_gatt_set_local_mtu (BT_MTU_SIZE_MAX );
873+ }
874+ else
875+ {
876+ esp_ble_gatt_set_local_mtu (mtu );
877+ }
849878
850879 self -> init = true;
851880 }
@@ -896,6 +925,7 @@ STATIC const mp_arg_t bt_init_args[] = {
896925 { MP_QSTR_modem_sleep , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
897926 { MP_QSTR_secure , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = false} },
898927 { MP_QSTR_io_cap , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = ESP_IO_CAP_NONE } },
928+ { MP_QSTR_mtu , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = BT_MTU_SIZE_MAX } },
899929
900930};
901931STATIC mp_obj_t bt_make_new (const mp_obj_type_t * type , mp_uint_t n_args , mp_uint_t n_kw , const mp_obj_t * all_args ) {
@@ -1173,6 +1203,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bt_events_obj, bt_events);
11731203static mp_obj_t bt_connect_helper (mp_obj_t addr , TickType_t timeout ){
11741204
11751205 bt_event_result_t bt_event ;
1206+ EventBits_t uxBits ;
11761207
11771208 if (bt_obj .busy ) {
11781209 nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , "operation already in progress" ));
@@ -1194,6 +1225,7 @@ static mp_obj_t bt_connect_helper(mp_obj_t addr, TickType_t timeout){
11941225 if (ESP_OK != esp_ble_gattc_open (bt_obj .gattc_if , bufinfo .buf , BLE_ADDR_TYPE_PUBLIC , true)) {
11951226 nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , mpexception_os_operation_failed ));
11961227 }
1228+ MP_THREAD_GIL_EXIT ();
11971229 if (xQueueReceive (xScanQueue , & bt_event , timeout ) == pdTRUE )
11981230 {
11991231 if (bt_event .connection .conn_id < 0 ) {
@@ -1205,6 +1237,11 @@ static mp_obj_t bt_connect_helper(mp_obj_t addr, TickType_t timeout){
12051237 conn -> base .type = (mp_obj_t )& mod_bt_connection_type ;
12061238 conn -> conn_id = bt_event .connection .conn_id ;
12071239 conn -> gatt_if = bt_event .connection .gatt_if ;
1240+ uxBits = xEventGroupWaitBits (bt_event_group , MOD_BT_GATTC_MTU_EVT , true, true, 1000 /portTICK_PERIOD_MS );
1241+ if (uxBits & MOD_BT_GATTC_MTU_EVT )
1242+ {
1243+ conn -> mtu = bt_conn_mtu ;
1244+ }
12081245 memcpy (conn -> srv_bda , bt_event .connection .srv_bda , 6 );
12091246 mp_obj_list_append ((void * )& MP_STATE_PORT (btc_conn_list ), conn );
12101247 return conn ;
@@ -1214,7 +1251,7 @@ static mp_obj_t bt_connect_helper(mp_obj_t addr, TickType_t timeout){
12141251 (void )esp_ble_gap_disconnect (bufinfo .buf );
12151252 nlr_raise (mp_obj_new_exception_msg (& mp_type_TimeoutError , "timed out" ));
12161253 }
1217-
1254+ MP_THREAD_GIL_ENTER ();
12181255 return mp_const_none ;
12191256}
12201257
@@ -1826,6 +1863,37 @@ STATIC mp_obj_t bt_tx_power(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t
18261863}
18271864STATIC MP_DEFINE_CONST_FUN_OBJ_KW (bt_tx_power_obj , 2 , bt_tx_power );
18281865
1866+ STATIC mp_obj_t bt_conn_get_mtu (mp_obj_t self_in ) {
1867+
1868+ bt_connection_obj_t * self = (bt_connection_obj_t * )self_in ;
1869+
1870+ if (self -> conn_id >= 0 )
1871+ {
1872+ return mp_obj_new_int (self -> mtu );
1873+ }
1874+ return mp_const_none ;
1875+ }
1876+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (bt_conn_get_mtu_obj , bt_conn_get_mtu );
1877+
1878+ STATIC mp_obj_t bt_gatts_get_mtu (mp_obj_t self_in ) {
1879+
1880+ bt_obj_t * self = (bt_obj_t * )self_in ;
1881+ EventBits_t uxBits ;
1882+
1883+ if (self -> gatts_conn_id >= 0 )
1884+ {
1885+ MP_THREAD_GIL_EXIT ();
1886+ uxBits = xEventGroupWaitBits (bt_event_group , MOD_BT_GATTS_MTU_EVT , true, true, 1000 /portTICK_PERIOD_MS );
1887+ MP_THREAD_GIL_ENTER ();
1888+ if (uxBits & MOD_BT_GATTS_MTU_EVT )
1889+ {
1890+ return mp_obj_new_int (self -> gatts_mtu );
1891+ }
1892+ }
1893+ return mp_const_none ;
1894+ }
1895+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (bt_gatts_get_mtu_obj , bt_gatts_get_mtu );
1896+
18291897STATIC const mp_map_elem_t bt_locals_dict_table [] = {
18301898 // instance methods
18311899 { MP_OBJ_NEW_QSTR (MP_QSTR_init ), (mp_obj_t )& bt_init_obj },
@@ -1847,6 +1915,7 @@ STATIC const mp_map_elem_t bt_locals_dict_table[] = {
18471915 { MP_OBJ_NEW_QSTR (MP_QSTR_disconnect_client ), (mp_obj_t )& bt_gatts_disconnect_client_obj },
18481916 { MP_OBJ_NEW_QSTR (MP_QSTR_modem_sleep ), (mp_obj_t )& bt_modem_sleep_obj },
18491917 { MP_OBJ_NEW_QSTR (MP_QSTR_tx_power ), (mp_obj_t )& bt_tx_power_obj },
1918+ { MP_OBJ_NEW_QSTR (MP_QSTR_gatts_mtu ), (mp_obj_t )& bt_gatts_get_mtu_obj },
18501919
18511920
18521921 // exceptions
@@ -2019,6 +2088,7 @@ STATIC const mp_map_elem_t bt_connection_locals_dict_table[] = {
20192088 { MP_OBJ_NEW_QSTR (MP_QSTR_isconnected ), (mp_obj_t )& bt_conn_isconnected_obj },
20202089 { MP_OBJ_NEW_QSTR (MP_QSTR_disconnect ), (mp_obj_t )& bt_conn_disconnect_obj },
20212090 { MP_OBJ_NEW_QSTR (MP_QSTR_services ), (mp_obj_t )& bt_conn_services_obj },
2091+ { MP_OBJ_NEW_QSTR (MP_QSTR_get_mtu ), (mp_obj_t )& bt_conn_get_mtu_obj },
20222092
20232093};
20242094STATIC MP_DEFINE_CONST_DICT (bt_connection_locals_dict , bt_connection_locals_dict_table );
0 commit comments