打印
[CC2640]

CC2640修改Profile实现蓝牙发送回传

[复制链接]
822|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
coshi|  楼主 | 2020-2-2 11:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
CC2640修改Simple GATT Profile Service

通过修改特征值Characteristic 4,实现手机使用Ble软件 发送字符串命令给开发板,开发板收到对应命令后,也发送对应字符串给手机。



Declaration总是属性的值之前,描述了价值属性是否可以读取或写入





首先找到simple_gatt_profile.c文件,找到

// Simple Profile Characteristic 4 Properties

static uint8 simpleProfileChar4Props = GATT_PROP_NOTIFY;

修改成

// Simple Profile Characteristic 4 Properties

static uint8 simpleProfileChar4Props = GATT_PROP_WRITE | GATT_PROP_NOTIFY;

这样, 在手机端就可以看到Characteristic 4能够写入字符



然后修改

// Characteristic 4 Value

static uint8 simpleProfileChar4 = 0;



// Characteristic 4 Value

static uint8 simpleProfileChar4[20] = {0};

这里改成20个长度的数组,(20长度对于输入普通命令基本够用,对于更长的长度,理论上应该支持到256,但我并没有尝试)



然后修改属性表Profile Attributes – Table

// Characteristic Value 4

{

{ ATT_BT_UUID_SIZE, simpleProfilechar4UUID },

0,

0,

&simpleProfileChar4

},

改成

// Characteristic Value 4

{

{ ATT_BT_UUID_SIZE, simpleProfilechar4UUID },

GATT_PERMIT_READ | GATT_PERMIT_WRITE,//增加读写属性

0,

simpleProfileChar4

},



然后修改 SimpleProfile_SetParameter函数中的判断添加和赋值

case SIMPLEPROFILE_CHAR4:

if ( len == sizeof ( uint8 ) )

{

simpleProfileChar4 = *((uint8*)value);



// See if Notification has been enabled

GATTServApp_ProcessCharCfg( simpleProfileChar4Config, &simpleProfileChar4, FALSE,

simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),

INVALID_TASK_ID, simpleProfile_ReadAttrCB );

}









case SIMPLEPROFILE_CHAR4:

//if ( len == sizeof ( uint8 ) )

if ( len <= 20)

{

//simpleProfileChar4 = *((uint8*)value);

memcpy(simpleProfileChar4,value,20);



// See if Notification has been enabled

GATTServApp_ProcessCharCfg( simpleProfileChar4Config, simpleProfileChar4, FALSE,

simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),

INVALID_TASK_ID, simpleProfile_ReadAttrCB );

}


使用特权

评论回复

相关帖子

沙发
coshi|  楼主 | 2020-2-2 11:11 | 只看该作者
然后修改SimpleProfile_GetParameter函数中的 case SIMPLEPROFILE_CHAR4:

case SIMPLEPROFILE_CHAR4:

*((uint8*)value) = simpleProfileChar4;

break;



case SIMPLEPROFILE_CHAR4:

//*((uint8*)value) = simpleProfileChar4;

memcpy(value,simpleProfileChar4,20);

break;



然后在 simpleProfile_ReadAttrCB函数中增加 case SIMPLEPROFILE_CHAR4_UUID:



case SIMPLEPROFILE_CHAR1_UUID:

case SIMPLEPROFILE_CHAR2_UUID:

case SIMPLEPROFILE_CHAR4_UUID:

*pLen = 1;

pValue[0] = *pAttr->pValue;

break;



//case SIMPLEPROFILE_CHAR1_UUID:

//case SIMPLEPROFILE_CHAR2_UUID:

case SIMPLEPROFILE_CHAR4_UUID:

*pLen = 20;

//pValue[0] = *pAttr->pValue;

memcpy(pValue,pAttr->pValue,20);

break;



修改 simpleProfile_WriteAttrCB函数添加

case SIMPLEPROFILE_CHAR1_UUID:

case SIMPLEPROFILE_CHAR3_UUID:



case SIMPLEPROFILE_CHAR1_UUID:

case SIMPLEPROFILE_CHAR3_UUID:

case SIMPLEPROFILE_CHAR4_UUID:

修改

if ( offset == 0 )

{

if ( len != 1 )

{

status = ATT_ERR_INVALID_VALUE_SIZE;

}

}



if ( offset == 0 )

{

if ( len > 20 )

{

status = ATT_ERR_INVALID_VALUE_SIZE;

}

}


使用特权

评论回复
板凳
coshi|  楼主 | 2020-2-2 11:12 | 只看该作者
修改

//Write the value

if ( status == SUCCESS )

{

uint8 *pCurValue = (uint8 *)pAttr->pValue;

*pCurValue = pValue[0];



if( pAttr->pValue == &simpleProfileChar1 )

{

notifyApp = SIMPLEPROFILE_CHAR1;

}

else

{

notifyApp = SIMPLEPROFILE_CHAR3;

}

}



break;



//Write the value

if ( status == SUCCESS )

{

uint8 *pCurValue = (uint8 *)pAttr->pValue;

//*pCurValue = pValue[0];

memcpy(pCurValue,pValue,20);

notifyApp = SIMPLEPROFILE_CHAR4;

}



break;



使用特权

评论回复
地板
coshi|  楼主 | 2020-2-2 11:13 | 只看该作者
//------------------------------------------------------

修改特征值初始化

{

uint8_t charValue1 = 1;

uint8_t charValue2 = 2;

uint8_t charValue3 = 3;

uint8_t charValue4 = 4;

uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };



SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t),

&charValue1);

SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t),

&charValue2);

SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t),

&charValue3);

SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),

&charValue4);

SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN,

charValue5);

}



{

uint8_t charValue1 = 1;

uint8_t charValue2 = 2;

uint8_t charValue3 = 3;

uint8_t charValue4[20] = {0};

uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };



SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t),

&charValue1);

SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t),

&charValue2);

SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t),

&charValue3);

SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, 20,

charValue4);

SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN,

charValue5);

}



当手机蓝牙连接以后,发送字符串将会回调用SimplePeripheral_processCharValueChangeEvt函数

修改

static void SimplePeripheral_processCharValueChangeEvt(uint8_t paramId)

{

uint8_t newValue;



switch(paramId)

{

case SIMPLEPROFILE_CHAR1:

SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, &newValue);



Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "Char 1: %d", (uint16_t)newValue);

break;



case SIMPLEPROFILE_CHAR3:

SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &newValue);



Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "Char 3: %d", (uint16_t)newValue);

break;



default:

// should not reach here!

break;

}

}



static void SimplePeripheral_processCharValueChangeEvt(uint8_t paramId)

{

uint8_t newValue[20] = {0};

switch(paramId)

{





case SIMPLEPROFILE_CHAR4:

SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR4, newValue);

Display_printf(dispHandle, 20, 0, "Char 4: %s", (char *)newValue);

// If the RPA has changed, update the display

SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(newValue), newValue);

//Display_printf(dispHandle, MR_ROW_CHARSTAT, 0, "Char 3: %d", (uint16_t)newValue);

break;



default:

// should not reach here!

break;

}

}

其中 SimpleProfile_GetParameter获取手机端接收到字符串

SimpleProfile_SetParameter发送字符串到手机端(手机端需要打开notify,最多单次调用该函数4次)





函数SimplePeripheral_performPeriodicTask其中的内容可以全部注释掉

static void SimplePeripheral_performPeriodicTask(void)

{

#if 0

uint8_t valueToCopy;



// Call to retrieve the value of the third characteristic in the profile

if (SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &valueToCopy) == SUCCESS)

{

// Call to set that value of the fourth characteristic in the profile.

// Note that if notifications of the fourth characteristic have been

// enabled by a GATT client device, then a notification will be sent

// every time this function is called.

SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),

&valueToCopy);

}

#endif

}

该函数默认 每3秒执行一次


使用特权

评论回复
5
nawu| | 2020-3-1 10:56 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
6
tfqi| | 2020-3-1 11:04 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
7
aoyi| | 2020-3-1 11:11 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
8
qcliu| | 2020-3-1 11:15 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
9
wiba| | 2020-3-1 11:22 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

96

主题

3309

帖子

4

粉丝