diff --git a/src/cntlr.h b/src/cntlr.h
index 659eb2e60e27d1a7e25be60ebb547195a09250ca..b6d7920a1ea463080fac302d002bd1f19e5c7c55 100644
--- a/src/cntlr.h
+++ b/src/cntlr.h
@@ -71,18 +71,6 @@ struct scan_req_data {
 	} radios[SCAN_REQ_MAX_NUM_RADIO];
 };
 
-struct proxied_encap_dpp_data {
-	/* TODO: implement & use as param
-	 * to cntlr_gen_proxied_encap_dpp
-	 */
-};
-
-struct direct_encap_dpp_data {
-	/* TODO: implement & use as param
-	 * to cntlr_gen_direct_encap_dpp
-	 */
-};
-
 struct bcn_meas_element {
 	uint8_t tag_number;
 	uint8_t tag_length;
diff --git a/src/cntlr_cmdu.c b/src/cntlr_cmdu.c
index 166e43a843f662090f672b72106f55564de9ada0..b1200c86ab1a5187926ca894af2e79330ede83e8 100644
--- a/src/cntlr_cmdu.c
+++ b/src/cntlr_cmdu.c
@@ -1127,16 +1127,14 @@ out:
 struct cmdu_buff *cntlr_gen_proxied_encap_dpp(struct controller *c,
 					      uint8_t *enrollee,
 					      uint8_t frametype,
-					      uint16_t framelen,
 					      uint8_t *frame,
-					      uint16_t hashlen,
-					      uint8_t *hash)
+					      uint16_t framelen,
+					      uint8_t *hash,
+					      uint16_t hashlen)
 {
 	struct cmdu_buff *frm;
 	uint16_t mid = 0;
 
-	/* TODO: Pass proxied_encap_dpp_data parameter */
-
 	frm = cmdu_alloc_frame(5000);
 	if (!frm) {
 		trace("%s: -ENOMEM\n", __func__);
diff --git a/src/cntlr_cmdu.h b/src/cntlr_cmdu.h
index 3066422d7113ae77f6a94256219d5bb0efce101b..2d47760f1c5afb088188fc149ffa61dd04efd089 100644
--- a/src/cntlr_cmdu.h
+++ b/src/cntlr_cmdu.h
@@ -98,10 +98,10 @@ int cntlr_send_client_steer_request(struct controller *c,
 struct cmdu_buff *cntlr_gen_proxied_encap_dpp(struct controller *c,
 					      uint8_t *enrollee,
 					      uint8_t frametype,
-					      uint16_t framelen,
 					      uint8_t *frame,
-					      uint16_t hashlen,
-					      uint8_t *hash);
+					      uint16_t framelen,
+					      uint8_t *hash,
+					      uint16_t hashlen);
 struct cmdu_buff *cntlr_gen_direct_encap_dpp(struct controller *c,
 					      uint8_t *dst,
 					      uint8_t *frame,
diff --git a/src/cntlr_map.c b/src/cntlr_map.c
index 60cb3a976748b836b5b2dd07b916af8cfd370330..4aa48a102390854dc38a86ef00bd470dec4023f5 100644
--- a/src/cntlr_map.c
+++ b/src/cntlr_map.c
@@ -3472,7 +3472,6 @@ int handle_proxied_encap_dpp(void *cntlr, struct cmdu_buff *cmdu,
 	int offset = 0;
 	uint8_t *frame;
 
-	UNUSED(enrollee);
 	UNUSED(hashlen);
 
 	if (!validate_proxied_encap_dpp(cmdu, tv)) {
@@ -3495,6 +3494,7 @@ int handle_proxied_encap_dpp(void *cntlr, struct cmdu_buff *cmdu,
 		/* TODO: what do we do if there is no mac address?
 		 * for which frames is this applicable?
 		 */
+		dbg("DPP: Proxied encap are expected to contain enrollee MAC\n");
 		return -1;
 	}
 
@@ -3525,6 +3525,7 @@ int handle_proxied_encap_dpp(void *cntlr, struct cmdu_buff *cmdu,
 		}
 	}
 
+#if 0
 	/* if we did not get hash from chirp, we can extract it
 	 * from the frame
 	 */
@@ -3555,13 +3556,12 @@ int handle_proxied_encap_dpp(void *cntlr, struct cmdu_buff *cmdu,
 
 	if (!hash)
 		return -1;
-
-
+#endif
 	switch (frm->type) {
 	case DPP_PA_PRESENCE_ANNOUNCEMENT: {
 		int ret;
 
-		ret = dpp_process_presence_announcement(c->dpp, cmdu->origin,
+		ret = dpp_process_presence_announcement(c->dpp, enrollee,
 							frame,
 							framelen);
 		if (ret) {
@@ -3569,7 +3569,11 @@ int handle_proxied_encap_dpp(void *cntlr, struct cmdu_buff *cmdu,
 			break;
 		}
 
-		dbg("%s processing PA\n", (!ret ? "Succeeded" : "Failed"));
+		ret = dpp_set_peer_private_data(c->dpp, enrollee, n);
+		if (ret) {
+			dbg("Failed to set private data!\n");
+			break;
+		}
 		/* FALLTHROUGH */
 	}
 	case DPP_PA_AUTHENTICATION_RESP:
@@ -3577,13 +3581,12 @@ int handle_proxied_encap_dpp(void *cntlr, struct cmdu_buff *cmdu,
 	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,
+		void *event = dpp_sm_create_event(c->dpp, enrollee,
 					    DPP_EVENT_RX_FRAME, framelen,
 					    frame);
 
 		if (event) {
-			dpp_trigger(c->dpp, cmdu->origin, event);
+			dpp_trigger(c->dpp, enrollee, event);
 			dpp_sm_free_event(event);
 		}
 		break;
diff --git a/src/dpp.c b/src/dpp.c
index 8162d0bf52c230e1edefc4ec9aae4a18ae297fee..df8f9ce24881054954ebc0e9a0e3b31c1e5144a9 100644
--- a/src/dpp.c
+++ b/src/dpp.c
@@ -269,6 +269,7 @@ int dpp_frame_handler(void *dpp, uint8_t *smac, enum dpp_event ev,
 	case DPP_EVENT_TX_FRAME: {
 		struct cmdu_buff *resp;
 		int frametype = 0;
+		struct node *proxy = NULL;
 
 		frametype = dpp_get_frame_type(frame + 1, framelen - 1);
 		if (frametype == 255) {
@@ -276,38 +277,56 @@ int dpp_frame_handler(void *dpp, uint8_t *smac, enum dpp_event ev,
 			return -1;
 		}
 
+		dbg("DPP frametype %s\n", dpp_frame_type2str(frametype));
+
 		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;
+		/* if peer has private data, it is the proxy node
+		 * thus we can infer its a proxied encap DPP message
+		 */
+		proxy = dpp_get_peer_private_data(dpp, smac);
+		if (proxy) {
+			resp = cntlr_gen_proxied_encap_dpp(c, smac, frametype,
+							   frame, framelen,
+							   NULL, 0);
+			if (!resp) {
+				warn("|%s:%d| DPP: ----> Error generating proxy encap\n",
+				__func__, __LINE__);
+				return -1;
+			}
+		} else {
+			resp = cntlr_gen_direct_encap_dpp(c, smac, frame,
+							  framelen);
+			if (!resp) {
+				warn("|%s:%d| DPP: ----> Error generating direct 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);
+			if (proxy) {
+				struct node *n;
+
+				list_for_each_entry(n, &c->nodelist, list) {
+					memcpy(resp->origin, n->alid, 6);
+					send_cmdu(c, resp);
+				}
+				cmdu_free(resp);
+				break;
 			}
-			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);
+			if (proxy)
+				memcpy(resp->origin, proxy->alid, 6);
+			else
+				memcpy(resp->origin, smac, 6);
 			send_cmdu(c, resp);
 			cmdu_free(resp);
 			break;