diff --git a/src/core/agent.c b/src/core/agent.c
index 936b33c98d92d2f8613a7fcdbad94d107ab71c62..1f14adccf967e13874b5c66db15f697a8d23ab64 100644
--- a/src/core/agent.c
+++ b/src/core/agent.c
@@ -1941,6 +1941,30 @@ out_str:
 static void wifi_radio_event_handler(void *c, struct blob_attr *msg)
 {
 	dbg("%s --->\n", __func__);
+	struct agent *agent = (struct agent *) c;
+	struct blob_attr *tb[2];
+	char radio[18] = {0}, action[14] = {0};
+	bool scan_finished;
+	static const struct blobmsg_policy ev_attr[2] = {
+		[0] = { .name = "radio", .type = BLOBMSG_TYPE_STRING },
+		[1] = { .name = "action", .type = BLOBMSG_TYPE_STRING },
+	};
+
+	blobmsg_parse(ev_attr, 2, tb, blob_data(msg), blob_len(msg));
+	if (!tb[0] || !tb[1])
+		dbg("Wifi event parse error.\n");
+	else {
+		strncpy(radio, blobmsg_data(tb[0]), sizeof(radio) - 1);
+		strncpy(action, blobmsg_data(tb[1]), sizeof(action) - 1);
+		dbg("%s for %s\n", action, radio);
+
+		scan_finished = !strcmp(action, "scan_finished");
+		if (scan_finished) {
+			struct wifi_radio_element *current_radio = wifi_ifname_to_radio_element(agent, radio);
+			current_radio->scanned = 1;
+			handle_wifi_radio_scan_finished(agent);
+		}
+	}
 }
 
 int wifi_mod_bridge(struct agent *a, char *ifname, char *action)
@@ -2413,6 +2437,7 @@ static void ieee1905_cmdu_event_handler(void *c, struct blob_attr *msg)
 		}
 
 		strtob(tlvstr, len, tlv);
+
 		free(tlvstr);
 	}
 
diff --git a/src/core/agent.h b/src/core/agent.h
index 65f5d5babfcd5b3f26a4f5a6103ba147c02cbc62..dd99093c27b86aa617e1957c791b1938e6351871 100644
--- a/src/core/agent.h
+++ b/src/core/agent.h
@@ -394,6 +394,9 @@ struct wifi_radio_element {
 	bool configured;
 	uint16_t mid;
 	struct wsc_data autconfig;
+
+	/* requested channel scan with event handling */
+	bool scanned;
 };
 
 struct wifi_netdev {
@@ -453,6 +456,9 @@ struct agent {
 	} loop_detection;
 
 	uint8_t depth;
+
+	/* requested channel scan with event handling */
+	struct cmdu_cstruct *req_channel_scan_cmdu;
 };
 
 struct netif_bk *find_bkhaul_by_bssid(struct agent *a, uint8_t *bssid);
diff --git a/src/core/agent_map.c b/src/core/agent_map.c
index 1fbcee44e830b07a9f6edd5e996271557419d20c..50810432082923e28e3c6f02864159eeae83ac83 100644
--- a/src/core/agent_map.c
+++ b/src/core/agent_map.c
@@ -3050,8 +3050,97 @@ int handle_channel_scan_request(void *agent, struct cmdu_cstruct *cmdu)
 	int opclass_index;
 	int channel_index;
 
-	struct cmdu_cstruct *cmdu_data;
-	int ret, ri;
+	struct cmdu_cstruct *cmdu_copy = NULL;
+	uint8_t *ss = NULL; // binary cmdu->tlvs
+	char *tlv_str = NULL; // string cmdu->tlvs
+	uint8_t *tlvs = NULL; // binary resulting tlvs
+	char *endtlvstr = NULL; // end_of_mes tlv string
+	char *restlvstr = NULL; // string resulting tlvs
+	uint16_t len, leng;
+
+	// Get the string value of cmdu->tlvs
+	if (cmdu->num_tlvs > 0) {
+		for (int it = 0; it < cmdu->num_tlvs; it++) {
+			len = 0;
+			ss = map_put_tlv_cstruct(cmdu->tlvs[it], &len);
+			if (ss) {
+				tlv_str = (char *)calloc((2 * len) + 1,
+						sizeof(char));
+				if (!tlv_str) {
+					dbg("|%s:%d| out of memory!\n", __func__, __LINE__);
+					free(ss);
+					return 0;
+				}
+				btostr(ss, len, tlv_str);
+			}
+		}
+	}
+
+	// End of message tlv
+	endtlvstr = calloc(7, 1);
+	if (!endtlvstr) {
+		dbg("|%s:%d| out of memory!\n", __func__, __LINE__);
+		free(tlv_str);
+		free(ss);
+		return 0;
+	}
+	endtlvstr = "000000";
+
+	// Append the cmdu->tlvs string with end of message tlv
+	// Get resulting tlvs string
+	const size_t len1 = strlen(tlv_str);
+	const size_t len2 = strlen(endtlvstr);
+	restlvstr = malloc(len1 + len2 + 1);
+	if (!restlvstr) {
+		dbg("|%s:%d| out of memory!\n", __func__, __LINE__);
+		free(tlv_str);
+		free(ss);
+		free(endtlvstr);
+		return 0;
+	}
+	memcpy(restlvstr, tlv_str, len1);
+	memcpy(restlvstr + len1, endtlvstr, len2 + 1);
+
+	// Resulting tlvs string to binary value
+	leng = len1 + len2;
+	leng = (leng - 1) / 2;
+	tlvs = calloc(leng, sizeof(uint8_t));
+	if (!tlvs) {
+		dbg("|%s:%d| out of memory!\n", __func__, __LINE__);
+		free(tlv_str);
+		free(ss);
+		free(endtlvstr);
+		free(restlvstr);
+		return 0;
+	}
+	strtob(restlvstr, leng, tlvs);
+
+	// Deep copy of cmdu
+	cmdu_copy = map_build_cmdu(cmdu->message_type,
+			cmdu->message_id, cmdu->intf_name, cmdu->origin, tlvs);
+	if (cmdu_copy) {
+		fprintf(stderr, "agent: %s: map_build_cmdu() successful!\n", __func__);
+	} else {
+		fprintf(stderr, "agent: %s: map_build_cmdu() failed!\n", __func__);
+		free(tlv_str);
+		free(ss);
+		free(endtlvstr);
+		free(restlvstr);
+		free(tlvs);
+		return 0;
+	}
+
+	// Saving the cmdu with the agent
+	a->req_channel_scan_cmdu = cmdu_copy;
+	cmdu_copy = NULL;
+	fprintf(stderr, "DONE ADDING CMDU TO AGENT\n");
+	dbg("\n%s L-%d | cmdu mid: %d\n", __func__,
+			__LINE__, a->req_channel_scan_cmdu->message_id);
+	dbg("%s L-%d | cmdu typs: %s\n", __func__,
+			__LINE__, map_stringify_cmdu_type(a->req_channel_scan_cmdu->message_type));
+
+	// struct cmdu_cstruct *cmdu_data;
+	int ret = 0, ri = 0;
 	// The received TLV
 	uint8_t *tmp = NULL;
 
@@ -3082,93 +3171,117 @@ int handle_channel_scan_request(void *agent, struct cmdu_cstruct *cmdu)
 		ubus_call_object(a, r_wobj, "scan", NULL, &a->radios[ri]);
 		trace("Scaning radio %s neighbors...\n", wifi_get_radio_by_mac(a, query->radio_data[i].radio_id));
 	}
-	sleep(5);
+	return 1;
+}
+
+bool all_channel_scanned(struct agent *a, struct tlv_ch_scan_req *query)
+{
+	int ri, i;
 	for (i = 0; i < query->nbr_radios; i++) {
-		snprintf(r_objname, 31, r_fmt, wifi_get_radio_by_mac(a, query->radio_data[i].radio_id)); //a->radios[ri].name
-		r_wobj = ubus_get_object(a->ubus_ctx, r_objname);
-		if (r_wobj == WIFI_OBJECT_INVALID)
-			continue;
 		ri = wifi_get_radio_index_by_mac(a, query->radio_data[i].radio_id);
-		trace("...done scanning radio %s neighbors.\n", wifi_get_radio_by_mac(a, query->radio_data[i].radio_id));
-		// ubus call wifi.radio.wl0 scanresults
-		ubus_call_object(a, r_wobj, "scanresults", parse_scanresults, &a->radios[ri]);
+		if (!a->radios[ri].scanned)
+			return 0;
 	}
+	return 1;
+}
 
-	// Allocate the cmdu
-	cmdu_data = (struct cmdu_cstruct *)calloc(1, sizeof(struct cmdu_cstruct));
-	if (!cmdu_data) {
-		dbg("Out of memory!\n");
-		return -1;
-	}
-	// Define the cmdu
-	cmdu_data->message_type = CMDU_CHANNEL_SCAN_REPORT;
-	cmdu_data->message_id = cmdu->message_id;
-	strcpy(cmdu_data->intf_name, cmdu->intf_name);
-	memcpy(cmdu_data->origin, cmdu->origin, 6);
-	cmdu_data->num_tlvs = 1; // timestamp tlv
-	for (m = 0; m < query->nbr_radios; m++) { // for each radio
-		if (query->radio_data[m].op_class_data->nbr_ch == 0) { // all_ch_scan
-			radio_index = wifi_get_radio_index_by_mac(a, query->radio_data[m].radio_id);
-			for (i = 0; i < radio[radio_index].scanlist->num_opclass_scanned; i++) {
-				if (radio[radio_index].scanlist->opclass_scanlist[i].bandwidth == 20) {
-					for (j = 0; j < radio[radio_index].scanlist->opclass_scanlist[i].num_channels_scanned; j++)
-						cmdu_data->num_tlvs++;
-				}
-			}
-		} else // specified channels
-			cmdu_data->num_tlvs += query->radio_data[m].op_class_data->nbr_ch; // ch scan res tlvs
-	}
-	trace("Number of tlvs: %d\n", cmdu_data->num_tlvs);
-	// Allocate the TLVs
-	cmdu_data->tlvs = (uint8_t **)calloc(cmdu_data->num_tlvs, sizeof(uint8_t *));
-	if (!cmdu_data->tlvs) {
-		map_free_cmdu(cmdu_data);
+int handle_wifi_radio_scan_finished(void *agent)
+{
+	trace("%s ---> scan_finished\n", __func__);
+	struct agent *a = (struct agent *) agent;
+	struct wifi_radio_element *radio = a->radios;
+	uint16_t tlv_index = 0;
+	uint32_t i, j, k, m;
+	int ret = 0, ri = 0;
+	int radio_index, opclass_index, channel_index;
+	// The received (request) cmdu
+	struct cmdu_cstruct *cmdu = a->req_channel_scan_cmdu;
+	// The response cmdu
+	struct cmdu_cstruct *cmdu_data = NULL;
+	// The received TLV
+	uint8_t *tmp = NULL;
+
+	tmp = cmdu->tlvs[0];
+	if (*tmp != MAP_TLV_CHANNEL_SCAN_REQ) {
+		dbg("Wrong received TLV type!\n");
 		return -1;
 	}
-	// Define the TLVs
-	/* Timestamp */
-	struct tlv_timestamp *p = (struct tlv_timestamp *)calloc(1, sizeof(struct tlv_timestamp));
+	struct tlv_ch_scan_req *query = (struct tlv_ch_scan_req *)tmp;
 
-	if (p) {
-		p->tlv_type = MAP_TLV_TIMESTAMP;
-		get_timestamp(NULL, &p->time);
-		p->time_len = strlen(p->time);
-		cmdu_data->tlvs[tlv_index++] = (uint8_t *)p;
-		trace("|%s:%d| Added %s\n", __func__, __LINE__, map_stringify_tlv_type(*cmdu_data->tlvs[tlv_index-1]));
-	}
-
-	/* Channel scan result */
-	// Multiple radio
-	for (m = 0; m < query->nbr_radios; m++) {
-		dbg("\tRadio_id in %d iteration: " MACFMT "\n", m, MAC2STR(query->radio_data[m].radio_id));
-		radio_index = wifi_get_radio_index_by_mac(a, query->radio_data[m].radio_id);
-		// All channels scan request
-		if (query->radio_data[m].op_class_data->nbr_ch == 0) {
-			for (i = 0; i < radio[radio_index].scanlist->num_opclass_scanned; i++) {
-				if (radio[radio_index].scanlist->opclass_scanlist[i].bandwidth == 20) {
-					for (j = 0; j < radio[radio_index].scanlist->opclass_scanlist[i].num_channels_scanned; j++) {
-						opclass_index = i;
-						channel_index = j;
-						struct tlv_ch_scan_res *p1 = (struct tlv_ch_scan_res *)calloc(1, sizeof(struct tlv_ch_scan_res));
-
-						if (p1) {
-							p1->tlv_type = MAP_TLV_CHANNEL_SCAN_RES;
-							scan_results(a, p1, radio_index, opclass_index, channel_index);
-							cmdu_data->tlvs[tlv_index++] = (uint8_t *)p1;
-							trace("|%s:%d| Added %s for channel %d\n", __func__, __LINE__, map_stringify_tlv_type(*cmdu_data->tlvs[tlv_index-1]),
-									radio[radio_index].scanlist->opclass_scanlist[i].channel_scanlist[j].channel);
-						}
+	// Response only when all channels are scanned
+	if (all_channel_scanned(a, query)) {
+		dbg("All radios have been scanned!\n");
+
+		// Parse channel scanresults
+		char r_objname[32] = {0};
+		const char *r_fmt = "wifi.radio.%s";
+		char *radio_name;
+		wifi_object_t r_wobj = WIFI_OBJECT_INVALID;
+
+		for (i = 0; i < query->nbr_radios; i++) {
+			snprintf(r_objname, 31, r_fmt, wifi_get_radio_by_mac(a, query->radio_data[i].radio_id)); //a->radios[ri].name
+			r_wobj = ubus_get_object(a->ubus_ctx, r_objname);
+			if (r_wobj == WIFI_OBJECT_INVALID)
+				continue;
+			ri = wifi_get_radio_index_by_mac(a, query->radio_data[i].radio_id);
+			trace("...done scanning radio %s neighbors.\n", wifi_get_radio_by_mac(a, query->radio_data[i].radio_id));
+			// ubus call wifi.radio.wl0 scanresults
+			ubus_call_object(a, r_wobj, "scanresults", parse_scanresults, &a->radios[ri]);
+		}
+
+		// Allocate the cmdu
+		cmdu_data = (struct cmdu_cstruct *)calloc(1, sizeof(struct cmdu_cstruct));
+		if (!cmdu_data) {
+			dbg("Out of memory!\n");
+			return -1;
+		}
+		// Define the cmdu
+		cmdu_data->message_type = CMDU_CHANNEL_SCAN_REPORT;
+		cmdu_data->message_id = cmdu->message_id;
+		strcpy(cmdu_data->intf_name, cmdu->intf_name);
+		memcpy(cmdu_data->origin, cmdu->origin, 6);
+		cmdu_data->num_tlvs = 1; // timestamp tlv
+		for (m = 0; m < query->nbr_radios; m++) { // for each radio
+			if (query->radio_data[m].op_class_data->nbr_ch == 0) { // all_ch_scan
+				radio_index = wifi_get_radio_index_by_mac(a, query->radio_data[m].radio_id);
+				for (i = 0; i < radio[radio_index].scanlist->num_opclass_scanned; i++) {
+					if (radio[radio_index].scanlist->opclass_scanlist[i].bandwidth == 20) {
+						for (j = 0; j < radio[radio_index].scanlist->opclass_scanlist[i].num_channels_scanned; j++)
+							cmdu_data->num_tlvs++;
 					}
 				}
-			}
-		} else {
-			for (k = 0; k < query->radio_data[m].op_class_data->nbr_ch; k++) {
-				uint8_t query_channel = query->radio_data[m].op_class_data->ch[k];
+			} else // specified channels
+				cmdu_data->num_tlvs += query->radio_data[m].op_class_data->nbr_ch; // ch scan res tlvs
+		}
+		trace("Number of tlvs: %d\n", cmdu_data->num_tlvs);
+		// Allocate the TLVs
+		cmdu_data->tlvs = (uint8_t **)calloc(cmdu_data->num_tlvs, sizeof(uint8_t *));
+		if (!cmdu_data->tlvs) {
+			map_free_cmdu(cmdu_data);
+			return -1;
+		}
+		// Define the TLVs
+		/* Timestamp */
+		struct tlv_timestamp *p = (struct tlv_timestamp *)calloc(1, sizeof(struct tlv_timestamp));
+
+		if (p) {
+			p->tlv_type = MAP_TLV_TIMESTAMP;
+			get_timestamp(NULL, &p->time);
+			p->time_len = strlen(p->time);
+			cmdu_data->tlvs[tlv_index++] = (uint8_t *)p;
+			trace("|%s:%d| Added %s\n", __func__, __LINE__, map_stringify_tlv_type(*cmdu_data->tlvs[tlv_index-1]));
+		}
 
+		/* Channel scan result */
+		// Multiple radio
+		for (m = 0; m < query->nbr_radios; m++) {
+			dbg("\tRadio_id in %d iteration: " MACFMT "\n", m, MAC2STR(query->radio_data[m].radio_id));
+			radio_index = wifi_get_radio_index_by_mac(a, query->radio_data[m].radio_id);
+			// All channels scan request
+			if (query->radio_data[m].op_class_data->nbr_ch == 0) {
 				for (i = 0; i < radio[radio_index].scanlist->num_opclass_scanned; i++) {
-					dbg("Numbre of scaned channels for the radio %d\n", radio[radio_index].scanlist->num_opclass_scanned);
-					for (j = 0; j < radio[radio_index].scanlist->opclass_scanlist[i].num_channels_scanned; j++) {
-						if (radio[radio_index].scanlist->opclass_scanlist[i].channel_scanlist[j].channel == query_channel) {
+					if (radio[radio_index].scanlist->opclass_scanlist[i].bandwidth == 20) {
+						for (j = 0; j < radio[radio_index].scanlist->opclass_scanlist[i].num_channels_scanned; j++) {
 							opclass_index = i;
 							channel_index = j;
 							struct tlv_ch_scan_res *p1 = (struct tlv_ch_scan_res *)calloc(1, sizeof(struct tlv_ch_scan_res));
@@ -3178,27 +3291,46 @@ int handle_channel_scan_request(void *agent, struct cmdu_cstruct *cmdu)
 								scan_results(a, p1, radio_index, opclass_index, channel_index);
 								cmdu_data->tlvs[tlv_index++] = (uint8_t *)p1;
 								trace("|%s:%d| Added %s for channel %d\n", __func__, __LINE__, map_stringify_tlv_type(*cmdu_data->tlvs[tlv_index-1]),
-										query_channel);
-								goto found;
+										radio[radio_index].scanlist->opclass_scanlist[i].channel_scanlist[j].channel);
 							}
 						}
 					}
 				}
+			} else {
+				for (k = 0; k < query->radio_data[m].op_class_data->nbr_ch; k++) {
+					uint8_t query_channel = query->radio_data[m].op_class_data->ch[k];
+
+					for (i = 0; i < radio[radio_index].scanlist->num_opclass_scanned; i++) {
+						for (j = 0; j < radio[radio_index].scanlist->opclass_scanlist[i].num_channels_scanned; j++) {
+							if (radio[radio_index].scanlist->opclass_scanlist[i].channel_scanlist[j].channel == query_channel) {
+								opclass_index = i;
+								channel_index = j;
+								struct tlv_ch_scan_res *p1 = (struct tlv_ch_scan_res *)calloc(1, sizeof(struct tlv_ch_scan_res));
+
+								if (p1) {
+									p1->tlv_type = MAP_TLV_CHANNEL_SCAN_RES;
+									scan_results(a, p1, radio_index, opclass_index, channel_index);
+									cmdu_data->tlvs[tlv_index++] = (uint8_t *)p1;
+									trace("|%s:%d| Added %s for channel %d\n", __func__, __LINE__, map_stringify_tlv_type(*cmdu_data->tlvs[tlv_index-1]),
+											query_channel);
+									goto found;
+								}
+							}
+						}
+					}
 found:
-				continue;
+					continue;
+				}
 			}
 		}
+		// TODO: memory leak from tlvs
+		// Send cmdu
+		ret = agent_send_cmdu(a, cmdu_data);
+		map_free_cmdu(cmdu_data);
+		map_free_cmdu(a->req_channel_scan_cmdu);
+		return ret;
 	}
-	// TODO: memory leak from tlvs
-	// Send cmdu
-	ret = agent_send_cmdu(a, cmdu_data);
-	map_free_cmdu(cmdu_data);
-	return ret;
-}
-
-int handle_wifi_radio_scan_finished(void *agent) //, struct cmdu_cstruct *cmdu) // LEJLA
-{
-	trace("%s ---> scan_finished\n", __func__);
+	dbg("Not all radios have been scanned.\n");
 	return 0;
 }