This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

simpleBLEperipheral修改特征值长度超过6后,lightblue不能写入特征值,只能读取

Other Parts Discussed in Thread: CC2541

        我在simpleGATTprofile.C、simpleGATTprofile.h、simpleBLEperipheral.c中修改好 char3 特征值的长度后发现一个奇怪的问题。只要把特征值长度修改超过6,每次用lightblue写入特征值,peripheral就会自动重启断开连接。但是修改特征值长度不超过6就可以正常写入。

       然而我把char3 改为可读可写,即使长度为20,都能正常读取特征值,却不能正常写入。希望有人帮忙解答~~~非常感激

  • 注意回调函数也要修改啊

    static bStatus_t simpleProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
    uint8 *pValue, uint8 len, uint16 offset,
    uint8 method )

    static bStatus_t simpleProfile_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
    uint8 *pValue, uint8 *pLen, uint16 offset,
    uint8 maxLen, uint8 method )

  • 下面是我在simpleProfile_WriteAttrCB添加的case(前面的case SIMPLEPROFILE_CHAR3_UUID已经注释掉)

    case SIMPLEPROFILE_CHAR3_UUID:
    if ( offset == 0 )
    {
    if ( len != SIMPLEPROFILE_CHAR3_LEN )
    {
    status = ATT_ERR_INVALID_VALUE_SIZE;

    }
    }
    else
    {
    status = ATT_ERR_ATTR_NOT_LONG;
    }

    //Write the value
    if ( status == SUCCESS )
    {
    VOID osal_memcpy( pAttr->pValue, pValue , SIMPLEPROFILE_CHAR3_LEN );
    notifyApp = SIMPLEPROFILE_CHAR3;
    }
    break;

    /********************************************************************************************/

    下面是simpleProfile_ReadAttrCB添加的部分

    case SIMPLEPROFILE_CHAR3_UUID:
    // *pLen = 1;
    // pValue[0] = *pAttr->pValue;
    *pLen = SIMPLEPROFILE_CHAR3_LEN;
    VOID osal_memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR3_LEN );
    break;

  • 我贴上读写回调函数的代码,有空帮忙看看,非常感谢~~!!!

  • 回调函数我有修改,回复里有贴上代码,请帮忙看看,非常感谢~~!!!

  • Read我跟你是一样的

    Write我写的是

    case SERIALPORTSERVICE_DATA_UUID:
    if ( offset == 0 )
    {
    if ( len > 20 )
    {
    status = ATT_ERR_INVALID_VALUE_SIZE;
    }
    }
    else
    {
    status = ATT_ERR_ATTR_NOT_LONG;
    }

    //Write the value
    if ( status == SUCCESS )
    {
    uint8 i = 0;
    uint8 *pCurValue = (uint8 *)pAttr->pValue;
    for ( i = 0; i<len; i++)
    {
    *pCurValue = pValue[i];
    pCurValue++;
    };
    if(len < 20)
    {
    for (i; i<20; i++)
    {
    *pCurValue = 0;
    *pCurValue ++;
    }
    }
    notifyApp = SERIALPORTSERVICE_CHAR_DATA;
    }

    break;

    所以感觉是数据长度的问题

  • 我修改成你的代码,然后每次用lightblue写这个特征值,peripheral都会重启。然后我试着将特征长度改为6,那又正常了。所以你的代码和我的代码都一样,只要特征长度超过6就会出现同样的情况。

  • 那就不是这里引起的 看看别的地方 是不是SimpleProfile_SetParameter 和 SimpleProfile_GetParameter

  • 应该不是这两个函数的问题吧~~~这两个函数很简单啊

    SimpleProfile_SetParameter  中修改如下:

    case SIMPLEPROFILE_CHAR3:
    // if ( len == sizeof ( uint8 ) )
    if ( len == SIMPLEPROFILE_CHAR3_LEN )
    {
    // simpleProfileChar3 = *((uint8*)value);
    VOID osal_memcpy( simpleProfileChar3, value, SIMPLEPROFILE_CHAR3_LEN );

    }
    else
    {
    ret = bleInvalidRange;
    }
    break;

    /**********************************************************************************************/

    SimpleProfile_GetParameter  中修改如下:

    case SIMPLEPROFILE_CHAR3:
    // *((uint8*)value) = simpleProfileChar3;
    VOID osal_memcpy( value, simpleProfileChar3, SIMPLEPROFILE_CHAR3_LEN );
    break;

    /**********************************************************************************************/

  • Set:

    case SERIALPORTSERVICE_CHAR_DATA:

    if( len <= SERIALPORTSERVICE_DATA_LEN )
    {
    VOID memcpy( SerialPortServiceData, value, len );

    // See if Notification has been enabled
    GATTServApp_ProcessCharCfg( SerialPortServiceDataConfig, SerialPortServiceData, FALSE,
    SerialPortServiceAttrTbl, GATT_NUM_ATTRS( SerialPortServiceAttrTbl ),
    INVALID_TASK_ID, SerialPortService_ReadAttrCB );
    }
    else
    {
    ret = bleInvalidRange;
    }
    break;

    Get:

    case SERIALPORTSERVICE_CHAR_DATA:


    VOID memcpy( value, SerialPortServiceData, SERIALPORTSERVICE_DATA_LEN );
    break;

  • 除了上面的函数以外,剩下的就是特征值的初始化了,但是几个地方都是改改数组大小内容,应该不会出错。想不明白为什么长度就是超过6就有这情况。。。

  • 这个肯定是代码的问题,只能自己查一下,我这边的特征值长度是20是没有问题的。你每次都写入固定长度的数值吗?有没有对数值初始化?

  • 建议自己重新添加一个新的UUID试一下,在原有的基础上改是会有一些奇怪的问题。

    我的新添加的,20字节,读写都没问题。

  • 刚才你发的SimpleProfile_SetParameter 代码那部分是notify属性的case吧?我修改的notify属性的特征值长度是20也是没有问题的。但是我现在用的是read、write属性才出现问题。lightblue读取这个特征值正常,就是不能写。只要我设置特征值长度少于6,我用lightblue写入什么长度都能正常。

    我在simpleGATTprofile.C初始化:

    #define SIMPLEPROFILE_CHAR3_LEN           6

    static uint8 simpleProfileChar3Props = GATT_PROP_READ | GATT_PROP_WRITE;

    // Characteristic 3 Value
    static uint8 simpleProfileChar3[SIMPLEPROFILE_CHAR3_LEN] = { 0, 0,0, 0,0,0};

    ?***************************************************************************************************************/

    在simpleBLEperipheral.c初始化:

    uint8 charValue3[SIMPLEPROFILE_CHAR3_LEN] = {1,2,3,4,5,6};

    SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR3, SIMPLEPROFILE_CHAR3_LEN, charValue3 );

  • 我的特征值的属性是GATT_PROP_WRITE_NO_RSP | GATT_PROP_NOTIFY;

    所以应该是可以被写入的 长度是20

    看看这个函数里面是不是改了呢

    static void SerialPortBLE_processCharValueChangeEvt(uint8_t paramID)

  • 你说的函数我没有找到,但是我像前面有人说的新建一个特征值就正常写入了。但是我新建的特征方式与之前修改的方式一样。

  • 是的,我今天尝试新建一个特征值就没有问题了~~但是方法都是一样的,真奇怪~~~

  • 没有这个函数 所以你应该是在CC2541上面吧?试看看这个例程..

    http://processors.wiki.ti.com/index.php/SerialBLEbridge

  • 能不能发一个BLE主从机的工程来?我修改特征值不成功,长度超过16就不行了。求一个修改长度为20的工程。邮箱:13729017278@163.com