]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Android: Add driver_cmd for arbitrary driver commands
authorJouni Malinen <j@w1.fi>
Thu, 7 Nov 2013 14:16:15 +0000 (16:16 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 22 Nov 2013 18:23:08 +0000 (20:23 +0200)
This is a mechanism used in Android to extend driver interface in vendor
specific ways. This is included only for the purpose of Android
compatibility. Proper interface commands should be used for any new
functionality.

Signed-hostap: Jouni Malinen <j@w1.fi>

src/drivers/driver.h
src/drivers/driver_nl80211.c
wpa_supplicant/ctrl_iface.c
wpa_supplicant/driver_i.h
wpa_supplicant/wpa_cli.c

index 2a804195b3c13ff5ac68f7ff396910594ca04430..3502eb8059ab9ef58830a6deb1ab40fec00b85fc 100644 (file)
@@ -2675,6 +2675,18 @@ struct wpa_driver_ops {
         */
        int (*set_authmode)(void *priv, int authmode);
 
+#ifdef ANDROID
+       /**
+        * driver_cmd - Execute driver-specific command
+        * @priv: Private driver interface data
+        * @cmd: Command to execute
+        * @buf: Return buffer
+        * @buf_len: Buffer length
+        * Returns: 0 on success, -1 on failure
+        */
+       int (*driver_cmd)(void *priv, char *cmd, char *buf, size_t buf_len);
+#endif /* ANDROID */
+
        /**
         * set_rekey_info - Set rekey information
         * @priv: Private driver interface data
index 484c6176803ef1c83a2c021a73924b6627e55024..9d4bcb8b558bce99a60c57744ad5e9afef8c913c 100644 (file)
@@ -362,6 +362,8 @@ static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss,
 static int android_pno_start(struct i802_bss *bss,
                             struct wpa_driver_scan_params *params);
 static int android_pno_stop(struct i802_bss *bss);
+extern int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
+                                        size_t buf_len);
 #endif /* ANDROID */
 #ifdef ANDROID_P2P
 int wpa_driver_set_p2p_noa(void *priv, u8 count, int start, int duration);
@@ -11454,4 +11456,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
        .get_noa = wpa_driver_get_p2p_noa,
        .set_ap_wps_ie = wpa_driver_set_ap_wps_p2p_ie,
 #endif /* ANDROID_P2P */
+#ifdef ANDROID
+       .driver_cmd = wpa_driver_nl80211_driver_cmd,
+#endif /* ANDROID */
 };
index 6472f4f5cd634d93522c3ceae03fb298ba752e07..d5a77b4ac8e3484f4f3a7d5d99a65d92a38eb913 100644 (file)
@@ -5158,6 +5158,20 @@ static int wpa_supplicant_pktcnt_poll(struct wpa_supplicant *wpa_s, char *buf,
 }
 
 
+#ifdef ANDROID
+static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, char *cmd,
+                                    char *buf, size_t buflen)
+{
+       int ret;
+
+       ret = wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen);
+       if (ret == 0)
+               ret = os_snprintf(buf, buflen, "%s\n", "OK");
+       return ret;
+}
+#endif /* ANDROID */
+
+
 static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
 {
        wpa_dbg(wpa_s, MSG_DEBUG, "Flush all wpa_supplicant state");
@@ -5749,6 +5763,11 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                if (wpa_supplicant_ctrl_iface_autoscan(wpa_s, buf + 9))
                        reply_len = -1;
 #endif /* CONFIG_AUTOSCAN */
+#ifdef ANDROID
+       } else if (os_strncmp(buf, "DRIVER ", 7) == 0) {
+               reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply,
+                                                     reply_size);
+#endif /* ANDROID */
        } else if (os_strcmp(buf, "REAUTHENTICATE") == 0) {
                pmksa_cache_clear_current(wpa_s->wpa);
                eapol_sm_request_reauth(wpa_s->eapol);
index 56d652990f96af1363eef7eede162013333cfcfa..7f196de25c6d90d8c3e2861bd942c7f707087e05 100644 (file)
@@ -665,6 +665,16 @@ static inline int wpa_drv_tdls_oper(struct wpa_supplicant *wpa_s,
        return wpa_s->driver->tdls_oper(wpa_s->drv_priv, oper, peer);
 }
 
+#ifdef ANDROID
+static inline int wpa_drv_driver_cmd(struct wpa_supplicant *wpa_s,
+                                    char *cmd, char *buf, size_t buf_len)
+{
+       if (!wpa_s->driver->driver_cmd)
+               return -1;
+       return wpa_s->driver->driver_cmd(wpa_s->drv_priv, cmd, buf, buf_len);
+}
+#endif /* ANDROID */
+
 static inline void wpa_drv_set_rekey_info(struct wpa_supplicant *wpa_s,
                                          const u8 *kek, const u8 *kck,
                                          const u8 *replay_ctr)
index c689e8f4dd7fcdad254c8f2581e5bf5330b60e46..aabaa3cccfc8b715d5a327064c855d59a77d0829 100644 (file)
@@ -2412,6 +2412,14 @@ static int wpa_cli_cmd_raw(struct wpa_ctrl *ctrl, int argc, char *argv[])
 }
 
 
+#ifdef ANDROID
+static int wpa_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "DRIVER", 1, argc, argv);
+}
+#endif /* ANDROID */
+
+
 static int wpa_cli_cmd_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
 {
        return wpa_ctrl_command(ctrl, "FLUSH");
@@ -2881,6 +2889,10 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
          "<params..> = Sent unprocessed command" },
        { "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
          "= flush wpa_supplicant state" },
+#ifdef ANDROID
+       { "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none,
+         "<command> = driver private commands" },
+#endif /* ANDROID */
        { NULL, NULL, NULL, cli_cmd_flag_none, NULL }
 };