예제 #1
0
/*********************************************************************
 * @fn      GenericApp_ProcessRtosMessage
 *
 * @brief   Receive message from RTOS queue, send response back.
 *
 * @param   none
 *
 * @return  none
 */
static void GenericApp_ProcessRtosMessage( void )
{
  osalQueue_t inMsg;

  if ( osal_queue_receive( OsalQueue, &inMsg, 0 ) == pdPASS )
  {
    uint8 cmndId = inMsg.cmnd;
    uint32 counter = osal_build_uint32( inMsg.cbuf, 4 );

    switch ( cmndId )
    {
      case CMD_INCR:
        counter += 1;  /* Increment the incoming counter */
                       /* Intentionally fall through next case */

      case CMD_ECHO:
      {
        userQueue_t outMsg;

        outMsg.resp = RSP_CODE | cmndId;  /* Response ID */
        osal_buffer_uint32( outMsg.rbuf, counter );    /* Increment counter */
        osal_queue_send( UserQueue1, &outMsg, 0 );  /* Send back to UserTask */
        break;
      }
      
      default:
        break;  /* Ignore unknown command */    
    }
  }
}
예제 #2
0
/*********************************************************************
 * @fn      thermometerMeasIndicate
 *
 * @brief   Prepare and send a thermometer measurement notification
 *
 * @return  none
 */
static void thermometerMeasIndicate(void)
{

    // att value notification structure
    uint8 *p = thermometerMeas.value;

    // temperature
    uint32 temperature;

    //flags
    uint8 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;

    //osal_buffer_uint32
    osal_buffer_uint32( p, temperature );

    //temperature is 4 bytes long
    *p++;
    *p++;
    *p++;
    *p++;

    //timestamp
    if (flags & THERMOMETER_FLAGS_TIMESTAMP)
    {

        UTCTimeStruct time;

        // Get time structure from OSAL
        osal_ConvertUTCTime( &time, osal_getClock() );

        *p++ = (time.year & 0x00FF);
        *p++ = (time.year & 0xFF00)>>8;
        //*p++ = time.year;
        //*p++;

        *p++=time.month;
        *p++=time.day;
        *p++=time.hour;
        *p++=time.minutes;
        *p++=time.seconds;
    }
/***************************************************************************************************
 * @fn      MT_SysGetUtcTime
 *
 * @brief   Get the OSAL UTC time
 *
 * @param   None
 *
 * @return  32-bit and Parsed UTC time
 ***************************************************************************************************/
void MT_SysGetUtcTime(void)
{
  uint8 len;
  uint8 *buf;

  len = sizeof( UTCTime ) + sizeof( UTCTimeStruct );

  buf = osal_mem_alloc( len );
  if ( buf )
  {
    uint8 *pBuf;
    UTCTime utcSecs;
    UTCTimeStruct utcTime;

    // Get current 32-bit UTC time and parse it
    utcSecs = osal_getClock();
    osal_ConvertUTCTime( &utcTime, utcSecs );

    // Start with 32-bit UTC time
    pBuf = osal_buffer_uint32( buf, utcSecs );

    // Concatenate parsed UTC time fields
    *pBuf++ = utcTime.hour;
    *pBuf++ = utcTime.minutes;
    *pBuf++ = utcTime.seconds;
    *pBuf++ = utcTime.month + 1;  // Convert to human numbers
    *pBuf++ = utcTime.day + 1;
    *pBuf++ = LO_UINT16( utcTime.year );
    *pBuf++ = HI_UINT16( utcTime.year );

    /* Build and send back the response */
    MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS),
                                   MT_SYS_GET_TIME, (uint8)(pBuf-buf), buf);

    osal_mem_free( buf );
  }
}
예제 #4
0
/*********************************************************************
 * @fn      thermometerMeasIndicate
 *
 * @brief   Prepare and send a thermometer measurement indication
 *
 * @return  none
 */
static void thermometerMeasIndicate(void)
{
    // Thermometer measurement value stored in this structure.
    attHandleValueInd_t thermometerMeas;

    thermometerMeas.pValue = GATT_bm_alloc(gapConnHandle,
                                           ATT_HANDLE_VALUE_IND,
                                           THERMOMETER_MEAS_LEN, NULL);
    if (thermometerMeas.pValue != NULL)
    {
        // att value notification structure
        uint8 *p = thermometerMeas.pValue;

        // temperature
        uint32 temperature;

        //flags
        uint8 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;

        //osal_buffer_uint32
        p = osal_buffer_uint32( p, temperature );

        //timestamp
        if (flags & THERMOMETER_FLAGS_TIMESTAMP)
        {
            UTCTimeStruct time;

            // Get time structure from OSAL
            osal_ConvertUTCTime( &time, osal_getClock() );

            *p++ = LO_UINT16(time.year);
            *p++ = HI_UINT16(time.year);
            *p++ = time.month;
            *p++ = time.day;
            *p++ = time.hour;
            *p++ = time.minutes;
            *p++ = time.seconds;
        }

        if(flags & THERMOMETER_FLAGS_TYPE)
        {
            uint8 site;
            Thermometer_GetParameter( THERMOMETER_TYPE, &site );
            *p++ =  site;
        }

        thermometerMeas.len = (uint8) (p - thermometerMeas.pValue);
        thermometerMeas.handle = THERMOMETER_TEMP_VALUE_POS;

        // Queue indication.
        thermometerStoreIndications( &thermometerMeas);

        //advertise measurement is ready
        thermometer_Advertise();
    }
}
예제 #5
0
/*********************************************************************
 * @fn      thermometerMeasNotify
 *
 * @brief   Prepare and send a thermometer measurement notification
 *
 * @return  none
 */
static void thermometerImeasNotify(void)
{
    if (temperatureIMeasCharConfig == true)
    {
        attHandleValueNoti_t thermometerIMeas;

        thermometerIMeas.pValue = GATT_bm_alloc( gapConnHandle,
                                  ATT_HANDLE_VALUE_NOTI,
                                  THERMOMETER_IMEAS_LEN, NULL );
        if ( thermometerIMeas.pValue != NULL )
        {
            // att value notification structure
            uint8 *p = thermometerIMeas.pValue;

            // temperature
            uint32 temperature;

            //flags
            uint8 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;

            //osal_buffer_uint32
            p = osal_buffer_uint32( p, temperature );

            //timestamp
            if (flags & THERMOMETER_FLAGS_TIMESTAMP)
            {
                UTCTimeStruct time;

                // Get time structure from OSAL
                osal_ConvertUTCTime( &time, osal_getClock() );

                *p++ = LO_UINT16(time.year);
                *p++ = HI_UINT16(time.year);
                *p++ = time.month;
                *p++ = time.day;
                *p++ = time.hour;
                *p++ = time.minutes;
                *p++ = time.seconds;
            }

            if(flags & THERMOMETER_FLAGS_TYPE)
            {
                uint8 site;
                Thermometer_GetParameter( THERMOMETER_TYPE, &site );
                *p++ =  site;
            }

            thermometerIMeas.len = (uint8) (p - thermometerIMeas.pValue);

            if ( Thermometer_IMeasNotify( gapConnHandle, &thermometerIMeas) != SUCCESS )
            {
                GATT_bm_free( (gattMsg_t *)&thermometerIMeas, ATT_HANDLE_VALUE_NOTI );
            }
        }
    }
}
예제 #6
0
/*********************************************************************
 * @fn      OTA_Send_ReadAttrInd
 *
 * @brief   Notifies the console about attribute values for a device.
 *
 * @param   none.
 *
 * @return  none
 */
void OTA_Send_ReadAttrInd(uint16 cluster, uint16 shortAddr, zclReadRspStatus_t *pAttr)
{
    uint8 buffer[OTA_APP_READ_ATTRIBUTE_IND_LEN];
    uint8 *pBuf = buffer;
    uint8 len;

    *pBuf++ = OTA_SYSAPP_ENDPOINT;
    *pBuf++ = OTA_APP_READ_ATTRIBUTE_IND;

    *pBuf++ = LO_UINT16(_NIB.nwkPanId);
    *pBuf++ = HI_UINT16(_NIB.nwkPanId);

    *pBuf++ = LO_UINT16(cluster);
    *pBuf++ = HI_UINT16(cluster);

    *pBuf++ = LO_UINT16(shortAddr);
    *pBuf++ = HI_UINT16(shortAddr);

    *pBuf++ = LO_UINT16(pAttr->attrID);
    *pBuf++ = HI_UINT16(pAttr->attrID);
    *pBuf++ = pAttr->status;
    *pBuf++ = pAttr->dataType;

    len = zclGetDataTypeLength(pAttr->dataType);

    // We should not be reading attributes greater than 8 bytes in length
    if (len <= 8)
    {
        *pBuf++ = len;

        if (len)
        {
            uint8 *pStr;

            switch ( pAttr->dataType )
            {
            case ZCL_DATATYPE_UINT8:
                *pBuf = *((uint8 *)pAttr->data);
                break;

            case ZCL_DATATYPE_UINT16:
                *pBuf++ = LO_UINT16( *((uint16*)pAttr->data) );
                *pBuf++ = HI_UINT16( *((uint16*)pAttr->data) );
                break;

            case ZCL_DATATYPE_UINT32:
                pBuf = osal_buffer_uint32( pBuf, *((uint32*)pAttr->data) );
                break;

            case ZCL_DATATYPE_IEEE_ADDR:
                pStr = (uint8*)pAttr->data;
                osal_memcpy( pBuf, pStr, 8 );
                break;

            default:
                break;
            }
        }
    }
    else
        *pBuf = 0;

    // Send the indication
    MT_BuildAndSendZToolResponse(MT_RPC_SYS_APP, MT_APP_MSG, OTA_APP_READ_ATTRIBUTE_IND_LEN, buffer);
}
예제 #7
0
/**************************************************************************************************
 * @fn          MT_ZnpBasicRsp
 *
 * @brief       Build and send the ZNP Basic Response to the ZAP.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      true if message built and sent; false otherwise.
 */
bool MT_ZnpBasicRsp(void)
{
  uint8 *pBuf = osal_mem_alloc(sizeof(mt_znp_basic_rsp_t));

  if (pBuf == NULL)
  {
    return false;
  }

  osal_buffer_uint32( &pBuf[0], MT_PeriodicMsgRate );

  osal_buffer_uint32( &pBuf[4], zgDefaultChannelList );

  pBuf[8] = LO_UINT16(zgConfigPANID);
  pBuf[9] = HI_UINT16(zgConfigPANID);

  osal_nv_read(ZCD_NV_STARTUP_OPTION, 0, 1, pBuf+10);
  pBuf[11] = zgDeviceLogicalType;

  pBuf[12] = LO_UINT16(_NIB.nwkDevAddress);
  pBuf[13] = HI_UINT16(_NIB.nwkDevAddress);

  pBuf[14] = LO_UINT16(_NIB.nwkCoordAddress);
  pBuf[15] = HI_UINT16(_NIB.nwkCoordAddress);

  pBuf[16] = LO_UINT16(_NIB.nwkPanId);
  pBuf[17] = HI_UINT16(_NIB.nwkPanId);

  pBuf[18] = _NIB.nwkLogicalChannel;
  pBuf[19] = _NIB.nwkState;

  (void)osal_memcpy(pBuf+20, _NIB.nwkCoordExtAddress, Z_EXTADDR_LEN);
  (void)osal_memcpy(pBuf+28, aExtendedAddress, Z_EXTADDR_LEN);

  pBuf[36] = devState;
#if defined INTER_PAN
  extern uint8 appEndPoint;
  pBuf[37] = appEndPoint;
  //rsp->spare1[2];
#else
  //rsp->spare1[3];
#endif

  // Initialize list with invalid EndPoints.
  (void)osal_memset(pBuf+40, AF_BROADCAST_ENDPOINT, (MT_ZNP_EP_ID_LIST_MAX * 3));
  uint8 idx = 40;
  epList_t *epItem = epList;

  for (uint8 cnt = 0; cnt < MT_ZNP_EP_ID_LIST_MAX; cnt++)
  {
    if (epItem == NULL)
    {
      break;
    }
    if ((epItem->epDesc->simpleDesc != NULL) && (epItem->epDesc->simpleDesc->EndPoint != ZDO_EP))
    {
      pBuf[idx++] = epItem->epDesc->simpleDesc->EndPoint;
      pBuf[idx++] = LO_UINT16(epItem->epDesc->simpleDesc->AppProfId);
      pBuf[idx++] = HI_UINT16(epItem->epDesc->simpleDesc->AppProfId);
    }
    epItem = epItem->nextDesc;
  }
  idx = 40 + (MT_ZNP_EP_ID_LIST_MAX * 3);

  // Initialize list with invalid Cluster Id's.
  (void)osal_memset(pBuf+idx, 0xFF, (MT_ZNP_ZDO_MSG_CB_LIST_MAX * 2));
  typedef struct
  {
    void *next;
    uint8 taskID;
    uint16 clusterID;
  } ZDO_MsgCB_t;
  extern ZDO_MsgCB_t *zdoMsgCBs;
  ZDO_MsgCB_t *pItem = zdoMsgCBs;

  for (uint8 cnt = 0; cnt < MT_ZNP_ZDO_MSG_CB_LIST_MAX; cnt++)
  {
    if (pItem == NULL)
    {
      break;
    }
    else if (pItem->taskID == MT_TaskID)
    {
      pBuf[idx++] = LO_UINT16(pItem->clusterID);
      pBuf[idx++] = HI_UINT16(pItem->clusterID);
    }
    pItem = pItem->next;
  }
  idx = 40 + (MT_ZNP_EP_ID_LIST_MAX * 3) + (MT_ZNP_ZDO_MSG_CB_LIST_MAX * 2);

  extern pfnZdoCb zdoCBFunc[MAX_ZDO_CB_FUNC];
  for (uint8 cnt = 0; cnt < MAX_ZDO_CB_FUNC; cnt++)
  {
    pBuf[idx++] = (zdoCBFunc[cnt] == NULL) ? 0 : 1;
  }

  MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_ZNP), MT_ZNP_BASIC_RSP,
      40 + (MT_ZNP_EP_ID_LIST_MAX * 3) + (MT_ZNP_ZDO_MSG_CB_LIST_MAX * 2) + MAX_ZDO_CB_FUNC, pBuf);
  (void)osal_mem_free(pBuf);

  return true;
}