diff --git a/src/cntlr_cmdu.c b/src/cntlr_cmdu.c
index 8d4a85b5d7eed86658f797bf1f34bd94ade23d3e..4863e4242eebe69a2cd11c6b03af07bcf4ee0ec3 100644
--- a/src/cntlr_cmdu.c
+++ b/src/cntlr_cmdu.c
@@ -521,7 +521,11 @@ out:
 }
 
 struct cmdu_buff *cntlr_gen_ap_autoconfig_response(struct controller *c,
-		uint8_t *dest, uint8_t band, uint16_t mid)
+#if (EASYMESH_VERSION > 2)
+		struct dpp_enrollee *e, bool hash_validity,
+#endif
+		uint8_t *dest, uint8_t band, uint16_t mid
+		)
 {
 	struct cmdu_buff *resp;
 	int ret;
@@ -553,11 +557,13 @@ 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 (e) {
+			ret = cntlr_gen_chirp_value_tlv(c, resp, e->mac, 32, e->hash);
+			if (ret)
+				goto out;
+		}
+
 		ret = cntlr_gen_cntlr_capability(c, resp, 0x00);
 		if (ret)
 			goto out;
@@ -1072,7 +1078,10 @@ 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,
+					      uint16_t framelen,
+					      uint8_t *frame)
 {
 	struct cmdu_buff *frm;
 	uint16_t mid = 0;
@@ -1086,7 +1095,7 @@ struct cmdu_buff *cntlr_gen_direct_encap_dpp(struct controller *c)
 	}
 
 	/* 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;
 	}
diff --git a/src/cntlr_cmdu.h b/src/cntlr_cmdu.h
index 968c24a04b58ec9951876a48faa116d26c2cef9a..a2ab5fd81ba1132cec13e005b20d14cae3e3a9fa 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)
+		struct dpp_enrollee *e, bool hash_validity,
+#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,
+					      uint16_t framelen,
+					      uint8_t *frame);
 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 832376a5d80719ce4c182ac19462e3de56aee3f3..09c94389ffe56b0d8d723810b06ef268591ef04e 100644
--- a/src/cntlr_map.c
+++ b/src/cntlr_map.c
@@ -950,6 +950,9 @@ 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)
+	struct dpp_enrollee *e = NULL;
+#endif
 	struct tlv *t;
 	struct cmdu_buff *cmdu;
 	uint8_t almac[6] = {0};
@@ -1042,9 +1045,47 @@ 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]) {
+		int offset = 0;
+		uint8_t flag = 0;
+		bool mac_present;
+		bool hash_validity;
+		uint8_t *mac;
+		uint8_t hashlen;
+		uint8_t *hash;
+
+		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];
+		err("|%s:%d| hashlen:%d\n", __func__, __LINE__, hashlen);
+		dump(hash, hashlen, "autoconf search chirp hash");
+		e = dpp_enrollee_get_hash(c, hash);
+		if (e) {
+			err("|%s:%d| WE FOUND A MATCH FOR AUTOCONIFG SEARCH!\n", __func__, __LINE__);
+		}
+	}
+
+#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)
+			e, !!e,
+#endif
+			almac,
 			freq->band,
 			cmdu_get_mid(rx_cmdu));
 	if (!cmdu)
@@ -3564,23 +3605,101 @@ 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;
+	struct dpp_enrollee *e = NULL;
+	struct dpp_frame *dpp_frm;
+
+	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;
 
-	// TODO: process DPP Message TLV
+	frame = dpp_msg->frame;
+	framelen = tlv->len;
 
+	if (FRAME_IS_DPP_PUB_AF(frame))
+		frametype = dpp_get_pub_af_type(frame, framelen);
+	else if (FRAME_IS_DPP_GAS_FRAME(frame))
+		frametype = dpp_get_gas_frame_type(frame, framelen);
+	else
+		return -1;
+
+	if (frametype == 255)
+		return -1;
+
+	/* Encapsulated frame length */
+	dump(frame, framelen, "DIRECT CMDU FRAME");
+
+	if (frametype == DPP_PA_PRESENCE_ANNOUNCEMENT) {
+		uint16_t attrlen = 0;
+		uint8_t *pos;
+
+		pos = dpp_get_attr(frame + 7, /* meta data to attributes */
+				framelen - 7,
+				DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
+				&attrlen);
+		if (pos) {
+			struct dpp_chirp *chirp;
+
+			chirp = dpp_chirp_get(c, pos);
+			if (!chirp) {
+				dbg("|%s:%d| matching chrip not found, allocate\n",
+					__func__, __LINE__);
+				chirp = dpp_chirp_alloc(c, pos);
+				if (!chirp) {
+					dbg("|%s:%d| Failed to allocate chirp\n",
+						__func__, __LINE__);
+					goto out;
+				}
+			}
+
+			//if (chirp->auth_req /* && chirp->chirp_fd.fd > 0 */) {
+				//struct dpp_frame *auth_req = chirp->auth_req;
+
+				//socket_send_dpp_tcp_message(c->chirp_fd.fd,
+				//			    auth_req->data,
+				//			    auth_req->len);
+				//warn("|%s:%d| already have assoc req frame!\n", __func__, __LINE__);
+				//goto out;
+			//}
+
+			e = dpp_enrollee_alloc(c, cmdu->origin);
+			if (!e)
+				goto out;
+
+			e->chirp = chirp;
+		}
+	}
+
+	if (!e) {
+		e = dpp_enrollee_get(c, cmdu->origin);
+		if (!e) {
+			err("|%s:%d|\n", __func__, __LINE__);
+			return -1;
+		}
+	}
+
+	dpp_frm = dpp_enrollee_add_frame(c, e, frametype, framelen, frame, cmdu->origin);
+	if (!dpp_frm) {
+		dbg("|%s:%d| frame for type:%d failed to allocate!\n", __func__,
+		    __LINE__, frametype);
+		return -1;
+	}
+out:
 	return 0;
 }
 
diff --git a/src/cntlr_tlv.c b/src/cntlr_tlv.c
index 041b24c1a957c8863991ab2aa81ef9c0227f0127..6303f8bc309469df7ad6a19f3d8a2f67a021500a 100644
--- a/src/cntlr_tlv.c
+++ b/src/cntlr_tlv.c
@@ -1680,14 +1680,10 @@ 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);
 	if (!t)
@@ -1695,14 +1691,9 @@ int cntlr_gen_dpp_message_tlv(struct controller *c, struct cmdu_buff *frm)
 
 	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;
 
diff --git a/src/cntlr_tlv.h b/src/cntlr_tlv.h
index 1479c98a85a67afdd035c090bdac32078df687c0..dfc5839e143b12f65e2d3bc213a62e681895ea1f 100644
--- a/src/cntlr_tlv.h
+++ b/src/cntlr_tlv.h
@@ -115,8 +115,8 @@ 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);
diff --git a/src/dpp.c b/src/dpp.c
index 2f9e2894ce80482bb5bf028698fda9110da3b430..e97053a8e0459b97893caeda7e57d5548121d667 100644
--- a/src/dpp.c
+++ b/src/dpp.c
@@ -50,6 +50,7 @@
 #include "utils/dpp_sock.h"
 #if (EASYMESH_VERSION > 2)
 #include "dpp.h"
+#include <math.h>
 #endif
 //#include "config.h"
 #include "cntlr.h"
@@ -193,6 +194,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 +218,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 +610,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 +621,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 +653,32 @@ 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, "jakob haha");
+		}
+	}
+
 	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 +688,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;
 }
@@ -736,6 +766,10 @@ out:
 	return rc;
 }
 
+//int dpp_handle_frame(struct controller *c, uint8_t frame)
+//{
+//
+//}
 
 static void dpp_fd_timeout(atimer_t *t)
 {
diff --git a/src/dpp.h b/src/dpp.h
index a32f58c6bc00aafe77509885e654f9f51c15b7e5..8da9f2527d5c2b13fe5efe92af3572cc12e5c8b2 100644
--- a/src/dpp.h
+++ b/src/dpp.h
@@ -125,8 +125,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;
@@ -164,6 +166,7 @@ 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);