/******************************************************************************
 * @fn          zb_StartRequest
 *
 * @brief       The zb_StartRequest function starts the ZigBee stack.  When the
 *              ZigBee stack starts, the device reads configuration parameters
 *              from Nonvolatile memory and the device joins its network.  The
 *              ZigBee stack calls the zb_StartConrifm callback function when
 *              the startup process completes.
 *
 * @param       none
 *
 * @return      none
 */
void zb_StartRequest()
{
  uint8 logicalType;

  zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType );

  // Check for bad combinations of compile flag definitions and device type setting.
  if ((logicalType > ZG_DEVICETYPE_ENDDEVICE)      ||
#if !ZG_BUILD_ENDDEVICE_TYPE   // Only RTR or Coord possible.
      (logicalType == ZG_DEVICETYPE_ENDDEVICE)     ||
#endif
#if !ZG_BUILD_RTR_TYPE         // Only End Device possible.
      (logicalType == ZG_DEVICETYPE_ROUTER)        ||
      (logicalType == ZG_DEVICETYPE_COORDINATOR)   ||
#elif ZG_BUILD_RTRONLY_TYPE    // Only RTR possible.
      (logicalType == ZG_DEVICETYPE_COORDINATOR)   ||
#elif !ZG_BUILD_JOINING_TYPE   // Only Coord possible.
      (logicalType == ZG_DEVICETYPE_ROUTER)        ||
#endif
      (0))
  {
    logicalType = ZB_INVALID_PARAMETER;
    SAPI_SendCback(SAPICB_START_CNF, logicalType, 0);
  }
  else
  {
    logicalType = ZB_SUCCESS;
    ZDOInitDevice(zgStartDelay);
  }

  
  return;
}
Beispiel #2
0
/******************************************************************************
 * @fn          zb_HandleOsalEvent
 *
 * @brief       The zb_HandleOsalEvent function is called by the operating
 *              system when a task event is set
 *
 * @param       event - Bitmask containing the events that have been set
 *
 * @return      none
 */
void zb_HandleOsalEvent( uint16 event )
{
  uint8 logicalType;
  
  if(event & SYS_EVENT_MSG)
  {
    
  }
  
  if( event & ZB_ENTRY_EVENT )
  {  
    // Initialise UART
    initUart(uartRxCB);
    
    // blind LED 1 to indicate starting/joining a network
#ifndef SYS_DEBUG_SH
    HalLedBlink ( HAL_LED_1, 0, 50, 500 );
#endif
    HalLedSet( HAL_LED_2, HAL_LED_MODE_OFF );
    
    // Read logical device type from NV
    zb_ReadConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType);
   
    // Start the device 
    zb_StartRequest();
#ifdef SYS_DEBUG_SH
    // Turn ON Allow Bind mode infinitly
    zb_AllowBind( 0xFF );
    HalLedSet( HAL_LED_2, HAL_LED_MODE_ON );
#endif
  }
  
  if ( event & MY_START_EVT )
  {
    zb_StartRequest();
  }
  
  if ( event & MY_REPORT_EVT )
  {
    if (isGateWay) 
    {
      osal_start_timerEx( sapi_TaskID, MY_REPORT_EVT, myReportPeriod );
    }
    else if (appState == APP_BINDED) 
    {
      sendDummyReport();
      osal_start_timerEx( sapi_TaskID, MY_REPORT_EVT, myReportPeriod );
    }
  }
  if ( event & MY_FIND_COLLECTOR_EVT )
  { 
    // Find and bind to a gateway device (if this node is not gateway)
    if (!isGateWay) 
    {
      zb_BindDevice( TRUE, DUMMY_REPORT_CMD_ID, (uint8 *)NULL );
    }
  }
  
}
/**
 * @brief   Esta función es llamada por el SO cuando se debe atender un
 *          evento de la tarea.
 * @param   event   Mascara de bits conteniendo los eventos a atender
 */
void zb_HandleOsalEvent(uint16 event)
{
    uint8 logicalType;
    
    if (event & SYS_EVENT_MSG)
    {      
    }
    if (event & ZB_ENTRY_EVENT)
    {  
        // inicializa UART
        initUart(uartRxCB);
        // blick LED 1 para indicar que se está uniendo a la red
        HalLedBlink(HAL_LED_1, 0, 50, 500 );
        HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF);   
        // lee tipo de logical device desde la memoria NV
        zb_ReadConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType);
        // inicia la red
        zb_StartRequest();
    }
    if (event & MY_START_EVT)
    {
        // inicia la red
        zb_StartRequest();
    }
    if (event & SEND_UART_MSG)
    {
        // envia mensaje por UART a la PC
        //HalLcdWriteString("UART_EVT", HAL_LCD_LINE_1);
        sendUartMessage(&msgReport, &alarmFlags);
    }
    if (event & MY_TEST_EVT)
    {
        // crea mensaje de prueba
        msgReport.msgType = MSG_TYPE_REPORT;
        msgReport.sequence++;
        msgReport.lenData = MSG_LEN_DATA_REPORT;
        for (uint8 i = 0; i < 8; i++)
            msgReport.mac[i] = i;
        // datos de prueba
        static double d[10] = {220.5, 0.354, 85.12, 88.33, 85.06, 0.98, 1.23, 3.25, 0.97, 4.55};
        for (int i = 0; i < 10; i++)
            memcpy(&(msgReport.data[i*4]), &(d[i]), sizeof(double));
        // flags de prueba
        uint16 flags = 0;
        // imprime info en LCD
        HalLcdWriteString("TEST_EVT", HAL_LCD_LINE_1);
        HalLcdWriteStringValue("#", msgReport.sequence, 10, HAL_LCD_LINE_2);
        // envia mensaje por UART
        sendUartMessage(&msgReport, &flags);
        // crea evento nuevamente
        osal_start_timerEx(sapi_TaskID, MY_TEST_EVT, 5000);
    }
}
Beispiel #4
0
/***************************************************************************************************
 * @fn          MT_SapiReadCfg
 *
 * @brief       Process SAPI Read Config Commands
 *
 * @param       pBuf - pointer to received buffer
 *
 * @return      none
 ***************************************************************************************************/
void MT_SapiReadCfg(uint8 *pBuf)
{
  uint8 len, retStatus;
  uint8 cfgId, cmdId;
  uint8 *pRetBuf;

  /* Parse header */
  cmdId = pBuf[MT_RPC_POS_CMD1];
  cfgId = pBuf[MT_RPC_POS_DAT0];

  /* Length of item in NV memory */
  len = (uint8)osal_nv_item_len(cfgId);

  pRetBuf = osal_mem_alloc(len+3);
  if (pRetBuf != NULL)
  {
    if (len && ((cfgId != ZCD_NV_NIB) && (cfgId != ZCD_NV_DEVICE_LIST) &&
                (cfgId != ZCD_NV_ADDRMGR) && (cfgId != ZCD_NV_NWKKEY)))
    {
      if ((zb_ReadConfiguration(cfgId, len, pRetBuf+3)) == ZSUCCESS)
      {
        retStatus = ZSuccess;
      }
      else
      {
        retStatus = ZFailure;
      }
    }
    else
    {
      retStatus = ZInvalidParameter;
    }

    if (retStatus != ZSuccess)
    {
       /* Don't return garbage with error */
       len = 0;
    }

    /* Status */
    pRetBuf[0] = retStatus;
    /* Config ID */
    pRetBuf[1] = cfgId;
    /* NV item length */
    pRetBuf[2] = len;

    /* Build and send back the response */
    MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SAPI), cmdId, len+3, pRetBuf );

    osal_mem_free(pRetBuf);
  }
}
Beispiel #5
0
/******************************************************************************
 * @fn          zb_StartRequest
 *
 * @brief       The zb_StartRequest function starts the ZigBee stack.  When the
 *              ZigBee stack starts, the device reads configuration parameters
 *              from Nonvolatile memory and the device joins its network.  The
 *              ZigBee stack calls the zb_StartConrifm callback function when
 *              the startup process completes.
 *
 * @param       none
 *
 * @return      none
 */
void zb_StartRequest()
{
  uint8 logicalType;

  // Start the device
  // start delay = min(NWK_START_DELAY, zgStartDelay) + rand() - only for fresh start, not restore
  if ( zgStartDelay < NWK_START_DELAY )
    zgStartDelay = 0;
  else
    zgStartDelay -= NWK_START_DELAY;

  // check that bad combinations of compile flag definitions and device type
  zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType );
   if (  ( logicalType > ZG_DEVICETYPE_ENDDEVICE )        ||
#if defined( RTR_NWK )
  #if defined( ZDO_COORDINATOR )
          // Only RTR or Coord possible
         ( logicalType == ZG_DEVICETYPE_ENDDEVICE )   ||
  #else
          // Only RTR possible
          ( logicalType != ZG_DEVICETYPE_ROUTER )     ||
  #endif
#else
  #if defined( ZDO_COORDINATOR )
          // Error
          ( 1 )                                     ||
  #else
          // only ED possible
          ( logicalType != ZG_DEVICETYPE_ENDDEVICE )  ||
  #endif
#endif
          ( 0 ) )
   {
     // error configuration
     SAPI_SendCback( SAPICB_START_CNF, ZInvalidParameter, 0 );
   }
   else
   {
     ZDOInitDevice(zgStartDelay);
   }

  return;
}
/*********************************************************************
 * @fn      SAPI_ProcessEvent
 *
 * @brief   Simple API 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  none
 */
UINT16 SAPI_ProcessEvent( byte task_id, UINT16 events )
{
  osal_event_hdr_t *pMsg;
  afIncomingMSGPacket_t *pMSGpkt;
  afDataConfirm_t *pDataConfirm;

  if ( events & SYS_EVENT_MSG )
  {
    pMsg = (osal_event_hdr_t *) osal_msg_receive( task_id );
    while ( pMsg )
    {
      switch ( pMsg->event )
      {
        case ZDO_CB_MSG:
          SAPI_ProcessZDOMsgs( (zdoIncomingMsg_t *)pMsg );
          break;

        case AF_DATA_CONFIRM_CMD:
          // This message is received as a confirmation of a data packet sent.
          // The status is of ZStatus_t type [defined in ZComDef.h]
          // The message fields are defined in AF.h
          pDataConfirm = (afDataConfirm_t *) pMsg;
          SAPI_SendDataConfirm( pDataConfirm->transID, pDataConfirm->hdr.status );
          break;

        case AF_INCOMING_MSG_CMD:
          pMSGpkt = (afIncomingMSGPacket_t *) pMsg;
          SAPI_ReceiveDataIndication( pMSGpkt->srcAddr.addr.shortAddr, pMSGpkt->clusterId,
                                    pMSGpkt->cmd.DataLength, pMSGpkt->cmd.Data);
          break;

        case ZDO_STATE_CHANGE:
          // If the device has started up, notify the application
          if (pMsg->status == DEV_END_DEVICE ||
              pMsg->status == DEV_ROUTER ||
              pMsg->status == DEV_ZB_COORD )
          {
            SAPI_StartConfirm( ZB_SUCCESS );
          }
          else  if (pMsg->status == DEV_HOLD ||
                  pMsg->status == DEV_INIT)
          {
            SAPI_StartConfirm( ZB_INIT );
          }
          break;

        case ZDO_MATCH_DESC_RSP_SENT:
          SAPI_AllowBindConfirm( ((ZDO_MatchDescRspSent_t *)pMsg)->nwkAddr );
          break;

        case KEY_CHANGE:
#if ( SAPI_CB_FUNC )
          zb_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys );
#endif
          break;

        case SAPICB_DATA_CNF:
          SAPI_SendDataConfirm( (uint8)((sapi_CbackEvent_t *)pMsg)->data,
                                    ((sapi_CbackEvent_t *)pMsg)->hdr.status );
          break;

        case SAPICB_BIND_CNF:
          SAPI_BindConfirm( ((sapi_CbackEvent_t *)pMsg)->data,
                              ((sapi_CbackEvent_t *)pMsg)->hdr.status );
          break;

        case SAPICB_START_CNF:
          SAPI_StartConfirm( ((sapi_CbackEvent_t *)pMsg)->hdr.status );
          break;

        default:
          // User messages should be handled by user or passed to the application
          if ( pMsg->event >= ZB_USER_MSG )
          {

          }
          break;
      }

      // Release the memory
      osal_msg_deallocate( (uint8 *) pMsg );

      // Next
      pMsg = (osal_event_hdr_t *) osal_msg_receive( task_id );
    }

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

  if ( events & ZB_ALLOW_BIND_TIMER )
  {
    afSetMatch(sapi_epDesc.simpleDesc->EndPoint, FALSE);
    return (events ^ ZB_ALLOW_BIND_TIMER);
  }

  if ( events & ZB_BIND_TIMER )
  {
    // Send bind confirm callback to application
    SAPI_BindConfirm( sapi_bindInProgress, ZB_TIMEOUT );
    sapi_bindInProgress = 0xffff;

    return (events ^ ZB_BIND_TIMER);
  }

  if ( events & ZB_ENTRY_EVENT )
  {
    uint8 startOptions;

    // Give indication to application of device startup
#if ( SAPI_CB_FUNC )
    zb_HandleOsalEvent( ZB_ENTRY_EVENT );
#endif

    // LED off cancels HOLD_AUTO_START blink set in the stack
    HalLedSet (HAL_LED_4, HAL_LED_MODE_OFF);

    zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
    if ( startOptions & ZCD_STARTOPT_AUTO_START )
    {
      zb_StartRequest();
    }
    else
    {
      // blink leds and wait for external input to config and restart
      HalLedBlink(HAL_LED_2, 0, 50, 500);
    }

    return (events ^ ZB_ENTRY_EVENT );
  }

  // This must be the last event to be processed
  if ( events & ( ZB_USER_EVENTS ) )
  {
    // User events are passed to the application
#if ( SAPI_CB_FUNC )
    zb_HandleOsalEvent( events );
#endif

    // Do not return here, return 0 later
  }

  // Discard unknown events
  return 0;
}
/*********************************************************************
 * @fn      zb_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:
 *                 EVAL_SW4
 *                 EVAL_SW3
 *                 EVAL_SW2
 *                 EVAL_SW1
 *
 * @return  none
 */
void zb_HandleKeys( uint8 shift, uint8 keys )
{
  uint8 startOptions;
  uint8 logicalType;

  // Shift is used to make each button/switch dual purpose.
  if ( shift )
  {
    if ( keys & HAL_KEY_SW_1 )
    {
    }
    if ( keys & HAL_KEY_SW_2 )
    {
    }
    if ( keys & HAL_KEY_SW_3 )
    {
    }
    if ( keys & HAL_KEY_SW_4 )
    {
    }
  }
  else
  {
    if ( keys & HAL_KEY_SW_1 )
    {
      if ( myAppState == APP_INIT  )
      {
        // In the init state, keys are used to indicate the logical mode.
        // Key 1 starts device as a coordinator

        zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType );
        if ( logicalType != ZG_DEVICETYPE_ENDDEVICE )
        {
          logicalType = ZG_DEVICETYPE_COORDINATOR;
          zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType);
        }

        // Do more configuration if necessary and then restart device with auto-start bit set
        // write endpoint to simple desc...dont pass it in start req..then reset


        zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
        startOptions = ZCD_STARTOPT_AUTO_START;
        zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
        zb_SystemReset();

      }
      else
      {
        // Turn ON Allow Bind mode indefinitely
        zb_AllowBind( 0xFF );
        HalLedSet( HAL_LED_1, HAL_LED_MODE_ON );
      }
    }
    if ( keys & HAL_KEY_SW_2 )
    {
      if ( myAppState == APP_INIT )
      {
        // In the init state, keys are used to indicate the logical mode.
        // Key 2 starts device as a router

        zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType );
        if ( logicalType != ZG_DEVICETYPE_ENDDEVICE )
        {
          logicalType = ZG_DEVICETYPE_ROUTER;
          zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType);
        }

        zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
        startOptions = ZCD_STARTOPT_AUTO_START;
        zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
        zb_SystemReset();
      }
      else
      {
        // Turn OFF Allow Bind mode indefinitely
        zb_AllowBind( 0x00 );
        HalLedSet( HAL_LED_1, HAL_LED_MODE_OFF );
      }
    }
    if ( keys & HAL_KEY_SW_3 )
    {
    }
    if ( keys & HAL_KEY_SW_4 )
    {
    }
  }
}