Add next gen profile and configurations (#67)
* fix: crash in picture animation * ble: add next gen profile * force read header from flash anyway * fix: bmlist: mem leak * feat: add reset option after legacy transfers
This commit is contained in:
committed by
GitHub
parent
512134607b
commit
4e556ab11f
@@ -1,5 +1,6 @@
|
||||
#include "CH58xBLE_LIB.h"
|
||||
#include "setup.h"
|
||||
#include "../config.h"
|
||||
|
||||
#define ADV_UUID (0xFEE0)
|
||||
|
||||
@@ -24,29 +25,6 @@ typedef struct
|
||||
|
||||
#define CONN_TIMEOUT 100 // Supervision timeout (units of 10ms)
|
||||
|
||||
// GAP - SCAN RSP data (max size = 31 bytes)
|
||||
static uint8 scanRspData[] = {
|
||||
// complete name
|
||||
16, // length of this section
|
||||
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
|
||||
'L', 'E','D', ' ',
|
||||
'B', 'a','d', 'g', 'e', ' ',
|
||||
'M', 'a','g', 'i', 'c',
|
||||
|
||||
// connection interval range
|
||||
0x05, // length of this section
|
||||
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
|
||||
LO_UINT16(MIN_CONN_INTERVAL),
|
||||
HI_UINT16(MIN_CONN_INTERVAL),
|
||||
LO_UINT16(MAX_CONN_INTERVAL),
|
||||
HI_UINT16(MAX_CONN_INTERVAL),
|
||||
|
||||
// Tx power level
|
||||
0x02, // length of this data
|
||||
GAP_ADTYPE_POWER_LEVEL,
|
||||
9 // 9dBm
|
||||
};
|
||||
|
||||
// GAP - Advertisement data (max size = 31 bytes)
|
||||
// keep short, save energy, save the planet
|
||||
static uint8 advertData[] = {
|
||||
@@ -61,9 +39,6 @@ static uint8 advertData[] = {
|
||||
HI_UINT16(ADV_UUID)
|
||||
};
|
||||
|
||||
// GAP GATT Attributes
|
||||
static uint8 devName[GAP_DEVICE_NAME_LEN] = "LED Badge Magic";
|
||||
|
||||
// Connection item list
|
||||
static peripheralConnItem_t conn_list;
|
||||
|
||||
@@ -210,21 +185,58 @@ void ble_disable_advertise()
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8), &e);
|
||||
}
|
||||
|
||||
// len should not exceed 20 chars excluding null-terminate char. Otherwise it
|
||||
// will be trimmed off and return -1
|
||||
static int setup_scan_rsp(char *name, uint8_t len)
|
||||
{
|
||||
int ret = 0;
|
||||
// GAP - SCAN RSP data (max size = 31 bytes)
|
||||
uint8_t scanRspData[31] = {
|
||||
// connection interval range
|
||||
0x05, // length of this section
|
||||
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
|
||||
LO_UINT16(MIN_CONN_INTERVAL),
|
||||
HI_UINT16(MIN_CONN_INTERVAL),
|
||||
LO_UINT16(MAX_CONN_INTERVAL),
|
||||
HI_UINT16(MAX_CONN_INTERVAL),
|
||||
|
||||
// Tx power level
|
||||
0x02, // length of this data
|
||||
GAP_ADTYPE_POWER_LEVEL,
|
||||
9, // 9dBm
|
||||
|
||||
len + 1,
|
||||
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
|
||||
};
|
||||
|
||||
if (len < (31 - 11)) {
|
||||
tmos_memcpy(&scanRspData[11], name, len);
|
||||
ret = -1;
|
||||
} else {
|
||||
tmos_memcpy(&scanRspData[11], name, 20);
|
||||
}
|
||||
int total_len = 11 + len;
|
||||
tmos_memset(&scanRspData[total_len], 0, 31 - total_len);
|
||||
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, total_len, scanRspData);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void gap_init()
|
||||
{
|
||||
GAPRole_PeripheralInit();
|
||||
|
||||
static uint16 desired_min_interval = 6;
|
||||
static uint16 desired_max_interval = 500;
|
||||
uint16_t min_interval = 6;
|
||||
uint16_t max_interval = 500;
|
||||
|
||||
// Set the GAP Role Parameters
|
||||
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData);
|
||||
setup_scan_rsp(badge_cfg.ble_devname, 20);
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
|
||||
GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16), &desired_min_interval);
|
||||
GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16), &desired_max_interval);
|
||||
GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16), &min_interval);
|
||||
GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16), &max_interval);
|
||||
|
||||
// Set the GAP Characteristics
|
||||
GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, devName);
|
||||
GGS_SetParameter(GGS_DEVICE_NAME_ATT, 20,
|
||||
badge_cfg.ble_devname);
|
||||
GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, MIN_ADV_INTERVAL);
|
||||
GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, MAX_ADV_INTERVAL);
|
||||
|
||||
|
||||
@@ -4,5 +4,8 @@
|
||||
int legacy_registerService();
|
||||
int devInfo_registerService();
|
||||
int batt_registerService();
|
||||
int ng_registerService();
|
||||
|
||||
bStatus_t ng_notify(uint8_t *pValue, uint8_t len);
|
||||
|
||||
#endif /* __BLE_UART_SERVICE_H__ */
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#include "utils.h"
|
||||
|
||||
#include "../../data.h"
|
||||
#include "../../power.h"
|
||||
#include "../../leddrv.h"
|
||||
#include "../../legacyctrl.h"
|
||||
|
||||
static const uint16_t ServiceUUID = 0xFEE0;
|
||||
static const gattAttrType_t service = {2, (uint8_t *)&ServiceUUID};
|
||||
@@ -18,39 +16,6 @@ static gattAttribute_t attr_table[] = {
|
||||
CHAR_VAL_DECLAR(&RxCharUUID, 2, GATT_PERMIT_WRITE, RxCharVal),
|
||||
};
|
||||
|
||||
static bStatus_t receive(uint8_t *val, uint16_t len)
|
||||
{
|
||||
static uint16_t c, data_len, n;
|
||||
static uint8_t *data;
|
||||
if (len != LEGACY_TRANSFER_WIDTH) {
|
||||
return ATT_ERR_INVALID_VALUE_SIZE;
|
||||
}
|
||||
if (c == 0) {
|
||||
if (memcmp(val, "wang\0\0", 6)) {
|
||||
return ATT_ERR_INVALID_VALUE;
|
||||
} else {
|
||||
data = malloc(sizeof(data_legacy_t));
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(data + c * len, val, len);
|
||||
|
||||
if (c == 1) {
|
||||
data_legacy_t *d = (data_legacy_t *)data;
|
||||
n = bigendian16_sum(d->sizes, 8);
|
||||
data_len = LEGACY_HEADER_SIZE + LED_ROWS * n;
|
||||
data = realloc(data, data_len);
|
||||
}
|
||||
|
||||
if (c > 2 && ((c+1) * LEGACY_TRANSFER_WIDTH) >= data_len) {
|
||||
data_flatSave(data, data_len);
|
||||
reset_jump();
|
||||
}
|
||||
|
||||
c++;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static bStatus_t write_handler(uint16 connHandle, gattAttribute_t *pAttr,
|
||||
uint8 *pValue, uint16 len, uint16 offset, uint8 method)
|
||||
{
|
||||
@@ -60,7 +25,10 @@ static bStatus_t write_handler(uint16 connHandle, gattAttribute_t *pAttr,
|
||||
|
||||
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
|
||||
if(uuid == RxCharUUID) {
|
||||
return receive(pValue, len);
|
||||
if (legacy_ble_rx(pValue, len)) {
|
||||
return ATT_ERR_UNLIKELY;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
return ATT_ERR_ATTR_NOT_FOUND;
|
||||
}
|
||||
|
||||
160
src/ble/profile/ng.c
Normal file
160
src/ble/profile/ng.c
Normal file
@@ -0,0 +1,160 @@
|
||||
#include "utils.h"
|
||||
|
||||
#include "CH583SFR.h"
|
||||
|
||||
#include "../../power.h"
|
||||
#include "../../ngctrl.h"
|
||||
#include "../../debug.h"
|
||||
|
||||
static const uint16_t ServiceUUID = 0xF055;
|
||||
static const gattAttrType_t service = {2, (uint8_t *)&ServiceUUID};
|
||||
|
||||
static const uint16_t TxCharUUID = 0xF056;
|
||||
static uint8_t TxCharProps = GATT_PROP_READ | GATT_PROP_NOTIFY;
|
||||
static uint8_t TxCharVal[256];
|
||||
static uint16_t TxLen;
|
||||
|
||||
static const uint16_t RxCharUUID = 0xF057;
|
||||
static uint8_t RxCharProps = GATT_PROP_WRITE;
|
||||
#define RxCharVal TxCharVal
|
||||
static gattCharCfg_t TxCCCD[1];
|
||||
|
||||
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),
|
||||
|
||||
CHAR_DECLAR(&TxCharProps),
|
||||
CHAR_VAL_DECLAR(&TxCharUUID, 2, GATT_PERMIT_READ, TxCharVal),
|
||||
ATTR_DECLAR(clientCharCfgUUID, 2, GATT_PERMIT_READ | GATT_PERMIT_WRITE, TxCCCD),
|
||||
};
|
||||
|
||||
#define notiAttr attr_table[4]
|
||||
|
||||
|
||||
static bStatus_t write_handler(uint16 connHandle, gattAttribute_t *pAttr,
|
||||
uint8 *pValue, uint16 len, uint16 offset, uint8 method)
|
||||
{
|
||||
PRINT("ble: write_handler(): connHandle: %04X\n", connHandle);
|
||||
|
||||
if (!gattPermitWrite(pAttr->permissions)) {
|
||||
return ATT_ERR_WRITE_NOT_PERMITTED;
|
||||
}
|
||||
|
||||
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
|
||||
if(uuid == GATT_CLIENT_CHAR_CFG_UUID) {
|
||||
bStatus_t ret = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len,
|
||||
offset, GATT_CLIENT_CFG_NOTIFY);
|
||||
PRINT("ble: CCCD changed: %02X\n", TxCCCD->value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (uuid == RxCharUUID) {
|
||||
return ng_parse(pValue, len);
|
||||
}
|
||||
|
||||
return ATT_ERR_ATTR_NOT_FOUND;
|
||||
}
|
||||
|
||||
static bStatus_t read_handler(uint16_t connHandle, gattAttribute_t *pAttr,
|
||||
uint8_t *pValue, uint16_t *pLen, uint16_t offset,
|
||||
uint16_t maxLen, uint8_t method)
|
||||
{
|
||||
if (!gattPermitRead(pAttr->permissions)) {
|
||||
return ATT_ERR_READ_NOT_PERMITTED;
|
||||
}
|
||||
|
||||
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
|
||||
if(uuid == GATT_CLIENT_CHAR_CFG_UUID) {
|
||||
*pLen = 2;
|
||||
tmos_memcpy(pValue, pAttr->pValue, *pLen);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if (uuid == TxCharUUID) {
|
||||
*pLen = MIN(TxLen-offset, maxLen);
|
||||
tmos_memcpy(pValue, &pAttr->pValue[offset], *pLen);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
return ATT_ERR_ATTR_NOT_FOUND;
|
||||
}
|
||||
|
||||
static gattServiceCBs_t service_handlers = {
|
||||
read_handler,
|
||||
write_handler,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void connStatus_handler(uint16 connHandle, uint8 changeType)
|
||||
{
|
||||
if(connHandle == LOOPBACK_CONNHANDLE)
|
||||
return;
|
||||
|
||||
// Reset ClientCharConfig if connection has dropped
|
||||
if((changeType == LINKDB_STATUS_UPDATE_REMOVED)
|
||||
|| ((changeType == LINKDB_STATUS_UPDATE_STATEFLAGS)
|
||||
&& (!linkDB_Up(connHandle)))) {
|
||||
GATTServApp_InitCharCfg(connHandle, TxCCCD);
|
||||
}
|
||||
}
|
||||
|
||||
int ng_registerService()
|
||||
{
|
||||
uint8 status = SUCCESS;
|
||||
GATTServApp_InitCharCfg(INVALID_CONNHANDLE, TxCCCD);
|
||||
linkDB_Register(connStatus_handler);
|
||||
|
||||
status = GATTServApp_RegisterService(attr_table,
|
||||
GATT_NUM_ATTRS(attr_table),
|
||||
GATT_MAX_ENCRYPT_KEY_SIZE,
|
||||
&service_handlers);
|
||||
return (status);
|
||||
}
|
||||
|
||||
static uint8 isNotifyEnabled(uint16 connHandle)
|
||||
{
|
||||
uint16_t val = GATTServApp_ReadCharCfg(connHandle, TxCCCD);
|
||||
return val & GATT_CLIENT_CFG_NOTIFY;
|
||||
}
|
||||
/**
|
||||
* @brief Send notify to client. Currently support one client connection
|
||||
* only.
|
||||
*
|
||||
* @param val Value to be sent
|
||||
* @param len length of val. This should not be larger than MTU.
|
||||
* @return bStatus_t
|
||||
*/
|
||||
bStatus_t ng_notify(uint8_t *val, uint8_t len)
|
||||
{
|
||||
if(!isNotifyEnabled(TxCCCD->connHandle)) {
|
||||
PRINT("ble: ng_notify() notify is not enabled\n");
|
||||
return bleIncorrectMode;
|
||||
}
|
||||
if(len > ATT_GetMTU(TxCCCD->connHandle)) {
|
||||
return bleInvalidRange;
|
||||
}
|
||||
|
||||
attHandleValueNoti_t noti = {
|
||||
.handle = notiAttr.handle,
|
||||
.len = len
|
||||
};
|
||||
noti.pValue = GATT_bm_alloc(TxCCCD->connHandle, ATT_HANDLE_VALUE_NOTI,
|
||||
len, NULL, 0);
|
||||
if (noti.pValue == NULL) {
|
||||
return bleMemAllocError;
|
||||
}
|
||||
|
||||
tmos_memcpy(noti.pValue, val, len);
|
||||
|
||||
bStatus_t ret = GATT_Notification(TxCCCD->connHandle, ¬i, FALSE);
|
||||
GATT_bm_free((gattMsg_t *)¬i, ATT_HANDLE_VALUE_NOTI);
|
||||
if (ret != SUCCESS) {
|
||||
PRINT("ble: noti sending failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
PRINT("ble: noti sent\n");
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -6,28 +6,39 @@
|
||||
#include "CH58x_common.h"
|
||||
|
||||
#ifndef BLE_BUFF_LEN
|
||||
#define BLE_BUFF_LEN 27
|
||||
#endif
|
||||
#ifndef BLE_BUFF_NUM
|
||||
#define BLE_BUFF_NUM 5
|
||||
// MTU = 64 but clients should request new MTU, otherwise default will be 23
|
||||
#define BLE_BUFF_LEN (64 + 4)
|
||||
#endif
|
||||
|
||||
#ifndef BLE_TX_NUM_EVENT
|
||||
#define BLE_TX_NUM_EVENT 1
|
||||
#endif
|
||||
|
||||
#ifndef BLE_TX_POWER
|
||||
#define BLE_TX_POWER LL_TX_POWEER_6_DBM
|
||||
// #define BLE_TX_POWER LL_TX_POWEER_MINUS_16_DBM
|
||||
#endif
|
||||
|
||||
#ifndef BLE_MEMHEAP_SIZE
|
||||
#define BLE_MEMHEAP_SIZE (1024*6)
|
||||
#define BLE_MEMHEAP_SIZE (1024 * 6)
|
||||
#endif
|
||||
|
||||
#ifndef CENTRAL_MAX_CONNECTION
|
||||
#define CENTRAL_MAX_CONNECTION 3
|
||||
#define CENTRAL_MAX_CONNECTION 1
|
||||
#endif
|
||||
|
||||
#ifndef BLE_BUFF_NUM
|
||||
// The BLE lib automatically stack up Write Long messages in Write handler.
|
||||
// A connection will be disconnected if this number is some how not enough.
|
||||
#define BLE_BUFF_NUM (512 / 23)
|
||||
#endif
|
||||
|
||||
#ifndef PERIPHERAL_MAX_CONNECTION
|
||||
#define PERIPHERAL_MAX_CONNECTION 1
|
||||
#endif
|
||||
|
||||
static __attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];
|
||||
static __attribute__((aligned(4), section(".noinit")))
|
||||
uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];
|
||||
|
||||
static void lsi_calib(void)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user