Is it possible to create a GATT table using variables instead of hard coding attributes; Failing to register service and characteristics statically using bt_gatt_service_register

I'm currently attempting to register a service and it's subsequent characteristics statically using variables and not hard coded GATT tabel , I can successfully register an  struct  array of service UUIDs when I use the macro 

BT_GATT_PRIMARY_SERVICE, below is the code that I was using 
 // generating UUID struct from array and registering service
for (int i = 0; i < 3; i++) {
  printk("\n serv no:\n");
  fnInitUuid128(&uuids_struct[i], uuid_bytesArray[i]);
  attrs[i] = (struct bt_gatt_attr)BT_GATT_PRIMARY_SERVICE(&uuids_struct[i]);
  services[i] = (struct bt_gatt_service) { .attrs = &attrs[i], .attr_count = 1 };
  int result = bt_gatt_service_register(&services[i]);
  if (result) {
    LOG_ERR("Failed to register service %d (err %d)", i, result);
  }else {
    LOG_INF("Service %d registered successfully result %d", i,result);
    }
  }
Each service is successfully registered as the error message returned is zero and the services appear on the nrf connect mobile app.  But when I attempt to register a single service and characteristic using the macro BT_GATT_CHARACTERISTIC in the code below:
    int serv_uuid=0;
    int characteristic_uuid=1;
    printk("\n serv no:\n");
    fnInitUuid128(&uuids_struct[serv_uuid], uuid_bytesArray[serv_uuid]);
    attrs[serv_uuid] = (struct bt_gatt_attr)BT_GATT_PRIMARY_SERVICE(&uuids_struct[serv_uuid]);
    attrs[characteristic_uuid] = (struct bt_gatt_attr)BT_GATT_CHARACTERISTIC(&uuids_struct[characteristic_uuid],BT_GATT_CHRC_READ, BT_GATT_PERM_READ, NULL, NULL, NULL);;
    services[serv_uuid] = (struct bt_gatt_service) { .attrs = &attrs, .attr_count = 2 };
    int result = bt_gatt_service_register(&services[serv_uuid]);
    if (result) {
        LOG_ERR("Failed to register service %d (err %d)", serv_uuid, result);
    } else {
        LOG_INF("Service %d registered successfully result %d", serv_uuid,result);
    }

error:

348 | attrs[characteristic_uuid] = (struct bt_gatt_attr)BT_GATT_CHARACTERISTIC(&uuids_struct[characteristic_uuid],BT_GATT_CHRC_READ, BT_GATT_PERM_READ, NULL, NULL, NULL);;
| ^
C:/ncs/v2.9.0/zephyr/include/zephyr/bluetooth/gatt.h:1191:22: note: in definition of macro 'BT_GATT_ATTRIBUTE'
1191 | .user_data = _user_data, \
| ^~~~~~~~~~
C:/ncs/v2.9.0/zephyr/include/zephyr/bluetooth/gatt.h:912:33: note: in expansion of macro 'BT_GATT_CHRC_INIT'
912 | BT_GATT_CHRC_INIT(_uuid, 0U, _props), \
| ^~~~~~~~~~~~~~~~~
C:src/main.c:348:67: note: in expansion of macro 'BT_GATT_CHARACTERISTIC'
348 | attrs[characteristic_uuid] = (struct bt_gatt_attr)BT_GATT_CHARACTERISTIC(&uuids_struct[characteristic_uuid],BT_GATT_CHRC_READ, BT_GATT_PERM_READ, NULL, NULL, NULL);;
| ^~~~~~~~~~~~~~~~~~~~~~
C:/src/main.c:348:90: note: (near initialization for '(anonymous)[0].uuid')
348 | attrs[characteristic_uuid] = (struct bt_gatt_attr)BT_GATT_CHARACTERISTIC(&uuids_struct[characteristic_uuid],BT_GATT_CHRC_READ, BT_GATT_PERM_READ, NULL, NULL, NULL);;
| ^
C:/ncs/v2.9.0/zephyr/include/zephyr/bluetooth/gatt.h:1191:22: note: in definition of macro 'BT_GATT_ATTRIBUTE'
1191 | .user_data = _user_data, \
| ^~~~~~~~~~
C:/ncs/v2.9.0/zephyr/include/zephyr/bluetooth/gatt.h:912:33: note: in expansion of macro 'BT_GATT_CHRC_INIT'
912 | BT_GATT_CHRC_INIT(_uuid, 0U, _props), \
| ^~~~~~~~~~~~~~~~~
C:/src/main.c:348:67: note: in expansion of macro 'BT_GATT_CHARACTERISTIC'
348 | attrs[characteristic_uuid] = (struct bt_gatt_attr)BT_GATT_CHARACTERISTIC(&uuids_struct[characteristic_uuid],BT_GATT_CHRC_READ, BT_GATT_PERM_READ, NULL, NULL, NULL);;
| ^~~~~~~~~~~~~~~~~~~~~~
C:/ncs/v2.9.0/zephyr/include/zephyr/bluetooth/gatt.h:1187:1: error: expected expression before '{' token
1187 | { \
| ^
C:/ncs/v2.9.0/zephyr/include/zephyr/bluetooth/gatt.h:914:9: note: in expansion of macro 'BT_GATT_ATTRIBUTE'
914 | BT_GATT_ATTRIBUTE(_uuid, _perm, _read, _write, _user_data)
| ^~~~~~~~~~~~~~~~~
C:/src/main.c:348:67: note: in expansion of macro 'BT_GATT_CHARACTERISTIC'
348 | attrs[characteristic_uuid] = (struct bt_gatt_attr)BT_GATT_CHARACTERISTIC(&uuids_struct[characteristic_uuid],BT_GATT_CHRC_READ, BT_GATT_PERM_READ, NULL, NULL, NULL);;
| ^~~~~~~~~~~~~~~~~~~~~~
C:/src/main.c:349:67: warning: initialization of 'struct bt_gatt_attr *' from incompatible pointer type 'struct bt_gatt_attr (*)[3]' [-Wincompatible-pointer-types]
349 | services[serv_uuid] = (struct bt_gatt_service) { .attrs = &attrs, .attr_count = 2 };
| ^
Parents Reply
  • thanks Sigurd, I found using the code below helped generate my service and characteristic 

    attrs[attr_count++] = (struct bt_gatt_attr) {
        .uuid = BT_UUID_GATT_PRIMARY,
        .perm = BT_GATT_PERM_READ,
        .read = bt_gatt_attr_read_service,
        .user_data = &uuids_struct[0],
    };
    
    attrs[(attr_count)++] = (struct bt_gatt_attr) {
        .uuid = BT_UUID_GATT_CHRC,
        .perm = BT_GATT_PERM_READ,
        .read = bt_gatt_attr_read_chrc,
        .user_data = &(struct bt_gatt_chrc) {
    	.properties = BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
    	.uuid = &uuids_struct[1],
    	},
    };
    attrs[(attr_count)++] = (struct bt_gatt_attr) {
        .uuid = &uuids_struct[1],
        .perm = BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
        .read = NULL,
        .write = NULL,
        .user_data = NULL,
    };

Children
No Data
Related