CC2640R2 ANCS

来源:互联网 发布:王者荣耀网络问卷调查 编辑:程序博客网 时间:2024/06/05 03:32

1.ANCS 

ANCS提供了通过BLE一个简单方便的方式来访问多种事件,在iOS设备上生成的通知,如来电,错过来电,新的电子邮件,等等。为了处理ANCS通知,附件必须外围设备实现了GATT的Client。这意味着iOS实现了GATT 服务器,它提供的数据将是通知。

2.

  • Notification Source: UUID: 9FBF120D-6301-42D9-8C58-25E699A21DBD (notifiable)
  • Control Point: UUID: 69D1D8F3-45E1-49A8-9821-9BBDFDAAD9D9 (writeable with response)
  • Data Source: UUID: 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB (notifiable)
3.大致需要改的地方如下:

static uint8_t AncsApp_advData[] ={  // Flags; this sets the device to use limited discoverable  // mode (advertises for 30 seconds at a time) instead of general  // discoverable mode (advertises indefinitely)  0x02, // length of this data    GAP_ADTYPE_FLAGS,  GAP_ADTYPE_FLAGS_GENERAL | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,  // Service Solicitation: this peripheral (NC) is looking for the ANCS service  // on the iOS device. As per Apple Bluetooth Design Guidelines, soliciting  // the ANCS service will cause the device to show up in the iOS settings app  0x11, // length of this data  GAP_ADTYPE_SERVICES_LIST_128BIT,  // ANCS service UUID  ANCS_SVC_UUID};
 //ANCS requires authentication, if the NP attempts to read/write chars on the //NP without proper authentication, the NP will respond with insufficent_athen //error to which we must respond with a slave security request else if  (pMsg->method == ATT_ERROR_RSP &&           pMsg->msg.errorRsp.reqOpcode == ATT_WRITE_REQ &&           pMsg->msg.errorRsp.errCode == ATT_ERR_INSUFFICIENT_AUTHEN) {   uint16 conn_handle;   GAPRole_GetParameter(GAPROLE_CONNHANDLE, &conn_handle);   uint8_t mitm;   uint8_t bonding;   GAPBondMgr_GetParameter(GAPBOND_MITM_PROTECTION, &mitm);   GAPBondMgr_GetParameter(GAPBOND_BONDING_ENABLED, &bonding);   uint8_t authRequest = ((mitm & 0x01) << 2) | ((bonding & 0x01) << 1) |                         (bonding & 0x01);   GAP_SendSlaveSecurityRequest(conn_handle, authRequest); }

4.完整的code

/****************************************************************************** @file ancs.c @brief This file contains the Simple BLE Peripheral sample application for use        with the CC2650 Bluetooth Low Energy Protocol Stack. Group: WCS, BTS Target Device: CC2640R2 ******************************************************************************  Copyright (c) 2013-2016, Texas Instruments Incorporated All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: *  Redistributions of source code must retain the above copyright    notice, this list of conditions and the following disclaimer. *  Redistributions in binary form must reproduce the above copyright    notice, this list of conditions and the following disclaimer in the    documentation and/or other materials provided with the distribution. *  Neither the name of Texas Instruments Incorporated nor the names of    its contributors may be used to endorse or promote products derived    from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ****************************************************************************** Release Name: ti-ble-3.0-stack-sdk_3_00_00 Release Date: 2016-12-21 12:44:47 *****************************************************************************//********************************************************************* * INCLUDES */#include <string.h>#include <ti/sysbios/knl/Task.h>#include <ti/sysbios/knl/Clock.h>#include <ti/sysbios/knl/Event.h>#include <ti/sysbios/knl/Queue.h>#include "hci_tl.h"#include "gatt.h"#include "linkdb.h"#include "gapgattserver.h"#include "gattservapp.h"#include "gatt_uuid.h"#include "peripheral.h"#include "gapbondmgr.h"#include "osal_snv.h"#include "icall_apimsg.h"#include "util.h"#include "board.h"#include "icall_api.h"#include "SensorUtil.h"#include "ancs.h"#include "oled.h"uint8_t ancsAppState = ANCS_STATE_IDLE;uint16_t Ancs_connHandle=0;// Handle cacheexternuint16_t Ancs_handleCache[HDL_CACHE_LEN];// ANCS Service: 7905F431-B5CE-4E99-A40F-4B1E122D00D0#define ANCS_SVC_UUID 0xD0, 0x00, 0x2D, 0x12, 0x1E, 0x4B, 0x0F, 0xA4, 0x99, 0x4E, 0xCE, 0xB5, 0x31, 0xF4, 0x05, 0x79// Notification Source: UUID 9FBF120D-6301-42D9-8C58-25E699A21DBD (notifiable)#define ANCS_NOTIF_SRC_CHAR_UUID        0x1DBD // Last 2 bytes of the 128bit-16bytes UUID// Control point: UUID 69D1D8F3-45E1-49A8-9821-9BBDFDAAD9D9 (writeable with response)#define ANCS_CTRL_PT_CHAR_UUID          0xD9D9// Data Source: UUID 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB (notifiable)#define ANCS_DATA_SRC_CHAR_UUID         0x7BFB#define CHAR_DESC_HDL_UUID128_LEN        21  // 5 + 16bytes = 21/********************************************************************* * @fn      Ancs_discoverService * * @brief   Function to handle the discovery of the ANCS service * * @param   pMsg - GATT message to process, may be NULL in DISC_ANCS_START  * * @return  none */void Ancs_discoverService(gattMsgEvent_t *pMsg){  static uint8_t discoveryState = DISC_ANCS_START;if(pMsg==NULL)discoveryState = DISC_ANCS_START;static uint16_t Ancs_svcStartHdl;  static uint16_t Ancs_svcEndHdl;  static uint8_t Ancs_endHdlIdx;  static uint8_t isNotifCCCD = FALSE;    uint8 temp_status=0;switch (discoveryState)  {   case DISC_ANCS_START:        {        uint8_t uuid[ATT_UUID_SIZE] = {ANCS_SVC_UUID};        // Initialize service discovery variables        Ancs_svcStartHdl = Ancs_svcEndHdl = 0;        Ancs_endHdlIdx = 0;                // Discover ANCS service by UUID        temp_status=GATT_DiscPrimaryServiceByUUID(Ancs_connHandle, uuid,ATT_UUID_SIZE, ICall_getEntityId());  if(temp_status==SUCCESS){discoveryState = DISC_ANCS_SVC;      }else{temp_status=GATT_DiscPrimaryServiceByUUID(Ancs_connHandle, uuid,ATT_UUID_SIZE, ICall_getEntityId());  if(temp_status==SUCCESS){discoveryState = DISC_ANCS_SVC;      }}}     break;    case DISC_ANCS_SVC:      // Service found, store handles      {if (pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP &&          pMsg->msg.findByTypeValueRsp.numInfo > 0)      {        Ancs_svcStartHdl =ATT_ATTR_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0);        Ancs_svcEndHdl = ATT_GRP_END_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0);      }            // If procedure complete     if ((pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP  &&pMsg->hdr.status == bleProcedureComplete) ||(pMsg->method == ATT_ERROR_RSP))      {        // If service found       if (Ancs_svcStartHdl != 0)        {          // Discover all characteristics         temp_status=GATT_DiscAllChars(Ancs_connHandle, Ancs_svcStartHdl, Ancs_svcEndHdl, ICall_getEntityId());//ICall_getEntityId()                if(temp_status == SUCCESS)discoveryState = DISC_ANCS_CHAR;       else{temp_status=GATT_DiscAllChars(Ancs_connHandle, Ancs_svcStartHdl, Ancs_svcEndHdl, ICall_getEntityId());//ICall_getEntityId()                if(temp_status == SUCCESS)discoveryState = DISC_ANCS_CHAR;   }}        else        {         // Service not found          discoveryState = DISC_FAILED;          }      }         }break;   case DISC_ANCS_CHAR:      {        // Characteristics found, chache them        uint8_t   *pHandleValuePairList;        uint16_t  handle;        uint16_t  uuid;       if (pMsg->method == ATT_READ_BY_TYPE_RSP && pMsg->msg.readByTypeRsp.numPairs > 0 && pMsg->msg.readByTypeRsp.len == CHAR_DESC_HDL_UUID128_LEN)        {          pHandleValuePairList = pMsg->msg.readByTypeRsp.pDataList;          uint8_t i;          // For each handle value pair in the list of chars in ANCS service          for (i = pMsg->msg.readByTypeRsp.numPairs; i > 0; i--)          {      // Parse characteristic declaration            handle = BUILD_UINT16(pHandleValuePairList[3],pHandleValuePairList[4]);            uuid = BUILD_UINT16(pHandleValuePairList[5],pHandleValuePairList[6]);                               // If looking for end handle           if (Ancs_endHdlIdx != 0)            {      // End handle is characteristic declaration handle - 1              Ancs_handleCache[Ancs_endHdlIdx] =BUILD_UINT16(pHandleValuePairList[0], pHandleValuePairList[1]) - 1;Ancs_endHdlIdx = 0;            }            // If UUID is of interest, cache handle            switch (uuid)            {              case ANCS_NOTIF_SRC_CHAR_UUID:          {Ancs_handleCache[HDL_ANCS_NTF_NOTIF_START] = handle;                Ancs_endHdlIdx = HDL_ANCS_NTF_NOTIF_END;  }break;                              case ANCS_CTRL_PT_CHAR_UUID:          {Ancs_handleCache[HDL_ANCS_CTRL_PT_START] = handle;                Ancs_endHdlIdx = HDL_ANCS_CTRL_PT_END;       }break;                              case ANCS_DATA_SRC_CHAR_UUID:      {Ancs_handleCache[HDL_ANCS_DATA_SRC_START] = handle;               Ancs_endHdlIdx = HDL_ANCS_DATA_SRC_END;  }break;                              default:                break;            }                        pHandleValuePairList += CHAR_DESC_HDL_UUID128_LEN;        }        }                  // If procedure complete       if ((pMsg->method == ATT_READ_BY_TYPE_RSP  &&  pMsg->hdr.status == bleProcedureComplete) ||(pMsg->method == ATT_ERROR_RSP))        {         // Special case of end handle at end of service          if (Ancs_endHdlIdx != 0)          {            Ancs_handleCache[Ancs_endHdlIdx] = Ancs_svcEndHdl;           Ancs_endHdlIdx = 0;          }                   // If notification source char is missing, there is something wrong          if (Ancs_handleCache[HDL_ANCS_NTF_NOTIF_START] == 0)          {            discoveryState = DISC_FAILED;          }          else if (Ancs_handleCache[HDL_ANCS_NTF_NOTIF_START] < Ancs_handleCache[HDL_ANCS_NTF_NOTIF_END])          {           // Discover ANCS Notification Source CCCD            temp_status=GATT_DiscAllCharDescs(Ancs_connHandle, Ancs_handleCache[HDL_ANCS_NTF_NOTIF_START] + 1, Ancs_handleCache[HDL_ANCS_NTF_NOTIF_END], ICall_getEntityId());            if(temp_status == SUCCESS){isNotifCCCD = TRUE;                                        discoveryState = DISC_ANCS_CCCD;        }else{temp_status=GATT_DiscAllCharDescs(Ancs_connHandle, Ancs_handleCache[HDL_ANCS_NTF_NOTIF_START] + 1, Ancs_handleCache[HDL_ANCS_NTF_NOTIF_END], ICall_getEntityId());            if(temp_status == SUCCESS){isNotifCCCD = TRUE;                                        discoveryState = DISC_ANCS_CCCD;        }}}          else         {             // Missing required characteristic descriptor            Ancs_handleCache[HDL_ANCS_NTF_NOTIF_START] = 0;           discoveryState = DISC_FAILED;          }        }        // Discover all characteristics of ANCS service until end handle       else        {          temp_status=GATT_DiscAllChars(Ancs_connHandle, handle+1, Ancs_svcEndHdl, ICall_getEntityId());if(temp_status == SUCCESS){}else{GATT_DiscAllChars(Ancs_connHandle, handle+1, Ancs_svcEndHdl, ICall_getEntityId());}}   }           break;    case DISC_ANCS_CCCD:      {        // Characteristic descriptors found       if (pMsg->method == ATT_FIND_INFO_RSP && pMsg->msg.findInfoRsp.numInfo > 0 &&  pMsg->msg.findInfoRsp.format == ATT_HANDLE_BT_UUID_TYPE)       {          uint8_t i;          // For each handle/uuid pair          for (i = 0; i < pMsg->msg.findInfoRsp.numInfo; i++)          {            // Look for CCCD            if (ATT_BT_PAIR_UUID(pMsg->msg.findInfoRsp.pInfo, i) == GATT_CLIENT_CHAR_CFG_UUID)           {              // CCCD found             // if it is Notification Source CCCDif (isNotifCCCD == TRUE)             {                Ancs_handleCache[HDL_ANCS_NTF_CCCD] = ATT_BT_PAIR_HANDLE(pMsg->msg.findInfoRsp.pInfo, i);              }              // else it is Data Source CCCD             else              {                Ancs_handleCache[HDL_ANCS_DATA_SRC_CCCD] = ATT_BT_PAIR_HANDLE(pMsg->msg.findInfoRsp.pInfo, i);             }              break;           }         }       }                // If procedure complete       if ((pMsg->method == ATT_FIND_INFO_RSP  &&   pMsg->hdr.status == bleProcedureComplete) || (pMsg->method == ATT_ERROR_RSP))        {          // Discover ANCS Data Source characteristic descriptors         if (isNotifCCCD == TRUE && Ancs_handleCache[HDL_ANCS_DATA_SRC_CCCD] == 0)          {           temp_status=GATT_DiscAllCharDescs(Ancs_connHandle,Ancs_handleCache[HDL_ANCS_DATA_SRC_START] + 1, Ancs_handleCache[HDL_ANCS_DATA_SRC_END],  ICall_getEntityId());            if(temp_status == SUCCESS){isNotifCCCD = FALSE;   }else{temp_status=GATT_DiscAllCharDescs(Ancs_connHandle,Ancs_handleCache[HDL_ANCS_DATA_SRC_START] + 1, Ancs_handleCache[HDL_ANCS_DATA_SRC_END],  ICall_getEntityId());            if(temp_status == SUCCESS){isNotifCCCD = FALSE;   }}}          else         {            discoveryState = DISC_IDLE;           ancsAppState = ANCS_STATE_READY;           while (SUCCESS != Ancs_subsNotifSrc()){}            while (SUCCESS != Ancs_subsDataSrc()){}      display_timer_data(14,"ancs6",5);}        }      }      break;    default:      break;  }}void Ancs_disconnected(void){  // Initialize state variables  //AncsApp_discState = DISC_IDLE;  ancsAppState = ANCS_STATE_IDLE;Ancs_unSubsNotifSrc();  Ancs_unSubsDataSrc();    // Invalidate connection variables.  Ancs_connHandle = 0xffff;}

/****************************************************************************** @file  ancs.h @brief This file contains the Simple BLE Peripheral sample application        definitions and prototypes. Group: WCS, BTS Target Device: CC2640R2 ******************************************************************************/#ifndef ANCS_H#define ANCS_H#ifdef __cplusplusextern "C"{#endif#include "SensorUtil.h"/********************************************************************* * INCLUDES */// ANCS discovery statesenum{  DISC_IDLE = 0x00,                  // Idle state    DISC_ANCS_START = 0x10,            // ANCS service  DISC_ANCS_SVC,                     // Discover service  DISC_ANCS_CHAR,                    // Discover all characteristics  DISC_ANCS_CCCD,                    // Discover ANCS CCCD  DISC_FAILED = 0xFF                 // Discovery failed};// ANCS handle cache indexesenum{  HDL_ANCS_NTF_NOTIF_START,             // ANCS notification characteristic start handle  HDL_ANCS_NTF_NOTIF_END,               // ANCS notification characteristic end handle  HDL_ANCS_NTF_CCCD,                    // ANCS notification CCCDHDL_ANCS_CTRL_PT_START,  HDL_ANCS_CTRL_PT_END,    HDL_ANCS_DATA_SRC_START,             // ANCS data source characteristic start handle  HDL_ANCS_DATA_SRC_END,               // ANCS data source characteristic end handle  HDL_ANCS_DATA_SRC_CCCD,              // ANCS data source CCCD     HDL_CACHE_LEN};  enum{ ANCS_STATE_IDLE = 0,  ANCS_STATE_DISCOVERY,  ANCS_STATE_READY,};/********************************************************************* * TYPEDEFS */typedef int32 notificationUID_t;typedef struct{  uint8  attrID;            //  uint16 maxLen;            // Some attributes need to have length} ctrlPtCmdParamAttrWithLen_t;typedef struct{  uint8  attrID;            //} ctrlPtCmdParamAttr_t;typedef struct _ancsCSKey_t{    uint_least16_t hwikey;    uint_least16_t taskkey;  } _ancsCSKey_t;/********************************************************************* * MACROS */// CommandID Values#define CommandIDGetNotificationAttributes      0       // CommandIDGetNotificationAttributes#define CommandIDGetAppAttributes               1       // CommandIDGetAppAttributes#define CommandIDPerformNotificationAction      2       // CommandIDPerformNotificationAction#define ActionIDPositive        0#define ActionIDNegative        1// Notification AttributeID Values#define NotificationAttributeIDAppIdentifier            0       // #define NotificationAttributeIDTitle                    1       // (Needs to be followed by a 2-bytes max length parameter)#define NotificationAttributeIDSubtitle                 2       // (Needs to be followed by a 2-bytes max length parameter)#define NotificationAttributeIDMessage                  3       // (Needs to be followed by a 2-bytes max length parameter)#define NotificationAttributeIDMessageSize              4 #define NotificationAttributeIDDate                     5 #define NotificationAttributeIDPositiveActionLabel      6 #define NotificationAttributeIDNegativeActionLabel      7// EventID Values#define EventIDNotificationAdded        0#define EventIDNotificationModified     1#define EventIDNotificationRemoved      2// EventFlags#define EventFlagSilent             0x01    // (1 << 0)#define EventFlagImportant          0x02    // (1 << 1)#define EventFlagPreExisting        0x04    // (1 << 2)#define EventFlagPositiveAction     0x08    // (1 << 3)#define EventFlagNegativeAction     0x10    // (1 << 4)// CategoryID Values#define CategoryIDOther                 0#define CategoryIDIncomingCall          1#define CategoryIDMissedCall            2#define CategoryIDVoicemail             3#define CategoryIDSocial                4#define CategoryIDSchedule              5#define CategoryIDEmail                 6#define CategoryIDNews                  7#define CategoryIDHealthAndFitness      8#define CategoryIDBusinessAndFinance    9#define CategoryIDLocation              10#define CategoryIDEntertainment         11//Define ANCS Client Flags#define CLIENT_NONE             0x00#define CLIENT_IMPORTANT_ALERT  0x01#define CLIENT_POSITIVE_ACT     0x02#define CLIENT_NEG_ACT          0x04/********************************************************************* * GLOBAL */enum{  CCCD_CONFIG_NOTIF = 0x00,  CCCD_CONFIG_DATA,  CCCD_CONFIG_DONE};// Connection handleextern /********************************************************************* * FUNCTIONS *//*  * ANCS service discovery functions. */extern void Ancs_disconnected(void);extern void Ancs_discoverService(gattMsgEvent_t *pMsg);extern uint8_t Ancs_discStart(void);extern uint8_t Ancs_discGattMsg(uint8_t state, gattMsgEvent_t *pMsg);extern uint8_t Ancs_subsNotifSrc(void);extern uint8_t Ancs_unSubsNotifSrc(void);extern uint8_t Ancs_subsDataSrc(void);extern uint8_t Ancs_unSubsDataSrc(void);extern void Ancs_performPositiveAction();extern void Ancs_performNegativeAction();/*  * ANCS notification handling function. */extern void Ancs_handleNotification(gattMsgEvent_t *pMsg);/******************************************************************************************************************************************/#ifdef __cplusplus}#endif#endif /* SIMPLEBLEPERIPHERAL_H */
5.官方;https://github.com/ti-simplelink/ble_examples/tree/ble_examples-2.1/Projects/ble/ancs


原创粉丝点击