@@ -166,7 +166,7 @@ STATIC void btstack_remove_pending_operation(mp_btstack_pending_op_t *pending_op
166
166
167
167
// Register a pending background operation -- copies the buffer, and makes it known to the GC.
168
168
STATIC 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 );
170
170
mp_btstack_pending_op_t * pending_op = m_new_obj_var (mp_btstack_pending_op_t , uint8_t , len );
171
171
pending_op -> op_type = op_type ;
172
172
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
1079
1079
return mp_bluetooth_gatts_db_write (MP_STATE_PORT (bluetooth_btstack_root_pointers )-> gatts_db , value_handle , value , value_len );
1080
1080
}
1081
1081
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
+
1082
1118
int 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 );
1084
1120
1085
1121
if (!mp_bluetooth_is_active ()) {
1086
1122
return ERRNO_BLUETOOTH_NOT_ACTIVE ;
@@ -1107,10 +1143,33 @@ int mp_bluetooth_gatts_notify_indicate(uint16_t conn_handle, uint16_t value_hand
1107
1143
}
1108
1144
MICROPY_PY_BLUETOOTH_EXIT
1109
1145
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
1112
1169
1113
- // TODO: re-implement the handling for this.
1170
+ if (err != ERROR_CODE_SUCCESS ) {
1171
+ m_tracked_free (pending_op );
1172
+ }
1114
1173
}
1115
1174
1116
1175
return btstack_error_to_errno (err );
0 commit comments