コード例 #1
0
/**
 * @brief Apply time delta to MAC time
 *
 * The Reference Design includes a 64-bit counter that increments every microsecond
 * and can be updated (ie the MAC time).  This function updates the counter value
 * by time_delta microseconds (note that the time delta is an s64 and can be positive
 * or negative).  Some 802.11 handshakes require updating the MAC time to match a
 * partner node's MAC time value (reception of a beacon, for example)
 *
 * @param   time_delta       - s64 number of microseconds to change the MAC time of the node
 * @return  None
 */
void apply_mac_time_delta_usec(s64 time_delta) {

	wlan_ipc_msg_t     ipc_msg_to_low;
	s64                ipc_msg_to_low_payload = time_delta;

	// Send message to CPU Low
	ipc_msg_to_low.msg_id            = IPC_MBOX_MSG_ID(IPC_MBOX_SET_MAC_TIME);
	ipc_msg_to_low.arg0				 = 1; //Indicates that the payload is a delta
	ipc_msg_to_low.num_payload_words = 2;
	ipc_msg_to_low.payload_ptr       = (u32*)(&(ipc_msg_to_low_payload));

	write_mailbox_msg(&ipc_msg_to_low);
}
コード例 #2
0
/**
 * @brief Set MAC time
 *
 * The Reference Design includes a 64-bit counter that increments every microsecond
 * and can be updated (ie the MAC time).  This function sets the counter value.
 * Some 802.11 handshakes require updating the MAC time to match a partner node's
 * MAC time value (reception of a beacon, for example)
 *
 * @param   new_time         - u64 number of microseconds for the new MAC time of the node
 * @return  None
 */
void set_mac_time_usec(u64 new_time) {

	wlan_ipc_msg_t     ipc_msg_to_low;
	u64                ipc_msg_to_low_payload = new_time;

	// Send message to CPU Low
	ipc_msg_to_low.msg_id            = IPC_MBOX_MSG_ID(IPC_MBOX_SET_MAC_TIME);
	ipc_msg_to_low.arg0				 = 0; //Indicates that the payload is absolute
	ipc_msg_to_low.num_payload_words = 2;
	ipc_msg_to_low.payload_ptr       = (u32*)(&(ipc_msg_to_low_payload));

	write_mailbox_msg(&ipc_msg_to_low);

}
コード例 #3
0
void mpdu_transmit(packet_bd* tx_queue) {

	wlan_ipc_msg ipc_msg_to_low;
	tx_frame_info* tx_mpdu = (tx_frame_info*) TX_PKT_BUF_TO_ADDR(tx_pkt_buf);
	station_info* station = (station_info*)(tx_queue->metadata_ptr);


	if(is_tx_buffer_empty()){

		//For now, this is just a one-shot DMA transfer that effectively blocks
		while(XAxiCdma_IsBusy(&cdma_inst)) {}
		XAxiCdma_SimpleTransfer(&cdma_inst, (u32)(tx_queue->buf_ptr), (u32)TX_PKT_BUF_TO_ADDR(tx_pkt_buf), ((tx_packet_buffer*)(tx_queue->buf_ptr))->frame_info.length + sizeof(tx_frame_info) + PHY_TX_PKT_BUF_PHY_HDR_SIZE, NULL, NULL);
		while(XAxiCdma_IsBusy(&cdma_inst)) {}


		if(station == NULL){
			//Broadcast transmissions have no station information, so we default to a nominal rate
			tx_mpdu->AID = 0;
			tx_mpdu->rate = WLAN_MAC_RATE_6M;
		} else {
			//Request the rate to use for this station
			tx_mpdu->AID = station->AID;
			tx_mpdu->rate = wlan_mac_util_get_tx_rate(station);
			//tx_mpdu->rate = default_unicast_rate;
		}

		tx_mpdu->state = TX_MPDU_STATE_READY;
		tx_mpdu->retry_count = 0;

		ipc_msg_to_low.msg_id = IPC_MBOX_MSG_ID(IPC_MBOX_TX_MPDU_READY);
		ipc_msg_to_low.arg0 = tx_pkt_buf;
		ipc_msg_to_low.num_payload_words = 0;

		if(unlock_pkt_buf_tx(tx_pkt_buf) != PKT_BUF_MUTEX_SUCCESS){
			warp_printf(PL_ERROR,"Error: unable to unlock tx pkt_buf %d\n",tx_pkt_buf);
		} else {
			set_cpu_low_not_ready();
			/* WMP START */
			tx_pkt_buf_prev_acc = 0;
			/* WMP END */
			ipc_mailbox_write_msg(&ipc_msg_to_low);
		}
	} else {
		warp_printf(PL_ERROR, "Bad state in mpdu_transmit. Attempting to transmit but tx_buffer %d is not empty\n",tx_pkt_buf);
	}

	return;
}
コード例 #4
0
void uart_rx(u8 rxByte){
	/* WMP_START */
	u32 i;
	u32 tmp_chan;
	/* WMP_END */
	#define MAX_NUM_AP_CHARS 4
	static char numerical_entry[MAX_NUM_AP_CHARS+1];
	static u8 curr_decade = 0;

	#define MAX_NUM_CHARS 31
	static char text_entry[MAX_NUM_CHARS+1];
	static u8 curr_char = 0;

	u16 ap_sel;
	wlan_ipc_msg ipc_msg_to_low;
	u32 ipc_msg_to_low_payload[1];
	ipc_config_rf_ifc* config_rf_ifc;

	void* ltg_sched_state;
	u32 ltg_type;

	void* ltg_callback_arg;
	ltg_sched_periodic_params periodic_params;
	ltg_sched_uniform_rand_params rand_params;

	if(rxByte == ASCII_ESC){
		uart_mode = UART_MODE_MAIN;
		print_menu();

		ltg_sched_remove(LTG_REMOVE_ALL);

		return;
	}

	switch(uart_mode){
		case UART_MODE_MAIN:
			switch(rxByte){
				case ASCII_1:
					uart_mode = UART_MODE_INTERACTIVE;
					print_station_status(1);
				break;

				case ASCII_a:

					if (modeofoperation == MODEOFOPERATION_AP) {
						print_menu();
						xil_printf("\n\nScan is disabled in AP mode\n");
						break;
					}

					//Send bcast probe requests across all channels
					if(active_scan ==0){
						num_ap_list = 0;
						//xil_printf("- Free 0x%08x\n",ap_list);
						wlan_free(ap_list);
						ap_list = NULL;
						active_scan = 1;
						access_point_ssid = wlan_realloc(access_point_ssid, 1);
						*access_point_ssid = 0;
						//xil_printf("+++ starting active scan\n");
						pause_queue = 1;
						mac_param_chan_save = mac_param_chan;
						probe_req_transmit();
					}
				break;

				/* WMP_START */
				case ASCII_c:
					uart_mode = UART_MODE_CHAN_CHANGE;
					curr_char = 0;
					print_chan_menu();

				break;

				case ASCII_b:
					if (modeofoperation == MODEOFOPERATION_STA) {
						print_menu();
						xil_printf("\n\nBeacon inteval change not supported in STA mode\n");
						break;
					}
					uart_mode = UART_MODE_BEACON_TU_CHANGE;
					curr_char = 0;
					print_beacon_tu_menu();

				break;

				case ASCII_s:
					if (modeofoperation == MODEOFOPERATION_STA) {
						print_menu();
						xil_printf("\n\nSSID change not supported in STA mode\n");
						break;
					}
					uart_mode = UART_MODE_SSID_CHANGE;
					curr_char = 0;
					print_ssid_menu();
				break;
				/* WMP_END */

				case ASCII_r:
					if(default_unicast_rate > WLAN_MAC_RATE_6M){
						default_unicast_rate--;
					} else {
						default_unicast_rate = WLAN_MAC_RATE_6M;
					}

					for(i=0; i < next_free_assoc_index; i++){
						associations[i].tx_rate = default_unicast_rate;
					}

					access_point.tx_rate = default_unicast_rate;


					xil_printf("(-) Default Unicast Rate: %d Mbps\n", wlan_lib_mac_rate_to_mbps(default_unicast_rate));
				break;
				case ASCII_R:
					if(default_unicast_rate < WLAN_MAC_RATE_54M){
						default_unicast_rate++;
					} else {
						default_unicast_rate = WLAN_MAC_RATE_54M;
					}

					access_point.tx_rate = default_unicast_rate;

					for(i=0; i < next_free_assoc_index; i++){
						associations[i].tx_rate = default_unicast_rate;
					}

					xil_printf("(+) Default Unicast Rate: %d Mbps\n", wlan_lib_mac_rate_to_mbps(default_unicast_rate));
				break;
				case ASCII_n:
					if(num_slots == 0 || num_slots == SLOT_CONFIG_RAND){
						num_slots = SLOT_CONFIG_RAND;
						xil_printf("num_slots = SLOT_CONFIG_RAND\n");
					} else {
						num_slots--;
						xil_printf("num_slots = %d\n", num_slots);
					}


					set_backoff_slot_value(num_slots);
				break;

				case ASCII_N:
					if(num_slots == SLOT_CONFIG_RAND){
						num_slots = 0;
					} else {
						num_slots++;
					}

					xil_printf("num_slots = %d\n", num_slots);

					set_backoff_slot_value(num_slots);
				break;

				/* WMP_START */
				case ASCII_m:
					uart_mode = UART_MODE_MODECHOICE;
					print_modechoice_menu();
				break;
				/* WMP_END */
			}
		break;

		/* WMP_START */
		case UART_MODE_MODECHOICE:
			switch(rxByte){
			case ASCII_0:
				if (modeofoperation == MODEOFOPERATION_STA) {
					uart_mode = UART_MODE_MAIN;
					print_menu();
					break;
				}
				modeofoperation = MODEOFOPERATION_STA;
				ipc_msg_to_low.msg_id = IPC_MBOX_MSG_ID(IPC_MBOX_MODE);
				ipc_msg_to_low.num_payload_words = 0;
				ipc_msg_to_low.arg0 = modeofoperation;
				ipc_mailbox_write_msg(&ipc_msg_to_low);
				wlan_mac_util_set_eth_encap_mode(ENCAP_MODE_STA);
				access_point_ssid = wlan_realloc(access_point_ssid, strlen(default_AP_SSID)+1);
				strcpy(access_point_ssid,default_AP_SSID);

				deauthenticate_stations();

				wlan_mac_util_set_eth_rx_callback(       (void*)ethernet_receive);
				wlan_mac_util_set_mpdu_tx_done_callback( (void*)mpdu_transmit_done);
				wlan_mac_util_set_mpdu_rx_callback(      (void*)mpdu_rx_process);
				wlan_mac_util_set_ipc_rx_callback(       (void*)ipc_rx);
				wlan_mac_util_set_check_queue_callback(  (void*)check_tx_queue);

				wlan_mac_util_set_fcs_bad_rx_callback(   (void*)bad_fcs_rx_process);
				wlan_mac_util_set_uart_rx_callback(      (void*)uart_rx);
				wlan_mac_ltg_sched_set_callback(         (void*)ltg_event);
				max_queue_size = MAX_PER_FLOW_QUEUE;
				write_hex_display(0);
				uart_mode = UART_MODE_MAIN;
				print_menu();
				xil_printf("\nSet mode: STA\n");
			break;
			case ASCII_1:
				if (modeofoperation == MODEOFOPERATION_AP) {
					uart_mode = UART_MODE_MAIN;
					print_menu();
					break;
				}
				modeofoperation = MODEOFOPERATION_AP;
				ipc_msg_to_low.msg_id = IPC_MBOX_MSG_ID(IPC_MBOX_MODE);
				ipc_msg_to_low.num_payload_words = 0;
				ipc_msg_to_low.arg0 = modeofoperation;
				ipc_mailbox_write_msg(&ipc_msg_to_low);
				wlan_mac_util_set_eth_encap_mode(ENCAP_MODE_AP);
				bzero(&(associations[0]), sizeof(station_info)*(MAX_ASSOCIATIONS+1));

				for(i = 0; i < MAX_ASSOCIATIONS; i++){
					associations[i].AID = (1+i); //7.3.1.8 of 802.11-2007
					memset((void*)(&(associations[i].addr[0])), 0xFF,6);
					associations[i].seq = 0; //seq
				}
				max_queue_size = min((queue_total_size()- eth_bd_total_size()) / (next_free_assoc_index+1),MAX_PER_FLOW_QUEUE);
				if (strlen(last_access_point_ssid) > 0) {
					access_point_ssid = wlan_realloc(access_point_ssid, strlen(last_access_point_ssid)+1);
					strcpy(access_point_ssid, last_access_point_ssid);
				} else {
					access_point_ssid = wlan_realloc(access_point_ssid, strlen(apmode_default_ssid)+1);
					strcpy(access_point_ssid, apmode_default_ssid);
				}
				// TODO: Deauthentication
				// TODO: Disassociation
				wlan_mac_util_set_eth_rx_callback(       (void*)ethernet_receive_ap);
				wlan_mac_util_set_mpdu_tx_done_callback( (void*)mpdu_transmit_done_ap);
				wlan_mac_util_set_mpdu_rx_callback(      (void*)mpdu_rx_process_ap);
				wlan_mac_util_set_ipc_rx_callback(       (void*)ipc_rx);
				wlan_mac_util_set_check_queue_callback(  (void*)check_tx_queue_ap);

				wlan_mac_util_set_fcs_bad_rx_callback(   (void*)bad_fcs_rx_process_ap);
				wlan_mac_util_set_uart_rx_callback(      (void*)uart_rx);
				wlan_mac_ltg_sched_set_callback(         (void*)ltg_event_ap);
				wmp_high_util_update_beacon_template();
				memset(&access_point, 0,sizeof(station_info));
				association_state = -1;
				write_hex_display(0);
				uart_mode = UART_MODE_MAIN;
				print_menu();
				xil_printf("\nSet mode: AP\n");
			break;
			case ASCII_ESC:
				uart_mode = UART_MODE_MAIN;
				print_menu();
			break;
			default:
				print_modechoice_menu();
			break;
			}
		break;

		case UART_MODE_CHAN_CHANGE:
			switch(rxByte){
				case ASCII_ESC:
					uart_mode = UART_MODE_MAIN;
					curr_char = 0;
					print_menu();
				break;

				case ASCII_CR:
					text_entry[curr_char] = 0;
					curr_char = 0;
					uart_mode = UART_MODE_MAIN;

					tmp_chan = atoi(text_entry);

					if ((tmp_chan != mac_param_chan) ||
							((tmp_chan >= 1) && (tmp_chan <= 14))) {
						mac_param_chan = tmp_chan;
						set_mac_channel( mac_param_chan );
						print_menu();
						xil_printf("\nSetting new channel: %d\n", mac_param_chan);
					} else {
						print_menu();
						xil_printf("\nStay on channel: %d\n", mac_param_chan);
					}
				break;

				case ASCII_DEL:
					if(curr_char > 0){
						curr_char--;
						xil_printf("\b \b");
					}

				break;
				default:
					if( (rxByte >= ASCII_0) && (rxByte <= ASCII_9) ){
						//the user entered a character

						if(curr_char < MAX_NUM_CHARS){
							xil_printf("%c", rxByte);
							text_entry[curr_char] = rxByte;
							curr_char++;
						}
					}
				break;
			}
		break;

		case UART_MODE_BEACON_TU_CHANGE:
		switch(rxByte){
			case ASCII_ESC:
				uart_mode = UART_MODE_MAIN;
				curr_char = 0;
				print_menu();
			break;

			case ASCII_CR:
				text_entry[curr_char] = 0;
				curr_char = 0;
				uart_mode = UART_MODE_MAIN;

				beacon_interval = atoi(text_entry);
				wmp_high_util_update_beacon_template();

				print_menu();
				xil_printf("\nSetting new beacon interval: %d\n", beacon_interval);

			break;

			case ASCII_DEL:
				if(curr_char > 0){
					curr_char--;
					xil_printf("\b \b");
				}

			break;
			default:
				if( (rxByte >= ASCII_0) && (rxByte <= ASCII_9) ){
					//the user entered a character

					if(curr_char < MAX_NUM_CHARS){
						xil_printf("%c", rxByte);
						text_entry[curr_char] = rxByte;
						curr_char++;
					}
				}
			break;
		}
		break;

		case UART_MODE_SSID_CHANGE:
		switch(rxByte){
			case ASCII_ESC:
				uart_mode = UART_MODE_MAIN;
				curr_char = 0;
				print_menu();
			break;

			case ASCII_CR:
				text_entry[curr_char] = 0;
				curr_char = 0;
				uart_mode = UART_MODE_MAIN;

				if (memcmp(access_point_ssid, text_entry, strlen(access_point_ssid))) {
					access_point_ssid = wlan_realloc(access_point_ssid, strlen(text_entry)+1);
					strcpy(access_point_ssid,text_entry);
					deauthenticate_stations();
					wmp_high_util_update_beacon_template();
					print_menu();
					xil_printf("\nSetting new SSID: %s\n", access_point_ssid);
				} else {
					print_menu();
					xil_printf("\nStay with SSID: %s\n", access_point_ssid);
				}

			break;

			case ASCII_DEL:
				if(curr_char > 0){
					curr_char--;
					xil_printf("\b \b");
				}

			break;
			default:
				if(  (rxByte <= ASCII_z) && (rxByte >= ASCII_A) ){
					//the user entered a character

					if(curr_char < MAX_NUM_CHARS){
						xil_printf("%c", rxByte);
						text_entry[curr_char] = rxByte;
						curr_char++;
					}
				}
			break;
		}
		break;
		/* WMP_END */

		case UART_MODE_INTERACTIVE:
			switch(rxByte){
				case ASCII_r:
					//Reset statistics
					reset_station_statistics();
				break;
				case ASCII_1:
					if(access_point.AID != 0){
						uart_mode = UART_MODE_LTG_SIZE_CHANGE;
						curr_char = 0;
						curr_traffic_type = TRAFFIC_TYPE_PERIODIC_FIXED;

						if(ltg_sched_get_state(0,&ltg_type,&ltg_sched_state) == 0){
							//A scheduler of ID = 0 has been previously configured
							if(((ltg_sched_state_hdr*)ltg_sched_state)->enabled == 1){
								//This LTG is currently running. We'll turn it off.
								ltg_sched_stop(0);
								uart_mode = UART_MODE_INTERACTIVE;
								print_station_status(1);
								return;
							}
						}
						xil_printf("\n\n Configuring Local Traffic Generator (LTG) for AP\n");
						xil_printf("\nEnter packet payload size (in bytes): ");
					}
				break;
				case ASCII_Q:
					if(access_point.AID != 0){
						uart_mode = UART_MODE_LTG_SIZE_CHANGE;
						curr_char = 0;
						curr_traffic_type = TRAFFIC_TYPE_RAND_RAND;

						if(ltg_sched_get_state(0,&ltg_type,&ltg_sched_state) == 0){
							//A scheduler of ID = 0 has been previously configured
							if(((ltg_sched_state_hdr*)ltg_sched_state)->enabled == 1){
								//This LTG is currently running. We'll turn it off.
								ltg_sched_stop(0);
								uart_mode = UART_MODE_INTERACTIVE;
								print_station_status(1);
								return;
							}
						}
						xil_printf("\n\n Configuring Random Local Traffic Generator (LTG) for AP\n");
						xil_printf("\nEnter maximum payload size (in bytes): ");
					}
				break;
			}
		break;
		case UART_MODE_LTG_SIZE_CHANGE:
			switch(rxByte){
				case ASCII_CR:
					text_entry[curr_char] = 0;
					curr_char = 0;

					if(ltg_sched_get_callback_arg(0,&ltg_callback_arg) == 0){
						//This LTG has already been configured. We need to free the old callback argument so we can create a new one.
						ltg_sched_stop(0);
						wlan_free(ltg_callback_arg);
					}
					switch(curr_traffic_type){
							case TRAFFIC_TYPE_PERIODIC_FIXED:
								ltg_callback_arg = wlan_malloc(sizeof(ltg_pyld_fixed));
								if(ltg_callback_arg != NULL){
									((ltg_pyld_fixed*)ltg_callback_arg)->hdr.type = LTG_PYLD_TYPE_FIXED;
									((ltg_pyld_fixed*)ltg_callback_arg)->length = str2num(text_entry);

									//Note: This call to configure is incomplete. At this stage in the uart menu, the periodic_params argument hasn't been updated. This is
									//simply an artifact of the sequential nature of UART entry. We won't start the scheduler until we call configure again with that updated
									//entry.
									ltg_sched_configure(0, LTG_SCHED_TYPE_PERIODIC, &periodic_params, ltg_callback_arg, &ltg_cleanup);

									uart_mode = UART_MODE_LTG_INTERVAL_CHANGE;
									xil_printf("\nEnter packet Tx interval (in microseconds): ");
								} else {
									xil_printf("Error allocating memory for ltg_callback_arg\n");
									uart_mode = UART_MODE_INTERACTIVE;
									print_station_status(1);
								}

							break;
							case TRAFFIC_TYPE_RAND_RAND:
								ltg_callback_arg = wlan_malloc(sizeof(ltg_pyld_uniform_rand));
								if(ltg_callback_arg != NULL){
									((ltg_pyld_uniform_rand*)ltg_callback_arg)->hdr.type = LTG_PYLD_TYPE_UNIFORM_RAND;
									((ltg_pyld_uniform_rand*)ltg_callback_arg)->min_length = 0;
									((ltg_pyld_uniform_rand*)ltg_callback_arg)->max_length = str2num(text_entry);

									//Note: This call to configure is incomplete. At this stage in the uart menu, the periodic_params argument hasn't been updated. This is
									//simply an artifact of the sequential nature of UART entry. We won't start the scheduler until we call configure again with that updated
									//entry.
									ltg_sched_configure(0, LTG_SCHED_TYPE_UNIFORM_RAND, &rand_params, ltg_callback_arg, &ltg_cleanup);

									uart_mode = UART_MODE_LTG_INTERVAL_CHANGE;
									xil_printf("\nEnter maximum packet Tx interval (in microseconds): ");
								} else {
									xil_printf("Error allocating memory for ltg_callback_arg\n");
									uart_mode = UART_MODE_INTERACTIVE;
									print_station_status(1);
								}

							break;
						}

				break;
				case ASCII_DEL:
					if(curr_char > 0){
						curr_char--;
						xil_printf("\b \b");
					}
				break;
				default:
					if( (rxByte <= ASCII_9) && (rxByte >= ASCII_0) ){
						//the user entered a character
						if(curr_char < MAX_NUM_CHARS){
							xil_printf("%c", rxByte);
							text_entry[curr_char] = rxByte;
							curr_char++;
						}
					}
				break;
			}
		break;
		case UART_MODE_LTG_INTERVAL_CHANGE:
			switch(rxByte){
				case ASCII_CR:
					text_entry[curr_char] = 0;
					curr_char = 0;

					if(ltg_sched_get_callback_arg(0,&ltg_callback_arg) != 0){
						xil_printf("Error: expected to find an already configured LTG ID %d\n", 0);
						return;
					}

					switch(curr_traffic_type){
						case TRAFFIC_TYPE_PERIODIC_FIXED:
							if(ltg_callback_arg != NULL){
								periodic_params.interval_usec = str2num(text_entry);
								ltg_sched_configure(0, LTG_SCHED_TYPE_PERIODIC, &periodic_params, ltg_callback_arg, &ltg_cleanup);
								ltg_sched_start(0);
							} else {
								xil_printf("Error: ltg_callback_arg was NULL\n");
							}

						break;
						case TRAFFIC_TYPE_RAND_RAND:
							if(ltg_callback_arg != NULL){
								rand_params.min_interval = 0;
								rand_params.max_interval = str2num(text_entry);
								ltg_sched_configure(0, LTG_SCHED_TYPE_UNIFORM_RAND, &rand_params, ltg_callback_arg, &ltg_cleanup);
								ltg_sched_start(0);
							} else {
								xil_printf("Error: ltg_callback_arg was NULL\n");
							}

						break;
					}
					uart_mode = UART_MODE_INTERACTIVE;
					print_station_status(1);

				break;
				case ASCII_DEL:
					if(curr_char > 0){
						curr_char--;
						xil_printf("\b \b");
					}
				break;
				default:
					if( (rxByte <= ASCII_9) && (rxByte >= ASCII_0) ){
						//the user entered a character
						if(curr_char < MAX_NUM_CHARS){
							xil_printf("%c", rxByte);
							text_entry[curr_char] = rxByte;
							curr_char++;
						}
					}
				break;
			}
		break;
		case UART_MODE_AP_LIST:
			switch(rxByte){
				case ASCII_CR:

					numerical_entry[curr_decade] = 0;
					curr_decade = 0;

					ap_sel = str2num(numerical_entry);

					if( (ap_sel >= 0) && (ap_sel <= (num_ap_list-1))){

						if( ap_list[ap_sel].private == 0) {
							uart_mode = UART_MODE_MAIN;
							mac_param_chan = ap_list[ap_sel].chan;

							//Send a message to other processor to tell it to switch channels
							ipc_msg_to_low.msg_id = IPC_MBOX_MSG_ID(IPC_MBOX_CONFIG_RF_IFC);
							ipc_msg_to_low.num_payload_words = sizeof(ipc_config_rf_ifc)/sizeof(u32);
							ipc_msg_to_low.payload_ptr = &(ipc_msg_to_low_payload[0]);
							init_ipc_config(config_rf_ifc,ipc_msg_to_low_payload,ipc_config_rf_ifc);
							config_rf_ifc->channel = mac_param_chan;
							ipc_mailbox_write_msg(&ipc_msg_to_low);


							xil_printf("\nAttempting to join %s\n", ap_list[ap_sel].ssid);
							memcpy(access_point.addr, ap_list[ap_sel].bssid, 6);

							access_point_ssid = wlan_realloc(access_point_ssid, strlen(ap_list[ap_sel].ssid)+1);
							//xil_printf("allocated %d bytes in 0x%08x\n", strlen(ap_list[ap_sel].ssid), access_point_ssid);
							strcpy(access_point_ssid,ap_list[ap_sel].ssid);

							access_point_num_basic_rates = ap_list[ap_sel].num_basic_rates;
							memcpy(access_point_basic_rates, ap_list[ap_sel].basic_rates,access_point_num_basic_rates);

							association_state = 1;
							attempt_authentication();

						} else {
							xil_printf("\nInvalid selection, please choose an AP that is not private: ");
						}


					} else {

						xil_printf("\nInvalid selection, please choose a number between [0,%d]: ", num_ap_list-1);

					}



				break;
				case ASCII_DEL:
					if(curr_decade > 0){
						curr_decade--;
						xil_printf("\b \b");
					}

				break;
				default:
					if( (rxByte <= ASCII_9) && (rxByte >= ASCII_0) ){
						//the user entered a character

						if(curr_decade < MAX_NUM_AP_CHARS){
							xil_printf("%c", rxByte);
							numerical_entry[curr_decade] = rxByte;
							curr_decade++;
						}



					}

				break;

			}