Example #1
0
static void ther_display_event_report(unsigned char event, uint16 arg)
{
	struct ther_info *ti = &ther_info;

	switch (event) {
	case OLED_EVENT_DISPLAY_ON:
		/* change temp measure to 1 sec */
//		change_measure_timer(ti, TEMP_MEASURE_MIN_INTERVAL);
		ti->display_picture = arg;

		if (ti->display_picture == OLED_PICTURE1) {
			if (ti->batt_percentage < LOW_BATT_WARNING_THRESHOLD) {
				ti->batt_in_dispaly = TRUE;
				osal_start_timerEx(ti->task_id, TH_LOW_BATT_BLINK_EVT, LOW_BATT_BLINK_INTERVAL);
			}
		}
		break;

	case OLED_EVENT_TIME_TO_END:
		osal_stop_timerEx(ti->task_id, TH_LOW_BATT_BLINK_EVT);

//		change_measure_timer(ti, TEMP_MEASURE_INTERVAL);
		if (ti->display_picture == OLED_PICTURE_WELCOME) {
			struct display_param param;

			/*
			 * show first picture after welcome
			 */
			encap_picture_param(ti, &param);
			oled_show_picture(OLED_PICTURE1, DISPLAY_TIME, &param);

		} else {
			ti->display_picture = OLED_PICTURE_NONE;
		}
		break;

	}
}
/***************************************************************************************************
 * @fn      MT_SysOsalStopTimer
 *
 * @brief
 *
 * @param   uint8 pData - pointer to the data
 *
 * @return  None
 ***************************************************************************************************/
void MT_SysOsalStopTimer(uint8 *pBuf)
{
  uint16 eventId;
  uint8 retValue = ZFailure;
  uint8 cmdId;

  /* parse header */
  cmdId = pBuf[MT_RPC_POS_CMD1];
  pBuf += MT_RPC_FRAME_HDR_SZ;

  if (*pBuf <= 3)
  {
    eventId = (uint16) MT_SysOsalEventId[*pBuf];
    retValue = osal_stop_timerEx(MT_TaskID, eventId);
  }
  else
  {
    retValue = ZInvalidParameter;
  }

  /* Build and send back the response */
  MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), cmdId, 1, &retValue );
}
/******************************************************************************
 * @fn          zb_AllowBind
 *
 * @brief       The zb_AllowBind function puts the device into the
 *              Allow Binding Mode for a given period of time.  A peer device
 *              can establish a binding to a device in the Allow Binding Mode
 *              by calling zb_BindDevice with a destination address of NULL
 *
 * @param       timeout - The number of seconds to remain in the allow binding
 *                        mode.  Valid values range from 1 through 65.
 *                        If 0, the Allow Bind mode will be set false without TO
 *                        If greater than 64, the Allow Bind mode will be true
 *
 * @return      ZB_SUCCESS if the device entered the allow bind mode, else
 *              an error code.
 */
void zb_AllowBind ( uint8 timeout )
{

  osal_stop_timerEx(sapi_TaskID, ZB_ALLOW_BIND_TIMER);

  if ( timeout == 0 )
  {
    afSetMatch(sapi_epDesc.simpleDesc->EndPoint, FALSE);
  }
  else
  {
    afSetMatch(sapi_epDesc.simpleDesc->EndPoint, TRUE);
    if ( timeout != 0xFF )
    {
      if ( timeout > 64 )
      {
        timeout = 64;
      }
      osal_start_timerEx(sapi_TaskID, ZB_ALLOW_BIND_TIMER, timeout*1000);
    }
  }
  return;
}
//This function process the ZDO events to bind
static void ParkWay_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg )
{
  switch ( inMsg->clusterID )
  {
    case End_Device_Bind_rsp:
      if ( ZDO_ParseBindRsp( inMsg ) == ZSuccess )
      {
        // Light LED
        //HalLedSet ( HAL_LED_2, HAL_LED_MODE_FLASH );
      }
      break;

    case Match_Desc_rsp:
      {
        ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( inMsg );
        if ( pRsp )
        {
          if ( pRsp->status == ZSuccess && pRsp->cnt )
          {
            ParkWay_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
            ParkWay_DstAddr.addr.shortAddr = pRsp->nwkAddr;
            // Take the first endpoint, Can be changed to search through endpoints
            ParkWay_DstAddr.endPoint = pRsp->epList[0];

            // Light LED
            //HalLedSet( HAL_LED_2, HAL_LED_MODE_ON );

            //This stop the peer from send request do the coordinator
            //HalLedSet ( HAL_LED_1, HAL_LED_MODE_OFF);
            osal_stop_timerEx( ParkWay_TaskID,POLLING_OF_DEV_EVT);
          }
          osal_mem_free( pRsp );
        }
      }
      break;
  }
}
Example #5
0
static void ther_system_power_off_pre(struct ther_info *ti)
{
	/* test */
	osal_stop_timerEx(ti->task_id, TH_TEST_EVT);

	/*
	 * stop auto power off
	 */
	osal_stop_timerEx(ti->task_id, TH_AUTO_POWER_OFF_EVT);

	/*
	 * batt measure
	 */
	osal_stop_timerEx(ti->task_id, TH_BATT_EVT);
	osal_stop_timerEx(ti->task_id, TH_LOW_BATT_WARNING_EVT);

	/*
	 * stop temp timer
	 */
	osal_stop_timerEx(ti->task_id, TH_TEMP_MEASURE_EVT);
	osal_stop_timerEx(ti->task_id, TH_HIS_TEMP_RESTORE_EVT);
	osal_stop_timerEx(ti->task_id, TH_HIGH_TEMP_WARNING_EVT);

	/*
	 * play power off music
	 */
	ther_buzzer_stop_music();
	ther_buzzer_start_music(BUZZER_MUSIC_SYS_POWER_OFF);

	/*
	 * oled says goodbye
	 */
	oled_show_picture(OLED_PICTURE_GOODBYE, DISPLAY_GOODBYE_TIME, NULL);

	osal_start_timerEx(ti->task_id, TH_POWER_OFF_EVT, SYSTEM_POWER_OFF_TIME);

	ther_device_exit_pre(ti);
}
Example #6
0
/*********************************************************************
 * @fn      SerialApp_ProcessMSGCmd
 *
 * @brief   Data message processor callback. This function processes
 *          any incoming data - probably from other devices. Based
 *          on the cluster ID, perform the intended action.
 *
 * @param   pkt - pointer to the incoming message packet
 *
 * @return  TRUE if the 'pkt' parameter is being used and will be freed later,
 *          FALSE otherwise.
 */
void SerialApp_ProcessMSGCmd( afIncomingMSGPacket_t *pkt )
{
  uint8 stat;
  uint8 seqnb;
  uint8 delay;

  switch ( pkt->clusterId )
  {
  // A message with a serial data block to be transmitted on the serial port.
  case SERIALAPP_CLUSTERID1:
    seqnb = pkt->cmd.Data[0];

    // Keep message if not a repeat packet
    if ( (seqnb > SerialApp_SeqRx) ||                    // Normal
        ((seqnb < 0x80 ) && ( SerialApp_SeqRx > 0x80)) ) // Wrap-around
    {
      // Transmit the data on the serial port.
      if ( HalUARTWrite( SERIAL_APP_PORT, pkt->cmd.Data+1,
                                         (pkt->cmd.DataLength-1) ) )
      {
        // Save for next incoming message
        SerialApp_SeqRx = seqnb;

        stat = OTA_SUCCESS;
      }
      else
      {
        stat = OTA_SER_BUSY;
      }
    }
    else
    {
      stat = OTA_DUP_MSG;
    }

    // Select approproiate OTA flow-control delay.
    delay = (stat == OTA_SER_BUSY) ? SERIALAPP_NAK_DELAY : SERIALAPP_ACK_DELAY;

    // Build & send OTA response message.
    rspBuf[0] = stat;
    rspBuf[1] = seqnb;
    rspBuf[2] = LO_UINT16( delay );
    rspBuf[3] = HI_UINT16( delay );
    stat = AF_DataRequest( &(pkt->srcAddr), (endPointDesc_t*)&SerialApp_epDesc,
                            SERIALAPP_CLUSTERID2, SERIAL_APP_RSP_CNT , rspBuf,
                           &SerialApp_MsgID, 0, AF_DEFAULT_RADIUS );

    if ( stat != afStatus_SUCCESS )
    {
      osal_start_timerEx( SerialApp_TaskID, SERIALAPP_RSP_RTRY_EVT,
                                            SERIALAPP_RSP_RTRY_TIMEOUT );

      // Store the address for the timeout retry.
      osal_memcpy(&SerialApp_RspDstAddr, &(pkt->srcAddr), sizeof( afAddrType_t ));
    }
    HalLedSet(HAL_LED_2,HAL_LED_MODE_ON);
    break;

  // A response to a received serial data block.
  case SERIALAPP_CLUSTERID2:
    if ( (pkt->cmd.Data[1] == SerialApp_SeqTx) &&
        ((pkt->cmd.Data[0] == OTA_SUCCESS) ||
         (pkt->cmd.Data[0] == OTA_DUP_MSG)) )
    {
      // Remove timeout waiting for response from other device.
      osal_stop_timerEx( SerialApp_TaskID, SERIALAPP_MSG_RTRY_EVT );
      FREE_OTABUF();
      HalLedSet(HAL_LED_2,HAL_LED_MODE_ON);
    }
    else
    {
      delay = BUILD_UINT16( pkt->cmd.Data[2], pkt->cmd.Data[3] );
      // Re-start timeout according to delay sent from other device.
      osal_start_timerEx( SerialApp_TaskID, SERIALAPP_MSG_RTRY_EVT, delay );
    }
    break;
#ifndef   ZDO_COORDINATOR
  case SERIALAPP_CLUSTERID_CMD:
    CommandToBox(pkt->cmd.Data[1]);
    break;
#endif
  default:
      break;
  }
}
/*********************************************************************
 * @fn      glucCollCentralEventCB
 *
 * @brief   Central event callback function.
 *
 * @param   pEvent - pointer to event structure
 *
 * @return  none
 */
static void glucCollCentralEventCB( gapCentralRoleEvent_t *pEvent )
{
  switch ( pEvent->gap.opcode )
  {
    case GAP_DEVICE_INIT_DONE_EVENT:  
      {
        LCD_WRITE_STRING( "Gluc. Collector", HAL_LCD_LINE_1 );
        LCD_WRITE_STRING( bdAddr2Str( pEvent->initDone.devAddr ),  HAL_LCD_LINE_2 );
      }
      break;

    case GAP_DEVICE_INFO_EVENT:
      {
        // if filtering device discovery results based on service UUID
        if ( DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE )
        {
          if ( glucCollFindSvcUuid( GLUCOSE_SERV_UUID,
                                     pEvent->deviceInfo.pEvtData,
                                     pEvent->deviceInfo.dataLen ) )
          {
            glucCollAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType );
          }
        }
      }
      break;
      
    case GAP_DEVICE_DISCOVERY_EVENT:
      {
        // discovery complete
        glucCollScanning = FALSE;

        // if not filtering device discovery results based on service UUID
        if ( DEFAULT_DEV_DISC_BY_SVC_UUID == FALSE )
        {
          // Copy results
          glucCollScanRes = pEvent->discCmpl.numDevs;
          osal_memcpy( glucCollDevList, pEvent->discCmpl.pDevList,
                       (sizeof( gapDevRec_t ) * pEvent->discCmpl.numDevs) );
        }
        
        LCD_WRITE_STRING_VALUE( "Devices Found", glucCollScanRes,
                                10, HAL_LCD_LINE_1 );
        if ( glucCollScanRes > 0 )
        {
          LCD_WRITE_STRING( "<- To Select", HAL_LCD_LINE_2 );
        }

        // initialize scan index to last device
        glucCollScanIdx = glucCollScanRes;

      }
      break;

    case GAP_LINK_ESTABLISHED_EVENT:
      {
        if ( pEvent->gap.hdr.status == SUCCESS )
        {          
          glucCollState = BLE_STATE_CONNECTED;
          glucCollConnHandle = pEvent->linkCmpl.connectionHandle;
          
          
          // If service discovery not performed initiate service discovery
          if ( glucCollCharHdls == false)
          {
            osal_start_timerEx( glucCollTaskId, START_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY );
          }
                    
          LCD_WRITE_STRING( "Connected", HAL_LCD_LINE_1 );
          LCD_WRITE_STRING( bdAddr2Str( pEvent->linkCmpl.devAddr ), HAL_LCD_LINE_2 );   
        }
        else
        {
          glucCollState = BLE_STATE_IDLE;
          glucCollConnHandle = GAP_CONNHANDLE_INIT;
          glucCollDiscState = DISC_IDLE;
          
          LCD_WRITE_STRING( "Connect Failed", HAL_LCD_LINE_1 );
          LCD_WRITE_STRING_VALUE( "Reason:", pEvent->gap.hdr.status, 10, HAL_LCD_LINE_2 );
          LCD_WRITE_STRING( "", HAL_LCD_LINE_3 );
        }
      }
      break;

    case GAP_LINK_TERMINATED_EVENT:
      {
        glucCollState = BLE_STATE_IDLE;
        glucCollConnHandle = GAP_CONNHANDLE_INIT;
        glucCollDiscState = DISC_IDLE;
        glucCollPairingStarted = false;
        glucCollDiscPostponed = false;
        glucCollClearPending = false;

        // stop procedure timer
        osal_stop_timerEx( glucCollTaskId, PROCEDURE_TIMEOUT_EVT );  

        LCD_WRITE_STRING( "Disconnected", HAL_LCD_LINE_1 );
        LCD_WRITE_STRING_VALUE( "Reason:", pEvent->linkTerminate.reason,
                                10, HAL_LCD_LINE_2 );
        LCD_WRITE_STRING( "", HAL_LCD_LINE_3 );        
      }
      break;

    case GAP_LINK_PARAM_UPDATE_EVENT:
      {
        LCD_WRITE_STRING( "Param Update", HAL_LCD_LINE_1 );
        LCD_WRITE_STRING( "", HAL_LCD_LINE_2 );
        LCD_WRITE_STRING( "", HAL_LCD_LINE_3 );
      }
      break;
      
    default:
      break;
  }
}
Example #8
0
/*********************************************************************
 * @fn      gapRole_ProcessGAPMsg
 *
 * @brief   Process an incoming task message.
 *
 * @param   pMsg - message to process
 *
 * @return  none
 */
static void gapRole_ProcessGAPMsg( gapEventHdr_t *pMsg )
{
  uint8 notify = FALSE;   // State changed notify the app? (default no)

  switch ( pMsg->opcode )
  {
    case GAP_DEVICE_INIT_DONE_EVENT:
      {
        gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *)pMsg;
        bStatus_t stat = pPkt->hdr.status;

        if ( stat == SUCCESS )
        {
          // Save off the generated keys
          VOID osal_snv_write( BLE_NVID_IRK, KEYLEN, gapRole_IRK );
          VOID osal_snv_write( BLE_NVID_CSRK, KEYLEN, gapRole_SRK );

          // Save off the information
          VOID osal_memcpy( gapRole_bdAddr, pPkt->devAddr, B_ADDR_LEN );

          gapRole_state = GAPROLE_STARTED;

          // Update the advertising data
          stat = GAP_UpdateAdvertisingData( gapRole_TaskID,
                              TRUE, gapRole_AdvertDataLen, gapRole_AdvertData );
        }

        if ( stat != SUCCESS )
        {
          gapRole_state = GAPROLE_ERROR;
        }

        notify = TRUE;
      }
      break;

    case GAP_ADV_DATA_UPDATE_DONE_EVENT:
      {
        gapAdvDataUpdateEvent_t *pPkt = (gapAdvDataUpdateEvent_t *)pMsg;

        if ( pPkt->hdr.status == SUCCESS )
        {
          if ( pPkt->adType )
          {
            // Setup the Response Data
            pPkt->hdr.status = GAP_UpdateAdvertisingData( gapRole_TaskID,
                              FALSE, gapRole_ScanRspDataLen, gapRole_ScanRspData );
          }
          else
          {
            // Start advertising
            VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
          }
        }

        if ( pPkt->hdr.status != SUCCESS )
        {
          // Set into Error state
          gapRole_state = GAPROLE_ERROR;
          notify = TRUE;
        }
      }
      break;

    case GAP_MAKE_DISCOVERABLE_DONE_EVENT:
    case GAP_END_DISCOVERABLE_DONE_EVENT:
      {
        gapMakeDiscoverableRspEvent_t *pPkt = (gapMakeDiscoverableRspEvent_t *)pMsg;

        if ( pPkt->hdr.status == SUCCESS )
        {
          if ( pMsg->opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT )
          {
            gapRole_state = GAPROLE_ADVERTISING;
          }
          else // GAP_END_DISCOVERABLE_DONE_EVENT
          {

            if ( gapRole_AdvertOffTime != 0 )
            {
              if ( ( gapRole_AdvEnabled ) )
              {
                VOID osal_start_timerEx( gapRole_TaskID, START_ADVERTISING_EVT, gapRole_AdvertOffTime );
              }
            }
            else
            {
              // Since gapRole_AdvertOffTime is set to 0, the device should not
              // automatically become discoverable again after a period of time.
              // Set enabler to FALSE; device will become discoverable again when
              // this value gets set to TRUE
              gapRole_AdvEnabled = FALSE;
            }

            // In the Advertising Off period
            gapRole_state = GAPROLE_WAITING;

          }
        }
        else
        {
          gapRole_state = GAPROLE_ERROR;
        }
        notify = TRUE;
      }
      break;

    case GAP_LINK_ESTABLISHED_EVENT:
      {
        gapEstLinkReqEvent_t *pPkt = (gapEstLinkReqEvent_t *)pMsg;

        if ( pPkt->hdr.status == SUCCESS )
        {
          VOID osal_memcpy( gapRole_ConnectedDevAddr, pPkt->devAddr, B_ADDR_LEN );
          gapRole_ConnectionHandle = pPkt->connectionHandle;
          gapRole_state = GAPROLE_CONNECTED;

          if ( gapRole_RSSIReadRate )
          {
            // Start the RSSI Reads
            VOID osal_start_timerEx( gapRole_TaskID, RSSI_READ_EVT, gapRole_RSSIReadRate );
          }

          // Store connection information
          gapRole_ConnInterval = pPkt->connInterval;
          gapRole_ConnSlaveLatency = pPkt->connLatency;
          gapRole_ConnTimeout = pPkt->connTimeout;

          // Check whether update parameter request is enabled
          if ( gapRole_ParamUpdateEnable == TRUE )
          {
            // Get the minimum time upon connection establishment before the 
            // peripheral can start a connection update procedure.
            uint16 timeout = GAP_GetParamValue( TGAP_CONN_PAUSE_PERIPHERAL );
            
            osal_start_timerEx( gapRole_TaskID, START_CONN_UPDATE_EVT, timeout*1000 );
          }

          // Notify the Bond Manager to the connection
          VOID GAPBondMgr_LinkEst( pPkt->devAddrType, pPkt->devAddr, pPkt->connectionHandle, GAP_PROFILE_PERIPHERAL );
        }
        else if ( pPkt->hdr.status == bleGAPConnNotAcceptable )
        {
          // Set enabler to FALSE; device will become discoverable again when
          // this value gets set to TRUE
          gapRole_AdvEnabled = FALSE;

          // Go to WAITING state, and then start advertising
          gapRole_state = GAPROLE_WAITING;
        }
        else
        {
          gapRole_state = GAPROLE_ERROR;
        }
        notify = TRUE;
      }
      break;

    case GAP_LINK_TERMINATED_EVENT:
      {
        gapTerminateLinkEvent_t *pPkt = (gapTerminateLinkEvent_t *)pMsg;

        GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
        osal_memset( gapRole_ConnectedDevAddr, 0, B_ADDR_LEN );

        // Erase connection information
        gapRole_ConnInterval = 0;
        gapRole_ConnSlaveLatency = 0;
        gapRole_ConnTimeout = 0;

        // Cancel all connection parameter update timers (if any active)
        VOID osal_stop_timerEx( gapRole_TaskID, START_CONN_UPDATE_EVT );
        VOID osal_stop_timerEx( gapRole_TaskID, CONN_PARAM_TIMEOUT_EVT );
          
        // Go to WAITING state, and then start advertising
        if( pPkt->reason == LL_SUPERVISION_TIMEOUT_TERM )
        {
          gapRole_state = GAPROLE_WAITING_AFTER_TIMEOUT;
        }
        else
        {
          gapRole_state = GAPROLE_WAITING;
        }

        notify = TRUE;

        VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );

        gapRole_ConnectionHandle = INVALID_CONNHANDLE;
      }
      break;

    case GAP_LINK_PARAM_UPDATE_EVENT:
      {
        gapLinkUpdateEvent_t *pPkt = (gapLinkUpdateEvent_t *)pMsg;

        // Cancel connection param update timeout timer (if active)
        VOID osal_stop_timerEx( gapRole_TaskID, CONN_PARAM_TIMEOUT_EVT );
        
        if ( pPkt->hdr.status == SUCCESS )
        {
          // Store new connection parameters
          gapRole_ConnInterval = pPkt->connInterval;
          gapRole_ConnSlaveLatency = pPkt->connLatency;
          gapRole_ConnTimeout = pPkt->connTimeout;
          
          // Make sure there's no pending connection update procedure
          if ( osal_get_timeoutEx( gapRole_TaskID, START_CONN_UPDATE_EVT ) == 0 )
          {
            // Notify the application with the new connection parameters
            if ( pGapRoles_ParamUpdateCB != NULL )
            {
              (*pGapRoles_ParamUpdateCB)( gapRole_ConnInterval, 
                                          gapRole_ConnSlaveLatency, 
                                          gapRole_ConnTimeout );
            }
          }
        }
      }
      break;

    default:
      break;
  }

  if ( notify == TRUE )
  {
    // Notify the application with the new state change
    if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange )
    {
      pGapRoles_AppCGs->pfnStateChange( gapRole_state );
    }
  }
}
Example #9
0
/*********************************************************************
 * @fn      SerialApp_ProcessEvent
 *
 * @brief   Generic Application Task event processor.
 *
 * @param   task_id  - The OSAL assigned task ID.
 * @param   events   - Bit map of events to process.
 *
 * @return  none
 */
UINT16 SerialApp_ProcessEvent( uint8 task_id, UINT16 events )
{
  if ( events & SYS_EVENT_MSG )
  {
    afIncomingMSGPacket_t *MSGpkt;

    while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive(
                                                          SerialApp_TaskID )) )
    {
      switch ( MSGpkt->hdr.event )
      {
        case ZDO_CB_MSG:
          SerialApp_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
          break;
          
        case KEY_CHANGE:
          SerialApp_HandleKeys( ((keyChange_t *)MSGpkt)->state,
                                ((keyChange_t *)MSGpkt)->keys );
          break;
  
        case AF_INCOMING_MSG_CMD:
          SerialApp_ProcessMSGCmd( MSGpkt );
          break;
  
        case ZDO_STATE_CHANGE:
          if (SerialApp_DstAddr.addrMode == afAddrNotPresent)
             ReqMatchDesc();
          break;
        default:
          break;
      }

      osal_msg_deallocate( (uint8 *)MSGpkt );  // Release the memory.
    }

    // Return unprocessed events
    return ( events ^ SYS_EVENT_MSG );
  }

  if ( events & SERIALAPP_MSG_SEND_EVT )
  {
    SerialApp_SendData( otaBuf, otaLen );

    return ( events ^ SERIALAPP_MSG_SEND_EVT );
  }

  if ( events & SERIALAPP_MSG_RTRY_EVT )
  {
    if ( --rtryCnt )
    {
      AF_DataRequest( &SerialApp_DstAddr,
                      (endPointDesc_t *)&SerialApp_epDesc,
                       SERIALAPP_CLUSTERID1, otaLen, otaBuf,
                      &SerialApp_MsgID, 0, AF_DEFAULT_RADIUS );
      osal_start_timerEx( SerialApp_TaskID, SERIALAPP_MSG_RTRY_EVT,
                                            SERIALAPP_MSG_RTRY_TIMEOUT );
    }
    else
    {
      FREE_OTABUF();
    }

    return ( events ^ SERIALAPP_MSG_RTRY_EVT );
  }

  if ( events & SERIALAPP_RSP_RTRY_EVT )
  {
    afStatus_t stat = AF_DataRequest( &SerialApp_RspDstAddr,
                                      (endPointDesc_t *)&SerialApp_epDesc,
                                       SERIALAPP_CLUSTERID2,
                                       SERIAL_APP_RSP_CNT, rspBuf,
                                      &SerialApp_MsgID, 0, AF_DEFAULT_RADIUS );

    if ( stat != afStatus_SUCCESS )
    {
      osal_start_timerEx( SerialApp_TaskID, SERIALAPP_RSP_RTRY_EVT,
                                            SERIALAPP_RSP_RTRY_TIMEOUT );
    }

    return ( events ^ SERIALAPP_RSP_RTRY_EVT );
  }

#if SERIAL_APP_LOOPBACK
  if ( events & SERIALAPP_TX_RTRY_EVT )
  {
    if ( rxLen )
    {
      if ( !HalUARTWrite( SERIAL_APP_PORT, rxBuf, rxLen ) )
      {
        osal_start_timerEx( SerialApp_TaskID, SERIALAPP_TX_RTRY_EVT,
                                              SERIALAPP_TX_RTRY_TIMEOUT );
      }
      else
      {
        rxLen = 0;
      }
    }

    return ( events ^ SERIALAPP_TX_RTRY_EVT );
  }
#endif
  
  if (events & SERIALAPP_MSG_AUTOMATCH)
  {
    if (SerialApp_DstAddr.addrMode == afAddrNotPresent)
    {
        ReqMatchDesc();
        osal_start_timerEx(SerialApp_TaskID,SERIALAPP_MSG_AUTOMATCH,4000);
    }
    else
    {
        osal_stop_timerEx(SerialApp_TaskID,SERIALAPP_MSG_AUTOMATCH);
    }
    return (events ^ SERIALAPP_MSG_AUTOMATCH);
  }

  return ( 0 );  // Discard unknown events.
}
Example #10
0
/*********************************************************************
 * @fn      SensorCB
 *
 * @brief   Callback function for CSC service.
 *
 * @param   event - service event
 * @param   pNewCummVal - pointer to new wheel revolution data
 *                        if specified by event.  NULL otherwise.
 * @return  none
 */
static void SensorCB( uint8 event, uint32 *pNewCummVal )
{
  switch ( event )
  {
    case CSC_CMD_SET_CUMM_VAL:
      // Cancel neglect timer
      if ( USING_NEGLECT_TIMEOUT )
      {
        osal_stop_timerEx( sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT );
      }

      cummWheelRevs = *pNewCummVal;

      // Start neglect timer
      if ( USING_NEGLECT_TIMEOUT )
      {
        osal_start_timerEx( sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT, NEGLECT_TIMEOUT_DELAY );
      }
      break;

    case CSC_CMD_UPDATE_SENS_LOC:
      // Cancel neglect timer
      if ( USING_NEGLECT_TIMEOUT )
      {
        osal_stop_timerEx( sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT );
      }

      // Get updated sensor location
      Cycling_GetParameter( CSC_SENS_LOC, &sensorLocation );

      // Start neglect timer
      if ( USING_NEGLECT_TIMEOUT )
      {
        osal_start_timerEx( sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT, NEGLECT_TIMEOUT_DELAY );
      }
      break;

    case CSC_MEAS_NOTI_ENABLED:
      // Cancel neglect timer
      if ( USING_NEGLECT_TIMEOUT )
      {
        osal_stop_timerEx( sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT );
      }

      // If connected start periodic measurement
      if (gapProfileState == GAPROLE_CONNECTED)
      {
        osal_start_timerEx( sensor_TaskID, CSC_PERIODIC_EVT, DEFAULT_CSC_PERIOD );
      }
      break;

    case CSC_MEAS_NOTI_DISABLED:
      // Stop periodic measurement
      osal_stop_timerEx( sensor_TaskID, CSC_PERIODIC_EVT );

      // Start neglect timer
      if ( USING_NEGLECT_TIMEOUT )
      {
        osal_start_timerEx( sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT, NEGLECT_TIMEOUT_DELAY );
      }
      break;

    case CSC_READ_ATTR:
    case CSC_WRITE_ATTR:
      if ( USING_NEGLECT_TIMEOUT )
      {
        // Cancel neglect timer
        osal_stop_timerEx( sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT );

        // Start neglect timer
        osal_start_timerEx( sensor_TaskID, CSC_NEGLECT_TIMEOUT_EVT, NEGLECT_TIMEOUT_DELAY );
      }
      break;

    default:
      break;
  }
}
/*********************************************************************************************
 * @fn      simpleBLECentralEventCB
 *
 * @brief   Central event callback function.
 *
 * @param   pEvent - pointer to event structure
 *
 * @return  none
 **********************************************************************************************/
static void simpleBLECentralEventCB( gapCentralRoleEvent_t *pEvent ){
  switch ( pEvent->gap.opcode ){
                case GAP_DEVICE_INIT_DONE_EVENT:{  
       			    //LCDPrintText("Central Initialized",0,PRINT_STRING);
                            osal_memcpy(mac_buffer[0],pEvent->initDone.devAddr, MAC_LEN);        		               
                            HalLcdWriteString(bdAddr2Str( mac_buffer[0]), HAL_LCD_LINE_1); 
			    
                            
                            uint32 random_scan_duration =500;//to avoid normal scan be discarded by the timer,so its lasting-time should be short
                            GAP_SetParamValue( TGAP_GEN_DISC_SCAN, random_scan_duration );        //random scan duration
                            //LCDPrintText("discovering",0,PRINT_STRING);
                            
                            uint32 timeout_value = 200;				// timeout_value - in milliseconds.
                            osal_start_timerEx(MasterSlaveSwitchTaskID, PERIOD_DETECH_EVT, timeout_value);
                            

                            
                            uint8 return_status;
                            if(return_status = GAPCentralRole_StartDiscovery(DISCOVERY_MODE, ACTIVE_SCAN, DISCOVERY_WHITE_LIST ))
                                 	LCDPrintText("discovery error:",return_status,PRINT_VALUE); 
			    break;
                }
      	
      
                case GAP_DEVICE_INFO_EVENT:{						//find a new device 				     			
				// filtering device discovery results based on service UUID
                            //LCDPrintText("find new device",0,PRINT_STRING);   
                            if(simpleBLEScanRes >= MAX_SCAN_RES){
                                            GAPCentralRole_CancelDiscovery();
                                            break;
                            }
                            
                            if ( simpleBLEFindSvcUuid(WANTED_SERVICE_UUID, pEvent->deviceInfo.pEvtData, pEvent->deviceInfo.dataLen) ){
         				simpleBLEAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType );
                                   //GAPCentralRole_CancelDiscovery();     //stop discoverying                                    
                            }			
			    break;
                }
      		           
   	 	case GAP_DEVICE_DISCOVERY_EVENT:{   			//discaovery has completed 
                           osal_stop_timerEx(MasterSlaveSwitchTaskID,PERIOD_DETECH_EVT);
                            //LCDPrintText("disca completed ",0,PRINT_STRING);    
        		    if ( simpleBLEScanRes > 0 ){
	          			// connect to current device in scan result                                                                             
                                        uint8 random_select = random_num%simpleBLEScanRes;
                                        //LCDPrintText("random_select ",random_select,PRINT_STRING); 
					CurrentConnectionInfo.MacType= simpleBLEDevList[random_select].addrType;
	     		 		CurrentConnectionInfo.MacAddr= simpleBLEDevList[random_select].addr; 
          				uint8 return_status;
                                        if(return_status = GAPCentralRole_EstablishLink( LINK_HIGH_DUTY_CYCLE, LINK_WHITE_LIST, CurrentConnectionInfo.MacType, CurrentConnectionInfo.MacAddr)){
                                                  LCDPrintText("Link Error",return_status,PRINT_VALUE); 
                                                  osal_set_event(MasterSlaveSwitchTaskID, MSS_CHANGE_ROLE_EVT);
                                        } 
			    }

                            else{
					//LCDPrintText("no device found",0,PRINT_STRING);                                        
                                       	osal_set_event(MasterSlaveSwitchTaskID, MSS_CHANGE_ROLE_EVT);     //switch to periperal                                        
                            }


			    break;
      		}
      
    		case GAP_LINK_ESTABLISHED_EVENT:{
      	 		    if ( pEvent->gap.hdr.status == SUCCESS ){ 
                                        
					//LCDPrintText("Connected",0,PRINT_STRING);     				
          				CurrentConnectionInfo.Handle= pEvent->linkCmpl.connectionHandle;  
                                        
                                        if(CharHandleSearchFlag == 1)
         				      simpleBLECentralStartDiscovery(); 
                                        else{
                                              ClientWriteValue();                                              
                                              CharSendingFlag =1;
                                              //LCDPrintText("NO NEED TO",0,PRINT_STRING);  
                                        }
      	 		    }
       			
       			    else{				                                        
                                        LCDPrintText("Connect Failed ",pEvent->gap.hdr.status,PRINT_VALUE);
                                            osal_set_event(MasterSlaveSwitchTaskID, MSS_CHANGE_ROLE_EVT);
       			    	}

			    break;
      		}
      

    		case GAP_LINK_TERMINATED_EVENT:{       
                                        osal_set_event(MasterSlaveSwitchTaskID, MSS_CHANGE_ROLE_EVT);
      			    break;
      		}

    		case GAP_LINK_PARAM_UPDATE_EVENT:
      				break;
      
    		default:
      				break;
  	}
}
Example #12
0
/*********************************************************************
 * @fn      SensorCB
 *
 * @brief   Callback function for RSC service.
 *
 * @param   event - service event
 * @param   pNewCummVal - pointer to new total distanace data
 *                        if specified by event.  NULL otherwise.
 *
 * @return  SUCCESS if operation successful. FAILURE, otherwise.
 */
static bStatus_t SensorCB(uint8 event, uint32 *pNewCummVal)
{
  bStatus_t status = SUCCESS;

  switch ( event )
  {
    case RSC_CMD_SET_CUMM_VAL:
      // Cancel neglect timer
      if ( USING_NEGLECT_TIMEOUT )
      {
        osal_stop_timerEx( sensor_TaskID, RSC_NEGLECT_TIMEOUT_EVT );
      }

      // Update total distance
      totalDistance = *pNewCummVal;

      // Start neglect timer
      if ( USING_NEGLECT_TIMEOUT )
      {
        osal_start_timerEx( sensor_TaskID, RSC_NEGLECT_TIMEOUT_EVT, NEGLECT_TIMEOUT_DELAY );
      }
      break;

    case RSC_CMD_START_SENS_CALIB:
      if ( sensorFlags[sensorFlagsIdx] != RSC_FLAGS_AT_REST )
      {
        // Induce a calibration error for conformance testing
        status = FAILURE;
      }
      break;

    case RSC_CMD_UPDATE_SENS_LOC:
      // Cancel neglect timer
      if ( USING_NEGLECT_TIMEOUT )
      {
        osal_stop_timerEx( sensor_TaskID, RSC_NEGLECT_TIMEOUT_EVT );
      }

      // Get updated sensor location
      Running_GetParameter( RSC_SENS_LOC, &sensorLocation );

      // Start neglect timer
      if ( USING_NEGLECT_TIMEOUT )
      {
        osal_start_timerEx( sensor_TaskID, RSC_NEGLECT_TIMEOUT_EVT, NEGLECT_TIMEOUT_DELAY );
      }
      break;

    case RSC_MEAS_NOTI_ENABLED:
      // Cancel neglect timer
      if ( USING_NEGLECT_TIMEOUT )
      {
        osal_stop_timerEx( sensor_TaskID, RSC_NEGLECT_TIMEOUT_EVT );
      }

      // if connected start periodic measurement
      if (gapProfileState == GAPROLE_CONNECTED)
      {
        osal_start_timerEx( sensor_TaskID, RSC_PERIODIC_EVT, DEFAULT_RSC_PERIOD );
      }
      break;

    case RSC_MEAS_NOTI_DISABLED:
      // stop periodic measurement
      osal_stop_timerEx( sensor_TaskID, RSC_PERIODIC_EVT );

      // Start neglect timer
      if ( USING_NEGLECT_TIMEOUT )
      {
        osal_start_timerEx( sensor_TaskID, RSC_NEGLECT_TIMEOUT_EVT, NEGLECT_TIMEOUT_DELAY );
      }
      break;

    case RSC_READ_ATTR:
    case RSC_WRITE_ATTR:
      if ( USING_NEGLECT_TIMEOUT )
      {
        // Cancel neglect timer
        osal_stop_timerEx( sensor_TaskID, RSC_NEGLECT_TIMEOUT_EVT );

        // Start neglect timer
        osal_start_timerEx( sensor_TaskID, RSC_NEGLECT_TIMEOUT_EVT, NEGLECT_TIMEOUT_DELAY );
      }
      break;

    default:
      break;
  }

  return ( status );
}
Example #13
0
/*********************************************************************
 * @fn      sensor_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 sensor_HandleKeys( uint8 shift, uint8 keys )
{
  if ( keys == ( HAL_KEY_SW_1 | HAL_KEY_SW_2 ) )
  {
    // Reset in progress has started
    resetInProgress = TRUE;

    // Set OSAL timer for reset
    osal_start_timerEx( sensor_TaskID, RSC_RESET_EVT, RSC_RESET_DELAY );
  }
  else if ( keys & HAL_KEY_SW_1 )
  {
    if ( resetInProgress == TRUE )
    {
      // Cancel the reset
      resetInProgress = FALSE;
      osal_stop_timerEx ( sensor_TaskID, RSC_RESET_EVT );
    }

    // set simulated measurement flag index
    if (++sensorFlagsIdx == FLAGS_IDX_MAX)
    {
      sensorFlagsIdx = 0;
    }
  }
  else if ( keys & HAL_KEY_SW_2 )
  {
    if ( resetInProgress == TRUE )
    {
      // Cancel the reset
      resetInProgress = FALSE;
      osal_stop_timerEx ( sensor_TaskID, RSC_RESET_EVT );
    }

    // if not in a connection, toggle advertising on and off
    if ( gapProfileState != GAPROLE_CONNECTED )
    {
      uint8 status;

      // Set fast advertising interval for user-initiated connections
      GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, DEFAULT_FAST_ADV_INTERVAL );
      GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, DEFAULT_FAST_ADV_INTERVAL );
      GAP_SetParamValue( TGAP_GEN_DISC_ADV_MIN, DEFAULT_WHITE_LIST_ADV_DURATION );

      // toggle GAP advertisement status
      GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, &status );
      status = !status;

      // If not already using white list, begin to do so.
      // Only do so if about to begin advertising
      if ( USING_WHITE_LIST && status == TRUE )
      {
        uint8 bondCount = 0;

        GAPBondMgr_GetParameter( GAPBOND_BOND_COUNT, &bondCount );

        if ((sensorUsingWhiteList == FALSE) && (bondCount > 0) )
        {
          uint8 value = GAP_FILTER_POLICY_WHITE;

          GAPRole_SetParameter(GAPROLE_ADV_FILTER_POLICY, sizeof( uint8 ), &value);

          sensorUsingWhiteList = TRUE;
        }
      }

      GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &status );

      // Set state variable
      if (status == FALSE)
      {
        sensorAdvCancelled = TRUE;
      }
    }
    else if ( gapProfileState == GAPROLE_CONNECTED )
    {
      // If connected, change rate of motion
      if( (++motionIdx) == MOTION_IDX_MAX )
      {
        motionIdx = 0;
      }

      motion = motionCycle[motionIdx];
    }
  }
  // end of key press
  else if ( keys == 0x00 )
  {
    if ( resetInProgress == TRUE )
    {
      resetInProgress = FALSE;

      osal_stop_timerEx( sensor_TaskID, RSC_RESET_EVT );
    }
  }
}
Example #14
0
static void ther_handle_ps_event(unsigned char event, unsigned char *data, unsigned char *len)
{
	struct ther_info *ti = &ther_info;
	UTCTimeStruct utc;
	uint16 high_temp_threshold;

	switch (event) {
	case THER_PS_GET_WARNING_ENABLED:
		*data = ti->warning_enabled;
		*len = 1;
		print(LOG_DBG, MODULE "get warning enabled: %d\n", *data);
		break;

	case THER_PS_SET_WARNING_ENABLED:
		ti->warning_enabled = *data;
		print(LOG_DBG, MODULE "set warning enabled: %d\n", *data);
		break;

	case THER_PS_CLEAR_WARNING:
		print(LOG_DBG, MODULE "clear warning: %d\n", *data);
		ther_clear_high_temp_warning(ti);
		break;

	case THER_PS_GET_HIGH_WARN_TEMP:
		memcpy(data, &ti->high_temp_threshold, sizeof(ti->high_temp_threshold));
		*len = sizeof(ti->high_temp_threshold);
		print(LOG_DBG, MODULE "get high temp: %d\n", *(unsigned short *)data);
		break;

	case THER_PS_SET_HIGH_WARN_TEMP:
		memcpy(&high_temp_threshold, data, sizeof(high_temp_threshold));

		if (storage_write_high_temp_threshold(high_temp_threshold)) {
			print(LOG_DBG, MODULE "set high temp: %d\n", high_temp_threshold);
			ti->high_temp_threshold = high_temp_threshold;
			ti->next_warning_threshold = ti->high_temp_threshold;
		} else {
			print(LOG_DBG, MODULE "set high temp: %d failed\n", high_temp_threshold);
		}

		break;

	case THER_PS_GET_TIME:
		osal_ConvertUTCTime(&utc, osal_getClock());

		memcpy(data, &utc, sizeof(utc));
		*len = sizeof(utc);
		print(LOG_DBG, MODULE "get time: %d-%02d-%02d %02d:%02d:%02d\n",
				utc.year, utc.month, utc.day, utc.hour, utc.minutes, utc.seconds);
		break;

	case THER_PS_SET_TIME:
		memcpy(&utc, data, sizeof(utc));
		osal_setClock(osal_ConvertUTCSecs(&utc));
		print(LOG_DBG, MODULE "set time: %d-%02d-%02d %02d:%02d:%02d\n",
				utc.year, utc.month, utc.day, utc.hour, utc.minutes, utc.seconds);

		ti->start_sec = osal_ConvertUTCSecs(&utc);
		break;

	case THER_PS_GET_DEBUG:
		{
			ti->mode = CAL_MODE;
			/*
			 * stop temp measurement
			 */
			osal_stop_timerEx(ti->task_id, TH_TEMP_MEASURE_EVT);
			ther_temp_power_on();
			ti->temp_measure_stage = TEMP_STAGE_SETUP;

			/*
			 * stop batt measurement
			 */
			osal_stop_timerEx(ti->task_id, TH_BATT_EVT);
		}
		*(unsigned short *)data = ther_get_hw_adc(HAL_ADC_CHANNEL_0, FROM_CUSTOM);
		*len = 2;
		break;

	case THER_PS_SET_DEBUG:
		break;

	default:
		*len = 0;
		break;
	}
}
Example #15
0
/*********************************************************************
 * @fn      zcl_ProcessEZMode
 *
 * @brief   Called when EZ-Mode changes state. See EZMODE_STATE_xxxx in zcl_ezmode.h
 *
 * @param   none
 *
 * @return  status
 */
static void zcl_ProcessEZMode( void )
{
  zAddrType_t dstAddr;
  afAddrType_t afDstAddr;
  zclEZMode_CBData_t cbData;

  dstAddr.addr.shortAddr = 0xfffc;        // all routers (for PermitJoin) devices
  dstAddr.addrMode = AddrBroadcast;

  afDstAddr.addr.shortAddr = 0xffff;      // all devices (for IdentifyQuery)
  afDstAddr.addrMode = afAddrBroadcast;
  afDstAddr.endPoint = 0xff;

  switch(zclEZModeState)
  {
    // openers will broadcast permit joining
    case EZMODE_STATE_OPENER:
      zclEZModeOpener = 1;

      // enable joining both locally and over-the-air
      NLME_PermitJoiningRequest( (byte)(EZMODE_TIME / 1000)  );
      ZDP_MgmtPermitJoinReq( &dstAddr, (byte)(EZMODE_TIME / 1000), TRUE, FALSE);

      // then go to identifying state
      zcl_SetEZModeState(EZMODE_STATE_IDENTIFYING);
    break;

    // joiners will try to join the network, and if success will go to identifying state
    case EZMODE_STATE_JOINER:
      zclEZModeOpener = 0;
      ZDOInitDevice(0);   // see ZDO_STATE_CHANGE in zclSampleSw_event_loop()
    break;

    // go into identify state
    case EZMODE_STATE_IDENTIFYING:

      // tell app to go into identify mode
      if ( zclEZModeRegisterData.pfnNotifyCB )
      {
        (*zclEZModeRegisterData.pfnNotifyCB)( zclEZModeState, NULL );
      }

      // initiators start looking for other nodes in identify mode
      if ( zclEZModeInvokeData.initiator )
      {
        zcl_SetEZModeState ( EZMODE_STATE_WAITING_IDENTIFYQUERYRSP );
      }
    break;

    // timeout out with no query response, send another
    case EZMODE_STATE_WAITING_IDENTIFYQUERYRSP:
      // ZStatus_t zclGeneral_SendIdentifyQuery( uint8 srcEP, afAddrType_t *dstAddr, uint8 disableDefaultRsp, uint8 seqNum );
      // NOTE: Ensure that Identify Cluster is enabled to use this function for EZ-Mode
      zclGeneral_SendIdentifyQuery( zclEZModeInvokeData.endpoint, &afDstAddr, TRUE, (*zclEZModeRegisterData.pZclSeqNum)++ );

      // wait some time before sending out the next IdentifyQuery, will stop when we get a response
      osal_start_timerEx( *zclEZModeRegisterData.pTaskID, zclEZModeRegisterData.processEvt, EZMODE_IDQUERYTIME );
      break;

    // waiting for simple descriptor response
    case EZMODE_STATE_WAITING_MATCHDESCRSP:
    break;

    // if waiting on autoclose, then we're done. Go to success.
    case EZMODE_STATE_AUTOCLOSE:

      // special case: if 2 initators, we only fail if no match from either side
      if( zclEZModeInvokeData.initiator && !zclEZModeMatched )
      {
        zcl_SetEZModeError ( EZMODE_ERR_NOMATCH );
      }

      // if user specified callback, call on AutoClose
      if ( zclEZModeRegisterData.pfnNotifyCB )
      {
        cbData.sAutoClose.err = zclEZModeErr;
        (*zclEZModeRegisterData.pfnNotifyCB)( zclEZModeState, &cbData );
      }

      // no longer will timeout, since cannot fail
      osal_stop_timerEx( *zclEZModeRegisterData.pTaskID, zclEZModeRegisterData.timeoutEvt );

      // wait a little to turn off identify mode, to give time for the other side to discover
      // in case of complex devices (both target/initiator)
      osal_start_timerEx( *zclEZModeRegisterData.pTaskID, zclEZModeRegisterData.processEvt, EZMODE_AUTOCLOSETIME );

      // go to finish state after autoclose. Don't use zcl_SetEZModeState() because we don't want it to happen immediately
      zclEZModeState = EZMODE_STATE_FINISH;
    break;

    case EZMODE_STATE_FINISH:

      // no longer will timeout, since we're done
      osal_stop_timerEx( *zclEZModeRegisterData.pTaskID, zclEZModeRegisterData.timeoutEvt );

      // if we opened the network, close it now (turn off joining)
      if ( zclEZModeOpener )
      {
        ZDP_MgmtPermitJoinReq( &dstAddr, 0, TRUE, FALSE);
      }

      // if user callback, inform them of the finish, which will also turn off identify
      if ( zclEZModeRegisterData.pfnNotifyCB )
      {
        cbData.sFinish.err = zclEZModeErr;
        cbData.sFinish.ep = zclEZModeQueryRspEP;
        cbData.sFinish.nwkaddr = zclEZModeQueryRspNwkAddr;
        (*zclEZModeRegisterData.pfnNotifyCB)( zclEZModeState, &cbData );
      }

      // done, back to ready state
      zclEZModeState = EZMODE_STATE_READY;
    break;
  }

}
Example #16
0
//static void peripheralStateNotificationCB( gaprole_States_t newState )
static void peripheralStateNotificationCB( gaprole_States_t* newState )
{

    // if connected
    if ( *newState == GAPROLE_CONNECTED )
    {
        linkDBItem_t  *pItem;

        // Get connection handle
        GAPRole_GetParameter( GAPROLE_CONNHANDLE, &gapConnHandle );

        // Get peer bd address
        if ( (pItem = linkDB_Find( gapConnHandle )) != NULL)
        {
            // If connected to device without bond do service discovery
            if ( !osal_memcmp( pItem->addr, timeAppBondedAddr, B_ADDR_LEN ) )
            {
                timeAppDiscoveryCmpl = FALSE;
            }
            else
            {
                timeAppDiscoveryCmpl = TRUE;
            }

            // if this was last connection address don't do discovery
            if(osal_memcmp( pItem->addr, lastConnAddr, B_ADDR_LEN ))
            {
                timeAppDiscoveryCmpl = TRUE;
                connectedToLastAddress = true;
            }
            else
            {
                //save the last connected address
                osal_memcpy(lastConnAddr, pItem->addr, B_ADDR_LEN );
            }

            // Initiate service discovery if necessary
            if ( timeAppDiscoveryCmpl == FALSE )
            {
                osal_start_timerEx( thermometerTaskId, TH_START_DISCOVERY_EVT, DEFAULT_DISCOVERY_DELAY );
            }

            //on connection initiate disconnect timer in 20 seconds
            osal_start_timerEx( thermometerTaskId, TH_DISCONNECT_EVT, 20000 );

        }
    }
    // if disconnected
    else if ( gapProfileState == GAPROLE_CONNECTED &&
              *newState != GAPROLE_CONNECTED )
    {
        timeAppDisconnected();

        //always stop intermediate timer
        osal_stop_timerEx( thermometerTaskId, TH_PERIODIC_IMEAS_EVT );

    }
    // if started
    else if ( *newState == GAPROLE_STARTED )
    {
        // Initialize time clock
        timeAppClockInit();
    }

    gapProfileState = *newState;

    updateUI();

}
Example #17
0
/*********************************************************************
 * @fn      gapProfileStateCB
 *
 * @brief   Notification from the profile of a state change.
 *
 * @param   newState - new state
 *
 * @return  none
 */
static void peripheralStateNotificationCB( gaprole_States_t newState )
{
 
  
  
  // if connected
  if ( newState == GAPROLE_CONNECTED )
  {
    linkDBItem_t  *pItem;

    
    HalLedSet ( HAL_LED_1, HAL_LED_MODE_OFF );
    
    // Get connection handle
    GAPRole_GetParameter( GAPROLE_CONNHANDLE, &gapConnHandle );

    // Get peer bd address
    if ( (pItem = linkDB_Find( gapConnHandle )) != NULL)
    {
      // If connected to device without bond do service discovery
      if ( !osal_memcmp( pItem->addr, timeAppBondedAddr, B_ADDR_LEN ) )
      {
        timeAppDiscoveryCmpl = FALSE;
      }
      else
      {
        timeAppDiscoveryCmpl = TRUE;
      }
      
      // if this was last connection address don't do discovery
      if(osal_memcmp( pItem->addr, lastConnAddr, B_ADDR_LEN ))
      {
        timeAppDiscoveryCmpl = TRUE;
        connectedToLastAddress = true;
      }
      else
      {
        //save the last connected address  
        osal_memcpy(lastConnAddr, pItem->addr, B_ADDR_LEN );
      }

      // Initiate service discovery if necessary
      if ( timeAppDiscoveryCmpl == FALSE )
      {
       
       // osal_start_timerEx( bloodPressureTaskId, BP_START_DISCOVERY_EVT, DEFAULT_DISCOVERY_DELAY );
      }
        
    } 
  }
  // if disconnected
  else if ( gapProfileState == GAPROLE_CONNECTED && 
            newState != GAPROLE_CONNECTED )
  {
    timeAppDisconnected();
    
    //always stop intermediate timer
    osal_stop_timerEx( bloodPressureTaskId, BP_TIMER_CUFF_EVT ); 
    
    // stop disconnect timer
    osal_stop_timerEx( bloodPressureTaskId, BP_DISCONNECT_PERIOD ); 
    
  }    
  // if started
  else if ( newState == GAPROLE_STARTED )
  {
    // Initialize time clock display
    //timeAppClockInit();
  }
  
  gapProfileState = newState;
  
  updateUI();
  
}
Example #18
0
/**************************************************************************************************
 * @fn          MHMSZdoStateChange 
 *
 * @brief       This function is called by MHMSSysEvtMsg() for a ZDO_STATE_CHANGE message.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
static void MHMSZdoStateChange(void)
{
  if(DEV_ZB_COORD == devState) 
  {
    (void)osal_stop_timerEx(MHMSTaskId, MHMS_EVT_ANN);

    if ((DEV_ZB_COORD == devState) || (DEV_ROUTER == devState) || (DEV_END_DEVICE == devState))
    {

      if (INVALID_NODE_ADDR == MHMSAddr)
      {
      MHMSAddr = NWK_PAN_COORD_ADDR;
      }

      if (INVALID_NODE_ADDR != MHMSAddr)
      {
        if (ZSuccess != osal_start_timerEx(MHMSTaskId, MHMS_EVT_ANN, MHMS_DLY_ANN))
        {
          (void)osal_set_event(MHMSTaskId, MHMS_EVT_ANN);
        }
      }
    }
  }
  else if ((DEV_ROUTER == devState) || (DEV_END_DEVICE == devState))
  {
    (void)osal_stop_timerEx(MHMSTaskId, MHMS_EVT_DAT);
    MHMSEvtDat_sync = FALSE; //allow node to respond to Anounce commands to begin pulse collection

        if ((DEV_ROUTER == devState) || (DEV_END_DEVICE == devState)) //
        {
          uint16 tmp = NLME_GetCoordShortAddr();
          uint8 dly = MHMS_STG_DAT;

          MHMSDat[MHMS_PAR_LSB] = LO_UINT16(tmp);
          MHMSDat[MHMS_PAR_MSB] = HI_UINT16(tmp);
          
          TestDatTx[MHMS_PAR_LSB] = LO_UINT16(tmp);
          TestDatTx[MHMS_PAR_MSB] = HI_UINT16(tmp);
          if ((DEV_ROUTER == devState) || (DEV_ZB_COORD == devState))
          {
            MHMSDat[MHMS_TYP_IDX] |= 0x80;
            TestDatTx[MHMS_TEST_PAYLOAD_LEN-3] |= 0x80;

          }
          else
          {
            MHMSDat[MHMS_TYP_IDX] &= (0xFF ^ 0x80);
            TestDatTx[MHMS_TEST_PAYLOAD_LEN-3] &= (0xFF ^ 0x80);
          }

          if (INVALID_NODE_ADDR != MHMSAddr && dev_gateway == FALSE)
          {
            if (ZSuccess != osal_start_timerEx(MHMSTaskId, MHMS_EVT_DAT, (dly + MHMS_DLY_MIN)))
            {
              (void)osal_set_event(MHMSTaskId, MHMS_EVT_DAT);
            }
          }

          if (0 == 0)
          {
            (void)osal_cpyExtAddr(MHMSDat+MHMS_IEE_IDX, &aExtendedAddress);
            (void)osal_cpyExtAddr(TestDatTx+MHMS_IEE_IDX, &aExtendedAddress);
          }
        }
  }

#if defined LCD_SUPPORTED
  HalLcdWriteValue(devState, 10, HAL_LCD_LINE_4);
#endif
}
Example #19
0
static void hidappProcessGATTMsg( gattMsgEvent_t *pPkt )
{
  // Build the message first
  switch ( pPkt->method )
  {
    case ATT_HANDLE_VALUE_NOTI:
      // First try to send out pending HID report
      if ( reportRetries > 0 )
      {
        hidappSendInReport( &lastInReport );

        reportRetries = 0;
        osal_stop_timerEx( hidappTaskId, HIDAPP_EVT_REPORT_RETRY );
      }

      // Send incoming HID report
      if ( hidappSendInReport( &(pPkt->msg.handleValueNoti) ) == FALSE )
      {
        // Save report for retries later
        osal_memcpy( &lastInReport, &(pPkt->msg.handleValueNoti), sizeof( attHandleValueNoti_t ) );

        reportRetries = 1;
        osal_start_timerEx( hidappTaskId, HIDAPP_EVT_REPORT_RETRY, HIDAPP_INPUT_RETRY_TIMEOUT );
      }
      break;

    case ATT_FIND_BY_TYPE_VALUE_RSP:
      // Response from GATT_DiscPrimaryServiceByUUID
      // Service found, store handles
      if ( pPkt->msg.findByTypeValueRsp.numInfo > 0 )
      {
        serviceStartHandle = pPkt->msg.findByTypeValueRsp.handlesInfo[0].handle;
        serviceEndHandle   = pPkt->msg.findByTypeValueRsp.handlesInfo[0].grpEndHandle;
      }
      // If procedure complete
      else if ( pPkt->hdr.status == bleProcedureComplete )
      {
        if ( serviceStartHandle != 0 )
        {
          if ( serviceToDiscover == GATT_SERVICE_UUID )
          {
            // Begin the search for characteristic handle of the service
            readReq.startHandle = serviceStartHandle;
            readReq.endHandle = serviceEndHandle;
            readReqType.len = 2;
            readReqType.uuid[0] = LO_UINT16(SERVICE_CHANGED_UUID);
            readReqType.uuid[1] = HI_UINT16(SERVICE_CHANGED_UUID);
            readReq.type = readReqType;

            GATT_DiscCharsByUUID(connHandle, &readReq, hidappTaskId );
          }
          else if ( serviceToDiscover == HID_SERVICE_UUID )
          {
            // Discover all characteristics
            GATT_DiscAllChars( connHandle, serviceStartHandle, serviceEndHandle, hidappTaskId );
          }
        }
      }
      break;

    case ATT_READ_BY_TYPE_RSP:
      // Response from Discover all Characteristics.
      // Success indicates packet with characteristic discoveries.
      if ( pPkt->hdr.status == SUCCESS )
      {
        attReadByTypeRsp_t rsp = pPkt->msg.readByTypeRsp;
        uint8 idx = 0;

        if ( serviceToDiscover ==  GATT_SERVICE_UUID )
        {
          // We have discovered the GATT Service Characteristic handle
          uint8 low = LO_UINT16(pPkt->msg.readByTypeRsp.dataList[3]);
          uint8 high = HI_UINT16(pPkt->msg.readByTypeRsp.dataList[4]);
          serviceChangeHandle = BUILD_UINT16(low, high);
          // Break to skip next part, it doesn't apply here
          break;
        }

        // Search characteristics for those with notification permissions.
        while( idx < ((rsp.numPairs * rsp.len ) - 1))
        {
          // Check permissions of characteristic for notification permission
          if ( (rsp.dataList[idx+2] & GATT_PROP_NOTIFY ) )
          {
            uint16* pHandle = (mouseCharHandle == GATT_INVALID_HANDLE) ? &mouseCharHandle : &keyCharHandle ;

            if ( pHandle == &keyCharHandle && consumerCtrlCharHandle == GATT_INVALID_HANDLE )
            {
              pHandle = ( keyCharHandle == GATT_INVALID_HANDLE ) ? &keyCharHandle : &consumerCtrlCharHandle;
            }

            if ( *pHandle == GATT_INVALID_HANDLE )
            {
              *pHandle = BUILD_UINT16( rsp.dataList[idx+3], rsp.dataList[idx+4] );
            }
          }

          idx += rsp.len;
        }
      }
      // This indicates that there is no more characteristic data
      // to be discovered within the given handle range.
      else if ( pPkt->hdr.status == bleProcedureComplete )
      {
        if ( serviceToDiscover == GATT_SERVICE_UUID )
        {
          // Begin Service Discovery of HID Service
          serviceToDiscover = HID_SERVICE_UUID;
          hidappDiscoverService( connHandle, HID_SERVICE_UUID );
          // Break to skip next part, it doesn't apply yet.
          break;
        }

        if ( enableCCCDs == TRUE )
        {
          mouseCCCHandle = mouseCharHandle + 1;

          // Begin configuring the characteristics for notifications
          hidappEnableNotification( connHandle, mouseCCCHandle );
        }
        else
        {
          serviceDiscComplete = TRUE;
        }
      }
      break;

    case ATT_WRITE_RSP:
      if ( pPkt->hdr.status == SUCCESS && !serviceDiscComplete )
      {
        uint16 handle = ( keyCCCHandle == GATT_INVALID_HANDLE ) ?
                        ( keyCCCHandle = keyCharHandle + 1 ) :
                        ( consumerCtrlCCCHandle = consumerCtrlCharHandle + 1 );

        hidappEnableNotification( connHandle, handle );

        if ( consumerCtrlCCCHandle != GATT_INVALID_HANDLE)
        {
          serviceDiscComplete = TRUE;
        }
      }
      break;

    // Service Change indication
    case ATT_HANDLE_VALUE_IND:
      // Note: this logic assumes that the only indications that will be sent
      //       will come from that GATT Service Changed Characteristic
      if ( pPkt->hdr.status == SUCCESS )
      {
        serviceChange = CHANGE_OCCURED;

        // Acknowledge receipt of indication
        ATT_HandleValueCfm( pPkt->connHandle );

        // Handles in server have changed while devices are connected
        if ( ( gapBondMgrState == PAIRED_BONDED_STATE ) &&
            ( serviceChangeHandle == pPkt->msg.handleValueInd.handle ) )
        {
          // Begin Service Discovery of HID Service
          serviceToDiscover = HID_SERVICE_UUID;
          hidappDiscoverService( connHandle, HID_SERVICE_UUID );

          serviceChange = NO_CHANGE;
        }
      }
      break;

    default:
      // Unknown event
      break;
  }
}
Example #20
0
void OS_timer_stop(unsigned char id)
{
  blueBasic_timers[id].linenum = 0;
  osal_stop_timerEx(blueBasic_TaskID, BLUEBASIC_EVENT_TIMER << id);
}
Example #21
0
/*********************************************************************
 * @fn      hidappCentralEventCB
 *
 * @brief   Notification from the profile of a state change.
 *
 * @param   pEvent - new role event
 *
 * @return  none
 */
static void hidappCentralEventCB( gapCentralRoleEvent_t *pEvent )
{
  static uint8 addrType;
  static uint8 peerDeviceFound = FALSE;

  switch( pEvent->gap.opcode )
  {
    case GAP_DEVICE_INIT_DONE_EVENT:
      {
        gapDeviceInitDoneEvent_t *pEvt = (gapDeviceInitDoneEvent_t *)pEvent;

        // See if device has a valid BD Address
        if ( osal_isbufset( pEvt->devAddr, 0xFF, B_ADDR_LEN ) == FALSE )
        {
          #if defined ( NANO_DONGLE )

          if ( hidappBondCount() > 0 )
          {
            // Initiate connection
            hidappEstablishLink( TRUE, addrType, remoteAddr );
          }
          else
          {
            // Sit idle till ask to scan
            hidappSetIdle();
          }

          #endif //  #if defined ( NANO_DONGLE )
        }
        else
        {
          uint8 ownBDaddr[] = OWN_ADDR;

          // An old CC2540 USB Dongle has all 0xFF's for its BD Address so
          // just use the hard-coded address in that case.
          HCI_EXT_SetBDADDRCmd( ownBDaddr );

          // Re-initialize the device with the new address
          osal_set_event( hidappTaskId, HIDAPP_EVT_START );
        }
      }
      break;

    case GAP_DEVICE_INFO_EVENT:
      // Goes here before entering GAP_DEVICE_DISCOVERY_EVENT

      // Read advertising/scan response data
      // if it contains HID remote, end service discovery
      if ( hidappFindSvcUuid( HID_SERVICE_UUID,
                              pEvent->deviceInfo.pEvtData,
                              pEvent->deviceInfo.dataLen ) )
      {
        // Record peer devices address data
        addrType = pEvent->deviceInfo.addrType;
        osal_memcpy( remoteAddr, pEvent->deviceInfo.addr, B_ADDR_LEN );

        peerDeviceFound = TRUE;
      }

      if ( ( peerDeviceFound == TRUE ) &&
           ( pEvent->deviceInfo.eventType == GAP_ADTYPE_SCAN_RSP_IND ) &&
           hidappFindHIDRemote( pEvent->deviceInfo.pEvtData,
                                pEvent->deviceInfo.dataLen ) )
      {
        // End device discovery
        VOID GAPCentralRole_CancelDiscovery();
      }
      break;

    case GAP_DEVICE_DISCOVERY_EVENT:
      // If we have found a connectable device, establish a connection
      if ( peerDeviceFound == TRUE )
      {
        hidappEstablishLink( FALSE, addrType, remoteAddr );

        peerDeviceFound = FALSE;
        numScans = 0;
      }
      else if ( numScans > 0 )
      {
        numScans--;

        // Scan again
        hidappDiscoverDevices();
      }
      else
      {
        // Go idle
        hidappSetIdle();
      }
      break;

    case GAP_LINK_ESTABLISHED_EVENT:
      // Cancel initiate connection timer
      VOID osal_stop_timerEx( hidappTaskId, HIDAPP_EVT_INIT_CONNECT );

      if ( pEvent->gap.hdr.status == SUCCESS )
      {
        hidappBLEState = BLE_STATE_CONNECTED;

        HalLedSet( HAL_LED_1, HAL_LED_MODE_ON );  // green led

        connHandle = ((gapEstLinkReqEvent_t*)pEvent)->connectionHandle;
      }
      else if ( hidappBondCount() > 0 )
      {
        // Re-initiate connection
        hidappEstablishLink( TRUE, addrType, remoteAddr );
      }
      else
      {
        // Go idle
        hidappSetIdle();
      }
      break;

    case GAP_LINK_TERMINATED_EVENT:
      // Cancel initiate connection timer
      VOID osal_stop_timerEx( hidappTaskId, HIDAPP_EVT_INIT_CONNECT );

      HalLedSet( HAL_LED_1, HAL_LED_MODE_OFF ); // green led

      hidappBLEState = BLE_STATE_IDLE;
      gapBondMgrState = UNPAIRED_STATE;
      connHandle = INVALID_CONNHANDLE;

      if ( serviceDiscComplete == TRUE )
      {
        // Remember the address of the last connected remote
        osal_memcpy( remoteHandles.lastRemoteAddr, remoteAddr, B_ADDR_LEN );

        // Save handle information
        hidappSaveHandles();
      }

      // Invalidate service discovery variables.
      serviceDiscComplete    = FALSE;
      mouseCharHandle        = GATT_INVALID_HANDLE;
      keyCharHandle          = GATT_INVALID_HANDLE;
      consumerCtrlCharHandle = GATT_INVALID_HANDLE;

      mouseCCCHandle         = GATT_INVALID_HANDLE;
      keyCCCHandle           = GATT_INVALID_HANDLE;
      consumerCtrlCCCHandle  = GATT_INVALID_HANDLE;
      serviceChangeHandle    = GATT_INVALID_HANDLE;
      serviceToDiscover      = GATT_INVALID_HANDLE;

      enableCCCDs = TRUE;

      if ( hidappBondCount() > 0 )
      {
        // Re-initiate connection
        hidappEstablishLink( TRUE, addrType, remoteAddr );
      }
      else
      {
        // Go idle
        hidappSetIdle();
      }
      break;

    default:
      break;
  }
}
/*********************************************************************
 * @fn      gapRole_ProcessGAPMsg
 *
 * @brief   Process an incoming task message.
 *
 * @param   pMsg - message to process
 *
 * @return  none
 */
static void gapRole_ProcessGAPMsg( gapEventHdr_t *pMsg )
{
  uint8 notify = FALSE;   // State changed notify the app? (default no)

  switch ( pMsg->opcode )
  {
    case GAP_DEVICE_INIT_DONE_EVENT:
      {
        gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *)pMsg;
        bStatus_t stat = pPkt->hdr.status;

        if ( stat == SUCCESS )
        {
          // Save off the generated keys
          VOID osal_snv_write( BLE_NVID_IRK, KEYLEN, gapRole_IRK );
          VOID osal_snv_write( BLE_NVID_CSRK, KEYLEN, gapRole_SRK );
          
          // Save off the information
          VOID osal_memcpy( gapRole_bdAddr, pPkt->devAddr, B_ADDR_LEN );

          gapRole_state = GAPROLE_STARTED;

          // Update the advertising data
          stat = GAP_UpdateAdvertisingData( gapRole_TaskID,
                              TRUE, gapRole_AdvertDataLen, gapRole_AdvertData );
        }

        if ( stat != SUCCESS )
        {
          gapRole_state = GAPROLE_ERROR;
        }

        notify = TRUE;
      }
      break;

    case GAP_ADV_DATA_UPDATE_DONE_EVENT:
      {
        gapAdvDataUpdateEvent_t *pPkt = (gapAdvDataUpdateEvent_t *)pMsg;

        if ( pPkt->hdr.status == SUCCESS )
        {
          if ( pPkt->adType )
          {
            // Setup the Response Data
            pPkt->hdr.status = GAP_UpdateAdvertisingData( gapRole_TaskID,
                              FALSE, gapRole_ScanRspDataLen, gapRole_ScanRspData );
          }
          else
          {
            // Start advertising
            VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
          }
        }

        if ( pPkt->hdr.status != SUCCESS )
        {
          // Set into Error state
          gapRole_state = GAPROLE_ERROR;
          notify = TRUE;
        }
      }
      break;

    case GAP_MAKE_DISCOVERABLE_DONE_EVENT:
    case GAP_END_DISCOVERABLE_DONE_EVENT:
      {
        gapMakeDiscoverableRspEvent_t *pPkt = (gapMakeDiscoverableRspEvent_t *)pMsg;

        if ( pPkt->hdr.status == SUCCESS )
        {
          if ( pMsg->opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT )
          {
            if ( gapRole_state == GAPROLE_CONNECTED )
            {
              gapRole_state = GAPROLE_CONNECTED_ADV;
            }
            else
            {
              gapRole_state = GAPROLE_ADVERTISING;
            }
          }
          else // GAP_END_DISCOVERABLE_DONE_EVENT
          {
            
            if ( gapRole_AdvertOffTime != 0 )
            {
              if ( ( gapRole_AdvEnabled ) )
              {
                VOID osal_start_timerEx( gapRole_TaskID, START_ADVERTISING_EVT, gapRole_AdvertOffTime );
              }
            }
            else
            {            
              // Since gapRole_AdvertOffTime is set to 0, the device should not
              // automatically become discoverable again after a period of time.
              // Set enabler to FALSE; device will become discoverable again when
              // this value gets set to TRUE
              gapRole_AdvEnabled = FALSE;
            }

            // In the Advertising Off period
            gapRole_state = GAPROLE_WAITING;

          }
        }
        else
        {
          gapRole_state = GAPROLE_ERROR;
        }
        notify = TRUE;
      }
      break;

    case GAP_LINK_ESTABLISHED_EVENT:
      {
        gapEstLinkReqEvent_t *pPkt = (gapEstLinkReqEvent_t *)pMsg;

        if ( pPkt->hdr.status == SUCCESS )
        {
          VOID osal_memcpy( gapRole_ConnectedDevAddr, pPkt->devAddr, B_ADDR_LEN );
          gapRole_ConnectionHandle = pPkt->connectionHandle;
          gapRole_state = GAPROLE_CONNECTED;

          if ( gapRole_RSSIReadRate )
          {
            // Start the RSSI Reads
            VOID osal_start_timerEx( gapRole_TaskID, RSSI_READ_EVT, gapRole_RSSIReadRate );
          }

          // Check whether update parameter request is enabled, and check the connection parameters
          if ( ( gapRole_ParamUpdateEnable == TRUE ) &&
               ( (pPkt->connInterval < gapRole_MinConnInterval) ||
                 (pPkt->connInterval > gapRole_MaxConnInterval) ||
                 (pPkt->connLatency != gapRole_SlaveLatency)    ||
                 (pPkt->connTimeout != gapRole_TimeoutMultiplier) ))
          {
            gapRole_SendUpdateParam( pPkt->connInterval, pPkt->connLatency );
          }
          
          // Notify the Bond Manager to the connection
          VOID GAPBondMgr_LinkEst( pPkt->devAddrType, pPkt->devAddr, pPkt->connectionHandle, GAP_PROFILE_PERIPHERAL );  
        }
        else
        {
          gapRole_state = GAPROLE_ERROR;
        }
        notify = TRUE;
      }
      break;

    case GAP_LINK_TERMINATED_EVENT:
      {
        VOID GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
        osal_memset( gapRole_ConnectedDevAddr, 0, B_ADDR_LEN );
        
        if ( gapRole_state == GAPROLE_CONNECTED_ADV )
        {
          // End the non-connectable advertising
          GAP_EndDiscoverable( gapRole_TaskID );
          gapRole_state = GAPROLE_CONNECTED;
        }
        else
        {
          gapTerminateLinkEvent_t *pPkt = (gapTerminateLinkEvent_t *)pMsg;
          if( pPkt->reason == LL_SUPERVISION_TIMEOUT_TERM )
          {
            gapRole_state = GAPROLE_WAITING_AFTER_TIMEOUT;
          }
          else
          {
            gapRole_state = GAPROLE_WAITING;
          }

          notify = TRUE;

          VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
        }

        gapRole_ConnectionHandle = INVALID_CONNHANDLE;
      }
      break;

    case GAP_LINK_PARAM_UPDATE_EVENT:
      {
        gapLinkUpdateEvent_t *pPkt = (gapLinkUpdateEvent_t *)pMsg;

        if ( (pPkt->hdr.status != SUCCESS)
            || (pPkt->connInterval < gapRole_MinConnInterval)
              || (pPkt->connInterval > gapRole_MaxConnInterval) )
        {
          // Ask to change the interval
          gapRole_SendUpdateParam( pPkt->connInterval, pPkt->connLatency );
        }
        else
        {
          // All is good stop Update Parameters timeout
          VOID osal_stop_timerEx( gapRole_TaskID, UPDATE_PARAMS_TIMEOUT_EVT );
        }
      }
      break;
      
    default:
      break;
  }

  if ( notify == TRUE )
  {
    // Notify the application
    if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange )
    {
      pGapRoles_AppCGs->pfnStateChange( gapRole_state );
    }
  }
}
Example #23
0
/*********************************************************************
 * @fn      SensorGapStateCB
 *
 * @brief   Notification from the profile of a state change.
 *
 * @param   newState - new state
 *
 * @return  none
 */
static void SensorGapStateCB( gaprole_States_t newState )
{
  // if connected
  if (newState == GAPROLE_CONNECTED)
  {
    // get connection handle
    GAPRole_GetParameter(GAPROLE_CONNHANDLE, &gapConnHandle);

    // Set timer to update connection parameters
    // 5 seconds should allow enough time for Service Discovery by the collector to finish
    osal_start_timerEx( sensor_TaskID, RSC_CONN_PARAM_UPDATE_EVT, SVC_DISC_DELAY);
  }
  // if disconnected
  else if (gapProfileState == GAPROLE_CONNECTED &&
           newState != GAPROLE_CONNECTED)
  {
    uint8 advState = TRUE;
    uint8 bondCount = 0;

    // stop periodic measurement
    osal_stop_timerEx( sensor_TaskID, RSC_PERIODIC_EVT );

    // reset client characteristic configuration descriptors
    Running_HandleConnStatusCB( gapConnHandle, LINKDB_STATUS_UPDATE_REMOVED );
    //Batt_HandleConnStatusCB( gapConnHandle, LINKDB_STATUS_UPDATE_REMOVED );

    // If not already using white list, begin to do so.
    GAPBondMgr_GetParameter( GAPBOND_BOND_COUNT, &bondCount );

    if(USING_WHITE_LIST && sensorUsingWhiteList == FALSE && bondCount > 0 )
    {
      uint8 value = GAP_FILTER_POLICY_WHITE;

      GAPRole_SetParameter(GAPROLE_ADV_FILTER_POLICY, sizeof( uint8 ), &value);

      sensorUsingWhiteList = TRUE;
    }

    if ( newState == GAPROLE_WAITING_AFTER_TIMEOUT )
    {
      // link loss timeout-- use fast advertising
      GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, DEFAULT_FAST_ADV_INTERVAL );
      GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, DEFAULT_FAST_ADV_INTERVAL );
      GAP_SetParamValue( TGAP_GEN_DISC_ADV_MIN, DEFAULT_WHITE_LIST_ADV_DURATION );
    }
    else
    {
      // Else use slow advertising
      GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, DEFAULT_SLOW_ADV_INTERVAL );
      GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, DEFAULT_SLOW_ADV_INTERVAL );
      GAP_SetParamValue( TGAP_GEN_DISC_ADV_MIN, DEFAULT_WHITE_LIST_ADV_DURATION );
    }

    // Enable advertising
    GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &advState );
  }
  // if advertising stopped
  else if ( gapProfileState == GAPROLE_ADVERTISING &&
            newState == GAPROLE_WAITING )
  {
    uint8 whiteListUsed = FALSE;

    // if white list is in use, disable to allow general access
    if ( sensorUsingWhiteList == TRUE )
    {
      uint8 value = GAP_FILTER_POLICY_ALL;

      GAPRole_SetParameter(GAPROLE_ADV_FILTER_POLICY, sizeof( uint8), &value);

      whiteListUsed = TRUE;

      sensorUsingWhiteList = FALSE;
    }

    // if advertising stopped by user
    if ( sensorAdvCancelled )
    {
      sensorAdvCancelled = FALSE;
    }
    // if fast advertising interrupted to cancel white list
    else if ( ( (!USING_WHITE_LIST) || whiteListUsed) &&
              (GAP_GetParamValue( TGAP_GEN_DISC_ADV_INT_MIN ) == DEFAULT_FAST_ADV_INTERVAL ) )
    {
      uint8 advState = TRUE;

      GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, DEFAULT_FAST_ADV_INTERVAL );
      GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, DEFAULT_FAST_ADV_INTERVAL );
      GAP_SetParamValue( TGAP_GEN_DISC_ADV_MIN, DEFAULT_FAST_ADV_DURATION );
      GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &advState );
    }
    // if fast advertising switch to slow or if was already slow but using white list.
    else if ( ((!USING_WHITE_LIST) || whiteListUsed) ||
              (GAP_GetParamValue( TGAP_GEN_DISC_ADV_INT_MIN ) == DEFAULT_FAST_ADV_INTERVAL) )
    {
      uint8 advState = TRUE;

      GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, DEFAULT_SLOW_ADV_INTERVAL );
      GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, DEFAULT_SLOW_ADV_INTERVAL );
      GAP_SetParamValue( TGAP_GEN_DISC_ADV_MIN, DEFAULT_SLOW_ADV_DURATION );
      GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &advState );
    }
  }
  // if started
  else if (newState == GAPROLE_STARTED)
  {
    // Set the system ID from the bd addr
    uint8 systemId[DEVINFO_SYSTEM_ID_LEN];
    GAPRole_GetParameter(GAPROLE_BD_ADDR, systemId);

    // shift three bytes up
    systemId[7] = systemId[5];
    systemId[6] = systemId[4];
    systemId[5] = systemId[3];

    // set middle bytes to zero
    systemId[4] = 0;
    systemId[3] = 0;

    DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId);
  }

  gapProfileState = newState;
}
Example #24
0
/*********************************************************************
 * @fn      hidDevStopIdleTimer
 *
 * @brief   Stop the idle timer.
 *
 * @return  None.
 */
static void hidDevStopIdleTimer( void )
{
  osal_stop_timerEx( hidDevTaskId, HID_IDLE_EVT );
}
Example #25
0
/*********************************************************************
 * @fn      TransmitApp_DisplayResults
 *
 * @brief   Display the results and clear the accumulators
 *
 * @param   none
 *
 * @return  none
 */
void TransmitApp_DisplayResults( void )
{
#ifdef LCD_SUPPORTED
  #define LCD_W  16
  uint32 rxShdw, txShdw, tmp;
  byte lcd_buf[LCD_W+1];
  byte idx;
#endif
  // The OSAL timers are not real-time, so calculate the actual time expired.
  uint32 msecs = osal_GetSystemClock() - clkShdw;
  clkShdw = osal_GetSystemClock();

  rxTotal += rxAccum;
  txTotal += txAccum;

#if defined ( LCD_SUPPORTED )
  rxShdw = (rxAccum * 1000 + msecs/2) / msecs;
  txShdw = (txAccum * 1000 + msecs/2) / msecs;

  osal_memset( lcd_buf, ' ', LCD_W );
  lcd_buf[LCD_W] = NULL;

  idx = 4;
  tmp = (rxShdw >= 100000) ? 99999 : rxShdw;
  do
  {
    lcd_buf[idx--] = (uint8) ('0' + (tmp % 10));
    tmp /= 10;
  } while ( tmp );

  idx = LCD_W-1;
  tmp = rxTotal;
  do
  {
    lcd_buf[idx--] = (uint8) ('0' + (tmp % 10));
    tmp /= 10;
  } while ( tmp );

  HalLcdWriteString( (char*)lcd_buf, HAL_LCD_LINE_1 );
  osal_memset( lcd_buf, ' ', LCD_W );

  idx = 4;
  tmp = (txShdw >= 100000) ? 99999 : txShdw;
  do
  {
    lcd_buf[idx--] = (uint8) ('0' + (tmp % 10));
    tmp /= 10;
  } while ( tmp );

  idx = LCD_W-1;
  tmp = txTotal;
  do
  {
    lcd_buf[idx--] = (uint8) ('0' + (tmp % 10));
    tmp /= 10;
  } while ( tmp );

  HalLcdWriteString( (char*)lcd_buf, HAL_LCD_LINE_2 );
#else
  DEBUG_INFO( COMPID_APP, SEVERITY_INFORMATION, 3, rxAccum,
                                              (uint16)msecs, (uint16)rxTotal );
#endif

  if ( (rxAccum == 0) && (txAccum == 0) )
  {
    osal_stop_timerEx( TransmitApp_TaskID, TRANSMITAPP_RCVTIMER_EVT );
    timerOn = FALSE;
  }

  rxAccum = txAccum = 0;
}
Example #26
0
/*********************************************************************
 * @fn      Thermometer_ProcessEvent
 *
 * @brief   Thermometer 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 Thermometer_ProcessEvent(uint8 task_id, uint16 events)
{
	struct ther_info *ti = &ther_info;

	/* message handle */
	if ( events & SYS_EVENT_MSG ) {
		uint8 *msg;

		if ( (msg = osal_msg_receive(ti->task_id)) != NULL ) {
			ther_dispatch_msg(ti, (osal_event_hdr_t *)msg);

			osal_msg_deallocate( msg );
		}

		return (events ^ SYS_EVENT_MSG);
	}

	if (events & TH_POWER_ON_EVT) {
		ther_system_power_on(ti);

		return (events ^ TH_POWER_ON_EVT);
	}

	if (events & TH_POWER_OFF_EVT) {
		ther_system_power_off_post(ti);

		return (events ^ TH_POWER_OFF_EVT);
	}

	if (events & TH_AUTO_POWER_OFF_EVT) {
		if (!ti->ble_connect &&
			((ti->previous_temp >= ti->temp_current && ti->previous_temp - ti->temp_current < 50) ||
			(ti->previous_temp < ti->temp_current && ti->temp_current - ti->previous_temp < 50))) {

			ti->same_temp_number++;
		} else {
			ti->same_temp_number = 0;
//			ti->previous_temp = ti->temp_current;
		}

		print(LOG_DBG, MODULE "auto power off: same_temp_number %d\n", ti->same_temp_number);

		if (ti->same_temp_number >= AUTO_POWER_OFF_NUMBER_THRESHOLD) {
			print(LOG_DBG, MODULE "auto power off\n");
			ther_system_power_off_pre(ti);
		} else {
			osal_start_timerEx( ti->task_id, TH_AUTO_POWER_OFF_EVT, AUTO_POWER_OFF_MEASURE_INTERVAL);
		}

		return (events ^ TH_AUTO_POWER_OFF_EVT);
	}

	/* batt measure */
	if (events & TH_BATT_EVT) {
		if (ti->mode == NORMAL_MODE) {
			Batt_MeasLevel();
			ti->batt_percentage = ther_batt_get_percentage(FALSE);
			oled_update_picture(OLED_CONTENT_BATT, TRUE, ti->batt_percentage);
			print(LOG_DBG, MODULE "batt %d%%\n", ti->batt_percentage);

			if (!ti->batt_warning_on && ti->batt_percentage < 10) {
				ti->batt_warning_on = TRUE;
				osal_start_timerEx( ti->task_id, TH_LOW_BATT_WARNING_EVT, LOW_BATT_WARNING_INTERVAL);
			}

			osal_start_timerEx( ti->task_id, TH_BATT_EVT, BATT_MEASURE_INTERVAL);
		}

		return (events ^ TH_BATT_EVT);
	}

	if (events & TH_LOW_BATT_BLINK_EVT) {
		if (ti->batt_in_dispaly) {
			oled_update_picture(OLED_CONTENT_BATT, FALSE, 0);
			ti->batt_in_dispaly = FALSE;
		} else {
			oled_update_picture(OLED_CONTENT_BATT, TRUE, ti->batt_percentage);
			ti->batt_in_dispaly = TRUE;
		}

		if (ti->display_picture != OLED_PICTURE_NONE)
			osal_start_timerEx(ti->task_id, TH_LOW_BATT_BLINK_EVT, LOW_BATT_BLINK_INTERVAL);

		return (events ^ TH_LOW_BATT_BLINK_EVT);
	}

	if (events & TH_LOW_BATT_WARNING_EVT) {
		ther_buzzer_start_music(BUZZER_MUSIC_LOW_BATT_WARNING);

		if (ti->batt_percentage < LOW_BATT_WARNING_THRESHOLD)
			osal_start_timerEx( ti->task_id, TH_LOW_BATT_WARNING_EVT, LOW_BATT_WARNING_INTERVAL);
		else
			ti->batt_warning_on = FALSE;

		return (events ^ TH_LOW_BATT_WARNING_EVT);
	}

	/* temp measure event */
	if (events & TH_TEMP_MEASURE_EVT) {

		if (ti->mode != NORMAL_MODE) {
			return (events ^ TH_TEMP_MEASURE_EVT);
		}

		switch (ti->temp_measure_stage) {
		case TEMP_STAGE_SETUP:
			ther_temp_power_on();

			osal_start_timerEx( ti->task_id, TH_TEMP_MEASURE_EVT, TEMP_POWER_SETUP_TIME);
			ti->temp_measure_stage = TEMP_STAGE_MEASURE;
			break;

		case TEMP_STAGE_MEASURE:

			ti->temp_last_saved = ti->temp_current;
			ti->temp_current = (int16)(ther_read_temp() * 100 + 0.5);
			ther_temp_power_off();

			/* for auto power off, save only once */
			if (ti->previous_temp == 0)
				ti->previous_temp = ti->temp_current;

			if (ti->temp_max < ti->temp_current) {
				ti->temp_max = ti->temp_current;
				print(LOG_DBG, MODULE "update max temp to %d\n", ti->temp_max);
				oled_update_picture(OLED_CONTENT_MAX_TEMP, TRUE, ti->temp_max);
			}

			/* high temp warning */
			if (ti->warning_enabled && !ti->temp_warning_on && ti->temp_current >= ti->next_warning_threshold) {
				ti->temp_warning_on = TRUE;
				osal_start_timerEx( ti->task_id, TH_HIGH_TEMP_WARNING_EVT, HIGH_TEMP_WARNING_INTERVAL);
			}
			if (ti->temp_warning_on && ti->temp_current < ti->next_warning_threshold) {
				ti->next_warning_threshold -= 50; /* 0.5 C */
				if (ti->next_warning_threshold < ti->high_temp_threshold)
					ti->next_warning_threshold = ti->high_temp_threshold;

				ti->temp_warning_on = FALSE;
				osal_stop_timerEx(ti->task_id, TH_HIGH_TEMP_WARNING_EVT);
			}

			if (ti->ble_connect) {
				if (ti->temp_notification_enable) {
//					ther_send_temp_notify(ti->temp_current);
				}
				if (ti->temp_indication_enable) {
					ther_send_temp_indicate(ti->task_id, ti->temp_current);
				}
			} else {
				ther_save_temp_to_local(ti->temp_current);
			}

			if (ti->temp_current != ti->temp_last_saved) {
				oled_update_picture(OLED_CONTENT_TEMP, TRUE, ti->temp_current);
			}

			osal_start_timerEx( ti->task_id, TH_TEMP_MEASURE_EVT, ti->temp_measure_interval);
			ti->temp_measure_stage = TEMP_STAGE_SETUP;
			break;

		default:
			break;
		}

		return (events ^ TH_TEMP_MEASURE_EVT);
	}

	if (events & TH_HIGH_TEMP_WARNING_EVT) {
		ther_buzzer_start_music(BUZZER_MUSIC_HIGH_TEMP_WARNING);
		osal_start_timerEx( ti->task_id, TH_HIGH_TEMP_WARNING_EVT, HIGH_TEMP_WARNING_INTERVAL);

		return (events ^ TH_HIGH_TEMP_WARNING_EVT);
	}

	if (events & TH_HIS_TEMP_RESTORE_EVT) {
		if (!ti->his_temp_bundle) {
			if (ti->temp_notification_enable) {
				storage_restore_temp((uint8 **)&ti->his_temp_bundle, &ti->his_temp_len);
				if (ti->his_temp_bundle) {
					ti->his_temp_offset = 0;
					osal_start_timerEx(ti->task_id, TH_HIS_TEMP_RESTORE_EVT, HIS_TEMP_UPLOADING_INTERVAL);
				} else {
					print(LOG_DBG, MODULE "his temp restore: no more his temp, exit\n");
					ti->his_temp_uploading = FALSE;
				}

			} else if (!ti->ble_connect) {
				print(LOG_DBG, MODULE "his temp restore: ble disconnect, exit\n");
				ti->his_temp_uploading = FALSE;

			} else {
//				print(LOG_DBG, MODULE "his temp restore: wait for notify enable\n");
				osal_start_timerEx(ti->task_id, TH_HIS_TEMP_RESTORE_EVT, HIS_TEMP_RESTORE_WAIT_ENABLE);
			}

		} else {
			if (ti->his_temp_offset < ti->his_temp_len) {
				uint8 *data = ti->his_temp_bundle + ti->his_temp_offset;

				ther_send_history_temp(ti->task_id, data, sizeof(struct temp_data));

				ti->his_temp_offset += sizeof(struct temp_data);
			} else {
				ti->his_temp_bundle = NULL;
				ti->his_temp_offset = 0;
				ti->his_temp_len = 0;
				print(LOG_DBG, MODULE "his temp restore: a bundle uploading completed\n");
			}
			osal_start_timerEx(ti->task_id, TH_HIS_TEMP_RESTORE_EVT, HIS_TEMP_UPLOADING_INTERVAL);
		}

		return (events ^ TH_HIS_TEMP_RESTORE_EVT);
	}

	/* Display event */
	if (events & TH_DISPLAY_EVT) {

		oled_display_state_machine();

		return (events ^ TH_DISPLAY_EVT);
	}

	/* buzzer event */
	if (events & TH_BUZZER_EVT) {
		ther_buzzer_playing_music();

		return (events ^ TH_BUZZER_EVT);
	}

	/* button event */
	if (events & TH_BUTTON_EVT) {
		ther_measure_button_time();

		return (events ^ TH_BUTTON_EVT);
	}

	if (events & TH_WATCHDOG_EVT) {
		feed_watchdog();
		osal_start_timerEx(ti->task_id, TH_WATCHDOG_EVT, WATCHDOG_FEED_INTERVAL);

		return (events ^ TH_WATCHDOG_EVT);
	}


	if (events & TH_TEST_EVT) {
		{
			struct display_param param;

			if (ti->display_picture > OLED_PICTURE_NONE) {
				print(LOG_DBG, MODULE "ignore button press when picture is %d\n", ti->display_picture);
				return (events ^ TH_TEST_EVT);
			}

			encap_picture_param(ti, &param);
			if (ti->display_picture == OLED_PICTURE_NONE) {
				oled_show_picture(OLED_PICTURE1, DISPLAY_TIME, &param);

			} else {
				oled_show_next_picture(DISPLAY_TIME, &param);
			}
		}
		osal_start_timerEx(ti->task_id, TH_TEST_EVT, SEC_TO_MS(10 * 60));

		return (events ^ TH_TEST_EVT);
	}

	return 0;
}
/*********************************************************************
 * @brief   Task Event Processor function.
 *
 * Internal function defined in peripheral.h.
 */
uint16 GAPRole_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( gapRole_TaskID )) != NULL )
    {
      gapRole_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 & GAP_EVENT_SIGN_COUNTER_CHANGED )
  {
    // Sign counter changed, save it to NV
    VOID osal_snv_write( BLE_NVID_SIGNCOUNTER, sizeof( uint32 ), &gapRole_signCounter );

    return ( events ^ GAP_EVENT_SIGN_COUNTER_CHANGED );
  }
  
  if ( events & START_ADVERTISING_EVT )
  {
    if ( gapRole_AdvEnabled )
    {
      gapAdvertisingParams_t params;

      // Setup advertisement parameters
      if ( gapRole_state == GAPROLE_CONNECTED )
      {
        // While in a connection, we can only advertise non-connectable undirected.
        params.eventType = GAP_ADTYPE_ADV_NONCONN_IND;
      }
      else
      {
        params.eventType = gapRole_AdvEventType;
        params.initiatorAddrType = gapRole_AdvDirectType;
        VOID osal_memcpy( params.initiatorAddr, gapRole_AdvDirectAddr, B_ADDR_LEN );
      }
      params.channelMap = gapRole_AdvChanMap;
      params.filterPolicy = gapRole_AdvFilterPolicy;

      if ( GAP_MakeDiscoverable( gapRole_TaskID, &params ) != SUCCESS )
      {
        gapRole_state = GAPROLE_ERROR;
        if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange )
        {
          pGapRoles_AppCGs->pfnStateChange( gapRole_state );
        }
      }
    }
    return ( events ^ START_ADVERTISING_EVT );
  }

  if ( events & RSSI_READ_EVT )
  {
    // Only get RSSI when in a connection
    if ( (gapRole_state == GAPROLE_CONNECTED)
        || (gapRole_state == GAPROLE_CONNECTED_ADV) )
    {
      // Ask for RSSI
      VOID HCI_ReadRssiCmd( gapRole_ConnectionHandle );

      // Setup next event
      if ( gapRole_RSSIReadRate )
      {
        VOID osal_start_timerEx( gapRole_TaskID, RSSI_READ_EVT, gapRole_RSSIReadRate );
      }
    }
    return ( events ^ RSSI_READ_EVT );
  }

  if ( events & UPDATE_PARAMS_TIMEOUT_EVT )
  {
    // Clear an existing timeout
    if ( osal_get_timeoutEx( gapRole_TaskID, UPDATE_PARAMS_TIMEOUT_EVT ) )
    {
      VOID osal_stop_timerEx( gapRole_TaskID, UPDATE_PARAMS_TIMEOUT_EVT );
    }

    // The Update Parameters Timeout occurred - Terminate connection
    VOID GAP_TerminateLinkReq( gapRole_TaskID, gapRole_ConnectionHandle, 
                               HCI_DISCONNECT_REMOTE_USER_TERM );

    return ( events ^ UPDATE_PARAMS_TIMEOUT_EVT );
  }

  // Discard unknown events
  return 0;
}
Example #28
0
/*********************************************************************
 * @brief   Set a GAP Role parameter.
 *
 * Public function defined in peripheral.h.
 */
bStatus_t GAPRole_SetParameter( uint16 param, uint8 len, void *pValue )
{
  bStatus_t ret = SUCCESS;
  switch ( param )
  {
    case GAPROLE_IRK:
      if ( len == KEYLEN )
      {
        VOID osal_memcpy( gapRole_IRK, pValue, KEYLEN ) ;
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case GAPROLE_SRK:
      if ( len == KEYLEN )
      {
        VOID osal_memcpy( gapRole_SRK, pValue, KEYLEN ) ;
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case GAPROLE_SIGNCOUNTER:
      if ( len == sizeof ( uint32 ) )
      {
        gapRole_signCounter = *((uint32*)pValue);
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case GAPROLE_ADVERT_ENABLED:
      if ( len == sizeof( uint8 ) )
      {
        uint8 oldAdvEnabled = gapRole_AdvEnabled;
        gapRole_AdvEnabled = *((uint8*)pValue);

        if ( (oldAdvEnabled) && (gapRole_AdvEnabled == FALSE) )
        {
          // Turn off Advertising
          if ( gapRole_state == GAPROLE_ADVERTISING )
          {
            VOID GAP_EndDiscoverable( gapRole_TaskID );
          }
        }
        else if ( (oldAdvEnabled == FALSE) && (gapRole_AdvEnabled) )
        {
          // Turn on Advertising
          if ( (gapRole_state == GAPROLE_STARTED)
              || (gapRole_state == GAPROLE_WAITING)
              || (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT) )
          {
            VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
          }
        }
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case GAPROLE_ADVERT_OFF_TIME:
      if ( len == sizeof ( uint16 ) )
      {
        gapRole_AdvertOffTime = *((uint16*)pValue);
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case GAPROLE_ADVERT_DATA:
      if ( len <= B_MAX_ADV_LEN )
      {
        VOID osal_memset( gapRole_AdvertData, 0, B_MAX_ADV_LEN );
        VOID osal_memcpy( gapRole_AdvertData, pValue, len );
        gapRole_AdvertDataLen = len;
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case GAPROLE_SCAN_RSP_DATA:
      if ( len <= B_MAX_ADV_LEN )
      {
        VOID osal_memset( gapRole_ScanRspData, 0, B_MAX_ADV_LEN );
        VOID osal_memcpy( gapRole_ScanRspData, pValue, len );
        gapRole_ScanRspDataLen = len;
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case GAPROLE_ADV_EVENT_TYPE:
      if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= GAP_ADTYPE_ADV_NONCONN_IND) )
      {
        gapRole_AdvEventType = *((uint8*)pValue);
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case GAPROLE_ADV_DIRECT_TYPE:
      if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= ADDRTYPE_PRIVATE_RESOLVE) )
      {
        gapRole_AdvDirectType = *((uint8*)pValue);
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case GAPROLE_ADV_DIRECT_ADDR:
      if ( len == B_ADDR_LEN )
      {
        VOID osal_memcpy( gapRole_AdvDirectAddr, pValue, B_ADDR_LEN ) ;
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case GAPROLE_ADV_CHANNEL_MAP:
      if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= 0x07) )
      {
        gapRole_AdvChanMap = *((uint8*)pValue);
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case GAPROLE_ADV_FILTER_POLICY:
      if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= GAP_FILTER_POLICY_WHITE) )
      {
        gapRole_AdvFilterPolicy = *((uint8*)pValue);
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case GAPROLE_RSSI_READ_RATE:
      if ( len == sizeof ( uint16 ) )
      {
        gapRole_RSSIReadRate = *((uint16*)pValue);

        if ( (gapRole_RSSIReadRate) && (gapRole_state == GAPROLE_CONNECTED) )
        {
          // Start the RSSI Reads
          VOID osal_start_timerEx( gapRole_TaskID, RSSI_READ_EVT, gapRole_RSSIReadRate );
        }
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case GAPROLE_PARAM_UPDATE_ENABLE:
      if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= TRUE) )
      {
        gapRole_ParamUpdateEnable = *((uint8*)pValue);
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case GAPROLE_MIN_CONN_INTERVAL:
      {
        uint16 newInterval = *((uint16*)pValue);
        if (   len == sizeof ( uint16 )           &&
             ( newInterval >= MIN_CONN_INTERVAL ) &&
             ( newInterval <= MAX_CONN_INTERVAL ) )
        {
          gapRole_MinConnInterval = newInterval;
        }
        else
        {
          ret = bleInvalidRange;
        }
      }
      break;

    case GAPROLE_MAX_CONN_INTERVAL:
      {
        uint16 newInterval = *((uint16*)pValue);
        if (   len == sizeof ( uint16 )          &&
             ( newInterval >= MIN_CONN_INTERVAL) &&
             ( newInterval <= MAX_CONN_INTERVAL) )
        {
          gapRole_MaxConnInterval = newInterval;
        }
        else
        {
          ret = bleInvalidRange;
        }
      }
      break;

    case GAPROLE_SLAVE_LATENCY:
      {
        uint16 latency = *((uint16*)pValue);
        if ( len == sizeof ( uint16 ) && (latency < MAX_SLAVE_LATENCY) )
        {
          gapRole_SlaveLatency = latency;
        }
        else
        {
          ret = bleInvalidRange;
        }
      }
      break;

    case GAPROLE_TIMEOUT_MULTIPLIER:
      {
        uint16 newTimeout = *((uint16*)pValue);
        if ( len == sizeof ( uint16 )
            && (newTimeout >= MIN_TIMEOUT_MULTIPLIER) && (newTimeout <= MAX_TIMEOUT_MULTIPLIER) )
        {
          gapRole_TimeoutMultiplier = newTimeout;
        }
        else
        {
          ret = bleInvalidRange;
        }
      }
      break;

      case GAPROLE_PARAM_UPDATE_REQ:
        {
          uint8 req = *((uint8*)pValue);
          if ( len == sizeof ( uint8 ) && (req == TRUE) )
          {
            // Make sure we don't send an L2CAP Connection Parameter Update Request
            // command within TGAP(conn_param_timeout) of an L2CAP Connection Parameter
            // Update Response being received.
            if ( osal_get_timeoutEx( gapRole_TaskID, CONN_PARAM_TIMEOUT_EVT ) == 0 )
            {             
              // Start connection update procedure
              gapRole_startConnUpdate( GAPROLE_NO_ACTION );
              
              // Connection update requested by app, cancel such pending procedure (if active)
              VOID osal_stop_timerEx( gapRole_TaskID, START_CONN_UPDATE_EVT );
            }
            else
            {
              ret = blePending;
            }
          }
          else
          {
            ret = bleInvalidRange;
          }
        }
        break;
  
    default:
      // The param value isn't part of this profile, try the GAP.
      if ( (param < TGAP_PARAMID_MAX) && (len == sizeof ( uint16 )) )
      {
        ret = GAP_SetParamValue( param, *((uint16*)pValue) );
      }
      else
      {
        ret = INVALIDPARAMETER;
      }
      break;
  }

  return ( ret );
}
Example #29
0
/**************************************************************************************************
 * @fn      HalKeyConfig
 *
 * @brief   Configure the Key serivce
 *
 * @param   interruptEnable - TRUE/FALSE, enable/disable interrupt
 *          cback - pointer to the CallBack function
 *
 * @return  None
 **************************************************************************************************/
void HalKeyConfig (bool interruptEnable, halKeyCBack_t cback)
{
  /* Enable/Disable Interrupt or */
  Hal_KeyIntEnable = interruptEnable;

  /* Register the callback fucntion */
  pHalKeyProcessFunction = cback;

  /* Determine if interrupt is enable or not */
  if (Hal_KeyIntEnable)
  {
#if defined ( CC2540_MINIDK )|| (JANSION_KEY)
    /* Rising/Falling edge configuratinn */
    PICTL |= HAL_KEY_SW_1_EDGEBIT;   /* Set the edge bit to set falling edge to give int */

    HAL_KEY_SW_1_ICTL |= HAL_KEY_SW_1_ICTLBIT; /* enable interrupt generation at port */
    HAL_KEY_SW_1_IEN |= HAL_KEY_SW_1_IENBIT;   /* enable CPU interrupt */
    HAL_KEY_SW_1_PXIFG = ~(HAL_KEY_SW_1_BIT); /* Clear any pending interrupt */
    HAL_KEY_SW_2_ICTL |= HAL_KEY_SW_2_ICTLBIT; /* enable interrupt generation at port */
    HAL_KEY_SW_2_IEN |= HAL_KEY_SW_2_IENBIT;   /* enable CPU interrupt */
    HAL_KEY_SW_2_PXIFG = ~(HAL_KEY_SW_2_BIT); /* Clear any pending interrupt */

#else
    /* Rising/Falling edge configuratinn */
    PICTL &= ~(HAL_KEY_SW_6_EDGEBIT);    /* Clear the edge bit */
    /* For falling edge, the bit must be set. */
  #if (HAL_KEY_SW_6_EDGE == HAL_KEY_FALLING_EDGE)
    PICTL |= HAL_KEY_SW_6_EDGEBIT;
  #endif


    /* Interrupt configuration:
     * - Enable interrupt generation at the port
     * - Enable CPU interrupt
     * - Clear any pending interrupt
     */
    HAL_KEY_SW_6_ICTL |= HAL_KEY_SW_6_ICTLBIT;
    HAL_KEY_SW_6_IEN |= HAL_KEY_SW_6_IENBIT;
    HAL_KEY_SW_6_PXIFG = ~(HAL_KEY_SW_6_BIT);



    /* Rising/Falling edge configuratinn */

    HAL_KEY_JOY_MOVE_ICTL &= ~(HAL_KEY_JOY_MOVE_EDGEBIT);    /* Clear the edge bit */
    /* For falling edge, the bit must be set. */
  #if (HAL_KEY_JOY_MOVE_EDGE == HAL_KEY_FALLING_EDGE)
    HAL_KEY_JOY_MOVE_ICTL |= HAL_KEY_JOY_MOVE_EDGEBIT;
  #endif


    /* Interrupt configuration:
     * - Enable interrupt generation at the port
     * - Enable CPU interrupt
     * - Clear any pending interrupt
     */
    HAL_KEY_JOY_MOVE_ICTL |= HAL_KEY_JOY_MOVE_ICTLBIT;
    HAL_KEY_JOY_MOVE_IEN |= HAL_KEY_JOY_MOVE_IENBIT;
    HAL_KEY_JOY_MOVE_PXIFG = ~(HAL_KEY_JOY_MOVE_BIT);
#endif // !CC2540_MINIDK

    /* Do this only after the hal_key is configured - to work with sleep stuff */
    if (HalKeyConfigured == TRUE)
    {
      osal_stop_timerEx(Hal_TaskID, HAL_KEY_EVENT);  /* Cancel polling if active */
    }
  }
  else    /* Interrupts NOT enabled */
  {
#if defined ( CC2540_MINIDK )|| (JANSION_KEY)
    HAL_KEY_SW_1_ICTL &= ~(HAL_KEY_SW_1_ICTLBIT); /* don't generate interrupt */
    HAL_KEY_SW_1_IEN &= ~(HAL_KEY_SW_1_IENBIT);   /* Clear interrupt enable bit */
    HAL_KEY_SW_2_ICTL &= ~(HAL_KEY_SW_2_ICTLBIT); /* don't generate interrupt */
    HAL_KEY_SW_2_IEN &= ~(HAL_KEY_SW_2_IENBIT);   /* Clear interrupt enable bit */
#else
    HAL_KEY_SW_6_ICTL &= ~(HAL_KEY_SW_6_ICTLBIT); /* don't generate interrupt */
    HAL_KEY_SW_6_IEN &= ~(HAL_KEY_SW_6_IENBIT);   /* Clear interrupt enable bit */
#endif  // !CC2540_MINIDK

    osal_set_event(Hal_TaskID, HAL_KEY_EVENT);
  }

  /* Key now is configured */
  HalKeyConfigured = TRUE;
}
Example #30
0
/*********************************************************************
 * @fn      gapRole_ProcessOSALMsg
 *
 * @brief   Process an incoming task message.
 *
 * @param   pMsg - message to process
 *
 * @return  none
 */
static void gapRole_ProcessOSALMsg( osal_event_hdr_t *pMsg )
{
  switch ( pMsg->event )
  {
    case HCI_GAP_EVENT_EVENT:
      if ( pMsg->status == HCI_COMMAND_COMPLETE_EVENT_CODE )
      {
        hciEvt_CmdComplete_t *pPkt = (hciEvt_CmdComplete_t *)pMsg;

        if ( pPkt->cmdOpcode == HCI_READ_RSSI )
        {
          int8 rssi = (int8)pPkt->pReturnParam[3];

          if ( (gapRole_state == GAPROLE_CONNECTED) && (rssi != RSSI_NOT_AVAILABLE) )
          {
            // Report RSSI to app
            if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnRssiRead )
            {
              pGapRoles_AppCGs->pfnRssiRead( rssi );
            }
          }
        }
      }
      break;

    case GAP_MSG_EVENT:
      gapRole_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
      break;

    case L2CAP_SIGNAL_EVENT:
      {
        l2capSignalEvent_t *pPkt = (l2capSignalEvent_t *)pMsg;

        // Process the Parameter Update Response
        if ( pPkt->opcode == L2CAP_PARAM_UPDATE_RSP )
        {
          l2capParamUpdateRsp_t *pRsp = (l2capParamUpdateRsp_t *)&(pPkt->cmd.updateRsp);
                  
          if ( ( pRsp->result == L2CAP_CONN_PARAMS_REJECTED ) &&
               ( paramUpdateNoSuccessOption == GAPROLE_TERMINATE_LINK ) )
          {
            // Cancel connection param update timeout timer
            VOID osal_stop_timerEx( gapRole_TaskID, CONN_PARAM_TIMEOUT_EVT );
                      
            // Terminate connection immediately
            GAPRole_TerminateConnection();
          }
          else
          {
            uint16 timeout = GAP_GetParamValue( TGAP_CONN_PARAM_TIMEOUT );
            
            // Let's wait for Controller to update connection parameters if they're
            // accepted. Otherwise, decide what to do based on no success option.
            VOID osal_start_timerEx( gapRole_TaskID, CONN_PARAM_TIMEOUT_EVT, timeout );
          }
        }
      }
      break;

    default:
      break;
  }
}