BLE發送接收任意字節數據

一、前言

BLE的SimpleBLECentral和SimpleBLEPeripheral例程是通過SIMPLEPROFILE_CHAR1來發送接收一個字節的數據的。要想發送多個字節的數據,必須修改simpleGATTprofile.c中與SIMPLEPROFILE_CHAR1相關的參數和函數。

二、修改

詳細可以參考例程中的SIMPLEPROFILE_CHAR5。

1.定義長度、定義數組

在simpleGATTprofile.h中定義長度:

 // Length of Characteristic 1 in bytes
 define SIMPLEPROFILE_CHAR1_LEN   32

在simpleGATTprofile.c中定義數組:

// Characteristic 1 Value
static uint8 simpleProfileChar1[SIMPLEPROFILE_CHAR1_LEN] = {0};

2.修改Characteristic Value

      // Characteristic Value 1
      {
        { ATT_BT_UUID_SIZE, simpleProfilechar1UUID },
        GATT_PERMIT_READ | GATT_PERMIT_WRITE,
        0,
        simpleProfileChar1
      },

3.修改SimpleProfile_SetParameter函數

          //if ( len == sizeof ( uint8 ) )
          //{
          //  simpleProfileChar1 = *((uint8*)value);
          //}

改爲:

          if ( len == SIMPLEPROFILE_CHAR1_LEN )
          {
            VOID osal_memcpy( simpleProfileChar1, value, SIMPLEPROFILE_CHAR1_LEN );
          }

4.修改SimpleProfile_GetParameter函數

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

改爲:

         VOID osal_memcpy( value, simpleProfileChar1, SIMPLEPROFILE_CHAR1_LEN );

5.修改simpleProfile_WriteAttrCB函數

        //Validate the value
        // Make sure it's not a blob oper
       if ( offset == 0 )
       {
            #if 0
            if ( len != SIMPLEPROFILE_CHAR1_LEN )
            {
                status = ATT_ERR_INVALID_VALUE_SIZE;
            }
            #else
            if ( len > SIMPLEPROFILE_CHAR1_LEN )
            {
                status = ATT_ERR_INVALID_VALUE_SIZE;
            }
            #endif
        }
        else
        {
            status = ATT_ERR_ATTR_NOT_LONG;
        }
        //Write the value
        if ( status == SUCCESS )
        {
            uint8 *pCurValue = (uint8 *)pAttr->pValue;
            osal_memset(pCurValue,0,SIMPLEPROFILE_CHAR1_LEN);
            VOID osal_memcpy( pCurValue, pValue, len );
            if( pAttr->pValue == simpleProfileChar1 )
            {
                notifyApp = SIMPLEPROFILE_CHAR1;
            }
            else
            {
                notifyApp = SIMPLEPROFILE_CHAR3;
            }
        }

6.修改simpleProfile_ReadAttrCB函數

      case SIMPLEPROFILE_CHAR1_UUID:
          *pLen = SIMPLEPROFILE_CHAR1_LEN;
          VOID osal_memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR1_LEN );
          break;

三、測試

修改完成後,就可以在主機和從機當中測試了。

主機:

在simpleBLECentral_HandleKeys函數中:

      if ( simpleBLEDoWrite )  //沒有其他的讀寫操作就進行讀寫操作
      {
           // Do a write
           attWriteReq_t req;                   //寫請求格式結構體
           uint8 buf[] = "123456789abcdef";
           osal_memcpy(req.value,buf,sizeof(buf)/sizeof(buf[0]));
           req.handle = simpleBLECharHdl;       //發現特徵句柄
           req.len = sizeof(buf)/sizeof(buf[0]);
           req.sig = 0;                         //身份驗證簽名狀態  0:不包含  1:有效  2:無效
           req.cmd = 0;                         //命令標誌
           status = GATT_WriteCharValue( simpleBLEConnHandle, &req, simpleBLETaskId );
      }

在此將發送”123456789abcdef”字符串到從機。


從機:

在simpleProfileChangeCB函數中:

uint8 *newValue = (uint8*)osal_mem_alloc(8*32);

switch( paramID )
{
    case SIMPLEPROFILE_CHAR1:
      SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR1, newValue );  //獲得主機發來數據
      #if (defined HAL_LCD) && (HAL_LCD == TRUE)
        HalLcdWriteString((char*)newValue,  HAL_LCD_LINE_3 ); //顯示到LCD
      #endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
      break;
    default:
      // should not reach here!
      break;
}
osal_mem_free(newValue);

四、結語

本文主要是在SIMPLEPROFILE_CHAR1的基礎上修改的,SIMPLEPROFILE_CHAR1本來只可以發送1個字節,修改後最大可以發送在simpleGATTprofile.h中定義的長度,我定義的是32個字節,測試成功。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章