diff --git a/src/core/agent.c b/src/core/agent.c
index 44a1cb2c1261af2f3de2b8351e63492192e32b02..6b84b84ca5ecf746b13a9a5fb2be7e760175526d 100644
--- a/src/core/agent.c
+++ b/src/core/agent.c
@@ -2386,8 +2386,8 @@ static void parse_radio(struct ubus_request *req, int type,
 		struct blob_attr *msg)
 {
 	struct wifi_radio_element *re = (struct wifi_radio_element *)req->priv;
-	struct blob_attr *tb[9];
-	static const struct blobmsg_policy radio_attr[9] = {
+	struct blob_attr *tb[10];
+	static const struct blobmsg_policy radio_attr[10] = {
 		[0] = { .name = "isup", .type = BLOBMSG_TYPE_BOOL },
 		[1] = { .name = "band", .type = BLOBMSG_TYPE_STRING },
 		[2] = { .name = "noise", .type = BLOBMSG_TYPE_INT32 },
@@ -2397,9 +2397,10 @@ static void parse_radio(struct ubus_request *req, int type,
 		[6] = { .name = "opclass", .type = BLOBMSG_TYPE_INT32 },
 		[7] = { .name = "channel", .type = BLOBMSG_TYPE_INT32 },
 		[8] = { .name = "regdomain", .type = BLOBMSG_TYPE_STRING },
+		[9] = { .name = "txpower", .type = BLOBMSG_TYPE_INT32 },
 	};
 
-	blobmsg_parse(radio_attr, 9, tb, blob_data(msg), blob_len(msg));
+	blobmsg_parse(radio_attr, 10, tb, blob_data(msg), blob_len(msg));
 
 	if (tb[0])
 		re->enabled = blobmsg_get_bool(tb[0]);
@@ -2460,15 +2461,17 @@ static void parse_radio(struct ubus_request *req, int type,
 			if (data[2])
 				re->supp_opclass[i].num_supported_channels = blobmsg_check_array(data[2], BLOBMSG_TYPE_INT32);
 
-			re->supp_opclass[i].supp_chanlist = calloc(re->supp_opclass[i].num_supported_channels, sizeof(uint8_t));
+			re->supp_opclass[i].supp_chanlist = calloc(re->supp_opclass[i].num_supported_channels, sizeof(struct supp_channel));
 			if (!re->supp_opclass[i].supp_chanlist) {
 				fprintf(stderr, "|%s:%d| out of memory!\n", __func__, __LINE__);
 				return;
 			}
 
-			blobmsg_for_each_attr(cur1, data[2], rem1)
-				re->supp_opclass[i].supp_chanlist[k++] = blobmsg_get_u32(cur1);
-
+			blobmsg_for_each_attr(cur1, data[2], rem1) {
+				re->supp_opclass[i].supp_chanlist[k].channel = blobmsg_get_u32(cur1);
+				re->supp_opclass[i].supp_chanlist[k].pref = 0xff;
+				k++;
+			}
 			re->supp_opclass[i].num_exclude_channels = 1;
 			if (re->supp_opclass[i].num_exclude_channels > 0) {
 				re->supp_opclass[i].exclude_chanlist =
@@ -2492,6 +2495,9 @@ static void parse_radio(struct ubus_request *req, int type,
 
 	if (tb[8])
 		memcpy(re->country_code, blobmsg_data(tb[8]), 2);
+
+	if (tb[9])
+		re->current_txpower_percent = (uint8_t) blobmsg_get_u32(tb[9]);
 }
 
 static void _enumerate_wifi_objects(struct ubus_request *req, int type,
@@ -3142,8 +3148,10 @@ void agent_free_radios(struct agent *a)
 
 		re = &a->radios[i];
 
-		for (j = 0; j < re->num_supp_opclass; j++)
+		for (j = 0; j < re->num_supp_opclass; j++) {
+			free(re->supp_opclass[j].supp_chanlist);
 			free(re->supp_opclass[j].exclude_chanlist);
+		}
 
 		free(re->supp_opclass);
 
diff --git a/src/core/agent.h b/src/core/agent.h
index 25831d27adaf11027af151dec443fbbb2f194a89..1216e6521685bc7cfaf349494af41dbc40961c1d 100644
--- a/src/core/agent.h
+++ b/src/core/agent.h
@@ -221,13 +221,18 @@ enum {
 	WIFI_IFACE_BK,
 };
 
+struct supp_channel {
+	uint8_t channel;
+	uint8_t pref;
+};
+
 struct wifi_opclass_supported_element {
 	uint8_t id;                     /* class number */
 	int8_t max_txpower;
 	uint32_t num_exclude_channels;
 	uint8_t *exclude_chanlist;      /* list of non-operable channels */
 	uint32_t num_supported_channels;
-	uint8_t *supp_chanlist;         /*list of supporting channels for each class*/
+	struct supp_channel *supp_chanlist;         /*list of supporting channels for each class*/
 };
 
 struct wifi_opclass_current_element {
@@ -340,8 +345,11 @@ struct wifi_radio_element {
 	uint8_t tx_streams;
 	uint8_t current_opclass;
 	uint8_t current_channel;
+	uint8_t current_txpower_percent;
+	uint8_t transmit_power_limit; /* set in the channel selection message */
 	uint8_t max_bss;
 
+
 	uint32_t num_supp_opclass;
 	uint32_t num_curr_opclass;
 	uint32_t num_unassoc_sta;
diff --git a/src/core/agent_map.c b/src/core/agent_map.c
index 6a134c1f015938c3aade44be9bb224a2ee1550ab..c3630d219dd541da79ef516bccae542ff44f03d0 100644
--- a/src/core/agent_map.c
+++ b/src/core/agent_map.c
@@ -57,6 +57,12 @@
 
 #define UBUS_TIMEOUT            1000
 
+#define MAX_RADIO 20
+struct channel_response {
+	uint8_t radio_id[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; \
@@ -219,14 +225,49 @@ int send_channel_pref_report(void *agent, struct cmdu_cstruct *cmdu)
 	return 0;
 }
 
-int send_channel_sel_response(void *agent, struct cmdu_cstruct *cmdu)
+int send_oper_channel_report(void *agent, struct cmdu_cstruct *rec_cmdu)
 {
-	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;
 
-int send_oper_channel_report(void *agent, struct cmdu_cstruct *cmdu)
-{
-	return 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_OPERATING_CHANNEL_REPORT;
+	memcpy(cmdu_data->origin, rec_cmdu->origin, 6);
+	cmdu_data->message_id = 10;
+	strcpy(cmdu_data->intf_name, rec_cmdu->intf_name);
+
+	cmdu_data->num_tlvs = 1 * a->num_radios; /* (Operating Channel 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;
+	}
+
+	/* Operating Channel Report TLV 17.2.17 */
+	for (j = 0; j < a->num_radios; j++) {
+		struct tlv_oper_ch_report *p =
+		p = agent_gen_operate_channel_report(a, rec_cmdu, j);
+		if (!p)
+			continue;
+		cmdu_data->tlvs[tlv_index++] = (uint8_t *)p;
+	}
+
+	ret = agent_send_cmdu(a, cmdu_data);
+	map_free_cmdu(cmdu_data);
+
+	return ret;
 }
 
 int send_sta_caps_report(void *agent, struct cmdu_cstruct *cmdu)
@@ -308,7 +349,7 @@ static const map_cmdu_sendfunc_t agent_maptxftable[] = {
 	[0x00] = send_1905_ack,
 	[0x02] = send_ap_caps_report,
 	[0x05] = send_channel_pref_report,
-	[0x07] = send_channel_sel_response,
+	//[0x07] = send_channel_sel_response,
 	[0x08] = send_oper_channel_report,
 	[0x0a] = send_sta_caps_report,
 	[0x0c] = send_ap_metrics_response,
@@ -780,115 +821,6 @@ int handle_map_policy_config(void *agent, struct cmdu_cstruct *cmdu)
 	return 0;
 }
 
-static void get_radio_channel_preference(struct agent *a,
-					struct tlv_channel_pref *p,
-					uint32_t radio_index)
-{
-	uint32_t j;
-	struct wifi_radio_element *radio = a->radios + radio_index;
-
-	trace("%s -----> parsing radio %s\n", __func__, radio->name);
-
-	memcpy(p->radio_id, radio->macaddr, 6);
-	p->ch_preference_op_class_nr = radio->num_supp_opclass;
-
-	if (p->ch_preference_op_class_nr > 0)
-		p->op_class = calloc(p->ch_preference_op_class_nr,
-				sizeof(*p->op_class));
-	if (!p->op_class) {
-		fprintf(stderr, "|%s:%d| out of memory!\n", __func__, __LINE__);
-		p->ch_preference_op_class_nr = 0;
-		return;
-	}
-
-	for (j = 0; j < p->ch_preference_op_class_nr; j++) {
-		p->op_class[j].op_class = radio->supp_opclass[j].id;
-		p->op_class[j].channel_nr = 0;
-		p->op_class[j].channel_list = NULL;
-		p->op_class[j].preference = 0xff;
-		p->op_class[j].preference_reason = 0x00;
-	}
-}
-
-static void get_radio_restrict_channel(struct agent *a,
-				struct tlv_radio_oper_restrict *p,
-				uint32_t radio_index)
-{
-	uint32_t j, k, l, m;
-	struct wifi_radio_element *radio = a->radios + radio_index;
-
-	trace("%s -----> parsing radio %s\n", __func__, radio->name);
-
-	memcpy(p->radio_id, radio->macaddr, 6);
-	p->op_restricted_op_class_nr = 1;
-
-	if (p->op_restricted_op_class_nr > 0)
-		p->restricted_op_class = calloc(p->op_restricted_op_class_nr,
-			sizeof(*p->restricted_op_class));
-	if (!p->restricted_op_class) {
-		fprintf(stderr, "|%s:%d| out of memory!\n", __func__, __LINE__);
-		p->op_restricted_op_class_nr = 0;
-		return;
-	}
-
-	for (j = 0, m = 0; j < radio->num_supp_opclass; j++) {
-		if (radio->supp_opclass[j].id != radio->current_opclass)
-			continue;
-		p->restricted_op_class[m].op_class = radio->current_opclass;
-		p->restricted_op_class[m].channel_nr = (radio->supp_opclass[j].num_supported_channels) - 1;
-
-		if (p->restricted_op_class[m].channel_nr > 0)
-			p->restricted_op_class[m].restricted_channels = calloc(p->restricted_op_class[j].channel_nr,
-				sizeof(*p->restricted_op_class[m].restricted_channels));
-
-		if (!p->restricted_op_class[m].restricted_channels) {
-			fprintf(stderr, "|%s:%d| out of memory!\n", __func__, __LINE__);
-			p->restricted_op_class[m].channel_nr = 0;
-			return;
-		}
-
-		for (k = 0, l = 0; k <  radio->supp_opclass[j].num_supported_channels; k++) {
-			if (radio->supp_opclass[j].supp_chanlist[k] == radio->current_channel)
-				continue;
-			p->restricted_op_class[m].restricted_channels[l].channel =
-						radio->supp_opclass[j].supp_chanlist[k];
-			p->restricted_op_class[m].restricted_channels[l].min_freq_sep = 0; //TODO dummy value
-			l++;
-		}
-		m++;
-	}
-}
-
-static void get_cac_comp_report(struct agent *a,
-				struct tlv_cac_comp_report *p)
-{
-	uint32_t j;
-	struct wifi_radio_element *radio = NULL;
-
-	trace("%s -----> Inside\n", __func__);
-	p->nbr_radios = a->num_radios;
-
-	if (p->nbr_radios > 0)
-		p->radio_data = calloc(p->nbr_radios,
-		sizeof(*p->radio_data));
-	if (!p->radio_data) {
-		fprintf(stderr, "|%s:%d| out of memory!\n", __func__, __LINE__);
-		p->nbr_radios = 0;
-		return;
-	}
-
-	for (j = 0; j < a->num_radios; j++) {
-		radio = a->radios + j;
-		memcpy(p->radio_data[j].radio_id, radio->macaddr, 6);
-
-		p->radio_data[j].op_class = 0x01;	//dummy value TODO
-		p->radio_data[j].ch = 0x01;	// dummy value TODO
-
-		p->radio_data[j].completion_status = 0x05;// dummy value TODO
-		p->radio_data[j].nbr_pairs = 0;	//dummy value TODO
-	}
-}
-
 int handle_channel_pref_query(void *agent, struct cmdu_cstruct *rec_cmdu)
 {
 	trace("%s: --->\n", __func__);
@@ -925,7 +857,7 @@ int handle_channel_pref_query(void *agent, struct cmdu_cstruct *rec_cmdu)
 				sizeof(struct tlv_channel_pref));
 		if (p) {
 			p->tlv_type = MAP_TLV_CHANNEL_PREFERENCE;
-			get_radio_channel_preference(a, p, j);
+			agent_gen_radio_channel_preference(a, p, j);
 			cmdu_data->tlvs[tlv_index++] = (uint8_t *)p;
 		}
 	}
@@ -937,7 +869,7 @@ int handle_channel_pref_query(void *agent, struct cmdu_cstruct *rec_cmdu)
 				sizeof(struct tlv_radio_oper_restrict));
 		if (p1) {
 			p1->tlv_type = MAP_TLV_RADIO_OPERATION_RESTRICTION;
-			get_radio_restrict_channel(a, p1, j);
+			agent_gen_radio_restrict_channel(a, p1, j);
 			cmdu_data->tlvs[tlv_index++] = (uint8_t *)p1;
 		}
 	}
@@ -950,7 +882,7 @@ int handle_channel_pref_query(void *agent, struct cmdu_cstruct *rec_cmdu)
 			sizeof(struct tlv_cac_comp_report));
 	if (p2) {
 		p2->tlv_type = MAP_TLV_CAC_COMPLETION_REPORT;
-		get_cac_comp_report(a, p2);
+		agent_gen_cac_comp_report(a, p2);
 		cmdu_data->tlvs[tlv_index++] = (uint8_t *)p2;
 	}
 
@@ -977,10 +909,233 @@ int handle_channel_pref_query(void *agent, struct cmdu_cstruct *rec_cmdu)
 
 int handle_channel_sel_request(void *agent, struct cmdu_cstruct *cmdu)
 {
-	trace("%s: --->\n", __func__);
+	trace("agent: %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 need to update the channel preference values
+	//from the channel selection request
+	//then send the CMDU for channel selection response
+
+	if (cmdu->num_tlvs != 0) {
+		for (i = 0; i < cmdu->num_tlvs; i++) {
+			tlv = (uint8_t *) cmdu->tlvs[i];
+			switch (*tlv) {
+			case MAP_TLV_CHANNEL_PREFERENCE:
+				{
+					struct tlv_channel_pref  *p =
+						(struct tlv_channel_pref *)tlv;
+					pref_tlv_present = 1;
+
+					ret = agent_process_channel_pref_tlv
+						(agent, p, channel_resp,
+						&channel_resp_nr);
+				}
+			case MAP_TLV_TRANSMIT_POWER_LIMIT:
+				{
+					struct tlv_tx_power_limit  *p =
+						(struct tlv_tx_power_limit *)tlv;
+
+					trace("tlv radio_id: " MACFMT "\n",
+						MAC2STR(p->radio_id));
+					for (l = 0; l < a->num_radios; l++) {
+						radio = a->radios + l;
+						match = memcmp(radio->macaddr, p->radio_id, 6);
+						if (match == 0) {
+							//Here we set the
+							//transmit_power_limit of the radio
+							radio->transmit_power_limit =
+								p->tx_power_limit;
+							trace("transmit power %d\n",
+								p->tx_power_limit);
+							break;
+						}
+					}
+				}
+			default:
+				break;
+			}
+		}
+	}
+
+	if (cmdu->num_tlvs == 0 || pref_tlv_present == 0) {
+		//Here the condition is that the
+		//channel selection request have no tlvs or only transmit power tlv
+		//so we need to set all the prefernce in all radios to max 15
+		agent_fill_radio_max_preference(agent,
+			channel_resp, &channel_resp_nr);
+	}
+
+	ret = send_channel_sel_response(agent, cmdu,
+		channel_resp, channel_resp_nr);
+
+	return ret;
+}
+
+int agent_process_channel_pref_tlv(void *agent, struct tlv_channel_pref  *p,
+		struct channel_response *channel_resp,
+		uint32_t *channel_resp_nr)
+{
+	trace("agent: %s: --->\n", __func__);
+	struct agent *a = (struct agent *) agent;
+	int ret = 0;
+	uint32_t  match = 0, found = 0;
+	int i, j, k, l, m;
+	struct wifi_radio_element *radio;
+	uint32_t pref_tlv_present = 0;
+
+	trace("\tradio_id: " MACFMT "\n",
+		MAC2STR(p->radio_id));
+	for (l = 0; l < a->num_radios; l++) {
+		radio = a->radios + l;
+		match = memcmp(radio->macaddr, p->radio_id, 6);
+		if (match == 0) {
+			found = 1;
+			memcpy(channel_resp[*channel_resp_nr].radio_id,
+				radio->macaddr, 6);
+			channel_resp[*channel_resp_nr].response = 0x00;
+			break;
+		}
+	}
+	if (found == 0) {
+		memcpy(channel_resp[*channel_resp_nr].radio_id,
+			p->radio_id, 6);
+		//Here response code is a Reserved code
+		//to decline the request
+		channel_resp[*channel_resp_nr].response = 0x04;
+		*channel_resp_nr = *channel_resp_nr + 1;
+		return ret;
+	}
+	trace("ch_preference_op_class_nr: %d\n",
+		p->ch_preference_op_class_nr);
+
+	for (j = 0; j < p->ch_preference_op_class_nr; j++) {
+		//Here we need to search the operating class in the radio
+		for (l = 0; l < radio->num_supp_opclass; l++) {
+			if (radio->supp_opclass[l].id ==  p->op_class[j].op_class) {
+				//Here we reset all the channels preferences in the
+				//operating class as 15 highest prefernce
+				trace("op_class : %d channel_nr %d\n",
+					p->op_class[j].op_class,
+					p->op_class[j].channel_nr);
+
+				for (k = 0; k <
+					radio->supp_opclass[l].num_supported_channels;
+						k++)
+					radio->supp_opclass[l].
+						supp_chanlist[k].pref = 0xff;
+
+				for (k = 0; k < p->op_class[j].channel_nr; k++) {
+					for (m = 0; m <
+						radio->supp_opclass[l].
+						num_supported_channels ; m++) {
+						trace("channel  %d\n",
+							p->op_class[j].channel_list[k]);
+						if (p->op_class[j].channel_list[k] ==
+							radio->supp_opclass[l].
+							supp_chanlist[m].channel) {
+							radio->supp_opclass[l].
+								supp_chanlist[m].pref =
+								p->op_class[j].preference;
+
+							trace("channel pref is %d\n",
+								p->op_class[j].preference);
+						}
+					}
+				}
+				break;
+			}
+		}
+	}
+	*channel_resp_nr = *channel_resp_nr + 1;
+	return ret;
+}
+
+int agent_fill_radio_max_preference(void *agent,
+		struct channel_response *channel_resp,
+		uint32_t *channel_response_nr)
+{
+	trace("agent: %s: --->\n", __func__);
+	struct agent *a = (struct agent *) agent;
+	uint32_t j = 0, k = 0, l = 0;
+	struct wifi_radio_element *radio = NULL;
+
+	*channel_response_nr = a->num_radios;
+
+	for (j = 0; j < a->num_radios; j++) {
+		radio = a->radios + j;
+		memcpy(channel_resp[j].radio_id, radio->macaddr, 6);
+
+		for (k = 0; k < radio->num_supp_opclass; k++) {
+			for (l = 0; l < radio->supp_opclass[k].
+				num_supported_channels; l++)
+				radio->supp_opclass[k].supp_chanlist[l].pref =
+				0xff;
+		}
+		channel_resp[j].response = 0x00;
+	}
 	return 0;
 }
 
+int send_channel_sel_response(void *agent, struct cmdu_cstruct *rec_cmdu,
+		struct channel_response *channel_resp,
+		uint32_t channel_response_nr)
+{
+	trace("agent: %s: --->\n", __func__);
+	struct agent *a = (struct agent *) agent;
+	uint16_t tlv_index = 0;
+	uint32_t j, ret = 0;
+	struct cmdu_cstruct *cmdu_data;
+
+	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_CHANNEL_SELECTION_RESPONSE;
+	memcpy(cmdu_data->origin, rec_cmdu->origin, 6);
+	cmdu_data->message_id = rec_cmdu->message_id;
+	strcpy(cmdu_data->intf_name, rec_cmdu->intf_name);
+
+	cmdu_data->num_tlvs = 1 * channel_response_nr; /* (channel selection response) */
+	cmdu_data->tlvs = (uint8_t **)calloc(cmdu_data->num_tlvs,
+				sizeof(uint8_t *));
+
+	if (!cmdu_data->tlvs) {
+		map_free_cmdu(cmdu_data);
+		return -1;
+	}
+
+	/* Operating Channel Response TLV 17.2.16 */
+	for (j = 0; j < channel_response_nr; j++) {
+		struct tlv_ch_selection_resp *p = NULL;
+		//Here we need to check that the radio
+		//response is for the radio for which we get request
+		p = agent_gen_operate_channel_response(a, rec_cmdu,
+			channel_resp[j].radio_id, channel_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);
+
+	//TODO send a report message for each radio. This will be
+	//sent not here but on receiving of the event when the
+	//actually radio channel poreference have been changed
+	send_oper_channel_report(agent, rec_cmdu);
+	return ret;
+}
+
 int handle_sta_caps_query(void *agent, struct cmdu_cstruct *rec_cmdu)
 {
 	struct agent *a = (struct agent *) agent;
diff --git a/src/core/agent_map.h b/src/core/agent_map.h
index c9159b0ebb17b88fcd089cf70304b017a96b0119..af1033a8126c5b6623478119e5eeaac4e23f88b8 100644
--- a/src/core/agent_map.h
+++ b/src/core/agent_map.h
@@ -15,6 +15,13 @@ extern int agent_handle_map_event(struct agent *a, uint16_t cmdutype,
 int build_ap_autoconfig_wsc(void *agent, uint8_t *hwaddr,
 		struct wifi_radio_element *radio, int idx);
 int agent_send_cmdu(struct agent *a, struct cmdu_cstruct *cmdu);
+int send_channel_sel_response(void *agent, struct cmdu_cstruct *cmdu,
+		struct channel_response *rec_cmdu, uint32_t channel_response_nr);
+int agent_fill_radio_max_preference(void *agent,
+		struct channel_response *channel_resp, uint32_t *channel_response_nr);
+int agent_process_channel_pref_tlv(void *agent, struct tlv_channel_pref  *p,
+		struct channel_response *channel_resp,
+		uint32_t *channel_response_nr);
 
 
 #endif /* AGENT_MAP_H */
diff --git a/src/core/agent_tlv_generator.c b/src/core/agent_tlv_generator.c
index aec2636f6a5036d1f82f6feb6c693c71c492f143..5f8a77a08ebdf7da1827d2a7601e0f6697c8c0dc 100644
--- a/src/core/agent_tlv_generator.c
+++ b/src/core/agent_tlv_generator.c
@@ -310,7 +310,7 @@ struct tlv_ch_scan_cap *agent_gen_ch_scan_cap(struct agent *a)
 				continue;
 
 			for (k = 0; k < p->radio[i].op_class[j].nbr_ch; k++)
-				p->radio[i].op_class[j].ch[k] = opclass->supp_chanlist[k];
+				p->radio[i].op_class[j].ch[k] = opclass->supp_chanlist[k].channel;
 		}
 	}
 
@@ -387,7 +387,7 @@ struct tlv_cac_cap *agent_gen_cac_cap(struct agent *a)
 					continue;
 
 				p->radio_data[i].cac_data[j].op_class_data[k].ch =
-						calloc(opclass->num_supported_channels, sizeof(uint8_t));
+						calloc(opclass->num_supported_channels, sizeof(struct supp_channel));
 
 				if (!p->radio_data[i].cac_data[j].op_class_data[k].ch)
 					continue;
@@ -395,7 +395,7 @@ struct tlv_cac_cap *agent_gen_cac_cap(struct agent *a)
 				for (l = 0; l < opclass->num_supported_channels; l++) {
 					uint8_t ch;
 
-					p->radio_data[i].cac_data[j].op_class_data[k].ch[l] = opclass->supp_chanlist[l];
+					p->radio_data[i].cac_data[j].op_class_data[k].ch[l] = opclass->supp_chanlist[l].channel;
 
 					ch = p->radio_data[i].cac_data[j].op_class_data[k].ch[l];
 					if (ch == 120 || ch == 124 || ch == 128)
@@ -422,4 +422,211 @@ struct tlv_metric_collection_interval *agent_gen_metric_collection_interval(stru
 	p->collection_interval = AP_COLLECTION_INTERVAL;
 
 	return p;
-}
\ No newline at end of file
+}
+
+struct tlv_oper_ch_report *agent_gen_operate_channel_report(struct agent *a,
+		struct cmdu_cstruct *cmdu, uint32_t radio_index)
+{
+	struct tlv_oper_ch_report *p;
+	struct wifi_radio_element *radio;
+	uint32_t j = 0;
+
+	radio = a->radios + radio_index;
+
+	p = (struct tlv_oper_ch_report *)calloc(1,
+		sizeof(struct tlv_oper_ch_report));
+	if (!p)
+		return NULL;
+
+	p->tlv_type = MAP_TLV_OPERATING_CHANNEL_REPORT;
+	memcpy(p->radio_id, radio->macaddr, 6);
+	p->op_ch_op_class_nr = 1;
+
+	if (p->op_ch_op_class_nr > 0)
+		p->op_ch_op_class = calloc(p->op_ch_op_class_nr,
+			sizeof(*p->op_ch_op_class));
+
+	if (!p->op_ch_op_class) {
+		fprintf(stderr, "|%s:%d| out of memory!\n", __func__, __LINE__);
+		p->op_ch_op_class_nr = 0;
+		return;
+	}
+
+	for (j = 0; j < p->op_ch_op_class_nr; j++) {
+		p->op_ch_op_class[j].op_class = radio->current_opclass;
+		p->op_ch_op_class[j].channel = radio->current_channel;
+	}
+
+	//current transmit power is the (operating class tx power) *
+	//	(current_tx_power_percent)/100
+	for (j = 0; j < radio->num_supp_opclass; j++) {
+		if (radio->supp_opclass[j].id == radio->current_opclass)
+			p->curr_tx_power =
+				radio->supp_opclass[j].max_txpower *
+					((radio->current_txpower_percent)/100);
+	}
+	return p;
+}
+
+struct tlv_ch_selection_resp *agent_gen_operate_channel_response(struct agent *a,
+		struct cmdu_cstruct *cmdu, uint8_t *radio_recvd, uint8_t reason_code)
+{
+	struct tlv_ch_selection_resp *p;
+
+	p = (struct tlv_ch_selection_resp *)calloc(1,
+		sizeof(struct tlv_ch_selection_resp));
+
+	if (!p)
+		return NULL;
+
+	p->tlv_type = MAP_TLV_CHANNEL_SELECTION_RESPONSE;
+	memcpy(p->radio_id, radio_recvd, 6);
+	p->response_code = reason_code;
+
+	return p;
+}
+
+void agent_gen_radio_channel_preference(struct agent *a,
+		struct tlv_channel_pref *p,
+		uint32_t radio_index)
+{
+	uint32_t j = 0, k = 0, count = 0, l = 0;
+	struct wifi_radio_element *radio = a->radios + radio_index;
+
+	trace("%s -----> parsing radio %s\n", __func__, radio->name);
+
+	memcpy(p->radio_id, radio->macaddr, 6);
+	p->ch_preference_op_class_nr = radio->num_supp_opclass;
+
+	if (p->ch_preference_op_class_nr > 0)
+		p->op_class = calloc(p->ch_preference_op_class_nr,
+				sizeof(*p->op_class));
+	if (!p->op_class) {
+		fprintf(stderr, "|%s:%d| out of memory!\n", __func__, __LINE__);
+		p->ch_preference_op_class_nr = 0;
+		return;
+	}
+
+	for (j = 0; j < p->ch_preference_op_class_nr; j++) {
+
+		p->op_class[j].op_class = radio->supp_opclass[j].id;
+		count = 0;
+
+		//Here we fill all the channels that are not having max preference 15
+		for (k = 0; k < radio->supp_opclass[j].num_supported_channels; k++) {
+			if (radio->supp_opclass[j].supp_chanlist[k].pref != 0xff)
+				count++;
+		}
+		p->op_class[j].channel_nr = count;
+
+		if (p->op_class[j].channel_nr > 0) {
+			p->op_class[j].channel_list = calloc(p->op_class[j].channel_nr,
+					sizeof(*p->op_class[j].channel_list));
+
+			if (!p->op_class[j].channel_list) {
+				fprintf(stderr, "|%s:%d| out of memory!\n",
+							__func__, __LINE__);
+				p->op_class[j].channel_nr = 0;
+				return;
+			}
+			l = 0;
+
+			for (k = 0; k < radio->supp_opclass[j].num_supported_channels; k++) {
+				if (radio->supp_opclass[j].supp_chanlist[k].pref != 0xff) {
+					p->op_class[j].channel_list[l] =
+						radio->supp_opclass[j].supp_chanlist[k].channel;
+					p->op_class[j].preference =
+						radio->supp_opclass[j].supp_chanlist[k].pref;
+					l++;
+				}
+			}
+
+			p->op_class[j].preference_reason = 0x00;
+		} else {
+			p->op_class[j].channel_list = NULL;
+			p->op_class[j].preference = 0xff;
+			p->op_class[j].preference_reason = 0x00;
+		}
+	}
+}
+
+void agent_gen_radio_restrict_channel(struct agent *a,
+		struct tlv_radio_oper_restrict *p,
+		uint32_t radio_index)
+{
+	uint32_t j, k, l, m;
+	struct wifi_radio_element *radio = a->radios + radio_index;
+
+	trace("%s -----> parsing radio %s\n", __func__, radio->name);
+
+	memcpy(p->radio_id, radio->macaddr, 6);
+	p->op_restricted_op_class_nr = 1;
+
+	if (p->op_restricted_op_class_nr > 0)
+		p->restricted_op_class = calloc(p->op_restricted_op_class_nr,
+			sizeof(*p->restricted_op_class));
+	if (!p->restricted_op_class) {
+		fprintf(stderr, "|%s:%d| out of memory!\n", __func__, __LINE__);
+		p->op_restricted_op_class_nr = 0;
+		return;
+	}
+
+	for (j = 0, m = 0; j < radio->num_supp_opclass; j++) {
+		if (radio->supp_opclass[j].id != radio->current_opclass)
+			continue;
+		p->restricted_op_class[m].op_class = radio->current_opclass;
+		p->restricted_op_class[m].channel_nr = (radio->supp_opclass[j].num_supported_channels) - 1;
+
+		if (p->restricted_op_class[m].channel_nr > 0)
+			p->restricted_op_class[m].restricted_channels =
+					calloc(p->restricted_op_class[j].channel_nr,
+						sizeof(*p->restricted_op_class[m].restricted_channels));
+
+		if (!p->restricted_op_class[m].restricted_channels) {
+			fprintf(stderr, "|%s:%d| out of memory!\n", __func__, __LINE__);
+			p->restricted_op_class[m].channel_nr = 0;
+			return;
+		}
+
+		for (k = 0, l = 0; k <  radio->supp_opclass[j].num_supported_channels; k++) {
+			if (radio->supp_opclass[j].supp_chanlist[k].channel == radio->current_channel)
+				continue;
+			p->restricted_op_class[m].restricted_channels[l].channel =
+				radio->supp_opclass[j].supp_chanlist[k].channel;
+			p->restricted_op_class[m].restricted_channels[l].min_freq_sep = 0; //TODO dummy value
+			l++;
+		}
+		m++;
+	}
+}
+
+void agent_gen_cac_comp_report(struct agent *a,
+		struct tlv_cac_comp_report *p)
+{
+	uint32_t j;
+	struct wifi_radio_element *radio = NULL;
+
+	trace("%s -----> Inside\n", __func__);
+	p->nbr_radios = a->num_radios;
+
+	if (p->nbr_radios > 0)
+		p->radio_data = calloc(p->nbr_radios,
+					sizeof(*p->radio_data));
+
+	if (!p->radio_data) {
+		fprintf(stderr, "|%s:%d| out of memory!\n", __func__, __LINE__);
+		p->nbr_radios = 0;
+		return;
+	}
+
+	for (j = 0; j < a->num_radios; j++) {
+		radio = a->radios + j;
+		memcpy(p->radio_data[j].radio_id, radio->macaddr, 6);
+
+		p->radio_data[j].op_class = 0x01;       //dummy value TODO
+		p->radio_data[j].ch = 0x01;     // dummy value TODO
+
+		p->radio_data[j].completion_status = 0x05;// dummy value TODO
+		p->radio_data[j].nbr_pairs = 0; //dummy value TODO
+	}
+}
diff --git a/src/core/agent_tlv_generator.h b/src/core/agent_tlv_generator.h
index 0c289e2dd834c98af2bb67a7f4fd93247dda8eb7..d14c63a778f4770ee3669f2d7fe10775d5ccf86a 100644
--- a/src/core/agent_tlv_generator.h
+++ b/src/core/agent_tlv_generator.h
@@ -26,5 +26,16 @@ struct tlv_wsc *agent_gen_wsc(struct agent *a, struct cmdu_cstruct *cmdu,
 struct tlv_ch_scan_cap *agent_gen_ch_scan_cap(struct agent *a);
 struct tlv_cac_cap *agent_gen_cac_cap(struct agent *a);
 struct tlv_metric_collection_interval *agent_gen_metric_collection_interval(struct agent *a);
-
+struct tlv_oper_ch_report *agent_gen_operate_channel_report(struct agent *a,
+		struct cmdu_cstruct *cmdu, uint32_t radio_index);
+struct tlv_ch_selection_resp *agent_gen_operate_channel_response(struct agent *a,
+		struct cmdu_cstruct *cmdu, uint8_t *radio_recvd, uint8_t reason_code);
+void agent_gen_radio_channel_preference(struct agent *a,
+		struct tlv_channel_pref *p,
+		uint32_t radio_index);
+void agent_gen_radio_restrict_channel(struct agent *a,
+		struct tlv_radio_oper_restrict *p,
+		uint32_t radio_index);
+void agent_gen_cac_comp_report(struct agent *a,
+		struct tlv_cac_comp_report *p);
 #endif