int basic_client( const wpan_envelope_t FAR *envelope, void FAR *context) { zcl_command_t zcl; if (zcl_command_build( &zcl, envelope, context) == 0 && zcl.command == ZCL_CMD_READ_ATTRIB_RESP && ZCL_CMD_MATCH( &zcl.frame_control, GENERAL, SERVER_TO_CLIENT, PROFILE)) { // response to our read basic attr return basic_parse( &zcl); } return zcl_general_command( envelope, context); }
/* START _FUNCTION DESCRIPTION ******************************************* _zcl_basic_server <zcl_basic.c> SYNTAX: int _zcl_basic_server( const wpan_envelope_t FAR *envelope, void FAR *context) DESCRIPTION: Handles commands for the Basic Server Cluster. Currently supports the only command ID in the spec, 0x00 - Reset to Factory Defaults. NOTE: You must define the macro ZCL_FACTORY_RESET_FN in your program, and have it point to a function to be called when a factory reset command is sent. **************************************************************************/ int _zcl_basic_server( const wpan_envelope_t FAR *envelope, void FAR *context) { zcl_command_t zcl; if (zcl_command_build( &zcl, envelope, context) == 0 && ZCL_CMD_MATCH( &zcl.frame_control, GENERAL, CLIENT_TO_SERVER, CLUSTER)) { // This function only handles command 0x00, reset to factory defaults. if (zcl.command == ZCL_BASIC_CMD_FACTORY_DEFAULTS) { #ifdef ZCL_BASIC_VERBOSE printf( "%s: resetting to factory defaults\n", __FUNCTION__); #endif ZCL_FACTORY_RESET_FN(); return zcl_default_response( &zcl, ZCL_STATUS_SUCCESS); } } return zcl_general_command( envelope, context); }
// TODO: make use of zcl_process_read_attr_response() in zcl_client.c to parse // Read Attributes Response and populate a temporary attribute list with the // values. _zcl_time_debug int zcl_time_client( const wpan_envelope_t FAR *envelope, void FAR *context) { zcl_command_t zcl; // We're only expecting Read Attribute Responses. // Make sure frame is server-to-client, not manufacturer-specific and // a profile (not cluster) command. if (zcl_command_build( &zcl, envelope, context) == 0 && zcl.command == ZCL_CMD_READ_ATTRIB_RESP && ZCL_CMD_MATCH( &zcl.frame_control, GENERAL, SERVER_TO_CLIENT, PROFILE)) { const zcl_header_t FAR *header = envelope->payload; union { const uint8_t FAR *u8; const uint16_t FAR *u16_le; const uint32_t FAR *u32_le; } walk; // used to walk the payload uint8_t FAR *payload_end; uint16_t attribute_id; uint8_t attribute_type; zcl_utctime_t time = 0; uint8_t time_status = 0; uint8_t response = ZCL_STATUS_SUCCESS; #ifdef ZCL_TIME_VERBOSE printf( "%s: %d-byte payload to time client\n", __FUNCTION__, envelope->length); hex_dump( envelope->payload, envelope->length, HEX_DUMP_FLAG_TAB); #endif payload_end = ((uint8_t FAR *)envelope->payload) + envelope->length; walk.u8 = header->type.std.common.payload; while (response == ZCL_STATUS_SUCCESS && walk.u8 < payload_end) { attribute_id = le16toh( *walk.u16_le++); if (*walk.u8++ == ZCL_STATUS_SUCCESS) { attribute_type = *walk.u8++; if (attribute_id == ZCL_TIME_ATTR_TIME) { if (attribute_type != ZCL_TYPE_TIME_UTCTIME) { response = ZCL_STATUS_INVALID_DATA_TYPE; } else { time = le32toh( *walk.u32_le++); } } else if (attribute_id == ZCL_TIME_ATTR_TIME_STATUS) { if (attribute_type != ZCL_TYPE_BITMAP_8BIT) { response = ZCL_STATUS_INVALID_DATA_TYPE; } else { time_status = *walk.u8++; } } else { // unexpected attribute in response response = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE; } } } // didn't get a valid time in response if (response == ZCL_STATUS_SUCCESS && ! time) { #ifdef ZCL_TIME_VERBOSE printf( "%s: response did not contain a valid time\n", __FUNCTION__); #endif response = ZCL_STATUS_FAILURE; } if (response == ZCL_STATUS_SUCCESS) { #ifdef ZCL_TIME_VERBOSE printf( "%s: the time is %" PRIu32 "\n", __FUNCTION__, time); #endif // only set the clock if the response has a valid time if (time != ZCL_UTCTIME_INVALID && (time_status & (ZCL_TIME_STATUS_MASTER | ZCL_TIME_STATUS_SYNCHRONIZED)) != 0) { zcl_time_time = time; _zcl_time_time_set( NULL, NULL); // set Synchronized bit of our TimeStatus zcl_time_timestatus |= ZCL_TIME_STATUS_SYNCHRONIZED; } } return zcl_default_response( &zcl, response); } // command not handled by this function, try general command handler return zcl_general_command( envelope, context); }