这个配置或者说任务, 让这个蓝牙设备成为了一个简单的BLE外设.
这里定义了外设的广播数据, 以及最重要, char被改变之后的回调, 引出后来的coreHandler里面的, ack 以及写e2prom.
/**************************************************************************************************
**************************************************************************************************/
/*********************************************************************
* INCLUDES
*/
#include <stdio.h>
#include "bcomdef.h"
#include "OSAL.h"
#include "OSAL_PwrMgr.h"
#include "OnBoard.h"
#include "hal_adc.h"
#include "hal_led.h"
#include "hal_key.h"
#include "hal_lcd.h"
#include "npi.h"
#include "gatt.h"
#include "GUA_Timer1.h"
#include "hci.h"
#include "gapgattserver.h"
#include "gattservapp.h"
#include "devinfoservice.h"
#include "simpleGATTprofile.h"
#if defined( CC2540_MINIDK )
#include "simplekeys.h"
#endif
#if defined ( PLUS_BROADCASTER )
#include "peripheralBroadcaster.h"
#else
#include "peripheral.h"
#endif
#include "gapbondmgr.h"
#include "simpleBLEPeripheral.h"
#if defined FEATURE_OAD
#include "oad.h"
#include "oad_target.h"
#endif
#include "coreHandler.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
// How often to perform periodic event
#define SBP_PERIODIC_EVT_PERIOD 5000
//定义广播间隔.
// What is the advertising interval when device is discoverable (units of 625us, 160=100ms)
#define DEFAULT_ADVERTISING_INTERVAL 160
//有限发现模式会限制在开机内30.72s内发现, 之后就无法再被发现了.
// Limited discoverable mode advertises for 30.72s, and then stops
//普通模式没有限制.
// General discoverable mode advertises indefinitely
#if defined ( CC2540_MINIDK )
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_LIMITED
#else
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL
#endif // defined ( CC2540_MINIDK )
//定义默认连接间隔, 80相当于100ms
// Minimum connection interval (units of 1.25ms, 80=100ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 80
//定义默认最大连接间隔,800ms,
// Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 800
//latency是0
// Slave latency to use if automatic parameter update request is enabled
#define DEFAULT_DESIRED_SLAVE_LATENCY 0
//断线超时时间为1000即10s, 就是收不到连接10s后,就会判断连接已经断开.
// Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_CONN_TIMEOUT 1000
//是否自动更新配置信息.
// Whether to enable automatic parameter update request when a connection is formed
#define DEFAULT_ENABLE_UPDATE_REQUEST TRUE
// Connection Pause Peripheral time value (in seconds)
#define DEFAULT_CONN_PAUSE_PERIPHERAL 6
//公司识别ID
// Company Identifier: Texas Instruments Inc. (13)
#define TI_COMPANY_ID 0x000D
#define INVALID_CONNHANDLE 0xFFFF
// Length of bd addr as a string
#define B_ADDR_STR_LEN 15
#if defined ( PLUS_BROADCASTER )
#define ADV_IN_CONN_WAIT 500 // delay 500 ms
#endif
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
本地变量
*/
//这个task的taskID
static uint8 simpleBLEPeripheral_TaskID; // Task ID for internal task/event processing
//GAPROLE中断的一个结构体.
static gaprole_States_t gapProfileState = GAPROLE_INIT;
//GAP: 扫描回应的数据, 最多能有31个byte
// GAP - SCAN RSP data (max size = 31 bytes)
static uint8 scanRspData[] =
{
// complete name
//完整的名称.
0x09, // length of this data 数据长度.
GAP_ADTYPE_LOCAL_NAME_COMPLETE, //下面定义完整的设备名称.
0x48, //H
0x58, //X
0x53, //S
0x63, //c
0x72, //r
0x65, //e
0x65, //e
0x6E, //n
#if 0
0x53, // ‘S‘
0x69, // ‘i‘
0x6d, // ‘m‘
0x70, // ‘p‘
0x6c, // ‘l‘
0x65, // ‘e‘
0x42, // ‘B‘
0x4c, // ‘L‘
0x45, // ‘E‘
0x50, // ‘P‘
0x65, // ‘e‘
0x72, // ‘r‘
0x69, // ‘i‘
0x70, // ‘p‘
0x68, // ‘h‘
0x65, // ‘e‘
0x72, // ‘r‘
0x61, // ‘a‘
0x6c, // ‘l‘
0x6c, //
#endif
// connection interval range 连接的间隔范围.
0x05, // length of this data //这段数据的长度.
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE, //连接间隔范围.
LO_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ), // 100ms
HI_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),
LO_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ), // 1s
HI_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),
// Tx power level
0x02, // length of this data还是长度
GAP_ADTYPE_POWER_LEVEL,//发射强度级别
0 // 0dBm 最高!
};
//GAP广告数据
// GAP - Advertisement data (max size = 31 bytes, though this is
// best kept short to conserve power while advertisting)
static uint8 advertData[] =
{
// 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,
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
// service UUID, to notify central devices what services are included
// in this peripheral
0x03, // length of this data
GAP_ADTYPE_16BIT_MORE, // some of the UUID‘s, but not all
LO_UINT16( SIMPLEPROFILE_SERV_UUID ),
HI_UINT16( SIMPLEPROFILE_SERV_UUID ),
};
// GAP GATT Attributes
static uint8 attDeviceName[GAP_DEVICE_NAME_LEN] = "MyBLEPeripheralDevice";
//att的设备名.
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void simpleBLEPeripheral_ProcessOSALMsg( osal_event_hdr_t *pMsg );
static void peripheralStateNotificationCB( gaprole_States_t newState );
static void performPeriodicTask( void );
static void simpleProfileChangeCB( uint8 paramID );
#if defined( CC2540_MINIDK )
static void simpleBLEPeripheral_HandleKeys( uint8 shift, uint8 keys );
#endif
#if (defined HAL_LCD) && (HAL_LCD == TRUE)
static char *bdAddr2Str ( uint8 *pAddr );
#endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
/*********************************************************************
* PROFILE CALLBACKS
*/
//GAP角色回调
// GAP Role Callbacks
static gapRolesCBs_t simpleBLEPeripheral_PeripheralCBs =
{
peripheralStateNotificationCB, // Profile State Change Callbacks 当GAP的P的状态如果发现改变时的回调就是这个peripheralStateNotificationCB.
NULL // When a valid RSSI is read from controller (not used by application)
};
//GAP绑定管理回调
// GAP Bond Manager Callbacks
static gapBondCBs_t simpleBLEPeripheral_BondMgrCBs =
{
NULL, // Passcode callback (not used by application)
NULL // Pairing / Bonding state Callback (not used by application)
};
//建议GATT的profile回调
// Simple GATT Profile Callbacks
static simpleProfileCBs_t simpleBLEPeripheral_SimpleProfileCBs =
{
simpleProfileChangeCB // Charactersitic value change callback 这个是GATT的特征值被改变时的回调.
};
/*********************************************************************
* PUBLIC FUNCTIONS
*/
static void NpiSerialCallback( uint8 port, uint8 events );
/*********************************************************************
* @fn SimpleBLEPeripheral_Init
*
* @brief Initialization function for the Simple BLE Peripheral App Task.
* This is called during initialization and should contain
* any application specific initialization (ie. hardware
* initialization/setup, table initialization, power up
* notificaiton ... ).
*
* @param task_id - the ID assigned by OSAL. This ID should be
* used to send messages and set timers.
*
* @return none
*/
void SimpleBLEPeripheral_Init( uint8 task_id )
{
//taskID
simpleBLEPeripheral_TaskID = task_id;
//定时器1初始化
GUA_Timer1_Init();
//NPI中断初始化
NPI_InitTransport(NpiSerialCallback);
//NPI输出
NPI_WriteTransport("SimpleBLETest_Init\r\n", 20);
// Setup the GAP, 设置GAP
VOID GAP_SetParamValue( TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL );
//设置GAP外设角色
// Setup the GAP Peripheral Role Profile
{
#if defined( CC2540_MINIDK )
// For the CC2540DK-MINI keyfob, device doesn‘t start advertising until button is pressed
//CC2540K-Mini的硬件, 要按一下按钮, 才开始广告.
uint8 initial_advertising_enable = FALSE;
#else
// For other hardware platforms, device starts advertising upon initialization
//其他硬件一开始就广告.
uint8 initial_advertising_enable = TRUE;
#endif
// 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
//这里设置为0, 设备将会在30秒之后进入等待模式而不再广播, 直到enabler被设置回TRUE.
uint16 gapRole_AdvertOffTime = 0;
//各种连接参数
uint8 enable_update_request = DEFAULT_ENABLE_UPDATE_REQUEST;
uint16 desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
uint16 desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
uint16 desired_slave_latency = DEFAULT_DESIRED_SLAVE_LATENCY;
uint16 desired_conn_timeout = DEFAULT_DESIRED_CONN_TIMEOUT;
// Set the GAP Role Parameters
//设置GAP角色参数
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );
GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_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 ), &enable_update_request );
GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &desired_min_interval );
GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &desired_max_interval );
GAPRole_SetParameter( GAPROLE_SLAVE_LATENCY, sizeof( uint16 ), &desired_slave_latency );
GAPRole_SetParameter( GAPROLE_TIMEOUT_MULTIPLIER, sizeof( uint16 ), &desired_conn_timeout );
}
// Set the GAP Characteristics
//设置GAP特征字
GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName );
// Set advertising interval
//设置广播间隔.
{
uint16 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 passkey = 0; // passkey "000000" key是6个0
uint8 pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
uint8 mitm = TRUE;
uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
uint8 bonding = TRUE;
GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof ( uint32 ), &passkey );
GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof ( uint8 ), &pairMode );
GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof ( uint8 ), &mitm );
GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof ( uint8 ), &ioCap );
GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof ( uint8 ), &bonding );
}
// Initialize GATT attributes
//初始化GATT属性
GGS_AddService( GATT_ALL_SERVICES ); // GATT所有服务
GATTServApp_AddService( GATT_ALL_SERVICES ); // GATT attributes
DevInfo_AddService(); // Device Information Service 设备信息服务也加进去.
SimpleProfile_AddService( GATT_ALL_SERVICES ); // Simple GATT Profile 加上simple GATT 的配置信息.
#if defined FEATURE_OAD
VOID OADTarget_AddService(); // OAD Profile
#endif
// Setup the SimpleProfile Characteristic Values
//设置特征字, 分别设置特征字的初始值跟类型.
{
uint8 charValue1 = 1;
uint8 charValue2 = 2;
uint8 charValue3 = 3;
uint8 charValue4 = 4;
uint8 charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };
uint8 charValue6[SIMPLEPROFILE_CHAR6_LEN] = { 1, 2, 3, 4, 5 };
SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR1, sizeof ( uint8 ), &charValue1 );
SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR2, sizeof ( uint8 ), &charValue2 );
SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR3, sizeof ( uint8 ), &charValue3 );
SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR4, sizeof ( uint8 ), &charValue4 );
SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN, charValue5 );
SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR6, SIMPLEPROFILE_CHAR6_LEN, charValue6 );
}
#if defined( CC2540_MINIDK )
SK_AddService( GATT_ALL_SERVICES ); // Simple Keys Profile
// Register for all key events - This app will handle all key events
RegisterForKeys( simpleBLEPeripheral_TaskID );
// makes sure LEDs are off
HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF );
// For keyfob board set GPIO pins into a power-optimized state
// Note that there is still some leakage current from the buzzer,
// accelerometer, LEDs, and buttons on the PCB.
P0SEL = 0; // Configure Port 0 as GPIO
P1SEL = 0; // Configure Port 1 as GPIO
P2SEL = 0; // Configure Port 2 as GPIO
P0DIR = 0xFC; // Port 0 pins P0.0 and P0.1 as input (buttons),
// all others (P0.2-P0.7) as output
P1DIR = 0xFF; // All port 1 pins (P1.0-P1.7) as output
P2DIR = 0x1F; // All port 1 pins (P2.0-P2.4) as output
P0 = 0x03; // All pins on port 0 to low except for P0.0 and P0.1 (buttons)
P1 = 0; // All pins on port 1 to low
P2 = 0; // All pins on port 2 to low
#endif // #if defined( CC2540_MINIDK )
#if (defined HAL_LCD) && (HAL_LCD == TRUE)
#if defined FEATURE_OAD
#if defined (HAL_IMAGE_A)
HalLcdWriteStringValue( "BLE Peri-A", OAD_VER_NUM( _imgHdr.ver ), 16, HAL_LCD_LINE_1 );
#else
HalLcdWriteStringValue( "BLE Peri-B", OAD_VER_NUM( _imgHdr.ver ), 16, HAL_LCD_LINE_1 );
#endif // HAL_IMAGE_A
#else
HalLcdWriteString( "BLE Peripheral", HAL_LCD_LINE_1 );
#endif // FEATURE_OAD
#endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
// Register callback with SimpleGATTprofile
//注册simpleGATTprofile的回调.
VOID SimpleProfile_RegisterAppCBs( &simpleBLEPeripheral_SimpleProfileCBs );
// Enable clock divide on halt
// This reduces active current while radio is active and CC254x MCU
// is halted
//估计是在无任务的状态下节能.
HCI_EXT_ClkDivOnHaltCmd( HCI_EXT_ENABLE_CLK_DIVIDE_ON_HALT );
#if defined ( DC_DC_P0_7 )
// Enable stack to toggle bypass control on TPS62730 (DC/DC converter)
HCI_EXT_MapPmIoPortCmd( HCI_EXT_PM_IO_PORT_P0, HCI_EXT_PM_IO_PORT_PIN7 );
#endif // defined ( DC_DC_P0_7 )
// Setup a delayed profile startup
//设置一个profile启动后的跟随的事件.
osal_set_event( simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT );
}
/*********************************************************************
* @fn SimpleBLEPeripheral_ProcessEvent
*
* @brief Simple BLE Peripheral Application Task event processor. This function
* is called to process all events for the task. Events
* include timers, messages and any other user defined events.
*
* @param task_id - The OSAL assigned task ID.
* @param events - events to process. This is a bit map and can
* contain more than one event.
*
* @return events not processed
*/
//事件处理函数.
uint16 SimpleBLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )
{
VOID task_id; // OSAL required parameter that isn‘t used in this function OSAL层面需要参数, 但是这个函数暂时不用.
//如果事件是系统消息.
if ( events & SYS_EVENT_MSG )
{
uint8 *pMsg;
if ( (pMsg = osal_msg_receive( simpleBLEPeripheral_TaskID )) != NULL )
{
//就运行这个消息处理的函数.
simpleBLEPeripheral_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
// Release the OSAL message
VOID osal_msg_deallocate( pMsg );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
//如果是系统启动的消息.
if ( events & SBP_START_DEVICE_EVT )
{
// Start the Device
//就启动设备
VOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs );
//启动绑定管理器
// Start Bond Manager
VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs );
//设置定时器
// Set timer for first periodic event
osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );
return ( events ^ SBP_START_DEVICE_EVT );
}
//如果事件是周期事件
if ( events & SBP_PERIODIC_EVT )
{
// Restart timer
//重启定时器.
if ( SBP_PERIODIC_EVT_PERIOD )
{
osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );
}
//执行周期应用任务.
// Perform periodic application task
performPeriodicTask();
return (events ^ SBP_PERIODIC_EVT);
}
#if defined ( PLUS_BROADCASTER )
if ( events & SBP_ADV_IN_CONNECTION_EVT )
{
uint8 turnOnAdv = TRUE;
// Turn on advertising while in a connection
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &turnOnAdv );
return (events ^ SBP_ADV_IN_CONNECTION_EVT);
}
#endif // PLUS_BROADCASTER
// Discard unknown events
return 0;
}
//task之间会传递消息, 如何处理这个消息, 就是下面的函数, 例子就是使用minidk, 按下按钮之后, 就会去开启/停止广告.
//使用的函数是: simpleBLEPeripheral_HandleKeys
/*********************************************************************
* @fn simpleBLEPeripheral_ProcessOSALMsg
*
* @brief Process an incoming task message.
*
* @param pMsg - message to process
*
* @return none
*/
static void simpleBLEPeripheral_ProcessOSALMsg( osal_event_hdr_t *pMsg )
{
switch ( pMsg->event )
{
#if defined( CC2540_MINIDK )
case KEY_CHANGE:
simpleBLEPeripheral_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys );
break;
#endif // #if defined( CC2540_MINIDK )
default:
// do nothing
break;
}
}
//定义这个事件处理函数.
#if defined( CC2540_MINIDK )
/*********************************************************************
* @fn simpleBLEPeripheral_HandleKeys
*
* @brief Handles all key events for this device.
*
* @param shift - true if in shift/alt.
* @param keys - bit field for key events. Valid entries:
* HAL_KEY_SW_2
* HAL_KEY_SW_1
*
* @return none
*/
static void simpleBLEPeripheral_HandleKeys( uint8 shift, uint8 keys )
{
uint8 SK_Keys = 0;
VOID shift; // Intentionally unreferenced parameter
if ( keys & HAL_KEY_SW_1 )
{
SK_Keys |= SK_KEY_LEFT;
}
if ( keys & HAL_KEY_SW_2 )
{
SK_Keys |= SK_KEY_RIGHT;
// if device is not in a connection, pressing the right key should toggle
// advertising on and off
if( gapProfileState != GAPROLE_CONNECTED )
{
uint8 current_adv_enabled_status;
uint8 new_adv_enabled_status;
//Find the current GAP advertisement status
GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, ¤t_adv_enabled_status );
if( current_adv_enabled_status == FALSE )
{
new_adv_enabled_status = TRUE;
}
else
{
new_adv_enabled_status = FALSE;
}
//change the GAP advertisement status to opposite of current status
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &new_adv_enabled_status );
}
}
// Set the value of the keys state to the Simple Keys Profile;
// This will send out a notification of the keys state if enabled
SK_SetParameter( SK_KEY_ATTR, sizeof ( uint8 ), &SK_Keys );
}
#endif // #if defined( CC2540_MINIDK )
//外设状态改变的通知回调.
/*********************************************************************
* @fn peripheralStateNotificationCB
*
* @brief Notification from the profile of a state change.
*
* @param newState - new state
*
* @return none
*/
static void peripheralStateNotificationCB( gaprole_States_t newState )
{
switch ( newState )
{
//如果是启动
case GAPROLE_STARTED:
{
uint8 ownAddress[B_ADDR_LEN];
uint8 systemId[DEVINFO_SYSTEM_ID_LEN];
GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress);
// use 6 bytes of device address for 8 bytes of system ID value
systemId[0] = ownAddress[0];
systemId[1] = ownAddress[1];
systemId[2] = ownAddress[2];
// set middle bytes to zero
systemId[4] = 0x00;
systemId[3] = 0x00;
// shift three bytes up
systemId[7] = ownAddress[5];
systemId[6] = ownAddress[4];
systemId[5] = ownAddress[3];
DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId);
#if (defined HAL_LCD) && (HAL_LCD == TRUE)
// Display device address
HalLcdWriteString( bdAddr2Str( ownAddress ), HAL_LCD_LINE_2 );
HalLcdWriteString( "Initialized", HAL_LCD_LINE_3 );
#endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
}
break;
case GAPROLE_ADVERTISING:
{
#if (defined HAL_LCD) && (HAL_LCD == TRUE)
HalLcdWriteString( "Advertising", HAL_LCD_LINE_3 );
#endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
NPI_WriteTransport("ADVERTISING \r\n", 20);
}
break;
case GAPROLE_CONNECTED:
{
#if (defined HAL_LCD) && (HAL_LCD == TRUE)
HalLcdWriteString( "Connected", HAL_LCD_LINE_3 );
#endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
NPI_WriteTransport("CONNECTED \r\n", 20);
}
break;
case GAPROLE_WAITING:
{
#if (defined HAL_LCD) && (HAL_LCD == TRUE)
HalLcdWriteString( "Disconnected", HAL_LCD_LINE_3 );
#endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
NPI_WriteTransport("WAITING \r\n", 20);
}
break;
case GAPROLE_WAITING_AFTER_TIMEOUT:
{
#if (defined HAL_LCD) && (HAL_LCD == TRUE)
HalLcdWriteString( "Timed Out", HAL_LCD_LINE_3 );
#endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
NPI_WriteTransport("WAITING_AFTER_TIMEOUT \r\n", 20);
}
break;
case GAPROLE_ERROR:
{
#if (defined HAL_LCD) && (HAL_LCD == TRUE)
HalLcdWriteString( "Error", HAL_LCD_LINE_3 );
#endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
}
break;
default:
{
#if (defined HAL_LCD) && (HAL_LCD == TRUE)
HalLcdWriteString( "", HAL_LCD_LINE_3 );
#endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
NPI_WriteTransport("default \r\n", 20);
}
break;
}
gapProfileState = newState;
#if !defined( CC2540_MINIDK )
VOID gapProfileState; // added to prevent compiler warning with
// "CC2540 Slave" configurations
#endif
}
/*********************************************************************
* @fn performPeriodicTask
*
* @brief Perform a periodic application task. This function gets
* called every five seconds as a result of the SBP_PERIODIC_EVT
* OSAL event. In this example, the value of the third
* characteristic in the SimpleGATTProfile service is retrieved
* from the profile, and then copied into the value of the
* the fourth characteristic.
*
* @param none
*
* @return none
*/
static void performPeriodicTask( void )
{
uint8 valueToCopy;
uint8 stat;
uint8 char6_value[SIMPLEPROFILE_CHAR6_LEN]={0};
SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR6, char6_value); //读取char6的值
SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR6, SIMPLEPROFILE_CHAR6_LEN, char6_value); //notify char6的值给主机
// Call to retrieve the value of the third characteristic in the profile
stat = SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR3, &valueToCopy);
if( stat == SUCCESS )
{
/*
* Call to set that value of the fourth characteristic in the profile. Note
* that if notifications of the fourth characteristic have been enabled by
* a GATT client device, then a notification will be sent every time this
* function is called.
*/
SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR4, sizeof(uint8), &valueToCopy);
}
}
//如果主机写了特征字, 就执行这个回调.
/*********************************************************************
* @fn simpleProfileChangeCB
*
* @brief Callback from SimpleBLEProfile indicating a value change
*
* @param paramID - parameter ID of the value that was changed.
*
* @return none
*/
static void simpleProfileChangeCB( uint8 paramID )
{
uint8 newValue;
//uint8 Char6_Value[SIMPLEPROFILE_CHAR6_LEN];
switch( paramID )
{
case SIMPLEPROFILE_CHAR1:
SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR1, &newValue );
#if (defined HAL_LCD) && (HAL_LCD == TRUE)
HalLcdWriteStringValue( "Char 1:", (uint16)(newValue), 10, HAL_LCD_LINE_3 );
#endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
NPI_PrintValue("Char 1 = ",(uint16)(newValue), 16);
NPI_PrintString("\r\n");
break;
case SIMPLEPROFILE_CHAR3:
SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR3, &newValue );
#if (defined HAL_LCD) && (HAL_LCD == TRUE)
HalLcdWriteStringValue( "Char 3:", (uint16)(newValue), 10, HAL_LCD_LINE_3 );
#endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
break;
//如果是char6被改变了, 就执行coreHandler里面的ackByPackageID
case SIMPLEPROFILE_CHAR6:
//SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR6, &Char6_Value );
#if (defined HAL_LCD) && (HAL_LCD == TRUE)
HalLcdWriteStringValue( "Char 6:", (uint16)(Char6_Value), 20, HAL_LCD_LINE_3 );
#endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
//NPI_WriteTransport(Char6_Value, 20);
ackByPackageID();
break;
default:
// should not reach here!
break;
}
}
#if (defined HAL_LCD) && (HAL_LCD == TRUE)
/*********************************************************************
* @fn bdAddr2Str
*
* @brief Convert Bluetooth address to string. Only needed when
* LCD display is used.
*
* @return none
*/
char *bdAddr2Str( uint8 *pAddr )
{
uint8 i;
char hex[] = "0123456789ABCDEF";
static char str[B_ADDR_STR_LEN];
char *pStr = str;
*pStr++ = ‘0‘;
*pStr++ = ‘x‘;
// Start from end of addr
pAddr += B_ADDR_LEN;
for ( i = B_ADDR_LEN; i > 0; i-- )
{
*pStr++ = hex[*--pAddr >> 4];
*pStr++ = hex[*pAddr & 0x0F];
}
*pStr = 0;
return str;
}
#endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
static void NpiSerialCallback( uint8 port, uint8 events )
{
(void)port;
if (events & (HAL_UART_RX_TIMEOUT | HAL_UART_RX_FULL))
{
uint8 numBytes = 0;
numBytes = NPI_RxBufLen();
if(numBytes == 0)
{
return;
}
else
{
uint8 *buffer = osal_mem_alloc(numBytes);
if(buffer)
{
NPI_ReadTransport(buffer,numBytes);
NPI_WriteTransport(buffer, numBytes);
osal_mem_free(buffer);
}
}
}
}
/*********************************************************************
*********************************************************************/