示例#1
0
文件: wifi.c 项目: cshnick/rpmFromGit
static int wifi_probe(struct connman_device *device)
{
	struct wifi_data *wifi;

	DBG("device %p", device);

	wifi = g_try_new0(struct wifi_data, 1);
	if (wifi == NULL)
		return -ENOMEM;

	wifi->connected = FALSE;
	wifi->disconnecting = FALSE;
	wifi->tethering = FALSE;
	wifi->bridged = FALSE;
	wifi->bridge = NULL;
	wifi->state = G_SUPPLICANT_STATE_INACTIVE;

	connman_device_set_data(device, wifi);
	wifi->device = connman_device_ref(device);

	wifi->index = connman_device_get_index(device);
	wifi->flags = 0;

	wifi->watch = connman_rtnl_add_newlink_watch(wifi->index,
							wifi_newlink, device);

	iface_list = g_list_append(iface_list, wifi);

	return 0;
}
示例#2
0
文件: peer.c 项目: jasonabele/connman
int connman_peer_register(struct connman_peer *peer)
{
	int index;

	DBG("peer %p", peer);

	if (peer->path && peer->registered)
		return -EALREADY;

	index = connman_device_get_index(peer->device);
	peer->ipconfig = create_ipconfig(index, peer);
	if (!peer->ipconfig)
		return -ENOMEM;

	peer->path = get_peer_path(peer->device, peer->identifier);
	DBG("path %s", peer->path);

	g_hash_table_insert(peers_table, peer->path, peer);

	g_dbus_register_interface(connection, peer->path,
					CONNMAN_PEER_INTERFACE,
					peer_methods, peer_signals,
					NULL, peer, NULL);
	peer->registered = true;
	peer_added(peer);

	return 0;
}
示例#3
0
int supplicant_stop(struct connman_device *device)
{
	int index = connman_device_get_index(device);
	struct supplicant_task *task;

	_DBG_SUPPLICANT("device %p", device);

	task = find_task_by_index(index);
	if (task == NULL)
		return -ENODEV;

	g_free(task->range);

	task_list = g_slist_remove(task_list, task);

	if (task->scan_call != NULL) {
		dbus_pending_call_cancel(task->scan_call);
		task->scan_call = NULL;
	}

	if (task->result_call != NULL) {
		dbus_pending_call_cancel(task->result_call);
		task->result_call = NULL;
	}

	if (task->scanning == TRUE)
		connman_device_set_scanning(task->device, FALSE);

	remove_network(task);

	disconnect_network(task);

	return remove_interface(task);
}
示例#4
0
static void add_network(struct connman_device *device,
                        struct ethernet_data *ethernet)
{
    struct connman_network *network;
    int index;

    network = connman_network_create("carrier",
                                     CONNMAN_NETWORK_TYPE_ETHERNET);
    if (network == NULL)
        return;

    index = connman_device_get_index(device);
    connman_network_set_index(network, index);

    connman_network_set_name(network, "Wired");

    if (connman_device_add_network(device, network) < 0) {
        connman_network_unref(network);
        return;
    }

    connman_network_set_group(network, "cable");

    ethernet->network = network;
}
示例#5
0
/**
* @brief Create a new qmi device, set default values and insert it in the hash table.
*/
static int qmi_probe(struct connman_device *device)
{
	struct qmi_data *qmi;

	DBG("device %p", device);

	g_return_val_if_fail(device, -ENODEV);

	qmi = g_try_new0(struct qmi_data, 1);
	if(qmi == NULL) {

		connman_error("Allocation error, no memory available.");
		return -ENOMEM;
	}

	DBG("device %p data %p", device, qmi);

	connman_device_set_data(device, qmi);

	qmi->device = connman_device_ref(device);
	qmi->network = NULL;
	qmi->qmi_proxy_device = NULL;
	qmi->modem_opening = FALSE;
	qmi->modem_connected = FALSE;
	qmi->modem_opened = FALSE;

	qmi->imsi = NULL;
	qmi->apn = NULL;
	/* Group has to be "IMSI_qmi" */
	qmi->group = NULL;

	qmi->strength = 0;
	/* Name of the provider e.g "o2" */
	qmi->provider = NULL;
	/* Name of the specific QMI-Device e.g. wwan0 */
	qmi->devname = g_strdup(connman_device_get_string(device, "Interface"));
	/* Index of the specific QMI-Device */
	qmi->index = connman_device_get_index(device);

	qmi->devpath = get_device_path_from_name(qmi->devname);
	qmi->object_path = NULL;
	qmi->qmi_proxy_device = NULL;
	DBG("device name %s path %s", qmi->devname, qmi->devpath);
	if(qmi->devpath == NULL) {

		connman_error("No device path available");
		return -ENODEV;
	}

	connman_device_set_string(device, "Path", qmi->devpath);

	g_hash_table_insert(qmi_hash, qmi->devpath, qmi);

	/* Signal to init thread a new connected modem is available. */
	sem_post(&new_device_sem);

	return 0;
}
示例#6
0
文件: mbm.c 项目: wenhann/chromiumos
static int mbm_enable(struct connman_device *device)
{
	struct mbm_data *data = connman_device_get_data(device);
	const char *devnode;
	GIOChannel *channel;
	struct termios ti;
	int fd, index;

	_DBG_MBM("device %p", device);

	devnode = connman_device_get_control(device);
	if (devnode == NULL)
		return -EIO;

	fd = open(devnode, O_RDWR | O_NOCTTY);
	if (fd < 0)
		return -ENODEV;

	tcflush(fd, TCIOFLUSH);

	/* Switch TTY to raw mode */
	memset(&ti, 0, sizeof(ti));
	cfmakeraw(&ti);

	tcsetattr(fd, TCSANOW, &ti);

	channel = g_io_channel_unix_new(fd);
	if (channel == NULL) {
		close(fd);
		return -ENOMEM;
	}

	data->chat = g_at_chat_new(channel, 0);
	if (data->chat == NULL)
		return -EIO;

	g_io_channel_unref(channel);

	g_at_chat_register(data->chat, "*EMRDY:", notify_callback,
							FALSE, NULL, NULL);
	g_at_chat_register(data->chat, "*EMWI:", notify_callback,
							FALSE, NULL, NULL);
	g_at_chat_register(data->chat, "+PACSP", notify_callback,
							FALSE, NULL, NULL);

	index = connman_device_get_index(device);
	connman_inet_ifup(index);

	g_at_chat_send(data->chat, "AT&F E0 V1 X4 &C1 +CMEE=1", NULL,
					generic_callback, NULL, NULL);

	g_at_chat_send(data->chat, "AT+CFUN?", cfun_prefix,
					cfun_callback, device, NULL);
	g_at_chat_send(data->chat, "AT+CFUN=1", NULL,
					cfun_callback, device, NULL);

	return -EINPROGRESS;
}
示例#7
0
文件: peer.c 项目: jasonabele/connman
static int start_dhcp_client(struct connman_peer *peer)
{
	if (peer->sub_device)
		__connman_ipconfig_set_index(peer->ipconfig,
				connman_device_get_index(peer->sub_device));

	__connman_ipconfig_enable(peer->ipconfig);

	return __connman_dhcp_start(peer->ipconfig, NULL, dhcp_callback, peer);
}
示例#8
0
int supplicant_start(struct connman_device *device)
{
	struct supplicant_task *task;
	int err;

	_DBG_SUPPLICANT("device %p", device);

	task = g_try_new0(struct supplicant_task, 1);
	if (task == NULL)
		return -ENOMEM;

	task->ifindex = connman_device_get_index(device);
	task->ifname = connman_inet_ifname(task->ifindex);

	if (task->ifname == NULL) {
		err = -ENOMEM;
		goto failed;
	}

	task->mac80211 = connman_inet_is_mac80211(task->ifindex);
	if (task->mac80211 == FALSE)
		connman_warn("Enabling quirks for unsupported driver");

	task->range = g_try_malloc0(sizeof(struct iw_range));
	if (task->range == NULL) {
		err = -ENOMEM;
		goto failed;
	}

	err = get_range(task);
	if (err < 0)
		goto failed;

	task->device = connman_device_ref(device);

	task->created = FALSE;
	task->scanning = FALSE;
	task->state = WPA_INVALID;
	task->disconnecting = FALSE;
	task->pending_network = NULL;

	task_list = g_slist_append(task_list, task);

	return create_interface(task);

failed:
	g_free(task->range);
	g_free(task->ifname);
	g_free(task);

	return err;
}
示例#9
0
static struct connman_device *find_device(int index)
{
	GSList *list;

	for (list = device_list; list; list = list->next) {
		struct connman_device *device = list->data;

		if (connman_device_get_index(device) == index)
			return device;
	}

	return NULL;
}
示例#10
0
static int mk3_probe(struct connman_device *device) {

	struct mk3_data *mk3;
	gint i;
	GString *str;

	DBG("device %p", device);

	g_return_val_if_fail(device, -ENODEV);

	mk3 = g_try_new0(struct mk3_data, 1);
	if(mk3 == NULL) {

		connman_error("Allocation error, no memory available.");
		return -ENOMEM;
	}

	DBG("device %p data %p", device, mk3);

	connman_device_set_data(device, mk3);
	mk3->device = connman_device_ref(device);

	/* Index of the specific QMI-Device */
	mk3->index = connman_device_get_index(device);
	/* Name of the specific Device  tun_mk3 */
	mk3->devname = g_strdup(connman_device_get_string(device, "Interface"));
	mk3->name = g_strdup("car2car");
	mk3->group = g_strdup("none");

	str = g_string_new(NULL);
	for(i = 0; i < strlen(mk3->devname); i++) {

		g_string_append_printf(str, "%02x", mk3->devname[i]);
	}

	g_string_append_c(str, '_');

	for(i = 0; i < strlen(mk3->name); i++) {

		g_string_append_printf(str, "%02x", mk3->name[i]);
	}

	mk3->ident = g_string_free(str, FALSE);
	connman_device_set_ident(mk3->device, mk3->ident);



	return 0;
}
示例#11
0
文件: mbm.c 项目: wenhann/chromiumos
static int mbm_disable(struct connman_device *device)
{
	struct mbm_data *data = connman_device_get_data(device);
	int index;

	_DBG_MBM("device %p", device);

	g_at_chat_send(data->chat, "AT+CFUN=4", NULL,
					cfun_callback, NULL, NULL);

	index = connman_device_get_index(device);
	connman_inet_ifdown(index);

	g_at_chat_unref(data->chat);
	data->chat = NULL;

	return -EINPROGRESS;
}
示例#12
0
文件: mbm.c 项目: wenhann/chromiumos
static void cfun_callback(gboolean ok, GAtResult *result,
						gpointer user_data)
{
	struct connman_device *device = user_data;
	struct mbm_data *data = connman_device_get_data(device);
	GAtResultIter iter;
	int status;

	if (ok == FALSE)
		return;

	g_at_result_iter_init(&iter, result);

	if (g_at_result_iter_next(&iter, "+CFUN:") == FALSE)
		return;

	g_at_result_iter_next_number(&iter, &status);

	if (status == 1) {
		connman_device_set_powered(device, TRUE);

		data->network = connman_network_create("internet",
						CONNMAN_NETWORK_TYPE_MBM);
		if (data->network != NULL) {
			int index;

			index = connman_device_get_index(device);
			connman_network_set_index(data->network, index);

			connman_network_set_protocol(data->network,
						CONNMAN_NETWORK_PROTOCOL_IP);

			connman_network_set_group(data->network, "internet");

			connman_device_add_network(device, data->network);
		}
	} else {
		connman_device_set_powered(device, FALSE);

		data->network = NULL;
	}
}
示例#13
0
static int ethernet_probe(struct connman_device *device)
{
	struct ethernet_data *ethernet;

	_DBG_ETHERNET("device %p", device);

	ethernet = g_try_new0(struct ethernet_data, 1);
	if (ethernet == NULL)
		return -ENOMEM;

	connman_device_set_data(device, ethernet);

	ethernet->index = connman_device_get_index(device);
	ethernet->flags = 0;

	ethernet->watch = connman_rtnl_add_newlink_watch(ethernet->index,
						ethernet_newlink, device);

	return 0;
}
示例#14
0
文件: mbm.c 项目: wenhann/chromiumos
static int mbm_probe(struct connman_device *device)
{
	struct mbm_data *data;
	int index;

	_DBG_MBM("device %p", device);

	data = g_try_new0(struct mbm_data, 1);
	if (data == NULL)
		return -ENOMEM;

	connman_device_set_data(device, data);

	index = connman_device_get_index(device);

	data->watch = connman_rtnl_add_newlink_watch(index,
						mbm_newlink, device);

	return 0;
}
示例#15
0
int supplicant_scan(struct connman_device *device)
{
	int index = connman_device_get_index(device);
	struct supplicant_task *task;
	int err;

	_DBG_SUPPLICANT("device %p", device);

	task = find_task_by_index(index);
	if (task == NULL)
		return -ENODEV;

	switch (task->state) {
	case WPA_SCANNING:
		return -EALREADY;
	case WPA_ASSOCIATING:
	case WPA_ASSOCIATED:
	case WPA_4WAY_HANDSHAKE:
	case WPA_GROUP_HANDSHAKE:
		return -EBUSY;
	default:
		break;
	}

	task->scanning = TRUE;

	err = initiate_scan(task);
	if (err < 0) {
		if (err == -EINPROGRESS)
			return 0;

		task->scanning = FALSE;
		return err;
	}

	connman_device_set_scanning(task->device, TRUE);

	return 0;
}
示例#16
0
static int get_bssid(struct connman_device *device,
				unsigned char *bssid, unsigned int *bssid_len)
{
	struct iwreq wrq;
	char *ifname;
	int ifindex;
	int fd, err;

	ifindex = connman_device_get_index(device);
	if (ifindex < 0)
		return -EINVAL;

	ifname = connman_inet_ifname(ifindex);
	if (ifname == NULL)
		return -EINVAL;

	fd = socket(PF_INET, SOCK_DGRAM, 0);
	if (fd < 0) {
		g_free(ifname);
		return -EINVAL;
	}

	memset(&wrq, 0, sizeof(wrq));
	strncpy(wrq.ifr_name, ifname, IFNAMSIZ);

	err = ioctl(fd, SIOCGIWAP, &wrq);

	g_free(ifname);
	close(fd);

	if (err < 0)
		return -EIO;

	memcpy(bssid, wrq.u.ap_addr.sa_data, ETH_ALEN);
	*bssid_len = ETH_ALEN;

	return 0;
}
示例#17
0
static void properties_reply(DBusPendingCall *call, void *user_data)
{
	struct supplicant_task *task = user_data;
	struct supplicant_result result;
	struct connman_network *network;
	DBusMessage *reply;
	DBusMessageIter array, dict;
	unsigned char strength;
	unsigned short channel, frequency;
	const char *mode, *security;
	char *group = NULL;

	reply = dbus_pending_call_steal_reply(call);
	if (reply == NULL) {
		_DBG_SUPPLICANT("task %p no reply", task);
		get_properties(task);
		return;
	}

	if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
		_DBG_SUPPLICANT("task %p ERROR", task);
		dbus_message_unref(reply);
		get_properties(task);
		return;
	}

	memset(&result, 0, sizeof(result));
	result.frequency = -1;
	result.quality = -1;
	result.level = 0;
	result.noise = 0;

	dbus_message_iter_init(reply, &array);

	dbus_message_iter_recurse(&array, &dict);

	while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
		DBusMessageIter entry, value;
		const char *key;

		dbus_message_iter_recurse(&dict, &entry);
		dbus_message_iter_get_basic(&entry, &key);

		dbus_message_iter_next(&entry);

		dbus_message_iter_recurse(&entry, &value);

		//type = dbus_message_iter_get_arg_type(&value);
		//dbus_message_iter_get_basic(&value, &val);

		/* 
		 * bssid        : a (97)
		 * ssid         : a (97)
		 * wpaie        : a (97)
		 * rsnie        : a (97)
		 * wpsie        : a (97)
		 * frequency    : i (105)
		 * capabilities : q (113)
		 * quality      : i (105)
		 * noise        : i (105)
		 * level        : i (105)
		 * maxrate      : i (105)
		 */

		if (g_str_equal(key, "bssid") == TRUE)
			extract_addr(&value, &result);
		else if (g_str_equal(key, "ssid") == TRUE)
			extract_ssid(&value, &result);
		else if (g_str_equal(key, "wpaie") == TRUE)
			extract_wpaie(&value, &result);
		else if (g_str_equal(key, "rsnie") == TRUE)
			extract_rsnie(&value, &result);
		else if (g_str_equal(key, "wpsie") == TRUE)
			extract_wpsie(&value, &result);
		else if (g_str_equal(key, "capabilities") == TRUE)
			extract_capabilites(&value, &result);
		else if (g_str_equal(key, "frequency") == TRUE)
			dbus_message_iter_get_basic(&value, &result.frequency);
		else if (g_str_equal(key, "quality") == TRUE)
			dbus_message_iter_get_basic(&value, &result.quality);
		else if (g_str_equal(key, "noise") == TRUE)
			dbus_message_iter_get_basic(&value, &result.noise);
		else if (g_str_equal(key, "level") == TRUE)
			dbus_message_iter_get_basic(&value, &result.level);
		else if (g_str_equal(key, "maxrate") == TRUE)
			dbus_message_iter_get_basic(&value, &result.maxrate);

		dbus_message_iter_next(&dict);
	}

	if (result.path == NULL)
		goto done;

	if (result.path[0] == '\0')
		goto done;

	if (result.frequency > 0 && result.frequency < 14)
		result.frequency = 2407 + (5 * result.frequency);
	else if (result.frequency == 14)
		result.frequency = 2484;

	strength = calculate_strength(task, &result);
	channel  = calculate_channel(&result);

	frequency = (result.frequency < 0) ? 0 : result.frequency;

	if (result.has_rsn == TRUE)
		security = "rsn";
	else if (result.has_wpa == TRUE)
		security = "wpa";
	else if (result.has_wep == TRUE)
		security = "wep";
	else
		security = "none";

	mode = (result.adhoc == TRUE) ? "adhoc" : "managed";

	group = build_group(result.path, result.name,
					result.ssid, result.ssid_len,
							mode, security);

	network = connman_device_get_network(task->device, result.path);
	if (network == NULL) {
		int index;

		network = connman_network_create(result.path,
						CONNMAN_NETWORK_TYPE_WIFI);
		if (network == NULL) {
			_DBG_SUPPLICANT("cannot create network %s",
				result.name);
			goto done;
		}

		index = connman_device_get_index(task->device);
		connman_network_set_index(network, index);

		connman_network_set_protocol(network,
						CONNMAN_NETWORK_PROTOCOL_IP);

		connman_network_set_address(network, result.addr,
							result.addr_len);

		if (connman_device_add_network(task->device, network) < 0) {
			_DBG_SUPPLICANT("cannot add network %s", result.name);
			connman_network_unref(network);
			goto done;
		}

		_DBG_SUPPLICANT("add %s (%s %s) signal %d (%s) freq %u path %s",
				result.name, mode, security, strength,
				(result.has_wps == TRUE) ? "WPS" : "no WPS",
				frequency, result.path);
	}

	connman_network_set_scangen(network, task->scangen);

	if (result.name != NULL && result.name[0] != '\0')
		connman_network_set_name(network, result.name);

	connman_network_set_blob(network, "WiFi.SSID",
						result.ssid, result.ssid_len);

	connman_network_set_string(network, "WiFi.Mode", mode);

	connman_network_set_available(network, TRUE);
	connman_network_set_strength(network, strength);

	connman_network_set_uint16(network, "Frequency", frequency);
	connman_network_set_uint16(network, "WiFi.Channel", channel);
	connman_network_set_string(network, "WiFi.Security", security);

	if (result.ssid != NULL)
		connman_network_set_group(network, group);

done:
	g_free(group);

	g_free(result.path);
	g_free(result.addr);
	g_free(result.name);
	g_free(result.ssid);

	dbus_message_unref(reply);

	get_properties(task);
}
示例#18
0
/**
* @brief Add the network associated to its qmi device
*/
static void add_network(struct qmi_data *qmi)
{
	struct connman_network *network = NULL;
	int index;
	struct connman_service *service = NULL;

	g_return_if_fail(qmi);

	DBG("data %p", qmi);

	if(qmi->network != NULL) {

		DBG("network %p already exists.", qmi->network);
		return;
	}

	/* Create an new qmi network */
	network = connman_network_create(qmi->devpath, CONNMAN_NETWORK_TYPE_QMI);
	if(network == NULL) {

		connman_error("Network could not be created.");
		return;
	}

	DBG("network %p", qmi->network);

	/* Set network properties */
	index = connman_device_get_index(qmi->device);
	connman_network_set_index(network, index);
	connman_network_set_data(network, qmi);
	connman_network_set_strength(network, qmi->strength);
	connman_network_set_group(network, qmi->group);

	if(qmi->provider)
		g_free(qmi->provider);
	qmi->provider = g_strdup("no-name");
	connman_network_set_name(network, qmi->provider);

	/* Add the created network */
	if (connman_device_add_network(qmi->device, network) < 0) {

		connman_error("Network not added to the device.");
		connman_network_unref(network);
		network = NULL;
		return;
	}

	qmi->network = network;

	/* Get configured values from the created *.config file */
	service = connman_service_lookup_from_network(network);
	DBG("service %p", service);
	if(service == NULL) {

		connman_error("No service available");
		return;
	}

	service = connman_service_ref(service);
	if(qmi->apn)
		g_free(qmi->apn);
	qmi->apn = g_strdup(connman_service_get_string(service, "APN"));

	if(qmi->passphrase)
		g_free(qmi->passphrase);
	qmi->passphrase = g_strdup(connman_service_get_string(service, "Passphrase"));

	if(qmi->username)
		g_free(qmi->username);
	qmi->username = g_strdup(connman_service_get_string(service, "Username"));

	if(qmi->provider)
		g_free(qmi->provider);
	qmi->provider = g_strdup(connman_service_get_string(service, "Provider"));
	if(qmi->provider == NULL)
		qmi->provider = g_strdup("no-name");

	connman_network_set_name(network, qmi->provider);
	connman_network_update(qmi->network);


    DBG("network %p IMSI %s APN %s PW %s Username %s", qmi->network, qmi->imsi, qmi->apn, qmi->passphrase, qmi->username);
	connman_service_unref(service);
	if((qmi->imsi == NULL) || (qmi->apn == NULL) || (qmi->passphrase == NULL)) {

		connman_error("There are not all required parameters available");
		return;
	}

}
示例#19
0
文件: peer.c 项目: jasonabele/connman
static int start_dhcp_server(struct connman_peer *peer)
{
	const char *start_ip, *end_ip;
	GDHCPServerError dhcp_error;
	const char *broadcast;
	const char *gateway;
	const char *subnet;
	int prefixlen;
	int index;
	int err;

	DBG("");

	err = -ENOMEM;

	if (peer->sub_device)
		index = connman_device_get_index(peer->sub_device);
	else
		index = connman_device_get_index(peer->device);

	peer->ip_pool = __connman_ippool_create(index, 2, 1, NULL, NULL);
	if (!peer->ip_pool)
		goto error;

	gateway = __connman_ippool_get_gateway(peer->ip_pool);
	subnet = __connman_ippool_get_subnet_mask(peer->ip_pool);
	broadcast = __connman_ippool_get_broadcast(peer->ip_pool);
	start_ip = __connman_ippool_get_start_ip(peer->ip_pool);
	end_ip = __connman_ippool_get_end_ip(peer->ip_pool);

	prefixlen = connman_ipaddress_calc_netmask_len(subnet);

	err = __connman_inet_modify_address(RTM_NEWADDR,
				NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
				gateway, NULL, prefixlen, broadcast);
	if (err < 0)
		goto error;

	peer->dhcp_server = g_dhcp_server_new(G_DHCP_IPV4, index, &dhcp_error);
	if (!peer->dhcp_server)
		goto error;

	g_dhcp_server_set_debug(peer->dhcp_server,
					dhcp_server_debug, "Peer DHCP server");
	g_dhcp_server_set_lease_time(peer->dhcp_server, 3600);
	g_dhcp_server_set_option(peer->dhcp_server, G_DHCP_SUBNET, subnet);
	g_dhcp_server_set_option(peer->dhcp_server, G_DHCP_ROUTER, gateway);
	g_dhcp_server_set_option(peer->dhcp_server, G_DHCP_DNS_SERVER, NULL);
	g_dhcp_server_set_ip_range(peer->dhcp_server, start_ip, end_ip);

	err = g_dhcp_server_start(peer->dhcp_server);
	if (err < 0)
		goto error;

	g_timeout_add_seconds(0, dhcp_server_started, connman_peer_ref(peer));

	return 0;

error:
	stop_dhcp_server(peer);
	return err;
}