@@ -166,7 +166,7 @@ STATIC void btstack_remove_pending_operation(mp_btstack_pending_op_t *pending_op
166166
167167// Register a pending background operation -- copies the buffer, and makes it known to the GC.
168168STATIC mp_btstack_pending_op_t * btstack_enqueue_pending_operation (uint16_t op_type , uint16_t conn_handle , uint16_t value_handle , const uint8_t * buf , size_t len ) {
169- DEBUG_printf ("btstack_enqueue_pending_operation op_type=%d conn_handle=%d value_handle=%d len=%zu \n" , op_type , conn_handle , value_handle , len );
169+ DEBUG_printf ("btstack_enqueue_pending_operation op_type=%d conn_handle=%d value_handle=%d len=%lu \n" , op_type , conn_handle , value_handle , len );
170170 mp_btstack_pending_op_t * pending_op = m_new_obj_var (mp_btstack_pending_op_t , uint8_t , len );
171171 pending_op -> op_type = op_type ;
172172 pending_op -> conn_handle = conn_handle ;
@@ -1079,8 +1079,44 @@ int mp_bluetooth_gatts_write(uint16_t value_handle, const uint8_t *value, size_t
10791079 return mp_bluetooth_gatts_db_write (MP_STATE_PORT (bluetooth_btstack_root_pointers )-> gatts_db , value_handle , value , value_len );
10801080}
10811081
1082+ #if !MICROPY_TRACKED_ALLOC
1083+ #error "btstack requires MICROPY_TRACKED_ALLOC"
1084+ #endif
1085+
1086+ typedef struct {
1087+ btstack_context_callback_registration_t btstack_registration ;
1088+ int gatts_op ;
1089+ uint16_t conn_handle ;
1090+ uint16_t value_handle ;
1091+ size_t value_len ;
1092+ uint8_t value [];
1093+ } notify_indicate_pending_op_t ;
1094+
1095+ // Called in response to a gatts_notify/indicate being unable to complete, which then calls
1096+ // att_server_request_to_send_notification.
1097+ STATIC void btstack_notify_indicate_ready_handler (void * context ) {
1098+ MICROPY_PY_BLUETOOTH_ENTER
1099+ notify_indicate_pending_op_t * pending_op = (notify_indicate_pending_op_t * )context ;
1100+ DEBUG_printf ("btstack_notify_indicate_ready_handler gatts_op=%d conn_handle=%d value_handle=%d len=%lu\n" , pending_op -> gatts_op , pending_op -> conn_handle , pending_op -> value_handle , pending_op -> value_len );
1101+ int err = ERROR_CODE_SUCCESS ;
1102+ switch (pending_op -> gatts_op ) {
1103+ case MP_BLUETOOTH_GATTS_OP_NOTIFY :
1104+ err = att_server_notify (pending_op -> conn_handle , pending_op -> value_handle , pending_op -> value , pending_op -> value_len );
1105+ DEBUG_printf ("btstack_notify_indicate_ready_handler: sending notification err=%d\n" , err );
1106+ break ;
1107+ case MP_BLUETOOTH_GATTS_OP_INDICATE :
1108+ err = att_server_indicate (pending_op -> conn_handle , pending_op -> value_handle , pending_op -> value , pending_op -> value_len );
1109+ DEBUG_printf ("btstack_notify_indicate_ready_handler: sending indication err=%d\n" , err );
1110+ break ;
1111+ }
1112+ assert (err == ERROR_CODE_SUCCESS );
1113+ (void )err ;
1114+ MICROPY_PY_BLUETOOTH_EXIT
1115+ m_tracked_free (pending_op );
1116+ }
1117+
10821118int mp_bluetooth_gatts_notify_indicate (uint16_t conn_handle , uint16_t value_handle , int gatts_op , const uint8_t * value , size_t value_len ) {
1083- DEBUG_printf ("mp_bluetooth_gatts_notify_indicate\n" );
1119+ DEBUG_printf ("mp_bluetooth_gatts_notify_indicate: gatts_op=%d \n" , gatts_op );
10841120
10851121 if (!mp_bluetooth_is_active ()) {
10861122 return ERRNO_BLUETOOTH_NOT_ACTIVE ;
@@ -1107,10 +1143,33 @@ int mp_bluetooth_gatts_notify_indicate(uint16_t conn_handle, uint16_t value_hand
11071143 }
11081144 MICROPY_PY_BLUETOOTH_EXIT
11091145
1110- if (err == BTSTACK_ACL_BUFFERS_FULL ) {
1111- DEBUG_printf ("mp_bluetooth_gatts_notify_indicate: ACL buffer full, scheduling callback\n" );
1146+ if (err == BTSTACK_ACL_BUFFERS_FULL || err == ATT_HANDLE_VALUE_INDICATION_IN_PROGRESS ) {
1147+ DEBUG_printf ("mp_bluetooth_gatts_notify_indicate: ACL buffer full / indication in progress, scheduling callback\n" );
1148+
1149+ // Copy the value and ask btstack to let us know when it can be sent.
1150+ notify_indicate_pending_op_t * pending_op = m_tracked_calloc (1 , sizeof (notify_indicate_pending_op_t ) + value_len );
1151+ pending_op -> btstack_registration .context = pending_op ;
1152+ pending_op -> btstack_registration .callback = & btstack_notify_indicate_ready_handler ;
1153+ pending_op -> gatts_op = gatts_op ;
1154+ pending_op -> conn_handle = conn_handle ;
1155+ pending_op -> value_handle = value_handle ;
1156+ pending_op -> value_len = value_len ;
1157+ memcpy (pending_op -> value , value , value_len );
1158+
1159+ MICROPY_PY_BLUETOOTH_ENTER
1160+ switch (gatts_op ) {
1161+ case MP_BLUETOOTH_GATTS_OP_NOTIFY :
1162+ err = att_server_request_to_send_notification (& pending_op -> btstack_registration , conn_handle );
1163+ break ;
1164+ case MP_BLUETOOTH_GATTS_OP_INDICATE :
1165+ err = att_server_request_to_send_indication (& pending_op -> btstack_registration , conn_handle );
1166+ break ;
1167+ }
1168+ MICROPY_PY_BLUETOOTH_EXIT
11121169
1113- // TODO: re-implement the handling for this.
1170+ if (err != ERROR_CODE_SUCCESS ) {
1171+ m_tracked_free (pending_op );
1172+ }
11141173 }
11151174
11161175 return btstack_error_to_errno (err );
0 commit comments