Esempio n. 1
0
/*-------------------- Backup_Bind_Table_req --------------------
	2.4.3.2.8 Backup_Bind_Table_req. (ClusterID=0x0027)

	The Backup_Bind_Table_req is generated from a local primary binding table
	cache and sent to the remote backup binding table cache device to request backup
	storage of its entire binding table. The destination addressing mode for this
	request is unicast.

	IN: The package with the request information.

	OUT: The size in bytes of the request payload.
*/
zbSize_t Backup_Bind_Table_req
(
	zbBackupBindTableRequest_t  *pMessageComingIn  /* IN: The package with the request information. */
)
{
	zbSize_t  payloadLength;
	uint8_t  *pPtr = NULL;
	uint16_t  cIndex;
	uint16_t  limit;

	payloadLength = MbrOfs(zbBackupBindTableRequest_t, BindingTableList[0]);
	pPtr = (uint8_t *)&pMessageComingIn->BindingTableList[0];

	limit = OTA2Native16(TwoBytesToUint16(pMessageComingIn->BindingTableListCount));
	for (cIndex = 0; cIndex < limit; cIndex++)
	{
		if (((zbApsmeBindEntry_t *)pPtr)->dstAddrMode == zbGroupMode)
		{
			payloadLength += (MbrOfs(zbApsmeBindEntry_t, dstAddrMode) + sizeof(zbGroupId_t));
			pPtr += (MbrOfs(zbApsmeBindEntry_t, dstAddrMode) + sizeof(zbGroupId_t));
		}
		else
		{
			payloadLength += sizeof(zbApsmeBindEntry_t);
			pPtr += sizeof(zbApsmeBindEntry_t);
		}
	}
	return (payloadLength);
}
Esempio n. 2
0
/*-------------------- Remove_Bkup_Bind_Entry_req --------------------
	2.4.3.2.7 Remove_Bkup_Bind_Entry_req. (ClusterID=0x0026)

	The Remove_Bkup_Bind_Entry_req is generated from a local primary binding
	table cache and sent to a remote backup binding table cache device to request
	removal of the entry from backup storage. It will be generated whenever a binding
	table entry has been unbound by the primary binding table cache. The destination
	addressing mode for this request is unicast.

	IN: The package with the request information.

	OUT: The size in bytes of the request payload.
*/
zbSize_t Remove_Bkup_Bind_Entry_req
(
	zbRemoveBackupBindEntryRequest_t *pMessageComingIn  /* IN: The package with the request information. */
)
{
	if (pMessageComingIn->addressMode == zbGroupMode)
		return (MbrOfs(zbRemoveBackupBindEntryRequest_t, destData) + sizeof(groupMode_t));
	else
		return (MbrOfs(zbRemoveBackupBindEntryRequest_t, destData) + sizeof(extendedMode_t));
}
Esempio n. 3
0
/*-------------------- Bind_Unbind_req --------------------
	2.4.3.2.2 Bind_req and 2.4.3.2.3 Unbind_req. (ClusterID=0x0021) - (ClusterID=0x0022)

	Retunrs the proper size in bytes for the Bind_req and Unbind_req primitives.

	IN: The request package with the message information.

	OUT: The size in bytes for the request package.
*/
zbSize_t Bind_Unbind_req
(
	zbBindUnbindRequest_t  *pMessageComingIn  /* IN: The request package with the message information. */
)
{
	if (pMessageComingIn->addressMode == zbGroupMode)
		return (MbrOfs(zbBindUnbindRequest_t, destData) + sizeof(groupMode_t));
	else
		return (MbrOfs(zbBindUnbindRequest_t, destData) + sizeof(extendedMode_t));
}
Esempio n. 4
0
/*-------------------- Match_Desc_req --------------------
	2.4.3.1.7 Match_Desc_req. (ClusterID=0x0006)

	The Match_Desc_req command is generated from a local device wishing to find
	remote devices supporting a specific simple descriptor match criterion. This
	command shall either be broadcast to all RxOnWhenIdle devices or unicast. If the
	command is unicast, it shall be directed either to the remote device itself or to an
	alternative device that contains the discovery information of the remote device.
	The local device shall generate the Match_Desc_req command using the format
	illustrated in Table 2.47. The NWKAddrOfInterest field shall contain the
	broadcast to all RxOnWhenIdle devices network address (0xfffd), if the command
	is to be broadcast, or the network address of the remote device for which the
	match is required.

	IN: The buffer where the request will be generated.
	IN: The package with the request data.
	IN: The Address of the destination node.

	OUT: The Size of the payload for the request.
*/
zbSize_t Match_Desc_req
(
  uint8_t *pkgPayload,                           /* IN: The buffer where the request will be generated. */
  zbMatchDescriptorRequestPtr_t *pMessageComingIn,  /* IN: The package with the request data. */
  zbNwkAddr_t aDestAddr                          /* IN: The Address of the destination node. */
)
{
  zbSize_t  payloadLength;

  FLib_MemCpy(pkgPayload , pMessageComingIn, MbrOfs(zbMatchDescriptorRequestPtr_t, inputClusterList));

  payloadLength = MbrOfs(zbMatchDescriptorRequestPtr_t, inputClusterList) +
                  ZDP_CopyClusterListPairToFrame(pkgPayload + MbrOfs(zbMatchDescriptorRequestPtr_t, inputClusterList), 
                  (void *)&pMessageComingIn->inputClusterList);

  Zdp_GenerateDataReq(gMatch_Desc_req_c, aDestAddr, (afToApsdeMessage_t *)(pkgPayload - SapHandlerDataStructureOffSet), payloadLength );
  return gZdpAlreadyHanlded_c;
}
Esempio n. 5
0
/*-------------------- End_Device_Bind_req --------------------
	2.4.3.2.1 End_Device_Bind_req. (ClusterID=0x0020)

	The End_Device_Bind_req is generated from a Local Device wishing to perform
	End Device Bind with a Remote Device. The End_Device_Bind_req is generated,
	typically based on some user action like a button press. The destination addressing
	on this command shall be unicast and the destination address shall be that of the
	ZigBee Coordinator.

	IN/OUT: The buffer where the request data will be filled in.
	IN: The package with the request information.
	IN: The destination address where to send the request.

	OUT: The size in bytes of the request payload.
*/
zbSize_t End_Device_Bind_req
(
	uint8_t  *pkgPayload,                        /* IN/OUT: The buffer where the request data will be filled in. */
	zbEndDeviceBindRequest_t *pMessageComingIn,  /* IN: The package with the request information. */
	zbNwkAddr_t aDestAddr                        /* IN: The destination address where to send the request. */
)
{
	zbSize_t  payloadLength;

	FLib_MemCpy(pkgPayload, pMessageComingIn, MbrOfs(zbEndDeviceBindRequest_t, inputClusterList));
	payloadLength = MbrOfs(zbEndDeviceBindRequest_t, inputClusterList) + 
									ZDP_CopyClusterListPairToFrame(pkgPayload + MbrOfs(zbEndDeviceBindRequest_t, inputClusterList), 
									&pMessageComingIn->inputClusterList);

	Zdp_GenerateDataReq( gEnd_Device_Bind_req_c, aDestAddr, (afToApsdeMessage_t *)(pkgPayload - SapHandlerDataStructureOffSet) , payloadLength );

	return gZdpAlreadyHanlded_c;
}
Esempio n. 6
0
uint8_t AppHcZtc_SAPHandler(hcZtcMessage_t *ztcMessage) {
  
  OepFragmentedApdu_t* pOepFragmentedApdu = (OepFragmentedApdu_t *)ztcMessage;
  
  uint8_t dataLenToCopy;
  uint8_t dstOffset = MbrOfs(OepFragmentedApdu_t, fragment) + MbrOfs(OepApduFragment_t, data);
  uint8_t srcOffset = MbrOfs(hcZtcMessage_t, data);
  
  if (ztcMessage->msgType >= gHcZtcOpcodeMarker_StartOfCfgRxCmds &&
      ztcMessage->msgType <= gHcZtcOpcodeMarker_EndOfCfgRxCmds) {
    
    oepObjCfgFrame_t* pZtcFrame;
    hcZtcObjCfgFrame_t* pZtcObjCfgFrame;
    
    dstOffset += MbrOfs(oepObjCfgFrame_t, frame);
    srcOffset += MbrOfs(hcZtcObjCfgFrame_t, objCfgFrame);
    dataLenToCopy = ztcMessage->msgLen - MbrSizeof(hcZtcObjCfgFrame_t, endPoint)
                    - MbrSizeof(hcZtcFrame_t, nextFragmentPresent);
    
    /* ZHCTODO support fragmentation */
    FLib_MemInPlaceCpy((uint8_t *)ztcMessage + dstOffset, (uint8_t *)ztcMessage + srcOffset, dataLenToCopy);
    pZtcFrame = (oepObjCfgFrame_t *)pOepFragmentedApdu->fragment.data;
    
    pZtcFrame->choice = (gHcZtcObjCfgChoice_HeaderByte << 8) | ztcMessage->msgType;
    pZtcFrame->apduLen = MbrSizeof(oepObjCfgFrame_t, choice) + dataLenToCopy;
    
    pOepFragmentedApdu->fragment.len = pZtcFrame->apduLen + MbrSizeof(oepObjCfgFrame_t, apduLen);
        
    pZtcObjCfgFrame = (hcZtcObjCfgFrame_t *)ztcMessage->data;
    pOepFragmentedApdu->dstEndPoint = pZtcObjCfgFrame->endPoint;
    
    /* ZHCTODO support fragmentation */ 
    pOepFragmentedApdu->fragment.nextFragment = NULL;
  } 
  else
  {
    /* ZHCTODO association and prst frames */ 
    
  }
  
  ZCL_Oep_SAPHandler(pOepFragmentedApdu);
  
  return gZbSuccess_c;
}
Esempio n. 7
0
/*-------------------- Backup_Source_Bind_req --------------------
	2.4.3.2.10 Backup_Source_Bind_req. (ClusterID=0x0029)

	The Backup_Source_Bind_req is generated from a local primary binding table
	cache and sent to a remote backup binding table cache device to request backup
	storage of its entire source table. The destination addressing mode for this request
	is unicast.

	IN: The package with the request information.

	OUT: The size in bytes of the request payload.
*/
zbSize_t Backup_Source_Bind_req
(
	zbBackupSourceBindRequest_t  *pMessageComingIn  /* IN: The package with the request information. */
)
{

	return ((MbrOfs(zbBackupSourceBindRequest_t, SourceTableList[0]) +
					(MbrSizeof(zbBackupSourceBindRequest_t, SourceTableList[0]) *
					OTA2Native16(TwoBytesToUint16(pMessageComingIn->SourceTableListCount)))));
}
Esempio n. 8
0
/*-------------------- Active_EP_store_req --------------------
	2.4.3.1.17 Active_EP_store_req. (ClusterID=0x0019)

	The Active_EP_store_req is provided to enable ZigBee end devices on the
	network to request storage of their list of Active Endpoints on a Primary
	Discovery Cache device which has previously received a SUCCESS status from a
	Discovery_store_req to the same Primary Discovery Cache device. Included in
	this request is the count of Active Endpoints the Local Device wishes to cache and
	the endpoint list itself.

	IN/OUT: The destination address where to send the request.
	IN: The package with the request information.

	OUT: The size in bytes of the request payload.
*/
zbSize_t Active_EP_store_req
(
	zbNwkAddr_t  aAddress,                       /* IN/OUT: The destination address where to send the request. */
	zbActiveEPStoreRequest_t  *pMessageGoingOut  /* IN: The package with the request information. */
)
{
	if (gDiscoveryCacheResponse)
				Copy2Bytes(aAddress, gDiscoveryCacheSuccess.aNwkAddress);

	return (MbrOfs(zbActiveEPStoreRequest_t, activeEPList[0]) + pMessageGoingOut->activeEPCount);
}
Esempio n. 9
0
/*-------------------- Simple_Desc_store_req --------------------
	2.4.3.1.18 Simple_Desc_store_req. (ClusterID=0x001a)

	The Simple_desc_store_req is provided to enable ZigBee end devices on the
	network to request storage of their list of Simple Descriptors on a Primary
	Discovery Cache device which has previously received a SUCCESS status from a
	Discovery_store_req to the same Primary Discovery Cache device. Note that each
	Simple Descriptor for every active endpoint on the Local Device must be
	individually uploaded to the Primary Discovery Cache device via this command
	to enable cached discovery. Included in this request is the length of the Simple
	Descriptor the Local Device wishes to cache and the Simple Descriptor itself. The
	endpoint is a field within the Simple Descriptor and is accessed by the Remote
	Device to manage the discovery cache information for the Local Device.

	IN/OUT: The buffer where the request data will be filled in.
	IN: The package with the request information.
	IN: The destination address where to send the request.

	OUT: The size in bytes of the request payload.
*/
zbSize_t Simple_Desc_store_req
(
	uint8_t *pkgPayload,                                 /* IN/OUT: The buffer where the request data will be filled in. */
	zbSimpleDescriptorStoreRequest_t *pMessageComingIn,  /* IN: The package with the request information. */
	zbNwkAddr_t aDestAddr                                /* IN: The destination address where to send the request. */
)
{
	zbSize_t  payloadLength;

	if (gDiscoveryCacheResponse)
			Copy2Bytes(aDestAddr, gDiscoveryCacheSuccess.aNwkAddress);

	FLib_MemCpy(pkgPayload, pMessageComingIn,MbrOfs(zbSimpleDescriptorStoreRequest_t, simpleDescriptor.inputClusters));

	payloadLength = MbrOfs(zbSimpleDescriptorStoreRequest_t, simpleDescriptor.inputClusters) + 
									ZDP_CopyClusterListPairToFrame(pkgPayload + MbrOfs(zbSimpleDescriptorStoreRequest_t, simpleDescriptor.inputClusters), 
									&(pMessageComingIn->simpleDescriptor.inputClusters));

	Zdp_GenerateDataReq(gSimple_Desc_store_req_c, aDestAddr, (afToApsdeMessage_t *)(pkgPayload - SapHandlerDataStructureOffSet) , payloadLength );

	return gZdpAlreadyHanlded_c;
}
Esempio n. 10
0
zbSize_t Mgmt_NWK_Update_notify
(
  zbMgmtNwkUpdateNotify_t  *pRequest
)
{
  zbSize_t  size = MbrOfs(zbMgmtNwkUpdateNotify_t, aEnergyValues);

    if (ZdoGetNwkManagerBitMask(gaServerMask))
  {
    (void) pRequest;
    (void) size;
    return gZero_c;
  }
  return (size + (pRequest->ScannedChannelsListCount /* *MbrSizeof(zbMgmtNwkUpdateNotify_t, aEnergyValues)*/));
}
Esempio n. 11
0
/*-------------------- User_Desc_set --------------------
	2.4.3.1.12 User_Desc_set. (ClusterID=0x0014)

	The User_Desc_set command is generated from a local device wishing to
	configure the user descriptor on a remote device. This command shall be unicast
	either to the remote device itself or to an alternative device that contains the
	discovery information of the remote device.
	The local device shall generate the User_Desc_set command using the format
	illustrated in Table 2.52. The NWKAddrOfInterest field shall contain the network
	address of the remote device for which the user descriptor is to be configured and
	the UserDescription field shall contain the ASCII character string that is to be
	configured in the user descriptor.

	IN: The buffer where the request data will be filled in.
	IN: The package with the request information.
	IN: The destination address where the message will be send.
*/
zbSize_t User_Desc_set
(
	uint8_t  *pkgPayload,                      /* IN: The buffer where the request data will be filled in. */
	zbUserDescriptorSet_t  *pMessageComingIn,  /* IN: The package with the request information. */
	zbNwkAddr_t  aDestAddr                     /* IN: The destination address where the message will be send. */
)
{
	zbSize_t  payloadLength;

	FLib_MemSet(pkgPayload, 0x20, sizeof(zbUserDescriptorSet_t));
	payloadLength = (MbrOfs(zbUserDescriptorSet_t, descriptor.aUserDescription[0]) + pMessageComingIn->descriptor.length);
	FLib_MemCpy(pkgPayload, pMessageComingIn,payloadLength);
	Zdp_GenerateDataReq( gUser_Desc_set_c, aDestAddr, (afToApsdeMessage_t *)(pkgPayload -SapHandlerDataStructureOffSet), sizeof(zbUserDescriptorSet_t) );
	return gZdpAlreadyHanlded_c;
}
Esempio n. 12
0
/*-------------------- Mgmt_NWK_Update_req --------------------
  2.4.3.3.9 Mgmt_NWK_Update_req. (ClusterID=0x0038)

  This command is provided to allow updating of network configuration parameters
  or to request information from devices on network conditions in the local
  operating environment. The destination addressing on this primitive shall be
  unicast or broadcast to all devices for which macRxOnWhenIdle = TRUE.
*/
zbSize_t Mgmt_NWK_Update_req
(
  zbMgmtNwkUpdateRequest_t  *pRequest,
  zbNwkAddr_t               aDestAddr
)
{
  zbSize_t  size = MbrOfs(zbMgmtNwkUpdateRequest_t, ExtraData);


  if (!ZdoGetNwkManagerBitMask(gaServerMask))
  {
    (void) pRequest;
    (void) aDestAddr;
    (void) size;
    return gZero_c;
  }

  if (!IsValidNwkUnicastAddr(aDestAddr) && !IsEqual2Bytes(aDestAddr,gaBroadcastRxOnIdle))
  {
    /*
      Consider it as an invalid request.
    */
    return gZero_c;
  }

  /*
    The values 0x00 and 0x05 are acording to the Table 2.87 Fields of the
    Mgmt_NWK_Update_req Command , since is a the ScanDuration is a uint8 then 
    it is not necesary to make the verification "pRequest->ScanDuration >= 0x00",
    that is why is commented.
  */

  /*
    Do a scan.
  */
  if ( pRequest->ScanDuration <= 0x05)
  {
     return (size + MbrSizeof(zbudata_t, ScanCount));
  }

  /*
    Channel channel.
  */
  else if (pRequest->ScanDuration == 0xfe)
  {
#if gFrequencyAgilityCapability_d
    /*
      This is a special case, is when the application commands the channge with out using
      the state machine.
    */
    if (ZdoGetNwkManagerBitMask(gaServerMask)&&(FA_GetNwkManagerState() == gInitState_c))
    {
      /*
        Place holder to the state machine of the Nwk Manager, to avoid hiting the same
        state many times.
      */
      FA_SetNwkManagerState(gSelfChannelChange_c);

      /*
        Send the same command to our selfs, in order to use the mechanism.
      */
      ASL_Mgmt_NWK_Update_req(NlmeGetRequest(gNwkShortAddress_c), /* To Us. */
                              pRequest->aScanChannels,  /* Same Channel list ot be use. */
                              0xfe,  /* Do a channel change. */
                              pRequest->ExtraData.NwkManagerData.nwkUpdateId);  /* No scan duration, is a channel change. */
    }

    /*
      This will make ZDP send the request to other devices.
    */
    return (size + MbrSizeof(zbNwkManagerData_t, nwkUpdateId));
#endif
  }

  /*
    Update NwkUpdateId and channel list.
  */
  else if(pRequest->ScanDuration == 0xff)
  {
    return (size + MbrSizeof(zbNwkManagerData_t, nwkUpdateId) +
            MbrSizeof(zbNwkManagerData_t, aNwkManagerAddr));
  }

  /*
    For any other value of Scanduration then it only needs the Scan Count.
  */
  return (size + MbrSizeof(zbudata_t, ScanCount));
}
Esempio n. 13
0
/******************************
  Illuminance Measurement Cluster
  See ZCL Specification Section 4.2
*******************************/

/******************************
  Illuminance Level Sensing Cluster
  See ZCL Specification Section 4.3
*******************************/

/******************************
  Temperature Measurement Cluster
  See ZCL Specification Section 4.4
*******************************/
const zclAttrDef_t gaZclTemperatureMeasurementClusterAttrDef[] = {  
  {gZclAttrTemperatureMeasurement_MeasuredValueId_c,     gZclDataTypeInt16_c,gZclAttrFlagsInRAM_c | gZclAttrFlagsReportable_c,sizeof(int16_t),  (void *)MbrOfs(zclTemperatureMeasurementAttrs_t,MeasuredValue)},
  {gZclAttrTemperatureMeasurement_MinMeasuredValuedId_c, gZclDataTypeInt16_c,gZclAttrFlagsInRAM_c | gZclAttrFlagsRdOnly_c,sizeof(int16_t),  (void *)MbrOfs(zclTemperatureMeasurementAttrs_t,MinMeasuredValue)},
  {gZclAttrTemperatureMeasurement_MaxMeasuredValuedId_c, gZclDataTypeInt16_c,gZclAttrFlagsInRAM_c | gZclAttrFlagsRdOnly_c,sizeof(int16_t),  (void *)MbrOfs(zclTemperatureMeasurementAttrs_t,MaxMeasuredValue)}
#if gZclClusterOptionals_d
  , {gZclAttrTemperatureMeasurement_ToleranceId_c, gZclDataTypeUint16_c,gZclAttrFlagsInRAM_c | gZclAttrFlagsReportable_c,sizeof(uint16_t),  (void *)MbrOfs(zclTemperatureMeasurementAttrs_t,Tolerance)}
#endif
};

const zclAttrDefList_t gZclTemperatureMeasurementClusterAttrDefList = {
  NumberOfElements(gaZclTemperatureMeasurementClusterAttrDef),
  gaZclTemperatureMeasurementClusterAttrDef
};

/******************************
  Pressure Measurement Cluster
  See ZCL Specification Section 4.5
Esempio n. 14
0
void HcOutgoingZtcTaskEventMonitor(OepOutgoingMessage_t *message) {
  
  
  hcZtcMessage_t* pMsgFromSAPHandler;
  
  /* cleaner access to the 11073 apdu */   
  oepGenericApdu_t *pApdu = (oepGenericApdu_t *)message->pApdu;
  
  uint8_t* pSrcDataPtr;
  uint8_t* pDstDataPtr;
  
  /* first fragment flag is initially set to True */   
  uint8_t firstFragment = TRUE;
  uint16_t apduLen = message->length - MbrSizeof(oepGenericApdu_t, apduLen);
  
  uint8_t dataCopyLen;

  /* iterate the fragments */   
  do
  {
    /* allocate a new buffer as the ZTC frames are quite different from the actual
       11073 frames */   
    pMsgFromSAPHandler = (hcZtcMessage_t *) MSG_Alloc(mSapHandlerMsgTotalLen_c);    

    if (firstFragment) {
    
      oepMsgType_t oepMsgType; 
    
      firstFragment = FALSE;
      
      /* is it a cfg, prst, other kind of frame? */ 
      oepMsgType = GetOepMsgType(pApdu);
    
      /* get ZTC opcode id for the frame */ 
      pMsgFromSAPHandler->msgType = GetMsgZtcOpCode(pApdu);
      
      
      /* frame is an object configuration frame */ 
      if (oepMsgType == msgType_ObjCfgMsg) {
      
        hcZtcObjCfgFrame_t* pHcZtcObjCfgFrame = (hcZtcObjCfgFrame_t *)pMsgFromSAPHandler->data;
        
        apduLen -= MbrSizeof(oepGenericApdu_t, choice);
        
        if (apduLen > mSapHandlerMsgTotalLen_c - MbrOfs(hcZtcObjCfgFrame_t, objCfgFrame)) {
        
          dataCopyLen = mSapHandlerMsgTotalLen_c - MbrOfs(hcZtcObjCfgFrame_t, objCfgFrame);
          apduLen -= dataCopyLen;
          pHcZtcObjCfgFrame->nextFragmentPresent = TRUE;
          
        }
        else {
        
          dataCopyLen = (uint8_t)apduLen;
          apduLen = 0;
          pHcZtcObjCfgFrame->nextFragmentPresent = FALSE;
          
        }
      
        pMsgFromSAPHandler->msgLen = dataCopyLen + MbrOfs(hcZtcObjCfgFrame_t, objCfgFrame);
                                     
        pSrcDataPtr = (uint8_t *)pApdu->payload;
        
        pDstDataPtr = (uint8_t *)pHcZtcObjCfgFrame->objCfgFrame; 
        
        pHcZtcObjCfgFrame->endPoint = message->srcEndPoint;
        
      }
      else {
        /* Aarq, Aars, Prst, etc type of frame */
        hcZtcFrame_t* pZtcFrameGeneric = (hcZtcFrame_t *)pMsgFromSAPHandler->data;
        
        if (apduLen > mSapHandlerMsgTotalLen_c - MbrOfs(hcZtcFrame_t, apdu)) {
        
          dataCopyLen = mSapHandlerMsgTotalLen_c - MbrOfs(hcZtcFrame_t, apdu);
          apduLen -= dataCopyLen;
          pZtcFrameGeneric->nextFragmentPresent = TRUE;
          
        } 
        else {

          dataCopyLen = (uint8_t)apduLen;
          apduLen = 0;
          pZtcFrameGeneric->nextFragmentPresent = FALSE;
          
        }
        
        pMsgFromSAPHandler->msgLen = dataCopyLen + MbrOfs(hcZtcFrame_t, apdu);
        
        pSrcDataPtr = (uint8_t *)&pApdu->choice;
        
        pDstDataPtr = (uint8_t *)pZtcFrameGeneric->apdu;
                                
        Copy2Bytes(pZtcFrameGeneric->aSrcDstAddr, message->aDstAddr);
        pZtcFrameGeneric->dstEndPoint = message->dstEndPoint;
        pZtcFrameGeneric->srcEndPoint = message->srcEndPoint;
      }
    }
    else 
    {
      /* this is not the first fragment; */
      
      hcZtcFragmentContinuationFrame_t* pZtcFragmentCont = 
                          (hcZtcFragmentContinuationFrame_t *)pMsgFromSAPHandler->data;
                          
      /* set fragment continuation opcode */
      pMsgFromSAPHandler->msgType = gHcZtcOpcode_FragmentContinuation_d;
      
      if (apduLen > mSapHandlerMsgTotalLen_c - 
          MbrOfs(hcZtcFragmentContinuationFrame_t, fragmentData)) {
        
        dataCopyLen = mSapHandlerMsgTotalLen_c -  
                      MbrOfs(hcZtcFragmentContinuationFrame_t, fragmentData);
        apduLen -= dataCopyLen;
        pZtcFragmentCont->nextFragmentPresent = TRUE;
        
      } 
      else {

        dataCopyLen = (uint8_t)apduLen;
        apduLen = 0;
        pZtcFragmentCont->nextFragmentPresent = FALSE;
        
      }
      
      pMsgFromSAPHandler->msgLen = dataCopyLen +
                           MbrSizeof(hcZtcFragmentContinuationFrame_t, fragmentData);

      pDstDataPtr = (uint8_t *)pZtcFragmentCont->fragmentData;
    }
    
    FLib_MemCpy(pDstDataPtr, pSrcDataPtr, dataCopyLen);
    
    pSrcDataPtr += dataCopyLen;
    
    /* send message to ZTC */
#ifndef gHostApp_d        
    ZTC_TaskEventMonitor(gHcApp_SAPHandlerId_c, (uint8_t *)pMsgFromSAPHandler, gZbSuccess_c);
#else
    ZTC_TaskEventMonitor(gpHostAppUart, gHcApp_SAPHandlerId_c, (uint8_t *)pMsgFromSAPHandler, gZbSuccess_c);
#endif     

    /* free the message if ZTC hasn't already done that */
    if (pMsgFromSAPHandler)
      MSG_Free(pMsgFromSAPHandler);
    
  } while (apduLen > 0);
}
Esempio n. 15
0
void HcIncomingZtcTaskEventMonitor(OepFragmentedApdu_t *message) {
  
  hcZtcMessage_t* pMsgFromSAPHandler;
  
  /* pCurrentFragment points initially to the fragment in OepFragmentedApdu_t */   
  OepApduFragment_t* pCurrentFragment = &message->fragment;
  
  /* cleaner access to the 11073 apdu */   
  oepGenericApdu_t *pApdu = (oepGenericApdu_t *)pCurrentFragment->data;
  
  
  /* first fragment flag is initially set to True */   
  uint8_t firstFragment = TRUE;

  /* iterate the fragments */   
  do {
  
    uint8_t srcOffset, dstOffset, dataCopyLen;
  
    /* allocate a new buffer as the ZTC frames are quite different from the actual
       11073 frames */   
    pMsgFromSAPHandler = (hcZtcMessage_t *) MSG_Alloc(mSapHandlerMsgTotalLen_c);    

    /* set default values for mem copy offsets and length */
    
    /* by default copy data beginning with the choice member in the apdu */      
    srcOffset = MbrOfs(oepGenericApdu_t, choice);
    
    /* by default copy data to the apdu member in the ztc frame*/          
    dstOffset = MbrOfs(hcZtcFrame_t, apdu);    
    
    /* data copy length adjusted to omit apduLen field */              
    dataCopyLen = pCurrentFragment->len - MbrOfs(oepGenericApdu_t, choice);
    
    if (firstFragment) {
      oepMsgType_t oepMsgType; 
    
      firstFragment = FALSE;
    
      /* is it a cfg, prst, other kind of frame? */ 
      oepMsgType = GetOepMsgType(pApdu);
    
      /* get ZTC opcode id for the frame */ 
      pMsgFromSAPHandler->msgType = GetMsgZtcOpCode(pApdu);
      
      /* frame is an object configuration frame */ 
      if (oepMsgType == msgType_ObjCfgMsg) {
      
        /* msgLen is the length of the ZTC payload; this includes the actual
           apdu payload, without the choice and apduLen as well as the src/dstEndPoint
           and nextFragmentPresent bytes */
        pMsgFromSAPHandler->msgLen = (uint8_t)(pCurrentFragment->len - 
                                     MbrOfs(oepGenericApdu_t, payload) +
                                     MbrOfs(hcZtcObjCfgFrame_t, objCfgFrame));
                                     
        /* adjust source offset for data copy to not include choice */ 
        srcOffset = MbrOfs(oepGenericApdu_t, payload);
        
        /* adjust dst offset for data copy as srcAddress and an endpoint are no longer included */
        dstOffset = MbrOfs(hcZtcObjCfgFrame_t, objCfgFrame);
        
        /* adjust data length for data copy as choice is no longer included */
        dataCopyLen -= MbrSizeof(oepGenericApdu_t, choice);
        
        /* set destination endpoint as second byte in the ZTC
           packet based on frame direction */
        pMsgFromSAPHandler->data[1] = message->dstEndPoint;
                                     
      }
      else {
        /* Aarq, Aars, Prst, etc type of frame */
        hcZtcFrame_t* pZtcFrameGeneric = (hcZtcFrame_t *)pMsgFromSAPHandler->data;
        
        /* msgLen is the length of the ZTC payload; this includes the actual
           apdu payload, without the apduLen as well as the addressing information
           and nextFragmentPresent bytes */
        pMsgFromSAPHandler->msgLen = pCurrentFragment->len -
                                     MbrOfs(oepGenericApdu_t, choice) +
                                     MbrOfs(hcZtcFrame_t, apdu);
                                     
        /* copy addressing info */
        Copy2Bytes(pZtcFrameGeneric->aSrcDstAddr, message->aSrcAddr);
        pZtcFrameGeneric->dstEndPoint = message->dstEndPoint;
        pZtcFrameGeneric->srcEndPoint = message->srcEndPoint;
      }
    }
    else 
    {
      /* this is not the first fragment; */
      
      /* set data copy and copy size accordingly */ 
      srcOffset = 0;
      dstOffset = 1;
      dataCopyLen = pCurrentFragment->len;
      
      pApdu =  (oepGenericApdu_t *)pCurrentFragment->data;
      
      /* set fragment continuation opcode */
      pMsgFromSAPHandler->msgType = gHcZtcOpcode_FragmentContinuation_d;
      
        /* msgLen includes the actualapdu payload and the nextFragmentPresent byte */      
      pMsgFromSAPHandler->msgLen = pCurrentFragment->len +
                                   MbrSizeof(hcZtcFrame_t, nextFragmentPresent);
    }
    
    /* nextFragmentPresent */
    pMsgFromSAPHandler->data[0] = FALSE;
    
    /* set nextFramgentPresent byte in ZTC frame to 1 if there is
       another fragment to be processed */
    if (pCurrentFragment->nextFragment != NULL)
      pMsgFromSAPHandler->data[0] = TRUE;
    
    /* do the fragment iteration */
    pCurrentFragment = pCurrentFragment->nextFragment;

    /* copy payload data */
    FLib_MemCpy((uint8_t*)pMsgFromSAPHandler->data + dstOffset,
                (uint8_t*)pApdu + srcOffset,
                dataCopyLen);
    
    /* send message to ZTC */
#ifndef gHostApp_d        
    ZTC_TaskEventMonitor(gAppHc_SAPHandlerId_c, (uint8_t *)pMsgFromSAPHandler, gZbSuccess_c);
#else
    ZTC_TaskEventMonitor(gpHostAppUart, gAppHc_SAPHandlerId_c, (uint8_t *)pMsgFromSAPHandler, gZbSuccess_c);
#endif     
    /* free the message if ZTC hasn't already done that */
    if (pMsgFromSAPHandler)
      MSG_Free(pMsgFromSAPHandler);
    
  } while (pCurrentFragment != NULL);
}