diff --git a/src/Makefile b/src/Makefile
index 97dd4a2c7d82e020e6df58b6b04e75bbecf98279..b58a578b323ee87584429c588e61f9795751c729 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -37,6 +37,9 @@ LIBS = -lubus -lubox -ljson-c -lblobmsg_json -luci -pthread
LIBS += -rdynamic -ldl
LIBS += -leasy -lwifiutils
LIBS += -lieee1905 -lmaputil
+ifneq (,$(findstring USE_LIBDPP,$(CFLAGS)))
+LIBS += -ldpp
+endif
plugin_subdirs ?= $(wildcard plugins/*/*)
plugin_sofile = $(wildcard $(d)/*.so)
diff --git a/src/cntlr.c b/src/cntlr.c
index 937e7c96689f1b2f7e6815fbb7ffd69a1384db2f..bb857d338e8adbe48cc02be60c17b79897d7db0c 100644
--- a/src/cntlr.c
+++ b/src/cntlr.c
@@ -34,6 +34,8 @@
#include "timer.h"
#if (EASYMESH_VERSION > 2)
+#include <dpp_api.h>
+
#include "dpp.h"
#endif
@@ -2177,6 +2179,7 @@ void run_controller(void)
INIT_LIST_HEAD(&c->dpp_ctx.enrolleelist);
INIT_LIST_HEAD(&c->dpp_ctx.chirplist);
#endif
+
as_init_table(&c->as_table);
allmac_init_table(&c->mac_table);
init_bh_topology();
@@ -2187,6 +2190,26 @@ void run_controller(void)
ubus_add_uloop(ctx);
+#if (EASYMESH_VERSION > 2)
+ {
+ char *argv[] = {"-I", "-C", "-V", "2"};
+ int argc = 4;
+ int ret;
+
+ ret = dpp_init(&c->dpp, argc, argv);
+ if (ret) {
+ dbg("Failed to init dpp context\n");
+ goto out_exit;
+ }
+
+ dpp_register_cb(c->dpp, dpp_frame_handler);
+ dpp_set_ctx_private_data(c->dpp, c);
+
+
+ dpp_cntlr_read_uris(c);
+ }
+#endif
+
cntlr_config_defaults(c, &c->cfg);
ret = cntlr_get_ieee1905_almac(c, c->almac);
@@ -2254,10 +2277,6 @@ void run_controller(void)
memset(&c->dlem.network.steer_summary, 0, sizeof(struct wifi_steer_summary));
cntlr_dbg("current wifi_cntlr profile %d\n", c->cfg.map_profile);
-#if (EASYMESH_VERSION > 2)
- dpp_cntlr_read_uris(c);
-#endif
-
uloop_run();
out_exit:
diff --git a/src/cntlr.h b/src/cntlr.h
index d7383758dd50d41ad6cb3e1fb28ddbffc6807e02..97adc8706f9bcd3219cae3bce891abfa03b2a4aa 100644
--- a/src/cntlr.h
+++ b/src/cntlr.h
@@ -307,9 +307,6 @@ struct controller {
struct list_head stalist; /* list of sta */
struct list_head bcnreqlist;
struct list_head linklist;
-#if (EASYMESH_VERSION > 2)
- struct dpp_context dpp_ctx;
-#endif
atimer_t radar_timer;
atimer_t discovery_timer;
atimer_t start_timer;
@@ -333,6 +330,11 @@ struct controller {
struct list_head sclist; /* steer_control module list */
struct steer_control *sctrl; /* active steer-control module */
+#if (EASYMESH_VERSION > 2)
+ struct dpp_context_wifi dpp_ctx;
+ void *dpp;
+#endif
+
struct wifi_data_element dlem; /* wifi data elements */
};
diff --git a/src/cntlr_cmdu.c b/src/cntlr_cmdu.c
index f92ddbdf19c57b87b0240d2f68bc7a4a7dba4f83..166e43a843f662090f672b72106f55564de9ada0 100644
--- a/src/cntlr_cmdu.c
+++ b/src/cntlr_cmdu.c
@@ -530,6 +530,9 @@ out:
}
struct cmdu_buff *cntlr_gen_ap_autoconfig_response(struct controller *c,
+#if (EASYMESH_VERSION > 2)
+ bool hash_validity, uint8_t *hash, uint16_t hashlen,
+#endif
uint8_t *dest, uint8_t band, uint16_t mid)
{
struct cmdu_buff *resp;
@@ -562,11 +565,14 @@ struct cmdu_buff *cntlr_gen_ap_autoconfig_response(struct controller *c,
ret = cntlr_gen_device_1905_layer_security_cap(c, resp);
if (ret)
goto out;
-#if 0
- ret = cntlr_gen_chirp_value_tlv(c, resp);
- if (ret)
- goto out;
-#endif
+
+ if (hash) {
+ ret = cntlr_gen_chirp_value_tlv(c, resp, NULL,
+ hash_validity, hashlen,
+ hash);
+ if (ret)
+ goto out;
+ }
#if (EASYMESH_VERSION > 5)
ret = cntlr_gen_cntlr_capability(c, resp, CONTROLLER_EARLY_AP_CAP_SUPPORTED);
@@ -1086,21 +1092,25 @@ error:
}
#if (EASYMESH_VERSION > 2)
-struct cmdu_buff *cntlr_gen_direct_encap_dpp(struct controller *c)
+struct cmdu_buff *cntlr_gen_direct_encap_dpp(struct controller *c,
+ uint8_t *dst,
+ uint8_t *frame,
+ uint16_t framelen)
{
struct cmdu_buff *frm;
uint16_t mid = 0;
/* TODO: Pass direct_encap_dpp_data parameter */
-
- frm = cmdu_alloc_simple(CMDU_DIRECT_ENCAP_DPP, &mid);
+ frm = cmdu_alloc_frame(5000);
if (!frm) {
- dbg("%s: -ENOMEM\n", __func__);
+ trace("%s: -ENOMEM\n", __func__);
return NULL;
}
+ cmdu_set_type(frm, CMDU_DIRECT_ENCAP_DPP);
+ cmdu_set_mid(frm, mid);
/* One DPP Message TLV */
- if (cntlr_gen_dpp_message_tlv(c, frm)) {
+ if (cntlr_gen_dpp_message_tlv(c, frm, framelen, frame)) {
dbg("%s: cntlr_gen_dpp_message_tlv failed.\n", __func__);
goto out;
}
@@ -1145,7 +1155,7 @@ struct cmdu_buff *cntlr_gen_proxied_encap_dpp(struct controller *c,
/* Zero or One Chirp Value TLV */
if (hashlen && hash) {
- if (cntlr_gen_chirp_value_tlv(c, frm, enrollee, hashlen, hash)) {
+ if (cntlr_gen_chirp_value_tlv(c, frm, enrollee, 1 /* TODO: hash_validity */, hashlen, hash)) {
dbg("%s: cntlr_gen_chirp_value_tlv failed.\n", __func__);
goto out;
}
diff --git a/src/cntlr_cmdu.h b/src/cntlr_cmdu.h
index 968c24a04b58ec9951876a48faa116d26c2cef9a..3066422d7113ae77f6a94256219d5bb0efce101b 100644
--- a/src/cntlr_cmdu.h
+++ b/src/cntlr_cmdu.h
@@ -42,6 +42,9 @@ struct cmdu_buff *cntlr_gen_unassoc_sta_metric_query(struct controller *c,
struct cmdu_buff *cntlr_gen_ap_autoconfig_search(struct controller *c,
uint8_t profile, uint8_t band);
struct cmdu_buff *cntlr_gen_ap_autoconfig_response(struct controller *c,
+#if (EASYMESH_VERSION > 2)
+ bool hash_validity, uint8_t *hash, uint16_t hashlen,
+#endif
uint8_t *dest, uint8_t band, uint16_t mid);
struct cmdu_buff *cntlr_gen_ap_autoconfig_wsc(struct controller *c,
struct node *n, struct cmdu_buff *rx_cmdu, uint8_t *radio_id,
@@ -99,7 +102,10 @@ struct cmdu_buff *cntlr_gen_proxied_encap_dpp(struct controller *c,
uint8_t *frame,
uint16_t hashlen,
uint8_t *hash);
-struct cmdu_buff *cntlr_gen_direct_encap_dpp(struct controller *c);
+struct cmdu_buff *cntlr_gen_direct_encap_dpp(struct controller *c,
+ uint8_t *dst,
+ uint8_t *frame,
+ uint16_t framelen);
struct cmdu_buff *cntrl_gen_bss_configuration_response(struct controller *c, struct cmdu_buff *request_cmdu);
struct cmdu_buff *cntlr_gen_dpp_cce_indication(struct controller *c,
uint8_t *agent, bool cce_advertise);
diff --git a/src/cntlr_map.c b/src/cntlr_map.c
index 8a77457d7566422c571ee33e26521cb07a901d14..6d27189b2cc74864b8455ae56d29b4939cd8155d 100644
--- a/src/cntlr_map.c
+++ b/src/cntlr_map.c
@@ -45,6 +45,8 @@
#include "timer.h"
#if (EASYMESH_VERSION > 2)
+#include <dpp_api.h>
+
#include "dpp.h"
#include "utils/dpp_sock.h"
#endif
@@ -957,6 +959,13 @@ int handle_ap_autoconfig_search(void *cntlr, struct cmdu_buff *rx_cmdu,
struct controller *c = (struct controller *) cntlr;
struct tlv_autoconfig_band *freq;
struct tlv_aladdr *aladdr;
+#if (EASYMESH_VERSION > 2)
+ void *event = NULL;
+ bool hash_known = false;
+ bool hash_validity;
+ uint8_t hashlen;
+ uint8_t *hash;
+#endif
struct tlv *t;
struct cmdu_buff *cmdu;
uint8_t almac[6] = {0};
@@ -1003,7 +1012,6 @@ int handle_ap_autoconfig_search(void *cntlr, struct cmdu_buff *rx_cmdu,
return -1;
}
- // todo: handle tv[6] i.e. MAP_TLV_DPP_CHIRP_VALUE
if (tv[1][0]->data[0] != IEEE80211_ROLE_REGISTRAR) {
trace("%s: Discard ap-autoconfig search for role != registrar\n",
__func__);
@@ -1049,21 +1057,73 @@ int handle_ap_autoconfig_search(void *cntlr, struct cmdu_buff *rx_cmdu,
if (tv[3][0])
handle_supported_service(c, almac, tv[3][0]);
+#if (EASYMESH_VERSION > 2)
+ if (tv[6][0] && c->cfg.map_profile > 2) {
+ int offset = 0;
+ uint8_t flag = 0;
+ bool mac_present;
+ uint8_t *mac;
+
+ flag = tv[6][0]->data[offset++];
+
+ mac_present = (flag & DPP_CHIRP_ENROLLEE_MAC_PRESENT);
+ hash_validity = (flag & DPP_CHIRP_HASH_VALIDITY);
+ UNUSED(hash_validity);
+
+ if (mac_present) {
+ mac = &tv[6][0]->data[offset];
+ UNUSED(mac);
+ offset += 6;
+ }
+
+ hashlen = tv[6][0]->data[offset++];
+ hash = &tv[6][0]->data[offset];
+
+ dump(hash, hashlen, "autoconf search chirp hash");
+
+ hash_known = dpp_is_peer_bootstrap_hash_known(c->dpp, hash, NULL);
+ if (hash_known) {
+ ret = dpp_process_virt_presence_announcement(c->dpp,
+ rx_cmdu->origin,
+ hash, hashlen);
+ if (!ret) {
+ event = dpp_sm_create_event(c->dpp, rx_cmdu->origin,
+ DPP_EVENT_RX_FRAME,
+ 0, NULL);
+ } else
+ err("%s: Failed to process virt presence announcement!\n", __func__);
+ } else {
+ err("%s: Hash was not known!\n", __func__);
+ }
+ }
+#endif
+
trace("%s: sending autoconfig response for band = %d, node %p\n",
__func__, freq->band, n);
- cmdu = cntlr_gen_ap_autoconfig_response(cntlr, almac,
+
+ cmdu = cntlr_gen_ap_autoconfig_response(cntlr,
+#if (EASYMESH_VERSION > 2)
+ (hash_known ? hash_validity : 0),
+ (hash_known ? hash : NULL),
+ (hash_known ? hashlen : 0),
+#endif
+ almac,
freq->band,
cmdu_get_mid(rx_cmdu));
if (!cmdu)
return -1;
ret = send_cmdu(c, cmdu);
-
cmdu_free(cmdu);
- UNUSED(ret);
+#if (EASYMESH_VERSION > 2)
+ if (event) {
+ dbg("|%s:%d| Trigger dpp event\n", __func__, __LINE__);
+ dpp_trigger(c->dpp, rx_cmdu->origin, event);
+ }
+#endif
- return 0;
+ return !!ret;
}
/* disable and quit on controller response */
@@ -3570,22 +3630,71 @@ int handle_direct_encap_dpp(void *cntlr, struct cmdu_buff *cmdu,
struct node *n)
{
trace("%s: --->\n", __func__);
-
struct controller *c = (struct controller *)cntlr;
struct tlv *tlv;
struct tlv *tlvs[DIRECT_ENCAP_DPP_MAX_NUMBER_OF_TLV_TYPES][TLV_MAXNUM] = { 0 };
+ struct tlv_dpp_message *dpp_msg;
+ uint16_t framelen;
+ uint8_t *frame;
+ int frametype;
+
+ UNUSED(c);
if (!validate_direct_encap_dpp(cmdu, tlvs)) {
dbg("cmdu validation: [DIRECT_ENCAP_DPP] failed\n");
return -1;
}
+ /* POSSIBLY MID CHECK HERE? */
+
/* One DPP Message TLV */
tlv = tlvs[DIRECT_ENCAP_DPP_MESSAGE_IDX][0];
- (void) tlv;
- (void) c;
+ dpp_msg = (struct tlv_dpp_message *) tlv->data;
+
+ frame = dpp_msg->frame;
+ framelen = BUF_GET_BE16(tlv->len);
- // TODO: process DPP Message TLV
+ frametype = dpp_get_frame_type(frame + 1, framelen - 1);
+ if (frametype == 255)
+ return -1;
+
+ /* Encapsulated frame length */
+ dump(frame, framelen, "DIRECT CMDU FRAME");
+
+ switch (frametype) {
+ case DPP_PA_PRESENCE_ANNOUNCEMENT: {
+ int ret;
+
+ ret = dpp_process_presence_announcement(c->dpp, cmdu->origin,
+ frame,
+ framelen);
+ if (ret) {
+ dbg("Failed to build presence announcement frame!\n");
+ break;
+ }
+
+ dbg("%s processing PA\n", (!ret ? "Succeeded" : "Failed"));
+ /* FALLTHROUGH */
+ }
+ case DPP_PA_AUTHENTICATION_RESP:
+ case DPP_PUB_AF_GAS_INITIAL_REQ:
+ case DPP_PA_CONFIGURATION_RESULT:
+ case DPP_PA_PEER_DISCOVERY_REQ:
+ case DPP_PA_CONNECTION_STATUS_RESULT: {
+ void *event =
+ dpp_sm_create_event(c->dpp, cmdu->origin, DPP_EVENT_RX_FRAME, framelen, frame);
+
+ if (event) {
+ dpp_trigger(c->dpp, cmdu->origin, event);
+ dpp_sm_free_event(event);
+ }
+ break;
+
+ }
+ default:
+ dbg("Unknown frame!\n");
+ break;
+ }
return 0;
}
diff --git a/src/cntlr_tlv.c b/src/cntlr_tlv.c
index 227045dc697180e119429f8cc8304d3fc0b0a177..2638d1745d7e9cc4ded818bf82e0f0b704c99f9a 100644
--- a/src/cntlr_tlv.c
+++ b/src/cntlr_tlv.c
@@ -1728,29 +1728,20 @@ int cntlr_gen_dpp_cce_indication_tlv(struct controller *c,
return 0;
}
-/* TODO: fill the DPP frame field */
-int cntlr_gen_dpp_message_tlv(struct controller *c, struct cmdu_buff *frm)
+int cntlr_gen_dpp_message_tlv(struct controller *c, struct cmdu_buff *frm,
+ uint16_t framelen, uint8_t *frame)
{
struct tlv *t;
- int offset = 0;
- /* dummy values */
- int framelen = 1;
- uint8_t frame[1] = { 0xff };
- t = cmdu_reserve_tlv(frm, 512);
+ t = cmdu_reserve_tlv(frm, 4700);
if (!t)
return -1;
t->type = MAP_TLV_DPP_MESSAGE;
- /* DPP Frame length */
- t->data[offset++] = framelen;
+ memcpy(&t->data[0], frame, framelen);
- /* DPP Frame */
- memcpy(&t->data[offset], frame, framelen);
- offset += framelen;
-
- t->len = offset;
+ t->len = framelen;
if (cmdu_put_tlv(frm, t))
return -1;
@@ -1804,12 +1795,9 @@ int cntlr_gen_1905_encap_dpp_tlv(struct controller *c, struct cmdu_buff *frm,
return 0;
}
-/* TODO: fill the following fields
- * DPP flag (Hash Validity & MAC addr present)
- * Enrollee MAC & hash
- */
int cntlr_gen_chirp_value_tlv(struct controller *c, struct cmdu_buff *frm,
- uint8_t *enrollee, uint16_t hashlen, uint8_t *hash)
+ uint8_t *enrollee, bool hash_validity,
+ uint16_t hashlen, uint8_t *hash)
{
struct tlv *t;
int offset = 0;
@@ -1824,7 +1812,7 @@ int cntlr_gen_chirp_value_tlv(struct controller *c, struct cmdu_buff *frm,
if (enrollee)
flags |= 1 << 7;
- flags |= 1 << 6; /* TODO: 0: purge (when?) -- 1: establish */
+ flags |= hash_validity << 6; /* TODO: 0: purge (when?) -- 1: establish */
t->data[offset++] = flags;
diff --git a/src/cntlr_tlv.h b/src/cntlr_tlv.h
index 741cc3f2165365566a8cd5271120ce4492faba79..c7b3749dc5fc7f83295d6aabdfce769aa201c909 100644
--- a/src/cntlr_tlv.h
+++ b/src/cntlr_tlv.h
@@ -115,13 +115,14 @@ int cntlr_gen_tlv_higher_layer_data(struct controller *c, struct cmdu_buff *frm,
uint8_t proto, uint8_t *data, int len);
#if (EASYMESH_VERSION > 2)
-int cntlr_gen_dpp_message_tlv(struct controller *c,
- struct cmdu_buff *frm);
+int cntlr_gen_dpp_message_tlv(struct controller *c, struct cmdu_buff *frm,
+ uint16_t framelen, uint8_t *frame);
int cntlr_gen_1905_encap_dpp_tlv(struct controller *c, struct cmdu_buff *frm,
uint8_t *enrollee, uint8_t frametype,
uint16_t framelen, uint8_t *frame);
int cntlr_gen_chirp_value_tlv(struct controller *c, struct cmdu_buff *frm,
- uint8_t *enrollee, uint16_t hashlen, uint8_t *hash);
+ uint8_t *enrollee, bool hash_validity,
+ uint16_t hashlen, uint8_t *hash);
int cntlr_gen_bss_config_response_tlv(struct controller *c,
struct cmdu_buff *cmdu);
int cntlr_gen_dpp_cce_indication_tlv(struct controller *c, struct cmdu_buff *frm,
diff --git a/src/cntlr_ubus.c b/src/cntlr_ubus.c
index 805824cd62aefebdd7da3d024069fb05b8ddc8c5..d4afb4cde4f72106f89d4e2cb36d888a3fa575be 100644
--- a/src/cntlr_ubus.c
+++ b/src/cntlr_ubus.c
@@ -37,6 +37,8 @@
#include "timer.h"
#if (EASYMESH_VERSION > 2)
+#include <dpp_api.h>
+
#include "dpp.h"
#endif
#include "utils/utils.h"
@@ -835,10 +837,57 @@ static int cntlr_steer_history(struct ubus_context *ctx, struct ubus_object *obj
}
#if (EASYMESH_VERSION > 2)
+static int cntlr_dpp_uri_eth(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ struct controller *c = container_of(obj, struct controller, obj);
+ struct blob_attr *tb[__DPP_URI_MAX];
+ struct dpp_bootstrap_info *enrollee_bi;
+ char *uri;
+ int ret;
+
+ blobmsg_parse(dpp_uri_params, __DPP_URI_MAX, tb,
+ blob_data(msg), blob_len(msg));
+
+ if (!tb[DPP_URI]) {
+ dbg("|%s:%d| URI must be provided!\n", __func__, __LINE__);
+ return UBUS_STATUS_INVALID_ARGUMENT;
+ }
+
+ uri = blobmsg_data(tb[DPP_URI]);
+ if (!uri)
+ return UBUS_STATUS_UNKNOWN_ERROR;
+
+
+ enrollee_bi = calloc(1, sizeof(*enrollee_bi));
+ if (!enrollee_bi) {
+ fprintf(stderr, "Failed to allocate enrollee_bi\n");
+ return UBUS_STATUS_UNKNOWN_ERROR;
+ }
+
+ ret = dpp_build_bootstrap_info_from_uri(uri, enrollee_bi);
+ if (ret) {
+ fprintf(stderr, "Failed to build bootstrap info\n");
+ return UBUS_STATUS_UNKNOWN_ERROR;
+ }
+
+ ret = dpp_bootstrap_add(c->dpp, enrollee_bi);
+ if (ret) {
+ fprintf(stderr, "Failed to add bootstrap\n");
+ return UBUS_STATUS_UNKNOWN_ERROR;
+ }
+
+ //dpp_append_uri_file(c, uri);
+
+ return UBUS_STATUS_OK;
+}
+
static int cntlr_dpp_uri(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
+
struct controller *c = container_of(obj, struct controller, obj);
struct blob_attr *tb[__DPP_URI_MAX];
struct dpp_enrollee *e;
@@ -870,9 +919,9 @@ DPP:C:81/1;M:b0dd74001c32;V:2;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgACtPpZTi2FPf1e
/* TODO: parse correctly */
if (tb[DPP_URI_TYPE])
- e->type = DPP_BOOTSTRAP_QR_CODE;
+ e->type = DPP_BOOTSTRAP_QR_CODE_WIFI;
else
- e->type = DPP_BOOTSTRAP_QR_CODE;
+ e->type = DPP_BOOTSTRAP_QR_CODE_WIFI;
dbg("|%s:%d| MAC "MACFMT" has URI %s\n", __func__, __LINE__, MAC2STR(e->mac), e->uri);
@@ -3538,6 +3587,8 @@ int cntlr_publish_object(struct controller *c, const char *objname)
#if (EASYMESH_VERSION > 2)
UBUS_METHOD("dpp_enrollee_uri", cntlr_dpp_uri,
dpp_uri_params),
+ UBUS_METHOD("dpp_enrollee_uri_eth", cntlr_dpp_uri_eth,
+ dpp_uri_params),
#endif /* DPP */
UBUS_METHOD("steer_summary", cntlr_steer_summary,
steer_summary_params),
diff --git a/src/config.c b/src/config.c
index 55c7d468384ea51a2b4942ee1f044dc7334cdef3..01a7a539a2cd8eae40161b0f98d13a0716cf111a 100644
--- a/src/config.c
+++ b/src/config.c
@@ -36,6 +36,8 @@
#include "config.h"
#include "timer.h"
#if (EASYMESH_VERSION > 2)
+#include <dpp_api.h>
+
#include "dpp.h"
#endif
#include "cntlr.h"
@@ -1230,6 +1232,24 @@ static int cntlr_config_get_credentials(struct controller_config *c,
c->num_bss++;
list_add_tail(&cred->list, &c->aplist);
+
+#if (EASYMESH_VERSION > 2)
+ if (cred->multi_ap & 0x01) {
+ struct controller *cntlr = container_of(c, struct controller, cfg);
+ const char *sec;
+
+ if (tb[CRED_SEC])
+ sec = tb[CRED_SEC]->v.string;
+ else
+ sec = "none";
+
+ dpp_set_configuration(cntlr->dpp, DPP_NETROLE_MAP_BH_STA,
+ dpp_akm_from_str(sec),
+ (char *) cred->ssid,
+ (char *) cred->key,
+ cred->band);
+ }
+#endif
return 0;
}
diff --git a/src/dpp.c b/src/dpp.c
index 2f9e2894ce80482bb5bf028698fda9110da3b430..927845364b19a5690be278f3963ca49670af1324 100644
--- a/src/dpp.c
+++ b/src/dpp.c
@@ -49,7 +49,10 @@
#include "utils/debug.h"
#include "utils/dpp_sock.h"
#if (EASYMESH_VERSION > 2)
+#include <dpp_api.h>
+
#include "dpp.h"
+#include <math.h>
#endif
//#include "config.h"
#include "cntlr.h"
@@ -62,33 +65,9 @@
static void dpp_fd_timeout(atimer_t *t);
-uint8_t *dpp_get_attr(uint8_t *buf, size_t len, uint16_t req_id,
- uint16_t *ret_len)
-{
- uint16_t id, alen;
- uint8_t *pos = buf, *end = buf + len;
-
- while (end - pos >= 4) {
- id = buf_get_le16(pos);
- pos += 2;
- alen = buf_get_le16(pos);
- pos += 2;
- if (alen > end - pos)
- return NULL;
- if (id == req_id) {
- *ret_len = alen;
- return pos;
- }
- pos += alen;
- }
-
- return NULL;
-}
-
-
const char *dpp_type2str(enum dpp_bootstrap_type type)
{
- if (type == DPP_BOOTSTRAP_QR_CODE)
+ if (type == DPP_BOOTSTRAP_QR_CODE_WIFI)
return "qrcode";
else if (type == DPP_BOOTSTRAP_PKEX)
return "pkex";
@@ -157,23 +136,6 @@ const char *dpp_frame_type2str(uint8_t type)
return "Unknown";
}
-uint8_t dpp_get_pub_af_type(uint8_t *frame, uint16_t framelen)
-{
- if (framelen < 7)
- return 255;
-
- return *(frame + 6);
-}
-
-uint8_t dpp_get_gas_frame_type(const uint8_t *frame, uint16_t framelen)
-{
- if (framelen < 1)
- return 255;
-
- return *frame;
-}
-
-
struct dpp_enrollee *dpp_enrollee_get(struct controller *c, uint8_t *mac)
{
struct dpp_enrollee *e;
@@ -193,6 +155,9 @@ struct dpp_enrollee *dpp_enrollee_get_hash(struct controller *c, uint8_t *hash)
list_for_each_entry(e, &c->dpp_ctx.enrolleelist, list) {
struct dpp_chirp *p = e->chirp;
+ if (!memcmp(e->hash, hash, 32))
+ return e;
+
if (!p)
continue;
@@ -214,6 +179,7 @@ struct dpp_enrollee *dpp_enrollee_alloc(struct controller *c, uint8_t *mac)
return NULL;
}
+ e->band = BAND_UNKNOWN;
e->c = c; /* TODO: deprecate */
memcpy(e->mac, mac, 6);
INIT_LIST_HEAD(&e->framelist);
@@ -605,6 +571,8 @@ struct dpp_enrollee *dpp_process_new_uri(struct controller *c, char *uri)
char *macstr;
uint8_t enrollee[6] = {0};
struct dpp_enrollee *e;
+ char *hashstr;
+ char *hashend;
int rc;
if (strncmp(uri, "DPP:", 4)) {
@@ -614,16 +582,22 @@ struct dpp_enrollee *dpp_process_new_uri(struct controller *c, char *uri)
macstr = strstr(uri, ";M:"); // find mac address in URI
if (!macstr) {
- dbg("|%s:%d| URI has invalid format! (Right now) MAC is mandated\n", __func__, __LINE__);
- return NULL;
+ macstr = strstr(uri, "DPP:M:"); // find mac address in URI
+ if (!macstr) {
+ dbg("|%s:%d| URI has invalid format! (Right now) MAC is mandated\n", __func__, __LINE__);
+ return NULL;
+ }
+ macstr += 3; /* step past DPP identifier */
}
- if (*(macstr + 15) != ';') {
+ macstr += 3; /* step past mac identifier */
+
+
+ if (*(macstr + 12) != ';') {
dbg("|%s:%d| URI MAC has invalid format!\n", __func__, __LINE__);
return NULL;
}
- macstr += 3; /* step past mac identifier */
strtob(macstr, 6, enrollee);
e = dpp_enrollee_get(c, enrollee);
@@ -640,15 +614,30 @@ struct dpp_enrollee *dpp_process_new_uri(struct controller *c, char *uri)
strncpy(e->uri, uri, sizeof(e->uri) - 1);
+ hashstr = strstr(uri, ";K:");
+ hashstr += 3 + 36; /* TODO: probably step 36 is not correct, but gives correct bytes in hashb output */
+ hashend = strstr(hashstr, ";");
+
+ if (hashstr && hashend) {
+ uint8_t len = 0;
+ uint8_t hashb[128] = {0};
+ size_t hlen = 128;
+
+ len = abs(hashend - hashstr);
+ rc = base64_decode((unsigned char *) hashstr, (size_t)len, (unsigned char *) hashb, &hlen);
+ memcpy(e->hash, hashb, hlen);
+ dump(e->hash, hlen, "enrollee hash");
+ }
+
dbg("|%s:%d| MAC "MACFMT" has URI %s\n", __func__, __LINE__, MAC2STR(e->mac), e->uri);
send_dpp_cce_indication_all(c, true);
rc = dpp_parse_uri_chan_list(c, e, e->uri);
if (rc < 0) {
- dbg("|%s:%d| URI MAC has invalid format! (Right now) Opclass/Channel list is mandated\n", __func__, __LINE__);
- dpp_enrollee_free(e);
- return NULL;
+ dbg("|%s:%d| URI chanlist has invalid format! (Right now) Opclass/Channel list is mandated\n", __func__, __LINE__);
+ // dpp_enrollee_free(e);
+ // return NULL;
}
if (e->num_chan) {
e->band = wifi_channel_to_band(e->chan[0].channel);
@@ -658,26 +647,26 @@ struct dpp_enrollee *dpp_process_new_uri(struct controller *c, char *uri)
}
- {
- /* THIS IS A HACK */
- uint8_t bssid[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- uint8_t radio[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- struct cmdu_buff *cmdu;
- int len = 0;
-
- len = strlen(e->uri);
- cmdu = cntlr_gen_dpp_bootstrapping_uri_notification(c, radio, bssid,
- enrollee, len, e->uri);
- if (cmdu) {
- struct node *n;
-
- list_for_each_entry(n, &c->nodelist, list) {
- memcpy(cmdu->origin, n->alid, 6);
- send_cmdu(c, cmdu);
- }
- cmdu_free(cmdu);
- }
- }
+// {
+// /* THIS IS A HACK */
+// uint8_t bssid[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+// uint8_t radio[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+// struct cmdu_buff *cmdu;
+// int len = 0;
+//
+// len = strlen(e->uri);
+// cmdu = cntlr_gen_dpp_bootstrapping_uri_notification(c, radio, bssid,
+// enrollee, len, e->uri);
+// if (cmdu) {
+// struct node *n;
+//
+// list_for_each_entry(n, &c->nodelist, list) {
+// memcpy(cmdu->origin, n->alid, 6);
+// send_cmdu(c, cmdu);
+// }
+// cmdu_free(cmdu);
+// }
+// }
return e;
}
@@ -726,15 +715,101 @@ int dpp_cntlr_read_uris(struct controller *c)
continue;
if (strcmp("qr", blobmsg_data(tb1[1])))
- e->type = DPP_BOOTSTRAP_QR_CODE;
+ e->type = DPP_BOOTSTRAP_QR_CODE_WIFI;
else
- e->type = DPP_BOOTSTRAP_QR_CODE;
+ e->type = DPP_BOOTSTRAP_QR_CODE_WIFI;
}
out:
blob_buf_free(&uris);
return rc;
}
+int dpp_frame_handler(void *dpp, uint8_t *smac, enum dpp_event ev,
+ uint8_t *frame, size_t framelen)
+{
+ struct controller *c;
+
+ err("%s: ----->\n", __func__);
+
+ if (!smac) {
+ warn("%s: Error: smac = NULL\n", __func__);
+ return -1;
+ }
+
+ err("%s: DPP_EVENT: event = %d smac = " MACFMT", frame = %p, len = %zu\n",
+ __func__, ev, MAC2STR(smac), frame, framelen);
+
+ switch (ev) {
+ case DPP_EVENT_TX_FRAME: {
+ struct cmdu_buff *resp;
+ int frametype = 0;
+
+ frametype = dpp_get_frame_type(frame + 1, framelen - 1);
+ if (frametype == 255) {
+ warn("Invalid frametype\n");
+ return -1;
+ }
+
+ c = dpp_get_ctx_private_data(dpp);
+ if (!c)
+ return -1;
+
+ dbg("DPP frametype %s\n", dpp_frame_type2str(frametype));
+ resp = cntlr_gen_direct_encap_dpp(c, smac, frame, framelen);
+ if (!resp) {
+ warn("|%s:%d| DPP: ----> Error generating proxy encap\n",
+ __func__, __LINE__);
+ return -1;
+ }
+
+ switch (frametype) {
+ case DPP_PA_AUTHENTICATION_REQ: {
+#if 0 /* TODO: will be needed for proxied encap */
+ struct node *n;
+
+ list_for_each_entry(n, &c->nodelist, list) {
+ memcpy(resp->origin, smac, 6);
+ send_cmdu(c, resp);
+ }
+ cmdu_free(resp);
+
+ break;
+#else
+ /* FALLTHROUGH */
+#endif
+ }
+ case DPP_PA_AUTHENTICATION_CONF:
+ case DPP_PUB_AF_GAS_INITIAL_RESP:
+ case DPP_PA_PEER_DISCOVERY_RESP:
+ memcpy(resp->origin, smac, 6);
+ send_cmdu(c, resp);
+ cmdu_free(resp);
+ break;
+ default:
+ warn("|%s:%d| DPP: ----> Unknown frame\n", __func__, __LINE__);
+ break;
+ }
+ break;
+ }
+ case DPP_EVENT_BAD_AUTH:
+ err("DPP: BAD AUTH!\n");
+ /* FALLTHROUGH */
+ case DPP_EVENT_TIMEOUT: {
+ struct dpp_peer *peer = dpp_lookup_peer(dpp, smac);
+
+ err("DPP: EVENT TIMEOUT!\n");
+
+ if (peer) {
+ list_del(&peer->list);
+ dpp_free_peer(dpp, peer);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return 0;
+}
static void dpp_fd_timeout(atimer_t *t)
diff --git a/src/dpp.h b/src/dpp.h
index a32f58c6bc00aafe77509885e654f9f51c15b7e5..0ab2eacd40276d7f80c17d7aa588a2cae6daf678 100644
--- a/src/dpp.h
+++ b/src/dpp.h
@@ -1,21 +1,7 @@
#ifndef DPP_H
#define DPP_H
-#define PUB_AF_CATEGORY 0x04
-#define DPP_PUB_AF_ACTION 0x09
-#define DPP_PUB_AF_ACTION_OUI_TYPE 0x1A
-#define DPP_PUB_AF_GAS_INITIAL_REQ 0x0A
-#define DPP_PUB_AF_GAS_INITIAL_RESP 0x0B
-
-#define FRAME_IS_DPP_PUB_AF(frame) \
- ((*(frame) == DPP_PUB_AF_ACTION) && \
- (memcmp((frame + 1), "\x50\x6F\x9A", 3) == 0) && \
- ((*(frame + 4)) == DPP_PUB_AF_ACTION_OUI_TYPE))
-
-#define FRAME_IS_DPP_GAS_FRAME(frame) \
- ((*(frame) == DPP_PUB_AF_GAS_INITIAL_REQ) || \
- (*(frame) == DPP_PUB_AF_GAS_INITIAL_RESP))
-
+#include <dpputils.h>
#define FRAME_DST_ENROLLEE(type) \
((type == DPP_PA_AUTHENTICATION_REQ) || \
@@ -23,63 +9,6 @@
#define DPP_URI_FILE "/etc/multiap/dpp_uris.json"
-enum dpp_public_action_frame_type {
- DPP_PA_AUTHENTICATION_REQ = 0,
- DPP_PA_AUTHENTICATION_RESP = 1,
- DPP_PA_AUTHENTICATION_CONF = 2,
- DPP_PA_PEER_DISCOVERY_REQ = 5,
- DPP_PA_PEER_DISCOVERY_RESP = 6,
- DPP_PA_PKEX_V1_EXCHANGE_REQ = 7,
- DPP_PA_PKEX_EXCHANGE_RESP = 8,
- DPP_PA_PKEX_COMMIT_REVEAL_REQ = 9,
- DPP_PA_PKEX_COMMIT_REVEAL_RESP = 10,
- DPP_PA_CONFIGURATION_RESULT = 11,
- DPP_PA_CONNECTION_STATUS_RESULT = 12,
- DPP_PA_PRESENCE_ANNOUNCEMENT = 13,
- DPP_PA_RECONFIG_ANNOUNCEMENT = 14,
- DPP_PA_RECONFIG_AUTH_REQ = 15,
- DPP_PA_RECONFIG_AUTH_RESP = 16,
- DPP_PA_RECONFIG_AUTH_CONF = 17,
- DPP_PA_PKEX_EXCHANGE_REQ = 18,
-};
-
-enum dpp_attribute_id {
- DPP_ATTR_STATUS = 0x1000,
- DPP_ATTR_I_BOOTSTRAP_KEY_HASH = 0x1001,
- DPP_ATTR_R_BOOTSTRAP_KEY_HASH = 0x1002,
- DPP_ATTR_I_PROTOCOL_KEY = 0x1003,
- DPP_ATTR_WRAPPED_DATA = 0x1004,
- DPP_ATTR_I_NONCE = 0x1005,
- DPP_ATTR_I_CAPABILITIES = 0x1006,
- DPP_ATTR_R_NONCE = 0x1007,
- DPP_ATTR_R_CAPABILITIES = 0x1008,
- DPP_ATTR_R_PROTOCOL_KEY = 0x1009,
- DPP_ATTR_I_AUTH_TAG = 0x100A,
- DPP_ATTR_R_AUTH_TAG = 0x100B,
- DPP_ATTR_CONFIG_OBJ = 0x100C,
- DPP_ATTR_CONNECTOR = 0x100D,
- DPP_ATTR_CONFIG_ATTR_OBJ = 0x100E,
- DPP_ATTR_BOOTSTRAP_KEY = 0x100F,
- DPP_ATTR_OWN_NET_NK_HASH = 0x1011,
- DPP_ATTR_FINITE_CYCLIC_GROUP = 0x1012,
- DPP_ATTR_ENCRYPTED_KEY = 0x1013,
- DPP_ATTR_ENROLLEE_NONCE = 0x1014,
- DPP_ATTR_CODE_IDENTIFIER = 0x1015,
- DPP_ATTR_TRANSACTION_ID = 0x1016,
- DPP_ATTR_BOOTSTRAP_INFO = 0x1017,
- DPP_ATTR_CHANNEL = 0x1018,
- DPP_ATTR_PROTOCOL_VERSION = 0x1019,
- DPP_ATTR_ENVELOPED_DATA = 0x101A,
- DPP_ATTR_SEND_CONN_STATUS = 0x101B,
- DPP_ATTR_CONN_STATUS = 0x101C,
- DPP_ATTR_RECONFIG_FLAGS = 0x101D,
- DPP_ATTR_C_SIGN_KEY_HASH = 0x101E,
- DPP_ATTR_CSR_ATTR_REQ = 0x101F,
- DPP_ATTR_A_NONCE = 0x1020,
- DPP_ATTR_E_PRIME_ID = 0x1021,
- DPP_ATTR_CONFIGURATOR_NONCE = 0x1022,
-};
-
enum dpp_responder_state {
DPP_BOOSTRAPPING,
DPP_AUTHENTICATING,
@@ -88,7 +17,7 @@ enum dpp_responder_state {
/* taken from dpp.h */
enum dpp_bootstrap_type {
- DPP_BOOTSTRAP_QR_CODE,
+ DPP_BOOTSTRAP_QR_CODE_WIFI,
DPP_BOOTSTRAP_PKEX,
DPP_BOOTSTRAP_NFC_URI,
};
@@ -125,8 +54,10 @@ struct dpp_chan {
struct dpp_enrollee {
struct controller *c; /* TODO: lazy, should all be part of some dpp_ctx which can be traced back to cntlr */
+ uint8_t almac[6];
uint8_t mac[6];
char uri[128];
+ uint8_t hash[32];
bool onboarded;
uint8_t bootstrap_id;
@@ -142,28 +73,24 @@ struct dpp_enrollee {
struct list_head list;
};
-struct dpp_context {
+struct dpp_context_wifi {
struct list_head enrolleelist;
struct list_head chirplist;
};
struct controller;
-
-uint8_t *dpp_get_attr(uint8_t *buf, size_t len, uint16_t req_id,
- uint16_t *ret_len);
+enum dpp_event;
const char *dpp_type2str(enum dpp_bootstrap_type type);
const char *dpp_frame_type2str(uint8_t type);
const char *dpp_state2str(enum dpp_responder_state state);
-uint8_t dpp_get_pub_af_type(uint8_t *frame, uint16_t framelen);
-uint8_t dpp_get_gas_frame_type(const uint8_t *frame, uint16_t framelen);
-
struct dpp_chirp *dpp_chirp_get(struct controller *c, uint8_t *hash);
struct dpp_chirp *dpp_chirp_alloc(struct controller *c, uint8_t *hash);
struct dpp_enrollee *dpp_enrollee_get(struct controller *c, uint8_t *mac);
+struct dpp_enrollee *dpp_enrollee_get_hash(struct controller *c, uint8_t *hash);
struct dpp_enrollee *dpp_enrollee_alloc(struct controller *c, uint8_t *mac);
void dpp_enrollee_free(struct dpp_enrollee *e);
@@ -192,4 +119,7 @@ struct dpp_enrollee *dpp_process_new_uri(struct controller *c, char *uri);
int dpp_cntlr_read_uris(struct controller *c);
void dpp_event_uloop_cb(struct uloop_fd *fd, unsigned int events);
+
+int dpp_frame_handler(void *dpp, uint8_t *smac, enum dpp_event ev,
+ uint8_t *frame, size_t framelen);
#endif