// see xbee/device.h for documentation
xbee_wpan_debug
int _xbee_handle_transmit_status( xbee_dev_t *xbee,
	const void FAR *payload, uint16_t length, void FAR *context)
{
	#ifdef XBEE_DEVICE_VERBOSE
		const xbee_frame_transmit_status_t FAR *frame = payload;
	#else
		XBEE_UNUSED_PARAMETER( payload);
	#endif

	// standard XBee frame handler; stub isn't using any parameters yet
	XBEE_UNUSED_PARAMETER( xbee);
	XBEE_UNUSED_PARAMETER( length);
	XBEE_UNUSED_PARAMETER( context);

	// it may be necessary to push information up to user code so they know when
	// a packet has been received or if it didn't make it out
	#ifdef XBEE_DEVICE_VERBOSE
	xSerialxPrintf_P( &xSerial1Port, PSTR( "%s: id 0x%02x to 0x%04x retries=%d del=0x%02x disc=0x%02x\n"),
			__FUNCTION__, frame->frame_id,
			be16toh( frame->network_address_be), frame->retries, frame->delivery,
			frame->discovery);
	#endif

	return 0;
}
/**
	@internal
	Dump the contents of the frame dispatch table for XBee
	device \a xbee.  Must have XBEE_DEVICE_VERBOSE defined.

	@param[in]	xbee	XBee device of table to dump.
*/
_xbee_device_debug
void _xbee_dispatch_table_dump( const xbee_dev_t *xbee)
{
#ifndef XBEE_DEVICE_VERBOSE
	// empty/ignored function unless VERBOSE output enabled
	XBEE_UNUSED_PARAMETER( xbee);
#else
	uint_fast8_t i;
	const xbee_dispatch_table_entry_t *entry;

	if (! xbee)
	{
		return;
	}

	puts( "Index\tType\tID\tHandler\tContext");
	entry = xbee_frame_handlers;
	for (i = 0; entry->frame_type != 0xFF; ++i, ++entry)
	{
		if (entry->frame_type)
		{
			printf( "%3d:\t0x%02x\t0x%02x\t0x%p\t%" PRIpFAR "\n", i,
				entry->frame_type, entry->frame_id, entry->handler, entry->context);
		}
		else
		{
			printf( "%3d:\t[empty]\n", i);
		}
	}
#endif
}
int zdo_device_annce_handler( const wpan_envelope_t FAR *envelope,
		void FAR *context)
{
	addr64 addr_be;
	char buffer[ADDR64_STRING_LENGTH];
	const zdo_device_annce_t FAR *annce;

	// Standard wpan_aps_handler_fn callback, but we don't use the context param.
	XBEE_UNUSED_PARAMETER( context);

	if (envelope == NULL)
	{
		return -EINVAL;
	}

	annce = envelope->payload;
	memcpy_letobe( &addr_be, &annce->ieee_address_le, 8);
	printf( "Device Announce %" PRIsFAR " (0x%04x) cap 0x%02x\n",
		addr64_format( buffer, &addr_be), le16toh( annce->network_addr_le),
		annce->capability);

	// discover the commissioning cluster and hand off to xbee_found?

	return 0;
}
Example #4
0
/**
	@internal
	@brief
	Special code for setting bitfield of TimeStatus attribute.

	See ZCL Spec section 3.12.2.2.2 for rules on setting values in this field.

	Only used if device has a Time Server.
*/
_zcl_time_debug
int _zcl_time_timestatus_set( const zcl_attribute_full_t FAR *attribute,
	zcl_attribute_write_rec_t *rec)
{
	uint8_t time_status;

	// zcl_attribute_write_fn API, but 'attribute' parameter's value is always
	// a pointer to 'time_status' variable.
	XBEE_UNUSED_PARAMETER( attribute);

	if (rec->flags & ZCL_ATTR_WRITE_FLAG_ASSIGN)
	{
		// Master and MasterZoneDst bits are not settable.
		// If Master is set to 1, Synchronized bit is always set to 0.

		time_status = *rec->buffer;
		// can only set the Synchronized bit if Master bit is not set
		if (!(zcl_time_timestatus & ZCL_TIME_STATUS_MASTER))
		{
			if (time_status & ZCL_TIME_STATUS_SYNCHRONIZED)
			{
				// set Synchronized bit
				zcl_time_timestatus |= ZCL_TIME_STATUS_SYNCHRONIZED;
			}
			else
			{
				// clear Synchronized bit
				zcl_time_timestatus &= ~ZCL_TIME_STATUS_SYNCHRONIZED;
			}
		}
	}

	return 1;
}
Example #5
0
/**
	@internal
	@brief
	Function registered to #ZCL_TIME_ATTR_TIME attribute of Time Cluster and
	called to refresh the Time attribute (global zcl_time_time).

	See zcl_attribute_update_fn() for calling convention.
*/
_zcl_time_debug
uint_fast8_t _zcl_time_time_get( const zcl_attribute_full_t FAR *attribute)
{
	// zcl_attribute_update_fn API, but 'attribute' parameter's value is always
	// a pointer to 'zcl_time_time' variable.
	XBEE_UNUSED_PARAMETER( attribute);

#if ZCL_TIME_EPOCH_DELTA > 0
	if (! zcl_time_skew && xbee_seconds_timer() < ZCL_TIME_EPOCH_DELTA)
	{
		// we don't really know what time it is...
		zcl_time_time = ZCL_UTCTIME_INVALID;
	}
	else
#endif
	{
		zcl_time_time = zcl_time_skew +
								(xbee_seconds_timer() - ZCL_TIME_EPOCH_DELTA);
	}

	#ifdef ZCL_TIME_VERBOSE
		printf( "%s: read clock & updated zcl_time_time to 0x%" PRIx32 "\n",
			__FUNCTION__, zcl_time_time);
	#endif

	return ZCL_STATUS_SUCCESS;
}
// hook for GetOpenFileName to move window to foreground
UINT APIENTRY OFNHookProc(HWND h, UINT msg, WPARAM wParam, LPARAM lParam)
{
    HWND hwndDlg, hwndOwner;
    RECT rc, rcDlg, rcOwner;

    // This function follows the standard API for an OPENFILENAME lpfnHook,
    // but we aren't using all of its parameters.  Since we set the OFN_EXPLORER
    // flag, this is an OFNHookProc.
    XBEE_UNUSED_PARAMETER( wParam);
    XBEE_UNUSED_PARAMETER( lParam);

    // Code to center window over console based on code from
    // http://msdn.microsoft.com/en-us/library/ms644996(v=VS.85).aspx#init_box
    if (msg == WM_INITDIALOG)
    {
        hwndDlg = GetParent(h);
        hwndOwner = GetConsoleWindow();

        GetWindowRect(hwndOwner, &rcOwner);
        GetWindowRect(hwndDlg, &rcDlg);
        CopyRect(&rc, &rcOwner);

        // Offset the owner and dialog box rectangles so that right and bottom
        // values represent the width and height, and then offset the owner again
        // to discard space taken up by the dialog box.

        OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
        OffsetRect(&rc, -rc.left, -rc.top);
        OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);

        // The new position is the sum of half the remaining space and the owner's
        // original position.

        SetWindowPos(hwndDlg,
                     HWND_TOPMOST,
                     rcOwner.left + (rc.right / 2),
                     rcOwner.top + (rc.bottom / 2),
                     0, 0,          // Ignores size arguments.
                     SWP_NOSIZE | SWP_SHOWWINDOW);
        return TRUE;
    }

    return FALSE;
}
int xbee_ota_error( const wpan_envelope_t	FAR *envelope,
	void FAR *context)
{
	// This cluster callback has a NULL context in the cluster table, so
	// there's no need to reference it here.
	XBEE_UNUSED_PARAMETER( context);

	// display any error messages sent to the OTA update client
	puts( "Error from target:");
	printf( "%.*s\n", envelope->length, (char *) envelope->payload);

	return 0;
}
	// ideas for flags:
	//		show portname
	//		extended dump
	//		super dump?  (state information)
_xbee_device_debug
void xbee_dev_dump_settings( xbee_dev_t *xbee, uint16_t flags)
{
	char addr[ADDR64_STRING_LENGTH];

	// flags parameter included in API for future expansion; unused for now
	XBEE_UNUSED_PARAMETER( flags);

	printf( "XBee on %s: HV=0x%x  VR=0x%" PRIx32 "  IEEE=%" PRIsFAR
		"  net=0x%04x\n\n", xbee_ser_portname( &xbee->serport),
		xbee->hardware_version, xbee->firmware_version,
		addr64_format( addr, &xbee->wpan_dev.address.ieee),
		xbee->wpan_dev.address.network);
}
/**
	Process XBee "Receive Explicit" frames (type 0x91) and hand
	off to wpan_envelope_dispatch() for further processing.

	Please view the function help for xbee_frame_handler_fn() for details
	on this function's parameters and possible return values.
*/
xbee_wpan_debug
int _xbee_handle_receive_explicit( xbee_dev_t *xbee, const void FAR *raw,
	uint16_t length, void FAR *context)
{
	const xbee_frame_receive_explicit_t FAR *frame = raw;
	wpan_envelope_t	env;

	// this XBee frame handler (standard API) doesn't use the context parameter
	XBEE_UNUSED_PARAMETER( context);

	if (frame == NULL)
	{
		return -EINVAL;
	}
	if (length < offsetof( xbee_frame_receive_explicit_t, payload))
	{
		// invalid frame -- should always be at least as long as payload field
		return -EBADMSG;
	}

	env.dev = &(xbee->wpan_dev);
	env.ieee_address = frame->ieee_address;
	env.network_address = be16toh( frame->network_address_be);
	env.source_endpoint = frame->source_endpoint;
	env.dest_endpoint = frame->dest_endpoint;
	env.cluster_id = be16toh( frame->cluster_id_be);
	env.profile_id = be16toh( frame->profile_id_be);
	env.options = 0;
	if (frame->options & XBEE_RX_OPT_BROADCAST)
	{
		env.options |= WPAN_ENVELOPE_BROADCAST_ADDR;
	}
	if (frame->options & XBEE_RX_OPT_APS_ENCRYPT)
	{
		env.options |= WPAN_ENVELOPE_RX_APS_ENCRYPT;
	}
	env.payload = frame->payload;
	env.length = length - offsetof( xbee_frame_receive_explicit_t, payload);

	return wpan_envelope_dispatch( &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;
}