/* START _FUNCTION DESCRIPTION ******************************************* _zcl_comm_command_build <zcl_commissioning.c> SYNTAX: int _zcl_comm_command_build( wpan_envelope_t FAR *envelope, zcl_header_nomfg_t *header) DESCRIPTION: Common function used by zcl_comm_restart_device and zcl_comm_reset_parameters Fills in frame_control and sequence of header. Fills in cluster_id and payload of envelope. Fills in source_endpoint and profile_id of envelope if necessary. Caller needs to fill in envelope->length and header->command **************************************************************************/ int _zcl_comm_command_build( wpan_envelope_t FAR *envelope, zcl_header_nomfg_t *header) { const wpan_endpoint_table_entry_t *ep; if (envelope->source_endpoint == 0) { #ifdef ZCL_COMMISSIONING_VERBOSE printf( "%s: searching for endpoint w/commissioning client cluster\n", __FUNCTION__); #endif ep = wpan_endpoint_of_cluster( envelope->dev, WPAN_APS_PROFILE_ANY, ZCL_CLUST_COMMISSIONING, WPAN_CLUST_FLAG_CLIENT); if (ep != NULL) { #ifdef ZCL_COMMISSIONING_VERBOSE printf( "%s: commissioning client on ep %u, profile 0x%04x\n", __FUNCTION__, ep->endpoint, ep->profile_id); #endif envelope->source_endpoint = ep->endpoint; envelope->profile_id = ep->profile_id; } } else { ep = wpan_endpoint_of_envelope( envelope); } if (ep == NULL) { #ifdef ZCL_COMMISSIONING_VERBOSE printf( "%s: couldn't locate source endpoint on this device\n", __FUNCTION__); #endif return -EINVAL; } envelope->cluster_id = ZCL_CLUST_COMMISSIONING; envelope->payload = header; header->frame_control = ZCL_FRAME_CLIENT_TO_SERVER | ZCL_FRAME_GENERAL | ZCL_FRAME_TYPE_CLUSTER | ZCL_FRAME_DISABLE_DEF_RESP; header->sequence = wpan_endpoint_next_trans( ep); return 0; }
/** @brief Find Time Servers on the network, query them for the current time and then synchronize this device's clock to that time. @note This function uses a static buffer to hold context information for the ZDO responder that generates the ZCL Read Attributes request. Wait at least 60 seconds between calls to allow for earlier requests to time out. @note This function will only work correctly if the Time Cluster Client in your endpoint table is using the zcl_time_client() function as its callback handler. If you use the ZCL_CLUST_ENTRY_TIME_CLIENT or ZCL_CLUST_ENTRY_TIME_BOTH macro, the client cluster is set up correctly. @param[in] dev device to send query on @param[in] profile_id profile ID to match in endpoint table or #WPAN_APS_PROFILE_ANY to use the first endpoint with a Time Cluster Client @retval 0 Successfully issued ZDO Match Descriptor Request to find Time Cluster Servers on the network. No guarantee that we'll get a response. @retval !0 Some sort of error occurred in generating or sending the ZDO Match Descriptor Request. @retval -EINVAL Couldn't find a Time Cluster Client with \p profile_id in the endpoint table of \p dev. */ int zcl_time_find_servers( wpan_dev_t *dev, uint16_t profile_id) { // Might as well keep this const -- fewer bytes to have a const table than // to have code to build it in RAM. If not const, still needs const table // to use for initializing a list in RAM. static const uint16_t clusters[] = { ZCL_CLUST_TIME, WPAN_CLUSTER_END_OF_LIST }; // These structures are static since they must persist after this function // ends. They're used as the context for a callback, and the function that // generages a ZCL Read Attributes Request from the ZDO Match Descriptor // response needs the contents of this structure. static const uint16_t attributes[] = { ZCL_TIME_ATTR_TIME, ZCL_TIME_ATTR_TIME_STATUS, ZCL_ATTRIBUTE_END_OF_LIST }; // This structure can't be const, since we fill in the endpoint from the // device's endpoint table. static zcl_client_read_t client_read = { NULL, // fill in with endpoint passed to function ZCL_MFG_NONE, // part of ZCL, not a manufacturer-specific cluster ZCL_CLUST_TIME, // cluster ID attributes // attributes to request }; // Find a Time Cluster Client with the correct profile ID client_read.ep = wpan_endpoint_of_cluster( dev, profile_id, ZCL_CLUST_TIME, WPAN_CLUST_FLAG_CLIENT); if (client_read.ep == NULL) { return -EINVAL; } return zcl_find_and_read_attributes( dev, clusters, &client_read); }