예제 #1
0
/***************************************************************************************************
 * @fn          MT_SapiSendData
 *
 * @brief       Process SAPI Send Data Command
 *
 * @param       pBuf - pointer to received buffer
 *
 * @return      none
 ***************************************************************************************************/
void MT_SapiSendData(uint8 *pBuf)
{
  uint8 cmdId;
  uint16 destination, command;
  uint8 len, handle, txOption, radius;

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

  /* Destination */
  destination = BUILD_UINT16(pBuf[0], pBuf[1]);
  /* Command */
  command = BUILD_UINT16(pBuf[2], pBuf[3]);
  /* Handle */
  handle = pBuf[4];
  /* txOption */
  txOption = pBuf[5];
  /* Radius */
  radius = pBuf[6];
  /* Length */
  len = pBuf[7];

  zb_SendDataRequest(destination, command, len, &pBuf[8], handle, txOption, radius);

  /* Build and send back the response */
  MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SAPI), cmdId, 0, NULL);
}
예제 #2
0
/******************************************************************************
 * @fn          sendReport
 *
 * @brief       Send sensor report
 *
 * @param       none
 *              
 * @return      none
 */
static void sendReport(void)
{
  uint8 pData[SENSOR_REPORT_LENGTH];
  static uint8 reportNr=0;
  uint8 txOptions;
  
  // Read and report temperature value
  pData[SENSOR_TEMP_OFFSET] =  readTemp();
  
  // Read and report voltage value
  pData[SENSOR_VOLTAGE_OFFSET] = readVoltage(); 
    
  pData[SENSOR_PARENT_OFFSET] =  HI_UINT16(parentShortAddr);
  pData[SENSOR_PARENT_OFFSET + 1] =  LO_UINT16(parentShortAddr);
  
  // Set ACK request on each ACK_INTERVAL report
  // If a report failed, set ACK request on next report
  if ( ++reportNr<ACK_REQ_INTERVAL && reportFailureNr==0 ) 
  {
    txOptions = AF_TX_OPTIONS_NONE;
  }
  else 
  {
    txOptions = AF_MSG_ACK_REQUEST;
    reportNr = 0;
  }
  // Destination address 0xFFFE: Destination address is sent to previously
  // established binding for the commandId.
  zb_SendDataRequest( 0xFFFE, SENSOR_REPORT_CMD_ID, SENSOR_REPORT_LENGTH, pData, 0, txOptions, 0 );
}
예제 #3
0
파일: DemoSensor.c 프로젝트: hylcos/WTSN
/******************************************************************************
 * @fn          sendReport
 *
 * @brief       Send sensor report
 *
 * @param       none
 *
 * @return      none
 */
static void sendReport(void)
{
  uint8 pData[SENSOR_REPORT_LENGTH];
  static uint8 reportNr = 0;
  uint8 txOptions;

  // Read and report temperature value
  pData[SENSOR_TEMP_OFFSET] = readTemp();

  // Read and report voltage value
  pData[SENSOR_VOLTAGE_OFFSET] = readVoltage();

  pData[SENSOR_PARENT_OFFSET] =  HI_UINT16(parentShortAddr);
  pData[SENSOR_PARENT_OFFSET + 1] =  LO_UINT16(parentShortAddr);
  pData[BUTTON_PARENT_OFFSET+1] = MCU_IO_GET(0,1);
 // HalUARTWrite(HAL_UART_PORT_0,pData,SENSOR_REPORT_LENGTH);
 // HalUARTWrite(HAL_UART_PORT_1,pData,SENSOR_REPORT_LENGTH);
  int test = MCU_IO_GET(0,1);
  if( MCU_IO_GET(0,1) > 0){
    MCU_IO_SET_LOW(0, 0);
  } else {
    MCU_IO_SET_HIGH(0, 0);
  }
  MCU_IO_SET_LOW(0, 1);
  // Set ACK request on each ACK_INTERVAL report
  // If a report failed, set ACK request on next report
  if ( ++reportNr<ACK_REQ_INTERVAL && reportFailureNr == 0 )
  {
    txOptions = AF_TX_OPTIONS_NONE;
  }
  else
  {
    txOptions = AF_MSG_ACK_REQUEST;
    reportNr = 0;
  }
  // Destination address 0xFFFE: Destination address is sent to previously
  // established binding for the commandId.
  //printf("%i %i",pData[SENSOR_TEMP_OFFSET],oldValue);
  if(timeDone >= 60000){
     timeDone += 1;
  }
  if(pData[SENSOR_TEMP_OFFSET] != oldValue && timeDone >= 60000){
    oldValue = pData[SENSOR_TEMP_OFFSET];
    zb_SendDataRequest( 0xFFFE, SENSOR_REPORT_CMD_ID, SENSOR_REPORT_LENGTH, pData, 0, txOptions, 0 );
    timeDone = 0;
  } else {
    timeDone += myReportPeriod;
  }
}
예제 #4
0
/******************************************************************************
 * @fn          sendCommand
 *
 * @brief       Sends a command message via Zigbee
 *
 * @param       command - uint8 containing the command bit
 *
 * @return      none
 */
void sendCommand ( uint8 command )
{
  uint8 pData[1];
  static uint8 reportNr = 0;
  uint8 txOptions;

  pData[0] = command;
  if ( ++reportNr < ACK_REQ_INTERVAL && reportFailureNr == 0 )
  {
    txOptions = AF_TX_OPTIONS_NONE;
  }
  else
  {
    txOptions = AF_MSG_ACK_REQUEST;
    reportNr = 0;
  }
  zb_SendDataRequest( 0xFFFE, ROUTER_REPORT_CMD_ID, 1, pData, 0, txOptions, 0 );
}
예제 #5
0
/*
 * This routine send data originated by the user layer to
 * the Z-Accel.
 */
void zaccel_xmt(struct work_struct *work)
{
	struct bmi_zb *zb;
	struct zaccel_info *z_info;
	struct zaccel_xmt_msg *msg;

	zb = container_of(work, struct bmi_zb, xmt_work);
	z_info = &zb->z_info;
	
	while(!list_empty(&z_info->xmt_list))
	{
		msg = list_entry(z_info->xmt_list.next, struct zaccel_xmt_msg, list);

		zb_SendDataRequest(zb, msg->buf, msg->len);

		list_del(z_info->xmt_list.next);
		kfree(msg);
	}
}
예제 #6
0
/**
 * @brief   Este callback es llamado asincrónicamente por el stack de ZigBee
 *          para notificar a la aplicación que se recibieron datos, enviados 
 *          por otro nodo de la red.
 * @param   source  Short Address (NWK) del nodo que envío los datos.
 * @param   command ID del comando asociado con los datos.
 * @param   len     Cantidad de bytes del parámetro pData.
 * @param   pData   Puntero al inicio de los datos envíados por el nodo.
 */
void zb_ReceiveDataIndication(uint16 source, uint16 command, uint16 len, uint8 *pData)
{ 
    // imprime la dirección fuente en el display
    HalLcdWriteStringValue("RCB", source, 16, 1);
    // flashea el LED 2 para indicar que se recibió un mensaje
    HalLedSet(HAL_LED_2, HAL_LED_MODE_FLASH);
    
    // deserealiza mensaje recibido
    msgReport = deserializeMessage(pData);
    
    if (msgReport.msgType == MSG_TYPE_REPORT)
    {
        HalLcdWriteStringValue("#", msgReport.sequence, 10, 2);
        // verifica condiciones de alarmas
        alarmFlags = checkAlarms(&msgReport);
        // imprime alarma en LCD
        //HalLcdWriteStringValue("ALARM", alarmFlags, 16, 2);
        
        if (alarmFlags != 0)
        {
            // crea paquete de respuesta con igual MAC y nº de secuencia
            struct message_t msgAlarm;
            msgAlarm.sequence = msgReport.sequence;
            memcpy(&(msgAlarm.mac), &(msgReport.mac), sizeof(msgReport.mac));
            msgAlarm.msgType = MSG_TYPE_ALARM;
            msgAlarm.lenData = MSG_LEN_DATA_ALARM;
            // flags en little-endian
            msgAlarm.data[0] = LO_UINT16(alarmFlags);
            msgAlarm.data[1] = HI_UINT16(alarmFlags);
            
            // serializa mensaje y lo envía
            serializeMessage(&(msgAlarm), msgBuf);
            zb_SendDataRequest(source, MESSAGE_CLUSTER,
                               getSizeOfMessage(&(msgAlarm)),
                               msgBuf, 0, AF_TX_OPTIONS_NONE, 0);
        }
        // crea evento para enviar el reporte por UART a la PC, añandiendo
        // los flags
        osal_start_timerEx(sapi_TaskID, SEND_UART_MSG, 0);
    }
}
/*********************************************************************
 * @fn      temcoApp_MessageMSGCB
 */
static void temcoApp_MessageMSGCB(afIncomingMSGPacket_t *pkt)
{
  switch(pkt->clusterId)
  {
    case TEMCO_CLUSTERID:
      if( zgDeviceLogicalType == ZG_DEVICETYPE_ROUTER)  // Prepare to insert modbus message into TSTAT's
      {
        if( (pkt->cmd.Data[1] == MODBUS_SINGLE_READ) && (pkt->cmd.DataLength == 8))
        {
          firstAddr = BUILD_UINT16(pkt->cmd.Data[3],pkt->cmd.Data[2]);
          uint8 length = pkt->cmd.Data[5];
          
          if( (firstAddr<21)&&((firstAddr+length)>21))
          {
            modbusDataLength = firstAddr+length-21;
            modbusStartAddr = 21;
          }
          else if( (firstAddr>=21) && (firstAddr <100))
          {
            modbusStartAddr = firstAddr;
            if(length <= (101-firstAddr))
              modbusDataLength = length;
            else
              modbusDataLength = 101-firstAddr;
          }
          else
          {
            modbusStartAddr = 0;
            modbusDataLength = 0;
          }
        }
        else if( pkt->cmd.Data[1] == MODBUS_SINGLE_WRITE)
        {
          modbus_single_write(pkt->cmd.Data, pkt->cmd.DataLength);
        }
        else if( pkt->cmd.Data[1] == MODBUS_MULTI_WRITE)
        {
          modbus_multi_write(pkt->cmd.Data, pkt->cmd.DataLength);
        }
      }
      HalUARTWrite ( 0, pkt->cmd.Data, pkt->cmd.DataLength );
      break;
      
    case ACK_CMD_CLUSTERID:  // 7/16取消修改 此处改为定时发广播,收到任何节点消息,不论对方类型,都不需要重启
      if(zgDeviceLogicalType == ZG_DEVICETYPE_COORDINATOR)
      {
        uint8 ack_byte = 1;
        zb_SendDataRequest( pkt->srcAddr.addr.shortAddr, ACK_CMD_CLUSTERID, 1, &ack_byte, 
                               0, AF_ACK_REQUEST, 0);
      }
      else
      {
        if(pkt->cmd.Data[0] == 1)
          ack_exist = TRUE;
      }
      break;
      
    case RSSI_REQ_CLUSTERID:
      if( pkt->cmd.Data[0] == 0)
      {
        if( zgDeviceLogicalType == ZG_DEVICETYPE_COORDINATOR)
        {
          zb_SendDataRequest( pkt->srcAddr.addr.shortAddr, RSSI_RSP_CLUSTERID, 1, &tstat_id, 
                                 0, AF_ACK_REQUEST, 0);
        }
        else
        {
          if( tstat_id != 0)
            zb_SendDataRequest( pkt->srcAddr.addr.shortAddr, RSSI_RSP_CLUSTERID, 1, &tstat_id, 
                                   0, AF_ACK_REQUEST, 0);
        }
      }
      break;
    case RSSI_RSP_CLUSTERID:
      if( pkt->cmd.Data[0] != 0)
      {
        
        signalStrength_t *pInSignal;
        pInSignal = findSignalStrength( pkt->cmd.Data[0]);
        if( pInSignal != NULL)
        {
          pInSignal->rssi = pkt->rssi;
          pInSignal->leaveTime = 0;
        }
        else
        {
          register_signalStrength( pkt->cmd.Data[0], pkt->rssi);
          numSignalStren++;
        }
      }
      break;
    default:
      break;
  }
}
/*********************************************************************
 * @fn      temcoApp_ProcessEvent
 */
uint16 temcoApp_ProcessEvent(uint8 task_id, uint16 events)
{
  osal_event_hdr_t *pMsg;
  afIncomingMSGPacket_t *pMSGpkt;
  
  if( events & SYS_EVENT_MSG)
  {
    pMsg = (osal_event_hdr_t *) osal_msg_receive( task_id );
    while(pMsg)
    {
      switch( pMsg->event)
      {
        case AF_INCOMING_MSG_CMD:
          pMSGpkt = (afIncomingMSGPacket_t *)pMsg;
          temcoApp_MessageMSGCB(pMSGpkt);
          break;
          
        case ZDO_STATE_CHANGE:
          if (pMsg->status == DEV_END_DEVICE ||
              pMsg->status == DEV_ROUTER )
              //||pMsg->status == DEV_ZB_COORD )
          {
            osal_set_event( temcoAPP_TaskID, ACK_CHECK);
//            HalLedSet ( HAL_LED_1, HAL_LED_MODE_FLASH );
//            HalLedBlink ( HAL_LED_1, 0, 50, 500 );
          }
          break;
          
        default:
          
          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 & ACK_CHECK)
  {
    uint8 ack_byte = 0;
    
    if( ack_count > ACK_TIMEOUT_NUM)
    {
      ack_count = 0;
      if( ack_exist == FALSE)
      {
        restore_factory_setting();
      }
    }
    if( ack_exist == TRUE)
    {
      zb_SendDataRequest( 0, ACK_CMD_CLUSTERID, 1, &ack_byte,
                           0, AF_ACK_REQUEST, 0);
      ack_exist = FALSE;
    }
    ack_count ++;
    osal_start_timerEx( temcoAPP_TaskID, ACK_CHECK, ACK_CHECK_TIMEOUT);   // Every minute check ack, if no receive, restart to join a new network
    return ( events ^ ACK_CHECK);
  }
  
  // Send the command to check TSTAT modbus id
  if( events & ASK_MODBUS_ID)
  {
    uint8 rssi_byte = 0;
    uint8 deleteId;

    if( type_assert >= TYPE_ASSERT_TIMEOUT)  // Decide which type to start up
    {
#if 0
      if( (product_id == 0) || (product_id == 100))   
      {
        if( zgDeviceLogicalType == ZG_DEVICETYPE_ROUTER)
        {
          zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR;
          restart_to_other_type();
        }
      }
      else
      {
        if( zgDeviceLogicalType == ZG_DEVICETYPE_COORDINATOR)
        {
          zgDeviceLogicalType = ZG_DEVICETYPE_ROUTER;
          restart_to_other_type();
        }
      }
#endif
      // To read register6 of TSTAT
      if( tstat_id != 0)
      {
        //if( zgDeviceLogicalType != ZG_DEVICETYPE_COORDINATOR)
        // Send a command asking other nodes' modbus id, the response message carry rssi 
        zb_SendDataRequest( 0xffff, RSSI_REQ_CLUSTERID, 1, &rssi_byte,
                             0, AF_ACK_REQUEST, 0);
        
        deleteId = checkNodeAlive();   // check if there are any nodes not alive
        if( deleteId != 255)
          deleteSignalStrength(deleteId);        // delete the dead id
      }
    }
    else
    {
      type_assert ++;
      HalUARTWrite ( 0, ask_modbus_id, 8 );
    }
    
    // if not received, send again X seconds later
    osal_start_timerEx( temcoAPP_TaskID, ASK_MODBUS_ID, RSSI_REQ_TIMEOUT);
    return ( events ^ ASK_MODBUS_ID);
  }
  
  if( events & SEND_ZIGBEE_FLAG)
  {
    if( tstat_id == 0)
      HalUARTWrite( 0, "zigbee", strlen("zigbee"));
    else
      osal_stop_timerEx( temcoAPP_TaskID, SEND_ZIGBEE_FLAG);
    osal_start_timerEx( temcoAPP_TaskID, SEND_ZIGBEE_FLAG, 3000);
  }
  
  // Discard unknown events
  return 0;
}