From 8274cab154f198447f12028e1686bbe2a6de6ebd Mon Sep 17 00:00:00 2001 From: Dien-Nhung Nguyen-Phu Date: Sun, 23 Jun 2024 19:22:20 +0700 Subject: feat: add initial Bluetooth LE module --- src/ble/profile/devinfo.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++ src/ble/profile/legacy.c | 51 ++++++++++++++++++++ src/ble/profile/utils.h | 22 +++++++++ 3 files changed, 193 insertions(+) create mode 100644 src/ble/profile/devinfo.c create mode 100644 src/ble/profile/legacy.c create mode 100644 src/ble/profile/utils.h (limited to 'src/ble/profile') diff --git a/src/ble/profile/devinfo.c b/src/ble/profile/devinfo.c new file mode 100644 index 0000000..f29526d --- /dev/null +++ b/src/ble/profile/devinfo.c @@ -0,0 +1,120 @@ +#include "../common.h" +#include "utils.h" + +// TODO: Automatic assign these on build +static const uint8_t systemId_val[] = {0, 0, 0, 0, 0, 0, 0, 0}; +static const uint16_t systemId_UUID = SYSTEM_ID_UUID; + +static const uint8_t modelNumber_val[] = "B1144"; +static const uint16_t modelNumber_UUID = MODEL_NUMBER_UUID; + +const uint16_t serialNumber_UUID = SERIAL_NUMBER_UUID; +static const uint8_t serialNumber_val[] = "N/A"; + +const uint16_t firmwareRev_UUID = FIRMWARE_REV_UUID; +static const uint8_t firmwareRev_val[] = "v0.0.1"; + +const uint16_t hardwareRev_UUID = HARDWARE_REV_UUID; +static const uint8_t hardwareRev_val[] = "221028"; + +const uint16_t softwareRev_UUID = SOFTWARE_REV_UUID; +static const uint8_t softwareRev_val[] = "N/A"; + +uint16_t mfr_name_UUID = MANUFACTURER_NAME_UUID; +static const uint8_t mfr_name_val[] = "FOSSASIA"; + +static const ble_char_t dev_info[7] = { + { + {systemId_val, sizeof(systemId_val)}, + GATT_PROP_READ, { (uint8_t*)&systemId_UUID, 2} + }, { + {modelNumber_val, sizeof(modelNumber_val) - 1}, + GATT_PROP_READ, { (uint8_t*)&modelNumber_UUID, 2} + }, { + {serialNumber_val, sizeof(serialNumber_val) - 1}, + GATT_PROP_READ, { (uint8_t*)&serialNumber_UUID, 2} + }, { + {firmwareRev_val, sizeof(firmwareRev_val) - 1}, + GATT_PROP_READ, { (uint8_t*)&firmwareRev_UUID, 2} + }, { + {hardwareRev_val, sizeof(hardwareRev_val) - 1}, + GATT_PROP_READ, { (uint8_t*)&hardwareRev_UUID, 2} + }, { + {softwareRev_val, sizeof(softwareRev_val) - 1}, + GATT_PROP_READ, { (uint8_t*)&softwareRev_UUID, 2} + }, { + {mfr_name_val, sizeof(mfr_name_val) - 1}, + GATT_PROP_READ, + { (uint8_t*)&mfr_name_UUID, 2}, + } +}; + +const uint16_t service_UUID = DEVINFO_SERV_UUID; +static const gattAttrType_t service = {ATT_BT_UUID_SIZE, (uint8_t *)&service_UUID}; + +static bStatus_t read_handler(uint16_t connHandle, gattAttribute_t *pAttr, + uint8_t *p_value, uint16_t *pLen, uint16_t offset, + uint16_t maxLen, uint8_t method) +{ + uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]); + + if (uuid < SYSTEM_ID_UUID || uuid > MANUFACTURER_NAME_UUID ) { + *pLen = 0; + return ATT_ERR_ATTR_NOT_FOUND; + } + + uint16_t i = uuid - SYSTEM_ID_UUID; + if(offset >= dev_info[i].val.size) { + return ATT_ERR_INVALID_OFFSET; + } else { + *pLen = MIN(maxLen, (dev_info[i].val.size - offset)); + tmos_memcpy(p_value, &dev_info[i].val.bytes[offset], *pLen); + } + return SUCCESS; +} + +gattServiceCBs_t devInfoCBs = { + read_handler, + NULL, + NULL +}; + +int devInfo_registerService() +{ + static gattAttribute_t attr_table[] = { + ATTR_DECLAR(primaryServiceUUID, 2, GATT_PERMIT_READ, &service), + + CHAR_DECLAR(&dev_info[0].props), + CHAR_VAL_DECLAR(dev_info[0].uuid.bytes, dev_info[0].uuid.size, \ + GATT_PERMIT_READ, dev_info[0].val.bytes), + + CHAR_DECLAR(&dev_info[1].props), + CHAR_VAL_DECLAR(dev_info[1].uuid.bytes, dev_info[1].uuid.size, \ + GATT_PERMIT_READ, dev_info[1].val.bytes), + + CHAR_DECLAR(&dev_info[2].props), + CHAR_VAL_DECLAR(dev_info[2].uuid.bytes, dev_info[2].uuid.size, \ + GATT_PERMIT_READ, dev_info[2].val.bytes), + + CHAR_DECLAR(&dev_info[3].props), + CHAR_VAL_DECLAR(dev_info[3].uuid.bytes, dev_info[3].uuid.size, \ + GATT_PERMIT_READ, dev_info[3].val.bytes), + + CHAR_DECLAR(&dev_info[4].props), + CHAR_VAL_DECLAR(dev_info[4].uuid.bytes, dev_info[4].uuid.size, \ + GATT_PERMIT_READ, dev_info[4].val.bytes), + + CHAR_DECLAR(&dev_info[5].props), + CHAR_VAL_DECLAR(dev_info[5].uuid.bytes, dev_info[5].uuid.size, \ + GATT_PERMIT_READ, dev_info[5].val.bytes), + + CHAR_DECLAR(&dev_info[6].props), + CHAR_VAL_DECLAR(dev_info[6].uuid.bytes, dev_info[6].uuid.size, \ + GATT_PERMIT_READ, dev_info[6].val.bytes), + }; + + return GATTServApp_RegisterService(attr_table, + GATT_NUM_ATTRS(attr_table), + GATT_MAX_ENCRYPT_KEY_SIZE, + &devInfoCBs); +} \ No newline at end of file diff --git a/src/ble/profile/legacy.c b/src/ble/profile/legacy.c new file mode 100644 index 0000000..fc775e5 --- /dev/null +++ b/src/ble/profile/legacy.c @@ -0,0 +1,51 @@ +#include "utils.h" + +static const uint16_t ServiceUUID = 0xFEE0; +static const gattAttrType_t service = {2, (uint8_t *)&ServiceUUID}; + +static const uint16_t RxCharUUID = 0xFEE1; +static uint8 RxCharProps = GATT_PROP_WRITE; +static uint8 RxCharVal[16]; + +static gattAttribute_t attr_table[] = { + ATTR_DECLAR(primaryServiceUUID, 2, GATT_PERMIT_READ, &service), + + CHAR_DECLAR(&RxCharProps), + CHAR_VAL_DECLAR(&RxCharUUID, 2, GATT_PERMIT_WRITE, RxCharVal), +}; + +static bStatus_t receive(uint8_t *val, uint16_t len) +{ + /* TODO: implement data receiving here*/ +} + +static bStatus_t write_handler(uint16 connHandle, gattAttribute_t *pAttr, + uint8 *pValue, uint16 len, uint16 offset, uint8 method) +{ + if(gattPermitAuthorWrite(pAttr->permissions)) { + return ATT_ERR_INSUFFICIENT_AUTHOR; + } + + uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]); + if(uuid == RxCharUUID) { + return receive(pValue, len); + } + return ATT_ERR_ATTR_NOT_FOUND; +} + +gattServiceCBs_t service_handlers = { + NULL, + write_handler, + NULL +}; + +int legacy_registerService() +{ + uint8 status = SUCCESS; + + status = GATTServApp_RegisterService(attr_table, + GATT_NUM_ATTRS(attr_table), + GATT_MAX_ENCRYPT_KEY_SIZE, + &service_handlers); + return (status); +} \ No newline at end of file diff --git a/src/ble/profile/utils.h b/src/ble/profile/utils.h new file mode 100644 index 0000000..b52504f --- /dev/null +++ b/src/ble/profile/utils.h @@ -0,0 +1,22 @@ +#ifndef __UTILS_H__ +#define __UTILS_H__ + +#include "CH58xBLE_LIB.h" + +#define ATTR_DECLAR(uuid, uuid_size, permissions, val) \ + { \ + {(uuid_size), (uint8_t *)(uuid)}, \ + (permissions), \ + 0, \ + (uint8_t *)(val) \ + } + +// Characteristic Declaration +#define CHAR_DECLAR(properties) \ + ATTR_DECLAR(characterUUID, 2, GATT_PERMIT_READ, properties) + +// Characteristic Value Declaration +#define CHAR_VAL_DECLAR(uuid, uuid_size, permissions, val) \ + ATTR_DECLAR(uuid, uuid_size, permissions, val) + +#endif /* __UTILS_H__ */ -- cgit v1.2.3