本帖最后由 damiaa 于 2015-4-1 22:46 编辑
首先 我们看BitCloud里有个消息缓冲结构和数据发送相关结构:
/typedef struct
{
/** The status of the data request. See \ref DataReqStatuses "details". */
APS_Status_t status;
/** Timestamp for the transmitted packet based on the local clock,
* as provided by the NWK layer. */
uint32_t txTime;
} APS_DataConf_t;
/**//**
* \struct APS_TxOptions_t apsdeData.h "aps.h"
*
* \brief Describes additional options for data transmission.
*
* The structure is used to set additional parameters for a data request such as
* \li to request for acknowledgement set acknowledgedTransmission to 1
* \li to enable fragmentation set fragmentationPermitted to 1
* \li to enable encryption of the application payload of a data frame set securityEnabledTransmission to 1
* \li to use network key to encrypt the application payload of a data frame set useNwkKey to 1
* \li to include extended nonce (combination of extended address and
* sequence number) to the auxiliary header set includeExtendedNonce to 1
*
* These fields conform to the primitive defined in ZigBee Specification r20, Table 2.2, page 25.
*
* Few extensions to the specification are defined:
* \li to disable decryption of sent data (clobbers data pointed by the asdu field) set doNotDecrypt to 1
* \li to enable indications from own broadcast transmissions set indicateBroadcasts to 1
* \li to disable discovery of a route path to the destination node in the case
* when such path is unknown; in such case if the route is unknown an error is reported
*
*/
BEGIN_PACK
typedef struct PACK
{
uint8_t securityEnabledTransmission :1;
uint8_t useNwkKey :1;
uint8_t acknowledgedTransmission :1;
uint8_t fragmentationPermitted :1;
uint8_t includeExtendedNonce :1;
uint8_t doNotDecrypt :1;
uint8_t indicateBroadcasts :1;
uint8_t noRouteDiscovery :1;
} APS_TxOptions_t;
END_PACK
/**//**
* \struct APS_DataReq_t apsdeData.h "aps.h"
*
* \brief The structure for request parameters of APS_DataReq() function
*
* The structure represents parameters of data request, i.e. the request for sending data across the network. A pointer
* to an instance of the structure should to be passed as an argument to APS_DataReq() function.
* The structure definition follows APSDE-DATA request primitive described in
* Zigbee Specification r18, 2.2.4.1.1 APSDE-DATA.request, page 23.
*/
//APS_DataReq_t结构的定义:
typedef struct
{
/** \cond SERVICE_FIELDS **/
struct
{
void *next; /*!< Used for queue support */
#ifdef _ZAPPSI_
/* to be compatible with MAC service. */
uint8_t requestId;
/* Sequence number to identify request-response pair. */
uint8_t sequenceNumber;
union
{
/* Callback wrapper routine pointer */
void (*callback)(void*);
/* Processing routine pointer to call after required memory will become free */
void (*process)(void*);
} zsi;
#endif /* # _ZAPPSI_ */
ZDO_ResolveAddrReq_t resolveAddrReq; /*!< Used for address resolving */
} service;
/** \endcond **/
/** The addressing mode for identifying the destination of a data request.
* May take any non-reserved value from the following list:
* \li APS_NO_ADDRESS (0x00) - used for binding; set dstAddress and dstEndpoint
* \li APS_GROUP_ADDRESS (0x01) - used for group transmission; 16-bit group address should be specified in dstAddress; dstEndpoint is not set
* \li APS_SHORT_ADDRESS (0x02) - identifying the destination (unicast or broadcast) with a 16-bit short address specified
* in dstAddress and the endpoint set in dstEndpoint
* \li APS_EXT_ADDRESS (0x03) - identifying the destination with a 64-bit extended address specified in dstAddress and the endpoint set in dstEndpoint
* \li 0x04..0xff - reserved values, must not be used by the application*/
APS_AddrMode_t dstAddrMode;
/**
* \ref Endian "[LE]" The address of the individual device or group address
* of the entity to which the ASDU is being transferred.
**/
APS_Address_t dstAddress;
/** This parameter shall be present if and only if the DstAddrMode parameter
* value is 0x02 or 0x03 and, if present, shall contain either the number of
* individual endpoints of the entity to which the ASDU is being transferred,
* or the broadcast endpoint (0xff). */
Endpoint_t dstEndpoint;
/** \ref Endian "[LE]" The identifier of the profile for which
* this frame is intended. */
ProfileId_t profileId;
/** \ref Endian "[LE]" The identifier of the cluster for which
* this frame is intended. */
ClusterId_t clusterId;
/** The endpoint on the request originator node from
* which the data frame is being transferred. */
Endpoint_t srcEndpoint;
/** The number of octets comprising the ASDU to be transferred.
* The maximum length of an individual APS frame payload is given
* as NsduLength-apscMinHeaderOverhead. Assuming the possibility
* of fragmentation, a maximum-sized single ASDU consists of 256 such blocks.
**/
uint16_t asduLength;
/** The set of octets comprising the ASDU to be transferred. */
uint8_t *asdu;
/** The transmission options for the ASDU to be transferred.
* See structure definition for details.
*/
APS_TxOptions_t txOptions;
#if defined _GREENPOWER_SUPPORT_
/* Alias usage by for the current frame */
bool useAlias;
/* The source address to be used for this NSDU. If the UseAlias parameter
has a value of FALSE, the AliasSrcAddr parameter is ignored.*/
ShortAddr_t aliasSrcAddr;
/* The sequence number to be used for this NSDU. If the UseAlias parameter
has a value of FALSE, the AliasSeqNumb parameter is ignored.*/
uint8_t aliasSeqNumber;
#endif /*_GREENPOWER_SUPPORT_*/
/** The distance, in hops, that a transmitted frame will be allowed to
* travel via the network*/
uint8_t radius;
/** A pointer to a callback function called upon request
* completion. Must not be set to NULL. */
void (*APS_DataConf)(APS_DataConf_t *conf);
/** Confirm primitive passed to the callback and containing the results of request execution*/
APS_DataConf_t confirm;
} APS_DataReq_t;
接下来看赋值:
AppMessageBuffer_t appMessageBuffer; //A variable for the message buffer
APS_DataReq_t dataReq; //A variable for the request parameters
...
//Specify the request parameters
dataReq.asdu = appMessageBuffer.data;
dataReq.asduLength = sizeof(appMessageBuffer.data);
AppMessageBuffer_t appMessageBuffer; //A variable for the message buffer
APS_DataReq_t dataReq; //A variable for the request parameters
//A confirmation callback for APS_DataReq()
static void APS_DataConf(APS_DataConf_t *confInfo) //回调函数
{
...
}
...
dataReq.profileId = APP_PROFILE_ID;//PROFILE ID
dataReq.dstAddrMode = APS_SHORT_ADDRESS;//目标短地址模式 单播 组播 广播的选择
dataReq.dstAddress.shortAddress = CPU_TO_LE16(0x0001);//目标地址
dataReq.dstEndpoint = DST_ENDPOINT_ID;//目标端点
dataReq.clusterId = CPU_TO_LE16(SAMPLE_CLUSTER_ID);//族ID列表
dataReq.srcEndpoint = SRC_ENDPOINT_ID;//源端点
dataReq.radius = 0x0;
//Specify a callback //回调函数配置
dataReq.APS_DataConf =
APS_DataConf;
//Configure the payload
dataReq.asdu = appMessageBuffer.data; //数据
dataReq.asduLength = sizeof(appMessageBuffer.data);//数据长度
最后调用:
//Issue the request
APS_DataReq(&dataReq);
调用上面的函数,这样数据就发到目的端点了。
接受函数将具有相同的端点,根据族ID列表和PROFILESID还有命令,属性等判断怎么处理数据。
端点
PROFILESID
族ID列表
要相同。
当然也必须是相同网络,也就是相同的PANID和CHANNEL
然后有个协调器有路由和终端设备。一起加入了一个网络之后才能执行发送。
以下是接收的情况,初始化的时候要登记一个端点的回调函数。在回调函数时处理数据APS_RegisterEndpointReq(&endpointDesc);函数就是登记的函数
//Global definitionsstatic
ClusterId_t clustersTable[] = {0};
//The list of clusters that the endpoint will support
//Configure the simple descriptor of the endpointstatic
SimpleDescriptor_t simpleDescriptor =
{
.
endpoint = APP_ENDPOINT, //Endpoint ID, an arbitrary number between 1 and 240
.AppDeviceVersion = 1,
.AppInClustersCount = 1, //The number of suppoted input clusters
.AppInClustersList = clustersTable, //The list of supported input clusters
.AppOutClustersCount = 0,
.AppOutClustersList = NULL, //Suppose out clusters are not supported
};
//Configure parameters for endpoint registration requeststatic
APS_RegisterEndpointReq_t endpointDesc =
{
.
simpleDescriptor = &simpleDescriptor,
.APS_DataInd = APS_DataInd,
};
//Data indication callback definitionstatic
void APS_DataInd(
APS_DataInd_t *ind)
{
//Perform appropriate actions, for example, switch on the value of
//cluster specified in the received frame
switch (ind->
clusterId)
{
case CPU_TO_LE16(APP_CLUSTER_ONE): ...
case CPU_TO_LE16(APP_CLUSTER_TWO): ...
}
}
...
simpleDescriptor.AppProfileId = CPU_TO_LE16(APP_PROFILE_ID);
simpleDescriptor.
AppDeviceId = CPU_TO_LE16(1);
APS_RegisterEndpointReq(&endpointDesc);
到此 发送和接收的问题我们就有了一个了解。