From 5e2c3490d5a59b6a9aebb9a5d094318d6bc6b779 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 7 Nov 2013 16:16:15 +0200 Subject: [PATCH] Android: Add driver_cmd for arbitrary driver commands 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 --- src/drivers/driver.h | 12 ++++++++++++ src/drivers/driver_nl80211.c | 5 +++++ wpa_supplicant/ctrl_iface.c | 19 +++++++++++++++++++ wpa_supplicant/driver_i.h | 10 ++++++++++ wpa_supplicant/wpa_cli.c | 12 ++++++++++++ 5 files changed, 58 insertions(+) diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 2a804195b..3502eb805 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -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 diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 484c61768..9d4bcb8b5 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -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 */ }; diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 6472f4f5c..d5a77b4ac 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -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); diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index 56d652990..7f196de25 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -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) diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index c689e8f4d..aabaa3ccc 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -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[] = { " = 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, + " = driver private commands" }, +#endif /* ANDROID */ { NULL, NULL, NULL, cli_cmd_flag_none, NULL } };