Ejemplo n.º 1
0
/*
 * This function is used by client only. Sends the finmypeer sync frame to remote
 * server on diffrent channels and  waits for the response.
 */
int
rwl_find_remote_wifi_server(void *wl, char *id)
{
	dot11_action_wifi_vendor_specific_t *rem_wifi_send, *rem_wifi_recv;
	rem_ioctl_t *rem_ptr = &rem_cdc;
	/* This list is generated considering valid channel and if this 
	 * may requires updation or deletion. This needs to be identified.
	 * we have assumed that server band is not known and considered all band channels.
	 */
	int wifichannel[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
	11, 36, 40, 44, 48, 149, 153, 157, 161, 165};
	int i, error, schannel, channel_count;

	if ((rem_wifi_send = rwl_wifi_allocate_actionframe()) == NULL) {
		DPRINT_ERR(ERR, " rwl_find_remote_wifi_server : Failed to allocate \n");
		return FAIL;
	}
	if ((rem_wifi_recv = rwl_wifi_allocate_actionframe()) == NULL) {
		DPRINT_ERR(ERR, " rwl_find_remote_wifi_server : Failed to allocate\n");
		free(rem_wifi_send);
		return FAIL;
	}

	channel_count = sizeof(wifichannel) / sizeof(int);

	/* make dummy read to make sure we don't read the already queued
	 * actionframes against the cmd we issue
	 */
	rwl_wifi_purge_actionframes(wl);

	/* update the client sync specifier */
	rem_wifi_send->type = RWL_WIFI_FIND_MY_PEER;
	/* update the CDC flag to indicate it is handshake frame */
	rem_ptr->msg.cmd = 0;
	/* cmd =0 ,this will be ignored when server receive frame 
	 * with REMOTE_FINDSERVER_IOCTL flag
	 */
	rem_ptr->msg.len = RWL_WIFI_FRAG_DATA_SIZE;
	rem_ptr->msg.flags = REMOTE_FINDSERVER_IOCTL;
	rem_ptr->data_len = RWL_WIFI_FRAG_DATA_SIZE;

	memcpy((char*)&rem_wifi_send->data, (char*)rem_ptr, REMOTE_SIZE);
	/* copy server mac to which ref driver needs to send unicast action frame */
	memcpy(&rem_wifi_send->data[RWL_REF_MAC_ADDRESS_OFFSET], &id[0], ETHER_ADDR_LEN);

	/* Start with the channel in the list and keep changing till the server
	 * responds or channels list ends
	 */
	for (i = 0; i < channel_count; i++) {
		if ((error = rwl_wifi_config_channel(wl, WLC_SET_CHANNEL,
		&wifichannel[i])) < 0) {
			DPRINT_ERR(ERR, " Failed to set the specified channel %d\n",
			wifichannel[i]);
			break;
		}
		/* send channel detail of client to server */
		rem_wifi_send->data[RWL_WIFI_CLIENT_CHANNEL_OFFSET] = wifichannel[i];

		if ((error = rwl_var_setbuf(wl, RWL_WIFI_ACTION_CMD, rem_wifi_send,
		RWL_WIFI_ACTION_FRAME_SIZE)) < 0) {
			DPRINT_DBG(OUTPUT, "Failed to Send the Frame %d\n", error);
			break;
		}
		/* read the server response on the same channel */
		if ((error = remote_CDC_DATA_wifi_rx(wl, rem_wifi_recv)) < 0) {
			rwl_sleep(RWL_WIFI_RETRY_DELAY);
			continue;
		}
		/* Verify for the Type RWL_WIFI_FOUND_PEER */
		if (rem_wifi_recv->type == RWL_WIFI_FOUND_PEER) {
			if (rem_wifi_recv->data[RWL_WIFI_SERVER_CHANNEL_OFFSET] ==
				rem_wifi_recv->data[RWL_WIFI_CLIENT_CHANNEL_OFFSET]) {

				DPRINT_INFO(OUTPUT, "Server is on channel # %d\n",
				rem_wifi_recv->data[RWL_WIFI_SERVER_CHANNEL_OFFSET]);

				schannel = rem_wifi_recv->data[RWL_WIFI_SERVER_CHANNEL_OFFSET];
				/* Set the back to the channel on which REF was originally */
				if ((error = rwl_wifi_config_channel(wl,
				WLC_SET_CHANNEL, &schannel) < 0)) {
					DPRINT_ERR(ERR, "Failed to set the specified"
					"channel %d\n", schannel);
				} else {
					DPRINT_ERR(ERR, "REF now moved to the"
					"channel of server # %d\n", schannel);
				}
				/* we are done here, end the loop */
				break;
			} else {
				DPRINT_INFO(OUTPUT, "Server is operating on diffrent channel."
				"continue scanning\n");
			}
		}
		/* before chaning the channel of client and sending sync frame
		 * wait for while and send
		 */
		rwl_sleep(RWL_WIFI_RETRY_DELAY);
	}

	free(rem_wifi_send);
	free(rem_wifi_recv);
	return error;
}
Ejemplo n.º 2
0
/*
* This is the front end query function for Set Ioctls. This is used by clients
for executing Set Ioctls.
*/
int
rwl_setinformation_fe(void *wl, int cmd, void* buf,
	unsigned long *len, int debug, int rem_ioctl_select) {
	int error = 0;
	uint tx_len;
#if defined  (RWL_SERIAL) || (RWL_WIFI)
	rem_ioctl_t *rem_ptr = NULL;
#endif

#ifdef RWL_WIFI
	dot11_action_wifi_vendor_specific_t *list = NULL;
	char *cbuf, retry;
#endif

	UNUSED_PARAMETER(debug);

	switch (remote_type) {
		case REMOTE_SOCKET:
#ifdef RWL_SOCKET
			error = rwl_information_socket(wl, cmd, buf, len, len, rem_ioctl_select);
#endif
			break;
#ifdef RWL_SERIAL
		case REMOTE_SERIAL:
			if (remote_CDC_tx(wl, cmd, buf, *len, *len, rem_ioctl_select, debug) < 0) {
				DPRINT_ERR(ERR, "set_info_fe: Send command failed\n");
				return FAIL;
			}

			if ((rem_ptr = remote_CDC_rx_hdr(wl, debug)) == NULL) {
				DPRINT_ERR(ERR, "set_info_fe: Reading CDC header failed\n");
				return FAIL;
			}

			if (rem_ptr->msg.flags != REMOTE_REPLY)	{
				DPRINT_ERR(ERR, "set_info_fe: response format error.\n");
				return FAIL;
			}

			if (rem_ptr->msg.len > *len) {
				DPRINT_ERR(ERR, "set_info_fe: needed size (%d) greater than "
					   "actual size (%lu)\n", rem_ptr->msg.len, *len);
				return FAIL;
			}

			error = rem_ptr->msg.cmd;
			if (error != 0) {
				DPRINT_ERR(ERR, "set_info_fe: remote cdc header return "
					   "error code (%d)\n", error);
			}

			if (remote_CDC_rx(wl, rem_ptr, buf, rem_ptr->msg.len, debug) == -1) {
				DPRINT_ERR(ERR, "set_info_fe: fetching results failed\n");
				return FAIL;
			}

			if (rem_ptr->msg.flags & REMOTE_REPLY)
				error = rem_ptr->msg.cmd;
			break;
#endif /* RWL_SERIAL */
#ifdef RWL_DONGLE
		case REMOTE_DONGLE:
			if ((int)(*len) > SERVER_RESPONSE_MAX_BUF_LEN)
				*len = SERVER_RESPONSE_MAX_BUF_LEN;

			/* Actual buffer to be sent should be max 256 bytes as
			 *UART input buffer
			 * is 512 bytes
			 */
			tx_len = MIN(*len, 512);
			error = rwl_information_dongle(wl, cmd, buf, len, tx_len, rem_ioctl_select);
			break;
#endif //ifdef RWL_DONGLE
		case REMOTE_WIFI:
#ifdef RWL_WIFI
			if ((int)(*len) > SERVER_RESPONSE_MAX_BUF_LEN)
				*len = SERVER_RESPONSE_MAX_BUF_LEN;

			/* Actual buffer to be sent should be max 960 bytes
			 * as wifi max frame size if 960
			 * and actual data for any command will not exceed 960 bytes
			*/
			tx_len = MIN(*len, RWL_WIFI_FRAG_DATA_SIZE);

			if ((cbuf = (char*) malloc(tx_len)) == NULL) {
				DPRINT_ERR(ERR, "Malloc failed for set_info_fe character buf\n");
				return FAIL;
			}
			if ((list = (dot11_action_wifi_vendor_specific_t *)
					malloc(RWL_WIFI_ACTION_FRAME_SIZE)) == NULL) {
				free(cbuf);
				return FAIL;
			}

			if ((rem_ptr = (rem_ioctl_t *)malloc(sizeof(rem_ioctl_t))) == NULL) {
				free(list);
				free(cbuf);
				return FAIL;
			}

			memcpy(cbuf, (char*)buf, tx_len);

			for (retry = 0; retry < RWL_WIFI_RETRY; retry++) {

				rwl_wifi_purge_actionframes(wl);
				/* copy back the buffer to input buffer */
				memcpy((char*)buf, (char*)cbuf, tx_len);

				if (retry > 3)
					DPRINT_INFO(OUTPUT, "retry %d cmd %d\n", retry, cmd);

				if ((error = remote_CDC_wifi_tx(wl, cmd, buf, *len,
				                                tx_len, rem_ioctl_select) < 0)) {
					DPRINT_ERR(ERR, "ir_setinformation_fe: Send"
					"command failed\n");
					rwl_sleep(RWL_WIFI_RETRY_DELAY);
					continue;
				}

				if ((char*)buf != NULL) {
					/* In case cmd is findserver, response is not
					 * required from the server
					 */
					if (!strcmp((char*)buf, RWL_WIFI_FIND_SER_CMD)) {
						break;
					}
				}

				/* Read the CDC header and data of for the sent cmd
				 * resposne
				 */
				if ((error = remote_CDC_DATA_wifi_rx((void*)wl, list) < 0)) {
					DPRINT_ERR(ERR, "ir_setinformation_fe: failed to read"
						"the response\n");
					rwl_sleep(RWL_WIFI_RETRY_DELAY);
					continue;
				}

				memcpy((char*)rem_ptr,
				(char*)&list->data[RWL_WIFI_CDC_HEADER_OFFSET],
				REMOTE_SIZE);
				rwl_swap_header(rem_ptr, NETWORK_TO_HOST);

				memcpy((char*)buf, (char*)&list->data[REMOTE_SIZE],
				rem_ptr->msg.len);

				if (rem_ptr->msg.flags & REMOTE_REPLY) {
					error = rem_ptr->msg.cmd;
					break;
				} else {
					rwl_sleep(RWL_WIFI_RETRY_DELAY);
				}
			}
				free(rem_ptr);
				free(list);
			if (cbuf != NULL)
				free(cbuf);
			break;
#endif /* RWL_WIFI */
		default:
			DPRINT_ERR(ERR, "rwl_setinformation_fe: Unknown remote_type:%d\n",
			remote_type);
		break;
	}

	return error;
}
Ejemplo n.º 3
0
/* 
 * read data that has reached client in fragments. If the functtion is
 * called from rwl_shell_information_fe then the flag will be set to 1.
 * For shell response this function will output the response on the standard interface.
 * Response will be coming in out of order , this fucntion will make it inorder.
 * Duplicate action frames are ignored.
 */
int
remote_CDC_DATA_wifi_rx_frag(void *wl, rem_ioctl_t *rem_ptr, uint input_len,
void *input, bool shell)
{
	int error, totalfrag, seq_num, num_frags, remainingbytes;
	dot11_action_wifi_vendor_specific_t *rec_frame;
	uchar *input_buf = (uchar*)input;
	/* An array of pointers to each recieved frag */
	dot11_action_wifi_vendor_specific_t *master_list[RWL_DEFAULT_WIFI_FRAG_COUNT];

	UNUSED_PARAMETER(input_len);

	memset(master_list, 0, sizeof(master_list));
	/* in case of shell cmd's receive size is unknown */
	if (shell) {
		input_buf = (uchar*)g_rwl_buf_shell;
		memset(input_buf, 0, WL_MAX_BUF_LEN);
	}

	/* We don't yet know how many fragments we will need to read since the
	   length is contained in the first frgment of the message itself. Set
	   totalfrag to an arbitry large number and we will readjust it after we
	   successfully recieve the first frag.
	*/
	totalfrag = RWL_DEFAULT_WIFI_FRAG_COUNT;

	for (num_frags = 0; num_frags <= totalfrag; num_frags++) {
		if ((rec_frame = rwl_wifi_allocate_actionframe()) == NULL) {
			DPRINT_DBG(OUTPUT, "malloc failure\n");
			rwl_wifi_free_list(master_list);
			return (FAIL);
		}
		if ((error = remote_CDC_DATA_wifi_rx((void*)wl, rec_frame)) < 0) {
			free(rec_frame);
			rwl_wifi_free_list(master_list);
			return FAIL;
		}

		if (rec_frame->subtype >= RWL_DEFAULT_WIFI_FRAG_COUNT) {
			DPRINT_DBG(OUTPUT, " Read bogus subtype %d\n", rec_frame->subtype);
			free(rec_frame);
			continue;
		}
		/* Keep only originals and discard any dup frags */
		if (!master_list[rec_frame->subtype]) {
			master_list[rec_frame->subtype] = rec_frame;
		} else {
			num_frags--;
			free(rec_frame);
		}

		/* Look for first frag so we can accurately calculate totalfrag */
		if (rec_frame->subtype == RWL_WIFI_DEFAULT_SUBTYPE) {
			memcpy((char*)rem_ptr,
			(char*)&master_list[rec_frame->subtype]->
			data[RWL_WIFI_CDC_HEADER_OFFSET], REMOTE_SIZE);
			totalfrag = rem_ptr->msg.len / RWL_WIFI_FRAG_DATA_SIZE;
			remainingbytes = rem_ptr->msg.len % RWL_WIFI_FRAG_DATA_SIZE;
		}
	}

	/* All frags are now read and there are no dups. Check for missing frags */
	for (seq_num = 0; seq_num < totalfrag; seq_num++) {
		if (!master_list[seq_num]) {
			DPRINT_DBG(OUTPUT, "Missing frag number %d\n", seq_num);
			rwl_wifi_free_list(master_list);
			return (FAIL);
		}
	}
	/* 
	case 1: response in one frame i.e if (totalfrag==0)
	case 2: response in multiple frame ( multiple of RWL_WIFI_FRAG_DATA_SIZE)
	case 3: response in multiple frame and not in multiple of RWL_WIFI_FRAG_DATA_SIZE
	*/

	/* case 1: Check for the response in single frame */
	if (totalfrag == 0)
		memcpy((char*)&input_buf[0],
		(char*)&master_list[0]->data[REMOTE_SIZE], rem_ptr->msg.len);
	else /* case 2: Copy fragments into contiguous frame */
		memcpy((char*)&input_buf[0],
		(char*)&master_list[0]->data[REMOTE_SIZE], RWL_WIFI_FRAG_DATA_SIZE);

	/* 
	* If all the frames are recieved , copy them to a contigues buffer
	*/
	for (seq_num = 1; seq_num < totalfrag; seq_num++) {
		memcpy((char*)&input_buf[seq_num*RWL_WIFI_FRAG_DATA_SIZE],
		(char*)&master_list[seq_num]->data, RWL_WIFI_FRAG_DATA_SIZE);
	}

	/* case 3 : if response is in fragments and valid data in the last frame is less
	 * than RWL_WIFI_FRAG_DATA_SIZE
	 */
	if (remainingbytes && (totalfrag > 0))
		memcpy((char*)&input_buf[seq_num*RWL_WIFI_FRAG_DATA_SIZE],
		(char*)&master_list[seq_num]->data, remainingbytes);

	if (shell) {
		fputs((char*)input_buf, stdout);
	}

	rwl_wifi_free_list(master_list);
	return error;
}
Ejemplo n.º 4
0
/* Function: remote_rx_header
 * This function will receive the CDC header from client
 * for socket transport
 * It will receive the command or ioctl from dongle driver for
 * dongle UART serial transport and wifi transport.
 * Arguments: wl - handle to driver
 *          : Des - Socket Descriptor to pass in AcceptConnection
 *          : g_rwl_hndle - Return socket handle that is used for transmission
 *          :           and reception of data in case of socket
 *                        In case of serial, it is just a return value
 */
static int
remote_rx_header(void *wl, int trans_Des)
{
	UNUSED_PARAMETER(wl);
	UNUSED_PARAMETER(trans_Des);

#ifdef RWL_SOCKET
	{
		struct sockaddr_in ClientAddress;
		int SizeOfCliAdd = sizeof(ClientAddress);

		/* Get the socket handle g_rwl_hndle for transmission & reception */
		if ((g_rwl_hndle = rwl_acceptconnection(trans_Des,
		                                        (struct sockaddr *)&ClientAddress,
		                                        &SizeOfCliAdd)) == BCME_ERROR) {
			return BCME_ERROR;
		}

		/* Get CDC header in order to determine buffer requirements */
		if ((g_rem_ptr = remote_CDC_rx_hdr((void *)&g_rwl_hndle, 0)) == NULL) {
			DPRINT_DBG(OUTPUT, "\n Waiting for client to transmit command\n");
			return BCME_ERROR;
		}
	}
#endif /* RWL_SOCKET */

#ifdef RWL_DONGLE
	{
		void *pkt_ptr = NULL;
		int error;

		/* wl driver is polled after every 200 ms (POLLING_TIME) */
		rwl_sleep(POLLING_TIME);

		if ((error = rwl_var_getbuf(wl, cmdname, NULL, 0, &pkt_ptr)) < 0) {
			DPRINT_ERR(ERR, "No packet in wl driver\r\n");
			return BCME_ERROR;
		}

		DPRINT_DBG(OUTPUT, "Polling the wl driver, error status=%d\n", error);

		if ((*(int *)pkt_ptr) == 0) {
			DPRINT_DBG(ERR, "packet not received\n");
			return BCME_ERROR;
		}

		DPRINT_DBG(OUTPUT, "packet received\n");

		/* Extract CDC header in order to determine buffer requirements */
		memcpy(g_rem_pkt_ptr, pkt_ptr, sizeof(rem_packet_t));
		g_rem_ptr = &g_rem_pkt_ptr->rem_cdc;
	}
#endif /* RWL_DONGLE */

#ifdef RWL_SERIAL
	{
		if (g_rwl_hndle == -1) {
			DPRINT_ERR(ERR, "failed to open com port.\r\n");
			return BCME_ERROR;
		}

		if ((g_rem_ptr = remote_CDC_rx_hdr((void *)&g_rwl_hndle, 1)) == NULL) {
			DPRINT_DBG(OUTPUT, "\n Waiting for client to transmit command\n");
			return BCME_ERROR;
		}
	}
#endif  /* RWL_SERIAL */

#ifdef RWL_WIFI
	{
		/* Poll the driver for the valid action frame and update the CDC + data  */
		dot11_action_wifi_vendor_specific_t *list;

		if ((list = rwl_wifi_allocate_actionframe()) == NULL) {
			DPRINT_DBG(OUTPUT, "remote_rx_header: Failed to allocate frame \n");
			return BCME_ERROR;
		}

		if (remote_CDC_DATA_wifi_rx((void *)wl, list) < 0) {
			free(list);
			return BCME_ERROR;
		}

		/* copy the valid length of the data to the g_rem_pkt_ptr */
		memcpy(g_rem_pkt_ptr, &list->data[0], sizeof(rem_packet_t));
		g_rem_ptr = &g_rem_pkt_ptr->rem_cdc;
		free(list);
	}
#endif /* RWL_WIFI */

	rwl_swap_header(g_rem_ptr, NETWORK_TO_HOST);

	DPRINT_INFO(OUTPUT, "%d %d %d %d\r\n", g_rem_ptr->msg.cmd,
	g_rem_ptr->msg.len, g_rem_ptr->msg.flags, g_rem_ptr->data_len);

	return SUCCESS;

}