<dd>Needed memory was not possible to get allocated.</dd>
</dl>
</li>
+ <li>
+ <h3>NANPublishStopListen ( u : publish_id ) --> nothing</h3>
+ <p>Stop listen operation for a previously added NAN USD publisher service.</p>
+ <h4>Arguments</h4>
+ <dl>
+ <dt>u : publish_id</dt>
+ <dd>Publish ID from NANPublish().</dd>
+ </dl>
+ <h4>Possible errors</h4>
+ <dl>
+ <dt>fi.w1.wpa_supplicant1.InvalidArgs</dt>
+ <dd>Invalid entries were found in the passed argument.</dd>
+ </dl>
+ </li>
<li>
<h3>NANSubscribe ( a{sv} : args ) --> u : subscribe_id</h3>
<p>Subscribe to a NAN USD service.</p>
<dd>Invalid entries were found in the passed argument.</dd>
</dl>
</li>
+ <li>
+ <h3>NANSubscribeStopListen ( u : subscribe_id ) --> nothing</h3>
+ <p>Stop listen operation for a previously started NAN USD subscription.</p>
+ <h4>Arguments</h4>
+ <dl>
+ <dt>u : subscribe_id</dt>
+ <dd>Subscription ID from NANSubscribe().</dd>
+ </dl>
+ <h4>Possible errors</h4>
+ <dl>
+ <dt>fi.w1.wpa_supplicant1.InvalidArgs</dt>
+ <dd>Invalid entries were found in the passed argument.</dd>
+ </dl>
+ </li>
<li>
<h3>NANTransmit ( a{sv} : args ) --> nothing</h3>
<p>Send a follow-up message for NAN USD service discovery.</p>
unsigned int next_publish_duration;
bool is_p2p;
bool is_pr;
+ bool listen_stopped;
};
struct nan_de {
duration = os_reltime_in_ms(&diff);
if (duration < 0)
continue;
+ if (srv->listen_stopped) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Publisher listen stopped temporarily - do not start driver listen operation");
+ continue;
+ }
if ((unsigned int) duration > de->max_listen)
duration = de->max_listen;
if (de->cb.listen(de->cb.ctx, srv->freq, duration) ==
!srv->subscribe.active))) {
int duration = 1000;
+ if (srv->listen_stopped) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Listen stopped temporarily - do not start driver listen operation");
+ continue;
+ }
+
if (srv->type == NAN_DE_PUBLISH) {
nan_de_check_chan_change(srv);
duration = nan_de_time_to_next_chan_change(srv);
nan_de_tx_sdf(de, srv, 100, NAN_SRV_CTRL_FOLLOW_UP,
peer_addr, a3, req_instance_id, ssi);
+ srv->listen_stopped = false;
+ return 0;
+}
+
+
+int nan_de_stop_listen(struct nan_de *de, int handle)
+{
+ struct nan_de_service *srv;
+
+ if (handle < 1 || handle > NAN_DE_MAX_SERVICE)
+ return -1;
+
+ srv = de->service[handle - 1];
+ if (!srv)
+ return -1;
+ srv->listen_stopped = true;
return 0;
}
const struct wpabuf *ssi, const struct wpabuf *elems,
const u8 *peer_addr, u8 req_instance_id);
+int nan_de_stop_listen(struct nan_de *de, int handle);
+
#endif /* NAN_DE_H */
This command maps to the UpdatePublish() method in the NAN Discovery
Engine.
+NAN_PUBLISH_STOP_LISTEN publish_id=<id from NAN_PUBLISH>
+
+This command is an implementation specific mechanism to allow a service
+to stop driver listen operation during an ongoing SDF exchange, e.g., to
+allow optimized radio use for parallel operations during provisioning
+sequence when no SDF is expected to be received from the peer during the
+other operations. NAN_TRANSMIT can used to re-enable listen operations.
+
NAN_SUBSCRIBE service_name=<name> [active=1] [ttl=<time-to-live-in-sec>] [freq=<in MHz>] [srv_proto_type=<type>] [ssi=<service specific information (hexdump)>]
If ttl=0 or the parameter is not included, operation is terminated once
This command maps to the CancelSubscribe() method in the NAN Discovery Engine.
+NAN_SUBSCRIBE_STOP_LISTEN subscribe_id=<id from NAN_SUBSCRIBE>
+
+This command is an implementation specific mechanism to allow a service
+to stop driver listen operation during an ongoing SDF exchange, e.g., to
+allow optimized radio use for parallel operations during provisioning
+sequence when no SDF is expected to be received from the peer during the
+other operations. NAN_TRANSMIT can used to re-enable listen operations.
+
NAN_TRANSMIT handle=<id from NAN_PUBLISH or NAN_SUBSCRIBE> req_instance_id=<peer's id> address=<peer's MAC address> [ssi=<service specific information (hexdump)>]
This command maps to the Transmit() method in the NAN Discovery Engine.
}
+static int wpas_ctrl_nan_publish_stop_listen(struct wpa_supplicant *wpa_s,
+ char *cmd)
+{
+ char *token, *context = NULL;
+ int publish_id = 0;
+
+ while ((token = str_token(cmd, " ", &context))) {
+ if (sscanf(token, "id=%i", &publish_id) == 1)
+ continue;
+ wpa_printf(MSG_INFO,
+ "CTRL: Invalid NAN_PUBLISH_STOP_LISTEN parameter: %s",
+ token);
+ return -1;
+ }
+
+ if (publish_id <= 0) {
+ wpa_printf(MSG_INFO,
+ "CTRL: Invalid or missing NAN_PUBLISH_STOP_LISTEN publish_id");
+ return -1;
+ }
+
+ return wpas_nan_usd_publish_stop_listen(wpa_s, publish_id);
+}
+
+
static int wpas_ctrl_nan_subscribe(struct wpa_supplicant *wpa_s, char *cmd,
char *buf, size_t buflen)
{
}
+static int wpas_ctrl_nan_subscribe_stop_listen(struct wpa_supplicant *wpa_s,
+ char *cmd)
+{
+ char *token, *context = NULL;
+ int subscribe_id = 0;
+
+ while ((token = str_token(cmd, " ", &context))) {
+ if (sscanf(token, "id=%i", &subscribe_id) == 1)
+ continue;
+ wpa_printf(MSG_INFO,
+ "CTRL: Invalid NAN_SUBSCRIBE_STOP_LISTEN parameter: %s",
+ token);
+ return -1;
+ }
+
+ if (subscribe_id <= 0) {
+ wpa_printf(MSG_INFO,
+ "CTRL: Invalid or missing NAN_SUBSCRIBE_STOP_LISTEN subscribe_id");
+ return -1;
+ }
+
+ return wpas_nan_usd_subscribe_stop_listen(wpa_s, subscribe_id);
+}
+
+
static int wpas_ctrl_nan_transmit(struct wpa_supplicant *wpa_s, char *cmd)
{
char *token, *context = NULL;
} else if (os_strncmp(buf, "NAN_UPDATE_PUBLISH ", 19) == 0) {
if (wpas_ctrl_nan_update_publish(wpa_s, buf + 19) < 0)
reply_len = -1;
+ } else if (os_strncmp(buf, "NAN_PUBLISH_STOP_LISTEN ", 24) == 0) {
+ if (wpas_ctrl_nan_publish_stop_listen(wpa_s, buf + 24) < 0)
+ reply_len = -1;
} else if (os_strncmp(buf, "NAN_SUBSCRIBE ", 14) == 0) {
reply_len = wpas_ctrl_nan_subscribe(wpa_s, buf + 14, reply,
reply_size);
} else if (os_strncmp(buf, "NAN_CANCEL_SUBSCRIBE ", 21) == 0) {
if (wpas_ctrl_nan_cancel_subscribe(wpa_s, buf + 21) < 0)
reply_len = -1;
+ } else if (os_strncmp(buf, "NAN_SUBSCRIBE_STOP_LISTEN ", 26) == 0) {
+ if (wpas_ctrl_nan_subscribe_stop_listen(wpa_s, buf + 26) < 0)
+ reply_len = -1;
} else if (os_strncmp(buf, "NAN_TRANSMIT ", 13) == 0) {
if (wpas_ctrl_nan_transmit(wpa_s, buf + 13) < 0)
reply_len = -1;
END_ARGS
}
},
+ { "NANPublishStopListen", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ (WPADBusMethodHandler) wpas_dbus_handler_nan_publish_stop_listen,
+ {
+ { "publish_id", "u", ARG_IN },
+ END_ARGS
+ }
+ },
{ "NANSubscribe", WPAS_DBUS_NEW_IFACE_INTERFACE,
(WPADBusMethodHandler) wpas_dbus_handler_nan_subscribe,
{
END_ARGS
}
},
+ { "NANSubscribeStopListen", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ (WPADBusMethodHandler) wpas_dbus_handler_nan_subscribe_stop_listen,
+ {
+ { "subscribe_id", "u", ARG_IN },
+ END_ARGS
+ }
+ },
{ "NANTransmit", WPAS_DBUS_NEW_IFACE_INTERFACE,
(WPADBusMethodHandler) wpas_dbus_handler_nan_transmit,
{
}
+/*
+ * wpas_dbus_handler_nan_publish_stop_listen - Stop listen for a NAN publish
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL indicating success or DBus error message on failure
+ *
+ * Handler function for "NANPublishStopListen" method call of network interface.
+ */
+DBusMessage *
+wpas_dbus_handler_nan_publish_stop_listen(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ dbus_uint32_t publish_id;
+
+ if (!wpa_s->nan_de)
+ return NULL;
+
+ if (!dbus_message_get_args(message, NULL,
+ DBUS_TYPE_UINT32, &publish_id,
+ DBUS_TYPE_INVALID)) {
+ wpa_printf(MSG_DEBUG,
+ "dbus: NANPublishStopListen failed to get args");
+ return wpas_dbus_error_invalid_args(message, NULL);
+ }
+
+ wpa_printf(MSG_DEBUG, "dbus: NANPublishStopListen: id=%u", publish_id);
+ if (wpas_nan_usd_publish_stop_listen(wpa_s, publish_id) < 0)
+ return wpas_dbus_error_unknown_error(
+ message, "error stopping listen");
+ return NULL;
+}
+
+
/*
* wpas_dbus_handler_nan_subscribe - Send out NAN USD subscribe messages
* @message: Pointer to incoming dbus message
}
+/*
+ * wpas_dbus_handler_nan_subscribe_stop_listen - Stop listen for a NAN subscription
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL indicating success or DBus error message on failure
+ *
+ * Handler function for "NANSubscribeStopListen" method call of network
+ * interface.
+ */
+DBusMessage *
+wpas_dbus_handler_nan_subscribe_stop_listen(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ dbus_uint32_t subscribe_id;
+
+ if (!wpa_s->nan_de)
+ return NULL;
+
+ if (!dbus_message_get_args(message, NULL,
+ DBUS_TYPE_UINT32, &subscribe_id,
+ DBUS_TYPE_INVALID)) {
+ wpa_printf(MSG_DEBUG,
+ "dbus: NANSubscribeStopListen failed to get args");
+ return wpas_dbus_error_invalid_args(message, NULL);
+ }
+
+ wpa_printf(MSG_DEBUG, "dbus: NANSubscribeStopListen: id=%u",
+ subscribe_id);
+ if (wpas_nan_usd_subscribe_stop_listen(wpa_s, subscribe_id) < 0)
+ return wpas_dbus_error_unknown_error(
+ message, "error stopping listen");
+ return NULL;
+}
+
+
/*
* wpas_dbus_handler_nan_transmit - Send out NAN followup frames
* @message: Pointer to incoming dbus message
DBusMessage *message, struct wpa_supplicant *wpa_s);
DBusMessage * wpas_dbus_handler_nan_update_publish(
DBusMessage *message, struct wpa_supplicant *wpa_s);
+DBusMessage * wpas_dbus_handler_nan_publish_stop_listen(
+ DBusMessage *message, struct wpa_supplicant *wpa_s);
DBusMessage * wpas_dbus_handler_nan_subscribe(DBusMessage *message,
struct wpa_supplicant *wpa_s);
DBusMessage *
wpas_dbus_handler_nan_cancel_subscribe(DBusMessage *message,
struct wpa_supplicant *wpa_s);
+DBusMessage *
+wpas_dbus_handler_nan_subscribe_stop_listen(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
DBusMessage * wpas_dbus_handler_nan_transmit(DBusMessage *message,
struct wpa_supplicant *wpa_s);
}
+static int wpas_nan_stop_listen(struct wpa_supplicant *wpa_s, int id)
+{
+ if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_OFFLOAD)
+ return 0;
+
+ if (nan_de_stop_listen(wpa_s->nan_de, id) < 0)
+ return -1;
+
+ if (wpa_s->nan_usd_listen_work) {
+ wpa_printf(MSG_DEBUG, "NAN: Stop listen operation");
+ wpa_drv_cancel_remain_on_channel(wpa_s);
+ wpas_nan_usd_listen_work_done(wpa_s);
+ }
+
+ if (wpa_s->nan_usd_tx_work) {
+ wpa_printf(MSG_DEBUG, "NAN: Stop TX wait operation");
+ offchannel_send_action_done(wpa_s);
+ wpas_nan_usd_tx_work_done(wpa_s);
+ }
+
+ return 0;
+}
+
+
+int wpas_nan_usd_publish_stop_listen(struct wpa_supplicant *wpa_s,
+ int publish_id)
+{
+ if (!wpa_s->nan_de)
+ return -1;
+
+ wpa_printf(MSG_DEBUG, "NAN: Request to stop listen for publish_id=%d",
+ publish_id);
+ return wpas_nan_stop_listen(wpa_s, publish_id);
+}
+
+
int wpas_nan_usd_subscribe(struct wpa_supplicant *wpa_s,
const char *service_name,
enum nan_service_protocol_type srv_proto_type,
}
+int wpas_nan_usd_subscribe_stop_listen(struct wpa_supplicant *wpa_s,
+ int subscribe_id)
+{
+ if (!wpa_s->nan_de)
+ return -1;
+
+ wpa_printf(MSG_DEBUG, "NAN: Request to stop listen for subscribe_id=%d",
+ subscribe_id);
+ return wpas_nan_stop_listen(wpa_s, subscribe_id);
+}
+
+
int wpas_nan_usd_transmit(struct wpa_supplicant *wpa_s, int handle,
const struct wpabuf *ssi, const struct wpabuf *elems,
const u8 *peer_addr, u8 req_instance_id)
const struct wpabuf *ssi);
int wpas_nan_usd_unpause_publish(struct wpa_supplicant *wpa_s, int publish_id,
u8 peer_instance_id, const u8 *peer_addr);
+int wpas_nan_usd_publish_stop_listen(struct wpa_supplicant *wpa_s,
+ int publish_id);
int wpas_nan_usd_subscribe(struct wpa_supplicant *wpa_s,
const char *service_name,
enum nan_service_protocol_type srv_proto_type,
struct nan_subscribe_params *params, bool p2p);
void wpas_nan_usd_cancel_subscribe(struct wpa_supplicant *wpa_s,
int subscribe_id);
+int wpas_nan_usd_subscribe_stop_listen(struct wpa_supplicant *wpa_s,
+ int subscribe_id);
int wpas_nan_usd_transmit(struct wpa_supplicant *wpa_s, int handle,
const struct wpabuf *ssi, const struct wpabuf *elems,
const u8 *peer_addr, u8 req_instance_id);