aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgal Chernobelsky2012-09-13 09:03:10 -0500
committerIgal Chernobelsky2012-09-13 09:03:10 -0500
commit37c7d38f3c3f6ceca5c53a7fa4117d682e7c2511 (patch)
treed6df0951dce87e0553c3a0165a3c5320dd83905a
parentcfff7784f4442b30c7075aedc653934130b0b7fa (diff)
downloadti-utils-37c7d38f3c3f6ceca5c53a7fa4117d682e7c2511.tar.gz
ti-utils-37c7d38f3c3f6ceca5c53a7fa4117d682e7c2511.tar.xz
ti-utils-37c7d38f3c3f6ceca5c53a7fa4117d682e7c2511.zip
wl_logproxy: updated to latest version
Update logproxy service to the latest version. Signed-off-by: Igal Chernobelsky <igalc@ti.com>
-rwxr-xr-xwl_logproxy.c461
1 files changed, 332 insertions, 129 deletions
diff --git a/wl_logproxy.c b/wl_logproxy.c
index fa82b2f..dee4a4b 100755
--- a/wl_logproxy.c
+++ b/wl_logproxy.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * 2 *
3 * Description: Log Proxy for real-time log viewing 3 * Description: wl Firmware Log Service for off-line and real-time log viewing
4 * Author: Gil Barak 4 * Maintainer: gil.barak@ti.com
5 * Date: 15/06/2012 5 * Last Update: 14/08/2012
6 * 6 *
7 */ 7 */
8#include <stdio.h> 8#include <stdio.h>
@@ -16,21 +16,32 @@
16#include <sys/time.h> 16#include <sys/time.h>
17#include <netinet/in.h> 17#include <netinet/in.h>
18#include <signal.h> 18#include <signal.h>
19#include <errno.h>
19 20
21
22/* Defines */
20#define INVALID_HANDLE -1 23#define INVALID_HANDLE -1
21 24
22#define BUFFER_SIZE 256 25#define FILE_NAME "wl_fwlog.log"
23#define FILE_POLL_INTERVAL 2 // in seconds 26#define FILE_NAME_PREV "wl_fwlog_prev.log"
24#define KEEP_ALIVE_INTERVAL 5 // in seconds
25 27
28#define BUFFER_SIZE 1024
29#define FILE_POLL_INTERVAL 60 // in seconds
30#define KEEP_ALIVE_INTERVAL 1 // in seconds
31#define MAX_PATH 256
32#define MAX_FILE_SIZE 100000000 // Max file size is 100mb
33/***********/
26 34
27int socket_connected = 0;
28 35
36/* Globals */
37int socket_connected = 0;
38int socket_enabled = 0;
39/***********/
29 40
30 41
31void error(const char *msg) 42void error(const char *msg)
32{ 43{
33 printf("FW LOGGER: %s\r\n", msg); 44 printf("FW LOGGER ERROR: %s\r\n", msg);
34} 45}
35 46
36 47
@@ -40,152 +51,344 @@ void sigpipe_handler()
40 socket_connected = 0; 51 socket_connected = 0;
41} 52}
42 53
54// ************************************************** //
55//
56// Function name: create_listen_socket
57//
58// Description: Listen on a local port for remote
59// client connections
60//
61//
62//
63//
64// ************************************************** //
65int create_listen_socket(int listen_port)
66{
67 struct sockaddr_in serv_addr, cli_addr;
68 int sock_flags = 0;
69 int listen_sock = INVALID_HANDLE;
70
71 if(listen_port == 0)
72 {
73 socket_enabled = 0;
74 return -1;
75 }
76
77 listen_sock = socket(AF_INET, SOCK_STREAM, 0);
78 if (listen_sock == INVALID_HANDLE)
79 {
80 error("opening socket\r\n");
81 exit(1);
82 }
83
84 bzero((char *) &serv_addr, sizeof(serv_addr));
85 serv_addr.sin_family = AF_INET;
86 serv_addr.sin_addr.s_addr = INADDR_ANY;
87 serv_addr.sin_port = htons(listen_port);
88
89 // Bind to local port
90 if (bind(listen_sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
91 {
92 error("on binding\r\n");
93 exit(1);
94 }
95
96 listen(listen_sock,1);
97
98 // Set the callback for socket timeout signal handling
99 signal(SIGPIPE,sigpipe_handler);
100
101
102 // Set the listening socket to non-blocking mode
103 sock_flags = fcntl(listen_sock, F_GETFL, 0);
104 fcntl(listen_sock, F_SETFL, sock_flags | O_NONBLOCK);
105
106 return listen_sock;
107}
43 108
44int main(int argc, char *argv[]) 109// ************************************************** //
110//
111// Function Name: accept_client
112//
113// Description:
114// Monitor client activity and allow new
115// connections if the client is disconnected
116//
117//
118// ************************************************** //
119int accept_client(int listen_sock)
45{ 120{
46 int sockfd, newsockfd, portno; 121 int client_sock = INVALID_HANDLE;
47 socklen_t clilen; 122 socklen_t clilen;
48 char buffer[BUFFER_SIZE + 1] = {0}; // +1 for safety 123 struct sockaddr_in cli_addr;
49 char ka_buff; 124 struct timeval tv;
50 struct sockaddr_in serv_addr, cli_addr; 125
51 int n = 0; 126 tv.tv_sec = KEEP_ALIVE_INTERVAL;
52 int sent_bytes = 0; 127 tv.tv_usec = 0;
53 int fp_fwlog = INVALID_HANDLE; 128
54 struct timeval tv; 129 clilen = sizeof(cli_addr);
130 // Non-Blocking accept for remote client connections
131 client_sock = accept(listen_sock, (struct sockaddr *) &cli_addr, &clilen);
132
133 if(client_sock != INVALID_HANDLE)
134 {
135 printf("Client connected!\r\n");
136 if(setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)))
137 {
138 error("failed to set timeout for recv\r\n");
139 close(client_sock);
140 close(listen_sock);
141 exit(EXIT_FAILURE);
142 }
143 socket_connected = 1;
144 }
145
146 return client_sock;
147}
55 148
149// ************************************************** //
150//
151// Function Name: send_data
152//
153// Description:
154// Send the binary logs to the remote
155// client that is currently connected
156//
157//
158// ************************************************** //
159void send_data(int client_sock, char *buffer, int buf_size)
160{
161 int sent_bytes = 0;
162 // Send the buffer to the remote client
163 if(socket_connected)
164 {
165 sent_bytes = 0;
166 while( buf_size > 0 )
167 {
168 sent_bytes = send(client_sock,(char *)(buffer + sent_bytes),buf_size,0);
169 if (sent_bytes < 0)
170 {
171 printf("Send failed! %d %d\n", buf_size, client_sock);
172 close(client_sock);
173 socket_connected = 0;
174 break;
175 }
176 buf_size -= sent_bytes;
177 }
178 }
179}
56 180
181// ************************************************** //
182//
183// Function Name: keep_alive
184//
185// Description:
186// Verify that the remote client is
187// alive by receiving keep alive data
188//
189//
190// ************************************************** //
191void keep_alive(int client_sock)
192{
193 char ka_buff;
194 int n = 0;
195 // Verify keep alive
196 if(socket_connected)
197 {
198 n = recv(client_sock, &ka_buff, 1, 0);
199 if (n < 0)
200 {
201 error("Client disconnected");
202 close(client_sock);
203 socket_connected = 0;
204 }
205 }
206}
57 207
58 if (argc < 3) { 208// ************************************************** //
59 fprintf(stderr,"Usage: ./logProxy [listen port] [log file path]\n"); 209//
60 exit(1); 210// Function Name: open_fwlog
61 } 211//
212// Description:
213// Wait until the fwlog file is created
214// and open it for read access
215//
216// Return:
217// file handle to fwlog
218//
219// ************************************************** //
220int open_fwlog(int fp_fwlog, char *file_path)
221{
222 if(fp_fwlog == INVALID_HANDLE)
223 {
224 fp_fwlog = open(file_path, O_RDONLY);
225 }
62 226
63 sockfd = socket(AF_INET, SOCK_STREAM, 0); 227 return fp_fwlog;
64 if (sockfd < 0) { 228}
65 error("opening socket\r\n");
66 exit(1);
67 }
68 229
69 bzero((char *) &serv_addr, sizeof(serv_addr)); 230// ************************************************** //
70 portno = atoi(argv[1]); 231//
71 serv_addr.sin_family = AF_INET; 232// Function Name: read_fwlog
72 serv_addr.sin_addr.s_addr = INADDR_ANY; 233//
73 serv_addr.sin_port = htons(portno); 234// Description:
74 235// read the binary logs from the fwlog
75 // Bind to local port 236// into the buffer
76 if (bind(sockfd, (struct sockaddr *) &serv_addr, 237//
77 sizeof(serv_addr)) < 0) { 238// Return:
78 error("on binding\r\n"); 239// file handle to fwlog
79 exit(1); 240//
80 } 241// ************************************************** //
242int read_fwlog(int fp_fwlog, char *buffer)
243{
244 int n = 0;
245 bzero(buffer,BUFFER_SIZE);
246
247 // Attempt to read logs from the fwlog
248 n = read(fp_fwlog,buffer,BUFFER_SIZE);
249 if (n < 0)
250 {
251 error("reading from file\r\n");
252 return INVALID_HANDLE;
253 }
254 return n;
255}
81 256
82 listen(sockfd,1); 257void backup_log(int fp_bkplog, char *buffer, int buf_size)
258{
259 int wr_bytes = 0;
260
261 do
262 {
263 wr_bytes = write(fp_bkplog, buffer, buf_size);
264 if(wr_bytes < 0)
265 {
266 error("writing to backup log!");
267 exit(EXIT_FAILURE);
268 }
269 }
270 while (wr_bytes < buf_size);
271}
272
273int create_file(char *filename)
274{
275 int fp_bkplog;
276#ifdef ANDROID
277 fp_bkplog = open(filename, O_RDWR|O_TRUNC|O_CREAT, S_IRUSR|S_IWUSR);
278#else
279 fp_bkplog = open(filename, O_RDWR|O_TRUNC|O_CREAT, S_IREAD|S_IWRITE);
280#endif
281
282 if (fp_bkplog == INVALID_HANDLE)
283 {
284 error("Could not open output log file");
285 exit(EXIT_FAILURE);
286 }
287
288 return fp_bkplog;
289}
290// ************************************************** //
291//
292// Function Name: main
293//
294// Description:
295//
296//x
297//
298//
299// ************************************************** //
300int main(int argc, char *argv[])
301{
302 int listen_sock, client_sock = INVALID_HANDLE;
303 char buffer[BUFFER_SIZE + 1] = {0}; // +1 for safety
304 int n = 0, buf_size = 0;
305 int fp_fwlog = INVALID_HANDLE;
306 int fp_bkplog = INVALID_HANDLE;
307 char filename[MAX_PATH + 1] = {0}; // +1 for safety
308 char filename_prev[MAX_PATH + 1] = {0}; // +1 for safety
309 uint max_file_size = MAX_FILE_SIZE;
310 struct stat st;
83 311
84 signal(SIGPIPE,sigpipe_handler);
85 312
86 clilen = sizeof(cli_addr); 313 if (argc < 3)
87 while(1)
88 { 314 {
89 newsockfd = accept(sockfd, 315 fprintf(stderr,"Usage: ./logProxy [listen port] [log file] [backup directory]\n");
90 (struct sockaddr *) &cli_addr, 316 exit(EXIT_FAILURE);
91 &clilen); 317 }
92 318
93 socket_connected = 1; 319 // Max file size is an optional value
320 if(argc > 4)
321 {
322 max_file_size = atol(argv[4]);
323 }
94 324
95 if (newsockfd <= 0) { 325 listen_sock = create_listen_socket(atoi(argv[1]));
96 error("accept\r\n");
97 close(sockfd);
98 exit(1);
99 }
100 326
101 printf("Client connected!\r\n"); 327 //
328 // If we arrive here the listen socket was created successfully, otherwise we would have exited the process
329 //
102 330
103 bzero(buffer,BUFFER_SIZE); 331 // Create the backup file names
332 strncpy(filename,argv[3], MAX_PATH - sizeof(FILE_NAME));
333 strncpy(filename_prev,argv[3], MAX_PATH - sizeof(FILE_NAME));
334 strcat(filename, FILE_NAME);
335 strcat(filename_prev, FILE_NAME_PREV);
104 336
105 tv.tv_sec = KEEP_ALIVE_INTERVAL; 337 fp_bkplog = create_file(filename);
106 tv.tv_usec = 0;
107 if(setsockopt(newsockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv))) {
108 error("failed to set timeout for recv\r\n");
109 close(newsockfd);
110 close(sockfd);
111 exit(1);
112 }
113 338
339 // Main Loop
340 while(1)
341 {
342 // Check on the client connection status
343 if ( (socket_enabled == 1) &&
344 (client_sock == INVALID_HANDLE || socket_connected == 0) )
345 {
346 client_sock = accept_client(listen_sock);
347 }
348
349 if(fp_fwlog != INVALID_HANDLE)
350 {
351 // Read the fwlog sysfs file - This is a blocking function
352 buf_size = read_fwlog(fp_fwlog, buffer);
353
354 if(buf_size == INVALID_HANDLE)
355 {
356 error("driver unloaded: fwlog has been removed");
357 fp_fwlog = INVALID_HANDLE;
358 continue;
359 }
114 360
115 // attempt to read the log file every 5 seconds 361 // Create a new file if the log file exceeds the max size
116 // this is done in case the driver is down and the file is removed 362 stat(filename, &st);
117 do 363 if(st.st_size >= max_file_size)
118 { 364 {
119 if(!socket_connected) { 365 close(fp_bkplog);
120 error("socket not connected anymore\r\n"); 366 rename(filename, filename_prev);
121 break; 367 fp_bkplog = create_file(filename);
122 } 368 }
123 369
124 n = recv(newsockfd, &ka_buff, 1, 0); 370 // keep alive
371 keep_alive(client_sock);
125 372
126 if (n < 0) { 373 if(buf_size > 0)
127 error("keep alive timeout\r\n"); 374 {
128 socket_connected = 0; 375 // write the log data into the backup file
129 close(newsockfd); 376 backup_log(fp_bkplog, buffer, buf_size);
130 if(fp_fwlog != INVALID_HANDLE) { 377
131 close(fp_fwlog); 378 // Try to send the logs to the remote client
132 fp_fwlog = INVALID_HANDLE; 379 send_data(client_sock, buffer, buf_size);
133 }
134 break;
135 } 380 }
136 381
137 fp_fwlog = open(argv[2], O_RDONLY);
138 sleep(FILE_POLL_INTERVAL);
139 382
140 } while(fp_fwlog <= 0); 383 }
384 else
385 {
386 // To prevent high io/cpu usage sleep between attempts
387 sleep(FILE_POLL_INTERVAL);
388 // Try to open the fwlog file
389 fp_fwlog = open_fwlog(fp_fwlog, argv[2]);
390 }
141 391
142 if(socket_connected)
143 {
144 do
145 {
146 if(!socket_connected) {
147 error("socket not connected anymore\r\n");
148 break;
149 }
150
151 n = read(fp_fwlog,&buffer,BUFFER_SIZE);
152 if (n < 0) {
153 error("reading from file\r\n");
154 if(fp_fwlog != INVALID_HANDLE) {
155 close(fp_fwlog);
156 fp_fwlog = INVALID_HANDLE;
157 }
158 close(newsockfd);
159 break;
160 }
161
162 sent_bytes = 0;
163 while( n > 0 )
164 {
165 printf("recved = %d\r\n",n);
166 sent_bytes = send(newsockfd,(char *)(buffer + sent_bytes),n,0);
167 if (sent_bytes < 0)
168 {
169 error("Send failed!");
170 break;
171 }
172 n -= sent_bytes;
173 printf("sent_bytes=%d, n=%d\n", sent_bytes,n);
174 }
175
176 n = recv(newsockfd, &ka_buff, 1, 0);
177
178 if (n < 0) {
179 error("keep alive timeout\r\n");
180 if(fp_fwlog != INVALID_HANDLE) {
181 close(fp_fwlog);
182 fp_fwlog = INVALID_HANDLE;
183 }
184 close(newsockfd);
185 break;
186 }
187 } while(1);
188 }
189 } 392 }
190 393
191 return 0; 394 return 0;