about summary refs log tree commit diff
path: root/src/wifi/wifi-utils-nl80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wifi/wifi-utils-nl80211.c')
-rw-r--r--src/wifi/wifi-utils-nl80211.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/src/wifi/wifi-utils-nl80211.c b/src/wifi/wifi-utils-nl80211.c
index 663cbc26..62ec6c2b 100644
--- a/src/wifi/wifi-utils-nl80211.c
+++ b/src/wifi/wifi-utils-nl80211.c
@@ -108,7 +108,6 @@ _nl80211_send_and_recv (struct nl_sock *nl_sock,
 	int err, done;
 
 	g_return_val_if_fail (msg != NULL, -ENOMEM);
-	g_return_val_if_fail (valid_handler != NULL, -EINVAL);
 
 	cb = nl_cb_clone (nl_cb);
 	if (!cb) {
@@ -124,7 +123,8 @@ _nl80211_send_and_recv (struct nl_sock *nl_sock,
 	nl_cb_err (cb, NL_CB_CUSTOM, error_handler, &done);
 	nl_cb_set (cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &done);
 	nl_cb_set (cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &done);
-	nl_cb_set (cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, valid_data);
+	if (valid_handler)
+		nl_cb_set (cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, valid_data);
 
 	/* Loop until one of our NL callbacks says we're done; on success
 	 * done will be 1, on error it will be < 0.
@@ -187,6 +187,9 @@ static int nl80211_iface_info_handler (struct nl_msg *msg, void *arg)
 	case NL80211_IFTYPE_ADHOC:
 		info->mode = NM_802_11_MODE_ADHOC;
 		break;
+	case NL80211_IFTYPE_AP:
+		info->mode = NM_802_11_MODE_AP;
+		break;
 	case NL80211_IFTYPE_STATION:
 		info->mode = NM_802_11_MODE_INFRA;
 		break;
@@ -216,12 +219,32 @@ wifi_nl80211_get_mode (WifiData *data)
 static gboolean
 wifi_nl80211_set_mode (WifiData *data, const NM80211Mode mode)
 {
-	/*
-	 * Used only to set mode for scanning as some old cards
-	 * don't properly scan in IBSS mode, nl80211 cards are
-	 * expected to scan properly so ignore this.
-	 */
-	return TRUE;
+	WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data;
+	struct nl_msg *msg;
+	int err;
+
+	msg = nl80211_alloc_msg (nl80211, NL80211_CMD_SET_INTERFACE, 0);
+
+	switch (mode) {
+	case NM_802_11_MODE_INFRA:
+		NLA_PUT_U32 (msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_STATION);
+		break;
+	case NM_802_11_MODE_ADHOC:
+		NLA_PUT_U32 (msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_ADHOC);
+		break;
+	case NM_802_11_MODE_AP:
+		NLA_PUT_U32 (msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_AP);
+		break;
+	default:
+		g_assert_not_reached ();
+	}
+
+	err = nl80211_send_and_recv (nl80211, msg, NULL, NULL);
+	return err ? FALSE : TRUE;
+
+ nla_put_failure:
+	nlmsg_free (msg);
+	return FALSE;
 }
 
 /* @divisor: pass what value @xbm should be divided by to get dBm */