我有一个以 SimpleLink Academy ProjectZero 开头的项目。
我添加了对外部闪存的访问、并禁用了 OSAL 和 UART 日志记录、以便有空间在 CC2640 128MB 上运行程序。
我删除了 LED 和数据特性、并为按钮特性添加了写入功能、该特性已重命名为 HALO。
当我向 HALO 特征添加了写入功能时、我可能做得不正确、因为 Notify 似乎有时仅起作用、并且当我的 IOS 应用程序请求将 Notify 更改为 Yes 时、 我在 USER_HaloService_ValueChangeHandler 中看到请求,IOS 请求失败,并出现“资源不足”错误。
在 USER_HaloService_ValueChangeHandler 中、将通知更改为是请求显示为"01:00"或0x30 0x31 0x3A 0x00 0x00。
为什么请求甚至会出现在我的 USER_HaloService_ValueChangeHandler 中、因为它应该被 BLE 2.2.1堆栈截取、不应该出现?
这是我可能犯了错误的 halo_service.c、有人能看到它吗?
/*********
*包括
*/
#include
#include
//#define XDC_runtime_Log_disable_all 1 //添加以禁用此文件中的日志
#include
#include
#include "bcomdef.h"
#include "OSAL.h"
#include "linkdb.h"
#include "att。h"
#include "gatt_uuid.h"
#include "gattservapp.h"
#include "gapbondmgr.h"
/*********
*宏
*/
*********
*常量
*/
* typedef
*/
/*********
*全局变量
*/
// Halo 服务 UUID
const uint8_t HaloServiceUUID[ATT_UUUUID_SIZE]=
{
HALO_SERVICE_SERV_UID_BASSE128 (HALO_SERVICE_SERV_UUID)
};
// offset
const uint8_OFFSET_UUID_OUTAUID[AM_OUT_TOUCC_UUID]
= OUT_TOOUNT_UID_UTI_AUUID_UTI_AUUTR_AUUID[_UTI_OUT_TR_OUTAUUID]
}*
*局部变量
*/
static HaloServiceCBs_t * pAppCBs = NULL;
static uint8_t bs_iCall_rs_task_id = inval_task_ID;
/*********
*配置文件属性-变量
*//
服务声明
静态 const gattAttrType_t TVoServiceDecl ={ATT_UUUUUART_SIZE、HaloServiceUUID};
//特征"偏移"属性(用于声明)
静态 uint8_t HS_OFFSETProps = GATT_PROP_NOTIFY | GATT_PROP_READ | GATT_OFFSET
=静态 uint8;static_OFFSET_TOP_ENT_PROP_ENTRY_OFFSET ={PROP_TOP_TOP_ENT}/TOP_ENT_PROPHS_W0_OFFSET =静态 uPROP_TOP_ENT = STAT_ENT + TOP_TOP_ENT = OT_OFFSET = TO
//特性"offset"值变量中的数据长度,初始化为最小大小。
静态 uint16_t HS_OFFSETVALLEEN = HS_OFFSET_LEN_MIN;
//特性"偏移"客户端特性配置描述符
静态 gattCharCfg_t * HS_OFFSETConfig;
//特性"偏移"值变量中的数据长度、初始化为最小大小。 //dale5
静态 uint16_t hs_OFFSETVallen = HS_OFFSET_LEN_MIN;//dale5
//特征"ONOFFREC"属性(用于声明)
静态 uint8_t HS_ONOFFSETProps = GATT_PROP_RECODED | GATT_PROP_READ | GATT_PROP_WRITE | GATT_PROOFFREC
= TOP_REC = TOP_REC 0 = INT_PROONOFFREC = TOP_REC 0;已初始化的静态值/ INT_PROONOFFREC = TO_PROT_REC = TOOT_PROT_REC 0 = TOP_REC 0 = TOOTGALL_REC 0 = TOOT_PROONOFFREC = TOOT_PROT_REC 0 = TOOTGAL_RET = TOOT
静态 uint16_t HS_ONOFFRECVALLEEN = HS_ONOFFREC_LEN_MIN;
//特性"ONOFFREC"客户端特性配置描述符
静态 gattCharCfg_t * HS_ONOFFRECConfig;
//特性"ONOFFREC"值变量中的数据长度,初始化为最小大小。 //dale5
静态 uint16_t hs_ONOFFRECVALLEEN = HS_ONOFFREC_LEN_MIN;//dale5
//特征"TOTALTIME"属性(用于声明)
静态 uint8_t HS_TOTALTIMEProps = GATT_PROP_NOTIFY | GATT_PROTIME"特性"TOTACT_PROTIME"值(用于声明);已
将 TOTALT_PROTIMER 值添加到"TOTACT_PROTIME_TOPRECT_PRECT_PRECT_PRECT_PRECT_PRECT_PRECT_PRECT_PRECT_PRECT_RELE/TOTALYEST_PRECT_PRECT_PRECT_PRECT_PRIMEND 中";
静态 uint16_t HS_TOTALTIMEValLen = HS_TOTALTIME_LEN_MIN;
//特性"TOTALTIME"客户端特性配置描述符
静态 gattCharCfg_t * HS_TOTALTIMEConfig;
//特性"TOTALTIME"值变量中的数据长度,初始化为最小大小。 //dle5
静态 uint16_t hs_TOTALTIMEVallen = HS_TOTALTIM_LEN_min;//dle5
/*********
*配置文件属性-表
*/
静态 gattAttribute_t HALO_ServiceAttrTbl[]=
{
// Halo 服务声明
{
{ATT_BT_UUID_SIZE、primServiceUUID}、
GATT_permit_read、
0、
(uint8_t *)&HaloServiceDecl
}、
//偏移特征声明
{
{ATT_BT_UUUART_SIZE、characterUUID}、
GATT_permit_read、
0、
HS_OFFSETProps
}、
//偏移特性值
{
{ATT_UUUID_SIZE、HS_OFFSETUUID}、
GATT_permit_read | GATT_permit_write、//Dale add | GATT_permit_write
0、
HS_OFFSETVal
}、
//偏移 CCCD
{
{ATT_BT_UUID_SIZE、clientCharCfgUUID}、
GATT_permit_read | GATT_permit_write、
0、
(uint8_t *)&hs_OFFSETConfig
}、
// ONOFFREC Characteristic Declaration
{
{ATT_BT_UUUART_SIZE、characterUUID}、
GATT_permit_read、
0、
&HS_ONOFFRECProps
}、
// ONOFFREC 特性值
{
{ ATT_UUUUUUUI_SIZE、HS_ONOFFRECUUID }、
GATT_permit_read | GATT_permit_write、//Dale add | GATT_permit_write
0、
HS_ONOFFRECVal
}、
// ONOFFREC CCCD
{
{ATT_BT_UUID_SIZE、clientCharCfgUUID}、
GATT_permit_read | GATT_permit_write、
0、
(uint8_t *)&HS_ONOFFRECConfig
}、
// TOTALTIME 特征声明
{
{ATT_BT_UUUART_SIZE、characterUUID}、
GATT_permit_read、
0、
&HS_TOTALTIMEProps
}、
// TOTALTIME 特性值
{
{ATT_UUUID_SIZE、HS_TOTALTIMEUUID}、
GATT_permit_read | GATT_permit_write、//Dale add | GATT_permit_write
0、
HS_TOTALTIMEVAL
}、
// ONOFFREC CCCD
{
{ATT_BT_UUID_SIZE、clientCharCfgUUID}、
GATT_permit_read | GATT_permit_write、
0、
(uint8_t *)&HS_TOTALTIMEConfig
}、
};
/*********
*本地函数
*/
static bStatus_t Halo_Service_ReadAttrCB (uint16_t connHandle、gattAttribute_t *pAttr、
uint8_t * pValue、uint16_t * PLEN、uint16_t offset、
uint16_t maxLen,uint8_t 方法);
static bStatus_t Halo_Service_WriteAttrCB (uint16_t connHandle,gattAttribute_t *pAttr,
uint8_t *pValue、uint16_t len、uint16_t offset、
uint8_t 方法);
/
*配置文件回调
*//
简单配置文件服务回调
const gattServiceCBs_t HALO_ServiceCBs =
{
HALO_Service_ReadAttrCB、//读取回调函数指针
HALO_Service_WriteAttrCB、//写入回调函数指针
NULL //授权回调函数指针
};
/*********
*公共函数
*/
/*
HaloService_AddService -通过注册
*初始化 HaloService 服务 GATT 属性与 GATT 服务器。
*
* rspTaskId -应接收指示响应的 ICall 任务 ID。
//
extern bStatus_t HaloService_AddService (uint8_t rspTaskId)
{
uint8_t status;
//分配客户端特征配置表
HS_OFFSETConfig =(gattCharCfg_t *) iCall_malloc (sizeof (gattCharCnL_t)* linkDBNumConns);
if =
(nL_FFHs)
return (bleMemAllocError);
}
//初始化客户端特征配置属性
GATTServApp_InitCharCfg (invalid_CONNNANDLE、HS_OFFSETConfig);
//分配客户端特征配置表
HS_ONOFFRECConfig =(gattCharCfg_t *) iCall_malloc (sizeof (g_OFFSETConfig
);
//分配客户端特征配置表 HS_ONCONFFRECConfig =(g_NULT_N))=(nLONNULL_NULT_N));(如果为 NULT_NFFCONN),则为 NFF
return (bleMemAllocError);
}
//初始化客户端特征配置属性
GATTServApp_InitCharCfg (invalid_CONNNANDLE、HS_ONOFFRECConfig);
//分配客户端特征配置表
HS_TOTALTIMEConfig =(GattCharCfg_t *)iCall_malloc (sizeof (
NULL)=(TOTALTECONN)=);{_TALCONN = NOT_TAMNULT_TAGNOT_NON_NOTECONTOCONNECT_NULESHOLD=(*)
return (bleMemAllocError);
}
//初始化客户端特征配置属性
GATTServApp_InitCharCfg (INVALID_CONNANDLE、HS_TOTALTIMEConfig);
//使用 GATT 服务器应用
程序状态注册 GATT 属性列表和 CBS = GATTServApp_RegisterService (Halo_ServiceAttrTbl、
GATT_NUM_ATTRS (HALO_ServiceAttrTbl),
GATT_MAX_encrypt_key_size、
&HALO_ServiceCBs );
Log_Info1 (“注册的服务,%d 属性”,(IARg) GATT_NUM_ATTRS (Halo_ServiceAttrTbl);
BS_iCall_rs_task_id = rspTaskId;
返回(状态);
}//*
HaloService_RegisterAppCBs -注册应用程序回调函数。
* 只调用此函数一次。
*
* appCallback -指向应用程序回调的指针。
//
bStatus_t HaloService_RegisterAppCBs (HaloServiceCBs_t *appCallback)
{
if (appCallback)
{
pAppCBs = appCallback;
log_info1 ("注册回调到应用程序。 struct %p"、(IArg) appCallbacks);
返回(成功);
}
否则
{
log_warning0 ("为应用程序回调指定的空指针。");
返回(失败);
}
//*
HaloService_SetParameter -设置 HaloService 参数。
*
* param -配置文件参数 ID
* len -要写入的数据长度
* value -要写入的数据的指针。 这取决于
* 参数 ID 和可被转换为相应
的* 数据类型(例如:uint16_t 的数据类型将转换为
* uint16_t 指针)。
//
bStatus_t HaloService_SetParameter (uint8_t param、uint16_t len、void *值)
{
bStatus_t ret = Success;
uint8_t * pAttrVal;
uint16_t * pValLen;
uint16_t valMinLen;
uint16_t MaxvalLen;
uint8_t sendNotiInd = false;
gattCharCfg_t * attrConfig;
uint8_t needAuth;
switch (param)
{
案例 HS_OFFSET_ID:
pAttrVal = HS_OFFSETVal;
pValLen =&HS_OFFSETValLen;
valMinLen = HS_OFFSET_LEN_MIN;
valMaxLen = HS_OFFSET_LEN;
sendNotitiInd = true;
attrConfig = HS_OFFSETConfig;
needAuth = false;//如果发送需要经过身份验证的链接,则更改。
log_info2 ("SetParameter:%s len:%d"、(IArg)"offset"、(IArg) len);
中断;
案例 HS_ONOFFREC_ID:
pAttrVal = HS_ONOFFRECVal;
pValLen =&HS_ONOFFRECValLen;
valMinLen = HS_ONOFFREC_LEN_MIN;
valMaxLen = HS_ONOFFREC_LEN;
sendNotitiInd = true;
attrConfig = HS_ONOFFRECConfig;
needAuth = false;//如果发送需要经过身份验证的链接,则更改。
log_info2 ("SetParameter:%s len:%d"、(IArg)"ONOFFREC"、(IArg) len);
中断;
案例 HS_TOTALTIME_ID:
pAttrVal = HS_TOTALTIMEVAL;
pValLen =&HS_TOTALTIMEValLen;
valMinLen = HS_TOTALTIME_LEN_MIN;
valMaxLen = HS_TOTALTIME_LEN;
sendNotitiInd = true;
attrConfig = HS_TOTALTIMEConfig;
needAuth = false;//如果发送需要经过身份验证的链接,则更改。
log_info2 ("SetParameter:%s len:%d"、(IArg)"TOTALTIME"、(IArg) len);
中断;
默认值:
log_error1 ("SetParameter:参数#%d 无效。"、(IArg)param);
返回 INVALIDPARAMETER;
}
//检查边界、更新值并发送通知或指示(如果可能)。
如果( len <= valMaxLen && len >= valMinLen ){
memcpy (pAttrVal、value、len);
*pVallen = len;//更新读取和获取的长度。
IF (sendNotitiInd)
{
log_info2 ("正在尝试发送通知/提示:connHandle %x、%s"、
(IArg) attrConfig[0]。connHandle、
(IARg)((attrConfig[0].value==0)?"\x1b[33mNoti/ind disabled \x1b[0m":
(attrConfig[0].value==1)?"通知已启用":
"指示已启用");
//尝试发送通知。
GATTServApp_ProcessCharCfg (atConfig、pAttrVal、needAuth、
HALO_ServiceAttrTbl、GATT_NUM_ATTRS (Halo_ServiceAttrTbl)、
BS_iCall_rs_task_id、HALO_Service_ReadAttrCB);
}
}
否则
{
log_error3 ("边界外的长度:len:%d minlen:%d maxLen:%d."、(IArg) len、(IArg) valMinLen、(IArg) valMaxLen;
RET = bleInvalidRange;
}
return;
}
//
* HaloService_GetParameter -获取 HaloService 参数。
*
* param -配置文件参数 ID
* len -指向包含可写入*值的最大长度的变量的指针。
调用后、该值将包含实际返回的长度。
* value -指向要写入的数据的指针。 这取决于
* 参数 ID 和可被转换为相应
的* 数据类型(例如:uint16_t 的数据类型将转换为
* uint16_t 指针)。
//
bStatus_t HaloService_GetParameter (uint8_t param、uint16_t * len、void * value)
{
bStatus_t ret = Success;
switch (param)
{
默认值:
log_error1 ("GetParameter:参数#%d 无效。"、(IArg)param);
RET = INVALIDPARAMETER;
中断;
}
返回;
}
/*********
*@内部
*@fn HALO_Service_findCharParamId
*
*@简介 在服务的 attr 表中查找属性的逻辑参数 ID。
*
* 仅适用于特征值属性和
* 客户端特征配置描述符属性。
*
*@param pAttr -指向属性
*
*@return 的指针 uint8_t paramID (参考 HALO_SERVICE.h)或0xFF (如果未找到)。
*/
static uint8_t HALO_Service_findCharParamId (gattAttribute_t *pAttr)
{
//这是一个客户端特征配置描述符吗?
if (ATT_BT_UUID_SIZE = pAttr->type.len & GATT_CLIENT_CHAR_CFG_UUID =*(uint16_t *) pAttr->type.uuid)
返回 HALL_Service_findCharParamId (pAttr - 1);//假设 value 属性在 CCCD 和递归之前
//此属性是否在"offset"中?
如果(ATT _ UUID_SIZE =pAttr->type.len &&!memcmp (pAttr->type.uuid、HS_OFFSETUUID、pAttr->type.len))则为其他值
返回 HS_OFFSET_ID;
//此属性是否位于"ONOFFREC"中?
如果(ATT _ UUID_size =pAttr->type.len &&!memcmp (pAttr->type.uuid、HS_ONOFFRECUUID、pAttr->type.len))则为其他值
返回 HS_ONOFFREC_ID;
//此属性是否在"TOTALTIME 中?
如果(ATT _ UUID_SIZE =pAttr->type.len &&!memcmp (pAttr->type.uuid、HS_TOTALTIMEUUID、pAttr->type.len))则为其他值
返回 HS_TOTALTIME_ID;
否则
返回0xFF;//未找到。 返回无效。
}
/*********
*@fn HALO_Service_ReadAttrCB
*
*@简介 读取属性。
*
*@param connHandle -在
*@param 上接收到连接消息 pAttr -指向属性
*@param 的指针 pValue -指向要读取的数据的指针
*@param PLEN -要读取的数据长度
*@param offset -要读取的第一个八位位组的偏移
*@param maxLen -要读取的数据的最大长度
*@param 方法-读取消息的类型
*
*@return 成功、blePending 或失败
*/
static bStatus_t Halo_Service_ReadAttrCB (uint16_t connHandle、gattAttribute_t *pAttr、
uint8_t * pValue、uint16_t * PLEN、uint16_t offset、
uint16_t maxLen、uint8_t method)
{
bStatus_t status = Success;
uint16_t valueLen;
uint8_t paramID = 0xFF;
//查找要读取的特征的设置。
paramID = HALO_Service_findCharParamId( pAttr );
switch ( paramID )
{
案例 HS_OFFSET_ID:
valueLen = HS_OFFSETValLen;
log_info4 ("ReadAttrCB:%s connHandle:%d offset:%d method:0x%02x"、
(IArg)"偏移"、
(IArg) connHandle、
(IArg)偏移、
(IArg)方法);
/*可以在此处插入有关偏移的其他注意事项*/
中断;
案例 HS_ONOFFREC_ID:
valueLen = HS_ONOFFRECValLen;
log_info4 ("ReadAttrCB:%s connHandle:%d offset:%d method:0x%02x"、
(IARg)"ONOFFREC"、
(IArg) connHandle、
(IArg)偏移、
(IArg)方法);
//此处可插入有关 ONOFFREC 的其他注意事项*/
中断;
案例 HS_TOTALTIME_ID:
valueLen = HS_TOTALTIMEValLen;
log_info4 ("ReadAttrCB:%s connHandle:%d offset:%d method:0x%02x"、
(IArg)"TOTALTIME (TOTALTIME)"、
(IArg) connHandle、
(IArg)偏移、
(IArg)方法);
//此处可插入 TOTALTIME 的其他注意事项*/
中断;
默认值:
log_error0 ("未找到属性。");
返回 ATT_ERR_ATTR_NOT FOUND;
}
//检查边界并返回值
,如果(offset > valueLen)//防止恶意的 ATT ReadBlob 偏移。
{
log_error0 ("请求的偏移无效。");
状态= ATT_ERR_INVALID_OFFSET;
}
否则
{
* PLEN = min (maxLen、valueLen - offset);//尽可能发送
memcpy (pValue、pAttr->pValue + offset、* PLEN);
}
返回状态;
}
/*********
*@fn HALO_Service_WriteAttrCB
*
@简要在写入操作之前验证属性数据
*
*@param connHandle -在
*@param pAttr 上接收到连接消息-指向属性的指针
*@param pValue -指向要写入的数据的指针
*@param len -数据长度
*@param offset - 要写入的第一个八位位组的偏移
*@param 方法-写入消息类型
*
*@返回成功、blePending 或失败
*/
static bStatus_t Halo_Service_WriteAttrCB (uint16_t connHandle、gattAttribute_t *pAttr、
uint8_t *pValue、uint16_t len、uint16_t offset、
uint8_t 方法)
{
bStatus_t status =成功;
uint8_t paramID = 0xFF;
uint8_t changeParamID = 0xFF;
uint16_t writeLenMin;
uint16_t writeLenMax;
uint16_t *pValueLenVar;
//查看请求是否与客户机特性配置有关//dle5 ????? 不是
if (ATT_BT_UUID_SIZE = pAttr->type.len & GATT_CLIENT_CHAR_CFG_UUID =*(uint16_t *) pAttr->type.uuid)
{
log_info3 ("WriteAttrCB (CCCD):参数:%d connHandle:%d %s"、
(IArg) HALO_Service_findCharParamId (pAttr)、
(IArg) connHandle、
(IArg)(方法= GATT_LOCAL_WRITE?"-恢复绑定状态":"- OTA 写入");
//允许通知和指示,但不要检查每个 CCCD 是否真正允许。
状态= GATTServApp_ProcessCCCWriteReq (connHandle、pAttr、pValue、len、
偏移量、GATT_CLIENT_CFG_NOTIFY |
GATT_CLIENT_CFG_Indicate);
if (成功=status && pAppCBs && pAppCBs->pfnCfgChangeCb)
pAppCBs->pfnCfgChangeCb (connHandle、HALO_SERVICE_SERV_UUID、
HALO_Service_findCharParamId (pAttr)、pValue、len);
//return status;//Dale removed
}
//dle5 start:添加了写入部分
//查找要写入的特征的设置。
paramID = HALO_Service_findCharParamId( pAttr );
switch ( paramID )
{
案例 HS_OFFSET_ID:
writeLenMin = HS_OFFSET_LEN_MIN;
writeLenMax = HS_OFFSET_LEN;
pValueLenVar =&hs_OFFSETValLen;
log_info5 ("WriteAttrCB:%s connHandle (%d) len (%d) offset (%d) method (0x%02x)"、
(IArg)"偏移"、
(IArg) connHandle、
(Iarg) len,
(IArg)偏移、
(IArg)方法);
/*可以在此处插入有关偏移的其他注意事项*/
中断;
案例 HS_ONOFFREC_ID:
writeLenMin = HS_ONOFFREC_LEN_MIN;
writeLenMax = HS_ONOFFREC_LEN;
pValueLenVar =&hs_ONOFFRECValLen;
log_info5 ("WriteAttrCB:%s connHandle (%d) len (%d) offset (%d) method (0x%02x)"、
(IARg)"ONOFFREC"、
(IArg) connHandle、
(Iarg) len,
(IArg)偏移、
(IArg)方法);
//此处可插入有关 ONOFFREC 的其他注意事项*/
中断;
案例 HS_TOTALTIME_ID:
writeLenMin = HS_TOTALTIME_LEN_MIN;
writeLenMax = HS_TOTALTIME_LEN;
pValueLenVar =&hs_TOTALTIMEValLen;
log_info5 ("WriteAttrCB:%s connHandle (%d) len (%d) offset (%d) method (0x%02x)"、
(IArg)"TOTALTIME (TOTALTIME)"、
(IArg) connHandle、
(Iarg) len,
(IArg)偏移、
(IArg)方法);
//此处可插入 TOTALTIME 的其他注意事项*/
中断;
默认值:
log_error0 ("未找到属性。");
返回 ATT_ERR_ATTR_NOT _ FOUND;
}
//检查长度是否在界限内。
if (offset >= writeLenMax)
{
log_error0 ("请求的偏移无效。");
状态= ATT_ERR_INVALID_OFFSET;
}
否则(offset + len > writeLenMax)
{
log_error0 ("接收到无效的值长度。");
状态= ATT_ERR_INVALID_VALUE SIZE;
}
否则(offset + len < writeLenMin &&(method = ATT_execute _WRITE_REQ || method = ATT_WRITE_REQ))
{
//拒绝低于最小值的写入。
//注:无法确定是否完成了可靠的写入(写入多个字符),因此这些字符将会完成
// 仅当此属性是队列中的最后一个属性时才被拒绝(方法为执行)。
// 否则、将接受可靠的写入并以零敲碎打的方式进行解析。
log_error0 ("接收到无效的值长度。");
状态= ATT_ERR_INVALID_VALUE SIZE;
}
其他
{
//将 pValue 复制到我们从属性表指向的变量中。
memcpy (pAttr->pValue + offset、pValue、len);
//仅在写入足够的数据时通知应用程序并更新长度。
//
//注意:如果使用可靠的写入(这意味着使用 ATT PrepareWrite 写入多个属性),
// 应用程序将为每次写入获得回调、偏移量+ len 大于_LEN_min。
//注意:对于长写入(ATT PREPARE + Execute 只针对一个属性),只会发出一个回调,
// 因为写入片段在发送到这里之前会连接在一起。
if (offset + len >= writeLenMin)
{
changeParamID = paramID;
*pValueLenVar =偏移+ len;//更新数据长度
。}
}
//使用让应用程序知道发生了哪些变化(如果发生了变化)
//将其回调到先前注册的位置(如果是)。
if (参数 ID!= 0xFF)
if (pAppCBs && pAppCBs->pfnChangeCb)
pAppCBs->pfnChangeCb( connHandle, HALO_SERVICE_SERV_UUID,paramID,pValue,len+offset ); //从堆栈任务上下文调用应用程序函数。
退货状态;
//Dale End:添加了写入部分
}
在这里、您可以看到、将"通知"设置为"是"(从主器件写入操作码0x12)的请求由从器件的"资源不足"响应:
