37
37
38
38
volatile int mp_bluetooth_btstack_state = MP_BLUETOOTH_BTSTACK_STATE_OFF ;
39
39
40
+ static btstack_packet_callback_registration_t hci_event_callback_registration ;
41
+
42
+ STATIC void att_server_packet_handler (uint8_t packet_type , uint16_t channel , uint8_t * packet , uint16_t size ) {
43
+ // printf("att_server_packet_handler: packet_type: %u, channel: %u, packet: %p, size: %u\n", packet_type, channel, packet, size);
44
+ if (packet_type == HCI_EVENT_PACKET ) {
45
+ uint8_t event_type = hci_event_packet_get_type (packet );
46
+ if (event_type == ATT_EVENT_CONNECTED ) {
47
+ printf (" --> att connected\n" );
48
+ } else if (event_type == ATT_EVENT_DISCONNECTED ) {
49
+ printf (" --> att disconnected\n" );
50
+ } else if (event_type == HCI_EVENT_LE_META ) {
51
+ printf (" --> att le meta\n" );
52
+ } else if (event_type == HCI_EVENT_DISCONNECTION_COMPLETE ) {
53
+ printf (" --> att disconnect complete\n" );
54
+ } else {
55
+ printf (" --> att type: unknown (%u)\n" , event_type );
56
+ }
57
+ }
58
+ }
59
+
60
+ STATIC void hci_packet_handler (uint8_t packet_type , uint16_t channel , uint8_t * packet , uint16_t size ) {
61
+ // printf("hci_packet_handler: packet_type: %u, channel: %u, packet: %p, size: %u\n", packet_type, channel, packet, size);
62
+ if (packet_type == HCI_EVENT_PACKET ) {
63
+ uint8_t event_type = hci_event_packet_get_type (packet );
64
+ if (event_type == HCI_EVENT_TRANSPORT_PACKET_SENT || event_type == HCI_EVENT_COMMAND_COMPLETE ) {
65
+ } else if (event_type == BTSTACK_EVENT_NR_CONNECTIONS_CHANGED ) {
66
+ printf (" --&
10000
gt; hci type: # conns changed\n" );
67
+ } else if (event_type == HCI_EVENT_VENDOR_SPECIFIC ) {
68
+ printf (" --> hci type: vendor specific\n" );
69
+ } else {
70
+ printf (" --> hci type: unknown (%u)\n" , event_type );
71
+ }
72
+ }
73
+ }
74
+
40
75
int mp_bluetooth_init (void ) {
41
76
btstack_memory_init ();
42
77
@@ -58,6 +93,15 @@ int mp_bluetooth_init(void) {
58
93
59
94
mp_bluetooth_btstack_port_start ();
60
95
mp_bluetooth_btstack_state = MP_BLUETOOTH_BTSTACK_STATE_ACTIVE ;
96
+
97
+ // Register for HCI events.
98
+ memset (& hci_event_callback_registration , 0 , sizeof (btstack_packet_callback_registration_t ));
99
+ hci_event_callback_registration .callback = & hci_packet_handler ;
100
+ hci_add_event_handler (& hci_event_callback_registration );
101
+
102
+ // Register for ATT event.
103
+ att_server_register_packet_handler (& att_server_packet_handler );
104
+
61
105
return 0 ;
62
106
}
63
107
@@ -118,14 +162,92 @@ void mp_bluetooth_gap_advertise_stop(void) {
118
162
}
119
163
120
164
int mp_bluetooth_gatts_register_service_begin (bool append ) {
165
+ if (!append ) {
166
+ // This will reset the DB.
167
+ // Becase the DB is statically allocated, there's no problem with just re-initing it.
168
+ // Note this would be a memory leak if we enabled HAVE_MALLOC (there's no API to free the existing db).
169
+ att_db_util_init ();
170
+
171
+ att_db_util_add_service_uuid16 (GAP_SERVICE_UUID );
172
+ att_db_util_add_characteristic_uuid16 (GAP_DEVICE_NAME_UUID , ATT_PROPERTY_READ , ATT_SECURITY_NONE , ATT_SECURITY_NONE , (uint8_t * )"MPY BTSTACK" , 11 );
173
+
174
+ att_db_util_add_service_uuid16 (0x1801 );
175
+ att_db_util_add_characteristic_uuid16 (0x2a05 , ATT_PROPERTY_READ , ATT_SECURITY_NONE , ATT_SECURITY_NONE , NULL , 0 );
176
+
177
+ }
178
+
179
+ return 0 ;
180
+ }
181
+
182
+ STATIC uint16_t att_read_callback (hci_con_handle_t connection_handle , uint16_t att_handle , uint16_t offset , uint8_t * buffer , uint16_t buffer_size ) {
183
+ printf ("btstack: att_read_callback (handle: %u, offset: %u, buffer: %p, size: %u)\n" , att_handle , offset , buffer , buffer_size );
184
+ return 0 ;
185
+ }
186
+
187
+ STATIC int att_write_callback (hci_con_handle_t connection_handle , uint16_t att_handle , uint16_t transaction_mode , uint16_t offset , uint8_t * buffer , uint16_t buffer_size ) {
188
+ printf ("btstack: att_write_callback (handle: %u, mode: %u, offset: %u, buffer: %p, size: %u)\n" , att_handle , transaction_mode , offset , buffer , buffer_size );
121
189
return 0 ;
122
190
}
123
191
192
+ // Note: modbluetooth UUIDs store their data in LE.
193
+ STATIC inline uint16_t get_uuid16 (const mp_obj_bluetooth_uuid_t * uuid ) {
194
+ return (uuid -> data [1 ] << 8 ) | uuid -> data [0 ];
195
+ }
196
+
124
197
int mp_bluetooth_gatts_register_service (mp_obj_bluetooth_uuid_t * service_uuid , mp_obj_bluetooth_uuid_t * * characteristic_uuids , uint8_t * characteristic_flags , mp_obj_bluetooth_uuid_t * * descriptor_uuids , uint8_t * descriptor_flags , uint8_t * num_descriptors , uint16_t * handles , size_t num_characteristics ) {
198
+ // TODO: It's not clear which endian btstack needs for uuids.
199
+
200
+ uint16_t service_handle ;
201
+ if (service_uuid -> type == MP_BLUETOOTH_UUID_TYPE_16 ) {
202
+ service_handle = att_db_util_add_service_uuid16 (get_uuid16 (service_uuid ));
203
+ } else if (service_uuid -> type == MP_BLUETOOTH_UUID_TYPE_128 ) {
204
+ service_handle = att_db_util_add_service_uuid128 (service_uuid -> data );
205
+ } else {
206
+ return MP_EINVAL ;
207
+ }
208
+
209
+ printf ("Registered service with handle %u\n" , service_handle );
210
+
211
+ size_t handle_index = 0 ;
212
+ size_t descriptor_index = 0 ;
213
+
214
+ for (size_t i = 0 ; i < num_characteristics ; ++ i ) {
215
+ uint16_t props = characteristic_flags [i ] | ATT_PROPERTY_DYNAMIC ;
216
+ uint16_t read_permission = ATT_SECURITY_NONE ;
217
+ uint16_t write_permission = ATT_SECURITY_NONE ;
218
+ if (characteristic_uuids [i ]-> type == MP_BLUETOOTH_UUID_TYPE_16 ) {
219
+ handles [handle_index ] = att_db_util_add_characteristic_uuid16 (get_uuid16 (characteristic_uuids [i ]), props , read_permission , write_permission , NULL , 0 );
220
+ } else if (characteristic_uuids [i ]-> type == MP_BLUETOOTH_UUID_TYPE_128 ) {
221
+ handles [handle_index ] = att_db_util_add_characteristic_uuid128 (characteristic_uuids [i ]-> data , props , read_permission , write_permission , NULL , 0 );
222
+ } else {
223
+ return MP_EINVAL ;
224
+ }
225
+ printf ("Registered char with handle %u\n" , handles [handle_index ]);
226
+ ++ handle_index ;
227
+
228
+ for (size_t j = 0 ; j < num_descriptors [i ]; ++ j ) {
229
+ uint16_t props = descriptor_flags [descriptor_index ] | ATT_PROPERTY_DYNAMIC ;
230
+ uint16_t read_permission = ATT_SECURITY_NONE ;
231
+ uint16_t write_permission = ATT_SECURITY_NONE ;
232
+
233
+ if (descriptor_uuids [descriptor_index ]-> type == MP_BLUETOOTH_UUID_TYPE_16 ) {
234
+ handles [handle_index ] = att_db_util_add_descriptor_uuid16 (get_uuid16 (descriptor_uuids [descriptor_index ]), props , read_permission , write_permission , NULL , 0 );
235
+ } else if (descriptor_uuids [descriptor_index ]-> type == MP_BLUETOOTH_UUID_TYPE_128 ) {
236
+ handles [handle_index ] = att_db_util_add_descriptor_uuid128 (descriptor_uuids [descriptor_index ]-> data , props , read_permission , write_permission , NULL , 0 );
237
+ } else {
238
+ return MP_EINVAL ;
239
+ }
240
+ printf ("Registered desc with handle %u\n" , handles [handle_index ]);
241
+ ++ descriptor_index ;
242
+ ++ handle_index ;
243
+ }
244
+ }
245
+
125
246
return 0 ;
126
247
}
127
248
128
249
int mp_bluetooth_gatts_register_service_end (void ) {
250
+ att_server_init (att_db_util_get_address (), & att_read_callback , & att_write_callback );
129
251
return 0 ;
130
252
}
131
253
0 commit comments