Esempio n. 1
0
/*********************************************************************
 *
 * @fn      hidappHandleKey
 *
 * @brief   Handle service for keys
 *
 * @param   keys  - key that was pressed (i.e. the scanned row/col index)
 *          state - shifted
 *
 * @return  void
 */
static void hidappHandleKeys( uint8 keys, uint8 state )
{
  // Unused arguments
  (void) state;

  if (keys & HAL_KEY_SW_1)
  {
    // If bonds exist, erase all of them
    if ( ( hidappBondCount() > 0 ) && ( hidappBLEState != BLE_STATE_CONNECTED ) )
    {
      if ( hidappBLEState == BLE_STATE_CONNECTING )
      {
        hidappBLEState = BLE_STATE_DISCONNECTING;
        VOID GAPCentralRole_TerminateLink( GAP_CONNHANDLE_INIT );
      }

      VOID GAPBondMgr_SetParameter( GAPBOND_ERASE_ALLBONDS, 0, NULL );
    }
  }

  if (keys & HAL_KEY_SW_2)
  {
    if ( hidappBLEState == BLE_STATE_CONNECTED )
    {
      hidappBLEState = BLE_STATE_DISCONNECTING;
      VOID GAPCentralRole_TerminateLink( connHandle );
    }
    else if ( hidappBLEState == BLE_STATE_IDLE )
    {
      #if defined ( NANO_DONGLE )

      HalLedSet( HAL_LED_2, HAL_LED_MODE_OFF ); // red led

      // Notify our task to start initial discovey
      osal_set_event( hidappTaskId, HIDAPP_EVT_START_DISCOVERY );

      #endif //  #if defined ( NANO_DONGLE )
    }
  }
}
static void controlBLECentral_HandleKeys( uint8 shift, uint8 keys )
{
  (void)shift;  // Intentionally unreferenced parameter
  uint8 adc;
  
  if(keys & KEY_FUN1)
  {
    app_write_string("\r\ngot the KEY_FUN1 V:");
    adc=halGetVoltageMonitorInput();
    app_write_string( uint8_to_string(adc));
    
    HalLedSet( HAL_LED_1 , HAL_LED_MODE_FLASH );
  }
   
  if(keys & KEY_FUN2)
  {
    app_write_string("\r\ngot the KEY_FUN2");
    HalLedSet(HAL_LED_2, HAL_LED_MODE_BLINK);
  }
  
  if ( keys & HAL_KEY_UP )
  {
    // Start or stop discovery
    if ( simpleBLEState != BLE_STATE_CONNECTED )
    {
      if ( !simpleBLEScanning )
      {
        simpleBLEScanning = TRUE;
        simpleBLEScanRes = 0;
        
        LCD_WRITE_STRING( "Discovering...", HAL_LCD_LINE_1 );
        LCD_WRITE_STRING( "", HAL_LCD_LINE_2 );
        
        GAPCentralRole_StartDiscovery( DEFAULT_DISCOVERY_MODE,
                                       DEFAULT_DISCOVERY_ACTIVE_SCAN,
                                       DEFAULT_DISCOVERY_WHITE_LIST );      
      }
      else
      {
        GAPCentralRole_CancelDiscovery();
      }
    }
    else if ( simpleBLEState == BLE_STATE_CONNECTED &&
              simpleBLECharHdl != 0 &&
              simpleBLEProcedureInProgress == FALSE )
    {
      uint8 status;
      
      // Do a read or write as long as no other read or write is in progress
      if ( simpleBLEDoWrite )
      {
        // Do a write
        attWriteReq_t req;
        
        req.handle = simpleBLECharHdl;
        req.len = 1;
        req.value[0] = simpleBLECharVal;
        req.sig = 0;
        req.cmd = 0;
        status = GATT_WriteCharValue( simpleBLEConnHandle, &req, simpleBLETaskId );         
      }
      else
      {
        // Do a read
        attReadReq_t req;
        
        req.handle = simpleBLECharHdl;
        status = GATT_ReadCharValue( simpleBLEConnHandle, &req, simpleBLETaskId );
      }
      
      if ( status == SUCCESS )
      {
        simpleBLEProcedureInProgress = TRUE;
        simpleBLEDoWrite = !simpleBLEDoWrite;
      }
    }    
  }

  if ( keys & HAL_KEY_LEFT )
  {
    // Display discovery results
    if ( !simpleBLEScanning && simpleBLEScanRes > 0 )
    {
        // Increment index of current result (with wraparound)
        simpleBLEScanIdx++;
        if ( simpleBLEScanIdx >= simpleBLEScanRes )
        {
          simpleBLEScanIdx = 0;
        }
        
        LCD_WRITE_STRING_VALUE( "Device", simpleBLEScanIdx + 1,
                                10, HAL_LCD_LINE_1 );
        LCD_WRITE_STRING( bdAddr2Str( simpleBLEDevList[simpleBLEScanIdx].addr ),
                          HAL_LCD_LINE_2 );
    }
  }

  if ( keys & HAL_KEY_RIGHT )
  {
    // Connection update
    if ( simpleBLEState == BLE_STATE_CONNECTED )
    {
      GAPCentralRole_UpdateLink( simpleBLEConnHandle,
                                 DEFAULT_UPDATE_MIN_CONN_INTERVAL,
                                 DEFAULT_UPDATE_MAX_CONN_INTERVAL,
                                 DEFAULT_UPDATE_SLAVE_LATENCY,
                                 DEFAULT_UPDATE_CONN_TIMEOUT );
    }
  }
  
  if ( keys & HAL_KEY_CENTER )
  {
    uint8 addrType;
    uint8 *peerAddr;
    
    // Connect or disconnect
    if ( simpleBLEState == BLE_STATE_IDLE )
    {
      // if there is a scan result
      if ( simpleBLEScanRes > 0 )
      {
        // connect to current device in scan result
        peerAddr = simpleBLEDevList[simpleBLEScanIdx].addr;
        addrType = simpleBLEDevList[simpleBLEScanIdx].addrType;
      
        simpleBLEState = BLE_STATE_CONNECTING;
        
        GAPCentralRole_EstablishLink( DEFAULT_LINK_HIGH_DUTY_CYCLE,
                                      DEFAULT_LINK_WHITE_LIST,
                                      addrType, peerAddr );
  
        LCD_WRITE_STRING( "Connecting", HAL_LCD_LINE_1 );
        LCD_WRITE_STRING( bdAddr2Str( peerAddr ), HAL_LCD_LINE_2 ); 
      }
    }
    else if ( simpleBLEState == BLE_STATE_CONNECTING ||
              simpleBLEState == BLE_STATE_CONNECTED )
    {
      // disconnect
      simpleBLEState = BLE_STATE_DISCONNECTING;

      gStatus = GAPCentralRole_TerminateLink( simpleBLEConnHandle );
      
      LCD_WRITE_STRING( "Disconnecting", HAL_LCD_LINE_1 ); 
    }
  }
  
  if ( keys & HAL_KEY_DOWN )
  {
    // Start or cancel RSSI polling
    if ( simpleBLEState == BLE_STATE_CONNECTED )
    {
      if ( !simpleBLERssi )
      {
        simpleBLERssi = TRUE;
        GAPCentralRole_StartRssi( simpleBLEConnHandle, DEFAULT_RSSI_PERIOD );
      }
      else
      {
        simpleBLERssi = FALSE;
        GAPCentralRole_CancelRssi( simpleBLEConnHandle );
        
        LCD_WRITE_STRING( "RSSI Cancelled", HAL_LCD_LINE_1 );
      }
    }
  }
}
/*********************************************************************
 * @fn      glucCollCentral_handleKeys
 *
 * @brief   Handles all key events for this device.
 *
 * @param   shift - true if in shift/alt.
 * @param   keys - bit field for key events.
 *
 * @return  none
 */
static void glucCollCentral_handleKeys(uint8_t shift, uint8_t keys)
{
  (void)shift;  // Intentionally unreferenced parameter

  if (keys & KEY_UP)
  {
    // Start or stop discovery
    if (glucCollState != BLE_STATE_CONNECTED)
    {
      if (!glucCollScanning)
      {
        glucCollScanning = TRUE;
        glucCollScanRes = 0;
        
        LCD_WRITE_STRING("Discovering...", LCD_PAGE0);
        LCD_WRITE_STRING("", LCD_PAGE1);
        LCD_WRITE_STRING("", LCD_PAGE2);
        
        GAPCentralRole_StartDiscovery(DEFAULT_DISCOVERY_MODE,
                                      DEFAULT_DISCOVERY_ACTIVE_SCAN,
                                      DEFAULT_DISCOVERY_WHITE_LIST);      
      }
      else
      {
        GAPCentralRole_CancelDiscovery();
      }
    }
    else if (glucCollState == BLE_STATE_CONNECTED &&
             glucCollCharHdls == true &&
             glucCollWritePending == false)
    {
      uint8_t status;
#if GLUCOSE_FILTER_ENABLED
     // Request number of records
      status = glucoseCtlPntWriteFilter(CTL_PNT_OP_GET_NUM, CTL_PNT_OPER_RANGE,
                                        DEFAULT_FILTER_TYPE, pFilter1, pFilter2);      
#else
      // Request number of records
      status = glucoseCtlPntWrite(CTL_PNT_OP_GET_NUM, CTL_PNT_OPER_ALL);
#endif      
      
      if(status == 0)
      {
        glucCollWritePending = true;
      }
    }

    return;
  }

  if (keys & KEY_LEFT)
  {
    // Display discovery results
    if (glucCollState != BLE_STATE_CONNECTED && !glucCollScanning && 
        glucCollScanRes > 0)
    {
        // Increment index of current result (with wraparound)
        glucCollScanIdx++;

        if (glucCollScanIdx >= glucCollScanRes)
        {
          glucCollScanIdx = 0;
        }

        LCD_WRITE_STRING_VALUE("Device", glucCollScanIdx + 1,
                                10, LCD_PAGE0);
        LCD_WRITE_STRING(Util_convertBdAddr2Str(glucCollDevList[glucCollScanIdx].addr),
                          LCD_PAGE1);
        LCD_WRITE_STRING("", LCD_PAGE2);
    }
    else if (glucCollState == BLE_STATE_CONNECTED)
    {
      if(glucoseCtlPntWrite(CTL_PNT_OP_ABORT, CTL_PNT_OPER_NULL) == 0)
      {
        glucCollWritePending = false;
      }
    }

    return;
  }

  if (keys & KEY_RIGHT)
  {
    // Request all records
    if (glucCollState == BLE_STATE_CONNECTED &&
        glucCollCharHdls == true &&
        glucCollWritePending == false)
    { 
      uint8_t status;
#if GLUCOSE_FILTER_ENABLED
      status = glucoseCtlPntWriteFilter(CTL_PNT_OP_REQ, CTL_PNT_OPER_RANGE, 
                                        DEFAULT_FILTER_TYPE, pFilter1, pFilter2);
#else
      status = glucoseCtlPntWrite(CTL_PNT_OP_REQ, CTL_PNT_OPER_ALL);
#endif

      if(status == SUCCESS)
      {
        glucCollWritePending = true;
      }
    }

    return;
  }
  
  if (keys & KEY_SELECT)
  {
    uint8_t addrType;
    uint8_t *peerAddr;
    
    // Connect or disconnect
    if (glucCollState == BLE_STATE_IDLE)
    {
      // if there is a scan result
      if (glucCollScanRes > 0)
      {
        // connect to current device in scan result
        peerAddr = glucCollDevList[glucCollScanIdx].addr;
        addrType = glucCollDevList[glucCollScanIdx].addrType;

        glucCollState = BLE_STATE_CONNECTING;

        GAPCentralRole_EstablishLink(DEFAULT_LINK_HIGH_DUTY_CYCLE,
                                     DEFAULT_LINK_WHITE_LIST,
                                     addrType, peerAddr);
  
        LCD_WRITE_STRING("Connecting", LCD_PAGE0);
        LCD_WRITE_STRING(Util_convertBdAddr2Str(peerAddr), LCD_PAGE1); 
        LCD_WRITE_STRING("", LCD_PAGE2);
      }
    }
    else if (glucCollState == BLE_STATE_CONNECTING ||
             glucCollState == BLE_STATE_CONNECTED)
    {
      // disconnect
      glucCollState = BLE_STATE_DISCONNECTING;

      GAPCentralRole_TerminateLink(glucCollConnHandle);

      LCD_WRITE_STRING("Disconnecting", LCD_PAGE0); 
      LCD_WRITE_STRING("", LCD_PAGE1);
      LCD_WRITE_STRING("", LCD_PAGE2);
    }
    
    return;
  }
  
  if (keys & KEY_DOWN)
  {
    // Clear stored records
    if (glucCollState == BLE_STATE_CONNECTED &&
        glucCollCharHdls == true &&
        glucCollWritePending == false)
    { 
      uint8_t status;      
#if GLUCOSE_FILTER_ENABLED
      status = glucoseCtlPntWriteFilter(CTL_PNT_OP_CLR, CTL_PNT_OPER_RANGE,
                                        DEFAULT_FILTER_TYPE, pFilter1, pFilter2);
#else         
      status = glucoseCtlPntWrite(CTL_PNT_OP_CLR, CTL_PNT_OPER_ALL);
#endif

      if(status == 0)
      {
        glucCollWritePending = true;
        glucCollClearPending = true;
      }
    }
    else if (glucCollState != BLE_STATE_CONNECTED)
    {
      // erase all bonds
      GAPBondMgr_SetParameter(GAPBOND_ERASE_ALLBONDS, 0, NULL);
      LCD_WRITE_STRING("Erasing bonds", LCD_PAGE0);
      LCD_WRITE_STRING("", LCD_PAGE1);
      LCD_WRITE_STRING("", LCD_PAGE2);

      // initiate service discovery again
      glucCollCharHdls = false;
    }
  }
}
/*********************************************************************
 * @fn     glucCollCentral_taskFxn
 *
 * @brief   Application task entry point for the Glucose collector.
 *
 * @param   a0, a1 - not used
 *
 * @return  none
 */
static void glucCollCentral_taskFxn(UArg a0, UArg a1)
{
  // Initialize application
  glucCollCentral_Init();

  // Application main loop
  for (;;)
  {
    // Waits for a signal to the semaphore associated with the calling thread.
    // Note that the semaphore associated with a thread is signaled when a
    // message is queued to the message receive queue of the thread or when
    // ICall_signal() function is called onto the semaphore.
    ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);

    if (errno == ICALL_ERRNO_SUCCESS)
    {
      ICall_EntityID dest;
      ICall_ServiceEnum src;
      ICall_HciExtEvt *pMsg = NULL;

      if (ICall_fetchServiceMsg(&src, &dest, 
                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
      {
        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
        {
          // Process inter-task message
          glucCollCentral_processStackMsg((ICall_Hdr *)pMsg);
        }

        if (pMsg)
        {
          ICall_freeMsg(pMsg);
        }
      }

      // If RTOS queue is not empty, process app message.
      while (!Queue_empty(appMsgQueue))
      {
        glucCollEvt_t *pMsg = (glucCollEvt_t *)Util_dequeueMsg(appMsgQueue);
        if (pMsg)
        {
          // Process message.
          glucCollCentral_processAppMsg(pMsg);

          // Free the space from the message.
          ICall_free(pMsg);
        }
      }

      if (events)
      {
        if (events & GLUCOLL_PROCEDURE_TIMEOUT_EVT)
        {
          events &= ~GLUCOLL_PROCEDURE_TIMEOUT_EVT;
          
          if (glucCollState == BLE_STATE_CONNECTED)
          {
            // disconnect
            glucCollState = BLE_STATE_DISCONNECTING;
            
            GAPCentralRole_TerminateLink(glucCollConnHandle);
            
            LCD_WRITE_STRING("Timeout", LCD_PAGE0); 
            LCD_WRITE_STRING("", LCD_PAGE1);
            LCD_WRITE_STRING("", LCD_PAGE2);
          }
        }

        if (events & GLUCOLL_START_DISCOVERY_EVT)
        {
          events &= ~GLUCOLL_START_DISCOVERY_EVT;
          
          if (glucCollPairingStarted)
          {
            // Postpone discovery until pairing completes
            glucCollDiscPostponed = TRUE;
          }
          else
          {
            glucCollCentral_startDiscovery();
          }  
        }
      }
    }
  }
}
Esempio n. 5
0
/*********************************************************************
 * @fn      GlucColl_ProcessEvent
 *
 * @brief   Glucose Collector 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 GlucColl_ProcessEvent( uint8 task_id, uint16 events )
{
  
  VOID task_id; // OSAL required parameter that isn't used in this function
  
  if ( events & SYS_EVENT_MSG )
  {
    uint8 *pMsg;

    if ( (pMsg = osal_msg_receive( glucCollTaskId )) != NULL )
    {
      glucCollCentral_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 & PROCEDURE_TIMEOUT_EVT )
  {
    if ( glucCollState == BLE_STATE_CONNECTED )
    {
      // disconnect
      glucCollState = BLE_STATE_DISCONNECTING;

      GAPCentralRole_TerminateLink( glucCollConnHandle );
      
      LCD_WRITE_STRING( "Timeout", HAL_LCD_LINE_1 ); 
      LCD_WRITE_STRING( "", HAL_LCD_LINE_2 );
      LCD_WRITE_STRING( "", HAL_LCD_LINE_3 );
    }

    // return unprocessed events
    return ( events ^ PROCEDURE_TIMEOUT_EVT );
  }

  if ( events & START_DEVICE_EVT )
  {
    // Start the Device
    VOID GAPCentralRole_StartDevice( (gapCentralRoleCB_t *) &glucCollRoleCB );

    // Register with bond manager after starting device
    GAPBondMgr_Register( (gapBondCBs_t *) &glucCollBondCB );

    return ( events ^ START_DEVICE_EVT );
  }

  if ( events & START_DISCOVERY_EVT )
  {
    if ( glucCollPairingStarted )
    {
      // Postpone discovery until pairing completes
      glucCollDiscPostponed = TRUE;
    }
    else
    {
      glucCollCentralStartDiscovery( );
    }  
    return ( events ^ START_DISCOVERY_EVT );
  }
  
  // Discard unknown events
  return 0;
}
/************************************************************************************************
 * @fn      simpleBLECentralProcessGATTMsg
 *
 * @brief   Process GATT messages
 *
 * @return  none
 ************************************************************************************************/
void simpleBLECentralProcessGATTMsg( gattMsgEvent_t *pMsg ){
  
  switch(pMsg->method){
        case ATT_READ_RSP:{   
              uint8 valueRead = pMsg->msg.readRsp.value[0];
              LCDPrintText("Read rsp:",valueRead,PRINT_VALUE); 
              
              //GAPCentralRole_TerminateLink( connHandle ); 
              break;
        }
  
        case ATT_WRITE_RSP:{  
              if(CharSendingFlag ==1){                    //to filt out the last rep message!
                         Z_DelayMS(50);
                         ClientWriteValue(); 
              }
              break;
        }

        case ATT_FIND_BY_TYPE_VALUE_RSP:{         
                                if(pMsg->msg.findByTypeValueRsp.numInfo > 0 ){
                                            //LCDPrintText("Found group h",0,PRINT_STRING);    
                                            HandleRangeStart = pMsg->msg.findByTypeValueRsp.handlesInfo[0].handle;          //Found attribute handle
                                            HandleRangeEnd = pMsg->msg.findByTypeValueRsp.handlesInfo[0].grpEndHandle;      //Group end handle
                                }
                                
                                if(pMsg->hdr.status == bleProcedureComplete)
                                           if( HandleRangeEnd != 0 ){ 
                                                attReadByTypeReq_t req;
                                                req.startHandle = HandleRangeStart;
                                                req.endHandle = HandleRangeEnd;
                                                req.type.len = ATT_BT_UUID_SIZE;                                                   
                                                req.type.uuid[0] = LO_UINT16(BLEChar.uuid);
                                                req.type.uuid[1] = HI_UINT16(BLEChar.uuid);           
                                                uint8 return_status;
                                                //LCDPrintText("seach attrib h",0,PRINT_STRING); 
                                                if(return_status = GATT_ReadUsingCharUUID(CurrentConnectionInfo.Handle, &req, MasterSlaveSwitchTaskID ))// Discover characteristic
                                                                LCDPrintText("ReadUsingChar error",return_status,PRINT_VALUE);                                                                                                                                       
                                          }
                                          else
                                                LCDPrintText("Handle range error",1,PRINT_STRING);           
                                break;
          
        }
  
        case ATT_READ_BY_TYPE_RSP:{
          
                                if(pMsg->msg.readByTypeRsp.numPairs > 0 ){
                                        uint16 temp_handle = BUILD_UINT16( pMsg->msg.readByTypeRsp.dataList[0], pMsg->msg.readByTypeRsp.dataList[1] );
                                        if((temp_handle == BLEChar.handle) && (BLEChar.handle != 0))
                                        {CharHandleSearchFlag = 0;
                                        //HalLcdWriteStringValue("HANDLE SA",temp_handle,10,HAL_LCD_LINE_5);
                                        }
                                        else
                                        {BLEChar.handle= temp_handle;	
                                        //HalLcdWriteStringValue("HANDLE DE",temp_handle,10,HAL_LCD_LINE_6);
                                        }
                                        
                                }      			
		    		
                                if(pMsg->hdr.status == bleProcedureComplete)
                                        if(BLEChar.handle != 0){                             
                                              ClientWriteValue();
                                              CharSendingFlag =1;
                                              //LCDPrintText("finished attrib h",0,PRINT_STRING);
                                        }
                                        else 
                                              LCDPrintText("Handle value error",1,PRINT_STRING);  
                                break;        
        }

	case ATT_HANDLE_VALUE_NOTI:{
          
                               //one transfer last 1s the most ,otherwise watchdog will reset the device
                                        //WD_KICK();
                                        
                                if(pMsg->msg.handleValueNoti.len != MAC_LEN){
                                        LCDPrintText("error noti lenth:",pMsg->msg.handleValueNoti.len,PRINT_VALUE);
                                        break;
                                }
                                
                                osal_memcpy(mac_buffer[Buffer_Top],pMsg->msg.handleValueNoti.value,pMsg->msg.handleValueNoti.len);
                                
                                if(TRUE == osal_memcmp(mac_buffer[Buffer_Top], mac_buffer[Buffer_Top+1] ,MAC_LEN)){
                                      
                                        
                                        GAPCentralRole_TerminateLink( CurrentConnectionInfo.Handle );
                                        uint32 timeout_value = 50;
                                        //osal_start_timerEx(MasterSlaveSwitchTaskID, CHECH_LINK_EVT, timeout_value);
                                        
                                        break;
                                }//wait for conn timeout
          
                                if(TRUE == MacBufferSearch(mac_buffer[Buffer_Top])){
                                        //LCDPrintText("valid value:",mac_buffer[Buffer_Top][0],PRINT_VALUE);                                                                            
                                        Buffer_Top++;                                        
                                        
                                }
                                
                                else
                                        osal_memset(mac_buffer[Buffer_Top], 0, MAC_LEN);
                                
                                break;
        }
        
        
        case ATT_ERROR_RSP:{
           
                        if(pMsg->msg.errorRsp.reqOpcode == ATT_READ_REQ){
                                      uint8 status = pMsg->msg.errorRsp.errCode;
                              LCDPrintText("Read Error",status,PRINT_VALUE);
                        }
          
                        else if(pMsg->msg.errorRsp.reqOpcode == ATT_WRITE_REQ){
                                      uint8 status = pMsg->msg.errorRsp.errCode;
                              LCDPrintText("Write Error",status,PRINT_VALUE);
                        }
                        
                        else if(pMsg->msg.errorRsp.reqOpcode == ATT_FIND_BY_TYPE_VALUE_REQ)
                              LCDPrintText("service find error",1,PRINT_STRING);
                        
                        else if(pMsg->msg.errorRsp.reqOpcode == ATT_READ_BY_TYPE_REQ)
                              LCDPrintText("charac find error",1,PRINT_STRING);
                        
                        break;
        }
        
        default:
                LCDPrintText("unknow gatt message",1,PRINT_STRING);
                break;


   
  } 

			
}
Esempio n. 7
0
/*********************************************************************
 * @fn      oadManager_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 oadManager_HandleKeys( uint8 shift, uint8 keys )
{
  (void)shift;  // Intentionally unreferenced parameter

  if ( keys & HAL_KEY_UP )  // Start or stop discovery
  {
    if ( oadManagerState != BLE_STATE_CONNECTED )
    {
      if ( !oadManagerScanning )
      {
        (void)osal_set_event(oadManagerTaskId, DEV_DISCOVERY_EVT);
      }
      else
      {
        GAPCentralRole_CancelDiscovery();
      }
    }
  }

  if ( keys & HAL_KEY_LEFT )
  {
    // Display discovery results
    if ( !oadManagerScanning && oadManagerScanRes > 0 )
    {
      // Increment index of current result (with wraparound)
      oadManagerScanIdx++;
      if ( oadManagerScanIdx >= oadManagerScanRes )
      {
        oadManagerScanIdx = 0;
      }

#if (defined HAL_LCD) && (HAL_LCD == TRUE)
      LCD_WRITE_STRING_VALUE( "Device", oadManagerScanIdx + 1, 10, HAL_LCD_LINE_1 );
      LCD_WRITE_STRING( bdAddr2Str( oadManagerDevList[oadManagerScanIdx].addr ), HAL_LCD_LINE_2 );
#endif
    }
  }

  if ( keys & HAL_KEY_RIGHT )
  {
  }

  if ( keys & HAL_KEY_CENTER )
  {
    uint8 addrType;
    uint8 *peerAddr;

    // Connect or disconnect
    if ( oadManagerState == BLE_STATE_IDLE )
    {
      // if there is a scan result
      if ( oadManagerScanRes > 0 )
      {
        if ( oadManagerScanIdx < oadManagerScanRes )
        {
          // connect to current device in scan result
          peerAddr = oadManagerDevList[oadManagerScanIdx].addr;
          addrType = oadManagerDevList[oadManagerScanIdx].addrType;

          oadManagerState = BLE_STATE_CONNECTING;

          GAPCentralRole_EstablishLink( DEFAULT_LINK_HIGH_DUTY_CYCLE,
                                        DEFAULT_LINK_WHITE_LIST,
                                        addrType, peerAddr );

#if (defined HAL_LCD) && (HAL_LCD == TRUE)
          LCD_WRITE_STRING( "Connecting", HAL_LCD_LINE_1 );
          LCD_WRITE_STRING( bdAddr2Str( peerAddr ), HAL_LCD_LINE_2 );
        }
        else
        {
          LCD_WRITE_STRING( "Select device", HAL_LCD_LINE_3 );
#endif
        }
      }
    }
    else if ( oadManagerState == BLE_STATE_CONNECTING || oadManagerState == BLE_STATE_CONNECTED )
    {
      // disconnect
      oadManagerState = BLE_STATE_DISCONNECTING;

      VOID GAPCentralRole_TerminateLink( oadManagerConnHandle );

#if (defined HAL_LCD) && (HAL_LCD == TRUE)
      LCD_WRITE_STRING( "Disconnecting", HAL_LCD_LINE_1 );
      LCD_WRITE_STRING( "", HAL_LCD_LINE_2 );
      LCD_WRITE_STRING( "", HAL_LCD_LINE_3 );
#endif
    }
  }

  if ( keys & HAL_KEY_DOWN )
  {
#if (defined HAL_LCD) && (HAL_LCD == TRUE)
    LCD_WRITE_STRING("SBL Mode...", HAL_LCD_LINE_3);
#endif
    EA = 0;
    sblRun();
    EA = 1;
#if (defined HAL_LCD) && (HAL_LCD == TRUE)
    LCD_WRITE_STRING("SBL Done.", HAL_LCD_LINE_3);
#endif
  }
}