dbus: Add support for vendor specific elements
The new methods are 1. VendorElemAdd "i" "ay" i=integer ay=array of bytes 2. VendorElemGet "i" i=integer (output array of bytes) 3. VendorElemRem "i" "ay" i=integer ay=array of bytes These provide functionality similar to the control interface commands VENDOR_ELEM_ADD, VENDOR_ELEM_GET, and VENDOR_ELEM_REMOVE. Signed-off-by: Avichal Agarwal <avichal.a@samsung.com> Signed-off-by: Purushottam Kushwaha <p.kushwaha@samsung.com> Signed-off-by: Kyeong-Chae Lim <kcya.lim@samsung.com> Signed-off-by: Mayank Haarit <mayank.h@samsung.com> Signed-off-by: Dilshad Ahmad <dilshad.a@samsung.com> [VendorElemGet to return array of bytes instead of string; cleanup] Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
		
							parent
							
								
									b4e1e99577
								
							
						
					
					
						commit
						af041f997d
					
				
					 7 changed files with 325 additions and 86 deletions
				
			
		|  | @ -455,6 +455,58 @@ fi.w1.wpa_supplicant1.CreateInterface. | |||
| 	  <dd>Initiating the TDLS operation failed for an unknown reason.</dd> | ||||
| 	</dl> | ||||
|       </li> | ||||
|       <li> | ||||
| 	<h3>VendorElemAdd ( i: frame_id, ay: 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>ay : ielems</dt> | ||||
| 	  <dd>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 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 ) --> ay: 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>ay : ielems</dt> | ||||
| 	  <dd>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, ay: 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>ay : ielems</dt> | ||||
| 	  <dd>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 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>SaveConfig ( ) --> nothing</h3> | ||||
| 	<p>Save configuration to the configuration file.</p> | ||||
|  |  | |||
|  | @ -7844,61 +7844,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; | ||||
|  | @ -7910,7 +7855,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) | ||||
|  | @ -7941,7 +7886,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; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -7952,7 +7897,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; | ||||
| } | ||||
|  | @ -7965,7 +7910,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; | ||||
|  | @ -7983,12 +7928,12 @@ static int wpas_ctrl_vendor_elem_remove(struct wpa_supplicant *wpa_s, char *cmd) | |||
| 	size_t len; | ||||
| 	u8 *buf; | ||||
| 	struct ieee802_11_elems elems; | ||||
| 	u8 *ie, *end; | ||||
| 	int res; | ||||
| 
 | ||||
| 	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) | ||||
|  | @ -7998,7 +7943,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; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -8026,31 +7971,9 @@ static int wpas_ctrl_vendor_elem_remove(struct wpa_supplicant *wpa_s, char *cmd) | |||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	ie = wpabuf_mhead_u8(wpa_s->vendor_elem[frame]); | ||||
| 	end = ie + wpabuf_len(wpa_s->vendor_elem[frame]); | ||||
| 
 | ||||
| 	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]) == len) { | ||||
| 			wpabuf_free(wpa_s->vendor_elem[frame]); | ||||
| 			wpa_s->vendor_elem[frame] = NULL; | ||||
| 		} else { | ||||
| 			os_memmove(ie, ie + len, | ||||
| 				   end - (ie + len)); | ||||
| 			wpa_s->vendor_elem[frame]->used -= len; | ||||
| 		} | ||||
| 		os_free(buf); | ||||
| 		wpas_ctrl_vendor_elem_update(wpa_s); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	res = wpas_vendor_elem_remove(wpa_s, frame, buf, len); | ||||
| 	os_free(buf); | ||||
| 
 | ||||
| 	return -1; | ||||
| 	return res; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -3070,6 +3070,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", "ay", ARG_IN }, | ||||
| 		  END_ARGS | ||||
| 	  } | ||||
| 	}, | ||||
| 	{ "VendorElemGet", WPAS_DBUS_NEW_IFACE_INTERFACE, | ||||
| 	  (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_get, | ||||
| 	  { | ||||
| 		  { "frame_id", "i", ARG_IN }, | ||||
| 		  { "ielems", "ay", ARG_OUT }, | ||||
| 		  END_ARGS | ||||
| 	  } | ||||
| 	}, | ||||
| 	{ "VendorElemRem", WPAS_DBUS_NEW_IFACE_INTERFACE, | ||||
| 	  (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_remove, | ||||
| 	  { | ||||
| 		  { "frame_id", "i", ARG_IN }, | ||||
| 		  { "ielems", "ay", ARG_IN }, | ||||
| 		  END_ARGS | ||||
| 	  } | ||||
| 	}, | ||||
| #ifndef CONFIG_NO_CONFIG_WRITE | ||||
| 	{ "SaveConfig", WPAS_DBUS_NEW_IFACE_INTERFACE, | ||||
| 	  (WPADBusMethodHandler) wpas_dbus_handler_save_config, | ||||
|  |  | |||
|  | @ -4363,3 +4363,147 @@ out: | |||
| } | ||||
| 
 | ||||
| #endif /* CONFIG_AP */ | ||||
| 
 | ||||
| 
 | ||||
| DBusMessage * wpas_dbus_handler_vendor_elem_add(DBusMessage *message, | ||||
| 						struct wpa_supplicant *wpa_s) | ||||
| { | ||||
| 	u8 *ielems; | ||||
| 	int len; | ||||
| 	struct ieee802_11_elems elems; | ||||
| 	dbus_int32_t frame_id; | ||||
| 	DBusMessageIter	iter, array; | ||||
| 
 | ||||
| 	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 ID"); | ||||
| 	} | ||||
| 
 | ||||
| 	dbus_message_iter_next(&iter); | ||||
| 	dbus_message_iter_recurse(&iter, &array); | ||||
| 	dbus_message_iter_get_fixed_array(&array, &ielems, &len); | ||||
| 	if (!ielems || len == 0) { | ||||
| 		return dbus_message_new_error( | ||||
| 			message, DBUS_ERROR_INVALID_ARGS, "Invalid value"); | ||||
| 	} | ||||
| 
 | ||||
| 	if (ieee802_11_parse_elems(ielems, len, &elems, 0) == ParseFailed) { | ||||
| 		return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, | ||||
| 					      "Parse error"); | ||||
| 	} | ||||
| 
 | ||||
| 	wpa_s = wpas_vendor_elem(wpa_s, frame_id); | ||||
| 	if (!wpa_s->vendor_elem[frame_id]) { | ||||
| 		wpa_s->vendor_elem[frame_id] = wpabuf_alloc_copy(ielems, len); | ||||
| 		wpas_vendor_elem_update(wpa_s); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	if (wpabuf_resize(&wpa_s->vendor_elem[frame_id], len) < 0) { | ||||
| 		return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, | ||||
| 					      "Resize error"); | ||||
| 	} | ||||
| 
 | ||||
| 	wpabuf_put_data(wpa_s->vendor_elem[frame_id], ielems, len); | ||||
| 	wpas_vendor_elem_update(wpa_s); | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| DBusMessage * wpas_dbus_handler_vendor_elem_get(DBusMessage *message, | ||||
| 						struct wpa_supplicant *wpa_s) | ||||
| { | ||||
| 	DBusMessage *reply; | ||||
| 	DBusMessageIter	iter, array_iter; | ||||
| 	dbus_int32_t frame_id; | ||||
| 	const u8 *elem; | ||||
| 	size_t elem_len; | ||||
| 
 | ||||
| 	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 ID"); | ||||
| 	} | ||||
| 
 | ||||
| 	wpa_s = wpas_vendor_elem(wpa_s, frame_id); | ||||
| 	if (!wpa_s->vendor_elem[frame_id]) { | ||||
| 		return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, | ||||
| 					      "ID value does not exist"); | ||||
| 	} | ||||
| 
 | ||||
| 	reply = dbus_message_new_method_return(message); | ||||
| 	if (!reply) | ||||
| 		return wpas_dbus_error_no_memory(message); | ||||
| 
 | ||||
| 	dbus_message_iter_init_append(reply, &iter); | ||||
| 
 | ||||
| 	elem = wpabuf_head_u8(wpa_s->vendor_elem[frame_id]); | ||||
| 	elem_len = wpabuf_len(wpa_s->vendor_elem[frame_id]); | ||||
| 
 | ||||
| 	if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, | ||||
| 					      DBUS_TYPE_BYTE_AS_STRING, | ||||
| 					      &array_iter) || | ||||
| 	    !dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE, | ||||
| 						  &elem, elem_len) || | ||||
| 	    !dbus_message_iter_close_container(&iter, &array_iter)) { | ||||
| 		dbus_message_unref(reply); | ||||
| 		reply = wpas_dbus_error_no_memory(message); | ||||
| 	} | ||||
| 
 | ||||
| 	return reply; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| DBusMessage * wpas_dbus_handler_vendor_elem_remove(DBusMessage *message, | ||||
| 						   struct wpa_supplicant *wpa_s) | ||||
| { | ||||
| 	u8 *ielems; | ||||
| 	int len; | ||||
| 	struct ieee802_11_elems elems; | ||||
| 	DBusMessageIter	iter, array; | ||||
| 	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 ID"); | ||||
| 	} | ||||
| 
 | ||||
| 	dbus_message_iter_next(&iter); | ||||
| 	dbus_message_iter_recurse(&iter, &array); | ||||
| 	dbus_message_iter_get_fixed_array(&array, &ielems, &len); | ||||
| 	if (!ielems || len == 0) { | ||||
| 		return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, | ||||
| 					      "Invalid value"); | ||||
| 	} | ||||
| 
 | ||||
| 	wpa_s = wpas_vendor_elem(wpa_s, frame_id); | ||||
| 
 | ||||
| 	if (len == 1 && *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]) { | ||||
| 		return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, | ||||
| 					      "ID value does not exist"); | ||||
| 	} | ||||
| 
 | ||||
| 	if (ieee802_11_parse_elems(ielems, len, &elems, 0) == ParseFailed) { | ||||
| 		return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, | ||||
| 					      "Parse error"); | ||||
| 	} | ||||
| 
 | ||||
| 	if (wpas_vendor_elem_remove(wpa_s, frame_id, ielems, len) == 0) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, | ||||
| 				      "Not found"); | ||||
| } | ||||
|  |  | |||
|  | @ -194,6 +194,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_handler_save_config(DBusMessage *message, | ||||
| 					    struct wpa_supplicant *wpa_s); | ||||
| 
 | ||||
|  |  | |||
|  | @ -6143,3 +6143,86 @@ 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 */ | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int wpas_vendor_elem_remove(struct wpa_supplicant *wpa_s, int frame, | ||||
| 			    const u8 *elem, size_t len) | ||||
| { | ||||
| 	u8 *ie, *end; | ||||
| 
 | ||||
| 	ie = wpabuf_mhead_u8(wpa_s->vendor_elem[frame]); | ||||
| 	end = ie + wpabuf_len(wpa_s->vendor_elem[frame]); | ||||
| 
 | ||||
| 	for (; ie + 1 < end; ie += 2 + ie[1]) { | ||||
| 		if (ie + len > end) | ||||
| 			break; | ||||
| 		if (os_memcmp(ie, elem, len) != 0) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if (wpabuf_len(wpa_s->vendor_elem[frame]) == len) { | ||||
| 			wpabuf_free(wpa_s->vendor_elem[frame]); | ||||
| 			wpa_s->vendor_elem[frame] = NULL; | ||||
| 		} else { | ||||
| 			os_memmove(ie, ie + len, end - (ie + len)); | ||||
| 			wpa_s->vendor_elem[frame]->used -= len; | ||||
| 		} | ||||
| 		wpas_vendor_elem_update(wpa_s); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	return -1; | ||||
| } | ||||
|  |  | |||
|  | @ -1179,6 +1179,12 @@ 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); | ||||
| int wpas_vendor_elem_remove(struct wpa_supplicant *wpa_s, int frame, | ||||
| 			    const u8 *elem, size_t len); | ||||
| 
 | ||||
| #ifdef CONFIG_FST | ||||
| 
 | ||||
| struct fst_wpa_obj; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Avichal Agarwal
						Avichal Agarwal