CC2640R2 ANCS

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 cacheextern
uint16_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 CCCD
						if (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 __cplusplus
extern "C"
{
#endif
#include "SensorUtil.h"
/*********************************************************************
 * INCLUDES
 */

// ANCS discovery states
enum
{  
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 indexes
enum
{  
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 CCCD
HDL_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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值