Beispiel #1
0
/*-------------------- Mgmt_Permit_Joining_req  --------------------

	IN: The package with the request information.

	OUT: The size in bytes of the request payload.
*/
zbSize_t Mgmt_Permit_Joining_req
(
zbMgmtPermitJoiningRequest_t *pMessageComingIn, /*IN The package with the request information.  */
zbNwkAddr_t aDestAddr /* IN: The destination address where to send the request.  */
)
{
zdoNlmeMessage_t * pZdoNlmeMsg;

  /* If the destiantion address is to all awake devices, first turn it on locally and then send it OTA. */
  if(FLib_MemCmp((uint8_t *)gaBroadcastZCnZR, aDestAddr, sizeof(zbNwkAddr_t)))
  {
    /* Do the permit joinig locally as well. */
    pZdoNlmeMsg = MSG_AllocType(zdoNlmeMessage_t);

    /* If we can not set this locally is highly probably that we are not able to send packets OTA. */
    if(pZdoNlmeMsg == NULL)
      return 0;
    if (NlmeGetRequest(gDevType_c) != gEndDevice_c)
    {          
      /* Build the NLME request using the incoming info. */
      BeeUtilZeroMemory(pZdoNlmeMsg,sizeof(zdoNlmeMessage_t ));
      pZdoNlmeMsg->msgData.permitJoiningReq.permitDuration = pMessageComingIn->PermitDuration;
      pZdoNlmeMsg->msgType = gNlmePermitJoiningRequest_c;
      (void)ZDO_NLME_SapHandler(pZdoNlmeMsg);
    }
  }

  /* By returning the size ZDP send out the request. */
  return sizeof(zbMgmtPermitJoiningRequest_t);
}
Beispiel #2
0
/*******************************************************************************
* State machine to send the next report. If it can't get the memory, tries
* again later.
*
* This will concatinate all of the reportable attributes in a single cluster
*******************************************************************************/
void ZCL_SendReport(void)
{
  afDeviceDef_t   *pDevice;
  uint8_t payloadLen;
  uint8_t reportLen;
  afToApsdeMessage_t *pMsg; /* a message for sending the report */
  afAddrInfo_t addrInfo;
  afClusterDef_t *pCluster;
  zclFrame_t  *pFrame;
  uint8_t i;
  zclReportAttr_t *pReportList;
  
  BeeUtilZeroMemory(&addrInfo, sizeof(addrInfo));
  /* starting over? reset indexes */
  if(gfZclReportRestart) {
    gZclReportDeviceIndex = gZclReportClusterIndex = gAsynchronousClusterIndex = 0;
    gfZclReportRestart = FALSE;
  }

  /* get a buffer to build the next report */
  pMsg = AF_MsgAlloc();
  if(!pMsg) {
    gfZclReportRestart = FALSE;
    ZLC_StartShortReportingTimer();
    return;
  }

  /* walk through all devices */
  while(gZclReportDeviceIndex < gNum_EndPoints_c) {

    /* make sure this app endpoint is a ZCL device */
    pDevice = (afDeviceDef_t *) endPointList[gZclReportDeviceIndex].pDevice;
    
    /* report list */
    pReportList = pDevice->pReportList;
    
    if(!pDevice || !pDevice->pfnZCL) {
      ++gZclReportDeviceIndex;
      continue;
    }

    /* Find if any attribute are a asynchronous, then update the attribute */ 
    do
    {
      for(i=0; i<pDevice->reportCount; ++i)
      {
        zclAttrDef_t *pAttrDef;
        zclReportAttr_t *pCurrentReportList = &pReportList[i];
        /* only looking for this one cluster, to see if it's in the reportinglist */
        if(!IsEqual2Bytes(pCurrentReportList->aClusterId, pDevice->pClusterDef[gAsynchronousClusterIndex].aClusterId))
          continue;            
               
        // If the cluster is on the reporting list, find the reporting attribute
        pAttrDef = ZCL_FindAttr(&pDevice->pClusterDef[gAsynchronousClusterIndex], pCurrentReportList->attrId);
        if(pAttrDef)
        {
          /* It's a asynchronous attribute, update before reporting */
          if(ZclAttrIsAsynchronous_c(pAttrDef->flags))
          {
            ++gAsynchronousClusterIndex;
            BeeAppUpdateDevice(0, gZclUI_SendReportingAttributeRequest_c, pAttrDef->id, pCurrentReportList->aClusterId, NULL);
            //Free the message, because we return from here
            MSG_Free(pMsg);
            return;
          }
        }
        
      }
      ++gAsynchronousClusterIndex;
    }while(gAsynchronousClusterIndex < pDevice->clusterCount);

    /* check each cluster for reporting attributes */
    while(gZclReportClusterIndex < pDevice->clusterCount) {

      pCluster = &pDevice->pClusterDef[gZclReportClusterIndex];

      pFrame = (void *)(&((uint8_t *)pMsg)[ApsmeGetAsduOffset()]);

      /* build the report for the next cluster */
      reportLen = ZCL_BuildAttrReport(
        (zclCmdReportAttr_t *)(pFrame + 1),   /* ptr to report frame */
        pDevice,                              /* ptr to device */
        pCluster
        );            

      /* no reporting attributes this cluster */
      if(!reportLen) {
        ++gZclReportClusterIndex;
        continue;
      }

      /* set up the address info */
      addrInfo.dstAddrMode = gZbAddrModeIndirect_c;
      addrInfo.srcEndPoint = endPointList[gZclReportDeviceIndex].pEndpointDesc->pSimpleDesc->endPoint;
      addrInfo.txOptions = gZclTxOptions;
      addrInfo.radiusCounter = afDefaultRadius_c;

      /* determine which cluster to send it to */
      Copy2Bytes(addrInfo.aClusterId, pCluster->aClusterId);

      /* set up frame */
      pFrame->frameControl = gZclFrameControl_FrameTypeGeneral | gZclFrameControl_DisableDefaultRsp;
      pFrame->transactionId = gZclTransactionId++;
      pFrame->command = gZclCmdReportAttr_c;

      /* send the report */
      payloadLen = sizeof(zclFrame_t) + reportLen;
      (void)ZCL_DataRequestNoCopy(&addrInfo, payloadLen, pMsg);

      ++gZclReportClusterIndex;

      /* start a short timer between reporting clusters */
      gfZclReportRestart = FALSE;
      ZLC_StartShortReportingTimer();
      return;
    }
    
    /* try next device */
    ++gZclReportDeviceIndex;
    gZclReportClusterIndex=0;
    gAsynchronousClusterIndex=0;
  } /* end of while(gZclReportDeviceIndex < gNum_EndPoints_c) */

  if(pMsg)
    MSG_Free(pMsg);

  /* start up a new timer if needed */
  if(gZclReportingSetup.reportTimeout != 0 && gZclReportingSetup.reportTimeout != 0xFFFF)
  {
      gZclReportingSetup.reportCounter = gZclReportingSetup.reportTimeout;
      ZLC_StartReportingTimer();
  }
}
/************************************************************************************
* Generates a local Nlme Leave command to let the nwk layer know that WE as a device
* are leaving the network, in other words, is a command to do a self-leave. Only called 
* from the ZDO state machine.
*
* NOTE: This function is meant to only be called byt the ZDO State machine on the
*       leaving state.
*
* Interface assumptions:
*   NONE.
*
* Return value:
*   NONE.
*
* Revison history:
*   Date   Author  Comments
*  ------  ------  --------
*  280208    MN    Updated
************************************************************************************/
void ZdoNwkMng_GenerateNlmeLeaveRequest
(
  void  /*IN: No Input Parameters*/
)
{
  /*
    Pointer to the buffer where the Nlme command will be filled.
  */
  zdoNlmeMessage_t *pZdoNlmeMessage;

  /*
    The size for the curretn command to be passed down.
  */
  uint8_t size = (sizeof(zbMsgId_t) + sizeof(nlmeLeaveReq_t));

  /*
    Allocated the exact size memory for the Nlme command, remember
    this will passed down using a Sap hanlder, the memory will be freed by the next layer.
  */
  pZdoNlmeMessage = MSG_AllocType(size);

  /*
    If for any reason the message was unable to be allocated, no further
    processing is done.
  */
  if(!pZdoNlmeMessage)
    return;

  /*
    Most of the options are filled with a Zero value, lets fill the whole
    thing with Zeros, and just set the ones that are not Zero (less code).
  */
  BeeUtilZeroMemory(pZdoNlmeMessage, size);

  /*
    Build the command.
  */
  pZdoNlmeMessage->msgType = gNlmeLeaveRequest_c;

#if gMgmt_Leave_rsp_d
  /* this would only occur if management leave command came from OTA */
  if(zbMgmtOptionRemoveChildren_c & gMgmtSelfLeaveMask)
  {
    gMgmtSelfLeaveMask &= ~(zbMgmtOptionRemoveChildren_c);
    pZdoNlmeMessage->msgData.leaveReq.removeChildren = TRUE;
  }

  /* If the mgmt command was sent with the  */
  if(zbMgmtOptionReJoin_c & gMgmtSelfLeaveMask)
  {
    /* don't turn off bit yet in gMgmtSelfLeaveMask, it will be turned off later */
    pZdoNlmeMessage->msgData.leaveReq.rejoin = TRUE;
    gMgmtSelfLeaveMask &= ~(zbMgmtOptionReJoin_c);
  }
#endif

  /* check if the ZDO or the application needs to remove the children. */
  if (gZdoStopMode & gZdoStopMode_RemoveChildren_c)
  {
    gZdoStopMode &= ~(gZdoStopMode_RemoveChildren_c);
    pZdoNlmeMessage->msgData.leaveReq.removeChildren = TRUE;
  }

  pZdoNlmeMessage->msgData.leaveReq.reuseAddress = mDefaultReuseAddressPolicy_c;

  if (ZDO_NLME_SapHandler( pZdoNlmeMessage ))
  {
    /*
      Catch the error message if needed.
    */
  }
}