* hostapd / DPP integration
* Copyright (c) 2017, Qualcomm Atheros, Inc.
* Copyright (c) 2018-2020, The Linux Foundation
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc.
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
return dpp_tcp_auth(hapd->iface->interfaces->dpp, conn, auth,
hapd->conf->dpp_name, DPP_NETROLE_AP,
- hostapd_dpp_process_conf_obj);
+ hostapd_dpp_process_conf_obj, NULL);
}
#endif /* CONFIG_DPP2 */
return dpp_tcp_init(hapd->iface->interfaces->dpp, auth,
&ipaddr, tcp_port, hapd->conf->dpp_name,
DPP_NETROLE_AP, hapd->msg_ctx, hapd,
- hostapd_dpp_process_conf_obj);
+ hostapd_dpp_process_conf_obj, NULL);
#endif /* CONFIG_DPP2 */
hapd->dpp_auth = auth;
* DPP functionality shared between hostapd and wpa_supplicant
* Copyright (c) 2017, Qualcomm Atheros, Inc.
* Copyright (c) 2018-2020, The Linux Foundation
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc.
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
* DPP functionality shared between hostapd and wpa_supplicant
* Copyright (c) 2017, Qualcomm Atheros, Inc.
* Copyright (c) 2018-2020, The Linux Foundation
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc.
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
void *msg_ctx;
void *cb_ctx;
int (*process_conf_obj)(void *ctx, struct dpp_authentication *auth);
+ bool (*tcp_msg_sent)(void *ctx, struct dpp_authentication *auth);
};
#ifdef CONFIG_TESTING_OPTIONS
const char *name, enum dpp_netrole netrole, void *msg_ctx,
void *cb_ctx,
int (*process_conf_obj)(void *ctx,
- struct dpp_authentication *auth));
+ struct dpp_authentication *auth),
+ bool (*tcp_msg_sent)(void *ctx,
+ struct dpp_authentication *auth));
int dpp_tcp_auth(struct dpp_global *dpp, void *_conn,
struct dpp_authentication *auth, const char *name,
enum dpp_netrole netrole,
int (*process_conf_obj)(void *ctx,
- struct dpp_authentication *auth));
+ struct dpp_authentication *auth),
+ bool (*tcp_msg_sent)(void *ctx,
+ struct dpp_authentication *auth));
+bool dpp_tcp_conn_status_requested(struct dpp_global *dpp);
+void dpp_tcp_send_conn_status(struct dpp_global *dpp,
+ enum dpp_status_error result,
+ const u8 *ssid, size_t ssid_len,
+ const char *channel_list);
struct wpabuf * dpp_build_presence_announcement(struct dpp_bootstrap_info *bi);
void dpp_notify_chirp_received(void *msg_ctx, int id, const u8 *src,
* DPP module internal definitions
* Copyright (c) 2017, Qualcomm Atheros, Inc.
* Copyright (c) 2018-2020, The Linux Foundation
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc.
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
struct dl_list tcp_init; /* struct dpp_connection */
void *cb_ctx;
int (*process_conf_obj)(void *ctx, struct dpp_authentication *auth);
+ bool (*tcp_msg_sent)(void *ctx, struct dpp_authentication *auth);
void (*remove_bi)(void *ctx, struct dpp_bootstrap_info *bi);
#endif /* CONFIG_DPP2 */
};
/*
* DPP over TCP
* Copyright (c) 2019-2020, The Linux Foundation
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc.
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
void *cb_ctx;
int (*process_conf_obj)(void *ctx, struct dpp_authentication *auth);
int (*pkex_done)(void *ctx, void *conn, struct dpp_bootstrap_info *bi);
+ bool (*tcp_msg_sent)(void *ctx, struct dpp_authentication *auth);
int sock;
u8 mac_addr[ETH_ALEN];
unsigned int freq;
void *msg_ctx;
void *cb_ctx;
int (*process_conf_obj)(void *ctx, struct dpp_authentication *auth);
+ bool (*tcp_msg_sent)(void *ctx, struct dpp_authentication *auth);
};
static void dpp_controller_rx(int sd, void *eloop_ctx, void *sock_ctx);
dpp_controller_rx, conn, NULL) == 0)
conn->read_eloop = 1;
if (conn->on_tcp_tx_complete_remove) {
+ if (conn->auth && conn->auth->connect_on_tx_status &&
+ conn->tcp_msg_sent &&
+ conn->tcp_msg_sent(conn->cb_ctx, conn->auth))
+ return 0;
dpp_connection_remove(conn);
} else if (conn->auth && (conn->ctrl || conn->auth->configurator) &&
conn->on_tcp_tx_complete_gas_done) {
wpa_msg(msg_ctx, MSG_INFO,
DPP_EVENT_CONF_SENT "wait_conn_status=1");
wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result");
+ auth->waiting_conn_status_result = 1;
eloop_cancel_timeout(
dpp_controller_conn_status_result_wait_timeout,
conn, NULL);
conn->msg_ctx = ctrl->msg_ctx;
conn->cb_ctx = ctrl->cb_ctx;
conn->process_conf_obj = ctrl->process_conf_obj;
+ conn->tcp_msg_sent = ctrl->tcp_msg_sent;
conn->sock = fd;
conn->netrole = ctrl->netrole;
const struct hostapd_ip_addr *addr, int port, const char *name,
enum dpp_netrole netrole, void *msg_ctx, void *cb_ctx,
int (*process_conf_obj)(void *ctx,
- struct dpp_authentication *auth))
+ struct dpp_authentication *auth),
+ bool (*tcp_msg_sent)(void *ctx,
+ struct dpp_authentication *auth))
{
struct dpp_connection *conn;
struct sockaddr_storage saddr;
conn->msg_ctx = msg_ctx;
conn->cb_ctx = cb_ctx;
conn->process_conf_obj = process_conf_obj;
+ conn->tcp_msg_sent = tcp_msg_sent;
conn->name = os_strdup(name ? name : "Test");
conn->netrole = netrole;
conn->global = dpp;
struct dpp_authentication *auth, const char *name,
enum dpp_netrole netrole,
int (*process_conf_obj)(void *ctx,
- struct dpp_authentication *auth))
+ struct dpp_authentication *auth),
+ bool (*tcp_msg_sent)(void *ctx,
+ struct dpp_authentication *auth))
{
struct dpp_connection *conn = _conn;
/* Continue with Authentication exchange on an existing TCP connection.
*/
conn->process_conf_obj = process_conf_obj;
+ conn->tcp_msg_sent = tcp_msg_sent;
os_free(conn->name);
conn->name = os_strdup(name ? name : "Test");
conn->netrole = netrole;
ctrl->msg_ctx = config->msg_ctx;
ctrl->cb_ctx = config->cb_ctx;
ctrl->process_conf_obj = config->process_conf_obj;
+ ctrl->tcp_msg_sent = config->tcp_msg_sent;
ctrl->sock = socket(AF_INET, SOCK_STREAM, 0);
if (ctrl->sock < 0)
}
}
+
+bool dpp_tcp_conn_status_requested(struct dpp_global *dpp)
+{
+ struct dpp_connection *conn;
+
+ dl_list_for_each(conn, &dpp->tcp_init, struct dpp_connection, list) {
+ if (conn->auth && conn->auth->conn_status_requested)
+ return true;
+ }
+
+ return false;
+}
+
+
+static void dpp_tcp_send_conn_status_msg(struct dpp_connection *conn,
+ enum dpp_status_error result,
+ const u8 *ssid, size_t ssid_len,
+ const char *channel_list)
+{
+ struct dpp_authentication *auth = conn->auth;
+ int res;
+ struct wpabuf *msg;
+
+ auth->conn_status_requested = 0;
+
+ msg = dpp_build_conn_status_result(auth, result, ssid, ssid_len,
+ channel_list);
+ if (!msg) {
+ dpp_connection_remove(conn);
+ return;
+ }
+
+ res = dpp_tcp_send_msg(conn, msg);
+ wpabuf_free(msg);
+
+ if (res < 0) {
+ dpp_connection_remove(conn);
+ return;
+ }
+
+ /* This exchange will be terminated in the TX status handler */
+ conn->on_tcp_tx_complete_remove = 1;
+}
+
+
+void dpp_tcp_send_conn_status(struct dpp_global *dpp,
+ enum dpp_status_error result,
+ const u8 *ssid, size_t ssid_len,
+ const char *channel_list)
+{
+ struct dpp_connection *conn;
+
+ dl_list_for_each(conn, &dpp->tcp_init, struct dpp_connection, list) {
+ if (conn->auth && conn->auth->conn_status_requested) {
+ dpp_tcp_send_conn_status_msg(conn, result, ssid,
+ ssid_len, channel_list);
+ break;
+ }
+ }
+}
+
#endif /* CONFIG_DPP2 */
* wpa_supplicant - DPP
* Copyright (c) 2017, Qualcomm Atheros, Inc.
* Copyright (c) 2018-2020, The Linux Foundation
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc.
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
static void wpas_dpp_start_gas_client(struct wpa_supplicant *wpa_s);
static int wpas_dpp_process_conf_obj(void *ctx,
struct dpp_authentication *auth);
+static bool wpas_dpp_tcp_msg_sent(void *ctx, struct dpp_authentication *auth);
#endif /* CONFIG_DPP2 */
static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
struct dpp_authentication *auth = wpa_s->dpp_auth;
enum dpp_status_error result;
- if (!auth || !auth->conn_status_requested)
+ if ((!auth || !auth->conn_status_requested) &&
+ !dpp_tcp_conn_status_requested(wpa_s->dpp))
return;
wpa_printf(MSG_DEBUG,
eloop_cancel_timeout(wpas_dpp_conn_status_result_timeout, wpa_s, NULL);
- if (!auth || !auth->conn_status_requested)
+ if ((!auth || !auth->conn_status_requested) &&
+ !dpp_tcp_conn_status_requested(wpa_s->dpp))
return;
- auth->conn_status_requested = 0;
+
wpa_printf(MSG_DEBUG, "DPP: Report connection status result %d",
result);
channel_list = channel_list_buf;
}
+ if (!auth || !auth->conn_status_requested) {
+ dpp_tcp_send_conn_status(wpa_s->dpp, result,
+ ssid ? ssid->ssid :
+ wpa_s->dpp_last_ssid,
+ ssid ? ssid->ssid_len :
+ wpa_s->dpp_last_ssid_len,
+ channel_list);
+ os_free(channel_list_buf);
+ return;
+ }
+
+ auth->conn_status_requested = 0;
+
msg = dpp_build_conn_status_result(auth, result,
ssid ? ssid->ssid :
wpa_s->dpp_last_ssid,
{
struct dpp_authentication *auth = wpa_s->dpp_auth;
- if (auth && auth->conn_status_requested)
+ if ((auth && auth->conn_status_requested) ||
+ dpp_tcp_conn_status_requested(wpa_s->dpp))
wpas_dpp_send_conn_status_result(wpa_s, DPP_STATUS_OK);
}
if (tcp)
return dpp_tcp_init(wpa_s->dpp, auth, &ipaddr, tcp_port,
wpa_s->conf->dpp_name, DPP_NETROLE_STA,
- wpa_s, wpa_s, wpas_dpp_process_conf_obj);
+ wpa_s, wpa_s, wpas_dpp_process_conf_obj,
+ wpas_dpp_tcp_msg_sent);
#endif /* CONFIG_DPP2 */
wpa_s->dpp_auth = auth;
}
+static bool wpas_dpp_tcp_msg_sent(void *ctx, struct dpp_authentication *auth)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+
+ wpa_printf(MSG_DEBUG, "DPP: TCP message sent callback");
+
+ if (auth->connect_on_tx_status) {
+ auth->connect_on_tx_status = 0;
+ wpa_printf(MSG_DEBUG,
+ "DPP: Try to connect after completed configuration result");
+ wpas_dpp_try_to_connect(wpa_s);
+ if (auth->conn_status_requested) {
+ wpa_printf(MSG_DEBUG,
+ "DPP: Start 15 second timeout for reporting connection status result");
+ eloop_cancel_timeout(
+ wpas_dpp_conn_status_result_timeout,
+ wpa_s, NULL);
+ eloop_register_timeout(
+ 15, 0, wpas_dpp_conn_status_result_timeout,
+ wpa_s, NULL);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
static void wpas_dpp_remove_bi(void *ctx, struct dpp_bootstrap_info *bi)
{
struct wpa_supplicant *wpa_s = ctx;
}
return dpp_tcp_auth(wpa_s->dpp, conn, auth, wpa_s->conf->dpp_name,
- DPP_NETROLE_STA, wpas_dpp_process_conf_obj);
+ DPP_NETROLE_STA, wpas_dpp_process_conf_obj,
+ wpas_dpp_tcp_msg_sent);
}
#endif /* CONFIG_DPP2 */
config.msg_ctx = wpa_s;
config.cb_ctx = wpa_s;
config.process_conf_obj = wpas_dpp_process_conf_obj;
+ config.tcp_msg_sent = wpas_dpp_tcp_msg_sent;
if (cmd) {
pos = os_strstr(cmd, " tcp_port=");
if (pos) {