/** @brief Send response to a Commissioning Server Cluster request. */ int zcl_comm_response( const wpan_envelope_t FAR *envelope, uint_fast8_t status) { const zcl_header_nomfg_t FAR *zcl; wpan_envelope_t reply_env; PACKED_STRUCT { zcl_header_nomfg_t header; uint8_t status; } reply; int retval; // wpan_envelope_reply() will test for envelope == NULL retval = wpan_envelope_reply( &reply_env, envelope); if (retval != 0) { return retval; } zcl = envelope->payload; reply.header.frame_control = ZCL_FRAME_SERVER_TO_CLIENT | ZCL_FRAME_DISABLE_DEF_RESP | ZCL_FRAME_TYPE_CLUSTER; reply.header.sequence = zcl->sequence; reply.header.command = zcl->command; reply.status = (uint8_t) status; reply_env.payload = &reply; reply_env.length = sizeof reply; return wpan_envelope_send( &reply_env); }
/*** EndHeader */ int xbee_ota_server_cmd( const wpan_envelope_t FAR *envelope, void FAR *context) { uint16_t options; const char *err = NULL; if (envelope == NULL) { // Stack should not pass NULL envelope; cover this condition for safety return -EINVAL; } // If cluster configuration requires encryption, make sure this // frame was received encrypted. options = envelope->options & (WPAN_ENVELOPE_RX_APS_ENCRYPT | WPAN_CLUST_FLAG_ENCRYPT); if (options == WPAN_CLUST_FLAG_ENCRYPT) { // cluster requires encryption, but frame wasn't encrypted // This isn't ZCL, so we can't send a Default Response and we // just have to ignore the message. err = "encryption required"; } else { // call function provided by the application for starting the update err = xbee_update_firmware_ota( envelope, context); // xbee_update_firmware_ota won't return if it's able to install the // update and reboot } if (err) { wpan_envelope_t reply; if (wpan_envelope_reply( &reply, envelope) == 0) { reply.payload = err; reply.length = strlen( err); wpan_envelope_send( &reply); } } return 0; }
/* START FUNCTION DESCRIPTION ******************************************** zcl_comm_response <zcl_commissioning.c> SYNTAX: int zcl_comm_response( const wpan_envelope_t FAR *envelope, uint_fast8_t status) DESCRIPTION: Send response to a Commissioning Server Cluster request. **************************************************************************/ int zcl_comm_response( const wpan_envelope_t FAR *envelope, uint_fast8_t status) { const zcl_header_nomfg_t FAR *zcl = envelope->payload; wpan_envelope_t reply_env; struct { zcl_header_nomfg_t header; uint8_t status; } reply; reply.header.frame_control = ZCL_FRAME_SERVER_TO_CLIENT | ZCL_FRAME_DISABLE_DEF_RESP | ZCL_FRAME_TYPE_CLUSTER; reply.header.sequence = zcl->sequence; reply.header.command = zcl->command; reply.status = (uint8_t) status; wpan_envelope_reply( &reply_env, envelope); reply_env.payload = &reply; reply_env.length = sizeof reply; return wpan_envelope_send( &reply_env); }
// This should be the ZDO Match Descriptor response to our search for // an XBee with the OTA update cluster. int xbee_found( wpan_conversation_t FAR *conversation, const wpan_envelope_t FAR *envelope) { int i; const uint16_t attributes[] = { ZCL_BASIC_ATTR_APP_VERSION, ZCL_BASIC_ATTR_STACK_VERSION, ZCL_BASIC_ATTR_MODEL_IDENTIFIER, ZCL_BASIC_ATTR_DATE_CODE, ZCL_ATTRIBUTE_END_OF_LIST }; const zcl_client_read_t client_read = { &sample_endpoints.zcl, ZCL_MFG_NONE, ZCL_CLUST_BASIC, attributes }; wpan_envelope_t reply_envelope; // We don't need to reference the 'converstation' parameter in this // wpan_response_fn callback. XBEE_UNUSED_PARAMETER( conversation); if (! envelope) // conversation timed out { if (target_index == 0) { printf( "%s: no targets found\n", __FUNCTION__); } return 0; } if (envelope->cluster_id != ZDO_MATCH_DESC_RSP) { printf( "%s: cluster is not a ZDO response?\n", __FUNCTION__); return -EINVAL; } i = find_target( &envelope->ieee_address); if (i < 0 && target_index < TARGET_COUNT) { i = target_index; // new target found -- add to list target_list[target_index].ieee = envelope->ieee_address; ++target_index; } if (i >= 0) { // send Read Attributes to Basic Cluster wpan_envelope_reply( &reply_envelope, envelope); reply_envelope.source_endpoint = client_read.ep->endpoint; reply_envelope.profile_id = client_read.ep->profile_id; reply_envelope.cluster_id = client_read.cluster_id; // use broadcast endpoint reply_envelope.dest_endpoint = 0xFF; reply_envelope.options = current_profile->flags; zcl_client_read_attributes( &reply_envelope, &client_read); } // just need to find one return WPAN_CONVERSATION_CONTINUE; }