Beispiel #1
0
/*
	main

	Initiate communication with the XBee module, then accept AT commands from
	STDIO, pass them to the XBee module and print the result.
*/
int main( int argc, char *argv[])
{
   char cmdstr[80];
	int status;
	xbee_serial_t XBEE_SERPORT;

	parse_serial_arguments( argc, argv, &XBEE_SERPORT);

	// initialize the serial and device layer for this XBee device
	if (xbee_dev_init( &my_xbee, &XBEE_SERPORT, NULL, NULL))
	{
		printf( "Failed to initialize device.\n");
		return 0;
	}

	// Initialize the AT Command layer for this XBee device and have the
	// driver query it for basic information (hardware version, firmware version,
	// serial number, IEEE address, etc.)
	xbee_cmd_init_device( &my_xbee);
	printf( "Waiting for driver to query the XBee device...\n");
	do {
		xbee_dev_tick( &my_xbee);
		status = xbee_cmd_query_status( &my_xbee);
	} while (status == -EBUSY);
	if (status)
	{
		printf( "Error %d waiting for query to complete.\n", status);
	}

	// report on the settings
	xbee_dev_dump_settings( &my_xbee, XBEE_DEV_DUMP_FLAG_DEFAULT);

   printATCmds( &my_xbee);

   while (1)
   {
      while (xbee_readline( cmdstr, sizeof cmdstr) == -EAGAIN)
      {
      	xbee_dev_tick( &my_xbee);
      }

		if (! strncmpi( cmdstr, "menu", 4))
      {
      	printATCmds( &my_xbee);
      }
      else if (! strcmpi( cmdstr, "quit"))
      {
			return 0;
		}
      else
      {
			process_command( &my_xbee, cmdstr);
	   }
   }
}
/*
	main

	Initiate communication with the XBee module, then accept AT commands from
	STDIO, pass them to the XBee module and print the result.
*/
int main( void)
{
    char cmdstr[80];
    int status;
    uint16_t t;


    if (xbee_dev_init( &my_xbee, &XBEE_SERPORT, xbee_awake_pin, xbee_reset_pin))
    {
        printf( "Failed to initialize device.\n");
        return 0;
    }

    //xbee_dev_reset( &my_xbee);
    // give the XBee 500ms to wake up after resetting it (or exit if it
    // receives a packet)
    t = XBEE_SET_TIMEOUT_MS(500);
    while (! XBEE_CHECK_TIMEOUT_MS(t) && xbee_dev_tick( &my_xbee) <= 0);

    // Initialize the AT Command layer for this XBee device and have the
    // driver query it for basic information (hardware version, firmware version,
    // serial number, IEEE address, etc.)
    xbee_cmd_init_device( &my_xbee);
    printf( "Waiting for driver to query the XBee device...\n");
    do {
        xbee_dev_tick( &my_xbee);
        status = xbee_cmd_query_status( &my_xbee);
    } while (status == -EBUSY);
    if (status)
    {
        printf( "Error %d waiting for query to complete.\n", status);
    }

    // report on the settings
    xbee_dev_dump_settings( &my_xbee, XBEE_DEV_DUMP_FLAG_DEFAULT);

    printATCmds( &my_xbee);
    printf("Target setting for remote commands:\n");
    printf(" > addr   (addr is hex ieee addr, high bytes assumed 0013a200)\n");
    printf(" >        (reset to local device)\n");
    printf(" <        (reinstate previous remote target)\n");

    while (1)
    {
        while (xbee_readline( cmdstr, sizeof cmdstr) == -EAGAIN)
        {
            xbee_dev_tick( &my_xbee);
        }

        if (! strncmpi( cmdstr, "menu", 4))
        {
            printATCmds( &my_xbee);
        }
        else if (! strcmpi( cmdstr, "quit"))
        {
            return 0;
        }
        else if ( cmdstr[0] == '>')
        {
            have_target = set_target( cmdstr+1, &target_ieee);
        }
        else if ( cmdstr[0] == '<')
        {
            if (ever_had_target)
            {
                have_target = 1;
                printf("Reinstating %" PRIsFAR "\n",
                       addr64_format(cmdstr, &target_ieee));
            }
            else
            {
                printf("Nothing to reinstate\n");
            }
        }
        else
        {
            have_target ?
            process_command_remote( &my_xbee, cmdstr, &target_ieee) :
            process_command( &my_xbee, cmdstr);
        }
    }
}
int main( int argc, char *argv[])
{
   char cmdstr[80];
	int status, i;
	xbee_serial_t XBEE_SERPORT;
	target_t *target = NULL;

	memset( target_list, 0, sizeof target_list);

	parse_serial_arguments( argc, argv, &XBEE_SERPORT);

	// initialize the serial and device layer for this XBee device
	if (xbee_dev_init( &my_xbee, &XBEE_SERPORT, NULL, NULL))
	{
		printf( "Failed to initialize device.\n");
		return 0;
	}

	// replace ZDO cluster table with one that intercepts Device Annce messages
	sample_endpoints.zdo.cluster_table = zdo_clusters;

	// Initialize the WPAN layer of the XBee device driver.  This layer enables
	// endpoints and clusters, and is required for all ZigBee layers.
	xbee_wpan_init( &my_xbee, &sample_endpoints.zdo);

	// Initialize the AT Command layer for this XBee device and have the
	// driver query it for basic information (hardware version, firmware version,
	// serial number, IEEE address, etc.)
	xbee_cmd_init_device( &my_xbee);
	printf( "Waiting for driver to query the XBee device...\n");
	do {
		xbee_dev_tick( &my_xbee);
		status = xbee_cmd_query_status( &my_xbee);
	} while (status == -EBUSY);
	if (status)
	{
		printf( "Error %d waiting for query to complete.\n", status);
	}

	// report on the settings
	xbee_dev_dump_settings( &my_xbee, XBEE_DEV_DUMP_FLAG_DEFAULT);

	// set Profile ID for our Basic Client Cluster endpoint
	sample_endpoints.zcl.profile_id = profile_id;

   print_help();

   puts( "searching for Commissioning Servers");
	find_devices();

	while (1)
   {
      while (xbee_readline( cmdstr, sizeof cmdstr) == -EAGAIN)
      {
      	wpan_tick( &my_xbee.wpan_dev);
      }

		if (! strcmpi( cmdstr, "quit"))
      {
			return 0;
		}
		else if (! strcmpi( cmdstr, "help") || ! strcmp( cmdstr, "?"))
		{
			print_help();
		}
		else if (! strncmpi( cmdstr, "profile ", 8))
		{
			profile_id = strtoul( &cmdstr[8], NULL, 16);
			printf( "Profile ID set to 0x%04x\n", profile_id);
			sample_endpoints.zcl.profile_id = profile_id;
		}
		else if (! strcmpi( cmdstr, "find"))
		{
			find_devices();
		}
		else if (! strcmpi( cmdstr, "target"))
		{
			puts( " #: --IEEE Address--- Ver. --------Application Name--------"
				" ---Date Code----");
			for (i = 0; i < target_index; ++i)
			{
				print_target( i);
			}
			puts( "End of List");
		}
		else if (! strncmpi( cmdstr, "target ", 7))
		{
			i = (int) strtoul( &cmdstr[7], NULL, 10);
			if (target_index == 0)
			{
				printf( "error, no targets in list, starting search now...\n");
				find_devices();
			}
			else if (i < 0 || i >= target_index)
			{
				printf( "error, index %d is invalid (must be 0 to %u)\n", i,
					target_index - 1);
			}
			else
			{
				target = &target_list[i];
				puts( "set target to:");
				print_target( i);
			}
		}
		else if (! strcmpi( cmdstr, "save"))
		{
			restart_target( target, TRUE);
		}
		else if (! strcmpi( cmdstr, "cancel"))
		{
			restart_target( target, FALSE);
		}
		else if (! strcmpi( cmdstr, "default"))
		{
			default_target( target);
		}
		else if (! strcmpi( cmdstr, "deploy"))
		{
			set_pan( target, &network_deploy);
		}
		else if (! strncmpi( cmdstr, "deploy ", 7))
		{
			if (cmdstr[7] == 'r')
			{
				puts( "deploy as router");
				network_deploy.startup_control = ZCL_COMM_STARTUP_JOINED;
			}
			else if (cmdstr[7] == 'c')
			{
				puts( "deploy as coordinator");
				network_deploy.startup_control = ZCL_COMM_STARTUP_COORDINATOR;
			}
			set_pan( target, &network_deploy);
		}
		else if (! strcmpi( cmdstr, "comm"))
		{
			set_pan( target, &network_comm);
		}
		else if (! strncmpi( cmdstr, "AT", 2))
		{
			process_command( &my_xbee, &cmdstr[2]);
		}
	   else
	   {
	   	printf( "unknown command: '%s'\n", cmdstr);
	   }
   }
}
Beispiel #4
0
/*
	main

	Initiate communication with the XBee module, then accept AT commands from
	STDIO, pass them to the XBee module and print the result.
*/
int main( int argc, char *argv[])
{
   char cmdstr[80];
   char buffer[ADDR64_STRING_LENGTH];
	int status;
	xbee_serial_t XBEE_SERPORT;
	addr64 return_ieee_be = *ZDO_IEEE_ADDR_PENDING;
	uint16_t return_net_addr = ZDO_NET_ADDR_PENDING;
	int err;

	parse_serial_arguments( argc, argv, &XBEE_SERPORT);

	// initialize the serial and device layer for this XBee device
	if (xbee_dev_init( &my_xbee, &XBEE_SERPORT, NULL, NULL))
	{
		printf( "Failed to initialize device.\n");
		return 0;
	}

	// Initialize the WPAN layer of the XBee device driver.  This layer enables
	// endpoints and clusters, and is required for all ZigBee layers.
	xbee_wpan_init( &my_xbee, &sample_endpoints.zdo);

	// Initialize the AT Command layer for this XBee device and have the
	// driver query it for basic information (hardware version, firmware version,
	// serial number, IEEE address, etc.)
	xbee_cmd_init_device( &my_xbee);
	printf( "Waiting for driver to query the XBee device...\n");
	do {
		xbee_dev_tick( &my_xbee);
		status = xbee_cmd_query_status( &my_xbee);
	} while (status == -EBUSY);
	if (status)
	{
		printf( "Error %d waiting for query to complete.\n", status);
	}

	// report on the settings
	xbee_dev_dump_settings( &my_xbee, XBEE_DEV_DUMP_FLAG_DEFAULT);

	// have XBee handle ZDO responses -- on SE device, need to have it respond
	// to match descriptors looking for the Key Establishment cluster.
	xbee_cmd_simple( &my_xbee, "AO", 1);

   print_help();

   while (1)
   {
      while (xbee_readline( cmdstr, sizeof cmdstr) == -EAGAIN)
      {
      	wpan_tick( &my_xbee.wpan_dev);
      	if (! addr64_equal( &return_ieee_be, ZDO_IEEE_ADDR_PENDING))
      	{
				if (addr64_equal( &return_ieee_be, ZDO_IEEE_ADDR_TIMEOUT))
				{
					puts( "IEEE_addr request timed out");
				}
				else if (addr64_is_zero( &return_ieee_be))
				{
					printf( "Error retrieving IEEE_addr");
				}
				else
				{
					printf( "IEEE address is %" PRIsFAR "\n",
						addr64_format( buffer, &return_ieee_be));
				}
				return_ieee_be = *ZDO_IEEE_ADDR_PENDING;
      	}
      	if (return_net_addr != ZDO_NET_ADDR_PENDING)
      	{
      		if (return_net_addr == ZDO_NET_ADDR_TIMEOUT)
      		{
					puts( "NWK_addr request timed out");
      		}
      		else if (return_net_addr == ZDO_NET_ADDR_ERROR)
      		{
					printf( "Error retrieving NWK_addr");
      		}
      		else
      		{
      			printf( "Network address is 0x%04X\n", return_net_addr);
      		}
      		return_net_addr = ZDO_NET_ADDR_PENDING;
      	}
      }

		if (! strcmpi( cmdstr, "help") || ! strcmp( cmdstr, "?"))
		{
			print_help();
		}
      else if (! strcmpi( cmdstr, "quit"))
      {
			return 0;
		}
		else if (! strncmpi( cmdstr, "ieee ", 5))
		{
			addr64 ieee_be;

			if (addr64_parse( &ieee_be, &cmdstr[5]))
			{
				printf( "couldn't parse '%s'\n", &cmdstr[5]);
			}
			else
			{
				err = zdo_send_nwk_addr_req( &my_xbee.wpan_dev, &ieee_be,
					&return_net_addr);
				printf( "sent NWK_addr request for %" PRIsFAR " (err=%d)\n",
					addr64_format( buffer, &ieee_be), err);
			}
		}
		else if (! strncmpi( cmdstr, "net ", 4))
		{
			uint16_t net_addr;
			char *tail;

			net_addr = strtoul( &cmdstr[4], &tail, 0);
			if (tail == NULL)
			{
				printf( "couldn't parse '%s'\n", &cmdstr[4]);
			}
			else
			{
				err = zdo_send_ieee_addr_req( &my_xbee.wpan_dev, net_addr,
					&return_ieee_be);
				printf( "sent IEEE_addr request for 0x%04X (err=%d)\n", net_addr,
					err);
			}
		}
      else if (! strncmpi( cmdstr, "AT", 2))
      {
			process_command( &my_xbee, cmdstr);
	   }
   }
}
/*
	main

	Initiate communication with the XBee module, then accept AT commands from
	STDIO, pass them to the XBee module and print the result.
*/
int main( void)
{
   char cmdstr[80];
	int status;
	int i;
	xbee_node_id_t *target = NULL;


	// initialize the serial and device layer for this XBee device
	if (xbee_dev_init( &my_xbee, &XBEE_SERPORT, xbee_awake_pin, xbee_reset_pin))
	{
		printf( "Failed to initialize device.\n");
		return 0;
	}

	// Initialize the WPAN layer of the XBee device driver.  This layer enables
	// endpoints and clusters, and is required for all ZigBee layers.
	xbee_wpan_init( &my_xbee, sample_endpoints);

	// Register handler to receive Node ID messages
	xbee_disc_add_node_id_handler( &my_xbee, &node_discovered);

	// Initialize the AT Command layer for this XBee device and have the
	// driver query it for basic information (hardware version, firmware version,
	// serial number, IEEE address, etc.)
	xbee_cmd_init_device( &my_xbee);
	printf( "Waiting for driver to query the XBee device...\n");
	do {
		xbee_dev_tick( &my_xbee);
		status = xbee_cmd_query_status( &my_xbee);
	} while (status == -EBUSY);
	if (status)
	{
		printf( "Error %d waiting for query to complete.\n", status);
	}

	// report on the settings
	xbee_dev_dump_settings( &my_xbee, XBEE_DEV_DUMP_FLAG_DEFAULT);

	print_menu();
	xbee_disc_discover_nodes( &my_xbee, NULL);

   while (1)
   {
      while (xbee_readline( cmdstr, sizeof cmdstr) == -EAGAIN)
      {
      	wpan_tick( &my_xbee.wpan_dev);
      	xbee_cmd_tick();
      }

		if (! strcmpi( cmdstr, "help") || ! strcmp( cmdstr, "?"))
		{
			print_menu();
		}
		else if (! strncmpi( cmdstr, "nd", 2))
      {
			// Initiate discovery for a specified node id (as parameter in command
			// or all node IDs.
			if (cmdstr[2] == ' ')
			{
				printf( "Looking for node [%s]...\n", &cmdstr[3]);
				xbee_disc_discover_nodes( &my_xbee, &cmdstr[3]);
			}
			else
			{
				puts( "Discovering nodes...");
				xbee_disc_discover_nodes( &my_xbee, NULL);
			}
      }
      else if (! strcmpi( cmdstr, "quit"))
      {
			return 0;
		}
      else if (! strncmpi( cmdstr, "AT", 2))
      {
			process_command( &my_xbee, cmdstr);
	   }
	   else if (! strcmpi( cmdstr, "target"))
	   {
	   	node_table_dump();
	   }
	   else if (! strncmpi( cmdstr, "target", 6))
	   {
	   	target = node_by_name( &cmdstr[7]);
	   	if (target == NULL)
	   	{
	   		printf( "couldn't find a target named '%s'\n", &cmdstr[7]);
	   	}
	   	else
	   	{
	   		printf( "target: ");
	   		xbee_disc_node_id_dump( target);
	   	}
	   }
	   else
	   {
	   	if (target == NULL)
	   	{
	   		puts( "you must first select a target with the `target` command");
	   	}
	   	else
	   	{
	   		i = strlen( cmdstr);
	   		printf( "sending %u bytes to '%s'\n", i, target->node_info);
	   		send_data( target, cmdstr, i);
	   	}
	   }
   }
}
Beispiel #6
0
/*
	main

	Initiate communication with the XBee module, then accept AT commands from
	STDIO, pass them to the XBee module and print the result.
*/
int main( int argc, char *argv[])
{
   char cmdstr[80];
	int status;
	xbee_serial_t XBEE_SERPORT;
	uint16_t params[3];

	parse_serial_arguments( argc, argv, &XBEE_SERPORT);

	// initialize the serial and device layer for this XBee device
	if (xbee_dev_init( &my_xbee, &XBEE_SERPORT, NULL, NULL))
	{
		printf( "Failed to initialize device.\n");
		return 0;
	}

	// Initialize the WPAN layer of the XBee device driver.  This layer enables
	// endpoints and clusters, and is required for all ZigBee layers.
	xbee_wpan_init( &my_xbee, sample_endpoints);

	// Initialize the AT Command layer for this XBee device and have the
	// driver query it for basic information (hardware version, firmware version,
	// serial number, IEEE address, etc.)
	xbee_cmd_init_device( &my_xbee);
	printf( "Waiting for driver to query the XBee device...\n");
	do {
		xbee_dev_tick( &my_xbee);
		status = xbee_cmd_query_status( &my_xbee);
	} while (status == -EBUSY);
	if (status)
	{
		printf( "Error %d waiting for query to complete.\n", status);
	}

	// report on the settings
	xbee_dev_dump_settings( &my_xbee, XBEE_DEV_DUMP_FLAG_DEFAULT);

	xbee_gpm_envelope_local( &envelope_self, &my_xbee.wpan_dev);
	if (envelope_self.ieee_address.u[0] == 0x0000)
	{
		// We're connected to a Wi-Fi XBee and need to use an IP address
		// (localhost, 127.0.0.1) as the target.
		envelope_self.ieee_address.l[0] = 0;
		envelope_self.ieee_address.l[1] = htobe32( 0x7F000001);
	}

	// get flash info, for use by later commands
	xbee_gpm_get_flash_info( &envelope_self);

   while (1)
   {
      while (xbee_readline( cmdstr, sizeof cmdstr) == -EAGAIN)
      {
      	xbee_dev_tick( &my_xbee);
      }

		if (! strcmpi( cmdstr, "help") || ! strcmp( cmdstr, "?"))
		{
			print_menu();
		}
      else if (! strcmpi( cmdstr, "quit"))
      {
			return 0;
		}
      else if (! strcmpi( cmdstr, "info"))
      {
      	printf( "Sending platform info request (result %d)\n",
      			xbee_gpm_get_flash_info( &envelope_self));
      }
      else if (! strcmpi( cmdstr, "erase all"))
      {
   		printf( "Erasing entire GPM (result %d)\n",
   				xbee_gpm_erase_flash( &envelope_self));
      }
      else if (! strncmpi( cmdstr, "erase ", 6))
      {
      	if (blocksize == 0)
      	{
      		puts( "Need to get 'info' response to learn blocksize before"
      				"erasing a page.");
      	}
      	else if (parse_uint16( params, &cmdstr[6], 1) == 1)
      	{
      		printf( "Erasing block %u (result %d)\n", params[0],
      				xbee_gpm_erase_block( &envelope_self, params[0], blocksize));
      	}
      	else
      	{
      		printf( "Couldn't parse block number from [%s]\n", &cmdstr[6]);
      	}
      }
      else if (! strncmpi( cmdstr, "read", 4))
      {
      	if (parse_uint16( params, &cmdstr[5], 3) == 3)
      	{
      		printf( "Read %u bytes from offset %u of block %u (result %d)\n",
      				params[2], params[1], params[0],
      				xbee_gpm_read( &envelope_self,
      						params[0], params[1], params[2]));
      	}
      	else
      	{
      		printf( "Couldn't parse three values from [%s]\n", &cmdstr[5]);
      	}
      }
      else if (! strcmpi( cmdstr, "pagesize"))
      {
      	printf( "upload page size is %u\n", upload_pagesize);
      }
      else if (! strncmpi( cmdstr, "pagesize ", 9))
      {
      	if (parse_uint16( params, &cmdstr[9], 1) == 1)
			{
				if (params[0] > xbee_gpm_max_write( &my_xbee.wpan_dev))
				{
					printf( "page size of %u exceeds maximum of %u\n",
							params[0], xbee_gpm_max_write( &my_xbee.wpan_dev));
				}
				else
				{
					upload_pagesize = params[0];
					printf( "upload page size is now %u\n", upload_pagesize);
				}
			}
			else
			{
				printf( "Couldn't parse page size from [%s]\n", &cmdstr[9]);
			}
      }
      else if (! strncmpi( cmdstr, "upload ", 7))
      {
      	start_upload( &cmdstr[7]);
      }
      else if (! strcmpi( cmdstr, "verify"))
      {
   		printf( "Verify firmware in GPM (result %d)\n",
   				xbee_gpm_firmware_verify( &envelope_self));
      }
      else if (! strcmpi( cmdstr, "install"))
      {
   		printf( "Install firmware in GPM (result %d)\n",
   				xbee_gpm_firmware_install( &envelope_self));
      }
		else if (! strncmpi( cmdstr, "AT", 2))
		{
			process_command( &my_xbee, &cmdstr[2]);
		}
	   else
	   {
	   	printf( "unknown command: '%s'\n", cmdstr);
	   }
   }
}
int main( int argc, char *argv[])
{
    const char *firmware = NULL;
    char xmodem_buffer[69];
    char cmdstr[80];
    int status, i;
    xbee_serial_t XBEE_SERPORT;
    FILE *fw_file = NULL;
#ifdef VERBOSE
    uint16_t last_state;
#endif
    uint16_t last_packet;
    target_t *target = NULL;

    // turn off buffering so status changes (lines ending in \r) display
    setvbuf( stdout, NULL, _IONBF, 0);

    memset( target_list, 0, sizeof target_list);

    // set serial port
    parse_serial_arguments( argc, argv, &XBEE_SERPORT);

    // parse args for this program
    parse_args( argc, argv);

    // initialize the serial and device layer for this XBee device
    if (xbee_dev_init( &my_xbee, &XBEE_SERPORT, NULL, NULL))
    {
        printf( "Failed to initialize device.\n");
        return 0;
    }

    // Initialize the WPAN layer of the XBee device driver.  This layer enables
    // endpoints and clusters, and is required for all ZigBee layers.
    xbee_wpan_init( &my_xbee, &sample_endpoints.zdo);

    // Initialize the AT Command layer for this XBee device and have the
    // driver query it for basic information (hardware version, firmware version,
    // serial number, IEEE address, etc.)
    xbee_cmd_init_device( &my_xbee);
    printf( "Waiting for driver to query the XBee device...\n");
    do {
        xbee_dev_tick( &my_xbee);
        status = xbee_cmd_query_status( &my_xbee);
    } while (status == -EBUSY);
    if (status)
    {
        printf( "Error %d waiting for query to complete.\n", status);
    }

    // report on the settings
    xbee_dev_dump_settings( &my_xbee, XBEE_DEV_DUMP_FLAG_DEFAULT);

    print_help();

    if (dynamic_profile.profile_id != 0)
    {
        printf( "Using profile ID 0x%04x with%s APS encryption.\n",
                dynamic_profile.profile_id,
                (dynamic_profile.flags & WPAN_CLUST_FLAG_ENCRYPT) ? "" : "out");
        xbee_ota_find_devices( &my_xbee.wpan_dev, xbee_found, NULL);
    }

    while (1)
    {
        while (xbee_readline( cmdstr, sizeof cmdstr) == -EAGAIN)
        {
            wpan_tick( &my_xbee.wpan_dev);

            if (fw_file != NULL)
            {
                if (xbee_xmodem_tx_tick( &xbee_ota.xbxm) != 0)
                {
                    uint16_t timer;

                    printf( "upload complete     \n");
                    fclose( fw_file);
                    fw_file = NULL;

                    // wait one second for device to reboot then rediscover it
                    timer = XBEE_SET_TIMEOUT_MS(1000);
                    while (! XBEE_CHECK_TIMEOUT_MS( timer));

                    xbee_ota_find_devices( &my_xbee.wpan_dev, xbee_found, NULL);
                }

#ifdef VERBOSE
                if (last_state != xbee_ota.xbxm.state)
                {
                    printf( "state change from %u to %u\n", last_state,
                            xbee_ota.xbxm.state);
                    last_state = xbee_ota.xbxm.state;
                }
#endif
                if (last_packet != xbee_ota.xbxm.packet_num)
                {
#ifdef VERBOSE
                    printf( "packet #%u\n", xbee_ota.xbxm.packet_num);
#else
                    printf( " %" PRIu32 " bytes\r",
                            UINT32_C(64) * xbee_ota.xbxm.packet_num);
#endif
                    last_packet = xbee_ota.xbxm.packet_num;
                }
            }
        }

        if (! strcmpi( cmdstr, "quit"))
        {
            return 0;
        }
        else if (! strcmpi( cmdstr, "help") || ! strcmp( cmdstr, "?"))
        {
            print_help();
        }
        else if (! strcmpi( cmdstr, "find"))
        {
            if (dynamic_profile.profile_id == 0)
            {
                puts( "Error: specify a profile via cmd line or 'profile' cmd");
            }
            else
            {
                xbee_ota_find_devices( &my_xbee.wpan_dev, xbee_found, NULL);
            }
        }
        else if (! strncmpi( cmdstr, "profile ", 8))
        {
            dynamic_profile.profile_id = strtoul( &cmdstr[8], NULL, 16);
            printf( "Profile ID set to 0x%04x\n", dynamic_profile.profile_id);
            profile_changed();
        }
        else if (! strcmpi( cmdstr, "target"))
        {
            puts( " #: --IEEE Address--- Ver. --------Application Name--------"
                  " ---Date Code----");
            for (i = 0; i < target_index; ++i)
            {
                print_target( i);
            }
            puts( "End of List");
        }
        else if (! strncmpi( cmdstr, "target ", 7))
        {
            i = (int) strtoul( &cmdstr[7], NULL, 10);
            if (target_index == 0)
            {
                printf( "error, no targets in list, starting search now...\n");
                xbee_ota_find_devices( &my_xbee.wpan_dev, xbee_found, NULL);
            }
            else if (i < 0 || i >= target_index)
            {
                printf( "error, index %d is invalid (must be 0 to %u)\n", i,
                        target_index - 1);
            }
            else
            {
                target = &target_list[i];
                puts( "set target to:");
                print_target( i);
            }
        }
        else if (! strcmpi( cmdstr, "F") && target != NULL)
        {
            // If the target is stuck in the bootloader, send an 'F' to start
            // a firmware update.
            wpan_envelope_t envelope;

            wpan_envelope_create( &envelope, &my_xbee.wpan_dev, &target->ieee,
                                  WPAN_NET_ADDR_UNDEFINED);
            envelope.options = current_profile->flags;
            xbee_transparent_serial_str( &envelope, "F");
        }
        else if (! strcmpi( cmdstr, "firmware"))
        {
            firmware = get_file();
        }
        else if (! strcmpi( cmdstr, "password"))
        {
            set_password( "");
            puts( "cleared password (will use default of a single null byte)");
        }
        else if (! strncmpi( cmdstr, "password ", 9))
        {
            set_password( &cmdstr[9]);
            printf( "set password to [%.*s]\n", xbee_ota.auth_length,
                    xbee_ota.auth_data);
        }
        else if (! strcmpi( cmdstr, "aps"))
        {
            xbee_ota.flags ^= XBEE_OTA_FLAG_APS_ENCRYPT;
            printf( "APS encryption %sabled\n",
                    (xbee_ota.flags & XBEE_OTA_FLAG_APS_ENCRYPT) ? "en" : "dis");
        }
        else if (! strcmpi( cmdstr, "go"))
        {
            if (target == NULL)
            {
                if (target_index > 0)
                {
                    target = &target_list[0];
                }
                else
                {
                    puts( "no targets available to send to");
                    continue;
                }
            }

            if (firmware == NULL)
            {
                firmware = get_file();
                if (firmware == NULL)
                {
                    printf( "Canceled.\n");
                    continue;
                }
            }

            printf( "Starting xmodem upload of\n  %s\n", firmware);

            fw_file = fopen( firmware, "rb");
            if (! fw_file)
            {
                printf( "Failed to open '%s'\n", firmware);
                exit( -1);
            }

            status = xbee_ota_init( &xbee_ota, &my_xbee.wpan_dev, &target->ieee);

            if (status)
            {
                printf( "%s returned %d\n", "xbee_ota_init", status);
                continue;
            }

            status = xbee_xmodem_set_source( &xbee_ota.xbxm, xmodem_buffer,
                                             fw_read, fw_file);
            if (status)
            {
                printf( "%s returned %d\n", "xbee_xmodem_set_source", status);
                continue;
            }

            // reset the xbee_xmodem_state_t state machine, keeping existing flags
            status = xbee_xmodem_tx_init( &xbee_ota.xbxm, xbee_ota.xbxm.flags);
            if (status)
            {
                printf( "%s returned %d\n", "xbee_xmodem_tx_init", status);
                continue;
            }

            // reset copies of basic cluster -- need to refresh after update
            memset( &target->basic, 0, sizeof(target->basic));

#ifdef VERBOSE
            last_state = last_packet = 0;
#endif

            // main loop will tick the xmodem transfre until fw_file == NULL
        }
#ifdef XBEE_XMODEM_TESTING
        else if (! strcmpi( cmdstr, "ACK"))
        {
            xbee_ota.xbxm.flags |= XBEE_XMODEM_FLAG_DROP_ACK;
        }
        else if (! strcmpi( cmdstr, "FRAME"))
        {
            xbee_ota.xbxm.flags |= XBEE_XMODEM_FLAG_DROP_FRAME;
        }
        else if (! strcmpi( cmdstr, "CRC"))
        {
            xbee_ota.xbxm.flags |= XBEE_XMODEM_FLAG_BAD_CRC;
        }
#endif
        else if (! strncmpi( cmdstr, "AT", 2))
        {
            process_command( &my_xbee, &cmdstr[2]);
        }
        else
        {
            printf( "unknown command: '%s'\n", cmdstr);
        }
    }
}