@@ -130,8 +130,6 @@ STATIC mp_obj_bluetooth_uuid_t create_mp_uuid(uint16_t uuid16, const uint8_t *uu
130130// Pending operation types.
131131enum {
132132 // Queued for sending when possible.
133- MP_BLUETOOTH_BTSTACK_PENDING_NOTIFY , // Waiting for context callback
134- MP_BLUETOOTH_BTSTACK_PENDING_INDICATE , // Waiting for context callback
135133 MP_BLUETOOTH_BTSTACK_PENDING_WRITE_NO_RESPONSE , // Waiting for conn handle
136134 // Hold buffer pointer until complete.
137135 MP_BLUETOOTH_BTSTACK_PENDING_WRITE , // Waiting for write done event
@@ -150,11 +148,7 @@ struct _mp_btstack_pending_op_t {
150148 uint16_t conn_handle ;
151149 uint16_t value_handle ;
152150
153- // For notify/indicate only.
154- // context_registration.context will point back to this struct.
155- btstack_context_callback_registration_t context_registration ;
156-
157- // For notify/indicate/write-without-response, this is the actual buffer to send.
151+ // For write-without-response, this is the actual buffer to send.
158152 // For write-with-response, just holding onto the buffer for GC ref.
159153 size_t len ;
160154 uint8_t buf [];
@@ -170,30 +164,6 @@ STATIC void btstack_remove_pending_operation(mp_btstack_pending_op_t *pending_op
170164 }
171165}
172166
173- // Called in response to a gatts_notify/indicate being unable to complete, which then calls
174- // att_server_request_to_send_notification.
175- // We now have an opportunity to re-try the operation with an empty ACL buffer.
176- STATIC void btstack_notify_indicate_ready_handler (void * context ) {
177- MICROPY_PY_BLUETOOTH_ENTER
178- mp_btstack_pending_op_t * pending_op = (mp_btstack_pending_op_t * )context ;
179- DEBUG_printf ("btstack_notify_indicate_ready_handler op_type=%d conn_handle=%d value_handle=%d len=%zu\n" , pending_op -> op_type , pending_op -> conn_handle , pending_op -> value_handle , pending_op -> len );
180- if (pending_op -> op_type == MP_BLUETOOTH_BTSTACK_PENDING_NOTIFY ) {
181- int err = att_server_notify (pending_op -> conn_handle , pending_op -> value_handle , pending_op -> buf , pending_op -> len );
182- DEBUG_printf ("btstack_notify_indicate_ready_handler: sending notification err=%d\n" , err );
183- assert (err == ERROR_CODE_SUCCESS );
184- (void )err ;
185- } else {
186- assert (pending_op -> op_type == MP_BLUETOOTH_BTSTACK_PENDING_INDICATE );
187- int err = att_server_indicate (pending_op -> conn_handle , pending_op -> value_handle , NULL , 0 );
188- DEBUG_printf ("btstack_notify_indicate_ready_handler: sending indication err=%d\n" , err );
189- assert (err == ERROR_CODE_SUCCESS );
190- (void )err ;
191- }
192- // Can't free the pending op as we're in IRQ context. Leave it for the GC.
193- btstack_remove_pending_operation (pending_op , false /* del */ );
194- MICROPY_PY_BLUETOOTH_EXIT
195- }
196-
197167// Register a pending background operation -- copies the buffer, and makes it known to the GC.
198168STATIC 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 ) {
199169 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 );
@@ -204,11 +174,6 @@ STATIC mp_btstack_pending_op_t *btstack_enqueue_pending_operation(uint16_t op_ty
204174 pending_op -> len = len ;
205175 memcpy (pending_op -> buf , buf , len );
206176
207- if (op_type == MP_BLUETOOTH_BTSTACK_PENDING_NOTIFY || op_type == MP_BLUETOOTH_BTSTACK_PENDING_INDICATE ) {
208- pending_op -> context_registration .callback = & btstack_notify_indicate_ready_handler ;
209- pending_op -> context_registration .context = pending_op ;
210- }
211-
212177 MICROPY_PY_BLUETOOTH_ENTER
213178 bool added = btstack_linked_list_add (& MP_STATE_PORT (bluetooth_btstack_root_pointers )-> pending_ops , (btstack_linked_item_t * )pending_op );
214179 assert (added );
@@ -854,7 +819,7 @@ void mp_bluetooth_set_io_capability(uint8_t capability) {
854819#endif // MICROPY_PY_BLUETOOTH_ENABLE_PAIRING_BONDING
855820
856821size_t mp_bluetooth_gap_get_device_name (const uint8_t * * buf ) {
857- uint8_t * value = NULL ;
822+ const uint8_t * value = NULL ;
858823 size_t value_len = 0 ;
859824 mp_bluetooth_gatts_db_read (MP_STATE_PORT (bluetooth_btstack_root_pointers )-> gatts_db , BTSTACK_GAP_DEVICE_NAME_HANDLE , & value , & value_len );
860825 * buf = value ;
@@ -1095,7 +1060,7 @@ int mp_bluetooth_gatts_register_service_end(void) {
10951060 return 0 ;
10961061}
10971062
1098- int mp_bluetooth_gatts_read (uint16_t value_handle , uint8_t * * value , size_t * value_len ) {
1063+ int mp_bluetooth_gatts_read (uint16_t value_handle , const uint8_t * * value , size_t * value_len ) {
10991064 DEBUG_printf ("mp_bluetooth_gatts_read\n" );
11001065 if (!mp_bluetooth_is_active ()) {
11011066 return ERRNO_BLUETOOTH_NOT_ACTIVE ;
@@ -1114,85 +1079,41 @@ int mp_bluetooth_gatts_write(uint16_t value_handle, const uint8_t *value, size_t
11141079 return mp_bluetooth_gatts_db_write (MP_STATE_PORT (bluetooth_btstack_root_pointers )-> gatts_db , value_handle , value , value_len );
11151080}
11161081
1117- int mp_bluetooth_gatts_notify (uint16_t conn_handle , uint16_t value_handle ) {
1118- DEBUG_printf ("mp_bluetooth_gatts_notify \n" );
1082+ 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" );
11191084
11201085 if (!mp_bluetooth_is_active ()) {
11211086 return ERRNO_BLUETOOTH_NOT_ACTIVE ;
11221087 }
11231088
1124- // Note: btstack doesn't appear to support sending a notification without a value, so include the stored value.
1125- uint8_t * data = NULL ;
1126- size_t len = 0 ;
1127- mp_bluetooth_gatts_db_read (MP_STATE_PORT (bluetooth_btstack_root_pointers )-> gatts_db , value_handle , & data , & len );
1128- return mp_bluetooth_gatts_notify_send (conn_handle , value_handle , data , len );
1129- }
1130-
1131- int mp_bluetooth_gatts_notify_send (uint16_t conn_handle , uint16_t value_handle , const uint8_t * value , size_t value_len ) {
1132- DEBUG_printf ("mp_bluetooth_gatts_notify_send\n" );
1133-
1134- if (!mp_bluetooth_is_active ()) {
1135- return ERRNO_BLUETOOTH_NOT_ACTIVE ;
1089+ if (!value ) {
1090+ // NULL value means "use DB value".
1091+ mp_bluetooth_gatts_db_read (MP_STATE_PORT (bluetooth_btstack_root_pointers )-> gatts_db , value_handle , & value , & value_len );
11361092 }
11371093
1094+ int err = ERROR_CODE_UNKNOWN_HCI_COMMAND ;
1095+
11381096 // Attempt to send immediately. If it succeeds, btstack will copy the buffer.
11391097 MICROPY_PY_BLUETOOTH_ENTER
1140- int err = att_server_notify (conn_handle , value_handle , value , value_len );
1141- MICROPY_PY_BLUETOOTH_EXIT
1142-
1143- if (err == BTSTACK_ACL_BUFFERS_FULL ) {
1144- DEBUG_printf ("mp_bluetooth_gatts_notify_send: ACL buffer full, scheduling callback\n" );
1145- // Schedule callback, making a copy of the buffer.
1146- mp_btstack_pending_op_t * pending_op = btstack_enqueue_pending_operation (MP_BLUETOOTH_BTSTACK_PENDING_NOTIFY , conn_handle , value_handle , value , value_len );
1147-
1148- err = att_server_request_to_send_notification (& pending_op -> context_registration , conn_handle );
1149-
1150- if (err != ERROR_CODE_SUCCESS ) {
1151- // Failure. Unref and free the pending operation.
1152- btstack_remove_pending_operation (pending_op , true /* del */ );
1153- }
1154-
1155- return 0 ;
1156- } else {
1157- return btstack_error_to_errno (err );
1158- }
1159- }
1160-
1161- int mp_bluetooth_gatts_indicate (uint16_t conn_handle , uint16_t value_handle ) {
1162- DEBUG_printf ("mp_bluetooth_gatts_indicate\n" );
1163-
1164- if (!mp_bluetooth_is_active ()) {
1165- return ERRNO_BLUETOOTH_NOT_ACTIVE ;
1098+ switch (gatts_op ) {
1099+ case MP_BLUETOOTH_GATTS_OP_NOTIFY :
1100+ err = att_server_notify (conn_handle , value_handle , value , value_len );
1101+ break ;
1102+ case MP_BLUETOOTH_GATTS_OP_INDICATE :
1103+ // Indicate will raise ATT_EVENT_HANDLE_VALUE_INDICATION_COMPLETE when
1104+ // acknowledged (or timeout/error).
1105+ err = att_server_indicate (conn_handle , value_handle , value , value_len );
1106+ break ;
11661107 }
1167-
1168- uint8_t * data = NULL ;
1169- size_t len = 0 ;
1170- mp_bluetooth_gatts_db_read (MP_STATE_PORT (bluetooth_btstack_root_pointers )-> gatts_db , value_handle , & data , & len );
1171-
1172- // Indicate will raise ATT_EVENT_HANDLE_VALUE_INDICATION_COMPLETE when
1173- // acknowledged (or timeout/error).
1174-
1175- // Attempt to send immediately, will copy buffer.
1176- MICROPY_PY_BLUETOOTH_ENTER
1177- int err = att_server_indicate (conn_handle , value_handle , data , len );
11781108 MICROPY_PY_BLUETOOTH_EXIT
11791109
11801110 if (err == BTSTACK_ACL_BUFFERS_FULL ) {
1181- DEBUG_printf ("mp_bluetooth_gatts_indicate: ACL buffer full, scheduling callback\n" );
1182- // Schedule callback, making a copy of the buffer.
1183- mp_btstack_pending_op_t * pending_op = btstack_enqueue_pending_operation (MP_BLUETOOTH_BTSTACK_PENDING_INDICATE , conn_handle , value_handle , data , len );
1184-
1185- err = att_server_request_to_send_indication (& pending_op -> context_registration , conn_handle );
1186-
1187- if (err != ERROR_CODE_SUCCESS ) {
1188- // Failure. Unref and free the pending operation.
1189- btstack_remove_pending_operation (pending_op , true /* del */ );
1190- }
1111+ DEBUG_printf ("mp_bluetooth_gatts_notify_indicate: ACL buffer full, scheduling callback\n" );
11911112
1192- return 0 ;
1193- } else {
1194- return btstack_error_to_errno (err );
1113+ // TODO: re-implement the handling for this.
11951114 }
1115+
1116+ return btstack_error_to_errno (err );
11961117}
11971118
11981119int mp_bluetooth_gatts_set_buffer (uint16_t value_handle , size_t len , bool append ) {
0 commit comments