您的位置:首页 > 产品设计 > UI/UE

CC2650 之UUID配置

2016-04-01 14:24 453 查看
CC2650与CC2541的配置是相似的,先不看操作系统的对任务的调度,方便大家理解2650的工作流程,首先是CC2650的初始化,初始化的流程在simpleBLEPreipheral.c中。执行的流程是在main.c中对参数进行配置,然后开始调用BIOS_start();开始跑系统,基本参数配置完成开始进行广播,

void SimpleBLEPeripheral_createTask(void)

{

  Task_Params taskParams;

  // Configure task

  Task_Params_init(&taskParams);

  taskParams.stack = sbpTaskStack;

  taskParams.stackSize = SBP_TASK_STACK_SIZE;

  taskParams.priority = SBP_TASK_PRIORITY;

  Task_construct(&sbpTask, SimpleBLEPeripheral_taskFxn, &taskParams, NULL);

} 通过这个函数对SimpleBLEPeripheral_taskFxn进行注册任务,

任务注册完后就开始执行SimpleBLEPeripheral_taskFxn函数,在这个函数中先执行SimpleBLEPeripheral_init();

static void SimpleBLEPeripheral_init(void)

{

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

  // N0 STACK API CALLS CAN OCCUR BEFORE THIS CALL TO ICall_registerApp

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

  // Register the current thread as an ICall dispatcher application

  // so that the application can send and receive messages.

  ICall_registerApp(&selfEntity, &sem);

  // 以下功能为修改mac地址

  // Hard code the BD Address till CC2650 board gets its own IEEE address

  //uint8 bdAddress[B_ADDR_LEN] = { 0xAD, 0xD0, 0x0A, 0xAD, 0xD0, 0x0A };

  //HCI_EXT_SetBDADDRCmd(bdAddress);

  // Set device's Sleep Clock Accuracy

  //HCI_EXT_SetSCACmd(40);

  // Create an RTOS queue for message from profile to be sent to app.

  appMsgQueue = Util_constructQueue(&appMsg);

  // Create one-shot clocks for internal periodic events.

  Util_constructClock(&periodicClock, SimpleBLEPeripheral_clockHandler,

                      SBP_PERIODIC_EVT_PERIOD, 0, true, SBP_PERIODIC_EVT);

  Util_constructClock(&BuzzerClock, SimpleBLEPeripheral_clockHandler,

                      200, 0, false, SBP_BUZZER_EVT);

  Board_initKeys(SimpleBLEPeripheral_keyChangeHandler);

  // led初始化

  HalLedInit();

  

#ifndef SENSORTAG_HW

  Board_openLCD();

#endif //SENSORTAG_HW

  

#if SENSORTAG_HW

  // Setup SPI bus for serial flash and Devpack interface

  bspSpiOpen();

#endif //SENSORTAG_HW

  

  // Setup the GAP

  GAP_SetParamValue(TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL);

  // Setup the GAP Peripheral Role Profile

  {

    // For all hardware platforms, device starts advertising upon initialization

    uint8_t initialAdvertEnable = TRUE;

    // By setting this to zero, the device will go into the waiting state after

    // being discoverable for 30.72 second, and will not being advertising again

    // until the enabler is set back to TRUE

    uint16_t advertOffTime = 0;

    uint8_t enableUpdateRequest = DEFAULT_ENABLE_UPDATE_REQUEST;

    uint16_t desiredMinInterval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;

    uint16_t desiredMaxInterval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;

    uint16_t desiredSlaveLatency = DEFAULT_DESIRED_SLAVE_LATENCY;

    uint16_t desiredConnTimeout = DEFAULT_DESIRED_CONN_TIMEOUT;

    // Set the GAP Role Parameters

    GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),

                         &initialAdvertEnable);

    GAPRole_SetParameter(GAPROLE_ADVERT_OFF_TIME, sizeof(uint16_t),

                         &advertOffTime);

    GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData),

                         scanRspData);

    GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);

    GAPRole_SetParameter(GAPROLE_PARAM_UPDATE_ENABLE, sizeof(uint8_t),

                         &enableUpdateRequest);

    GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t),

                         &desiredMinInterval);

    GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t),

                         &desiredMaxInterval);

    GAPRole_SetParameter(GAPROLE_SLAVE_LATENCY, sizeof(uint16_t),

                         &desiredSlaveLatency);

    GAPRole_SetParameter(GAPROLE_TIMEOUT_MULTIPLIER, sizeof(uint16_t),

                         &desiredConnTimeout);

  }

  // Set the GAP Characteristics

  GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);

  // Set advertising interval

  {

    uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;

    GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MIN, advInt);

    GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MAX, advInt);

    GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, advInt);

    GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, advInt);

  }

  // Setup the GAP Bond Manager

  {

    uint32_t passkey = 0; // passkey "000000"

    uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;

    uint8_t mitm = TRUE;

    uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;

    uint8_t bonding = TRUE;

    GAPBondMgr_SetParameter(GAPBOND_DEFAULT_PASSCODE, sizeof(uint32_t),

                            &passkey);

    GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);

    GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm);

    GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);

    GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t), &bonding);

  }

   // Initialize GATT attributes

  GGS_AddService(GATT_ALL_SERVICES);           // GAP

  GATTServApp_AddService(GATT_ALL_SERVICES);   // GATT attributes

  DevInfo_AddService();                        // Device Information Service

#ifndef FEATURE_OAD

  SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile

#endif //!FEATURE_OAD

#ifdef FEATURE_OAD

  VOID OAD_addService();                 // OAD Profile

  OAD_register((oadTargetCBs_t *)&simpleBLEPeripheral_oadCBs);

  hOadQ = Util_constructQueue(&oadQ);

#endif

#ifdef IMAGE_INVALIDATE

  Reset_addService();

#endif //IMAGE_INVALIDATE

  

  

#ifndef FEATURE_OAD

  // Setup the SimpleProfile Characteristic Values

  {

    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);

  }

  // Register callback with SimpleGATTprofile

  SimpleProfile_RegisterAppCBs(&SimpleBLEPeripheral_simpleProfileCBs);

#endif //!FEATURE_OAD

  // Start the Device

  VOID GAPRole_StartDevice(&SimpleBLEPeripheral_gapRoleCBs);

  // Start Bond Manager

  VOID GAPBondMgr_Register(&simpleBLEPeripheral_BondMgrCBs);

  // Register with GAP for HCI/Host messages

  GAP_RegisterForMsgs(selfEntity);

  

  // Register for GATT local events and ATT Responses pending for transmission

  GATT_RegisterForMsgs(selfEntity);

  // 串口初始化  

  Uart_Init();

  // pwm 输出初始化

  board_pwm_init();

  board_pwm_start(4096, 50);

  Util_startClock(&BuzzerClock);

}通过这个函数对设备进行配置,这个函数真的很重要,一定要弄懂。

然后就是static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1)函数

 通过一个for循环对任务进行查询,

{

  // Initialize application

  SimpleBLEPeripheral_init();

  // Application main loop

  for (;;)

  {

    // Waits for a signal to the semaphore associated with the calling thread.

    // Note that the semaphore associated with a thread is signaled when a

    // message is queued to the message receive queue of the thread or when

    // ICall_signal() function is called onto the semaphore.

    ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);

    if (errno == ICALL_ERRNO_SUCCESS)

    {

      ICall_EntityID dest;

      ICall_ServiceEnum src;

      ICall_HciExtEvt *pMsg = NULL;

      if (ICall_fetchServiceMsg(&src, &dest,

                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)

      {

        uint8 safeToDealloc = TRUE;

        

        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))

        {

          ICall_Event *pEvt = (ICall_Event *)pMsg;

          

          /
b298
/ Check for BLE stack events first

          if (pEvt->signature == 0xffff)

          {

            if (pEvt->event_flag & SBP_CONN_EVT_END_EVT)

            {

              // Try to retransmit pending ATT Response (if any)

              SimpleBLEPeripheral_sendAttRsp();

            }

          }

          else

          {

            // Process inter-task message

            safeToDealloc = SimpleBLEPeripheral_processStackMsg((ICall_Hdr *)pMsg);

          }

        }

        if (pMsg && safeToDealloc)

        {

          ICall_freeMsg(pMsg);

        }

      }

      // If RTOS queue is not empty, process app message.

      while (!Queue_empty(appMsgQueue))

      {

        sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue);

        if (pMsg)

        {

          // Process message.

          SimpleBLEPeripheral_processAppMsg(pMsg);

          // Free the space from the message.

          ICall_free(pMsg);

        }

      }

    }

{

  // Initialize application

  SimpleBLEPeripheral_init();

  // Application main loop

  for (;;)

  {

    // Waits for a signal to the semaphore associated with the calling thread.

    // Note that the semaphore associated with a thread is signaled when a

    // message is queued to the message receive queue of the thread or when

    // ICall_signal() function is called onto the semaphore.

    ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);

    if (errno == ICALL_ERRNO_SUCCESS)

    {

      ICall_EntityID dest;

      ICall_ServiceEnum src;

      ICall_HciExtEvt *pMsg = NULL;

      if (ICall_fetchServiceMsg(&src, &dest,

                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)

      {

        uint8 safeToDealloc = TRUE;

        

        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))

        {

          ICall_Event *pEvt = (ICall_Event *)pMsg;

          

          // Check for BLE stack events first

          if (pEvt->signature == 0xffff)

          {

            if (pEvt->event_flag & SBP_CONN_EVT_END_EVT)

            {

              // Try to retransmit pending ATT Response (if any)

              SimpleBLEPeripheral_sendAttRsp();

            }

          }

          else

          {

            // Process inter-task message

            safeToDealloc = SimpleBLEPeripheral_processStackMsg((ICall_Hdr *)pMsg);

          }

        }

        if (pMsg && safeToDealloc)

        {

          ICall_freeMsg(pMsg);

        }

      }

      // If RTOS queue is not empty, process app message.

      while (!Queue_empty(appMsgQueue))

      {

        sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue);

        if (pMsg)

        {

          // Process message.

          SimpleBLEPeripheral_processAppMsg(pMsg);

          // Free the space from the message.

          ICall_free(pMsg);

        }

      }

    }

然后就是在simpleGATTprofile.c和simpleGATTprofile.h中对UUID进行设置,通信的读写限制,数据大小等。

在static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] = 

{

  // Simple Profile Service

  { 

    { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */

    GATT_PERMIT_READ,                         /* permissions */

    0,                                        /* handle */

    (uint8 *)&simpleProfileService            /* pValue */

  },

    // Characteristic 1 Declaration

    { 

      { ATT_BT_UUID_SIZE, characterUUID },

      GATT_PERMIT_READ, 

      0,

      &simpleProfileChar1Props 

    },

      // Characteristic Value 1

      { 

        { ATT_BT_UUID_SIZE, simpleProfilechar1UUID },

        GATT_PERMIT_READ | GATT_PERMIT_WRITE, 

        0, 

        &simpleProfileChar1 

      },

      // Characteristic 1 User Description

      { 

        { ATT_BT_UUID_SIZE, charUserDescUUID },

        GATT_PERMIT_READ, 

        0, 

        simpleProfileChar1UserDesp 

      },      

    // Characteristic 2 Declaration

    { 

      { ATT_BT_UUID_SIZE, characterUUID },

      GATT_PERMIT_READ, 

      0,

      &simpleProfileChar2Props 

    },

      // Characteristic Value 2

      { 

        { ATT_BT_UUID_SIZE, simpleProfilechar2UUID },

        

         GATT_PERMIT_READ | GATT_PERMIT_WRITE,

        0, 

        &simpleProfileChar2 

      },

      // Characteristic 2 User Description

      { 

        { ATT_BT_UUID_SIZE, charUserDescUUID },

        GATT_PERMIT_READ, 

        0, 

        simpleProfileChar2UserDesp 

      },           

      

    // Characteristic 3 Declaration

    { 

      { ATT_BT_UUID_SIZE, characterUUID },

      GATT_PERMIT_READ, 

      0,

      &simpleProfileChar3Props 

    },

      // Characteristic Value 3

      { 

        { ATT_BT_UUID_SIZE, simpleProfilechar3UUID },

         GATT_PERMIT_READ | GATT_PERMIT_WRITE,

        0, 

        &simpleProfileChar3 

      },

      // Characteristic 3 User Description

      { 

        { ATT_BT_UUID_SIZE, charUserDescUUID },

        GATT_PERMIT_READ, 

        0, 

        simpleProfileChar3UserDesp 

      },

    // Characteristic 4 Declaration

    { 

      { ATT_BT_UUID_SIZE, characterUUID },

      GATT_PERMIT_READ, 

      0,

      &simpleProfileChar4Props 

    },

      // Characteristic Value 4

      { 

        { ATT_BT_UUID_SIZE, simpleProfilechar4UUID },

         GATT_PERMIT_READ | GATT_PERMIT_WRITE,

        0, 

        &simpleProfileChar4 

      },

      // Characteristic 4 configuration

      { 

        { ATT_BT_UUID_SIZE, clientCharCfgUUID },

        GATT_PERMIT_READ  ,

        0, 

        (uint8 *)&simpleProfileChar4Config 

      },

      

      // Characteristic 4 User Description

      { 

        { ATT_BT_UUID_SIZE, charUserDescUUID },

        GATT_PERMIT_READ, 

        0, 

        simpleProfileChar4UserDesp 

      },

      

    // Characteristic 5 Declaration

    { 

      { ATT_BT_UUID_SIZE, characterUUID },

      GATT_PERMIT_READ, 

      0,

      &simpleProfileChar5Props 

    },

      // Characteristic Value 5

      { 

        { ATT_BT_UUID_SIZE, simpleProfilechar5UUID },

         GATT_PERMIT_READ | GATT_PERMIT_WRITE,

        0, 

        simpleProfileChar5 

      },

      // Characteristic 5 User Description

      { 

        { ATT_BT_UUID_SIZE, charUserDescUUID },

        GATT_PERMIT_READ, 

        0, 

        simpleProfileChar5UserDesp 

      },

};

对UUID读写权限进行设置,和数据的大小。

通过static bStatus_t simpleProfile_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;

  // If attribute permissions require authorization to read, return error

  if ( gattPermitAuthorRead( pAttr->permissions ) )

  {

    // Insufficient authorization

    return ( ATT_ERR_INSUFFICIENT_AUTHOR );

  }

  

  // Make sure it's not a blob operation (no attributes in the profile are long)

  if ( offset > 0 )

  {

    return ( ATT_ERR_ATTR_NOT_LONG );

  }

 

  if ( pAttr->type.len == ATT_BT_UUID_SIZE )

  {

    // 16-bit UUID

    uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);

    switch ( uuid )

    {

      // No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;

      // gattserverapp handles those reads

      // characteristics 1 and 2 have read permissions

      // characteritisc 3 does not have read permissions; therefore it is not

      //   included here

      // characteristic 4 does not have read permissions, but because it

      //   can be sent as a notification, it is included here

      case SIMPLEPROFILE_CHAR1_UUID:

      case SIMPLEPROFILE_CHAR2_UUID:

      case   SIMPLEPROFILE_CHAR3_UUID: 

      case SIMPLEPROFILE_CHAR4_UUID:

        *pLen = 1;

        pValue[0] = *pAttr->pValue;

        break;

      case SIMPLEPROFILE_CHAR5_UUID:

        *pLen = SIMPLEPROFILE_CHAR5_LEN;

        VOID memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR5_LEN );

        break;

        

      default:

        // Should never get here! (characteristics 3 and 4 do not have read permissions)

        *pLen = 0;

        status = ATT_ERR_ATTR_NOT_FOUND;

        break;

    }

  }

  else

  {

    // 128-bit UUID

    *pLen = 0;

    status = ATT_ERR_INVALID_HANDLE;

  }

  return ( status );

}这个函数进行数据的读取和处理,我们也可以通过 这结构去添加自己的属性函数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: