SDK及路径:SDK\PHY62XX_SDK_3.1.1_0922\example\ble_peripheral\simpleBlePeripheral
硬件:PHY6222开发板
APP:nRF connect
自定义的UUID
CONST uint8 my_serviceUUIID[ATT_UUID_SIZE] =
{0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
CONST uint8 my_Characteristic_UUID[ATT_UUID_SIZE] =
{0x34, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
CONST uint8 my_2_Characteristic_UUID[ATT_UUID_SIZE] =
{0x56, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
初始化属性表
static gattAttribute_t my_Attrb1[] =
{
//my primary service
{
{ATT_BT_UUID_SIZE, primaryServiceUUID},/* type */ //主服务
GATT_PERMIT_READ, /* permissions */ //权限
0, /* handle */ //头
(uint8*)& my_service /* pValue */ //值
},
//我的理解是GATT_PERMIT_READ 这个描述的是 数组 这个元素 具有的 权限 是 可读 或者 可写,
//my_Characteristic_permissions这个变量 描述 的 是 该数组元素 代表的特征值 具有 可写 的属性
{
{ATT_BT_UUID_SIZE, characterUUID},//type,属性类型 是特征值类型
GATT_PERMIT_READ,
0,
&my_Characteristic_permissions//read , write ,notify, indicate权限
},
{
{ATT_UUID_SIZE, my_Characteristic_UUID},//自定义特征类型
GATT_PERMIT_WRITE,
0,
&my_Characteristic_UUID_value//自定义特征UUID的值
},
{
{ ATT_BT_UUID_SIZE, clientCharCfgUUID },//类型是描述UUID
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
(uint8*)my_notify_CCCD_value//描述的值
},
//----------------------------------------------------
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&my_2_Characteristic_permissions
},
{
{ATT_UUID_SIZE, my_2_Characteristic_UUID},
GATT_PERMIT_WRITE,
0,
&my_2_Characteristic_UUID_value
},
{
{ATT_BT_UUID_SIZE, clientCharCfgUUID},
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
(uint8*)my_indcate_CCCD_value
},
};
profile有改变时触发的回调函数
CONST gattServiceCBs_t my_ProfileCBs =
{
my_ReadAttrCB,
my_WriteAttrCB,
NULL
};
static bStatus_t my_WriteAttrCB(uint16 connHandle, gattAttribute_t* pAttr,
uint8* pValue, uint16 len, uint16 offset)
{
bStatus_t status = SUCCESS;
//uint8 notifyApp = 0xFF;
// If attribute permissions require authorization to write, return error
if (gattPermitAuthorWrite(pAttr->permissions))
{
// Insufficient authorization
return (ATT_ERR_INSUFFICIENT_AUTHOR);
}
if (pAttr->type.len == ATT_BT_UUID_SIZE)
{
// 16-bit UUID
uint16 uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
if (uuid == GATT_CLIENT_CHAR_CFG_UUID)
{
if(pAttr->handle == my_Attrb1[3].handle) {
status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len,
offset, GATT_CLIENT_CFG_NOTIFY);
if (status == SUCCESS)
{
uint16 charCfg = BUILD_UINT16(pValue[0], pValue[1]);
LOG("CCCD set: [%d]\n", charCfg);
s_my_app.notify_en = (charCfg == 1);
osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_TEST_TX_NOTIFY, 500 );
}
} else if(pAttr->handle == my_Attrb1[6].handle)
{
status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len,
offset, GATT_CLIENT_CFG_INDICATE);
if (status == SUCCESS)
{
uint16 charCfg = BUILD_UINT16(pValue[0], pValue[1]);
LOG("write indicata: [%d]\n", charCfg);
}
}
}
else
{
LOG("WR:%d\n", pAttr->handle);
// 128-bit UUID Command
if (pAttr->handle == my_Attrb1[MY_COMMAND_HANDLE].handle)
{
// process_cmd(pValue, len);
}
}
return (status);
}
}
static uint8 my_ReadAttrCB(uint16 connHandle, gattAttribute_t* pAttr,uint8 * pValue, uint16 * pLen, uint16 offset, uint8 maxLen)
{
bStatus_t status = SUCCESS;
LOG("ReadAttrCB\n");
// If attribute permissions require authorization to read, return error
if (gattPermitAuthorRead(pAttr->permissions))
{
// Insufficient authorization
return (ATT_ERR_INSUFFICIENT_AUTHOR);
}
return (status);
}
notify
static bStatus_t send_Notify(attHandleValueNoti_t* pNoti)
{
uint16 connHandle;
uint16 value;
GAPRole_GetParameter(GAPROLE_CONNHANDLE, &connHandle);
value = GATTServApp_ReadCharCfg(connHandle, my_notify_CCCD_value);
if (connHandle == INVALID_CONNHANDLE)
return bleIncorrectMode;
// If notifications enabled
if (value & GATT_CLIENT_CFG_NOTIFY)
{
// Set the handle
pNoti->handle = my_Attrb1[MY_RSP_HANDLE].handle;
// Send the Indication
return GATT_Notification(connHandle, pNoti, FALSE);
}
return bleIncorrectMode;
}
indicate
static bStatus_t send_indicate(attHandleValueInd_t* indi)
{
uint16 connHandle;
uint16 value;
GAPRole_GetParameter(GAPROLE_CONNHANDLE, &connHandle);
value = GATTServApp_ReadCharCfg(connHandle, my_indcate_CCCD_value);
if (connHandle == INVALID_CONNHANDLE)
return bleIncorrectMode;
// If notifications enabled
if (value & GATT_CLIENT_CFG_INDICATE)
{
// Set the handle
indi->handle = my_Attrb1[5].handle;
// Send the Indication
return GATT_Indication(connHandle, indi, FALSE, simpleBLEPeripheral_TaskID);
}
return bleIncorrectMode;
}
注册profile回调
bStatus_t my_Profile_RegisterAppCBs( my_ProfileCBs_t* appCallbacks )
{
if ( appCallbacks )
{
my_Profile_AppCBs = appCallbacks;
return ( SUCCESS );
}
else
{
return ( bleAlreadyInRequestedMode );
}
}
注册服务(关键点)
bStatus_t my_app_addservice(uint32 services)
{
uint8 status = SUCCESS;
VOID linkDB_Register(my_Profile_HandleConnStatusCB);
GATTServApp_InitCharCfg(INVALID_CONNHANDLE, my_notify_CCCD_value);
status = GATTServApp_RegisterService(my_Attrb1, GATT_NUM_ATTRS(my_Attrb1), &my_ProfileCBs);
if (status != SUCCESS)
LOG("Add OTA service failed!\n");
return (status);
}