Exemplo n.º 1
0
int tool_cmd_peek(int argc, char* argv[])
{
	int ret = 0;
	int c;
	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
	DBusConnection* connection = NULL;
	DBusMessage *message = NULL;
	DBusMessage *reply = NULL;
	DBusError error;
	uint32_t address = 0;
	uint16_t count = 32;
	bool simple_data_format = false;

	dbus_error_init(&error);

	while (1) {
		static struct option long_options[] = {
			{"help", no_argument, 0, 'h'},
			{"timeout", required_argument, 0, 't'},
			{"count", required_argument, 0, 'c'},
			{"data", no_argument, 0, 'd'},
			{0, 0, 0, 0}
		};

		int option_index = 0;
		c = getopt_long(argc, argv, "ht:c:d", long_options,	&option_index);

		if (c == -1) {
			break;
		}

		switch (c) {
		case 'h':
			print_arg_list_help(peek_option_list, argv[0], peek_cmd_syntax);
			ret = ERRORCODE_HELP;
			goto bail;

		case 't':
			timeout = strtol(optarg, NULL, 0);
			break;

		case 'c':
			count = strtol(optarg, NULL, 0);
			break;

		case 'd':
			simple_data_format = true;
			break;
		}
	}

	if (optind < argc) {
		address = strtol(argv[optind], NULL, 0);
		optind++;
	} else {
		fprintf(stderr,	"%s: error: Missing required address parameter\n", argv[0]);
		ret = ERRORCODE_BADARG;
		goto bail;
	}

	if (optind < argc) {
		fprintf(stderr,	"%s: error: Unexpected extra argument: \"%s\"\n", argv[0], argv[optind]);
		ret = ERRORCODE_BADARG;
		goto bail;
	}

	if (gInterfaceName[0] == 0) {
		fprintf(
			stderr,
			"%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
			argv[0]
		);
		ret = ERRORCODE_BADARG;
		goto bail;
	}

	connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);

	require_string(connection != NULL, bail, error.message);

	{
		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
		bool did_succeed;
		uint8_t *data_ptr = NULL;
		int data_len = 0;
		uint16_t i;

		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
		if (ret != 0) {
			print_error_diagnosis(ret);
			goto bail;
		}
		snprintf(path,
				 sizeof(path),
				 "%s/%s",
				 WPANTUND_DBUS_PATH,
				 gInterfaceName);

		message = dbus_message_new_method_call(
			interface_dbus_name,
			path,
			WPANTUND_DBUS_APIv1_INTERFACE,
			WPANTUND_IF_CMD_PEEK
		);

		fprintf(stdout, "Peeking at address 0x%x (%d) for %d bytes\n", address, address, count);

		dbus_message_append_args(
			message,
			DBUS_TYPE_UINT32, &address,
			DBUS_TYPE_UINT16, &count,
			DBUS_TYPE_INVALID
		);

		reply = dbus_connection_send_with_reply_and_block(
			connection,
			message,
			timeout,
			&error
		);

		if (!reply) {
			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
			ret = ERRORCODE_TIMEOUT;
			goto bail;
		}

		did_succeed = dbus_message_get_args(reply, &error,
			DBUS_TYPE_INT32, &ret,
			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data_ptr, &data_len,
			DBUS_TYPE_INVALID
		);

		if (!did_succeed)
		{
			did_succeed = dbus_message_get_args(reply, NULL,
				DBUS_TYPE_INT32, &ret,
				DBUS_TYPE_INVALID
			);
		}

		if (!did_succeed || ret != 0) {
			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
			print_error_diagnosis(ret);
			goto bail;
		}

		if (simple_data_format) {
			for (i = 0; i < data_len; i++) {
				fprintf(stdout, "%02X ", *data_ptr++);
				if (i % 32 == 31) {
					fprintf(stdout, "\n");
				}
			}
			fprintf(stdout, "\n");
		} else {
			dump_data(data_ptr, data_len);
		}
	}

bail:

	if (connection) {
		dbus_connection_unref(connection);
	}

	if (message) {
		dbus_message_unref(message);
	}

	if (reply) {
		dbus_message_unref(reply);
	}

	dbus_error_free(&error);

	return ret;
}
Exemplo n.º 2
0
int tool_cmd_scan(int argc, char *argv[])
{
	int ret = 0;
	int c;
	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
	DBusConnection* connection = NULL;
	DBusMessage *message = NULL;
	DBusMessage *reply = NULL;
	DBusPendingCall *pending = NULL;
	DBusError error;
	int32_t scan_period = 0;
	uint32_t channel_mask = 0;

	dbus_error_init(&error);

	while (1) {
		static struct option long_options[] = {
			{"help", no_argument, 0, 'h'},
			{"timeout", required_argument, 0, 't'},
			{"channel", required_argument, 0, 'c'},
			{0, 0, 0, 0}
		};

		int option_index = 0;
		c = getopt_long(argc, argv, "hc:t:", long_options,
				&option_index);

		if (c == -1)
			break;

		switch (c) {
		case 'h':
			print_arg_list_help(scan_option_list, argv[0],
					    scan_cmd_syntax);
			ret = ERRORCODE_HELP;
			goto bail;

		case 't':
			timeout = strtol(optarg, NULL, 0);
			break;

		case 'c':
			channel_mask = strtomask_uint32(optarg);
			break;
		}
	}

	if (optind < argc) {
		if (scan_period == 0) {
			scan_period = strtol(argv[optind], NULL, 0);
			optind++;
		}
	}

	if (optind < argc) {
			fprintf(stderr,
			        "%s: error: Unexpected extra argument: \"%s\"\n",
			argv[0], argv[optind]);
			ret = ERRORCODE_BADARG;
			goto bail;
		}

	if (gInterfaceName[0] == 0) {
		fprintf(stderr,
		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
		        argv[0]);
		ret = ERRORCODE_BADARG;
		goto bail;
	}

	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);

	if (!connection) {
		dbus_error_free(&error);
		dbus_error_init(&error);
		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
	}

	require_string(connection != NULL, bail, error.message);

	dbus_bus_add_match(connection, gDBusObjectManagerMatchString, &error);

	require_string(error.name == NULL, bail, error.message);

	dbus_connection_add_filter(connection, &dbus_beacon_handler, NULL, NULL);

	{
		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
		DBusMessageIter iter;
		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);

		if (ret != 0) {
			goto bail;
		}

		snprintf(
			path,
			sizeof(path),
			"%s/%s",
			WPANTUND_DBUS_PATH,
			gInterfaceName
		);

		message = dbus_message_new_method_call(
			interface_dbus_name,
			path,
			WPANTUND_DBUS_APIv1_INTERFACE,
			WPANTUND_IF_CMD_NET_SCAN_START
		);

		dbus_message_append_args(
			message,
			DBUS_TYPE_UINT32, &channel_mask,
			DBUS_TYPE_INVALID
		);

		print_scan_header();

		gScannedNetworkCount = 0;

		if(!dbus_connection_send_with_reply(
		    connection,
		    message,
			&pending,
		    timeout
	    )) {
			fprintf(stderr, "%s: error: IPC failure\n", argv[0]);
			ret = ERRORCODE_UNKNOWN;
			goto bail;
		}

		while ((dbus_connection_get_dispatch_status(connection) == DBUS_DISPATCH_DATA_REMAINS)
			|| dbus_connection_has_messages_to_send(connection)
			|| !dbus_pending_call_get_completed(pending)
		) {
			dbus_connection_read_write_dispatch(connection, 5000 /*ms*/);
		}

		reply = dbus_pending_call_steal_reply(pending);

		require(reply!=NULL, bail);


		dbus_message_iter_init(reply, &iter);

		if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) {
			fprintf(stderr, "%s: error: Server returned a bad response ('%c')\n",
			        argv[0], dbus_message_iter_get_arg_type(&iter));
			ret = ERRORCODE_UNKNOWN;
			goto bail;
		}

		// Get return code
		dbus_message_iter_get_basic(&iter, &ret);

		if (ret) {
			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
			print_error_diagnosis(ret);
			goto bail;
		}
	}


bail:

	if (reply) {
		dbus_message_unref(reply);
	}

	if (pending != NULL) {
		dbus_pending_call_unref(pending);
	}

	if (message) {
		dbus_message_unref(message);
	}

	if (connection) {
		dbus_bus_remove_match(connection, gDBusObjectManagerMatchString, NULL);
		dbus_connection_remove_filter(connection,&dbus_beacon_handler,NULL);
		dbus_connection_unref(connection);
	}

	dbus_error_free(&error);

	return ret;
}
Exemplo n.º 3
0
int tool_cmd_reset(int argc, char *argv[])
{
	int ret = 0;
	int c;
	int timeout = 10 * 1000;
	DBusConnection* connection = NULL;
	DBusMessage *message = NULL;
	DBusMessage *reply = NULL;
	DBusError error;

	dbus_error_init(&error);

	while (1) {
		static struct option long_options[] = {
			{"help", no_argument, 0, 'h'},
			{"timeout", required_argument, 0, 't'},
			{0, 0, 0, 0}
		};

		int option_index = 0;
		c = getopt_long(argc, argv, "ht:", long_options, &option_index);

		if (c == -1)
			break;

		switch (c) {
		case 'h':
			print_arg_list_help(reset_option_list, argv[0],
					    reset_cmd_syntax);
			ret = ERRORCODE_HELP;
			goto bail;

		case 't':
			timeout = strtol(optarg, NULL, 0);
			break;
		}
	}

	if (optind < argc) {
		fprintf(stderr,
		        "%s: error: Unexpected extra argument: \"%s\"\n",
			argv[0], argv[optind]);
		ret = ERRORCODE_BADARG;
		goto bail;
	}

	if (gInterfaceName[0] == 0) {
		fprintf(stderr,
		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
		        argv[0]);
		ret = ERRORCODE_BADARG;
		goto bail;
	}

	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);

	if (!connection) {
		dbus_error_free(&error);
		dbus_error_init(&error);
		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
	}

	require_string(connection != NULL, bail, error.message);

	{
		DBusMessageIter iter;
		DBusMessageIter list_iter;
		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
		if (ret != 0) {
			goto bail;
		}
		snprintf(path,
		         sizeof(path),
		         "%s/%s",
		         WPANTUND_DBUS_PATH,
		         gInterfaceName);

		message = dbus_message_new_method_call(
		    interface_dbus_name,
		    path,
		    WPANTUND_DBUS_APIv1_INTERFACE,
		    WPANTUND_IF_CMD_RESET
		    );

		fprintf(stderr, "Resetting NCP. . .\n");

		reply = dbus_connection_send_with_reply_and_block(
		    connection,
		    message,
		    timeout,
		    &error
		    );

		if (!reply) {
			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
			ret = ERRORCODE_TIMEOUT;
			goto bail;
		}

		dbus_message_get_args(reply, &error,
		                      DBUS_TYPE_INT32, &ret,
		                      DBUS_TYPE_INVALID
		                      );

		if (ret == 6)
			ret = 0;
	}

bail:

	if (connection)
		dbus_connection_unref(connection);

	if (message)
		dbus_message_unref(message);

	if (reply)
		dbus_message_unref(reply);

	dbus_error_free(&error);

	return ret;
}
Exemplo n.º 4
0
int tool_cmd_joiner(int argc, char* argv[])
{
	int ret = 0;
	int c;
	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
	DBusConnection* connection = NULL;
	DBusMessage *message = NULL;
	DBusMessage *reply = NULL;
	DBusMessageIter iter;
	DBusMessageIter dict_iter;
	DBusError error;
	const char *empty_string = "";
	const char *psk = NULL;
	const char *provisioning_url = NULL;
	const char *vendor_name = NULL;
	const char *vendor_model = NULL;
	const char *vendor_sw_version = NULL;
	const char *vendor_data = NULL;
	const char *property_joiner_state = kWPANTUNDProperty_ThreadJoinerState;
	dbus_bool_t action = false;

	dbus_error_init(&error);

	if (argc == 1) {
		fprintf(stderr, "%s: error: Missing command.\n", argv[0]);
		print_arg_list_help(joiner_option_list,
				argv[0], joiner_cmd_syntax);
		goto bail;
	}

	while (1) {
		static struct option long_options[] = {
			{"help", no_argument, 0, 'h'},
			{"timeout", required_argument, 0, 't'},
			{"start", no_argument, 0, 'e'},
			{"stop", no_argument, 0, 'd'},
			{"attach", no_argument, 0, 'a'},
			{"state", no_argument, 0, 's'},
			{0, 0, 0, 0}
		};

		int option_index = 0;
		c = getopt_long(argc, argv, "hst:eda", long_options,
						&option_index);
		if (c == -1) {
			break;
		}

		switch (c) {
		case 'h':
			print_arg_list_help(joiner_option_list,
								argv[0], joiner_cmd_syntax);
			ret = ERRORCODE_HELP;
			goto bail;

		case 't':
			//timeout
			timeout = strtol(optarg, NULL, 0);
			break;

		case 's':
			// state
			if (optind < argc) {
				fprintf(stderr,
						"%s: error: Unexpected extra argument: \"%s\"\n",
						argv[0], argv[optind]);
				ret = ERRORCODE_BADARG;
				goto bail;
			}

			connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);

			ret = create_new_wpan_dbus_message(&message, WPANTUND_IF_CMD_PROP_GET);
			require_action(ret == 0, bail, print_error_diagnosis(ret));

			dbus_message_append_args(
				message,
				DBUS_TYPE_STRING, &property_joiner_state,
				DBUS_TYPE_INVALID
			);

			reply = dbus_connection_send_with_reply_and_block(
				connection,
				message,
				timeout,
				&error
			);

			if (!reply) {
				fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
				ret = ERRORCODE_TIMEOUT;
				goto bail;
			}

			dbus_message_iter_init(reply, &iter);

			// Get return code
			dbus_message_iter_get_basic(&iter, &ret);

			if (ret) {
				const char* error_cstr = NULL;

				// Try to see if there is an error explanation we can extract
				dbus_message_iter_next(&iter);
				if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) {
					dbus_message_iter_get_basic(&iter, &error_cstr);
				}

				if(!error_cstr || error_cstr[0] == 0) {
					error_cstr = (ret<0)?strerror(-ret):"Get failed";
				}

				fprintf(stderr, "%s: %s (%d)\n", property_joiner_state, error_cstr, ret);
				goto bail;
			}

			// Move to the property
			dbus_message_iter_next(&iter);

			uint8_t state;
			dbus_message_iter_get_basic(&iter, &state);
			fprintf(stdout, "%d (%s)\n", state, joiner_state_int2str(state));
			goto bail;

		case 'a':
			// joiner attaches to commissioned thread network
			connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);

			ret = create_new_wpan_dbus_message(&message, WPANTUND_IF_CMD_JOINER_ATTACH);
			require_action(ret == 0, bail, print_error_diagnosis(ret));

			reply = dbus_connection_send_with_reply_and_block(
				connection,
				message,
				timeout,
				&error
			);

			if (!reply) {
				fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
				ret = ERRORCODE_TIMEOUT;
				goto bail;
			}

			dbus_message_get_args(reply, &error,
					DBUS_TYPE_INT32, &ret,
					DBUS_TYPE_INVALID
					);

			if (!ret) {
				fprintf(stderr, "Successfully Attached!\n");
			} else {
				fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
				print_error_diagnosis(ret);
			}
			goto bail;

		case 'e':
			// start commissioning

			if (optind < argc) {
				psk = argv[optind];
				optind++;
			}

			if (!psk) {
				fprintf(stderr, "%s: error: Missing PSK value.\n", argv[0]);
				ret = ERRORCODE_BADARG;
				goto bail;
			}

			ret = check_psk_format(psk);
			if (ret != 0) {
				fprintf(stderr, "%s: error: Invalid PSKd %d\n", argv[0], ret);
				goto bail;
			}

			if (optind < argc) {
				size_t len;

				provisioning_url = argv[optind++];
				len = strnlen(provisioning_url, (COMMR_PROVIISIONING_URL_MAX_LENGTH + 1));

				if (len > COMMR_PROVIISIONING_URL_MAX_LENGTH) {
					fprintf(stderr, "%s: error: Provisioning URL is too long, must be maximum %d characters\n",
						argv[0], COMMR_PROVIISIONING_URL_MAX_LENGTH);
					ret = ERRORCODE_BADARG;
					goto bail;
				}
			}

			if (optind < argc) {
				vendor_name = argv[optind++];
			}

			if (optind < argc) {
				vendor_model = argv[optind++];
			}

			if (optind < argc) {
				vendor_sw_version = argv[optind++];
			}

			if (optind < argc) {
				vendor_data = argv[optind++];
			}

			if (optind < argc) {
				fprintf(stderr,	"%s: error: Unexpected extra argument: \"%s\"\n", argv[0], argv[optind]);
				ret = ERRORCODE_BADARG;
				goto bail;
			}

			connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);

			require_string(connection != NULL, bail, error.message);

			ret = create_new_wpan_dbus_message(&message, WPANTUND_IF_CMD_JOINER_START);
			require_action(ret == 0, bail, print_error_diagnosis(ret));

			dbus_message_iter_init_append(message, &iter);

			// Open a container as "Array of Dictionary entries from String to Variants" (dbus type "a{sv}")
			dbus_message_iter_open_container(
				&iter,
				DBUS_TYPE_ARRAY,
				DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
					DBUS_TYPE_STRING_AS_STRING
					DBUS_TYPE_VARIANT_AS_STRING
				DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
				&dict_iter
			);

			// Append dictionary entries

			append_dbus_dict_entry_basic(
				&dict_iter,
				kWPANTUNDValueMapKey_Joiner_PSKd,
				DBUS_TYPE_STRING, &psk
			);

			if (provisioning_url) {
				append_dbus_dict_entry_basic(
					&dict_iter,
					kWPANTUNDValueMapKey_Joiner_ProvisioningUrl,
					DBUS_TYPE_STRING, &provisioning_url
				);
			}

			if (vendor_name) {
				append_dbus_dict_entry_basic(
					&dict_iter,
					kWPANTUNDValueMapKey_Joiner_VendorName,
					DBUS_TYPE_STRING, &vendor_name
				);
			}

			if (vendor_model) {
				append_dbus_dict_entry_basic(
					&dict_iter,
					kWPANTUNDValueMapKey_Joiner_VendorModel,
					DBUS_TYPE_STRING, &vendor_model
				);
			}

			if (vendor_sw_version) {
				append_dbus_dict_entry_basic(
					&dict_iter,
					kWPANTUNDValueMapKey_Joiner_VendorSwVersion,
					DBUS_TYPE_STRING, &vendor_sw_version
				);
			}

			if (vendor_data) {
				append_dbus_dict_entry_basic(
					&dict_iter,
					kWPANTUNDValueMapKey_Joiner_VendorData,
					DBUS_TYPE_STRING, &vendor_data
				);
			}

			dbus_message_iter_close_container(&iter, &dict_iter);

			// Send DBus message and parse the DBus reply

			reply = dbus_connection_send_with_reply_and_block(connection, message, timeout, &error);

			if (!reply) {
				fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
				ret = ERRORCODE_TIMEOUT;
				goto bail;
			}

			dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);

			if (ret) {
				fprintf(stderr, "Failed to start Joiner Commissioning - error %d. %s\n", ret, wpantund_status_to_cstr(ret));
				print_error_diagnosis(ret);
				goto bail;
			}

			fprintf(stdout, "Started joiner commissioning, PSKd:\"%s\"", psk);

			if (provisioning_url) {
				fprintf(stdout, ", ProvisioningURL:\"%s\"", provisioning_url);
			}

			if (vendor_name) {
				fprintf(stdout, ", VendorName:\"%s\"", vendor_name);
			}

			if (vendor_model) {
				fprintf(stdout, ", VendorModel:\"%s\"", vendor_model);
			}

			if (vendor_sw_version) {
				fprintf(stdout, ", VendorSwVersion:\"%s\"", vendor_sw_version);
			}

			if (vendor_data) {
				fprintf(stdout, ", VendorData:\"%s\"", vendor_data);
			}

			fprintf(stdout, "\n", psk);

			goto bail;

		case 'd':
			// stop commissioning

			if (optind < argc) {
				fprintf(stderr,	"%s: error: Unexpected extra argument: \"%s\"\n", argv[0], argv[optind]);
				ret = ERRORCODE_BADARG;
				goto bail;
			}

			connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);

			require_string(connection != NULL, bail, error.message);

			ret = create_new_wpan_dbus_message(&message, WPANTUND_IF_CMD_JOINER_STOP);
			require_action(ret == 0, bail, print_error_diagnosis(ret));

			reply = dbus_connection_send_with_reply_and_block(connection, message, timeout, &error);

			if (!reply) {
				fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
				ret = ERRORCODE_TIMEOUT;
				goto bail;
			}

			dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);

			if (ret) {
				fprintf(stderr, "Failed to stop joiner commissioning - error %d. %s\n", ret, wpantund_status_to_cstr(ret));
				print_error_diagnosis(ret);
				goto bail;
			}

			fprintf(stdout, "Stopped joiner commissioning\n");
			goto bail;
		}
	}

bail:
	if (connection) {
		dbus_connection_unref(connection);
	}

	if (message) {
		dbus_message_unref(message);
	}

	if (reply) {
		dbus_message_unref(reply);
	}

	dbus_error_free(&error);

	return ret;
}
Exemplo n.º 5
0
int tool_cmd_begin_net_wake(int argc, char *argv[])
{
	int ret = 0;
	int c;
	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
	DBusConnection* connection = NULL;
	DBusMessage *message = NULL;
	DBusMessage *reply = NULL;
	DBusError error;

	bool has_net_wake_data = false;
	uint8_t net_wake_data = 0;
	uint32_t net_wake_flags = -1;

	dbus_error_init(&error);

	while (1) {
		static struct option long_options[] = {
			{"help", no_argument, 0, 'h'},
			{"timeout", required_argument, 0, 't'},
			{0, 0, 0, 0}
		};

		int option_index = 0;
		c = getopt_long(argc, argv, "ht:", long_options, &option_index);

		if (c == -1)
			break;

		switch (c) {
		case 'h':
			print_arg_list_help(begin_net_wake_option_list,
					    argv[0], begin_net_wake_cmd_syntax);
			ret = ERRORCODE_HELP;
			goto bail;

		case 't':
			timeout = strtol(optarg, NULL, 0);
			break;
		}
	}

	if (optind < argc) {
		if (!has_net_wake_data) {
			net_wake_data = strtol(argv[optind], NULL, 0);
			has_net_wake_data = true;
			optind++;
		}
	}

	if (optind < argc) {
		fprintf(stderr,
		        "%s: error: Unexpected extra argument: \"%s\"\n",
		        argv[0], argv[optind]);
		ret = ERRORCODE_BADARG;
		goto bail;
	}

	if (gInterfaceName[0] == 0) {
		fprintf(stderr,
		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
		        argv[0]);
		ret = ERRORCODE_BADARG;
		goto bail;
	}

	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);

	if (!connection) {
		dbus_error_free(&error);
		dbus_error_init(&error);
		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
	}

	require_string(connection != NULL, bail, error.message);

	{
		DBusMessageIter iter;
		DBusMessageIter list_iter;
		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
		if (ret != 0) {
			goto bail;
		}
		snprintf(path,
		         sizeof(path),
		         "%s/%s",
		         WPAN_TUNNEL_DBUS_PATH,
		         gInterfaceName);

		message = dbus_message_new_method_call(
		    interface_dbus_name,
		    path,
		    WPAN_TUNNEL_DBUS_INTERFACE,
		    WPAN_IFACE_CMD_BEGIN_NET_WAKE
		    );

		dbus_message_append_args(
		    message,
		    DBUS_TYPE_BYTE, &net_wake_data,
		    DBUS_TYPE_UINT32, &net_wake_flags,
		    DBUS_TYPE_INVALID
		    );

		fprintf(stderr,
				"Begin Net Wake, data = 0x%02X\n",
				net_wake_data);

		reply = dbus_connection_send_with_reply_and_block(
		    connection,
		    message,
		    timeout,
		    &error
		    );

		if (!reply) {
			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
			ret = ERRORCODE_TIMEOUT;
			goto bail;
		}

		dbus_message_get_args(reply, &error,
		                      DBUS_TYPE_INT32, &ret,
		                      DBUS_TYPE_INVALID
		                      );

		if (ret) {
			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, (ret<0)?strerror(-ret):"");
			print_error_diagnosis(ret);
		}
	}

bail:

	if (connection)
		dbus_connection_unref(connection);

	if (message)
		dbus_message_unref(message);

	if (reply)
		dbus_message_unref(reply);

	dbus_error_free(&error);

	return ret;
}
Exemplo n.º 6
0
int tool_cmd_form(int argc, char* argv[])
{
	int ret = 0;
	int c;
	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
	DBusConnection* connection = NULL;
	DBusMessage *message = NULL;
	DBusMessage *reply = NULL;
	DBusError error;
	const char* network_name = NULL;
	const char* ula_prefix = NULL;
	uint16_t node_type = WPAN_IFACE_ROLE_ROUTER; // Default to router for form
	uint32_t channel_mask = 0;

	dbus_error_init(&error);

	while (1) {
		static struct option long_options[] = {
			{"help", no_argument, 0, 'h'},
			{"timeout", required_argument, 0, 't'},
			{"channel", required_argument, 0, 'c'},
			{"ula-prefix", required_argument, 0, 'u'},
			{"mesh-local-prefix", required_argument, 0, 'M'},
			{"legacy-prefix", required_argument, 0, 'L'},
			{"type", required_argument, 0, 'T'},
			{0, 0, 0, 0}
		};

		int option_index = 0;
		c = getopt_long(argc, argv, "hc:t:T:u:", long_options,
				&option_index);

		if (c == -1)
			break;

		switch (c) {
		case 'h':
			print_arg_list_help(form_option_list, argv[0],
					    form_cmd_syntax);
			ret = ERRORCODE_HELP;
			goto bail;

		case 't':
			timeout = strtol(optarg, NULL, 0);
			break;

		case 'c':
			channel_mask = (1 << strtol(optarg, NULL, 0));
			break;

		case 'M':
			fprintf(stderr,
					"%s: error: Setting the mesh local address at the command line isn't yet implemented. Set it as a property instead.\n",
					argv[0]);
			ret = ERRORCODE_BADARG;
			goto bail;
			break;

		case 'L':
		case 'u':
			ula_prefix = optarg;
			break;

		case 'T':
			node_type = node_type_str2int(optarg);
			break;
		}
	}

	if (optind < argc) {
		if (!network_name) {
			network_name = argv[optind];
			optind++;
		}
	}

	if (optind < argc) {
		fprintf(stderr,
			"%s: error: Unexpected extra argument: \"%s\"\n",
			argv[0], argv[optind]);
		ret = ERRORCODE_BADARG;
		goto bail;
	}

	if (!network_name) {
		fprintf(stderr, "%s: error: Missing network name.\n", argv[0]);
		ret = ERRORCODE_BADARG;
		goto bail;
	}

	if (gInterfaceName[0] == 0) {
		fprintf(stderr,
		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
		        argv[0]);
		ret = ERRORCODE_BADARG;
		goto bail;
	}

	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);

	if (!connection) {
		dbus_error_free(&error);
		dbus_error_init(&error);
		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
	}

	require_string(connection != NULL, bail, error.message);

	{
		DBusMessageIter iter;
		DBusMessageIter list_iter;
		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
		if (ret != 0) {
			goto bail;
		}
		snprintf(path,
		         sizeof(path),
		         "%s/%s",
		         WPAN_TUNNEL_DBUS_PATH,
		         gInterfaceName);

		message = dbus_message_new_method_call(
		    interface_dbus_name,
		    path,
		    WPAN_TUNNEL_DBUS_INTERFACE,
		    WPAN_IFACE_CMD_FORM
		    );

		dbus_message_append_args(
		    message,
		    DBUS_TYPE_STRING, &network_name,
		    DBUS_TYPE_INT16, &node_type,
		    DBUS_TYPE_UINT32, &channel_mask,
		    DBUS_TYPE_INVALID
		    );

		if(ula_prefix) {
			uint8_t ula_bytes[16] = {};

			// So the ULA prefix could either be
			// specified like an IPv6 address, or
			// specified as a bunch of hex numbers.
			// We use the presence of a colon (':')
			// to differentiate.
			if(strstr(ula_prefix,":")) {

				// Address-style
				int bits = inet_pton(AF_INET6,ula_prefix,ula_bytes);
				if(bits<0) {
					fprintf(stderr,
					        "Bad ULA \"%s\", errno=%d (%s)\n",
					        ula_prefix,
					        errno,
					        strerror(errno));
					goto bail;
				} else if(!bits) {
					fprintf(stderr, "Bad ULA \"%s\"\n", ula_prefix);
					goto bail;
				}
			} else {
				// DATA-style
				int length = parse_string_into_data(ula_bytes,
				                                    8,
				                                    ula_prefix);
				if(length<=0) {
					fprintf(stderr, "Bad ULA \"%s\"\n", ula_prefix);
					goto bail;
				}
			}

			fprintf(stderr, "Using ULA prefix \"%s\"\n", ula_prefix);

			uint8_t *addr = ula_bytes;
			dbus_message_append_args(
			    message,
			    DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &addr, 8,
			    DBUS_TYPE_INVALID
			    );
		}

		fprintf(stderr,
		        "Forming WPAN \"%s\" as node type %d\n",
		        network_name,
		        node_type);

		reply = dbus_connection_send_with_reply_and_block(
		    connection,
		    message,
		    timeout,
		    &error
		    );

		if (!reply) {
			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
			ret = ERRORCODE_TIMEOUT;
			goto bail;
		}

		dbus_message_get_args(reply, &error,
		                      DBUS_TYPE_INT32, &ret,
		                      DBUS_TYPE_INVALID
		                      );

		if (!ret) {
			fprintf(stderr, "Successfully formed!\n");
		} else {
			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
			print_error_diagnosis(ret);
		}
	}

bail:

	if (connection)
		dbus_connection_unref(connection);

	if (message)
		dbus_message_unref(message);

	if (reply)
		dbus_message_unref(reply);

	dbus_error_free(&error);

	return ret;
}
Exemplo n.º 7
0
int
tool_cmd_pcap(int argc, char *argv[])
{
	static const int set = 1;
	int ret = 0;
	int timeout = 10 * 1000;

	int fd_out = -1;
	int fd_pair[2] = { -1, -1 };
	bool force_ctty = false;
	bool stdout_was_closed = false;

	DBusError error;

	dbus_error_init(&error);

	while (1) {
		static struct option long_options[] = {
			{"help", no_argument, 0, 'h'},
			{"timeout", required_argument, 0, 't'},
			{0, 0, 0, 0}
		};

		int option_index = 0;
		int c;

		c = getopt_long(argc, argv, "fht:", long_options, &option_index);

		if (c == -1) {
			break;
		}

		switch (c) {
		case 'h':
			print_arg_list_help(pcap_option_list, argv[0],
					    pcap_cmd_syntax);
			ret = ERRORCODE_HELP;
			goto bail;

		case 'f':
			force_ctty = true;
			break;

		case 't':
			timeout = strtol(optarg, NULL, 0);
			break;
		}
	}

	// We use a socket pair for the socket we hand to wpantund,
	// so that the termination of this process will stop packet
	// capture.
	if (socketpair(PF_UNIX, SOCK_DGRAM, 0, fd_pair) < 0) {
		perror("socketpair");
		ret = ERRORCODE_UNKNOWN;
		goto bail;
	}

	if (optind < argc) {
		// Capture packets to a file path

		fd_out = open(argv[optind], O_WRONLY|O_CREAT|O_TRUNC, 0666);

		optind++;

	} else {
		// Capture packets to stdout

		if (!force_ctty && is_descriptor_ctty(STDOUT_FILENO)) {
			fprintf(stderr, "%s: error: Cowardly refusing write binary data to controlling tty, use -f to override\n", argv[0]);
			ret = ERRORCODE_REFUSED;
			goto bail;
		}

		// Update fd_out, close the original stdout.
		fd_out = dup(STDOUT_FILENO);
		close(STDOUT_FILENO);
		stdout_was_closed = true;
	}

	if (optind < argc) {
		fprintf(
			stderr,
		    "%s: error: Unexpected extra argument: \"%s\"\n",
			argv[0],
			argv[optind]
		);
		ret = ERRORCODE_BADARG;
		goto bail;
	}

	if (fd_out < 0) {
		fprintf(
			stderr,
			"%s: error: Unable to open file for pcap: \"%s\"\n",
			argv[0],
			strerror(errno)
		);
		ret = ERRORCODE_BADARG;
		goto bail;
	}

	if (gInterfaceName[0] == 0) {
		fprintf(
			stderr,
		    "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
		    argv[0]
		);
		ret = ERRORCODE_BADARG;
		goto bail;
	}

	// Have wpantund start writing PCAP data to one end of our socket pair.
	ret = do_pcap_to_fd(fd_pair[1], timeout, &error);

	if (ret) {
		if (error.message != NULL) {
			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
		}
		goto bail;
	}

	// Close this side of the socket pair so that we can
	// detect if wpantund closed the socket.
	close(fd_pair[1]);

#ifdef SO_NOSIGPIPE
	// Turn off sigpipe so we can gracefully exit.
	setsockopt(fd_pair[0], SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
	setsockopt(fd_out, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
#endif

	fprintf(stderr, "%s: Capture started\n", argv[0]);

	// Data pump
	while (true) {
		char buffer[2048];
		ssize_t buffer_len;

		// Read in from datagram socket
		buffer_len = read(fd_pair[0], buffer, sizeof(buffer));

		if (buffer_len <= 0) {
			break;
		}

		// Write out the buffer to our file descriptor
		buffer_len = write(fd_out, buffer, buffer_len);
		if (buffer_len <= 0) {
			break;
		}
	}

	fprintf(stderr, "%s: Capture terminated\n", argv[0]);

bail:

	if (ret) {
		fprintf(stderr, "pcap: failed with error %d. %s\n", ret, wpantund_status_to_cstr(ret));
		print_error_diagnosis(ret);
	}

	// Clean up.

	close(fd_out);

	close(fd_pair[0]);

	close(fd_pair[1]);

	dbus_error_free(&error);

	if (stdout_was_closed) {
		exit (ret);
	}

	return ret;
}