Пример #1
0
/* 
 * check for the channel of remote and respond if it matches with its current
 * channel. Once the server gets the handshake cmd, it will check the channel
 * number of the remote with its channel and if it matches , then it send out the
 * ack to the remote client. This fucntion is used only by the server.
 */
void
rwl_wifi_find_server_response(void *wl, dot11_action_wifi_vendor_specific_t *rec_frame)
{
	int error, send, server_channel;

	if (rec_frame->type == RWL_WIFI_FIND_MY_PEER) {

		rec_frame->type = RWL_WIFI_FOUND_PEER;
		/* read channel on of the SERVER */
		rwl_wifi_config_channel(wl, WLC_GET_CHANNEL, &server_channel);
		/* overlapping channel not supported, 
		so server will only respond to client on the channel of the client
		*/
		if (rec_frame->data[RWL_WIFI_CLIENT_CHANNEL_OFFSET] == server_channel) {
			/* send the response by updating server channel in the frame */
			rec_frame->data[RWL_WIFI_SERVER_CHANNEL_OFFSET] = server_channel;
			/* change the TYPE feild for giving the ACK */
			for (send = 0; send < RWL_WIFI_SEND; send++) {
				if ((error = rwl_var_setbuf(wl, RWL_WIFI_ACTION_CMD, rec_frame,
					RWL_WIFI_ACTION_FRAME_SIZE)) < 0) {
					DPRINT_ERR(ERR, "rwl_wifi_find_server_response: Failed"
					"to Send the Frame %d\n", error);
					break;
				}
				rwl_sleep(RWL_WIFI_SEND_DELAY);
			}
		}
	}
	return;
}
Пример #2
0
static int
remote_CDC_dongle_tx(void *wl, uint cmd, uchar *buf, uint buf_len, uint data_len, uint flags)
{
	int error;
	rem_ioctl_t resp_rem_cdc;

	if (flags & REMOTE_SET_IOCTL) {
		uchar* rem_buf_ptr;
		/* for set commands message length and data length should be set to zero
		 * unlike Get Ioctl which will have valid data and message length
		 */
		resp_rem_cdc.msg.len = 0;
		resp_rem_cdc.data_len = 0;
		resp_rem_cdc.msg.cmd = cmd;
		resp_rem_cdc.msg.flags = REMOTE_REPLY;

		DPRINT_INFO(OUTPUT, "Set:Resp packet:%d %d %d %d\n", resp_rem_cdc.msg.cmd,
		resp_rem_cdc.msg.len, resp_rem_cdc.msg.flags, resp_rem_cdc.data_len);

		if ((rem_buf_ptr = (uchar*)malloc(DONGLE_TX_FRAME_SIZE + REMOTE_SIZE)) == NULL) {
			DPRINT_ERR(ERR, "malloc failed for remote_CDC_dongle_tx\n");
			return BCME_ERROR;
		}

		/* Send reply to client here */
		memcpy(rem_buf_ptr, (char*)(&resp_rem_cdc), REMOTE_SIZE);
		if ((error = rwl_var_setbuf((void*)wl, cmdname, rem_buf_ptr,
		                 DONGLE_TX_FRAME_SIZE + REMOTE_SIZE)) < 0) {
			DPRINT_ERR(ERR, "unable to send SET results to driver=%d\n", error);
		} else
			DPRINT_INFO(OUTPUT, "Packet sent to wl driver, error=%d\n", error);

		if (rem_buf_ptr)
			free(rem_buf_ptr);

	} else { /* GET_IOCTL */
		resp_rem_cdc.msg.cmd = cmd;
		resp_rem_cdc.msg.len = buf_len;
		resp_rem_cdc.msg.flags = flags;
		resp_rem_cdc.data_len = data_len;
		if ((error = rwl_serial_fragmented_tx(wl, &resp_rem_cdc, buf, cmd)) < 0)
			DPRINT_ERR(ERR, "wl_server_serial: Return error code failed\n");
	}
	return error;
}
Пример #3
0
int
remote_CDC_tx(void *wl, uint cmd, uchar *buf, uint buf_len, uint data_len, uint flags, int debug)
{
#if defined(RWL_SOCKET) || defined(RWL_SERIAL)
	unsigned long numwritten = 0;
#endif
	rem_ioctl_t *rem_ptr = &rem_cdc;
#ifdef RWL_WIFI
	int error;
	uint totalframes, tx_count;
	dot11_action_wifi_vendor_specific_t *rem_wifi_send;
#endif
	UNUSED_PARAMETER(debug);

	rem_ptr->msg.cmd = cmd;
	rem_ptr->msg.len = buf_len;
	rem_ptr->msg.flags = flags;
	rem_ptr->data_len = data_len;

	if (data_len > buf_len) {
		DPRINT_ERR(ERR, "remote_CDC_tx: data_len (%d) > buf_len (%d)\n", data_len, buf_len);
		return (FAIL);
	}
#ifdef RWL_SERIAL
	if (remote_type == REMOTE_SERIAL) {
		int ret;
		/* Send CDC header first */
		if ((ret = rwl_write_serial_port(wl, (char *)rem_ptr,
			REMOTE_SIZE, &numwritten)) == -1) {
			DPRINT_ERR(ERR, "CDC_Tx: Data: Write failed \n");
			return (FAIL);
		}
		numwritten = ret;

		/* Send data second */
		if ((ret = rwl_write_serial_port(wl, (char*)buf,
			data_len, &numwritten)) == -1) {
			DPRINT_ERR(ERR, "CDC_Tx: Data: Write failed \n");
			return (FAIL);
		}
		numwritten = ret;

		return (buf_len);
	}
#endif /* RWL_SERIAL */
#ifdef RWL_DONGLE
	if (remote_type == REMOTE_DONGLE) {
		return (remote_CDC_tx_dongle(wl, rem_ptr, buf));
	}
#endif /* RWL_DONGLE */
#ifdef RWL_SOCKET
	if (remote_type == REMOTE_SOCKET) {
		int ret;

		/* Send CDC header first */
		if ((ret = rwl_send_to_streamsocket(*(int*)wl, (char *)rem_ptr,
			REMOTE_SIZE, 0)) == -1) {
			DPRINT_ERR(ERR, "CDC_Tx: Data: Write failed \n");
			return (FAIL);
		}
		numwritten = ret;

		/* Send data second */
		if ((ret = rwl_send_to_streamsocket(*(int*)wl, (const char*)buf,
			data_len, 0)) == -1) {
			DPRINT_ERR(ERR, "CDC_Tx: Data: Write failed \n");
			return (FAIL);
		}
		numwritten = ret;

		return (buf_len);
	}
#endif /* RWL_SOCKET */

#ifdef RWL_WIFI
	/* 
	 * wifi action frame is formed based on the CDC header and data.
	 * If the data is bigger than RWL_WIFI_FRAG_DATA_SIZE size, number of fragments are
	 * calculated and sent
	 * similar number of action frames with subtype incremented with sequence.
	 * Frames are sent with delay to avoid the outof order at receving end
	 */
	if (remote_type == REMOTE_WIFI) {
		if ((rem_wifi_send = rwl_wifi_allocate_actionframe()) == NULL) {
			DPRINT_ERR(ERR, "remote_CDC_tx: Failed to get allocated buffer\n");
			return (FAIL);
		}

		if (rem_ptr->msg.len > RWL_WIFI_FRAG_DATA_SIZE) {
			/* response needs to be sent in fragments */
			totalframes = rem_ptr->msg.len / RWL_WIFI_FRAG_DATA_SIZE;
			memcpy((char*)&rem_wifi_send->data[RWL_WIFI_CDC_HEADER_OFFSET],
			(char*)rem_ptr,	REMOTE_SIZE);
			memcpy((char*)&rem_wifi_send->data[REMOTE_SIZE], &buf[0],
			RWL_WIFI_FRAG_DATA_SIZE);
			/* update type feild to inform receiver it's frammeted response frame
			*/
			rem_wifi_send->type = RWL_ACTION_WIFI_FRAG_TYPE;
			rem_wifi_send->subtype = RWL_WIFI_DEFAULT_SUBTYPE;

			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);
				free(rem_wifi_send);
				return error;
			}
			/* Send remaining bytes in fragments */
			for (tx_count = 1; tx_count < totalframes; tx_count++) {
				rem_wifi_send->type = RWL_ACTION_WIFI_FRAG_TYPE;
				rem_wifi_send->subtype = tx_count;
				/* First frame onwards , buf contains only data */
				memcpy((char*)&rem_wifi_send->data,
				&buf[tx_count*RWL_WIFI_FRAG_DATA_SIZE], RWL_WIFI_FRAG_DATA_SIZE);
				if ((error = rwl_var_setbuf(wl, RWL_WIFI_ACTION_CMD,
					rem_wifi_send, RWL_WIFI_ACTION_FRAME_SIZE)) < 0) {
					free(rem_wifi_send);
					return error;
				}
				rwl_sleep(RWL_WIFI_SEND_DELAY);
			}

			/* Check for remaing bytes to send */
			if ((totalframes*RWL_WIFI_FRAG_DATA_SIZE) != rem_ptr->msg.len) {
				rem_wifi_send->type = RWL_ACTION_WIFI_FRAG_TYPE;
				rem_wifi_send->subtype = tx_count;
				memcpy((char*)&rem_wifi_send->data,
				&buf[tx_count*RWL_WIFI_FRAG_DATA_SIZE],
				(rem_ptr->msg.len - (tx_count*RWL_WIFI_FRAG_DATA_SIZE)));
				if ((error = rwl_var_setbuf(wl, RWL_WIFI_ACTION_CMD, rem_wifi_send,
				RWL_WIFI_ACTION_FRAME_SIZE)) < 0) {
					free(rem_wifi_send);
					return error;
				}
			}
		} else {
			/* response fits to single frame */
			memcpy((char*)&rem_wifi_send->data[RWL_WIFI_CDC_HEADER_OFFSET],
			(char*)rem_ptr,	REMOTE_SIZE);
			/* when data_len is 0 , buf will be NULL */
			if (buf != NULL) {
				memcpy((char*)&rem_wifi_send->data[REMOTE_SIZE],
				&buf[0], data_len);
			}
			error = rwl_var_setbuf(wl, RWL_WIFI_ACTION_CMD, rem_wifi_send,
			RWL_WIFI_ACTION_FRAME_SIZE);
			free(rem_wifi_send);
			return error;
		}
	}
#endif /* RWL_WIFI */
	return (0);
}
Пример #4
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;
}
Пример #5
0
/*
 * Send the valid action frame (CDC+DATA) through the REF driver interface.
 * if the CMD is "findserver" then "findmypeer" frames are sent on the diffrent
 * channels to reconnect
 * to with server. Other wl cmd takes the normal path.
 * parameter 3 , i.e. buf contains the cmd line arguments  and buf_len is the actual
 * length of the buf. data_len is the length of the actual data to be sent to remote server.
 */
int
remote_CDC_wifi_tx(void *wl, uint cmd, uchar *buf, uint buf_len, uint data_len, uint flags)
{
	rem_ioctl_t *rem_ptr = &rem_cdc;
	int error, read_try;
	dot11_action_wifi_vendor_specific_t *rem_wifi_send;

	/* prepare CDC header */
	rem_ptr->msg.cmd = cmd;
	rem_ptr->msg.len = buf_len;
	rem_ptr->msg.flags = flags;
	rem_ptr->data_len = data_len;

	if ((data_len > buf_len)) {
		DPRINT_ERR(ERR, "remote_CDC_wifi_tx: data_len (%d) > buf_len (%d)\n",
		data_len, buf_len);
		return (FAIL);
	}
	/* client will not send data greater than RWL_WIFI_FRAG_DATA_SIZE to server,
	 * this condition should not be hit on client side, when sending the cmd
	 * to remote server
	 */
	if (rem_ptr->data_len > RWL_WIFI_FRAG_DATA_SIZE)
		DPRINT_DBG(OUTPUT, "data size exceeds data_len %d\n", rem_ptr->msg.len);

	if ((buf != NULL) && (strlen((char*)buf) >= (sizeof(RWL_WIFI_FIND_SER_CMD)-1)) &&
		(!strcmp((char*)buf, RWL_WIFI_FIND_SER_CMD))) {
		/* This is special case for wifi, when user wants to findserver,
		* client has to execute it locally.Find the channel on the on
		* which DUT is operating and sync up with specified MAC address,
		* retry if fails to find the server
		*/
		for (read_try = 0; read_try < RWL_WIFI_RETRY; read_try++) {
			if (((error = rwl_find_remote_wifi_server(wl,
			&g_rwl_buf_mac[0])) == 0)) {
				break;
			}
		}
		return error;
	}

	if ((rem_wifi_send = rwl_wifi_allocate_actionframe()) == NULL) {
		DPRINT_ERR(ERR, "remote_CDC_wifi_tx: Failed to allocate memory\n");
		return (FAIL);
	}
	/* only data length needs to be sent to remote server using this function 
	* This function is only meant for client to send data to server
	* Copy the CDC header and data to action frame data feild
	* Now we have encapsulated the CDC header and data completely to in the
	* action frame.
	*/
	memcpy(&rem_wifi_send->data[RWL_WIFI_CDC_HEADER_OFFSET], (char*)rem_ptr, REMOTE_SIZE);
	if (buf != NULL) {
		memcpy(&rem_wifi_send->data[REMOTE_SIZE], buf, data_len);
	}

	/* Send the action frame to remote server using the  rwl_var_setbuf fucntion,
	 * which will use the local driver interface to send this frame on the air
	 */
	if ((error = rwl_var_setbuf(wl, RWL_WIFI_ACTION_CMD, rem_wifi_send,
	RWL_WIFI_ACTION_FRAME_SIZE)) < 0) {
		DPRINT_ERR(ERR, "Unable to read the action frame %d error\n", error);
	}
	free(rem_wifi_send);
	return error;
}
Пример #6
0
/* Main server module common for all transports
 * This module will do the initial transport setups.
 * Then it receives the command from client in CDC format
 * and transmits the response back to the client.
 * In the case of socket, it receives the command from the client
 * and sends the response directly to the client via TCP socket.
 *
 * In the case of serial & wifi , it receives the command from the driver
 * and sends the response to the driver.
 */
int
remote_server_exec(int argc, char **argv, void *wl)
{
	int err;
	int transport_descriptor;
	char *async_cmd_flag = NULL;
	int skip;
	int download_flag = 0;
#if defined(LINUX) || defined(vxworks) || defined(OLYMPIC_RWL)
	char old_intf_name[IFNAMSIZ];
#endif
#ifdef WIN32
	char shell_fname[MAX_SHELL_FILE_LENGTH];
	DWORD dwlen;
#endif
#ifdef RWL_DONGLE
	int uart_enable = 1;
	/* To set dongle flag when dongle server starts */
	if ((err = rwl_var_setbuf(wl, dongleset, &uart_enable,
		sizeof(int))) < 0) {
			DPRINT_INFO(OUTPUT, "Unable to send to wl driver,error=%d\n", err);
	}
#endif
	if (rwl_iovar_check (wl) < 0) {
		DPRINT_ERR(ERR, "wl_server: RWL_WIFI/RWL_DONGLE not defined ");
		DPRINT_ERR(ERR, "Or In-Dongle mode enabled\n");
		exit(0);
	}
	/* Initialise for all the transports - socket, serial, and wifi
	 * In Socket transport, main socket handler will be returned.
	 */
	if ((transport_descriptor = rwl_transport_setup(argc, argv)) < 0)
		return BCME_ERROR;

#ifdef RWL_WIFI
	remote_wifi_ser_init_cmds(wl);
#endif
	/* Create a directory /tmp/RWL for the shell response files */
	if (rwl_create_dir() < 0)
		return BCME_ERROR;


#ifdef RWLASD
	/* DUT initialization function */
	wfa_dut_init(&trafficBuf, &respBuf, &parmsVal, &xcCmdBuf, &toutvalp);
#endif

#if defined(LINUX) || defined(vxworks)
	/* Copy old interface name to restore it */
	store_old_interface(wl, old_intf_name);
#endif /* defined(LINUX) || defined(vxworks) */

	while (1) {
		uchar *buf_ptr = NULL;
#ifdef VISTA_SERVER
		int index;
		char *vista_buf[MAX_VISTA_ARGC];
#endif
#ifdef RWL_SERIAL
		g_rwl_hndle = transport_descriptor;
#else
		g_rwl_hndle = -1;
#endif
#ifdef RWL_DONGLE
		if (set_ctrlc) {
			uart_enable = 0;
			if ((err = rwl_var_setbuf(wl, dongleset, &uart_enable,
				sizeof(int))) < 0) {
				DPRINT_INFO(OUTPUT, "Unable to send to wl driver,error=%d\n", err);
			}
			set_ctrlc = 0;
			exit(0);
		}
#endif /* RWL_DONGLE */

		/* Receive the CDC header */
		if ((remote_rx_header(wl, transport_descriptor)) == BCME_ERROR) {
			DPRINT_DBG(OUTPUT, "\n Waiting for client to transmit command\n");
			continue;
		}

		DPRINT_INFO(OUTPUT, "REC : cmd %d\t msg len %d  msg flag %d\t msg status %d\n",
		            g_rem_ptr->msg.cmd, g_rem_ptr->msg.len,
		            g_rem_ptr->msg.flags, g_rem_ptr->msg.status);

#ifdef RWL_WIFI
		/* send the response to remote if it is findserver cmd, this is specific to wifi */
		if (g_rem_ptr->msg.flags & REMOTE_FINDSERVER_IOCTL) {
			remote_wifi_response(wl);
			continue;
		}
#endif /* RWL_WIFI */

		/*
		 * Allocate buffer only if there is a response message expected.
		 * Some commands such as up/down do not output anything.
		 */
		if (g_rem_ptr->msg.len) {
			if ((buf_ptr = malloc(g_rem_ptr->msg.len)) == NULL) {
				DPRINT_ERR(ERR, "malloc of %d bytes failed\n", g_rem_ptr->msg.len);
				continue;
			}
		}

		/* Receive the data */
		if ((err = remote_rx_data(buf_ptr)) == BCME_ERROR) {
			if (buf_ptr)
				free(buf_ptr);
			continue;
		}

		/* Process RWL negotiate commands */
		if (g_rem_ptr->msg.flags & REMOTE_NEGOTIATE_CMD) {
			if (g_rem_ptr->msg.cmd == NEGOTIATE_GET_OS) {
				if (g_rem_ptr->msg.len >= sizeof(int)) {
#if defined(LINUX)
					*(int*)buf_ptr = LINUX_OS;
#elif defined(VISTA_SERVER)
					*(int*)buf_ptr = WINVISTA_OS;
#elif defined(WIN32)
					*(int*)buf_ptr = WIN32_OS;
#elif defined(MACOSX)
					*(int*)buf_ptr = MAC_OSX;
#else
					*(int*)buf_ptr = UNKNOWN_OS;
#endif
					g_rem_ptr->msg.len = sizeof(int);

					DPRINT_INFO(OUTPUT, "RESP : os type %d\n", *(int*)buf_ptr);
					if (remote_tx_response(wl, buf_ptr, 0) < 0)
						DPRINT_ERR(ERR, "\nReturn results failed\n");
				}
			}
#ifdef RWL_SOCKET
			close_sock_handle(g_rwl_hndle);
#endif /* RWL_SOCKET */
			if (buf_ptr)
				free(buf_ptr);
			continue;
		}

		/* Process command */
		if (g_rem_ptr->msg.flags & REMOTE_SHELL_CMD) {
			/* Get the response length first and get the response buffer in case of
			 * synchronous shell commands and the buf_ptr will have the response file
			 * name. In case of asynchronous shell commands, buf_ptr
			 * will be get updated by the remote_shell_execute function.
			 */
			need_speedy_response = 1;
#ifndef WIN32
			if (buf_ptr) {
				async_cmd_flag = strstr((char*)buf_ptr, "%");
			}
			if ((err = remote_shell_execute((char*)buf_ptr, wl)) > 0) {
				if (async_cmd_flag)
					g_rem_ptr->msg.len = err;
			}
			/* Sync shell command: No need to send response from here */
			else {
#ifdef RWL_SOCKET
				/* Transmitted to client. Then close the handle &
				 * get the new handle for next transmission & reception.
				 */
				close_sock_handle(g_rwl_hndle);
#endif /* RWL_SOCKET */
				continue;
			}
#else
			if ((err = remote_shell_execute((char*)buf_ptr, wl)) != SUCCESS) {
				DPRINT_ERR(ERR, "Error in executing shell command\n");
				if (buf_ptr)
					free(buf_ptr);
#ifdef RWL_SOCKET
				/* Transmitted to client. Then close the handle &
				 * get the new handle for next transmission & reception.
				 */
				close_sock_handle(g_rwl_hndle);
#endif /* RWL_SOCKET */
				continue;
			}
			/* Get the response from the temporary file */
			if ((err = remote_shell_get_resp(shell_fname, wl)) != SUCCESS) {
				DPRINT_ERR(ERR, "Error in executing shell command\n");
			}
			if (buf_ptr)
				free(buf_ptr);
#ifdef RWL_SOCKET
			/* Transmitted to client. Then close the handle &
			 * get the new handle for next transmission & reception.
			 */
			close_sock_handle(g_rwl_hndle);
#endif /* RWL_SOCKET */
			continue;
#endif	/* WIN32 */
		} /* REMOTE_SHELL_CMD */

#ifdef RWLASD
		if (g_rem_ptr->msg.flags & REMOTE_ASD_CMD) {
			if ((err = remote_asd_exec(buf_ptr, (int *)&g_rem_ptr->msg.len)) < 0) {
				DPRINT_ERR(ERR, "Error in executing asd command\n");
			}
		} /* REMOTE_ASD_CMD */
#endif

/*
 * added to take care of OID base problem for cross OS RWL cleint server
 * In case of LX Server and WIN32 client OID base need to be removed
 * In case of WIN32 server and LX client OID base need to be added
 */
		if (!(g_rem_ptr->msg.flags & REMOTE_ASD_CMD)) {
#if defined(LINUX) || defined(vxworks)
		if (g_rem_ptr->msg.cmd > MAX_IOVAR)
			g_rem_ptr->msg.cmd -= WL_OID_BASE;
#endif
#if defined(WIN32)
		if (g_rem_ptr->msg.cmd < MAX_IOVAR)
			g_rem_ptr->msg.cmd += WL_OID_BASE;
#endif
		}
#ifdef VISTA_SERVER
		if (g_rem_ptr->msg.flags & REMOTE_VISTA_CMD) {
			vista_buf[0] = strtok(buf_ptr, " \t\n");
			for (index = 1; (vista_buf[index] = strtok(NULL, " \t\n")) != NULL;
				index++);
			if ((err = remote_vista_exec(wl, vista_buf)) < 0) {
				DPRINT_ERR(ERR, "Error in executing vista command\n");
			}
			memcpy(buf_ptr, vista_buf[0], strlen(vista_buf[0]));
			g_rem_ptr->msg.len = strlen(vista_buf[0]);
		} /* REMOTE_VISTA_CMD */
#endif /* VISTA_SERVER */

#ifndef OLYMPIC_RWL
#if defined(LINUX) || defined(vxworks)
#ifndef RWL_DONGLE
		if (g_rem_ptr->msg.flags & REMOTE_GET_IOCTL ||
			g_rem_ptr->msg.flags & REMOTE_SET_IOCTL) {
			if (strlen(g_rem_ptr->intf_name) != 0) {
#if defined(LINUX)
				struct ifreq ifr;
				/* validate the interface */
				memset(&ifr, 0, sizeof(ifr));
				if (g_rem_ptr->intf_name)
					strncpy(ifr.ifr_name, g_rem_ptr->intf_name, IFNAMSIZ);

				if (wl_check((void *)&ifr)) {
					DPRINT_ERR(ERR, "%s: wl driver adapter not found\n",
						g_rem_ptr->intf_name);
					/* Signal end of command output */
					g_rem_ptr->msg.len = 0;
					remote_tx_response(wl, NULL, BCME_NODEVICE);
					if (buf_ptr)
						free(buf_ptr);
#ifdef RWL_SOCKET
					close_sock_handle(g_rwl_hndle);
#endif
					continue;
				}
#endif /* LINUX */
#if defined(vxworks)
				if (wl_check((void *)g_rem_ptr->intf_name)) {
					DPRINT_ERR(ERR, "%s: wl driver adapter not found\n",
						g_rem_ptr->intf_name);
					/* Signal end of command output */
					g_rem_ptr->msg.len = 0;
					remote_tx_response(wl, NULL, BCME_NODEVICE);
					if (buf_ptr)
						free(buf_ptr);
#ifdef RWL_SOCKET
					close_sock_handle(g_rwl_hndle);
#endif
					continue;
				}
#endif /* vxworks */

				if (set_interface(wl, g_rem_ptr->intf_name) == BCME_OK)
					DPRINT_DBG(OUTPUT, "\n %s Interface will be used \n",
						(char *)wl);
			}
		}
#endif /* ifndef RWL_DONGLE */
#endif /* defined(LINUX) || defined(vxworks) */
#endif /* ifndef OLYMPIC_RWL */
		if (g_rem_ptr->msg.flags & REMOTE_SET_IOCTL ||
			g_rem_ptr->msg.flags & RDHD_SET_IOCTL) {
#ifdef WIN32
#if defined (RWL_DONGLE) || defined (RWL_WIFI)
			/* For commands with msg length as zero initialize the buffer to null */
			if (g_rem_ptr->msg.len == 0)
				buf_ptr = NULL;
#endif
#else
			if (g_rem_ptr->msg.len == 0)
				buf_ptr = NULL;
#endif /* WIN32 */

#if defined(LINUX) || defined(TARGETOS_symbian) || defined(TARGETOS_nucleus) || defined(MACOSX) || defined(TARGET_wiced)
#ifdef OLYMPIC_RWL
			set_interface(wl, old_intf_name);
#endif
#if defined( TARGET_wiced )
            set_interface(wl, g_rem_ptr->intf_name);
#endif
			if (g_rem_ptr->msg.flags & REMOTE_SET_IOCTL) {
				if (g_rem_ptr->msg.cmd == WLC_SET_VAR && buf_ptr &&
				    !strncmp((const char *)buf_ptr,
					     "init", g_rem_ptr->msg.len)) {
					DPRINT_INFO(OUTPUT, "REC : init command\n");
					err = 0;
				} else if (g_rem_ptr->msg.cmd == WLC_SET_VAR && buf_ptr &&
				   !strncmp((const char *)buf_ptr,
					    "download", g_rem_ptr->msg.len)) {
					DPRINT_INFO(OUTPUT, "REC : download command\n");
					download_flag =  download_flag? 0: 1;
					if (download_flag) {
						DPRINT_INFO(OUTPUT, "download started\n");
						start_download( );
					} else {
						DPRINT_INFO(OUTPUT, "download completed\n");
						finish_download( );
					}
					err = 0;
				} else if (g_rem_ptr->msg.cmd == WLC_SET_VAR && buf_ptr &&
				   !strncmp((const char *)buf_ptr,
					    "membytes", g_rem_ptr->msg.len)) {
					DPRINT_INFO(OUTPUT, "REC : membytes command\n");
					skip = strlen("membytes ");
					uint32_t address = *((uint32_t*)(buf_ptr + skip));
					skip += sizeof(uint32_t);
                    uint32_t len = *((uint32_t*)(buf_ptr + skip));
                    skip += sizeof(uint32_t);
                    if ( len != g_rem_ptr->msg.len - skip )
                    {
                        DPRINT_ERR(ERR, "Length does not match\n");
                    }
					membytes_write( address, buf_ptr + skip, g_rem_ptr->msg.len - skip );
					err = 0;
				} else {
					err = wl_ioctl(wl, g_rem_ptr->msg.cmd,
					       (void *)buf_ptr, g_rem_ptr->msg.len, TRUE);
					DPRINT_INFO(OUTPUT, "SEND : cmd %d\t msg len %d\n",
					    g_rem_ptr->msg.cmd, g_rem_ptr->msg.len);
					DPRINT_INFO(OUTPUT, "error code: %d\n", err);
				}
			}
#if defined(LINUX)
			if (err == IOCTL_ERROR) {
				DPRINT_ERR(ERR, "Error in executing wl_ioctl\n");
				DPRINT_ERR(ERR, "Setting Default Interface1 \n");
				set_interface(wl, old_intf_name);
			}

			if (g_rem_ptr->msg.flags & RDHD_SET_IOCTL) {
				err = dhd_ioctl(wl, g_rem_ptr->msg.cmd,
				(void *)buf_ptr, g_rem_ptr->msg.len, TRUE);
			}
#endif /* LINUX */

#elif vxworks
			if ((err = wl_ioctl_vx(wl, g_rem_ptr->msg.cmd, (void *)buf_ptr,
				g_rem_ptr->msg.len)) != 0) {
				DPRINT_ERR(ERR, "Error in executing wl_ioctl_vx\n");
			}

			if (err == IOCTL_ERROR) {
				DPRINT_ERR(ERR, "Error in executing wl_ioctl\n");
				DPRINT_ERR(ERR, "Setting Default Interface \n");
				set_interface(wl, old_intf_name);
			}
#elif WIN32
			dwlen = g_rem_ptr->msg.len;
			if (g_rem_ptr->msg.flags & RDHD_SET_IOCTL) {
				g_rem_ptr->msg.cmd = g_rem_ptr->msg.cmd
					- WL_OID_BASE + OID_DHD_IOCTLS;
			}

			err = (int)ir_setinformation(wl, g_rem_ptr->msg.cmd,
			                       buf_ptr, &dwlen);
#endif /* LINUX TARGETOS_symbian MACOSX */
			g_rem_ptr->msg.flags = REMOTE_SET_IOCTL;

		} /* RDHD/REMOTE_SET_IOCTL */

		if (g_rem_ptr->msg.flags & REMOTE_GET_IOCTL ||
			g_rem_ptr->msg.flags & RDHD_GET_IOCTL) {
#if defined(LINUX) || defined(TARGETOS_symbian) || defined(TARGETOS_nucleus) || defined(MACOSX) || defined(TARGET_wiced)
			if (g_rem_ptr->msg.cmd == WLC_GET_VAR && buf_ptr &&
				strncmp((const char *)buf_ptr, "exit", g_rem_ptr->msg.len) == 0) {
					/* exit command from remote client terminates server */
					free(buf_ptr);
					break;
			}
#if defined( TARGET_wiced )
            set_interface(wl, g_rem_ptr->intf_name);
#endif
			if (g_rem_ptr->msg.flags & REMOTE_GET_IOCTL)
				err = wl_ioctl(wl, g_rem_ptr->msg.cmd, (void *)buf_ptr,
					g_rem_ptr->msg.len, FALSE);
#if defined (LINUX)
			if (err == IOCTL_ERROR) {
				DPRINT_ERR(ERR, "REMOTE_GET_IOCTL::Error in executing wl_ioctl\n");
				DPRINT_ERR(ERR, "Setting Default Interface \n");
				set_interface(wl, old_intf_name);
			}

			if (g_rem_ptr->msg.flags & RDHD_GET_IOCTL)
				err = dhd_ioctl(wl, g_rem_ptr->msg.cmd, (void *)buf_ptr,
					g_rem_ptr->msg.len, FALSE);
#endif /* LINUX */
#elif vxworks
			if ((err = wl_ioctl_vx(wl, g_rem_ptr->msg.cmd, (void *)buf_ptr,
				g_rem_ptr->msg.len)) != 0) {
				DPRINT_ERR(ERR, "Error in executing wl_ioctl_vx\n");
			}

			if (err == IOCTL_ERROR) {
				DPRINT_ERR(ERR, "Error in executing wl_ioctl_vx\n");
				DPRINT_ERR(ERR, "Setting Default Interface \n");
				set_interface(wl, old_intf_name);
			}
#elif WIN32
			if (g_rem_ptr->msg.cmd == (WL_OID_BASE + WLC_GET_VAR) &&
				strncmp(buf_ptr, "exit", g_rem_ptr->msg.len) == 0) {
					/* exit command from remote client terminates server */
					if (buf_ptr) {
						free(buf_ptr);
					}
					break;
			}

			dwlen = g_rem_ptr->msg.len;
			if (g_rem_ptr->msg.flags & RDHD_GET_IOCTL) {
				g_rem_ptr->msg.cmd = g_rem_ptr->msg.cmd -
					WL_OID_BASE + OID_DHD_IOCTLS;
				}

			err = (int)ir_queryinformation(wl,
			g_rem_ptr->msg.cmd, buf_ptr, &dwlen);

#endif /* defined(LINUX) || defined(TARGETOS_symbian) || defined(TARGETOS_nucleus)  || defined(TARGET_wiced) */
			g_rem_ptr->msg.flags = REMOTE_GET_IOCTL;
		} /* REMOTE_GET_IOCTL */
		DPRINT_INFO(OUTPUT, "RESP : cmd %d\t msg len %d\n",
		g_rem_ptr->msg.cmd, g_rem_ptr->msg.len);
#if defined(LINUX) || defined(vxworks)
		/* setting back default interface  */
		set_interface(wl, old_intf_name);
#endif /*  defined(LINUX) || defined(vxworks) */
		/* Transmit the response results */
		if (remote_tx_response(wl, buf_ptr, err) < 0) {
			DPRINT_ERR(ERR, "\nReturn results failed\n");
		}

#ifdef RWL_SOCKET
		if (g_rem_ptr->msg.flags != REMOTE_SHELL_CMD)
		/* Transmitted to client. Then close the handle & get the new handle
		 * for next transmission & reception. In case of shell commands this
		 * should be closed in respective shellproc files.
		 */
		close_sock_handle(g_rwl_hndle);
#endif /* RWL_SOCKET */

		if (buf_ptr) {
			free(buf_ptr);
		}
	} /* end of while */
#if defined (RWL_SOCKET)
	/* Close the main handle for socket */
	close_sock_handle(transport_descriptor);
#elif defined(RWL_SERIAL)
	/* Close the main handle for serial pipe  */
	rwl_close_pipe(remote_type, (void*)&transport_descriptor);
#endif

#ifdef RWLASD
	wfa_dut_deinit();
#endif

	return err;
}
Пример #7
0
static int
rwl_serial_fragmented_tx(void* wl, rem_ioctl_t *rem_ptr, uchar *buf_ptr, int error)
{
	rem_ioctl_t *loc_ptr = &loc_cdc;
	uchar* rem_buf_ptr;
	uint noframes = 1;    /* Default noframes = 1 */
	uint count;
	uint frame_count;
	uint rem_bytes;

	loc_ptr->msg.cmd = error;
	loc_ptr->msg.flags = REMOTE_REPLY;
	loc_ptr->msg.len = rem_ptr->msg.len;
	loc_ptr->data_len = rem_ptr->data_len;

	/* Fragment the result if it is more than DATA_FRAME_LEN (960) */
	if (loc_ptr->msg.len > DATA_FRAME_LEN) {
		/* Calculate no of frames */
		noframes = (loc_ptr->msg.len)/DATA_FRAME_LEN;
		if ((loc_ptr->msg.len) % DATA_FRAME_LEN > 0) {
			noframes += 1;
			rem_bytes = (loc_ptr->msg.len) % DATA_FRAME_LEN;
		} else {
			rem_bytes = DATA_FRAME_LEN;
		}
	} else {
		rem_bytes = loc_ptr->msg.len;
	}
	DPRINT_INFO(OUTPUT, "No of frames = %d, rem_bytes:%d\n", noframes, rem_bytes);
	count = 0;
	frame_count = noframes;
	rem_buf_ptr = (uchar*)malloc(DONGLE_TX_FRAME_SIZE + REMOTE_SIZE);

	while (count < noframes) {
		memset(rem_buf_ptr, 0, DONGLE_TX_FRAME_SIZE + REMOTE_SIZE);
		/* Send reply to client */
		rem_ptr->msg.cmd = loc_ptr->msg.cmd;
		rem_ptr->msg.flags = loc_ptr->msg.flags;
		rem_ptr->msg.len = loc_ptr->msg.len;

		if (frame_count == 1)
			rem_ptr->data_len = rem_bytes;
		else
			rem_ptr->data_len = DATA_FRAME_LEN;

		DPRINT_DBG(OUTPUT, "GET--rem_ptr->data_len=%d\n", rem_ptr->data_len);

		/* Copy CDC Header */
		memcpy(rem_buf_ptr, (uchar*)rem_ptr, REMOTE_SIZE);

		/* Copy Data now */
		memcpy(&rem_buf_ptr[REMOTE_SIZE], &buf_ptr[count*DATA_FRAME_LEN],
		                                              rem_ptr->data_len);
		count++;
		frame_count--;

		DPRINT_INFO(OUTPUT, "FRAME %d\n", count);
		DPRINT_INFO(OUTPUT, "%d %d  %d  %d\n", rem_ptr->msg.cmd, rem_ptr->msg.len,
			rem_ptr->msg.flags, rem_ptr->data_len);

		rwl_sync_delay(noframes);

		if ((error = rwl_var_setbuf(wl, cmdname, rem_buf_ptr,
		            DONGLE_TX_FRAME_SIZE+REMOTE_SIZE)) < 0) {
			DPRINT_INFO(OUTPUT, "Unable to send to wl driver,error=%d\n", error);
			if (rem_buf_ptr)
				free(rem_buf_ptr);
			return BCME_ERROR;
		}
		else
			DPRINT_INFO(OUTPUT, "Packet sent to wl driver,error=%d\n", error);
	}

	if (rem_buf_ptr)
		free(rem_buf_ptr);

	return error;
}