|
33 | 33 |
|
34 | 34 | #include <zephyr/bluetooth/bluetooth.h>
|
35 | 35 | #include <zephyr/bluetooth/hci.h>
|
| 36 | +#include <zephyr/bluetooth/gatt.h> |
| 37 | +#include <zephyr/bluetooth/uuid.h> |
36 | 38 | #include "extmod/modbluetooth.h"
|
37 | 39 |
|
38 | 40 | #define DEBUG_printf(...) // printk("BLE: " __VA_ARGS__)
|
@@ -279,19 +281,116 @@ int mp_bluetooth_gatts_register_service_begin(bool append) {
|
279 | 281 | // Don't support append yet (modbluetooth.c doesn't support it yet anyway).
|
280 | 282 | return MP_EOPNOTSUPP;
|
281 | 283 | }
|
282 |
| - |
283 | 284 | // Reset the gatt characteristic value db.
|
284 | 285 | mp_bluetooth_gatts_db_reset(MP_STATE_PORT(bluetooth_zephyr_root_pointers)->gatts_db);
|
285 | 286 |
|
286 |
| - return MP_EOPNOTSUPP; |
| 287 | + return 0; |
287 | 288 | }
|
288 | 289 |
|
289 | 290 | int mp_bluetooth_gatts_register_service_end(void) {
|
290 |
| - return MP_EOPNOTSUPP; |
| 291 | + return 0; |
| 292 | +} |
| 293 | +// struct bt_gatt_service { |
| 294 | +// /** Service Attributes */ |
| 295 | +// struct bt_gatt_attr *attrs; |
| 296 | +// /** Service Attribute count */ |
| 297 | +// size_t attr_count; |
| 298 | + |
| 299 | +// sys_snode_t node; |
| 300 | +// }; |
| 301 | +// struct bt_gatt_attr { |
| 302 | +// /** Attribute UUID */ |
| 303 | +// const struct bt_uuid *uuid; |
| 304 | +// bt_gatt_attr_read_func_t read; |
| 305 | +// /** Attribute write callback */ |
| 306 | +// bt_gatt_attr_write_func_t write; |
| 307 | +// /** Attribute user data */ |
| 308 | +// void *user_data; |
| 309 | +// /** Attribute handle */ |
| 310 | +// uint16_t handle; |
| 311 | +// /** @brief Attribute permissions. |
| 312 | +// * |
| 313 | +// * Will be 0 if returned from bt_gatt_discover(). |
| 314 | +// */ |
| 315 | +// uint16_t perm; |
| 316 | +// }; |
| 317 | + |
| 318 | +// Note: modbluetooth UUIDs store their data in LE. |
| 319 | +STATIC void *create_zephyr_uuid(const mp_obj_bluetooth_uuid_t *uuid) { |
| 320 | + if (uuid->type == MP_BLUETOOTH_UUID_TYPE_16) { |
| 321 | + struct bt_uuid_16 *result = m_new(struct bt_uuid_16, 1); |
| 322 | + result->uuid.type = BT_UUID_TYPE_16; |
| 323 | + result->val = (uuid->data[1] << 8) | uuid->data[0]; |
| 324 | + return (void *)result; |
| 325 | + } else if (uuid->type == MP_BLUETOOTH_UUID_TYPE_32) { |
| 326 | + struct bt_uuid_32 *result = m_new(struct bt_uuid_32, 1); |
| 327 | + result->uuid.type = BT_UUID_TYPE_32; |
| 328 | + result->val = (uuid->data[1] << 24) | (uuid->data[1] << 16) | (uuid->data[1] << 8) | uuid->data[0]; |
| 329 | + return (void *)result; |
| 330 | + } else if (uuid->type == MP_BLUETOOTH_UUID_TYPE_128) { |
| 331 | + struct bt_uuid_128 *result = m_new(struct bt_uuid_128, 1); |
| 332 | + result->uuid.type = BT_UUID_TYPE_128; |
| 333 | + memcpy(result->val, uuid->data, 16); |
| 334 | + return (void *)result; |
| 335 | + } else { |
| 336 | + return NULL; |
| 337 | + } |
291 | 338 | }
|
292 | 339 |
|
293 | 340 | int mp_bluetooth_gatts_register_service(mp_obj_bluetooth_uuid_t *service_uuid, mp_obj_bluetooth_uuid_t **characteristic_uuids, uint16_t *characteristic_flags, mp_obj_bluetooth_uuid_t **descriptor_uuids, uint16_t *descriptor_flags, uint8_t *num_descriptors, uint16_t *handles, size_t num_characteristics) {
|
294 |
| - return MP_EOPNOTSUPP; |
| 341 | + struct bt_gatt_service svc = {0}; |
| 342 | + svc.attr_count = num_characteristics; |
| 343 | + svc.attrs = m_new(struct bt_gatt_attr, num_characteristics + 1); |
| 344 | + size_t handle_index = 0; |
| 345 | + size_t descriptor_index = 0; |
| 346 | + |
| 347 | + for (size_t i = 0; i < num_characteristics; ++i) { |
| 348 | + svc.attrs[i].uuid = create_zephyr_uuid(characteristic_uuids[i]); |
| 349 | + //svc.attrs[i].read = characteristic_access_cb; |
| 350 | + //svc.attrs[i].write = characteristic_access_cb; |
| 351 | + svc.attrs[i].user_data = NULL; |
| 352 | + // NimBLE flags match the MP_BLUETOOTH_CHARACTERISTIC_FLAG_ ones exactly (including the security/privacy options). |
| 353 | + svc.attrs[i].perm = characteristic_flags[i]; |
| 354 | + //characteristics[i].min_key_size = 0; |
| 355 | + svc.attrs[i].handle = handles[handle_index]; |
| 356 | + ++handle_index; |
| 357 | + |
| 358 | + // if (num_descriptors[i] == 0) { |
| 359 | + // characteristics[i].descriptors = NULL; |
| 360 | + // } else { |
| 361 | + // struct ble_gatt_dsc_def *descriptors = m_new(struct ble_gatt_dsc_def, num_descriptors[i] + 1); |
| 362 | + |
| 363 | + // for (size_t j = 0; j < num_descriptors[i]; ++j) { |
| 364 | + // descriptors[j].uuid = create_nimble_uuid(descriptor_uuids[descriptor_index], NULL); |
| 365 | + // descriptors[j].access_cb = characteristic_access_cb; |
| 366 | + // // NimBLE doesn't support security/privacy options on descriptors. |
| 367 | + // descriptors[j].att_flags = (uint8_t)descriptor_flags[descriptor_index]; |
| 368 | + // descriptors[j].min_key_size = 0; |
| 369 | + // // Unlike characteristic, Nimble doesn't provide an au
10000
tomatic way to remember the handle, so use the arg. |
| 370 | + // descriptors[j].arg = &handles[handle_index]; |
| 371 | + // ++descriptor_index; |
| 372 | + // ++handle_index; |
| 373 | + // } |
| 374 | + // descriptors[num_descriptors[i]].uuid = NULL; // no more descriptors |
| 375 | + |
| 376 | + // characteristics[i].descriptors = descriptors; |
| 377 | + // } |
| 378 | + } |
| 379 | + // characteristics[num_characteristics].uuid = NULL; // no more characteristics |
| 380 | + |
| 381 | + // struct ble_gatt_svc_def *service = m_new(struct ble_gatt_svc_def, 2); |
| 382 | + // service[0].type = BLE_GATT_SVC_TYPE_PRIMARY; |
| 383 | + // service[0].uuid = create_nimble_uuid(service_uuid, NULL); |
| 384 | + // service[0].includes = NULL; |
| 385 | + // service[0].characteristics = characteristics; |
| 386 | + // service[1].type = 0; // no more services |
| 387 | + |
| 388 | + int ret = bt_gatt_service_register(&svc); |
| 389 | + if (ret != 0) { |
| 390 | + return bt_err_to_errno(ret); |
| 391 | + } |
| 392 | + |
| 393 | + return 0; |
295 | 394 | }
|
296 | 395 |
|
297 | 396 | int mp_bluetooth_gap_disconnect(uint16_t conn_handle) {
|
|
0 commit comments