コード例 #1
0
/*********************************************************************
 * @fn      zclApplianceStatistics_LogQueueRsp_NativeToOta
 *
 * @brief   Converts from native to OTA format.
 *
 * @param   disableDefaultRsp - whether to disable the Default Response command
 * @param   pZclPayloadLen - returns zcl payload len
 *
 * @return  pointer to zcl payload
*/
uint8 *zclApplianceStatistics_LogQueueRsp_NativeToOta( zclCmdApplianceStatisticsLogQueueRspPayload_t *pPayload , uint16 * pZclPayloadLen )
{
  uint8 *pZclPayload;      // OTA ZCL payload
  uint16 zclPayloadLen;    // OTA ZCL payload length
  uint16 i;
  uint16 offset;

  // allocate some memory for the ZCL payload
  zclPayloadLen = 1 + (pPayload->logQueueSize * sizeof(uint32));    // # of LogQueue IDs
  pZclPayload = zcl_mem_alloc( zclPayloadLen );
  if( !pZclPayload )
  {
    return NULL;  // no memory
  }

  // fill in payload
  pZclPayload[0] = pPayload->logQueueSize;
  offset = 1;
  for( i = 0; i < pPayload->logQueueSize; ++i )
  {
    pZclPayload[offset]   = BREAK_UINT32(pPayload->pLogID[i], 0);
    pZclPayload[offset+1] = BREAK_UINT32(pPayload->pLogID[i], 1);
    pZclPayload[offset+2] = BREAK_UINT32(pPayload->pLogID[i], 2);
    pZclPayload[offset+3] = BREAK_UINT32(pPayload->pLogID[i], 3);
    offset += sizeof( uint32 );
  }

  // return OTA payload and length
  *pZclPayloadLen = zclPayloadLen;
  return pZclPayload;
}
コード例 #2
0
/**
 *  SNP_getRev
 *
 */
void SNP_getRev(snpGetRevisionRsp_t *pRsp)
{
  ICall_BuildRevision buildRev = {0};
  pRsp->snpVer = BUILD_UINT16(HI_UINT16(SNP_VERSION), LO_UINT16(SNP_VERSION));
  pRsp->status = Util_buildRevision(&buildRev);
  
  // Stack revision
  // Byte 0: Major
  // Byte 1: Minor
  // Byte 2: Patch
  pRsp->stackBuildVer[0] = BREAK_UINT32(buildRev.stackVersion, 0);
  pRsp->stackBuildVer[1] = BREAK_UINT32(buildRev.stackVersion, 1);
  pRsp->stackBuildVer[2] = BREAK_UINT32(buildRev.stackVersion, 2);

  // Build revision
  pRsp->stackBuildVer[3] = LO_UINT16(buildRev.buildVersion);
  pRsp->stackBuildVer[4] = HI_UINT16(buildRev.buildVersion);

  // Stack info (Byte 5)
  pRsp->stackBuildVer[5] = buildRev.stackInfo;

  // Controller info - part 1 (Byte 6)
  pRsp->stackBuildVer[6] = LO_UINT16(buildRev.ctrlInfo);

  // Controller info - part 2 (Byte 7)
  pRsp->stackBuildVer[7] = 0; // reserved

  // Host info - part 1 (Byte 8)
  pRsp->stackBuildVer[8] = LO_UINT16(buildRev.hostInfo);

  // Host info - part 2 (Byte 9)
  pRsp->stackBuildVer[9] = 0; // reserved

}
コード例 #3
0
/***************************************************************************************************
 * @fn      packDev_t
 *
 * @brief   Pack an associated_devices_t structure into a byte buffer (pack INVALID_NODE_ADDR if
 *          the pDev parameter is NULL).
 *
 * @param   pBuf - pointer to the buffer into which to pack the structure.
 * @param   pDev - pointer to the structure.
 *
 * @return  void
 ***************************************************************************************************/
static void packDev_t(uint8 *pBuf, associated_devices_t *pDev)
{
  if (NULL == pDev)
  {
    uint16 rtrn = INVALID_NODE_ADDR;
    *pBuf++ = LO_UINT16(rtrn);
    *pBuf++ = HI_UINT16(rtrn);
  }
  else
  {
    *pBuf++ = LO_UINT16(pDev->shortAddr);
    *pBuf++ = HI_UINT16(pDev->shortAddr);
    *pBuf++ = LO_UINT16(pDev->addrIdx);
    *pBuf++ = HI_UINT16(pDev->addrIdx);
    *pBuf++ = pDev->nodeRelation;
    *pBuf++ = pDev->devStatus;
    *pBuf++ = pDev->assocCnt;
    *pBuf++ = pDev->age;
    *pBuf++ = pDev->linkInfo.txCounter;
    *pBuf++ = pDev->linkInfo.txCost;
    *pBuf++ = pDev->linkInfo.rxLqi;
    *pBuf++ = pDev->linkInfo.inKeySeqNum;
    *pBuf++ = BREAK_UINT32(pDev->linkInfo.inFrmCntr, 0);
    *pBuf++ = BREAK_UINT32(pDev->linkInfo.inFrmCntr, 1);
    *pBuf++ = BREAK_UINT32(pDev->linkInfo.inFrmCntr, 2);
    *pBuf++ = BREAK_UINT32(pDev->linkInfo.inFrmCntr, 3);
    *pBuf++ = LO_UINT16(pDev->linkInfo.txFailure);
    *pBuf++ = HI_UINT16(pDev->linkInfo.txFailure);
  }
}
コード例 #4
0
/*********************************************************************
 * @fn      zclElectricalMeasurement_Send_GetMeasurementProfileRsp
 *
 * @brief   Call to send out Electrical Measurement Get Measurement Profile Response. This will
 *          tell the client the appropriate parameters of the measurement profile.
 *
 * @param   srcEP - Sending application's endpoint
 * @param   dstAddr - where you want the message to go
 * @param   pPayload:
 *          startTime - represents the end time of the most chronologically recent interval being requested
 *          status - table status enumeration lists the valid values returned in status field
 *          profileIntervalPeriod - time frame used to capture parameter for profiling purposes
 *          numberOfIntervalsDelivered - number of intervals the device is returning
 *          attributeID - attribute that has been profiled by the application
 *          intervals   - array of intervals that depend on numberOfIntervalsDelivered, type based on attributeID
 * @param   disableDefaultRsp - whether to disable the Default Response command
 * @param   seqNum - sequence number
 *
 * @return  ZStatus_t
 */
ZStatus_t zclElectricalMeasurement_Send_GetMeasurementProfileRsp( uint8 srcEP, afAddrType_t *dstAddr,
                                                                  zclElectricalMeasurementGetMeasurementProfileRsp_t *pPayload,
                                                                  uint8 disableDefaultRsp, uint8 seqNum )
{
  uint8 i;
  uint8 offset;
  uint8 *pBuf;    // variable length payload
  uint8 attrRtn;
  uint8 calculatedAttrLen;
  uint16 calculatedIntervalSize;
  uint16 calculatedBufLen;
  ZStatus_t status;
  zclAttrRec_t attrRec;

  // determine if attribute ID is found per EP and cluster ID
  attrRtn = zclFindAttrRec( dstAddr->endPoint, ZCL_CLUSTER_ID_HA_ELECTRICAL_MEASUREMENT, pPayload->attributeID, &attrRec );

  if ( attrRtn == TRUE )
  {
    // if found, determine length of attribute based on given type
    calculatedAttrLen = zclGetDataTypeLength( attrRec.attr.dataType );
  }

  calculatedIntervalSize = calculatedAttrLen * pPayload->numberOfIntervalsDelivered;

  // get a buffer large enough to hold the whole packet, including size of variable array
  calculatedBufLen = ( 9 + calculatedIntervalSize );

  pBuf = zcl_mem_alloc( calculatedBufLen );
  if ( !pBuf )
  {
    return ( ZMemError );  // no memory, return failure
  }

  pBuf[0] = BREAK_UINT32(pPayload->startTime, 0);
  pBuf[1] = BREAK_UINT32(pPayload->startTime, 1);
  pBuf[2] = BREAK_UINT32(pPayload->startTime, 2);
  pBuf[3] = BREAK_UINT32(pPayload->startTime, 3);
  pBuf[4] = pPayload->status;
  pBuf[5] = pPayload->profileIntervalPeriod;
  pBuf[6] = pPayload->numberOfIntervalsDelivered;
  pBuf[7] = LO_UINT16(pPayload->attributeID);
  pBuf[8] = HI_UINT16(pPayload->attributeID);
  offset = 9;
  for ( i = 0; i < calculatedIntervalSize; i++ )
  {
    pBuf[offset++] = pPayload->pIntervals[i];
  }

  status = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_HA_ELECTRICAL_MEASUREMENT,
                            COMMAND_ELECTRICAL_MEASUREMENT_GET_MEASUREMENT_PROFILE_RSP, TRUE,
                            ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, calculatedBufLen, pBuf );
  zcl_mem_free( pBuf );

  return ( status );
}
コード例 #5
0
ファイル: thermometer.c プロジェクト: victor-zheng/BLE
/*********************************************************************
 * @fn      Thermometer_measIndicate
 *
 * @brief   Prepare and send a thermometer measurement notification.
 *
 * @param   none
 *
 * @return  none
 */
static void Thermometer_measIndicate(void)
{
  // Thermometer measurement value stored in this structure.
  attHandleValueInd_t thermometerMeas;

  thermometerMeas.pValue = GATT_bm_alloc(thermometer_connHandle,
                                         ATT_HANDLE_VALUE_IND,
                                         THERMOMETER_MEAS_LEN, NULL);
  if (thermometerMeas.pValue != NULL)
  {
    // ATT value notification structure.
    uint8_t *p = thermometerMeas.pValue;
    
    // Temperature.
    uint32_t temperature;
    
    // Flags.
    uint8_t flags = thermometerFlags[thermometerFlagsIdx];
    
    // Flags 1 byte long.
    *p++ = flags;
    
    if(flags & THERMOMETER_FLAGS_FARENHEIT)
    {
      temperature = (thermometerCelcius *9/5) +320;
    }
    else
    {
       temperature = thermometerCelcius;
    }
    
    temperature = 0xFF000000 | temperature;
    
    // Temperature is 4 bytes long.
    *p++ = BREAK_UINT32(temperature, 0);
    *p++ = BREAK_UINT32(temperature, 1);
    *p++ = BREAK_UINT32(temperature, 2);
    *p++ = BREAK_UINT32(temperature, 3);
     
    // Timestamp.
    if (flags & THERMOMETER_FLAGS_TIMESTAMP)
    {
      UTCTimeStruct time;
    
      // Get time structure from UTC.
      UTC_convertUTCTime(&time, UTC_getClock());
      
      *p++ = (time.year & 0x00FF);
      *p++ = (time.year & 0xFF00)>>8;
              
      *p++=time.month;    
      *p++=time.day;  
      *p++=time.hour;    
      *p++=time.minutes;    
      *p++=time.seconds;   
    }
コード例 #6
0
ファイル: zap_af.c プロジェクト: sdhczw/ACGatewayDemo
/**************************************************************************************************
 * @fn          afRetrieve
 *
 * @brief       This function retrieves the data of a huge incoming message. On an failure during
 *              the retrieval, the incoming message is freed. Otherwise, the incoming message is
 *              forwarded to the corresponding task.
 *
 * input parameters
 *
 * @param       pMsg - Pointer to the incoming AF message.
 * @param       taskId - The task ID corresponding to the destination endpoint of the message.
 *
 * output parameters
 *
 * @param       pMsg->cmd.Data - The incoming message data buffer member is filled.
 *
 * @return      None.
 **************************************************************************************************
 */
static void afRetrieve(uint8 taskId, afIncomingMSGPacket_t *pMsg)
{
  #define ZAP_AF_RTV_MSG_HDR  7  // Retrieve message header length.
  #define ZAP_AF_RTV_RPY_HDR  2  // Retrieve-reply message header length.
  #define ZAP_AF_RTV_DAT_MAX (MT_RPC_DATA_MAX - ZAP_AF_RTV_RPY_HDR)

  uint16 idx = 0, len = pMsg->cmd.DataLength;
  uint8 *pBuf, rtrn, tmpLen = 0;

  do {
    /* This trick to pre-decrement (with zero on the first pass) allows the while() test to
     * succeed and loop to send a zero data length message which will trigger the ZNP to
     * de-allocate the huge incoming message being held.
     */
    len -= tmpLen;
    idx += tmpLen;

    if (len > ZAP_AF_RTV_DAT_MAX)
    {
      tmpLen = ZAP_AF_RTV_DAT_MAX;
    }
    else
    {
      tmpLen = len;
    }

    if ((pBuf = zap_msg_allocate(ZAP_AF_RTV_MSG_HDR, ((uint8)MT_RPC_SYS_AF | MT_RPC_CMD_SREQ),
                                                             MT_AF_DATA_RETRIEVE)) == NULL)
    {
      rtrn = afStatus_MEM_FAIL;
      break;
    }

    pBuf[0] = BREAK_UINT32(pMsg->timestamp, 0);
    pBuf[1] = BREAK_UINT32(pMsg->timestamp, 1);
    pBuf[2] = BREAK_UINT32(pMsg->timestamp, 2);
    pBuf[3] = BREAK_UINT32(pMsg->timestamp, 3);
    pBuf[4] = LO_UINT16(idx);
    pBuf[5] = HI_UINT16(idx);
    pBuf[6] = tmpLen;
    zapPhySend(zapAppPort, pBuf);
    rtrn = (afStatus_t)ZAP_SRSP_STATUS(pBuf);
    (void)osal_memcpy(pMsg->cmd.Data+idx, pBuf+ZAP_AF_RTV_RPY_HDR, tmpLen);
    zap_msg_deallocate(&pBuf);
  } while ((rtrn == afStatus_SUCCESS) && len);

  if (rtrn == afStatus_SUCCESS)
  {
    (void)osal_msg_send(taskId, (uint8 *)pMsg);
  }
  else
  {
    (void)osal_msg_deallocate((uint8 *)pMsg);
  }
}
コード例 #7
0
ファイル: LCSC_Sensor.c プロジェクト: linan0827/ble_csc
/*********************************************************************
 * @fn      sensorMeasNotify
 *
 * @brief   Prepare and send a CSC measurement notification
 *
 * @return  none
 */
static void sensorMeasNotify( void )
{
  uint8 *p = sensorMeas.value;
  uint8 flags = sensorFlags[sensorFlagsIdx];

  // Build CSC measurement structure from simulated values
  // Flags simulate the isPresent bits.
  *p++ = flags;

  // If present, add Speed data into measurement
  if (flags & CSC_FLAGS_SPEED)
  {
    *p++ = BREAK_UINT32(cummWheelRevs, 0);
    *p++ = BREAK_UINT32(cummWheelRevs, 1);
    *p++ = BREAK_UINT32(cummWheelRevs, 2);
    *p++ = BREAK_UINT32(cummWheelRevs, 3);

    *p++ = LO_UINT16(lastWheelEvtTime);
    *p++ = HI_UINT16(lastWheelEvtTime);

    // Update simulated values (simulate in the reverse direction)
 /*   if (cummWheelRevs < WHEEL_REV_INCREMENT) //don't allow revolutions to roll over
    {
      cummWheelRevs = 0;
    }
    else
    {
      cummWheelRevs -= WHEEL_REV_INCREMENT;
    }

    lastWheelEvtTime += WHEEL_EVT_INCREMENT;   */
  }

  // If present, add Cadence data into measurement
  if (flags & CSC_FLAGS_CADENCE)
  {
    *p++ = LO_UINT16(cummCrankRevs);
    *p++ = HI_UINT16(cummCrankRevs);

    *p++ = LO_UINT16(lastCrankEvtTime);
    *p++ = HI_UINT16(lastCrankEvtTime);

    // Update Simualted Values
   /* cummCrankRevs += CRANK_REV_INCREMENT;
    lastCrankEvtTime += CRANK_EVT_INCREMENT; */
  }

  // Get length
  sensorMeas.len = (uint8) (p - sensorMeas.value);

  // Send to service to send the notification
  Cycling_MeasNotify( gapConnHandle, &sensorMeas );
}
コード例 #8
0
ファイル: MT_UTIL.c プロジェクト: 12019/hellowsn
/***************************************************************************************************
 * @fn      MT_UtilAPSME_LinkKeyDataGet
 *
 * @brief   Proxy the APSME_LinkKeyDataGet() function.
 *
 * @param   pBuf - pointer to the received buffer
 *
 * @return  void
 ***************************************************************************************************/
static void MT_UtilAPSME_LinkKeyDataGet(uint8 *pBuf)
{
  // Status + LinkKeyDataLen + Tx+Rx Frame counter.
  #define MT_APSME_LINKKEY_GET_RSP_LEN (1 + SEC_KEY_LEN + 4 + 4)
  uint8 rsp[MT_APSME_LINKKEY_GET_RSP_LEN];
  APSME_LinkKeyData_t *pData;
  uint8 cmdId = pBuf[MT_RPC_POS_CMD1];
  pBuf += MT_RPC_FRAME_HDR_SZ;

  *rsp = APSME_LinkKeyDataGet(pBuf, &pData);

  if (SUCCESS == *rsp)
  {
    uint8 *ptr = rsp+1;
    (void)osal_memcpy(ptr, pData->key, SEC_KEY_LEN);
    ptr += SEC_KEY_LEN;
    *ptr++ = BREAK_UINT32(pData->txFrmCntr, 0);
    *ptr++ = BREAK_UINT32(pData->txFrmCntr, 1);
    *ptr++ = BREAK_UINT32(pData->txFrmCntr, 2);
    *ptr++ = BREAK_UINT32(pData->txFrmCntr, 3);
    *ptr++ = BREAK_UINT32(pData->rxFrmCntr, 0);
    *ptr++ = BREAK_UINT32(pData->rxFrmCntr, 1);
    *ptr++ = BREAK_UINT32(pData->rxFrmCntr, 2);
    *ptr++ = BREAK_UINT32(pData->rxFrmCntr, 3);
  }

  MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 
                                       MT_APSME_LINKKEY_GET_RSP_LEN, rsp);
}
コード例 #9
0
/***************************************************************************************************
 * @fn      MT_UtilAPSME_LinkKeyDataGet
 *
 * @brief   Retrieves APS Link Key data from NV.
 *
 * @param   pBuf - pointer to the received buffer
 *
 * @return  void
 ***************************************************************************************************/
static void MT_UtilAPSME_LinkKeyDataGet(uint8 *pBuf)
{
  uint8 rsp[MT_APSME_LINKKEY_GET_RSP_LEN];
  APSME_LinkKeyData_t *pData = NULL;
  uint8 cmdId = pBuf[MT_RPC_POS_CMD1];
  uint16 apsLinkKeyNvId;
  uint32 *apsRxFrmCntr;
  uint32 *apsTxFrmCntr;

  pBuf += MT_RPC_FRAME_HDR_SZ;

  *rsp = APSME_LinkKeyNVIdGet(pBuf, &apsLinkKeyNvId);

  if (SUCCESS == *rsp)
  {
    pData = (APSME_LinkKeyData_t *)osal_mem_alloc(sizeof(APSME_LinkKeyData_t));

    if (pData != NULL)
    {
      // retrieve key from NV
      if ( osal_nv_read( apsLinkKeyNvId, 0,
                        sizeof(APSME_LinkKeyData_t), pData) == SUCCESS)

      {
        apsRxFrmCntr = &ApsLinkKeyFrmCntr[apsLinkKeyNvId - ZCD_NV_APS_LINK_KEY_DATA_START].rxFrmCntr;
        apsTxFrmCntr = &ApsLinkKeyFrmCntr[apsLinkKeyNvId - ZCD_NV_APS_LINK_KEY_DATA_START].txFrmCntr;

        uint8 *ptr = rsp+1;
        (void)osal_memcpy(ptr, pData->key, SEC_KEY_LEN);
        ptr += SEC_KEY_LEN;
        *ptr++ = BREAK_UINT32(*apsTxFrmCntr, 0);
        *ptr++ = BREAK_UINT32(*apsTxFrmCntr, 1);
        *ptr++ = BREAK_UINT32(*apsTxFrmCntr, 2);
        *ptr++ = BREAK_UINT32(*apsTxFrmCntr, 3);
        *ptr++ = BREAK_UINT32(*apsRxFrmCntr, 0);
        *ptr++ = BREAK_UINT32(*apsRxFrmCntr, 1);
        *ptr++ = BREAK_UINT32(*apsRxFrmCntr, 2);
        *ptr++ = BREAK_UINT32(*apsRxFrmCntr, 3);
      }

      // clear copy of key in RAM
      osal_memset( pData, 0x00, sizeof(APSME_LinkKeyData_t) );

      osal_mem_free(pData);
    }
  }
  else
  {
    // set data key and counters 0xFF
    osal_memset(&rsp[1], 0xFF, SEC_KEY_LEN + (MT_UTIL_FRM_CTR_LEN * 2));
  }

  MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId,
                                       MT_APSME_LINKKEY_GET_RSP_LEN, rsp);

  // clear key data
  osal_memset(rsp, 0x00, MT_APSME_LINKKEY_GET_RSP_LEN);

}
コード例 #10
0
/*********************************************************************
 * @fn      zclApplianceStatistics_Send_LogReq
 *
 * @brief   Request sent to server for Log Request.
 *
 * @param   srcEP - Sending application's endpoint
 * @param   dstAddr - where you want the message to go
 * @param   logID - identifies uniquely the log information contained in log payload
 * @param   disableDefaultRsp - whether to disable the Default Response command
 * @param   seqNum - sequence number
 *
 * @return  ZStatus_t
 */
ZStatus_t zclApplianceStatistics_Send_LogReq( uint8 srcEP, afAddrType_t *dstAddr,
                                                     uint32 logID,
                                                     uint8 disableDefaultRsp, uint8 seqNum )
{
  uint8 buf[4];   // 4 byte payload

  buf[0] = BREAK_UINT32(logID, 0);
  buf[1] = BREAK_UINT32(logID, 1);
  buf[2] = BREAK_UINT32(logID, 2);
  buf[3] = BREAK_UINT32(logID, 3);

  return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_HA_APPLIANCE_STATISTICS,
                          COMMAND_APPLIANCE_STATISTICS_LOG_REQ, TRUE,
                          ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, sizeof( buf ), buf );
}
コード例 #11
0
/***************************************************************************************************
 * @fn      MT_UtilTimeAlive
 *
 * @brief   Process Time Alive
 *
 * @param   None.
 *
 * @return  None
 ***************************************************************************************************/
void MT_UtilTimeAlive(void)
{
  uint8 timeAlive[4];
  uint32 tmp32;

  /* Time since last reset (seconds) */
  tmp32 = osal_GetSystemClock() / 1000;

  /* Convert to high byte first into temp buffer */
  timeAlive[0] = BREAK_UINT32(tmp32, 0);
  timeAlive[1] = BREAK_UINT32(tmp32, 1);
  timeAlive[2] = BREAK_UINT32(tmp32, 2);
  timeAlive[3] = BREAK_UINT32(tmp32, 3);

  /* Build and send back the response */
  MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL),
                                       MT_UTIL_TIME_ALIVE, sizeof(timeAlive), timeAlive);
}
コード例 #12
0
ファイル: MT_OTA.c プロジェクト: Daan1992/WSN-Lab
/***************************************************************************************************
 * @fn      MT_OtaFileReadReq
 *
 * @brief   Requests a block of a file be read from the remote.
 *
 * @param   pAddr - The addres of the device requsting the data
 * @param   pFileId - Teh id of the image to read from
 * @param       len - Amount of data to read (must be smaller than the max MT message payload len)
 * @param    offset - The offset into the image to start reading from
 *
 * @return  status
 ***************************************************************************************************/
uint8 MT_OtaFileReadReq(afAddrType_t *pAddr, zclOTA_FileID_t *pFileId, uint8 len, uint32 offset)
{
  uint8   msgLen;
  uint8   *pBuf;
  uint8   *p;

  // Check if the requested length is longer than the RX receive buffer
  if (len + MT_OTA_FILE_READ_RSP_LEN + SPI_0DATA_MSG_LEN > MT_UART_RX_BUFF_MAX)
    return 0;
  
  // Get length
  msgLen = MT_OTA_FILE_READ_REQ_LEN;
  
  // Allocate a buffer
  if ((p = pBuf = MT_TransportAlloc(0, msgLen)) != NULL)
  {
    /* build header */
    *p++ = msgLen;
    *p++ = (uint8) MT_RPC_CMD_AREQ | (uint8) MT_RPC_SYS_OTA;
    *p++ = MT_OTA_FILE_READ_REQ;
    
    // Add the file ID
    p = OTA_FileIdToStream(pFileId, p);

    // Add the device address 
    p = OTA_AfAddrToStream(pAddr, p);

    // File ofset to read from
    *p++ = BREAK_UINT32(offset, 0);
    *p++ = BREAK_UINT32(offset, 1);
    *p++ = BREAK_UINT32(offset, 2);
    *p++ = BREAK_UINT32(offset, 3);

    *p = len;
    
    // Send command to server
    MT_TransportSend(pBuf);
    
    return ZSuccess;
  }
  
  return ZMemError;
}
コード例 #13
0
/*********************************************************************
 * @fn      zclElectricalMeasurement_Send_GetMeasurementProfile
 *
 * @brief   Call to send out Electrical Measurement Get Measurement Profile. This will
 *          ask the server for the appropriate parameters of the measurement profile.
 *
 * @param   srcEP - Sending application's endpoint
 * @param   dstAddr - where you want the message to go
 * @param   attributeID - the electricity measurement attribute being profiled
 * @param   startTime - selects the interval block from available interval blocks
 * @param   numberOfIntervals - represents the number of intervals being requested
 * @param   disableDefaultRsp - whether to disable the Default Response command
 * @param   seqNum - sequence number
 *
 * @return  ZStatus_t
 */
ZStatus_t zclElectricalMeasurement_Send_GetMeasurementProfile( uint8 srcEP, afAddrType_t *dstAddr,
                                                               uint16 attributeID, uint32 startTime,
                                                               uint8 numberOfIntervals,
                                                               uint8 disableDefaultRsp, uint8 seqNum )
{
  uint8 buf[7];   // 7 byte payload

  buf[0] = LO_UINT16(attributeID);
  buf[1] = HI_UINT16(attributeID);
  buf[2] = BREAK_UINT32(startTime, 0);
  buf[3] = BREAK_UINT32(startTime, 1);
  buf[4] = BREAK_UINT32(startTime, 2);
  buf[5] = BREAK_UINT32(startTime, 3);
  buf[6] = numberOfIntervals;

  return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_HA_ELECTRICAL_MEASUREMENT,
                          COMMAND_ELECTRICAL_MEASUREMENT_GET_MEASUREMENT_PROFILE, TRUE,
                          ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, sizeof(buf), buf );
}
コード例 #14
0
ファイル: ota_common.c プロジェクト: LILCMU/WRATIOT
/******************************************************************************
 * @fn      OTA_FileIdToStream
 *
 * @brief   Writes a file ID to a stream
 *
 * @param   pFileId - File ID
 *          pStream - Stream
 *
 * @return  new stream pointer
 */
uint8 *OTA_FileIdToStream(zclOTA_FileID_t *pFileId, uint8 *pStream)
{
  if (pStream)
  {
    *pStream++ = LO_UINT16(pFileId->manufacturer);
    *pStream++ = HI_UINT16(pFileId->manufacturer);

    *pStream++ = LO_UINT16(pFileId->type);
    *pStream++ = HI_UINT16(pFileId->type);

    // osal_buffer_uint32 not available under windows
    //pStream = osal_buffer_uint32(pStream, pFileId->version);
    *pStream++ = BREAK_UINT32(pFileId->version, 0);
    *pStream++ = BREAK_UINT32(pFileId->version, 1);
    *pStream++ = BREAK_UINT32(pFileId->version, 2);
    *pStream++ = BREAK_UINT32(pFileId->version, 3);
  }

  return pStream;
}
コード例 #15
0
/*********************************************************************
 * @fn      sensorMeasNotify
 *
 * @brief   Prepare and send a CSC measurement notification
 *
 * @return  none
 */
static void sensorMeasNotify( void )
{
  attHandleValueNoti_t sensorMeas;
  
  sensorMeas.pValue = GATT_bm_alloc( gapConnHandle, ATT_HANDLE_VALUE_NOTI,
                                     CSC_MEAS_LEN, NULL );
  if ( sensorMeas.pValue != NULL )
  {
    uint8 *p = sensorMeas.pValue;
    uint8 flags = sensorFlags[sensorFlagsIdx];

    // Build CSC measurement structure from simulated values
    // Flags simulate the isPresent bits.
    *p++ = flags;

    // If present, add Speed data into measurement
    if (flags & CSC_FLAGS_SPEED)
    {
      *p++ = BREAK_UINT32(cummWheelRevs, 0);
      *p++ = BREAK_UINT32(cummWheelRevs, 1);
      *p++ = BREAK_UINT32(cummWheelRevs, 2);
      *p++ = BREAK_UINT32(cummWheelRevs, 3);

      *p++ = LO_UINT16(lastWheelEvtTime);
      *p++ = HI_UINT16(lastWheelEvtTime);

      // Update simulated values (simulate in the reverse direction)
      if (cummWheelRevs < WHEEL_REV_INCREMENT) //don't allow revolutions to roll over
      {
        cummWheelRevs = 0;
      }
      else
      {
        cummWheelRevs -= WHEEL_REV_INCREMENT;
      }

      lastWheelEvtTime += WHEEL_EVT_INCREMENT;
    }

    // If present, add Cadence data into measurement
    if (flags & CSC_FLAGS_CADENCE)
    {
      *p++ = LO_UINT16(cummCrankRevs);
      *p++ = HI_UINT16(cummCrankRevs);

      *p++ = LO_UINT16(lastCrankEvtTime);
      *p++ = HI_UINT16(lastCrankEvtTime);

      // Update Simualted Values
      cummCrankRevs += CRANK_REV_INCREMENT;
      lastCrankEvtTime += CRANK_EVT_INCREMENT;
    }

    // Get length
    sensorMeas.len = (uint8) (p - sensorMeas.pValue);

    // Send to service to send the notification
    if ( Cycling_MeasNotify( gapConnHandle, &sensorMeas ) != SUCCESS )
    {
      GATT_bm_free( (gattMsg_t *)&sensorMeas, ATT_HANDLE_VALUE_NOTI );
    }
  }
}
コード例 #16
0
ファイル: modbus.c プロジェクト: TemcoLijun/Zigbee_Modules
/******************************************************************************
 * @fn      modbus_insert_msg
 */
void modbus_insert_msg( uint8 *pBuf, uint8 len)
{
  uint8 index = 0;
  afAddrType_t destAddr;
  destAddr.addrMode = afAddr16Bit;
  destAddr.addr.shortAddr = 0;                
  destAddr.endPoint = 10;
  signalStrength_t* pSigStren;
    
  initCRC16();
//  uint8 *pInsertBuf = osal_mem_alloc( modbusDataLength*2);
  if( firstAddr < 21)
    index = 45 - 2*firstAddr;
  else
    //index = (modbusStartAddr-20)*2 + 1;
    index = 3;
  
  for (uint8 i=0; i<modbusDataLength; i++)
  {
    if( i+modbusStartAddr == MODBUS_PANID)
    {
      pBuf[index++] = HI_UINT16( _NIB.nwkPanId);
      pBuf[index++] = LO_UINT16( _NIB.nwkPanId);
    }
    else if( i + modbusStartAddr == MODBUS_DEVICE_TYPE)
    {
      pBuf[index++] = ZERO;
      pBuf[index++] = zgDeviceLogicalType;
    }
    else if( i + modbusStartAddr == MODBUS_CHANNEL_LIST_HI)
    {
      pBuf[index++] = BREAK_UINT32(zgDefaultChannelList, 3);
      pBuf[index++] = BREAK_UINT32(zgDefaultChannelList, 2);
    }
    else if( i + modbusStartAddr == MODBUS_CHANNEL_LIST_LO)
    {
      pBuf[index++] = BREAK_UINT32(zgDefaultChannelList, 1);
      pBuf[index++] = BREAK_UINT32(zgDefaultChannelList, 0);
    }
    else if( i + modbusStartAddr == MODBUS_SOFTWARE_REV)
    {
      pBuf[index++] = ZERO;
      pBuf[index++] = ZIG_SOFTWARE_VER;
    }
    else if( (i + modbusStartAddr >= MODBUS_EXTENDED_ADDR_HI) && (i + modbusStartAddr <= MODBUS_EXTENDED_ADDR_LO))
    {
      pBuf[index++] = ZERO;
      pBuf[index++] = aExtendedAddress[ i+modbusStartAddr-MODBUS_EXTENDED_ADDR_HI];
    }
    else if( (i + modbusStartAddr >= MODBUS_SECURITY_KEY_START) && (i + modbusStartAddr <= MODBUS_SECURITY_KEY_END))
    {
      pBuf[index++] = ZERO;
      pBuf[index++] = defaultKey[ i+modbusStartAddr-MODBUS_SECURITY_KEY_START];
    }
    else if( i + modbusStartAddr == MODBUS_TSTAT_NUM)
    {
      pBuf[index++] = ZERO;
      pBuf[index++] = numSignalStren;
    }
    else if( (i + modbusStartAddr >= MODBUS_FIRST_TSTAT_ID) && ( i+ modbusStartAddr <= MODBUS_LAST_TSTAT_ID))
    {
      if( i + modbusStartAddr == MODBUS_FIRST_TSTAT_ID)
      {
        pSigStren = pSignalStren;
      }
      else
      {
        pSigStren = pSignalStren;
        for( uint8 j=0; j<((i+modbusStartAddr)-MODBUS_FIRST_TSTAT_ID); j++)
        {
          if(pSigStren)
            pSigStren = pSigStren->next;
        }
      }
      pBuf[index++] = ZERO;
      if(pSigStren != NULL)
      {
        pBuf[index++] = pSigStren->modbus_id;
      }
      else
        pBuf[index++] = ZERO;
    }
    else if( (i + modbusStartAddr >= MODBUS_FIRST_SIG_STREN) && ( i+ modbusStartAddr <= MODBUS_LAST_SIG_STREN))
    {
      if( i + modbusStartAddr == MODBUS_FIRST_SIG_STREN)
      {
        pSigStren = pSignalStren;
      }
      else
      {
        pSigStren = pSignalStren;
        for( uint8 j=0; j<((i+modbusStartAddr)-MODBUS_FIRST_SIG_STREN); j++)
        {
          if(pSigStren)
            pSigStren = pSigStren->next;
        }
      }
      pBuf[index++] = ZERO;
      if(pSigStren != NULL)
      {
        pBuf[index++] = pSigStren->rssi;
      }
      else
        pBuf[index++] = ZERO;
    }
    else
    {
      pBuf[index++] = ZERO;
      pBuf[index++] = ZERO;
    }
  }
  
  for( uint8 i=0; i<len-2; i++)
    CRC16_byte(pBuf[i]);
  
  pBuf[len-2] = CRChi;
  pBuf[len-1] = CRClo;
  
  AF_DataRequest( &destAddr, &temco_epDesc,
                     TEMCO_CLUSTERID,
                     len,
                     pBuf,
                     &temcoApp_TransID,
                     AF_DISCV_ROUTE,
                     AF_DEFAULT_RADIUS );
  
  modbusStartAddr = 0;
  modbusDataLength = 0;
}
コード例 #17
0
ファイル: ota_common.c プロジェクト: LILCMU/WRATIOT
/******************************************************************************
 * @fn      OTA_WriteHeader
 *
 * @brief   Writes the OTA header to the output buffer.
 *
 * @param   pHdr - pointer to the header information
 * @param   pHdr - pointer to the output buffer
 *
 * @return  none
 */
uint8 *OTA_WriteHeader(OTA_ImageHeader_t *pHdr, uint8 *pBuf)
{
  uint8 i;

  // Output the Magic Number
  // osal_buffer_uint32 not available under windows
  //pBuf = osal_buffer_uint32(pBuf, pHdr->magicNumber);
  *pBuf++ = BREAK_UINT32(pHdr->magicNumber, 0);
  *pBuf++ = BREAK_UINT32(pHdr->magicNumber, 1);
  *pBuf++ = BREAK_UINT32(pHdr->magicNumber, 2);
  *pBuf++ = BREAK_UINT32(pHdr->magicNumber, 3);

  // Output the Header Version
  *pBuf++ = LO_UINT16(pHdr->headerVersion);
  *pBuf++ = HI_UINT16(pHdr->headerVersion);

  // Output the Header Length
  *pBuf++ = LO_UINT16(pHdr->headerLength);
  *pBuf++ = HI_UINT16(pHdr->headerLength);

  // Output the Field Control
  *pBuf++ = LO_UINT16(pHdr->fieldControl);
  *pBuf++ = HI_UINT16(pHdr->fieldControl);

  // Output the Manufacturer ID
  *pBuf++ = LO_UINT16(pHdr->fileId.manufacturer);
  *pBuf++ = HI_UINT16(pHdr->fileId.manufacturer);

  // Output the Image Type
  *pBuf++ = LO_UINT16(pHdr->fileId.type);
  *pBuf++ = HI_UINT16(pHdr->fileId.type);

  // Output the File Version
  // osal_buffer_uint32 not available under windows
  //pBuf = osal_buffer_uint32(pBuf, pHdr->fileId.version);
  *pBuf++ = BREAK_UINT32(pHdr->fileId.version, 0);
  *pBuf++ = BREAK_UINT32(pHdr->fileId.version, 1);
  *pBuf++ = BREAK_UINT32(pHdr->fileId.version, 2);
  *pBuf++ = BREAK_UINT32(pHdr->fileId.version, 3);

  // Output the Stack Version
  *pBuf++ = LO_UINT16(pHdr->stackVersion);
  *pBuf++ = HI_UINT16(pHdr->stackVersion);

  // Output the Header string
  for (i=0; i<OTA_HEADER_STR_LEN; i++)
  {
    *pBuf++ = pHdr->headerString[i];
  }

  // Output the Image Size
  // osal_buffer_uint32 not available under windows
  //pBuf = osal_buffer_uint32(pBuf, pHdr->imageSize);
  *pBuf++ = BREAK_UINT32(pHdr->imageSize, 0);
  *pBuf++ = BREAK_UINT32(pHdr->imageSize, 1);
  *pBuf++ = BREAK_UINT32(pHdr->imageSize, 2);
  *pBuf++ = BREAK_UINT32(pHdr->imageSize, 3);

  // Output the Security Credential Version
  if (pHdr->fieldControl & OTA_FC_SCV_PRESENT)
  {
    *pBuf++ = pHdr->secCredentialVer;
  }

  // Output the Upgrade File Destination
  if (pHdr->fieldControl & OTA_FC_DSF_PRESENT)
  {
    for (i=0; i<Z_EXTADDR_LEN; i++)
    {
      *pBuf++ = pHdr->destIEEE[i];
    }
  }

  // Output the Min and Max Hardware Versions
  if (pHdr->fieldControl & OTA_FC_HWV_PRESENT)
  {
    *pBuf++ = LO_UINT16(pHdr->minHwVer);
    *pBuf++ = HI_UINT16(pHdr->minHwVer);

    *pBuf++ = LO_UINT16(pHdr->maxHwVer);
    *pBuf++ = HI_UINT16(pHdr->maxHwVer);
  }

  return pBuf;
}
コード例 #18
0
/******************************************************************************
 * @fn      modbus_process_msg
 * 
 * @brief   Process modbus message
 * 
 * @param   uint8 - the pointer the buffer
 *          uint8 - length 
 * 
 * @return  none
 */
static void modbus_process_msg( uint8 *data_buffer, uint8 len)
{
  uint8 num, tempByte;
  uint8 zero = 0;
  uint16 i;
  uint16 address;
  boatMonitor_t *pTempMonitor;
  
  UTCTime utcSecs;
  UTCTimeStruct utcTime;

  utcSecs = osal_getClock();
  osal_ConvertUTCTime( &utcTime, utcSecs );
  
  address = BUILD_UINT16( data_buffer[3], data_buffer[2]);
  
  if(( data_buffer[0] == modbus_id) || ( data_buffer[0] == 255))
  {
    if(data_buffer[1] == MODBUS_SINGLE_WRITE)
    {
      HalUARTWrite( 0, data_buffer, len);
      if( address == MODBUS_ADDRESS)
      {
        modbus_id = data_buffer[5];
        osal_nv_write( ZCD_NV_MODBUS_ID, 0, sizeof(modbus_id), &modbus_id);
      }
      if( address == MODBUS_BAUDRATE)
      {
        if((data_buffer[5] >=0) &&(data_buffer[5] <= 4))
        {
          modbus_set_baudrate = data_buffer[5];
          osal_nv_write( ZCD_NV_BAUDRATE, 0, sizeof(modbus_set_baudrate), &modbus_set_baudrate);
          restore_factory_setting();
        }
      }
    }
    else if( data_buffer[1] == MODBUS_MULTI_WRITE)
    {
      if( address == MODBUS_SERIALNUMBER_LOWORD)
      {
        if(data_buffer[6] == 8)
        {
          for( uint8 k=0;k<4;k++)
          {
            ttt[k] = data_buffer[2*k+8];
            osal_nv_write( ZCD_NV_SERIAL_NUM, 0, sizeof(ttt), ttt);
          }
        }
      }
      
      // write system UTC
      if( address == MODBUS_SYS_HOUR)
      {
        if( data_buffer[6] >= 12)
          modbus_setUtcTime( &data_buffer[7]);
      }
    }
    else if( data_buffer[1] == MODBUS_SINGLE_READ)
    {
      num = data_buffer[5];
      uint8 *pBuf;
      uint8 index=0;
      pBuf = osal_mem_alloc(num*2+5);
      if( pBuf != NULL)
      {
        pBuf[index++] = data_buffer[0];
        pBuf[index++] = data_buffer[1];
        pBuf[index++] = num*2;
      //modbus_send_byte( data_buffer[0], CRC_NO);
      //modbus_send_byte( data_buffer[1], CRC_NO);
      //modbus_send_byte( num*2, CRC_NO);
        for( i = 0; i < num; i++)
        {
          if ( i + address <= MODBUS_SERIALNUMBER_LOWORD + 3)
          {
            //modbus_send_byte( zero, CRC_NO);
            pBuf[index++] = zero;
            pBuf[index++] =  ttt[ i + address - MODBUS_SERIALNUMBER_LOWORD];
          }
          else if( i + address == MODBUS_FIRMWARE_VERSION_NUMBER_LO)
          {
            pBuf[index++] = zero;
            pBuf[index++] = ttt[4];
          }
          else if( i + address == MODBUS_FIRMWARE_VERSION_NUMBER_HI)
          {
            pBuf[index++] = zero;
            pBuf[index++] = ttt[5];
          }
          else if( i + address == MODBUS_ADDRESS)
          {
            pBuf[index++] = zero;
            pBuf[index++] = modbus_id;
          }
          else if( i + address == MODBUS_PRODUCT_ID)
          {
            pBuf[index++] = zero;
            pBuf[index++] = 210;
          }
          // System UTC Time
          else if( i + address == MODBUS_SYS_HOUR)
          {
            pBuf[index++] = zero;
            pBuf[index++] = utcTime.hour;
          }
          else if( i + address == MODBUS_SYS_MINUTES)
          {
            pBuf[index++] = zero;
            pBuf[index++] = utcTime.minutes;          
          }
          else if( i + address == MODBUS_SYS_SECONDS)
          {
            pBuf[index++] = zero;
            pBuf[index++] = utcTime.seconds;
          }
          else if( i + address == MODBUS_SYS_MONTH)
          {
            tempByte = utcTime.month + 1;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_SYS_DAY)
          {
            tempByte = utcTime.day + 1;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_SYS_YEAR)
          {
            tempByte = HI_UINT16( utcTime.year);
            pBuf[index++] = tempByte;
            tempByte = LO_UINT16( utcTime.year);
            pBuf[index++] = tempByte;
          }
          /*else if( i + address == MODBUS_WATER_SWITCH)
          {
            if(leaveTimeCounter){
              tempByte = water_switch;
              //leaveTimeCounter=0;
            }
            else
              tempByte = zero;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_DETECT_POWER)
          {
            uint16 power_temp;
            if(leaveTimeCounter){
              power_temp = (ad_power-196)*10/10.57+90;//(ad_power-186)*100/74+90;//((ad_power-644)*64)/100+70;
              //leaveTimeCounter = 0;
            }else
              power_temp = 0;
            
            tempByte = HI_UINT16( power_temp);
            pBuf[index++] = tempByte;
            tempByte = LO_UINT16( power_temp);
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_WATER_ID)
          {
            if(leaveTimeCounter){
              tempByte = water_id;
              //leaveTimeCounter=0;
            }
            else
              tempByte = zero;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_WATER_RSSI)
          {
            if(leaveTimeCounter){
              tempByte = (uint8)water_rssi;
              
            }
            else
              tempByte = zero;
            pBuf[index++] = 255;
            pBuf[index++] = tempByte;
          }
          
          else if( i + address == MODBUS_WATER_SWITCH1)
          {
            if(leaveTimeCounter1){
              tempByte = water_switch1;
              //leaveTimeCounter=0;
            }
            else
              tempByte = zero;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_DETECT_POWER1)
          {
            uint16 power_temp;
            if(leaveTimeCounter1){
              power_temp = (ad_power1-196)*10/10.57+90;//(ad_power-186)*100/74+90;//((ad_power-644)*64)/100+70;
              //leaveTimeCounter = 0;
            }else
              power_temp = 0;
            
            tempByte = HI_UINT16( power_temp);
            pBuf[index++] = tempByte;
            tempByte = LO_UINT16( power_temp);
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_WATER_ID1)
          {
            if(leaveTimeCounter1){
              tempByte = water_id1;
              //leaveTimeCounter=0;
            }
            else
              tempByte = zero;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }*/
          else if( i + address == MODBUS_BAUDRATE)
          {
            tempByte = modbus_set_baudrate;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          
          else if( i + address == MODBUS_PANID)
          {
            tempByte = HI_UINT16( _NIB.nwkPanId);
            pBuf[index++] = tempByte;
            tempByte = LO_UINT16( _NIB.nwkPanId);
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_DEVICE_TYPE)
          {
            tempByte = zgDeviceLogicalType;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_CHANNEL_LIST_HI)
          {
            tempByte = BREAK_UINT32(zgDefaultChannelList, 3);
            pBuf[index++] = tempByte;
            tempByte = BREAK_UINT32(zgDefaultChannelList, 2);
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_CHANNEL_LIST_LO)
          {
            tempByte = BREAK_UINT32(zgDefaultChannelList, 1);
            pBuf[index++] = tempByte;
            tempByte = BREAK_UINT32(zgDefaultChannelList, 0);
            pBuf[index++] = tempByte;
          }
          else if( (i + address >= MODBUS_EXTENDED_ADDR_HI) && (i + address <= MODBUS_EXTENDED_ADDR_LO))
          {
            tempByte = aExtendedAddress[ i+address-MODBUS_EXTENDED_ADDR_HI];
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          else if( (i + address >= MODBUS_SECURITY_KEY_START) && (i + address <= MODBUS_SECURITY_KEY_END))
          {
            tempByte = defaultKey[ i+address-MODBUS_SECURITY_KEY_START];
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          /*else if( i + address == MODBUS_DETECT_PIN1)
          {
            uint16 power_temp;
            if(leaveTimeCounter){
              power_temp = detectPin1;
            }else
              power_temp = 0;
            
            tempByte = HI_UINT16( power_temp);
            pBuf[index++] = tempByte;
            tempByte = LO_UINT16( power_temp);
            pBuf[index++] = tempByte;
          }
          else if( i + address == MODBUS_DETECT_PIN2)
          {
            uint16 power_temp;
            if(leaveTimeCounter){
              power_temp = detectPin2;
              //leaveTimeCounter=0;
            }else
              power_temp = 0;
            
            tempByte = HI_UINT16( power_temp);
            pBuf[index++] = tempByte;
            tempByte = LO_UINT16( power_temp);
            pBuf[index++] = tempByte;
          }*/
          else if( i + address == MODBUS_MONITOR_NUM)
          {
            tempByte = numMonitor;
            pBuf[index++] = zero;
            pBuf[index++] = tempByte;
          }
          else if( (i + address >= MODBUS_FIRST_MONITOR_ID) && ( i+ address <= MODBUS_LAST_MONITOR_ID))
          {
            if( i + address == MODBUS_FIRST_MONITOR_ID)
            {
              pTempMonitor = pBoatMonitor;
            }
            else
            {
              pTempMonitor = pBoatMonitor;
              for( uint8 j=0; j<((i+address)-MODBUS_FIRST_MONITOR_ID); j++)
              {
                if(pTempMonitor)
                  pTempMonitor = pTempMonitor->next;
              }
            }
            pBuf[index++]= zero;
            if(pTempMonitor != NULL)
            {
              pBuf[index++]= pTempMonitor->modbus_id;
            }
            else
              pBuf[index++]= zero;
          }
          else if( (i + address >= MODBUS_FIRST_DETECT_POWER) && ( i+ address <= MODBUS_LAST_DETECT_POWER))
          {
            if( i + address == MODBUS_FIRST_DETECT_POWER)
            {
              pTempMonitor = pBoatMonitor;
            }
            else
            {
              pTempMonitor = pBoatMonitor;
              for( uint8 j=0; j<((i+address)-MODBUS_FIRST_DETECT_POWER); j++)
              {
                if(pTempMonitor)
                  pTempMonitor = pTempMonitor->next;
              }
            }
            if(pTempMonitor != NULL)
            { 
              uint16 power_temp;
              power_temp = (pTempMonitor->ad_power-196)*10/10.57+90;
              tempByte = HI_UINT16( power_temp);
              pBuf[index++] = tempByte;
              tempByte = LO_UINT16( power_temp);
              pBuf[index++] = tempByte;
            }
            else
            {
              pBuf[index++]= zero;
              pBuf[index++]= zero;
            }
          }
          else if( (i + address >= MODBUS_FIRST_WATER_SWITCH) && ( i+ address <= MODBUS_LAST_WATER_SWITCH))
          {
            if( i + address == MODBUS_FIRST_WATER_SWITCH)
            {
              pTempMonitor = pBoatMonitor;
            }
            else
            {
              pTempMonitor = pBoatMonitor;
              for( uint8 j=0; j<((i+address)-MODBUS_FIRST_WATER_SWITCH); j++)
              {
                if(pTempMonitor)
                  pTempMonitor = pTempMonitor->next;
              }
            }
            pBuf[index++]= zero;
            if(pTempMonitor != NULL)
            {
              pBuf[index++]= pTempMonitor->water_switch;
            }
            else
              pBuf[index++]= zero;
          }
          else if((i + address >= MODBUS_FIRST_DETECT_PIN1) && ( i+ address <= MODBUS_LAST_DETECT_PIN1))
          {
            if( i + address == MODBUS_FIRST_DETECT_PIN1)
            {
              pTempMonitor = pBoatMonitor;
            }
            else
            {
              pTempMonitor = pBoatMonitor;
              for( uint8 j=0; j<((i+address)-MODBUS_FIRST_DETECT_PIN1); j++)
              {
                if(pTempMonitor)
                  pTempMonitor = pTempMonitor->next;
              }
            }
            if(pTempMonitor != NULL)
            { 
              tempByte = HI_UINT16( pTempMonitor->detectPin1);
              pBuf[index++] = tempByte;
              tempByte = LO_UINT16( pTempMonitor->detectPin1);
              pBuf[index++] = tempByte;
            }
            else
            {
              pBuf[index++]= zero;
              pBuf[index++]= zero;
            }
          } 
          else if((i + address >= MODBUS_FIRST_DETECT_PIN2) && ( i+ address <= MODBUS_LAST_DETECT_PIN2))
          {
            if( i + address == MODBUS_FIRST_DETECT_PIN2)
            {
              pTempMonitor = pBoatMonitor;
            }
            else
            {
              pTempMonitor = pBoatMonitor;
              for( uint8 j=0; j<((i+address)-MODBUS_FIRST_DETECT_PIN2); j++)
              {
                if(pTempMonitor)
                  pTempMonitor = pTempMonitor->next;
              }
            }
            if(pTempMonitor != NULL)
            { 
              tempByte = HI_UINT16( pTempMonitor->detectPin2);
              pBuf[index++] = tempByte;
              tempByte = LO_UINT16( pTempMonitor->detectPin2);
              pBuf[index++] = tempByte;
            }
            else
            {
              pBuf[index++]= zero;
              pBuf[index++]= zero;
            }
          }
          else if( (i + address >= MODBUS_FIRST_RSSI) && ( i+ address <= MODBUS_LAST_RSSI))
          {
            if( i + address == MODBUS_FIRST_RSSI)
            {
              pTempMonitor = pBoatMonitor;
            }
            else
            {
              pTempMonitor = pBoatMonitor;
              for( uint8 j=0; j<((i+address)-MODBUS_FIRST_RSSI); j++)
              {
                if(pTempMonitor)
                  pTempMonitor = pTempMonitor->next;
              }
            }
            if(pTempMonitor->rssi>=0)
              pBuf[index++] = 0;
            else
              pBuf[index++]= 0xff;
            
            if(pTempMonitor != NULL)
            {
              pBuf[index++]= pTempMonitor->rssi;
            }
            else
              pBuf[index++]= zero;
          }
          
          
          else
          {
            pBuf[index++] = zero;
            pBuf[index++] = zero;
          }
        }
        for( i=0; i<num*2+3; i++)
          CRC16_byte(pBuf[i]);
        pBuf[num*2+3] = CRChi;
        pBuf[num*2+4] = CRClo;
        P1_0 = 1;
        send_str_Uart( pBuf, num*2+5, 0);
        P1_0 = 0;
        osal_mem_free(pBuf);
      }
      else{
        send_str_Uart( pBuf, num*2+5, 0);
      }
    }
  }
}
コード例 #19
0
ファイル: zcl_diagnostic.c プロジェクト: comword/SmartIR-8051
/*********************************************************************
 * @fn      zclDiagnostic_ReadWriteAttrCB
 *
 * @brief   Handle Diagnostics attributes.
 *
 * @param   clusterId - cluster that attribute belongs to
 * @param   attrId - attribute to be read or written
 * @param   oper - ZCL_OPER_LEN, ZCL_OPER_READ, or ZCL_OPER_WRITE
 * @param   pValue - pointer to attribute value, OTA endian
 * @param   pLen - length of attribute value read, native endian
 *
 * @return  status
 */
ZStatus_t zclDiagnostic_ReadWriteAttrCB( uint16 clusterId, uint16 attrId, uint8 oper,
                                         uint8 *pValue, uint16 *pLen )
{
  ZStatus_t status = ZSuccess;
  uint16 tempAttr;
  uint32 attrValue;
  afIncomingMSGPacket_t *origPkt;

  origPkt = zcl_getRawAFMsg();

  switch ( oper )
  {
    case ZCL_OPER_LEN:
      if ( ( attrId == ATTRID_DIAGNOSTIC_LAST_MESSAGE_LQI ) ||
           ( attrId == ATTRID_DIAGNOSTIC_LAST_MESSAGE_RSSI ) )
      {
        *pLen = 1;
      }
      else if ( attrId == ATTRID_DIAGNOSTIC_AVERAGE_MAC_RETRY_PER_APS_MESSAGE_SENT )
      {
        *pLen = 2;
      }
      // The next function call only returns the length for attributes that are defined
      // in lower layers
      else if ( zclDiagnostic_GetAttribData( attrId, &tempAttr, pLen ) != ZSuccess )
      {
        *pLen = 0;
        status = ZFailure;  // invalid length
      }
      break;

    case ZCL_OPER_READ:
      // Identify if incoming msg is LQI or RSSI attribute
      // and return the LQI and RSSI of the incoming values
      if ( attrId == ATTRID_DIAGNOSTIC_LAST_MESSAGE_LQI )
      {
        *pLen = 1;
        attrValue = origPkt->LinkQuality;
      }
      else if ( attrId == ATTRID_DIAGNOSTIC_LAST_MESSAGE_RSSI )
      {
        //origPkt = zcl_getRawAFMsg();
        *pLen = 1;
        attrValue = origPkt->rssi;
      }
      else if ( zclDiagnostic_GetStatsAttr( attrId, &attrValue, pLen ) == ZSuccess )
      {
        if ( ( attrId == ATTRID_DIAGNOSTIC_MAC_TX_UCAST_RETRY ) ||
             ( attrId == ATTRID_DIAGNOSTIC_MAC_TX_UCAST_FAIL  ) )
        {
          // The lower layer counter is a 32 bit counter, report the higher 16 bit value
          // util the lower layer counter wraps-up
          if ( attrValue > 0x0000FFFF )
          {
            attrValue = 0x0000FFFF;
          }
        }
      }
      else
      {
        *pLen = 0;
        status = ZFailure;  // invalid attribute
      }

      if ( *pLen == 1 )
      {
        pValue[0] = BREAK_UINT32( attrValue, 0 );
      }
      else if ( *pLen == 2 )
      {
        pValue[0] = LO_UINT16( attrValue );
        pValue[1] = HI_UINT16( attrValue );
      }
      else if ( *pLen == 4 )
      {
        pValue[0] = BREAK_UINT32( attrValue, 0 );
        pValue[1] = BREAK_UINT32( attrValue, 1 );
        pValue[2] = BREAK_UINT32( attrValue, 2 );
        pValue[3] = BREAK_UINT32( attrValue, 3 );
      }

      break;

    case ZCL_OPER_WRITE:
      status = ZFailure;  // All attributes in Diagnostics cluster are READ ONLY
      break;
  }

  return ( status );
}
コード例 #20
0
ファイル: MT_DEBUG.c プロジェクト: Daan1992/WSN-Lab
/***************************************************************************************************
 * @fn      MT_DebugMacDataDump
 *
 * @brief   Process the debug MAC Data Dump request.
 *
 * @param   pBuf - pointer to received buffer
 *
 * @return  void
 ***************************************************************************************************/
static void MT_DebugMacDataDump(void)
{
  uint8 buf[sizeof(mtDebugMacDataDump_t)];
  uint8 *pBuf = buf;

#ifdef FEATURE_PACKET_FILTER_STATS
  *pBuf++ = BREAK_UINT32(nwkInvalidPackets, 0);
  *pBuf++ = BREAK_UINT32(nwkInvalidPackets, 1);
  *pBuf++ = BREAK_UINT32(nwkInvalidPackets, 2);
  *pBuf++ = BREAK_UINT32(nwkInvalidPackets, 3);
  *pBuf++ = BREAK_UINT32(rxCrcFailure, 0);
  *pBuf++ = BREAK_UINT32(rxCrcFailure, 1);
  *pBuf++ = BREAK_UINT32(rxCrcFailure, 2);
  *pBuf++ = BREAK_UINT32(rxCrcFailure, 3);
  *pBuf++ = BREAK_UINT32(rxCrcSuccess, 0);
  *pBuf++ = BREAK_UINT32(rxCrcSuccess, 1);
  *pBuf++ = BREAK_UINT32(rxCrcSuccess, 2);
  *pBuf++ = BREAK_UINT32(rxCrcSuccess, 3);
#endif
#if defined MAC_RADIO_CC2520
  *pBuf++ = macSpiReadReg(FSMSTAT0);
  *pBuf++ = macSpiReadReg(FSMSTAT1);
#else
  *pBuf++ = FSMSTAT0;
  *pBuf++ = FSMSTAT1;
#endif
  *pBuf++ = macData.rxCount;
  *pBuf++ = macData.directCount;
  *pBuf++ = macMain.state;
  *pBuf++ = macRxActive;
  *pBuf   = macTxActive;

  MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_DBG),
                                       MT_DEBUG_MAC_DATA_DUMP, sizeof(buf), buf);
}
コード例 #21
0
/*********************************************************************
 * @fn      zclApplianceStatistics_LogNotification_NativeToOta
 *
 * @brief   Converts from native to OTA format.
 *
 * @param   disableDefaultRsp - whether to disable the Default Response command
 * @param   pZclPayloadLen - returns zcl payload len
 *
 * @return  pointer to zcl payload
*/
uint8 *zclApplianceStatistics_LogNotification_NativeToOta( zclCmdApplianceStatisticsLogNotificationPayload_t *pPayload , uint16 * pZclPayloadLen )
{
  uint8 *pZclPayload;      // OTA ZCL payload
  uint16 zclPayloadLen;    // OTA ZCL payload length
  uint16 i;

  // get a buffer large enough to hold the whole packet
  zclPayloadLen = 12 + (uint16)( pPayload->logLength );   // 12=sizeof(TimeStamp) + sizeof(LogID) + sizeof(LogLength)
  pZclPayload = zcl_mem_alloc( zclPayloadLen );
  if( !pZclPayload )
    return NULL;  // no memory

  // convert from Native to OTA format
  pZclPayload[0] = BREAK_UINT32(pPayload->timeStamp, 0);
  pZclPayload[1] = BREAK_UINT32(pPayload->timeStamp, 1);
  pZclPayload[2] = BREAK_UINT32(pPayload->timeStamp, 2);
  pZclPayload[3] = BREAK_UINT32(pPayload->timeStamp, 3);
  pZclPayload[4] = BREAK_UINT32(pPayload->logID, 0);
  pZclPayload[5] = BREAK_UINT32(pPayload->logID, 1);
  pZclPayload[6] = BREAK_UINT32(pPayload->logID, 2);
  pZclPayload[7] = BREAK_UINT32(pPayload->logID, 3);
  pZclPayload[8] = BREAK_UINT32(pPayload->logLength, 0);
  pZclPayload[9] = BREAK_UINT32(pPayload->logLength, 1);
  pZclPayload[10] = BREAK_UINT32(pPayload->logLength, 2);
  pZclPayload[11] = BREAK_UINT32(pPayload->logLength, 3);
  for( i = 0; i < pPayload->logLength; ++i )
    pZclPayload[12 + i] = pPayload->pLogPayload[i];

  // return payload and length
  *pZclPayloadLen = zclPayloadLen;
  return pZclPayload;
}
コード例 #22
0
ファイル: MT_AF.c プロジェクト: 12019/hellowsn
/***************************************************************************************************
 * @fn          MT_AfIncomingMsg
 *
 * @brief       Process the callback subscription for AF Incoming data.
 *
 * @param       pkt - Incoming AF data.
 *
 * @return      none
 ***************************************************************************************************/
void MT_AfIncomingMsg(afIncomingMSGPacket_t *pMsg)
{
  uint8 dataLen = pMsg->cmd.DataLength;  /* Length of the data section in the response packet */
  uint8 respLen = 17 + dataLen;          /* Length of the whole response packet */
  uint8 cmd = MT_AF_INCOMING_MSG;
  uint8 *pRsp, *tempPtr;

#if defined INTER_PAN
  if (StubAPS_InterPan(pMsg->srcAddr.panId, pMsg->srcAddr.endPoint))
  {
    cmd = MT_AF_INCOMING_MSG_EXT;
  }
  else
#endif
  if (pMsg->srcAddr.addrMode == afAddr64Bit)
  {
    cmd = MT_AF_INCOMING_MSG_EXT;
  }

  if (cmd == MT_AF_INCOMING_MSG_EXT)
  {
    respLen += 9;
  }

  // Attempt to allocate memory for the response packet.
  if ((pRsp = osal_mem_alloc(respLen)) == NULL)
  {
    return;
  }
  tempPtr = pRsp;

  /* Fill in the data */

  /* Group ID */
  *tempPtr++ = LO_UINT16(pMsg->groupId);
  *tempPtr++ = HI_UINT16(pMsg->groupId);

  /* Cluster ID */
  *tempPtr++ = LO_UINT16(pMsg->clusterId);
  *tempPtr++ = HI_UINT16(pMsg->clusterId);

  if (cmd == MT_AF_INCOMING_MSG_EXT)
  {
    *tempPtr++ = pMsg->srcAddr.addrMode;

    if (pMsg->srcAddr.addrMode == afAddr64Bit)
    {
      (void)osal_memcpy(tempPtr, pMsg->srcAddr.addr.extAddr, Z_EXTADDR_LEN);
    }
    else
    {
      tempPtr[0] = LO_UINT16(pMsg->srcAddr.addr.shortAddr);
      tempPtr[1] = HI_UINT16(pMsg->srcAddr.addr.shortAddr);
    }
    tempPtr += Z_EXTADDR_LEN;

    *tempPtr++ = pMsg->srcAddr.endPoint;
#if defined INTER_PAN
    *tempPtr++ = LO_UINT16(pMsg->srcAddr.panId);
    *tempPtr++ = HI_UINT16(pMsg->srcAddr.panId);
#else
    *tempPtr++ = 0;
    *tempPtr++ = 0;
#endif
  }
  else
  {
    /* Source Address */
    *tempPtr++ = LO_UINT16(pMsg->srcAddr.addr.shortAddr);
    *tempPtr++ = HI_UINT16(pMsg->srcAddr.addr.shortAddr);

    /* Source EP */
    *tempPtr++ = pMsg->srcAddr.endPoint;
  }

  /* Destination EP */
  *tempPtr++ = pMsg->endPoint;

  /* WasBroadCast */
  *tempPtr++ = pMsg->wasBroadcast;

  /* LinkQuality */
  *tempPtr++ = pMsg->LinkQuality;

  /* SecurityUse */
  *tempPtr++ = pMsg->SecurityUse;

  /* Timestamp */
  *tempPtr++ = BREAK_UINT32(pMsg->timestamp, 0);
  *tempPtr++ = BREAK_UINT32(pMsg->timestamp, 1);
  *tempPtr++ = BREAK_UINT32(pMsg->timestamp, 2);
  *tempPtr++ = BREAK_UINT32(pMsg->timestamp, 3);

  /* Transmit Sequence Number */
  *tempPtr++ = pMsg->cmd.TransSeqNumber;

  /* Data Length */
  *tempPtr++ = dataLen;

  /* Data */
  if (dataLen)
  {
    osal_memcpy(tempPtr, pMsg->cmd.Data, dataLen);
  }

  /* Build and send back the response */
  MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ|(uint8)MT_RPC_SYS_AF), cmd, respLen, pRsp);

  /* Free memory */
  osal_mem_free(pRsp);
}
コード例 #23
0
/***************************************************************************************************
 * @fn      MT_UtilGetNvInfo
 *
 * @brief   The Get NV Info serial message.
 *
 * @param   None.
 *
 * @return  void
 ***************************************************************************************************/
void MT_UtilGetNvInfo(void)
{
  uint8 len;
  uint8 stat;
  uint8 *buf;
  uint8 *pBuf;
  uint16 tmp16;
  uint32 tmp32;

  /*
    Get required length of buffer
    Status + ExtAddr + ChanList + PanID  + SecLevel + PreCfgKey
  */
  len = 1 + Z_EXTADDR_LEN + 4 + 2 + 1 + SEC_KEY_LEN;

  buf = osal_mem_alloc( len );
  if ( buf )
  {
    /* Assume NV not available */
    osal_memset( buf, 0xFF, len );

    /* Skip over status */
    pBuf = buf + 1;

    /* Start with 64-bit extended address */
    stat = osal_nv_read( ZCD_NV_EXTADDR, 0, Z_EXTADDR_LEN, pBuf );
    if ( stat ) stat = 0x01;
    pBuf += Z_EXTADDR_LEN;

    /* Scan channel list (bit mask) */
    if (  osal_nv_read( ZCD_NV_CHANLIST, 0, sizeof( tmp32 ), &tmp32 ) )
      stat |= 0x02;
    else
    {
      pBuf[0] = BREAK_UINT32( tmp32, 3 );
      pBuf[1] = BREAK_UINT32( tmp32, 2 );
      pBuf[2] = BREAK_UINT32( tmp32, 1 );
      pBuf[3] = BREAK_UINT32( tmp32, 0 );
    }
    pBuf += sizeof( tmp32 );

    /* ZigBee PanID */
    if ( osal_nv_read( ZCD_NV_PANID, 0, sizeof( tmp16 ), &tmp16 ) )
      stat |= 0x04;
    else
    {
      pBuf[0] = LO_UINT16( tmp16 );
      pBuf[1] = HI_UINT16( tmp16 );
    }
    pBuf += sizeof( tmp16 );

    /* Security level */
    if ( osal_nv_read( ZCD_NV_SECURITY_LEVEL, 0, sizeof( uint8 ), pBuf++ ) )
      stat |= 0x08;

    /* Pre-configured security key */
    if ( osal_nv_read( ZCD_NV_PRECFGKEY, 0, SEC_KEY_LEN, pBuf ) )
      stat |= 0x10;

    /* Status bit mask - bit=1 indicates failure */
    *buf = stat;

    MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), MT_UTIL_GET_NV_INFO,
                                  len, buf );

    osal_mem_free( buf );
  }
}
コード例 #24
0
/*********************************************************************
 * @fn      sensorMeasNotify
 *
 * @brief   Prepare and send a RSC measurement notification
 *
 * @return  none
 */
static void sensorMeasNotify(void)
{
  static uint16 centimeters = 0;
  uint8 *p = sensorMeas.value;
  uint8 flags = sensorFlags[sensorFlagsIdx];

  switch( motion )
  {
    case STANDING_STILL:
      instSpeed = instCadence = instStrideLength =  STANDING_STILL;
      // 0 for walking bit
      flags = flags & 0xFB; //0b1111 1011
      break;

    case WALKING_MOTION:
      instStrideLength = STRIDE_LENGTH_WALKING;
      instCadence = WALKING_CADENCE;
      instSpeed = WALKING_SPEED;
      // 0 for walking bit
      flags = flags & 0xFB;
      break;

    case RUNNING_MOTION:
      instStrideLength = STRIDE_LENGTH_RUNNING;
      instCadence = RUNNING_CADENCE;
      instSpeed = RUNNING_SPEED;
      // set in 1 for walking bit.
      flags = flags | 0x04;
      break;

    default: // Do nothing
      break;
  }

  // Add distance
  centimeters += (uint16)DISTANCE_TRAVELED( instSpeed );

  // If traveled at least a meter
  if ( centimeters >= 100 )
  {
    // add distance, truncated to meters
    totalDistance += (centimeters / 100);
    // and continue to store the remaining centimeters
    centimeters %= 100;
  }

  // Build RSC measurement structure from simulated values
  // Flags simulate the isPresent bits.
  *p++ = flags;

  //Included regardless of flags.
  *p++ = LO_UINT16( instSpeed );
  *p++ = HI_UINT16( instSpeed );
  *p++ = instCadence;

  if (flags & RSC_FLAGS_STRIDE)
  {
    *p++ = LO_UINT16( instStrideLength );
    *p++ = HI_UINT16( instStrideLength );
  }

  if (flags & RSC_FLAGS_DIST)
  {
    *p++ = BREAK_UINT32(totalDistance, 0);
    *p++ = BREAK_UINT32(totalDistance, 1);
    *p++ = BREAK_UINT32(totalDistance, 2);
    *p++ = BREAK_UINT32(totalDistance, 3);
  }

  // Get length
  sensorMeas.len = (uint8) (p - sensorMeas.value);

  // Send to service to send the notification
  Running_MeasNotify( gapConnHandle, &sensorMeas );
}
コード例 #25
0
/***************************************************************************************************
 * @fn          MT_AfIncomingMsg
 *
 * @brief       Process the callback subscription for AF Incoming data.
 *
 * @param       pkt - Incoming AF data.
 *
 * @return      none
 ***************************************************************************************************/
void MT_AfIncomingMsg(afIncomingMSGPacket_t *pMsg)
{
  #define MT_AF_INC_MSG_LEN  17
  #define MT_AF_INC_MSG_EXT  10

  uint16 dataLen = pMsg->cmd.DataLength;  // Length of the data section in the response packet.
  uint16 respLen = MT_AF_INC_MSG_LEN + dataLen;
  uint8 cmd = MT_AF_INCOMING_MSG;
  uint8 *pRsp, *pTmp;
  mtAfInMsgList_t *pItem = NULL;

#if defined INTER_PAN
  if (StubAPS_InterPan(pMsg->srcAddr.panId, pMsg->srcAddr.endPoint))
  {
    cmd = MT_AF_INCOMING_MSG_EXT;
  }
  else
#endif
  if ((pMsg->srcAddr.addrMode == afAddr64Bit) ||
      (respLen > (uint16)(MT_RPC_DATA_MAX - MT_AF_INC_MSG_EXT)))
  {
    cmd = MT_AF_INCOMING_MSG_EXT;
  }

  if (cmd == MT_AF_INCOMING_MSG_EXT)
  {
    respLen += MT_AF_INC_MSG_EXT;
  }

  if (respLen > (uint16)MT_RPC_DATA_MAX)
  {
    if ((pItem = (mtAfInMsgList_t *)osal_mem_alloc(sizeof(mtAfInMsgList_t) + dataLen)) == NULL)
    {
      return;  // If cannot hold a huge message, cannot give indication at all.
    }

    pItem->data = (uint8 *)(pItem+1);
    respLen -= dataLen;  // Zero data bytes are sent with an over-sized incoming indication.
  }

  // Attempt to allocate memory for the response packet.
  if ((pRsp = osal_mem_alloc(respLen)) == NULL)
  {
    if (pItem != NULL)
    {
      (void)osal_mem_free(pItem);
    }
    return;
  }
  pTmp = pRsp;

  /* Group ID */
  *pTmp++ = LO_UINT16(pMsg->groupId);
  *pTmp++ = HI_UINT16(pMsg->groupId);

  /* Cluster ID */
  *pTmp++ = LO_UINT16(pMsg->clusterId);
  *pTmp++ = HI_UINT16(pMsg->clusterId);

  if (cmd == MT_AF_INCOMING_MSG_EXT)
  {
    *pTmp++ = pMsg->srcAddr.addrMode;

    if (pMsg->srcAddr.addrMode == afAddr64Bit)
    {
      (void)osal_memcpy(pTmp, pMsg->srcAddr.addr.extAddr, Z_EXTADDR_LEN);
    }
    else
    {
      pTmp[0] = LO_UINT16(pMsg->srcAddr.addr.shortAddr);
      pTmp[1] = HI_UINT16(pMsg->srcAddr.addr.shortAddr);
    }
    pTmp += Z_EXTADDR_LEN;

    *pTmp++ = pMsg->srcAddr.endPoint;
#if defined INTER_PAN
    *pTmp++ = LO_UINT16(pMsg->srcAddr.panId);
    *pTmp++ = HI_UINT16(pMsg->srcAddr.panId);
#else
    *pTmp++ = 0;
    *pTmp++ = 0;
#endif
  }
  else
  {
    /* Source Address */
    *pTmp++ = LO_UINT16(pMsg->srcAddr.addr.shortAddr);
    *pTmp++ = HI_UINT16(pMsg->srcAddr.addr.shortAddr);

    /* Source EP */
    *pTmp++ = pMsg->srcAddr.endPoint;
  }

  /* Destination EP */
  *pTmp++ = pMsg->endPoint;

  /* WasBroadCast */
  *pTmp++ = pMsg->wasBroadcast;

  /* LinkQuality */
  *pTmp++ = pMsg->LinkQuality;

  /* SecurityUse */
  *pTmp++ = pMsg->SecurityUse;

  /* Timestamp */
  *pTmp++ = BREAK_UINT32(pMsg->timestamp, 0);
  *pTmp++ = BREAK_UINT32(pMsg->timestamp, 1);
  *pTmp++ = BREAK_UINT32(pMsg->timestamp, 2);
  *pTmp++ = BREAK_UINT32(pMsg->timestamp, 3);


  /* Data Length */
  if (cmd == MT_AF_INCOMING_MSG_EXT)
  {
    /* Z-Tool apparently takes the last Byte before the data buffer as the dynamic length and
     * ignores the bigger UInt16 length of an EXT incoming message. But no data bytes will be sent
     * with a huge message, so it's necessary to work-around and fake-out Z-Tool with a zero here.
     */
    *pTmp++ = 0;  // TODO - workaround Z-Tool shortcoming; should be: = pMsg->cmd.TransSeqNumber;
    *pTmp++ = LO_UINT16(dataLen);
    *pTmp++ = HI_UINT16(dataLen);
  }
  else
  {
    *pTmp++ = pMsg->cmd.TransSeqNumber;
    *pTmp++ = dataLen;
  }

  /* Data */
  if (pItem != NULL)
  {
    // Enqueue the new huge incoming item.
    pItem->next = pMtAfInMsgList;
    pMtAfInMsgList = pItem;

    // Setup to time-out the huge incoming item if host does not MT_AF_DATA_RETRIEVE it.
    pItem->tick = MT_AF_EXEC_CNT;
    if (ZSuccess != osal_start_timerEx(MT_TaskID, MT_AF_EXEC_EVT, MT_AF_EXEC_DLY))
    {
      (void)osal_set_event(MT_TaskID, MT_AF_EXEC_EVT);
    }

    pItem->timestamp = pMsg->timestamp;
    (void)osal_memcpy(pItem->data, pMsg->cmd.Data, dataLen);
  }
  else
  {
    (void)osal_memcpy(pTmp, pMsg->cmd.Data, dataLen);
  }

  /* Build and send back the response */
  MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ|(uint8)MT_RPC_SYS_AF), cmd, respLen, pRsp);

  (void)osal_mem_free(pRsp);
}
コード例 #26
0
/*********************************************************************
 * @fn      RunningSensor_measNotify
 *
 * @brief   Prepare and send a RSC measurement notification.
 *
 * @param   none
 *
 * @return  none
 */
static void RunningSensor_measNotify(void)
{
  static uint16_t centimeters = 0;
  attHandleValueNoti_t sensorMeas;

  sensorMeas.pValue = GATT_bm_alloc(gapConnHandle, ATT_HANDLE_VALUE_NOTI, 
                                    RSC_MEAS_LEN, NULL);
  if (sensorMeas.pValue != NULL)
  {
    uint8_t *p = sensorMeas.pValue;
    uint8_t flags = sensorFlags[sensorFlagsIdx];

    switch(motion)
    {
      case STANDING_STILL:
        instSpeed = instCadence = instStrideLength = STANDING_STILL;
        
        // 0 for walking bit.
        flags = flags & 0xFB; // 0b1111 1011
        break;

      case WALKING_MOTION:
        instStrideLength = STRIDE_LENGTH_WALKING;
        instCadence = WALKING_CADENCE;
        instSpeed = WALKING_SPEED;
        
        // 0 for walking bit.
        flags = flags & 0xFB;
        break;

      case RUNNING_MOTION:
        instStrideLength = STRIDE_LENGTH_RUNNING;
        instCadence = RUNNING_CADENCE;
        instSpeed = RUNNING_SPEED;
        
        // set in 1 for walking bit.
        flags = flags | 0x04;
        break;

      default: 
        // Do nothing.
        break;
    }

    // Add distance.
    centimeters += (uint16_t)DISTANCE_TRAVELED(instSpeed);

    // If travelled at least a meter
    if (centimeters >= 100)
    {
      // Add distance, truncated to meters.
      totalDistance += (centimeters / 100);
      
      // And continue to store the remaining centimeters.
      centimeters %= 100;
    }

    // Build RSC measurement structure from simulated values
    // Flags simulate the isPresent bits.
    *p++ = flags;

    // Included regardless of flags.
    *p++ = LO_UINT16(instSpeed);
    *p++ = HI_UINT16(instSpeed);
    *p++ = instCadence;

    if (flags & RSC_FLAGS_STRIDE)
    {
      *p++ = LO_UINT16(instStrideLength);
      *p++ = HI_UINT16(instStrideLength);
    }

    if (flags & RSC_FLAGS_DIST)
    {
      *p++ = BREAK_UINT32(totalDistance, 0);
      *p++ = BREAK_UINT32(totalDistance, 1);
      *p++ = BREAK_UINT32(totalDistance, 2);
      *p++ = BREAK_UINT32(totalDistance, 3);
    }

    // Get length.
    sensorMeas.len = (uint8_t)(p - sensorMeas.pValue);

    // Send to service to send the notification.
    if (RunningService_measNotify(gapConnHandle, &sensorMeas) != SUCCESS)
    {
      GATT_bm_free((gattMsg_t *)&sensorMeas, ATT_HANDLE_VALUE_NOTI);
    }
  }
}