diff --git a/src/agent_map.c b/src/agent_map.c
index 23c97562d5ba82db26cfa1fe51edac834e8b4f9d..882d7760782d67cedb9f5d208ba39b7f584aecb4 100644
--- a/src/agent_map.c
+++ b/src/agent_map.c
@@ -820,22 +820,13 @@ int handle_ap_autoconfig_search(void *agent, struct cmdu_buff *rx_cmdu)
 	struct agent *a = (struct agent *) agent;
 	bool cntlr = false;
 	int i;
-	struct tlv_policy a_policy[] = {
-		[0] = { .type = TLV_TYPE_AL_MAC_ADDRESS_TYPE, .present = TLV_PRESENT_ONE },
-		[1] = { .type = TLV_TYPE_SEARCHED_ROLE, .present = TLV_PRESENT_ONE },
-		[2] = { .type = TLV_TYPE_AUTOCONFIG_FREQ_BAND, .present = TLV_PRESENT_ONE },
-		[3] = { .type = MAP_TLV_SUPPORTED_SERVICE, .present = TLV_PRESENT_ONE },
-		[4] = { .type = MAP_TLV_SEARCHED_SERVICE, .present = TLV_PRESENT_ONE },
-		[5] = { .type = MAP_TLV_MULTIAP_PROFILE, .present = TLV_PRESENT_ONE }
-	};
 	uint8_t aladdr_origin[6] = {0};
 	struct tlv *tv[6][16] = {0};
 
-	cmdu_parse_tlvs(rx_cmdu, tv, a_policy, 6);
-
-	if (!tv[0][0] || !tv[1][0] || !tv[2][0] || !tv[3][0] || !tv[4][0]
-			|| !tv[5][0])
+	if (!validate_ap_autoconfig_search(rx_cmdu, tv)) {
+		dbg("cmdu validation: [AP_AUTOCONFIG_SEARCH] failed\n");
 		return -1;
+	}
 
 	memcpy(aladdr_origin, tv[0][0]->data, 6);
 	if (hwaddr_is_zero(aladdr_origin)) {
diff --git a/src/cmdu_validate.c b/src/cmdu_validate.c
index b58bafe0d589bb7cfb33da785c373914faec0870..9e0bf4aab01106648a3562e0028191cd09f9a08f 100644
--- a/src/cmdu_validate.c
+++ b/src/cmdu_validate.c
@@ -373,3 +373,165 @@ bool validate_ap_autoconfig_wsc(struct cmdu_buff *cmdu, struct tlv *tv[][16])
 
 	return true;
 }
+
+bool validate_ap_autoconfig_search(struct cmdu_buff *cmdu, struct tlv *tv[][16])
+{
+	struct tlv_policy a_policy[] = {
+		[0] = { .type = TLV_TYPE_AL_MAC_ADDRESS_TYPE,
+				.present = TLV_PRESENT_ONE,
+				.minlen = 6, /* macaddr */
+				.maxlen = 6
+		},
+		[1] = { .type = TLV_TYPE_SEARCHED_ROLE,
+				.present = TLV_PRESENT_ONE,
+				.minlen = 1, /* tlv_searched_role */
+				.maxlen = 1
+		},
+		[2] = { .type = TLV_TYPE_AUTOCONFIG_FREQ_BAND,
+				.present = TLV_PRESENT_ONE,
+				.minlen = 1, /* tlv_autoconfig_band */
+				.maxlen = 1
+		},
+		[3] = { .type = MAP_TLV_SUPPORTED_SERVICE,
+				.present = TLV_PRESENT_ONE,
+				.minlen = 1, /* num of services */
+		},
+		[4] = { .type = MAP_TLV_SEARCHED_SERVICE,
+				.present = TLV_PRESENT_ONE,
+				.minlen = 1, /* num of services */
+		},
+		[5] = { .type = MAP_TLV_MULTIAP_PROFILE,
+				.present = TLV_PRESENT_ONE,
+				.minlen = 1, /* tlv_map_profile */
+				.maxlen = 1
+		}
+	};
+	//int num = 0;
+	int ret;
+
+	trace("%s |" MACFMT "|CMDU: ap autoconfig search\n",
+		  __func__, MAC2STR(cmdu->origin));
+
+	ret = cmdu_parse_tlvs(cmdu, tv, a_policy, 6);
+	if (ret) {
+		dbg("%s: parse_tlv failed\n", __func__);
+		return false;
+	}
+
+	if (!tv[0][0] || !tv[1][0] || !tv[2][0] || !tv[5][0]) {
+		dbg("%s: Missing one or more mandatory TLV!\n", __func__);
+		return false;
+	}
+
+	/* Parse 1905.1 AL MAC address type TLV */
+	if (tv[0][0]) {
+		uint8_t *tv_data;
+		uint16_t tlv_len = tlv_length(tv[0][0]);
+
+		/* macaddr (6 bytes) */
+		if (tlv_len != 6)
+			return false;
+
+		tv_data = (uint8_t *) tv[0][0]->data;
+		if (!tv_data)
+			return false;
+	}
+
+	/* Parse SearchedRole TLV */
+	if (tv[1][0]) {
+		struct tlv_searched_role *tlv;
+		uint16_t tlv_len = tlv_length(tv[1][0]);
+
+		/* role (1 byte) */
+		if (tlv_len != sizeof(struct tlv_searched_role))
+			return false;
+
+		tlv = (struct tlv_searched_role *)tv[1][0]->data;
+		if (!tlv)
+			return false;
+	}
+
+	/* Parse AutoconfigFreqBand TLV */
+	if (tv[2][0]) {
+		struct tlv_autoconfig_band *tlv;
+		uint16_t tlv_len = tlv_length(tv[2][0]);
+
+		/* band (1 byte) */
+		if (tlv_len != sizeof(struct tlv_autoconfig_band))
+			return false;
+
+		tlv = (struct tlv_autoconfig_band *)tv[2][0]->data;
+		if (!tlv)
+			return false;
+	}
+
+	/* Parse SupportedService TLV */
+	if (tv[3][0]) {
+		uint8_t *tv_data;
+		uint8_t num_services;
+		int offset = 0;
+		uint16_t tlv_len = tlv_length(tv[3][0]);
+
+		if (tlv_len < 1)
+			return false;
+
+		tv_data = (uint8_t *) tv[3][0]->data;
+		if (!tv_data)
+			return false;
+
+		/* num_services (1 byte) */
+		if (offset + 1 > tlv_len)
+			return false;
+
+		num_services = tv_data[offset];
+
+		offset += 1;
+
+		/* services (num_services bytes) */
+		if (offset + num_services > tlv_len)
+			return false;
+	}
+
+	/* Parse SearchedService TLV */
+	if (tv[4][0]) {
+		uint8_t *tv_data;
+		uint8_t num_services;
+		int offset = 0;
+		uint16_t tlv_len = tlv_length(tv[4][0]);
+
+		if (tlv_len < 1)
+			return false;
+
+		tv_data = (uint8_t *) tv[4][0]->data;
+		if (!tv_data)
+			return false;
+
+		/* num_services (1 byte) */
+		if (offset + 1 > tlv_len)
+			return false;
+
+		num_services = tv_data[offset];
+
+		offset += 1;
+
+		/* services (num_services bytes) */
+		if (offset + num_services > tlv_len)
+			return false;
+	}
+
+	/* Parse MultiAP Profile TLV */
+	if (tv[5][0]) {
+		struct tlv_map_profile *tlv;
+		uint16_t tlv_len = tlv_length(tv[5][0]);
+
+		/* profile (1 byte) */
+		if (tlv_len != sizeof(struct tlv_map_profile))
+			return false;
+
+		tlv = (struct tlv_map_profile *)tv[5][0]->data;
+		if (!tlv)
+			return false;
+	}
+
+	return true;
+}
diff --git a/src/cmdu_validate.h b/src/cmdu_validate.h
index 681eb23cb2c9f60ca10cbe3eb9fa079558a93f40..26a0acc89304a551da51b39ade35e08e770a9577 100644
--- a/src/cmdu_validate.h
+++ b/src/cmdu_validate.h
@@ -5,5 +5,6 @@
 bool validate_channel_scan_request(struct cmdu_buff *cmdu, struct tlv *tv[][16]);
 bool validate_topology_response(struct cmdu_buff *cmdu, struct tlv *tv[][16]);
 bool validate_ap_autoconfig_wsc(struct cmdu_buff *cmdu, struct tlv *tv[][16]);
+bool validate_ap_autoconfig_search(struct cmdu_buff *cmdu, struct tlv *tv[][16]);
 
 #endif	/* CMDU_VALIDATE */