• 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 ", 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 ", 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 ", 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 ", 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 ", 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 ", 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(" ");
              
          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);
                }
            }
        }
    }

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

  • 相关阅读:
    vue慕课网音乐项目手记:9-封装一个公用的scroll组件
    vue慕课网音乐项目手记:50-搜索列表的点击删除、删除全部的交互事件
    vue慕课网音乐项目手记:48-搜索历史数据的处理
    vue慕课网音乐项目手记:6-手写滚动轮播图(中)
    vue慕课网音乐项目手记:5-手写滚动轮播图(上)
    vue慕课网音乐项目手记:30-音乐环形进度条的实现
    vue慕课网音乐项目手记:45-搜索页面跳转歌手页面
    基于Vue2.0的音乐播放器(2)——歌手模块
    linux学习笔记-(1)-安装
    linux学习笔记-前篇
  • 原文地址:https://www.cnblogs.com/Montauk/p/5874973.html
Copyright © 2020-2023  润新知