simpleBLEPeripheral.c 文件分析

这个配置或者说任务, 让这个蓝牙设备成为了一个简单的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, &current_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);
            }
        }
    }
}

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

时间: 2024-10-06 02:58:37

simpleBLEPeripheral.c 文件分析的相关文章

10046 trace文件分析

SQL> create table t10046 as select * from dba_objects; Table created. SQL> select file_id,block_id,blocks from dba_extents where segment_name='T10046'; FILE_ID BLOCK_ID BLOCKS ---------- ---------- ---------- 1 94664 8 1 94672 8 1 94680 8 1 94688 8

/proc/cpuinfo 文件分析(查看CPU信息)

/proc/cpuinfo文件分析 根据以下内容,我们则可以很方便的知道当前系统关于CPU.CPU的核数.CPU是否启用超线程等信息. <1>查询系统具有多少个逻辑核:cat /proc/cpuinfo | grep "processor" | wc -l   //逻辑处理器的id(逻辑核数) <3>查询系统CPU的个数:cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l 

Debug目录、Release目录,bin目录、obj目录,vshost.exe.config文件、.exe.config文件分析【C#】

Debug目录.Release目录,bin目录.obj目录,vshost.exe.config文件..exe.config文件分析[C#] 2013-10-06  孤风卓影  摘自 csdn博客  阅 558  转 4 转藏到我的图书馆 微信分享: 今天写程序的时候,需要更改.exe.config文件中的引用的webservice地址,用vs调试的时候,发现会修改vshost.exe.config中的对应项,.exe.config中的对应项是不会修改的,这样会导致在软件重启的情况下,.exe.c

java:Servlet(Create,LifeCycle,交互式,Tomcat文件分析)

1.Servlet: Servlet(Server Applet)是Java Servlet的简称,是为小服务程序或服务连接器,用Java编写的服务器端程序,主要功能在于交互式地浏览和修改数据,生成动态Web内容. 狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者.Servlet运行于支持Java的应用服务器中.从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servle

结合程序崩溃后的core文件分析bug

结合程序崩溃后的core文件分析bug 引言 在<I/O的效率比较>中,我们在修改图1程序的BUF_SIZE为8388608时,运行程序出现崩溃,如下图1: 图1. 段错误 一般而言,导致程序段错误的原因如下: 内存访问出错,这类问题的典型代表就是数组越界. 非法内存访问,出现这类问题主要是程序试图访问内核段内存而产生的错误. 栈溢出, Linux默认给一个进程分配的栈空间大小为8M,因此你的数组开得过大的话会出现这种问题. 首先我们先看一下系统默认分配的资源: $ ulimit -acore

linux实践之ELF文件分析

linux实践之ELF文件分析 下面开始elf文件的分析. 我们首先编写一个简单的C代码. 编译链接生成可执行文件. 首先,查看scn15elf.o文件的详细信息. 以16进制形式查看scn15elf.o文件. 查看scn15elf.o中各个段和符号表的信息. 各个段的详细信息如下. 符号表的信息如下: 使用readelf命令查看各个段的详细信息: 段表信息如下: 符号表信息如下: 下面让我们开始分析文件头吧! 由于我的虚拟机是32位的,我下面就主要以32位的系统进行分析,就不比较32位机和64

蓝屏 Dump文件分析方法

WinDbg使用有点麻烦,还要符号表什么的.试了下,感觉显示很乱,分析的也不够全面... 试试其他的吧!今天电脑蓝屏了,就使用其dump文件测试,如下: 1.首先,最详细的,要属Osr Online这个在线分析网站了: 打开其分析地址:http://www.osronline.com/page.cfm?name=analyze 下拉,找到上传按钮(上图),将需要分析的dump文件浏览上传即可...dump文件一般在C:\www\minidump下 分析完成后生成的内容非常多: 主要看第一个Pri

使用 Eclipse Memory Analyzer 进行堆转储文件分析

Eclipse Memory Analyzer(MAT)是著名的跨平台集成开发环境 Eclipse Galileo 版本的 33 个组成项目中之一,它是一个功能丰富的 JAVA 堆转储文件分析工具,可以帮助你发现内存漏洞和减少内存消耗.本文主要介绍如何安装配置 Memory Analyzer,并结合一个实例,介绍如何利用 MAT 来进行堆转储文件分析,找到内存泄露的根源. 0 评论: 仇 璐, 软件工程师, IBM 杨 晓峰, 软件工程师, IBM 2010 年 7 月 22 日 内容 在 IB

rtems 4.11 部分m4文件分析

本来想把configure.ac和各种m4文件分析明白,发现有点困难,不过好在也能理解一些. 基本教程 首先要明白m4,参见这个教程,写得不错,不论怎么样m4替换来替换去的,还真是不那么容易懂,好在我们自己不用写,只要看懂大意而已- 然后我们还得去了解下 autoconf和automake,这本书不错 <Autotools: A Practioner's Guide to GNU Autoconf, Automake, and Libtool>,csdn有下载. 文件夹结构 当autoconf