[PATCH] [DBus] Add support for vendor specific methods on dbus
Avichal Agarwal
avichal.a at samsung.com
Wed Oct 28 23:12:52 PDT 2015
this also includes dbus.doxygen
From d8dbae9286107d10d8a4937f92d5739db74a67ec Mon Sep 17 00:00:00 2001
From: Avichal Agarwal <avichal.a at samsung.com>
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 at samsung.com>
Signed-off-by: Purushottam Kushwaha <p.kushwaha at samsung.com>
Signed-off-by: Kyeong-Chae Lim <kcya.lim at samsung.com>
Signed-off-by: Dilshad Ahmad <dilshad.a at samsung.com>
---
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
More information about the Hostap
mailing list