diff --git a/src/core/agent.c b/src/core/agent.c
index 6b84b84ca5ecf746b13a9a5fb2be7e760175526d..32e63dae0ad7d8029afaafa7b1c4d3436e5a2361 100644
--- a/src/core/agent.c
+++ b/src/core/agent.c
@@ -150,7 +150,7 @@ static void wifiagent_log_stainfo(struct agent *a, struct sta *s)
 			s->tx_pkts, s->rx_pkts,
 			s->tx_fail_pkts, s->rx_fail_pkts);
 
-	trace("stainfo: %s\n", ev);
+	//trace("stainfo: %s\n", ev);
 	wifiagent_notify_event(a, "wifi.sta", ev);
 }
 
@@ -569,11 +569,10 @@ static int update_sta_entry(struct netif_fh *vif, struct sta *e)
 			s->tx_fail_pkts = e->tx_fail_pkts;
 			s->rx_fail_pkts = e->rx_fail_pkts;
 
-			loud("STA: " MACFMT " (rssi = %d)   " \
+		/*loud("STA: " MACFMT " (rssi = %d)   " \
 				"Tx-bytes/sec = %u    Rx-bytes/sec = %u\n",
 				MAC2STR(s->macaddr), s->rssi[0],
-				s->tx_thput, s->rx_thput);
-
+				s->tx_thput, s->rx_thput);*/
 			wifiagent_log_stainfo(vif->agent, s);
 			return 0;
 		}
@@ -1121,8 +1120,8 @@ static void wifi_sta_periodic_run(struct uloop_timeout *t)
 	if (!vif->cfg->enabled)
 		return;
 
-	trace("%s: STA = " MACFMT " ref = %d\n", __func__,
-					MAC2STR(s->macaddr), s->ref);
+	//trace("%s: STA = " MACFMT " ref = %d\n", __func__,
+	//					MAC2STR(s->macaddr), s->ref);
 
 	if (s->legacy_steered && s->ref == 2)
 		goto rearm_periodic;
@@ -1157,6 +1156,37 @@ rearm_periodic:
 	uloop_timeout_set(&s->sta_timer, STA_PERIODIC_RUN_INTERVAL);
 }
 
+static int wifi_send_sta_report(struct agent *a, const char *vif,
+		uint8_t *macaddr, uint32_t status, uint8_t *bssid)
+{
+	uint8_t src_bssid[6] = { 0 };
+	char ifname[IFNAMESIZE] = {0};
+	uint8_t origin[6] = { 0 };
+	uint8_t ret = 0;
+	struct netif_fh *ifptr;
+	bool ifready = false;
+
+	list_for_each_entry(ifptr, &a->fhlist, list) {
+		if (!strcmp(ifptr->name, vif)) {
+			ifready = true;
+			memcpy(src_bssid, ifptr->bssid, 6);
+			break;
+		}
+	}
+
+	if (!ifready)
+		return -1;
+
+	//TODO use the cntl ifname and origin address
+	strcpy(ifname, "lo");
+
+	/* Here we get need to send the steering report */
+	ret = send_steer_btm_report(a, origin, ifname,
+		bssid, src_bssid, macaddr, status);
+
+	return ret;
+}
+
 static int wifi_add_sta(struct agent *a, const char *vif,
 		unsigned char *macaddr)
 {
@@ -1452,6 +1482,8 @@ static void wifi_sta_event_handler(void *c, struct blob_attr *msg)
 		if (!hwaddr_aton(bssid_str, bssid))
 			return;
 
+		wifi_send_sta_report(a, ifname, mac, status, bssid);
+
 		/* TODO: which status toggle corresponds to what? */
 		if (status) {
 			/* TODO:
@@ -2815,6 +2847,7 @@ static void parse_ap(struct ubus_request *req, int type,
 		return;
 
 	strncpy(ifname, blobmsg_data(tb[0]), 15);
+	strncpy(fh->name, blobmsg_data(tb[0]), 15);
 
 	strncpy(bssid, blobmsg_data(tb[1]), 17);
 	hwaddr_aton(bssid, fh->bssid);
@@ -2983,6 +3016,24 @@ static void agent_periodic_run(struct uloop_timeout *t)
 	}
 }
 
+/* send the steering compled message this function also resets the value of
+ * steering opportunity
+ */
+static void agent_steering_opp_timeout(struct uloop_timeout *t)
+{
+	trace("agent: %s: --->\n", __func__);
+	struct agent *a = container_of(t, struct agent, sta_steer_req_timer);
+	uint8_t src_bssid[6] = { 0 };
+	char ifname[IFNAMESIZE] = { 0 };
+	uint8_t origin[6] = { 0 };
+
+	//TODO here we need to fill the controller
+	//src and interface to which the message needs to be sent
+
+	strcpy(ifname, "lo");
+	send_sta_steer_complete((void *)a, origin, ifname);
+}
+
 static struct msg *agent_msg_enqueue(struct agent *a, int id,
 						char *data, int len)
 {
@@ -3121,6 +3172,11 @@ int start_agent(void)
 		run_agent(w);
 	}
 
+	/*Here we need to set the callback for the steering opportunity timer */
+	w->is_sta_steer_start = 0;
+	w->sta_steerlist_count = 0;
+	w->sta_steer_req_timer.cb = agent_steering_opp_timeout;
+
 	uloop_run();
 
 /* out_and_exit: */
diff --git a/src/core/agent.h b/src/core/agent.h
index 1216e6521685bc7cfaf349494af41dbc40961c1d..8c10a5ac4f5e3dafa6e0b494fa7c80f15c22a22e 100644
--- a/src/core/agent.h
+++ b/src/core/agent.h
@@ -16,10 +16,10 @@
 // TODO: TODO: fixme: remove this include
 //#include <ieee1905/1905_tlvs.h>
 
-
+#define MAX_STA 20
 typedef char timestamp_t[32];
 
-typedef struct ip_address {
+typedef struct ipaddress {
 	uint8_t ver;
 	uint8_t addr[16];
 } ipaddr_t;
@@ -380,6 +380,11 @@ struct wifi_netdev {
 	} iface[WIFI_IFACE_MAX_NUM];
 };
 
+struct wifi_sta_steer_list {
+	uint8_t sta_mac[6];
+	uint8_t complete;
+};
+
 /** struct agent - wifi agent */
 struct agent {
 	int debug;
@@ -404,6 +409,12 @@ struct agent {
 
 	/* plugins */
 	struct list_head pluginlist;
+
+	/* steering opportunity */
+	bool is_sta_steer_start; /* To know whether STA steering is on going */
+	struct uloop_timeout sta_steer_req_timer; /** steer opportunity timer */
+	uint32_t sta_steerlist_count;
+	struct wifi_sta_steer_list sta_steer_list[MAX_STA];
 };
 
 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 c3630d219dd541da79ef516bccae542ff44f03d0..f409ef2eb0c4b83bbb3eb6274548a01cce28c612 100644
--- a/src/core/agent_map.c
+++ b/src/core/agent_map.c
@@ -58,11 +58,17 @@
 #define UBUS_TIMEOUT            1000
 
 #define MAX_RADIO 20
+#define MAX_STA 30
 struct channel_response {
 	uint8_t radio_id[6];
 	uint8_t response;
 };
 
+struct sta_error_response {
+	uint8_t sta_mac[6];
+	uint8_t response;
+};
+
 #define for_each_tlv(e, _buf, _len)					  \
 for ((e) = (struct tlv *)(_buf);					  \
 	(e)->len && (_buf) + (_len) - (uint8_t *)(e) - 3 - (e)->len >= 0; \
@@ -270,6 +276,94 @@ int send_oper_channel_report(void *agent, struct cmdu_cstruct *rec_cmdu)
 	return ret;
 }
 
+int send_steer_btm_report(void *agent, uint8_t *origin, const char *intf_name,
+		uint8_t *target_bssid, uint8_t *src_bssid,
+		uint8_t *sta, uint8_t status_code)
+{
+
+	trace("agent: %s: --->\n", __func__);
+	struct agent *a = (struct agent *) agent;
+	uint16_t tlv_index = 0;
+	uint32_t j;
+	struct cmdu_cstruct *cmdu_data;
+	int ret = 0, all_complete = 1;
+
+	cmdu_data = (struct cmdu_cstruct *)calloc(1,
+			sizeof(struct cmdu_cstruct));
+
+	if (!cmdu_data) {
+		fprintf(stderr, "Out of memory!\n");
+		return -1;
+	}
+
+	cmdu_data->message_type = CMDU_CLIENT_STEERING_BTM_REPORT;
+	memcpy(cmdu_data->origin, origin, 6);
+	//cmdu_data->message_id = 15;
+	strcpy(cmdu_data->intf_name, intf_name);
+
+	cmdu_data->num_tlvs = 1; /* (Steering BTM report) */
+	cmdu_data->tlvs = (uint8_t **)calloc(cmdu_data->num_tlvs,
+			sizeof(uint8_t *));
+
+	if (!cmdu_data->tlvs) {
+		map_free_cmdu(cmdu_data);
+		return -1;
+	}
+
+	/* Clent Steering BTM Report TLV 17.2.30 */
+	struct tlv_steer_btm_report *p =
+	p = agent_gen_steer_btm_report(a, target_bssid,
+			src_bssid, sta, status_code);
+	if (!p) {
+		map_free_cmdu(cmdu_data);
+		return -1;
+	}
+
+	cmdu_data->tlvs[tlv_index++] = (uint8_t *)p;
+
+	ret = agent_send_cmdu(a, cmdu_data);
+	map_free_cmdu(cmdu_data);
+
+	trace("is_steer is %d steer count %d\n",
+			a->is_sta_steer_start, a->sta_steerlist_count);
+
+	/**
+	 * Check that the report is sent for a steering opportunity.
+	 * Here we store the status in the sta list and check
+	 * if the steering completed message can be sent
+	 */
+	if (a->is_sta_steer_start) {
+		int i;
+
+		/* iterate list of clients attempted to be steered */
+		for (i = 0; i < a->sta_steerlist_count; i++) {
+
+			/* mark all steered clients as completed */
+			ret = memcmp(sta, a->sta_steer_list[i].sta_mac, 6);
+			if (ret == 0)
+				a->sta_steer_list[i].complete = 1;
+		}
+
+		/**
+		 * Now we need to check if the steering completed
+		 * message can be sent
+		 */
+		for (i = 0; i < a->sta_steerlist_count; i++) {
+			if (a->sta_steer_list[i].complete != 1) {
+				all_complete = 0;
+				break;
+			}
+		}
+
+		if (all_complete) {
+			/* Here we need to send the steering completed CMDU */
+			send_sta_steer_complete(agent, origin, intf_name);
+		}
+	}
+
+	return ret;
+}
+
 int send_sta_caps_report(void *agent, struct cmdu_cstruct *cmdu)
 {
 	return 0;
@@ -296,9 +390,44 @@ int send_beacon_metrics_response(void *agent, struct cmdu_cstruct *cmdu)
 	return 0;
 }
 
-int send_sta_steer_complete(void *agent, struct cmdu_cstruct *cmdu)
+int send_sta_steer_complete(void *agent, uint8_t *origin, const char *intf_name)
 {
-	return 0;
+	trace("agent: %s: --->\n", __func__);
+	struct agent *a = (struct agent *) agent;
+	uint16_t tlv_index = 0;
+	uint32_t j;
+	struct cmdu_cstruct *cmdu_data;
+	int ret = 0, res = 0, i = 0;
+
+	cmdu_data = (struct cmdu_cstruct *)calloc(1,
+			sizeof(struct cmdu_cstruct));
+	if (!cmdu_data) {
+		fprintf(stderr, "Out of memory!\n");
+		return -1;
+	}
+
+	cmdu_data->message_type = CMDU_STEERING_COMPLETED;
+	memcpy(cmdu_data->origin, origin, 6);
+	//cmdu_data->message_id = 19;
+	strcpy(cmdu_data->intf_name, intf_name);
+
+	cmdu_data->num_tlvs = 0; /* (No TLVs) */
+	if (a->is_sta_steer_start) {
+		/**
+		 * Here we are sending the steering completed message
+		 * so we need to reset all the values of the
+		 * steering opportunity
+		 */
+		a->is_sta_steer_start = 0;
+		a->sta_steerlist_count = 0;
+		memset(a->sta_steer_list, 0, sizeof(a->sta_steer_list));
+		/* stop the timer if it is running */
+		uloop_timeout_cancel(&a->sta_steer_req_timer);
+	}
+
+	agent_send_cmdu(a, cmdu_data);
+	map_free_cmdu(cmdu_data);
+	return ret;
 }
 
 int send_backhaul_sta_steer_response(void *agent, struct cmdu_cstruct *cmdu)
@@ -356,7 +485,8 @@ static const map_cmdu_sendfunc_t agent_maptxftable[] = {
 	[0x0e] = send_sta_link_metrics_response,
 	[0x10] = send_unassoc_sta_link_metrics_response,
 	[0x12] = send_beacon_metrics_response,
-	[0x17] = send_sta_steer_complete,
+	//[0x15] = send_steer_btm_report,
+	//[0x17] = send_sta_steer_complete,
 	[0x1a] = send_backhaul_sta_steer_response,
 	[0x1c] = send_channel_scan_report,
 	[0x22] = send_sta_disassoc_stats,
@@ -1300,15 +1430,489 @@ int handle_combined_infra_metrics(void *agent, struct cmdu_cstruct *cmdu)
 int handle_sta_steer_request(void *agent, struct cmdu_cstruct *cmdu)
 {
 	trace("%s: --->\n", __func__);
+	struct agent *a = (struct agent *) agent;
+	int ret = 0;
+	struct channel_response channel_resp[MAX_RADIO];
+	uint32_t channel_resp_nr = 0, match = 0, found = 0;
+	int i, j, k, l, m;
+	uint8_t *tlv = NULL;
+	struct wifi_radio_element *radio;
+	uint32_t pref_tlv_present = 0;
+
+	/* Here we first parse the steer request */
+	if (cmdu->num_tlvs != 0) {
+		for (i = 0; i < cmdu->num_tlvs; i++) {
+			tlv = (uint8_t *) cmdu->tlvs[i];
+			switch (*tlv) {
+			case MAP_TLV_STEERING_REQUEST:
+				{
+					struct tlv_steer_Req  *p =
+						(struct tlv_steer_Req *)tlv;
+
+					ret = agent_process_steer_request_tlv(agent,
+							p, cmdu);
+				}
+//#ifdef profile2
+			case MAP_TLV_PROFILE2_STEERING_REQ:
+				{
+					//TODO here we need to call the request transmission for the
+					//STAs are Agile Multiband capable
+					struct tlv_profile2_steer_req  *p =
+						(struct tlv_profile2_steer_req *)tlv;
+				}
+//#endif
+			default:
+				break;
+			}
+		}
+	}
+	return ret;
+}
+
+int validate_sta_bssid_assoc(struct netif_fh *fh, struct tlv_steer_Req *p,
+	struct sta_error_response  *sta_resp, uint32_t *cnt,
+	struct agent *a)
+{
+	int l = 0;
+	struct sta *s;
+	uint32_t count = 0;
+	uint32_t res = 0, found = 0;
+
+	for (l = 0; l < p->sta_list_cnt; l++) {
+		list_for_each_entry(s, &fh->stalist, list) {
+			trace("stalist :" MACFMT "\n",
+				MAC2STR(s->macaddr));
+			res = memcmp(s->macaddr, p->steering_req_macs[l].addr, 6);
+			if (res == 0) {
+				found = 1;
+				/**
+				 * Here as the sta is present check that in this case
+				 * for steering opportunity put that in the array
+				 */
+				if (p->request_mode == 0x00) {
+					memcpy(a->sta_steer_list[a->sta_steerlist_count].sta_mac,
+						p->steering_req_macs[l].addr, 6);
+					a->sta_steerlist_count = a->sta_steerlist_count + 1;
+				}
+				break;
+			}
+		}
+		if (found == 0 || !s) {
+			dbg("Missing STA client!\n");
+			memcpy(sta_resp[count].sta_mac, p->steering_req_macs[l].addr, 6);
+			sta_resp[count].response = 0x02;
+			count++;
+		}
+	}
+	*cnt += count;
 	return 0;
 }
 
-int handle_sta_steer_btm_report(void *agent, struct cmdu_cstruct *cmdu)
+int agent_transition_sta(struct agent *a, struct tlv_steer_Req *p, struct netif_fh *fh,
+	int l, int m)
 {
-	trace("%s: --->\n", __func__);
+	uint8_t wildcard[6];
+	uint8_t wildcard_bssid[6];
+	int result = 0;
+	char wildcard_str[18] = { 0x0 };
+	int ret = 0;
+
+	trace("agent: %s: --->\n", __func__);
+	snprintf(wildcard_str, 18, "FF:FF:FF:FF:FF:FF");
+	hwaddr_aton(wildcard_str, wildcard);
+
+	result = memcmp(p->steering_req_target_bssids[l].bssid, wildcard, 6);
+	if (result == 0) {
+		/**
+		 * code to search bssid as the bssid is a
+		 * wildcard
+		 */
+		trace("[%s:%d] bssid id wildcard\n",
+				__func__, __LINE__);
+		ret = agent_search_bssid_for_sta(a,
+			p->steering_req_macs[l].addr,
+			wildcard_bssid, p->bssid);
+		if (ret == 0)
+			ret = agent_send_request_transition(a,
+				p->steering_req_macs[l].addr,
+				fh, wildcard_bssid, 0);
+	} else {
+		ret = agent_send_request_transition(a,
+			p->steering_req_macs[l].addr,
+			fh, p->steering_req_target_bssids[m].bssid, 0);
+	}
 	return 0;
 }
 
+/* Add the rcpi based check according to section
+ * 11.3
+ */
+bool agent_rcpi_steer(void)
+{
+	/**
+	 * TODO: Implement proper logic to trigger steer
+	 */
+	trace("agent: %s: --->\n", __func__);
+	return false;
+}
+
+
+int agent_process_steer_request_tlv(void *agent, struct tlv_steer_Req *p,
+		struct cmdu_cstruct *cmdu)
+{
+	trace("agent: %s: --->\n", __func__);
+	struct agent *a = (struct agent *) agent;
+	int ret = 0, result = 0;
+	uint32_t  match = 0, found = 0;
+	int i, j, k, l, m;
+	struct netif_fh *fh;
+	struct sta *s;
+	struct sta_error_response  sta_resp[MAX_STA];
+	uint32_t count = 0;
+	char wildcard_str[18] = { 0x0 };
+	uint8_t wildcard[6];
+	uint8_t wildcard_bssid[6];
+	uint32_t res = 0, present = 0;
+
+	snprintf(wildcard_str, 18, "FF:FF:FF:FF:FF:FF");
+	hwaddr_aton(wildcard_str, wildcard);
+
+	trace("request_mode: %d\n",
+		p->request_mode);
+
+	if (p->request_mode == 0x00) {
+		/* Here we start the steer opportunity timer */
+		if (a->is_sta_steer_start == 1) {
+			trace("Error steering opportunity timer already running\n");
+			return 1;
+		}
+
+		/**
+		 * Here we need to check the three conditions that needs to be
+		 * satisfied according to section 11.2
+		 */
+		if (p->steer_opp_window == 0) {
+			trace("Error steering opportunity timer value is zero\n");
+			return 1;
+		}
+
+		/**
+		 * TODO check that the sta mac address is not included
+		 * in the Local Steering Disallowed STA List in the Steering
+		 * Policy TLV
+		 */
+		a->is_sta_steer_start = 1;
+		a->sta_steerlist_count = 0;
+		uloop_timeout_set(&a->sta_steer_req_timer, p->steer_opp_window * 1000);
+
+	} else if (p->request_mode != 0x01) {
+		trace("Invalid request mode");
+		return 1;
+	}
+
+	/* TODO check the rcpi based steering rule section 11.3*/
+	agent_rcpi_steer();
+
+	/**
+	 * The src bssid is with which the STA is associated so
+	 * Here we need to check that the STA is associated with the
+	 * src_bssid according to section 11.1 of the steer mandate
+	 * Here we trace the values
+	 */
+	trace("btm_disassoc_imminent: %d\n",
+		p->btm_disassoc_imminent);
+	trace("btm_abridged: %d\n",
+		p->btm_abridged);
+	trace("reserved: %d\n",
+		p->reserved);
+	trace("steer_opp_window: %d\n",
+		p->steer_opp_window);
+	trace("btm_disassoc_timer: %d\n",
+		p->btm_disassoc_timer);
+	trace("sta_list_cnt: %d\n",
+		p->sta_list_cnt);
+	trace("target_bssid_list_cnt: %d\n",
+		p->target_bssid_list_cnt);
+	trace("src_bssid: " MACFMT "\n",
+		MAC2STR(p->bssid));
+
+	/* Here we validate if the sta is associated with the src bssid */
+	fh = get_netif_by_bssid(a, p->bssid);
+	if (!fh) {
+		trace("[%s:%d] Error BSSID not present", __func__, __LINE__);
+		for (l = 0; l < p->sta_list_cnt; l++) {
+			memcpy(sta_resp[count].sta_mac, p->steering_req_macs[l].addr, 6);
+			sta_resp[count].response = 0x02;
+			count++;
+			goto send_ack;
+		}
+	}
+
+	ret = validate_sta_bssid_assoc(fh, p, sta_resp, &count, a);
+	if (ret == -1)
+		goto send_ack;
+
+	/* Number of STAs and BSSIDs are equal, map STA to BSSID */
+	if (p->sta_list_cnt > 0 && p->sta_list_cnt == p->target_bssid_list_cnt) {
+		for (l = 0; l < p->sta_list_cnt; l++) {
+			trace("sta_addr: " MACFMT "\n",
+				MAC2STR(p->steering_req_macs[l].addr));
+			trace("target bssid: " MACFMT "\n",
+				MAC2STR(p->steering_req_target_bssids[l].bssid));
+			trace("op_class: %d\n",
+				p->steering_req_target_bssids[l].op_class);
+			trace("channel: %d\n",
+				p->steering_req_target_bssids[l].channel);
+			/**
+			 * Here we need to check that the STA is associated with the
+			 * src bssid or not
+			 */
+			present = 0;
+			trace("count of error code sta %d\n", count);
+			for (m = 0; m < count; m++) {
+				trace("steer mac: " MACFMT "\n",
+					MAC2STR(p->steering_req_macs[l].addr));
+				trace("sta error mac: " MACFMT "\n",
+					MAC2STR(sta_resp[m].sta_mac));
+				res = memcmp(p->steering_req_macs[l].addr,
+						sta_resp[m].sta_mac, 6);
+				if (res == 0) {
+					present = 1;
+					break;
+				}
+			}
+			if (present != 1) {
+				/*Here we call for transition of sta*/
+				ret = agent_transition_sta(a, p, fh, l, l);
+			}
+		}
+	}
+	/* Multiple STAs and single BSSID, send all STAs to same BSSID */
+	else if (p->sta_list_cnt > 0 && p->target_bssid_list_cnt == 1) {
+		trace("target bssid: " MACFMT "\n",
+			MAC2STR(p->steering_req_target_bssids[0].bssid));
+		trace("op_class: %d\n",
+			p->steering_req_target_bssids[0].op_class);
+		trace("channel: %d\n",
+			p->steering_req_target_bssids[0].channel);
+
+		for (l = 0; l < p->sta_list_cnt; l++) {
+			/* Here we need to call the ubus method */
+			trace("sta_addr: " MACFMT "\n",
+			MAC2STR(p->steering_req_macs[l].addr));
+			/**
+			 * Here we need to check that the STA is associated with
+			 * the src bssid or not
+			 */
+			present = 0;
+			for (m = 0; m < count; m++) {
+				res =  memcmp(p->steering_req_macs[l].addr,
+						sta_resp[m].sta_mac, 6);
+				if (res == 0) {
+					present = 1;
+					break;
+				}
+			}
+			if (present != 1) {
+				/*Here we call for transition of sta*/
+				ret = agent_transition_sta(a, p, fh, l, 0);
+			}
+		}
+	}
+	/**
+	 * No STA provided, Steering request applies to all associated STAs
+	 * in the BSS, per policy setting.
+	 */
+	else if (p->sta_list_cnt  == 0 && p->target_bssid_list_cnt == 1) {
+		result = memcmp(p->steering_req_target_bssids[0].bssid, wildcard, 6);
+		if (result == 0) {
+			trace("[%s:%d] bssid id wildcard", __func__, __LINE__);
+			ret = agent_search_bssid_for_sta(a,
+					p->steering_req_macs[l].addr, wildcard_bssid, p->bssid);
+			if (ret != 0) {
+				list_for_each_entry(s, &fh->stalist, list) {
+					ret = agent_send_request_transition(
+						agent, s->macaddr,
+						fh, wildcard_bssid, 0);
+				}
+			}
+		} else {
+			list_for_each_entry(s, &fh->stalist, list) {
+				ret = agent_send_request_transition(
+					agent, s->macaddr,
+					fh, p->steering_req_target_bssids[0].bssid, 0);
+			}
+		}
+	}
+	/* No BSSID specified for the STAs */
+	else if (p->sta_list_cnt  > 0 && p->target_bssid_list_cnt == 0) {
+		if (p->request_mode != 0x00) {
+			trace("[%s:%d]Error steer mandate target BSSID not present\n",
+				__func__, __LINE__);
+			return 1;
+		}
+		trace("[%s:%d] target BSSID not present\n", __func__, __LINE__);
+		for (l = 0; l < p->sta_list_cnt; l++) {
+			trace("sta_addr: " MACFMT "\n",
+				MAC2STR(p->steering_req_macs[l].addr));
+			/**
+			 * Here we need to check that the STA is associated with the
+			 * src bssid or not
+			 */
+			present = 0;
+			for (m = 0; m < count; m++) {
+				res =  memcmp(p->steering_req_macs[l].addr, sta_resp[m].sta_mac, 6);
+				if (res == 0) {
+					present = 1;
+					break;
+				}
+			}
+			if (present != 1) {
+				/**
+				 * Here we need to get the bssids that are best
+				 * for the STAs in case of steering opportunity
+				 */
+				ret = agent_search_bssid_for_sta(a,
+						p->steering_req_macs[l].addr,
+						wildcard_bssid, p->bssid);
+				if (ret != 0)
+					ret = agent_send_request_transition(
+						agent, p->steering_req_macs[l].addr,
+						fh, wildcard_bssid, 0);
+			}
+		}
+	}
+	/* No BSSID or STAs */
+	else if (p->sta_list_cnt  == 0 && p->target_bssid_list_cnt == 0) {
+		trace("[%s:%d] Error No STA and target BSSID present\n", __func__, __LINE__);
+		return 1;
+	} else {
+		trace("[%s:%d] Error condition\n", __func__, __LINE__);
+		return 1;
+	}
+
+send_ack:
+	send_1905_acknowledge(agent, p, cmdu, sta_resp, count);
+	return ret;
+}
+
+//TODO search BSSID incase of wildcard or in case need to get the
+//implementation specific policy section 11.4
+int agent_search_bssid_for_sta(struct agent *a, uint8_t *sta, uint8_t *bssid,
+		uint8_t *src_bssid)
+{
+
+	struct netif_fh *p;
+	int ret = 0;
+
+	trace("agent: %s: --->\n", __func__);
+	list_for_each_entry(p, &a->fhlist, list) {
+		trace("bssid = " MACFMT " pbssid = " MACFMT "\n",
+			MAC2STR(bssid), MAC2STR(p->bssid));
+		ret = memcmp(src_bssid, p->bssid, 6);
+		if (ret != 0) {
+			memcpy(bssid, p->bssid, 6);
+			return 0;
+		}
+	}
+	memcpy(bssid, src_bssid, 6);
+	return 0;
+}
+
+int send_1905_acknowledge(void *agent, struct tlv_error_code *p,
+	struct cmdu_cstruct *rec_cmdu,
+	struct sta_error_response *sta_resp, uint32_t sta_count)
+{
+	struct agent *a = (struct agent *) agent;
+	uint16_t tlv_index = 0;
+	uint32_t j;
+	struct cmdu_cstruct *cmdu_data;
+	int ret = 0;
+
+	trace("agent: %s: --->\n", __func__);
+	cmdu_data = (struct cmdu_cstruct *)calloc(1,
+			sizeof(struct cmdu_cstruct));
+
+	if (!cmdu_data) {
+		fprintf(stderr, "Out of memory!\n");
+		return -1;
+	}
+
+	cmdu_data->message_type = CMDU_1905_ACK;
+	memcpy(cmdu_data->origin, rec_cmdu->origin, 6);
+	//cmdu_data->message_id = 11;
+	strcpy(cmdu_data->intf_name, rec_cmdu->intf_name);
+
+	cmdu_data->num_tlvs = sta_count; /* (TLV for error) */
+	cmdu_data->tlvs = (uint8_t **)calloc(cmdu_data->num_tlvs,
+				sizeof(uint8_t *));
+
+	if (!cmdu_data->tlvs) {
+		map_free_cmdu(cmdu_data);
+		return -1;
+	}
+
+	/* Error Code TLV 17.2.36 */
+	for (j = 0; j < sta_count; j++) {
+		struct tlv_error_code *p = NULL;
+		/**
+		 * Here we need to check that the sta error
+		 * response
+		 */
+		p = agent_gen_tlv_error_code(a, rec_cmdu,
+			sta_resp[j].sta_mac, sta_resp[j].response);
+		if (!p)
+			continue;
+		cmdu_data->tlvs[tlv_index++] = (uint8_t *)p;
+	}
+	ret = agent_send_cmdu(a, cmdu_data);
+	map_free_cmdu(cmdu_data);
+	return 0;
+}
+
+int agent_send_request_transition(void *agent, uint8_t *client_sta,
+	struct netif_fh *fh, uint8_t *bssid, uint32_t timeout)
+{
+	struct agent *a = (struct agent *) agent;
+	char client_macstr[18] = { 0 };
+	char bssid_str[18] = { 0 };
+	struct blob_buf bb = { 0 };
+	int ret = 0;
+	uint32_t id;
+	char ap_ifname[30] = { 0 };
+	void *tbl;
+
+	trace("agent: %s: --->\n", __func__);
+	if (!client_sta || !bssid)
+		return -1;
+
+	blob_buf_init(&bb, 0);
+
+	hwaddr_ntoa(client_sta, client_macstr);
+	blobmsg_add_string(&bb, "client", client_macstr);
+
+	hwaddr_ntoa(bssid, bssid_str);
+	tbl = blobmsg_open_array(&bb, "bssid");
+	blobmsg_add_string(&bb, NULL, bssid_str);
+	blobmsg_close_table(&bb, tbl);
+
+	if (timeout) {
+		//fill the timeout
+	}
+
+	ret = ubus_invoke(a->ubus_ctx, fh->wifi, "request_transition", bb.head,
+		NULL, NULL, UBUS_TIMEOUT);
+	if (ret) {
+		trace("[%s:%d] ubus call failed for |wifi.ap. send|",
+			__func__, __LINE__);
+		goto out;
+	}
+
+out:
+	blob_buf_free(&bb);
+	return ret;
+}
+
 int handle_sta_assoc_control_request(void *agent, struct cmdu_cstruct *cmdu)
 {
 	trace("%s: --->\n", __func__);
@@ -1457,7 +2061,7 @@ static const map_cmdu_handler_t agent_mapftable[] = {
 	[0x12] = handle_beacon_metrics_response,
 	[0x13] = handle_combined_infra_metrics,
 	[0x14] = handle_sta_steer_request,
-	[0x15] = handle_sta_steer_btm_report,
+	/*[0x15] = handle_sta_steer_btm_report,*/
 	[0x16] = handle_sta_assoc_control_request,
 	/* [0x17] = handle_sta_steer_complete, */
 	[0x18] = handle_hld_message,
@@ -1563,7 +2167,7 @@ bool is_cmdu_for_us(struct agent *a, uint16_t type)
 
 	// until then, the following should be okay..
 
-	if (type >= CMDU_TYPE_1905_START && type <= CMDU_TYPE_MAP_START) {
+	if (type >= CMDU_TYPE_1905_START && type <= CMDU_TYPE_1905_END) {
 		if (i1905ftable[type])
 			return true;
 	} else if (type >= CMDU_TYPE_MAP_START && type <= CMDU_TYPE_MAP_END) {
diff --git a/src/core/agent_tlv_generator.c b/src/core/agent_tlv_generator.c
index 5f8a77a08ebdf7da1827d2a7601e0f6697c8c0dc..0d83c425beb38e333d2a04666078fc12f298468e 100644
--- a/src/core/agent_tlv_generator.c
+++ b/src/core/agent_tlv_generator.c
@@ -630,3 +630,45 @@ void agent_gen_cac_comp_report(struct agent *a,
 		p->radio_data[j].nbr_pairs = 0; //dummy value TODO
 	}
 }
+
+struct tlv_error_code *agent_gen_tlv_error_code(struct agent *a,
+	struct cmdu_cstruct *cmdu, uint8_t *sta_mac, uint8_t reason_code)
+{
+	struct tlv_error_code *p;
+
+	p = (struct tlv_error_code *)calloc(1,
+		sizeof(struct tlv_error_code));
+
+	if (!p)
+		return NULL;
+
+	p->tlv_type = MAP_TLV_ERROR_CODE;
+	p->reason_code = reason_code;
+	memcpy(p->addr, sta_mac, 6);
+
+	return p;
+}
+
+struct tlv_steer_btm_report *agent_gen_steer_btm_report(struct agent *a,
+		uint8_t *target_bssid, uint8_t *src_bssid,
+		uint8_t *sta, uint8_t status_code)
+{
+	struct tlv_steer_btm_report *p;
+
+	p = (struct tlv_steer_btm_report *)calloc(1,
+		sizeof(struct tlv_steer_btm_report));
+
+	if (!p)
+		return NULL;
+
+	p->tlv_type = MAP_TLV_STEERING_BTM_REPORT;
+	memcpy(p->bssid, src_bssid, 6);
+	p->status_code = status_code;
+
+	if (p->status_code == 0x00)
+		memcpy(p->target_bssid, target_bssid, 6);
+
+	memcpy(p->sta_mac_addr, sta, 6);
+
+	return p;
+}
diff --git a/src/core/agent_tlv_generator.h b/src/core/agent_tlv_generator.h
index d14c63a778f4770ee3669f2d7fe10775d5ccf86a..c5ef25efc3817cdb31da7419826c8726cee73f65 100644
--- a/src/core/agent_tlv_generator.h
+++ b/src/core/agent_tlv_generator.h
@@ -38,4 +38,9 @@ void agent_gen_radio_restrict_channel(struct agent *a,
 		uint32_t radio_index);
 void agent_gen_cac_comp_report(struct agent *a,
 		struct tlv_cac_comp_report *p);
+struct tlv_error_code *agent_gen_tlv_error_code(struct agent *a,
+		struct cmdu_cstruct *cmdu, uint8_t *sta_mac, uint8_t reason_code);
+struct tlv_steer_btm_report *agent_gen_steer_btm_report(struct agent *a,
+		uint8_t *target_bssid, uint8_t *src_bssid,
+		uint8_t *sta, uint8_t status_code);
 #endif