• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2 **+--------------------------------------------------------------------------+**
3 **|                                                                          |**
4 **| Copyright 1998-2008 Texas Instruments, Inc. - http://www.ti.com/         |**
5 **|                                                                          |**
6 **| Licensed under the Apache License, Version 2.0 (the "License");          |**
7 **| you may not use this file except in compliance with the License.         |**
8 **| You may obtain a copy of the License at                                  |**
9 **|                                                                          |**
10 **|     http://www.apache.org/licenses/LICENSE-2.0                           |**
11 **|                                                                          |**
12 **| Unless required by applicable law or agreed to in writing, software      |**
13 **| distributed under the License is distributed on an "AS IS" BASIS,        |**
14 **| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |**
15 **| See the License for the specific language governing permissions and      |**
16 **| limitations under the License.                                           |**
17 **|                                                                          |**
18 **+--------------------------------------------------------------------------+**
19 *******************************************************************************/
20 
21 /****************************************************************************************************/
22 /*                                                                                                  */
23 /*      MODULE:     eth_utils.c                                                                     */
24 /*      PURPOSE:    Ethernet communication utilities                                                */
25 /*                                                                                                  */
26 /****************************************************************************************************/
27 
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <sys/select.h>
31 #include <unistd.h>
32 #include <arpa/inet.h>
33 
34 #include "ipc.h"
35 #include "ticon.h"
36 #include "errno.h"
37 #include "signal.h"
38 #include "eth_utils.h"
39 
40 extern char* inet_ntoa(struct  in_addr);
41 	/************/
42 	/* Defines */
43 	/**********/
44 
45 #define LOOGER_ETHERNET_PORT	(700)
46 #define WIPP_ETHERNET_PORT		(701)
47 #define G_TESTER_ETHERNET_PORT	(702)
48 
49 #define READ_STATE_GET_HEADER		(0x00)
50 #define READ_STATE_GET_LENGTH1		(0x01)
51 #define READ_STATE_GET_LENGTH2		(0x02)
52 #define READ_STATE_GET_PAYLOAD		(0x03)
53 
54 #define PACKET_PREFIX			(0xFF)
55 
56 #define IN_BUFFER_SIZE			(1024)
57 #define OUT_BUFFER_SIZE			(512)
58 
59 	/*********************/
60 	/* Global variables */
61 	/*******************/
62 
63 unsigned char ethernet_utils_welcome_message[] = {'W', 2, 0, 2, ETH_UTILS_PROTOCOL_VERSION};
64 
65 char ethernet_utils_module_names[ETHERNET_UTILS_NUMBER_OF_MODULES][20] =
66 {
67 	"terminal",
68 	"logger",
69 	"wipp control",
70 	"g tester"
71 };
72 
73 	/********************************/
74 	/* static functions prototypes */
75 	/******************************/
76 
77 int ethernet_utils_init_module(int module_index, u_short port_number, int *module_pipe, unsigned char mux_uart_id);
78 void ethernet_utils_signal_handler(int signal);
79 int ethernet_utils_process_in_command(int module_index, unsigned char *read_state, unsigned short *packet_size, unsigned char *in_buffer, unsigned int *in_buffer_offset);
80 int ethernet_utils_write_socket(int module_index, int length, unsigned char *buffer);
81 void ethernet_utils_disconnect_socket(int module_index);
82 
83 	/**************/
84 	/* Functions */
85 	/************/
86 
87 /************************************************************************
88  *                        ethernet_utils_init                           *
89  ************************************************************************
90 DESCRIPTION: Initialize the ethernet communication
91 
92 CONTEXT	   : main process only!
93 ************************************************************************/
ethernet_utils_init()94 void ethernet_utils_init()
95 {
96 	ethernet_logger_process_pid = ethernet_utils_init_module(ETHERNET_UTILS_LOGGER_MODULE_ID, LOOGER_ETHERNET_PORT, ethernet_logger_pipe, LOGGER_MUX_UART_ID);
97 	ethernet_wipp_process_pid = ethernet_utils_init_module(ETHERNET_UTILS_WIPP_MODULE_ID, WIPP_ETHERNET_PORT, ethernet_wipp_control_pipe, WIPP_CONTROL_MUX_UART_ID);
98 	ethernet_g_tester_process_pid = ethernet_utils_init_module(ETHERNET_UTILS_G_TESTER_MODULE_ID, G_TESTER_ETHERNET_PORT, ethernet_g_tester_pipe, G_TESTER_MUX_UART_ID);
99 }
100 
101 /************************************************************************
102  *                        ethernet_utils_deinit                         *
103  ************************************************************************
104 DESCRIPTION: Deinitialize the ethernet communication
105 
106 CONTEXT	   : main process only!
107 ************************************************************************/
ethernet_utils_deinit()108 void ethernet_utils_deinit()
109 {
110 	/* Kill the logger process */
111 	if (ethernet_logger_process_pid > 0)
112 	{
113 		kill(ethernet_logger_process_pid, SIGKILL);
114 	}
115 
116 	/* Kill the wipp control process */
117 	if (ethernet_wipp_process_pid > 0)
118 	{
119 		kill(ethernet_wipp_process_pid, SIGKILL);
120 	}
121 
122 	/* Kill the wipp control process */
123 	if (ethernet_g_tester_process_pid > 0)
124 	{
125 		kill(ethernet_g_tester_process_pid, SIGKILL);
126 	}
127 }
128 
129 /************************************************************************
130  *                        ethernet_utils_signal_handler                 *
131  ************************************************************************
132 DESCRIPTION: Signal handler - receive the USER
133 
134 CONTEXT	   : Signal owner
135 ************************************************************************/
ethernet_utils_signal_handler(int signal)136 void ethernet_utils_signal_handler(int signal)
137 {
138 }
139 
140 /************************************************************************
141  *                        ethernet_utils_init_module                    *
142  ************************************************************************
143 DESCRIPTION: Initialize ethernet communication
144 
145 RETURNS:   : Process ID of the new process or -1 if error.
146 
147 CONTEXT	   : main process only!
148 ************************************************************************/
ethernet_utils_init_module(int module_index,u_short port_number,int * module_pipe,unsigned char mux_uart_id)149 int ethernet_utils_init_module(int module_index, u_short port_number, int *module_pipe, unsigned char mux_uart_id)
150 {
151 	int child_process_id;
152 
153 	/***************************************/
154 	/* Create a pipe to control the child */
155 	/*************************************/
156 
157 	if (pipe(module_pipe) < 0)
158 	{
159 		console_printf_terminal("eth_utils, error creating pipe\n");
160 
161 		return -1;
162 	}
163 
164 	/* Set the shared memory variables */
165 	SHARED_MEMORY_IPC_PIPE(module_index) = module_pipe[1];
166 	SHARED_MEMORY_MUX_UART_ID(module_index) = mux_uart_id;
167 
168 	/* Create a child process */
169 	child_process_id = fork();
170 
171 	if (0 == child_process_id)
172 	{
173 		/******************/
174 		/* Child process */
175 		/****************/
176 
177 		int result;
178 		int socket_id;
179 		int optval = 1;
180 		int socket_alive;
181 		int max_fd_index;
182 		socklen_t client_addr_len;
183 		fd_set read_set;
184 		unsigned char out_buffer[OUT_BUFFER_SIZE];
185 		unsigned char in_buffer[IN_BUFFER_SIZE];
186 		unsigned char read_state;
187 		unsigned short packet_size;
188 		unsigned int in_buffer_offset;
189 		struct sockaddr_in server_addr;
190 		struct sockaddr_in client_addr;
191 
192 		console_printf_terminal("eth_utils, Hello from %s child module (pid = %d).\n", ethernet_utils_module_names[module_index], getpid());
193 
194 		/* Close the write direction of the pipe  - because i only read information from this pipe. */
195 		close(module_pipe[1]);
196 
197 		SHARED_MEMORY_OUTPUT_PATH(module_index) = OUTPUT_PATH_SIMPLE_UART;
198 
199 		/* Set the signal handler for the 'SIGUSR1' signal */
200 		signal(SIGUSR1, ethernet_utils_signal_handler);
201 
202 		while (TRUE)
203 		{
204 			/******************/
205 			/* Open a socket */
206 			/****************/
207 
208 			socket_id = socket(PF_INET, SOCK_STREAM, 0);
209 
210 			if (!socket_id)
211 			{
212 				/* Error opening socket */
213 
214 				console_printf_terminal("eth_utils, error opening %s socket. (errno = %d)\n", ethernet_utils_module_names[module_index], errno);
215 
216 				_exit(1);
217 			}
218 
219 			/*************************/
220 			/* Configure the socket */
221 			/***********************/
222 
223 			if (setsockopt(socket_id, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1)
224 			{
225 				/* Error setting socket option */
226 
227 				console_printf_terminal("eth_utils, error setting %s socket option.  (errno = %d)\n", ethernet_utils_module_names[module_index], errno);
228 
229 				_exit(1);
230 			}
231 
232 			/********************/
233 			/* Bind the socket */
234 			/******************/
235 
236 			server_addr.sin_family = AF_INET;
237 			server_addr.sin_addr.s_addr = htonl (INADDR_ANY);
238 			server_addr.sin_port = htons(port_number);
239 
240 			result = bind(socket_id, (struct sockaddr *)&server_addr, sizeof(server_addr));
241 
242 			if (result != 0)
243 			{
244 				/* Error binding socket */
245 
246 				console_printf_terminal("eth_utils, error binding %s socket. (errno = %d)\n", ethernet_utils_module_names[module_index], errno);
247 
248 				_exit(1);
249 			}
250 
251 			/****************************/
252 			/* Listening to the socket */
253 			/**************************/
254 
255 			result = listen(socket_id, 5);
256 
257 			if (-1 == result)
258 			{
259 				/* Error listening to socket */
260 
261 				console_printf_terminal("eth_utils, error listening to %s socket. (errno = %d)\n", ethernet_utils_module_names[module_index], errno);
262 
263 				_exit(1);
264 			}
265 
266 			/**********************/
267 			/* Accept connection */
268 			/********************/
269 
270 			client_addr_len = sizeof(client_addr);
271 
272 			/* We suppose to get new socket id after accept (blocking action) */
273 			result = accept(socket_id, (struct sockaddr *)&client_addr, &client_addr_len);
274 
275 			if (-1 == result)
276 			{
277 				/* Error accepting connection */
278 
279 				console_printf_terminal("eth_utils, error accepting %s connection. (errno = %d)\n", ethernet_utils_module_names[module_index], errno);
280 
281 				_exit(1);
282 			}
283 
284 			close(socket_id);
285 
286 			socket_id = result;
287 
288 			read_state = READ_STATE_GET_HEADER;
289 
290 			SHARED_MEMORY_ETHERNET_SOCKET_ID(module_index) = socket_id;
291 
292 			console_printf_terminal("\n***********************************************\n");
293 			console_printf_terminal("* eth_utils, %s connection accepted. \n", ethernet_utils_module_names[module_index]);
294 			console_printf_terminal("*\n* Remote IP: %s\n***********************************************\n", inet_ntoa(client_addr.sin_addr));
295 
296 			/* Switch to ethernet output */
297 			SHARED_MEMORY_OUTPUT_PATH(module_index) = OUTPUT_PATH_ETHERNET;
298 
299 			/*********************************/
300 			/* Send Hello message to client */
301 			/*******************************/
302 
303 			ethernet_utils_write_socket(module_index, sizeof(ethernet_utils_welcome_message), ethernet_utils_welcome_message);
304 
305 			/**********************/
306 			/* Manage connection */
307 			/********************/
308 
309 			socket_alive = TRUE;
310 
311 			while (socket_alive)
312 			{
313 				/***********************************************************************************/
314 				/* Wait for one of two external events: 									      */
315 				/* -----------------------------------											 */
316 				/*																			    */
317 				/* 1. Data received from TCP client and should be transfered to parent process */
318 				/* 2. Data received from parent process and should be transfered to client 	  */
319 				/*****************************************************************************/
320 
321 				/* Prepare the read set fields */
322 				FD_ZERO(&read_set);
323 				FD_SET(socket_id, &read_set);
324 				FD_SET(module_pipe[0], &read_set);
325 
326 				/* Determine the maximum index of the file descriptor */
327 				max_fd_index = (max(socket_id, module_pipe[0]) + 1);
328 
329 				/* Wait for event - blocking */
330 				result = select(max_fd_index, &read_set, NULL, NULL, NULL);
331 
332 				/************************/
333 				/* Check event results */
334 				/**********************/
335 
336 				if (result > 0)
337 				{
338 					if (FD_ISSET(socket_id, &read_set))
339 					{
340 						/******************************/
341 						/* Data received from client */
342 						/****************************/
343 
344 						/* Process the input command */
345 						if (ethernet_utils_process_in_command(module_index, &read_state, &packet_size, in_buffer, &in_buffer_offset) <= 0)
346 						{
347 							socket_alive = FALSE;
348 						}
349 					}
350 
351 					if (FD_ISSET(module_pipe[0], &read_set))
352                     {
353 						/**************************************/
354 						/* Data received from parent process */
355 						/************************************/
356 
357 						result = read(module_pipe[0], out_buffer, sizeof(out_buffer));
358                         if( result < 0 )
359                         {
360                             console_printf_terminal("eth_utils, read error (err=%d)\n", result);
361                             socket_alive = FALSE;
362                         }
363 
364 						if (ethernet_utils_write_socket(module_index, result, out_buffer) == -1)
365 						{
366 							socket_alive = FALSE;
367 						}
368 					}
369 				}
370 				else
371 				{
372 					console_printf_terminal("eth_utils, 'select' command error\n");
373 
374 					socket_alive = FALSE;
375 				}
376 			}
377 
378 			/* Disconnect the socket */
379 			ethernet_utils_disconnect_socket(module_index);
380 		}
381 	}
382 
383 	/* Close the read direction of the pipe  - because i only write information from this pipe. (to child process) */
384 	close(module_pipe[0]);
385 
386 	/* return the process id, I will use it later when i want to kill this process */
387 	return child_process_id;
388 }
389 
390 /************************************************************************
391  *                        ethernet_utils_process_in_command             *
392  ************************************************************************
393 DESCRIPTION: Handle In commands
394 
395 CONTEXT	   : Only the same process that is reading from the socket
396 ************************************************************************/
ethernet_utils_process_in_command(int module_index,unsigned char * read_state,unsigned short * packet_size,unsigned char * in_buffer,unsigned int * in_buffer_offset)397 int ethernet_utils_process_in_command(int module_index, unsigned char *read_state, unsigned short *packet_size, unsigned char *in_buffer, unsigned int *in_buffer_offset)
398 {
399 	unsigned char prefix;
400 	int socket_id = SHARED_MEMORY_ETHERNET_SOCKET_ID(module_index);
401     int result = 1;
402 
403 	/*console_printf_terminal("ethernet_utils_process_in_command (socket = %d)\n", socket_id); */
404 
405 	/* Continue while there is data in the RX buffer */
406 	switch (*read_state)
407 	{
408 	case READ_STATE_GET_HEADER:
409 
410 		/* Read the packet prefix - one byte */
411 		result = read(socket_id, &prefix, sizeof(prefix));
412 		/*console_printf_terminal("ethernet_utils_process_in_command (State = READ_STATE_GET_HEADER, length = %d)\n", result); */
413 
414 		if (result > 0)
415 		{
416 			if (prefix == PACKET_PREFIX)
417 			{
418 				*read_state = READ_STATE_GET_LENGTH1;
419 			}
420 			else
421 			{
422 				console_printf_terminal("ethernet_utils_process_in_command, Error: protocol sync error! \n");
423 
424 				result = -1;
425 			}
426 		}
427 
428 		break;
429 
430 	case READ_STATE_GET_LENGTH1:
431 
432 		/* Read the packet size first byte */
433 		result = read(socket_id, (void *)((unsigned char *)(packet_size) + 0), sizeof(unsigned char));
434 		/*console_printf_terminal("ethernet_utils_process_in_command (State = READ_STATE_GET_LENGTH1, length = %d)\n", result); */
435 
436 		if (result > 0)
437 		{
438 			*read_state = READ_STATE_GET_LENGTH2;
439 		}
440 
441 		break;
442 
443 	case READ_STATE_GET_LENGTH2:
444 
445 		/* Read the packet size second byte */
446 		result = read(socket_id, (void *)((unsigned char *)(packet_size) + 1), sizeof(unsigned char));
447 		/*console_printf_terminal("ethernet_utils_process_in_command (State = READ_STATE_GET_LENGTH2, length = %d, packet_size = %d)\n", result, *packet_size); */
448 
449 		if (result > 0)
450 		{
451 			/* Sanity check on the length */
452 
453 			*in_buffer_offset = 0;
454 
455 			*read_state = READ_STATE_GET_PAYLOAD;
456 		}
457 
458 		break;
459 
460 
461 	case READ_STATE_GET_PAYLOAD:
462 
463 		/* Read the packet size second byte */
464 		result = read(socket_id, (in_buffer + 3 + *in_buffer_offset), (*packet_size - *in_buffer_offset));
465 		/*console_printf_terminal("ethernet_utils_process_in_command (State = READ_STATE_GET_PAYLOAD, offset = %d, length = %d)\n", *in_buffer_offset, result); */
466 
467 		if (result > 0)
468 		{
469 			*in_buffer_offset += result;
470 
471 			if (*packet_size == *in_buffer_offset)
472 			{
473 				/* All the packet has arrived */
474 
475 				*read_state = READ_STATE_GET_HEADER;
476 
477 				/* Send it to the main process */
478 
479 				ipc_send_command_to_main_process(module_index, in_buffer, (*packet_size + 3));
480 			}
481 		}
482 
483 		break;
484 	}
485 
486 	return result;
487 }
488 
489 /************************************************************************
490  *                        ethernet_utils_write_socket     			    *
491  ************************************************************************
492 DESCRIPTION: write data to socket
493 
494 CONTEXT    : Only the same process that is writing to the socket
495 ************************************************************************/
ethernet_utils_write_socket(int module_index,int length,unsigned char * buffer)496 int ethernet_utils_write_socket(int module_index, int length, unsigned char *buffer)
497 {
498 	int result;
499 
500 /*	console_printf_terminal("eth_utils, ethernet_utils_wipp_write() (length = %d).\n", length); */
501 
502 	/* Write to the socket */
503 	result = write(SHARED_MEMORY_ETHERNET_SOCKET_ID(module_index), buffer, length);
504 
505 /*	console_printf_terminal("eth_utils, ethernet_utils_wipp_write() (result = %d).\n", result); */
506 
507 	if (result != length)
508 	{
509 		/**************************/
510 		/* Error writing to port */
511 		/************************/
512 
513 		console_printf_terminal("eth_utils, Error writing to %s socket (result = %d, errno = %d, error = %s)\n", ethernet_utils_module_names[module_index], result, errno, strerror(errno));
514 
515 		result = -1;
516 	}
517 
518 	return result;
519 }
520 
521 /************************************************************************
522  *                        ethernet_utils_disconnect_socket 			    *
523  ************************************************************************
524 DESCRIPTION: Disconnect a socket
525 
526 CONTEXT    : Only the process that is disconnecting
527 ************************************************************************/
ethernet_utils_disconnect_socket(int module_index)528 void ethernet_utils_disconnect_socket(int module_index)
529 {
530 	char temp_buf[6] = {'x','x','x', '5', '0', 0};
531 
532 	/* Switch to UART output */
533 	SHARED_MEMORY_SWITCH_TO_UART_OUTPUT(module_index);
534 
535 	console_printf_terminal("eth_utils, disconnecting from %s socket.\n", ethernet_utils_module_names[module_index]);
536 
537 	switch (module_index)
538 	{
539 	case ETHERNET_UTILS_LOGGER_MODULE_ID:
540 		/* Set debug path back to UART */
541 		ipc_send_command_to_main_process(ETHERNET_UTILS_LOGGER_MODULE_ID, (unsigned char*)temp_buf, 5);
542 		break;
543 
544 	case ETHERNET_UTILS_WIPP_MODULE_ID:
545 		temp_buf[3] = WIPP_CONTROL_FROM_GENERAL_PROCESS_DEACTIVATE_IPERF;
546 		ipc_send_command_to_main_process(GENERAL_PROCESS_MODULE_ID,(unsigned char*) temp_buf, 5);
547 		break;
548 	}
549 
550 	/* Close the socket */
551 	close(SHARED_MEMORY_ETHERNET_SOCKET_ID(module_index));
552 }
553