this also includes dbus.doxygen >From d8dbae9286107d10d8a4937f92d5739db74a67ec Mon Sep 17 00:00:00 2001 From: Avichal Agarwal <avichal.a@xxxxxxxxxxx> Date: Tue, 27 Oct 2015 10:30:23 +0530 Subject: [PATCH] [DBus] Add support for vendor specific methods on dbus Methods are 1.VendorElemAdd type "is" i=integer s=string 2.VendorElemGet "i" i=integer (output string) 3.VendorElemRem "is" i=integer s=string Signed-off-by: Avichal Agarwal <avichal.a@xxxxxxxxxxx> Signed-off-by: Purushottam Kushwaha <p.kushwaha@xxxxxxxxxxx> Signed-off-by: Kyeong-Chae Lim <kcya.lim@xxxxxxxxxxx> Signed-off-by: Dilshad Ahmad <dilshad.a@xxxxxxxxxxx> --- doc/dbus.doxygen | 52 ++++++++ wpa_supplicant/ctrl_iface.c | 69 ++--------- wpa_supplicant/dbus/dbus_new.c | 24 ++++ wpa_supplicant/dbus/dbus_new_handlers.c | 206 +++++++++++++++++++++++++++++++ wpa_supplicant/dbus/dbus_new_handlers.h | 7 ++ wpa_supplicant/wpa_supplicant.c | 53 ++++++++ wpa_supplicant/wpa_supplicant_i.h | 4 + 7 files changed, 353 insertions(+), 62 deletions(-) diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen index 437f9fc..bab8628 100644 --- a/doc/dbus.doxygen +++ b/doc/dbus.doxygen @@ -456,6 +456,58 @@ fi.w1.wpa_supplicant1.CreateInterface. </dl> </li> <li> + <h3>VendorElemAdd ( i: frame_id, s: ielems ) --> nothing</h3> + <p>Add Vendor Elements to corresponding frame ID.</p> + <h4>Arguments</h4> + <dl> + <dt>i : frame_id</dt> + <dd>Frame ID for which Vendor specific IE is to be added.</dd> + <dt>s : ielems</dt> + <dd>Hexdump of Information Element(s).</dd> + </dl> + <h4>Possible errors</h4> + <dl> + <dt>fi.w1.wpa_supplicant1.InvalidArgs</dt> + <dd>The "ielems" argument is not a properly formatted Hexdump or size mismatch.</dd> + <dt>fi.w1.wpa_supplicant1.NoMemory</dt> + <dd>Needed memory was not possible to get allocated.</dd> + </dl> + </li> + <li> + <h3>VendorElemGet ( i: frame_id ) --> s: ielems</h3> + <p>Get Vendor Elements of corresponding frame ID.</p> + <h4>Arguments</h4> + <dl> + <dt>i : frame_id</dt> + <dd>Frame ID for which Vendor specific IE is being queried.</dd> + <dt>s : ielems</dt> + <dd>Hexdump of Information Element(s).</dd> + </dl> + <h4>Possible errors</h4> + <dl> + <dt>fi.w1.wpa_supplicant1.InvalidArgs</dt> + <dd>The "frame_id" argument is not valid.</dd> + </dl> + </li> + <li> + <h3>VendorElemRem ( i: frame_id, s: ielems ) --> nothing</h3> + <p>Remove Vendor Elements of corresponding frame ID.</p> + <h4>Arguments</h4> + <dl> + <dt>i : frame_id</dt> + <dd>Frame ID for which Vendor specific IE is to be removed.</dd> + <dt>s : ielems</dt> + <dd>Hexdump of Information Element(s) OR * to remove all.</dd> + </dl> + <h4>Possible errors</h4> + <dl> + <dt>fi.w1.wpa_supplicant1.InvalidArgs</dt> + <dd>The "ielems" argument is not a properly formatted Hexdump or size mismatch.</dd> + <dt>fi.w1.wpa_supplicant1.NoMemory</dt> + <dd>Needed memory was not possible to get allocated.</dd> + </dl> + </li> + <li> <h3>EAPLogoff ( ) --> nothing</h3> <p>IEEE 802.1X EAPOL state machine logoff.</p> </li> diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 9538c51..88ad1a7 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -7779,61 +7779,6 @@ static int wpas_ctrl_event_test(struct wpa_supplicant *wpa_s, const char *cmd) #endif /* CONFIG_TESTING_OPTIONS */ -static void wpas_ctrl_vendor_elem_update(struct wpa_supplicant *wpa_s) -{ - unsigned int i; - char buf[30]; - - wpa_printf(MSG_DEBUG, "Update vendor elements"); - - for (i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) { - if (wpa_s->vendor_elem[i]) { - int res; - - res = os_snprintf(buf, sizeof(buf), "frame[%u]", i); - if (!os_snprintf_error(sizeof(buf), res)) { - wpa_hexdump_buf(MSG_DEBUG, buf, - wpa_s->vendor_elem[i]); - } - } - } - -#ifdef CONFIG_P2P - if (wpa_s->parent == wpa_s && - wpa_s->global->p2p && - !wpa_s->global->p2p_disabled) - p2p_set_vendor_elems(wpa_s->global->p2p, wpa_s->vendor_elem); -#endif /* CONFIG_P2P */ -} - - -static struct wpa_supplicant * -wpas_ctrl_vendor_elem_iface(struct wpa_supplicant *wpa_s, - enum wpa_vendor_elem_frame frame) -{ - switch (frame) { -#ifdef CONFIG_P2P - case VENDOR_ELEM_PROBE_REQ_P2P: - case VENDOR_ELEM_PROBE_RESP_P2P: - case VENDOR_ELEM_PROBE_RESP_P2P_GO: - case VENDOR_ELEM_BEACON_P2P_GO: - case VENDOR_ELEM_P2P_PD_REQ: - case VENDOR_ELEM_P2P_PD_RESP: - case VENDOR_ELEM_P2P_GO_NEG_REQ: - case VENDOR_ELEM_P2P_GO_NEG_RESP: - case VENDOR_ELEM_P2P_GO_NEG_CONF: - case VENDOR_ELEM_P2P_INV_REQ: - case VENDOR_ELEM_P2P_INV_RESP: - case VENDOR_ELEM_P2P_ASSOC_REQ: - case VENDOR_ELEM_P2P_ASSOC_RESP: - return wpa_s->parent; -#endif /* CONFIG_P2P */ - default: - return wpa_s; - } -} - - static int wpas_ctrl_vendor_elem_add(struct wpa_supplicant *wpa_s, char *cmd) { char *pos = cmd; @@ -7845,7 +7790,7 @@ static int wpas_ctrl_vendor_elem_add(struct wpa_supplicant *wpa_s, char *cmd) frame = atoi(pos); if (frame < 0 || frame >= NUM_VENDOR_ELEM_FRAMES) return -1; - wpa_s = wpas_ctrl_vendor_elem_iface(wpa_s, frame); + wpa_s = wpas_vendor_elem(wpa_s, frame); pos = os_strchr(pos, ' '); if (pos == NULL) @@ -7876,7 +7821,7 @@ static int wpas_ctrl_vendor_elem_add(struct wpa_supplicant *wpa_s, char *cmd) if (wpa_s->vendor_elem[frame] == NULL) { wpa_s->vendor_elem[frame] = buf; - wpas_ctrl_vendor_elem_update(wpa_s); + wpas_vendor_elem_update(wpa_s); return 0; } @@ -7887,7 +7832,7 @@ static int wpas_ctrl_vendor_elem_add(struct wpa_supplicant *wpa_s, char *cmd) wpabuf_put_buf(wpa_s->vendor_elem[frame], buf); wpabuf_free(buf); - wpas_ctrl_vendor_elem_update(wpa_s); + wpas_vendor_elem_update(wpa_s); return 0; } @@ -7900,7 +7845,7 @@ static int wpas_ctrl_vendor_elem_get(struct wpa_supplicant *wpa_s, char *cmd, if (frame < 0 || frame >= NUM_VENDOR_ELEM_FRAMES) return -1; - wpa_s = wpas_ctrl_vendor_elem_iface(wpa_s, frame); + wpa_s = wpas_vendor_elem(wpa_s, frame); if (wpa_s->vendor_elem[frame] == NULL) return 0; @@ -7923,7 +7868,7 @@ static int wpas_ctrl_vendor_elem_remove(struct wpa_supplicant *wpa_s, char *cmd) frame = atoi(pos); if (frame < 0 || frame >= NUM_VENDOR_ELEM_FRAMES) return -1; - wpa_s = wpas_ctrl_vendor_elem_iface(wpa_s, frame); + wpa_s = wpas_vendor_elem(wpa_s, frame); pos = os_strchr(pos, ' '); if (pos == NULL) @@ -7933,7 +7878,7 @@ static int wpas_ctrl_vendor_elem_remove(struct wpa_supplicant *wpa_s, char *cmd) if (*pos == '*') { wpabuf_free(wpa_s->vendor_elem[frame]); wpa_s->vendor_elem[frame] = NULL; - wpas_ctrl_vendor_elem_update(wpa_s); + wpas_vendor_elem_update(wpa_s); return 0; } @@ -7979,7 +7924,7 @@ static int wpas_ctrl_vendor_elem_remove(struct wpa_supplicant *wpa_s, char *cmd) wpa_s->vendor_elem[frame]->used -= len; } os_free(buf); - wpas_ctrl_vendor_elem_update(wpa_s); + wpas_vendor_elem_update(wpa_s); return 0; } diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c index 9b04ee1..df870d2 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -2998,6 +2998,30 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = { } }, #endif /* CONFIG_TDLS */ + { "VendorElemAdd", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_add, + { + { "frame_id", "i", ARG_IN }, + { "ielems", "s", ARG_IN }, + END_ARGS + } + }, + { "VendorElemGet", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_get, + { + { "frame_id", "i", ARG_IN }, + { "ielems", "s", ARG_OUT }, + END_ARGS + } + }, + { "VendorElemRem", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_remove, + { + { "frame_id", "i", ARG_IN }, + { "ielems", "s", ARG_IN }, + END_ARGS + } + }, { NULL, NULL, NULL, { END_ARGS } } }; diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index 57dc25b..258d90f 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -4232,3 +4232,209 @@ out: } #endif /* CONFIG_AP */ + +DBusMessage * wpas_dbus_handler_vendor_elem_add(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + char *ielems = NULL; + size_t len; + struct wpabuf *buf; + struct ieee802_11_elems elems; + dbus_int32_t frame_id; + DBusMessageIter iter; + + dbus_message_iter_init(message, &iter); + dbus_message_iter_get_basic(&iter, &frame_id); + + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &ielems); + if (ielems == NULL) { + return dbus_message_new_error( + message, DBUS_ERROR_INVALID_ARGS, + "Invalid hex value"); + } + + if (frame_id < 0 || frame_id >= NUM_VENDOR_ELEM_FRAMES) + return dbus_message_new_error( message, DBUS_ERROR_INVALID_ARGS, + "Invalid ID"); + + wpa_s = wpas_vendor_elem(wpa_s, frame_id); + + len = os_strlen(ielems); + if (len == 0) + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Invalid hex value"); + if (len & 1) + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Invalid length of value"); + len /= 2; + + buf = wpabuf_alloc(len); + if (buf == NULL) + return wpas_dbus_error_no_memory(message); + + if (hexstr2bin(ielems, wpabuf_put(buf, len), len) < 0) { + wpabuf_free(buf); + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + NULL); + } + + if (ieee802_11_parse_elems(wpabuf_head_u8(buf), len, &elems, 0) == + ParseFailed) { + wpabuf_free(buf); + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "parse error"); + } + + if (wpa_s->vendor_elem[frame_id] == NULL) { + wpa_s->vendor_elem[frame_id] = buf; + wpas_vendor_elem_update(wpa_s); + return NULL; + } + + if (wpabuf_resize(&wpa_s->vendor_elem[frame_id], len) < 0) { + wpabuf_free(buf); + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Resize error "); + } + + wpabuf_put_buf(wpa_s->vendor_elem[frame_id], buf); + wpabuf_free(buf); + wpas_vendor_elem_update(wpa_s); + return NULL; + +} +DBusMessage * wpas_dbus_handler_vendor_elem_get(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply; + char *buf; + char arr[4096]; + int buflen = 4096; + buf = arr; + DBusMessageIter iter; + dbus_int32_t frame_id; + + dbus_message_iter_init(message, &iter); + dbus_message_iter_get_basic(&iter, &frame_id); + + if (frame_id < 0 || frame_id >= NUM_VENDOR_ELEM_FRAMES) + { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Invalid arguments"); + } + wpa_s = wpas_vendor_elem(wpa_s, frame_id); + + reply = dbus_message_new_method_return(message); + + if (wpa_s->vendor_elem[frame_id] == NULL) + { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "ID value does not exist"); + } + + wpa_snprintf_hex(buf, buflen, + wpabuf_head_u8(wpa_s->vendor_elem[frame_id]), + wpabuf_len(wpa_s->vendor_elem[frame_id])); + + + dbus_message_append_args(reply, DBUS_TYPE_STRING, + &buf, DBUS_TYPE_INVALID); + + return reply; +} + +DBusMessage * wpas_dbus_handler_vendor_elem_remove(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + char *ielems; + size_t len; + u8 *buf; + struct ieee802_11_elems elems; + u8 *ie, *end; + DBusMessageIter iter; + dbus_int32_t frame_id; + + dbus_message_iter_init(message, &iter); + dbus_message_iter_get_basic(&iter, &frame_id); + + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &ielems); + if (ielems == NULL) { + return dbus_message_new_error( + message, DBUS_ERROR_INVALID_ARGS, + "Invalid hex value"); + } + + if (frame_id < 0 || frame_id >= NUM_VENDOR_ELEM_FRAMES) + { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Invalid arguments"); + } + + wpa_s = wpas_vendor_elem(wpa_s, frame_id); + + + + if (*ielems == '*') { + wpabuf_free(wpa_s->vendor_elem[frame_id]); + wpa_s->vendor_elem[frame_id] = NULL; + wpas_vendor_elem_update(wpa_s); + return NULL; + } + + if (wpa_s->vendor_elem[frame_id] == NULL) + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "ID value does not exist"); + + len = os_strlen(ielems); + if (len == 0) + return NULL; + if (len & 1) + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Invalid length of value"); + len /= 2; + + buf = os_malloc(len); + if (buf == NULL) + return wpas_dbus_error_no_memory(message); + + if (hexstr2bin(ielems, buf, len) < 0) { + os_free(buf); + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + NULL); + } + + if (ieee802_11_parse_elems(buf, len, &elems, 0) == ParseFailed) { + os_free(buf); + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Parse error"); + } + + ie = wpabuf_mhead_u8(wpa_s->vendor_elem[frame_id]); + end = ie + wpabuf_len(wpa_s->vendor_elem[frame_id]); + + for (; ie + 1 < end; ie += 2 + ie[1]) { + if (ie + len > end) + break; + if (os_memcmp(ie, buf, len) != 0) + continue; + + if (wpabuf_len(wpa_s->vendor_elem[frame_id]) == len) { + wpabuf_free(wpa_s->vendor_elem[frame_id]); + wpa_s->vendor_elem[frame_id] = NULL; + } else { + os_memmove(ie, ie + len, + end - (ie + len)); + wpa_s->vendor_elem[frame_id]->used -= len; + } + os_free(buf); + wpas_vendor_elem_update(wpa_s); + return NULL; + } + + os_free(buf); + + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Not found"); +} diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h index 1be81df..62886b9 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.h +++ b/wpa_supplicant/dbus/dbus_new_handlers.h @@ -324,6 +324,13 @@ DBusMessage * wpas_dbus_handler_tdls_status(DBusMessage *message, DBusMessage * wpas_dbus_handler_tdls_teardown(DBusMessage *message, struct wpa_supplicant *wpa_s); +DBusMessage * wpas_dbus_handler_vendor_elem_add(DBusMessage *message, + struct wpa_supplicant *wpa_s); +DBusMessage * wpas_dbus_handler_vendor_elem_get(DBusMessage *message, + struct wpa_supplicant *wpa_s); +DBusMessage * wpas_dbus_handler_vendor_elem_remove(DBusMessage *message, + struct wpa_supplicant *wpa_s); + DBusMessage * wpas_dbus_error_invalid_args(DBusMessage *message, const char *arg); DBusMessage * wpas_dbus_error_unknown_error(DBusMessage *message, diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 7631a79..e3cc19e 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -6056,3 +6056,56 @@ void wpas_rrm_handle_link_measurement_request(struct wpa_supplicant *wpa_s, } wpabuf_free(buf); } + +struct wpa_supplicant * +wpas_vendor_elem(struct wpa_supplicant *wpa_s, + enum wpa_vendor_elem_frame frame) +{ + switch (frame) { +#ifdef CONFIG_P2P + case VENDOR_ELEM_PROBE_REQ_P2P: + case VENDOR_ELEM_PROBE_RESP_P2P: + case VENDOR_ELEM_PROBE_RESP_P2P_GO: + case VENDOR_ELEM_BEACON_P2P_GO: + case VENDOR_ELEM_P2P_PD_REQ: + case VENDOR_ELEM_P2P_PD_RESP: + case VENDOR_ELEM_P2P_GO_NEG_REQ: + case VENDOR_ELEM_P2P_GO_NEG_RESP: + case VENDOR_ELEM_P2P_GO_NEG_CONF: + case VENDOR_ELEM_P2P_INV_REQ: + case VENDOR_ELEM_P2P_INV_RESP: + case VENDOR_ELEM_P2P_ASSOC_REQ: + case VENDOR_ELEM_P2P_ASSOC_RESP: + return wpa_s->parent; +#endif /* CONFIG_P2P */ + default: + return wpa_s; + } +} + +void wpas_vendor_elem_update(struct wpa_supplicant *wpa_s) +{ + unsigned int i; + char buf[30]; + + wpa_printf(MSG_DEBUG, "Update vendor elements"); + + for (i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) { + if (wpa_s->vendor_elem[i]) { + int res; + + res = os_snprintf(buf, sizeof(buf), "frame[%u]", i); + if (!os_snprintf_error(sizeof(buf), res)) { + wpa_hexdump_buf(MSG_DEBUG, buf, + wpa_s->vendor_elem[i]); + } + } + } + +#ifdef CONFIG_P2P + if (wpa_s->parent == wpa_s && + wpa_s->global->p2p && + !wpa_s->global->p2p_disabled) + p2p_set_vendor_elems(wpa_s->global->p2p, wpa_s->vendor_elem); +#endif /* CONFIG_P2P */ +} diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index fc5fc17..5025b65 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1169,6 +1169,10 @@ int get_shared_radio_freqs(struct wpa_supplicant *wpa_s, void wpas_network_reenabled(void *eloop_ctx, void *timeout_ctx); +void wpas_vendor_elem_update(struct wpa_supplicant *wpa_s); +struct wpa_supplicant * wpas_vendor_elem(struct wpa_supplicant *wpa_s, + enum wpa_vendor_elem_frame frame); + #ifdef CONFIG_FST struct fst_wpa_obj; -- 1.7.9.5 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap