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 2a80419..3502eb8 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 484c617..9d4bcb8 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 6472f4f..d5a77b4 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 56d6529..7f196de 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 c689e8f..aabaa3c 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 }
 };