1fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt/*
2fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt * Driver interaction with Linux nl80211/cfg80211 - Android specific
3fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
4fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
5fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt * Copyright (c) 2009-2010, Atheros Communications
6fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt *
7fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
8fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt * See README for more details.
9fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt */
10fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
11fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt#include "includes.h"
12fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt#include <sys/ioctl.h>
13fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt#include <net/if.h>
14fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt#include <netlink/genl/genl.h>
15fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt#include <netlink/genl/family.h>
16fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt#include <netlink/genl/ctrl.h>
17fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt#include <fcntl.h>
18fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
19fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt#include "utils/common.h"
20fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt#include "driver_nl80211.h"
21fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt#include "android_drv.h"
22fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
23fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
24fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidttypedef struct android_wifi_priv_cmd {
25fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	char *buf;
26fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	int used_len;
27fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	int total_len;
28fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt} android_wifi_priv_cmd;
29fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
30fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidtstatic int drv_errors = 0;
31fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
32fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidtstatic void wpa_driver_send_hang_msg(struct wpa_driver_nl80211_data *drv)
33fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt{
34fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	drv_errors++;
35fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	if (drv_errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
36fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		drv_errors = 0;
37fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
38fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	}
39fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt}
40fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
41fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
42fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidtstatic int android_priv_cmd(struct i802_bss *bss, const char *cmd)
43fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt{
44fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	struct wpa_driver_nl80211_data *drv = bss->drv;
45fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	struct ifreq ifr;
46fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	android_wifi_priv_cmd priv_cmd;
47fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	char buf[MAX_DRV_CMD_SIZE];
48fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	int ret;
49fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
50fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	os_memset(&ifr, 0, sizeof(ifr));
51fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	os_memset(&priv_cmd, 0, sizeof(priv_cmd));
52fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);
53fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
54fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	os_memset(buf, 0, sizeof(buf));
55fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	os_strlcpy(buf, cmd, sizeof(buf));
56fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
57fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	priv_cmd.buf = buf;
58fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	priv_cmd.used_len = sizeof(buf);
59fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	priv_cmd.total_len = sizeof(buf);
60fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	ifr.ifr_data = &priv_cmd;
61fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
62fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr);
63fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	if (ret < 0) {
64fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		wpa_printf(MSG_ERROR, "%s: failed to issue private commands",
65fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt			   __func__);
66fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		wpa_driver_send_hang_msg(drv);
67fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		return ret;
68fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	}
69fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
70fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	drv_errors = 0;
71fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	return 0;
72fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt}
73fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
74fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
75fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidtint android_pno_start(struct i802_bss *bss,
76fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		      struct wpa_driver_scan_params *params)
77fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt{
78fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	struct wpa_driver_nl80211_data *drv = bss->drv;
79fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	struct ifreq ifr;
80fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	android_wifi_priv_cmd priv_cmd;
81fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	int ret = 0, i = 0, bp;
82fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	char buf[WEXT_PNO_MAX_COMMAND_SIZE];
83fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
84fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	bp = WEXT_PNOSETUP_HEADER_SIZE;
85fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	os_memcpy(buf, WEXT_PNOSETUP_HEADER, bp);
86fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	buf[bp++] = WEXT_PNO_TLV_PREFIX;
87fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	buf[bp++] = WEXT_PNO_TLV_VERSION;
88fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	buf[bp++] = WEXT_PNO_TLV_SUBVERSION;
89fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	buf[bp++] = WEXT_PNO_TLV_RESERVED;
90fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
91fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	while (i < WEXT_PNO_AMOUNT && (size_t) i < params->num_ssids) {
92fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		/* Check that there is enough space needed for 1 more SSID, the
93fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		 * other sections and null termination */
94fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		if ((bp + WEXT_PNO_SSID_HEADER_SIZE + MAX_SSID_LEN +
95fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		     WEXT_PNO_NONSSID_SECTIONS_SIZE + 1) >= (int) sizeof(buf))
96fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt			break;
97fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		wpa_hexdump_ascii(MSG_DEBUG, "For PNO Scan",
98fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt				  params->ssids[i].ssid,
99fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt				  params->ssids[i].ssid_len);
100fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		buf[bp++] = WEXT_PNO_SSID_SECTION;
101fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		buf[bp++] = params->ssids[i].ssid_len;
102fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		os_memcpy(&buf[bp], params->ssids[i].ssid,
103fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt			  params->ssids[i].ssid_len);
104fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		bp += params->ssids[i].ssid_len;
105fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		i++;
106fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	}
107fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
108fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	buf[bp++] = WEXT_PNO_SCAN_INTERVAL_SECTION;
109fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	os_snprintf(&buf[bp], WEXT_PNO_SCAN_INTERVAL_LENGTH + 1, "%x",
110fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		    WEXT_PNO_SCAN_INTERVAL);
111fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	bp += WEXT_PNO_SCAN_INTERVAL_LENGTH;
112fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
113fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	buf[bp++] = WEXT_PNO_REPEAT_SECTION;
114fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	os_snprintf(&buf[bp], WEXT_PNO_REPEAT_LENGTH + 1, "%x",
115fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		    WEXT_PNO_REPEAT);
116fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	bp += WEXT_PNO_REPEAT_LENGTH;
117fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
118fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	buf[bp++] = WEXT_PNO_MAX_REPEAT_SECTION;
119fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	os_snprintf(&buf[bp], WEXT_PNO_MAX_REPEAT_LENGTH + 1, "%x",
120fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		    WEXT_PNO_MAX_REPEAT);
121fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	bp += WEXT_PNO_MAX_REPEAT_LENGTH + 1;
122fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
123fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	memset(&ifr, 0, sizeof(ifr));
124fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	memset(&priv_cmd, 0, sizeof(priv_cmd));
125fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);
126fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
127fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	priv_cmd.buf = buf;
128fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	priv_cmd.used_len = bp;
129fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	priv_cmd.total_len = bp;
130fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	ifr.ifr_data = &priv_cmd;
131fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
132fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr);
133fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
134fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	if (ret < 0) {
135fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (pnosetup): %d",
136fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt			   ret);
137fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		wpa_driver_send_hang_msg(drv);
138fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt		return ret;
139fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	}
140fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
141fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	drv_errors = 0;
142fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
143fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	return android_priv_cmd(bss, "PNOFORCE 1");
144fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt}
145fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
146fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
147fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidtint android_pno_stop(struct i802_bss *bss)
148fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt{
149fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	return android_priv_cmd(bss, "PNOFORCE 0");
150fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt}
151fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
152fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
153fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt#ifdef ANDROID_P2P
1544171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt#ifdef ANDROID_LIB_STUB
155fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
156fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidtint wpa_driver_set_p2p_noa(void *priv, u8 count, int start, int duration)
157fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt{
158fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	return 0;
159fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt}
160fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
161fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
162fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidtint wpa_driver_get_p2p_noa(void *priv, u8 *buf, size_t len)
163fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt{
164fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	return 0;
165fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt}
166fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
167fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
168fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidtint wpa_driver_set_p2p_ps(void *priv, int legacy_ps, int opp_ps, int ctwindow)
169fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt{
170fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	return -1;
171fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt}
172fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
173fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
174fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidtint wpa_driver_set_ap_wps_p2p_ie(void *priv, const struct wpabuf *beacon,
175fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt				 const struct wpabuf *proberesp,
176fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt				 const struct wpabuf *assocresp)
177fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt{
178fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	return 0;
179fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt}
180fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
1814171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt#endif /* ANDROID_LIB_STUB */
182fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt#endif /* ANDROID_P2P */
183fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
184fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
185fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidtint android_nl_socket_set_nonblocking(struct nl_handle *handle)
186fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt{
187fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt	return fcntl(nl_socket_get_fd(handle), F_SETFL, O_NONBLOCK);
188fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt}
189fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
190fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt
191