diff options
author | Shahar Patury | 2015-10-18 02:20:42 -0500 |
---|---|---|
committer | Shahar Patury | 2015-11-01 01:46:32 -0600 |
commit | d39cb9d35247ad6c06542fbac1d40a7c5bcb9856 (patch) | |
tree | 5912b4329d6dbd34d75dc7aba8829adc961043fd | |
parent | c0bb5c6e053be618abbe6ef03442b3d042aa2e12 (diff) | |
download | 18xx-ti-utils-d39cb9d35247ad6c06542fbac1d40a7c5bcb9856.tar.gz 18xx-ti-utils-d39cb9d35247ad6c06542fbac1d40a7c5bcb9856.tar.xz 18xx-ti-utils-d39cb9d35247ad6c06542fbac1d40a7c5bcb9856.zip |
tools: fw logger proxy update for wl18xxol_r8.a9.28R8.6_SP1R8.6SP1
the wl_logproxy was upadated to support new fw logger over sdio
in wl18xx.
Signed-off-by: Shahar Patury <shaharp@ti.com>
-rw-r--r-- | wl_logproxy/Makefile | 40 | ||||
-rwxr-xr-x | wl_logproxy/wl_logproxy.c | 462 |
2 files changed, 502 insertions, 0 deletions
diff --git a/wl_logproxy/Makefile b/wl_logproxy/Makefile new file mode 100644 index 0000000..6a79302 --- /dev/null +++ b/wl_logproxy/Makefile | |||
@@ -0,0 +1,40 @@ | |||
1 | CC = $(CROSS_COMPILE)gcc | ||
2 | CFLAGS = -O2 -Wall | ||
3 | CFLAGS += -I$(NFSROOT)/usr/include -I$(NFSROOT)/include | ||
4 | |||
5 | ifdef NLROOT | ||
6 | CFLAGS += -I${NLROOT} | ||
7 | endif | ||
8 | |||
9 | LDFLAGS += -L$(NFSROOT)/lib | ||
10 | LIBS += -lm | ||
11 | |||
12 | ifeq ($(NLVER),3) | ||
13 | CFLAGS+=-DCONFIG_LIBNL32 | ||
14 | LIBS += -lnl-3 -lnl-genl-3 | ||
15 | else | ||
16 | CFLAGS+=-DCONFIG_LIBNL20 | ||
17 | LIBS += -lnl -lnl-genl | ||
18 | endif | ||
19 | |||
20 | OBJS = wl_logproxy.o | ||
21 | |||
22 | %.o: %.c | ||
23 | $(CC) $(CFLAGS) -c -o $@ $< | ||
24 | |||
25 | all: $(OBJS) | ||
26 | $(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o wl_logproxy | ||
27 | |||
28 | uim: | ||
29 | $(CC) $(CFLAGS) $(LDFLAGS) uim_rfkill/$@.c -o $@ | ||
30 | |||
31 | static: $(OBJS) | ||
32 | $(CC) $(LDFLAGS) --static $(OBJS) $(LIBS) -o wl_logproxy | ||
33 | |||
34 | install: | ||
35 | @echo Copy files to $(NFSROOT)/usr/share/wl18xx | ||
36 | @cp -f ./wl_logproxy $(NFSROOT)/usr/share/wl18xx | ||
37 | @chmod 755 $(NFSROOT)/usr/share/wl18xx/wl_logproxy | ||
38 | |||
39 | clean: | ||
40 | @rm -f *.o wl_logproxy uim | ||
diff --git a/wl_logproxy/wl_logproxy.c b/wl_logproxy/wl_logproxy.c new file mode 100755 index 0000000..117b53e --- /dev/null +++ b/wl_logproxy/wl_logproxy.c | |||
@@ -0,0 +1,462 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Description: wl Firmware Log Service for off-line and real-time log viewing | ||
4 | * Maintainer: gil.barak@ti.com | ||
5 | * Last Update: 11/09/2012 | ||
6 | * | ||
7 | */ | ||
8 | #include <stdio.h> | ||
9 | #include <stdlib.h> | ||
10 | #include <string.h> | ||
11 | #include <unistd.h> | ||
12 | #include <fcntl.h> | ||
13 | #include <sys/types.h> | ||
14 | #include <sys/stat.h> | ||
15 | #include <sys/socket.h> | ||
16 | #include <sys/time.h> | ||
17 | #include <netinet/in.h> | ||
18 | #include <signal.h> | ||
19 | #include <errno.h> | ||
20 | #include <pthread.h> | ||
21 | |||
22 | /* Defines */ | ||
23 | #define INVALID_HANDLE -1 | ||
24 | |||
25 | #define FILE_NAME "wl_fwlog.log" | ||
26 | #define FILE_NAME_PREV "wl_fwlog_" | ||
27 | |||
28 | #define BUFFER_SIZE 2048 | ||
29 | #define FILE_POLL_INTERVAL 5 // 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 | #define EMPTY_SLEEP_INTERVAL 200000 // On Read Empty buffer, Sleep 200mSec to avoid endless read tries | ||
34 | /***********/ | ||
35 | |||
36 | |||
37 | /* Globals */ | ||
38 | int socket_connected = 0; | ||
39 | int socket_enabled = 1; | ||
40 | /***********/ | ||
41 | |||
42 | |||
43 | void error(const char *msg) | ||
44 | { | ||
45 | printf("FW LOGGER ERROR: %s\r\n", msg); | ||
46 | } | ||
47 | |||
48 | |||
49 | void sigpipe_handler() | ||
50 | { | ||
51 | error("sigpipe caught!\r\n"); | ||
52 | socket_connected = 0; | ||
53 | } | ||
54 | |||
55 | // ************************************************** // | ||
56 | // | ||
57 | // Function name: create_listen_socket | ||
58 | // | ||
59 | // Description: Listen on a local port for remote | ||
60 | // client connections | ||
61 | // | ||
62 | // | ||
63 | // | ||
64 | // | ||
65 | // ************************************************** // | ||
66 | int create_listen_socket(int listen_port) | ||
67 | { | ||
68 | struct sockaddr_in serv_addr; | ||
69 | int sock_flags = 0; | ||
70 | int listen_sock = INVALID_HANDLE; | ||
71 | |||
72 | if(listen_port == 0) | ||
73 | { | ||
74 | socket_enabled = 0; | ||
75 | return INVALID_HANDLE; | ||
76 | } | ||
77 | |||
78 | listen_sock = socket(AF_INET, SOCK_STREAM, 0); | ||
79 | if (listen_sock == INVALID_HANDLE) | ||
80 | { | ||
81 | error("opening socket\r\n"); | ||
82 | exit(1); | ||
83 | } | ||
84 | |||
85 | bzero((char *) &serv_addr, sizeof(serv_addr)); | ||
86 | serv_addr.sin_family = AF_INET; | ||
87 | serv_addr.sin_addr.s_addr = INADDR_ANY; | ||
88 | |||
89 | serv_addr.sin_port = htons(listen_port); | ||
90 | |||
91 | // Bind to local port | ||
92 | if (bind(listen_sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) | ||
93 | { | ||
94 | error("on binding\r\n"); | ||
95 | exit(1); | ||
96 | } | ||
97 | |||
98 | listen(listen_sock,1); | ||
99 | |||
100 | // Set the callback for socket timeout signal handling | ||
101 | signal(SIGPIPE,sigpipe_handler); | ||
102 | |||
103 | |||
104 | // Set the listening socket to non-blocking mode | ||
105 | sock_flags = fcntl(listen_sock, F_GETFL, 0); | ||
106 | fcntl(listen_sock, F_SETFL, sock_flags | O_NONBLOCK); | ||
107 | |||
108 | return listen_sock; | ||
109 | } | ||
110 | |||
111 | // ************************************************** // | ||
112 | // | ||
113 | // Function Name: accept_client | ||
114 | // | ||
115 | // Description: | ||
116 | // Monitor client activity and allow new | ||
117 | // connections if the client is disconnected | ||
118 | // | ||
119 | // | ||
120 | // ************************************************** // | ||
121 | int accept_client(int listen_sock) | ||
122 | { | ||
123 | int client_sock = INVALID_HANDLE; | ||
124 | socklen_t clilen; | ||
125 | struct sockaddr_in cli_addr; | ||
126 | struct timeval tv; | ||
127 | |||
128 | tv.tv_sec = KEEP_ALIVE_INTERVAL; | ||
129 | tv.tv_usec = 0; | ||
130 | |||
131 | clilen = sizeof(cli_addr); | ||
132 | // Non-Blocking accept for remote client connections | ||
133 | client_sock = accept(listen_sock, (struct sockaddr *) &cli_addr, &clilen); | ||
134 | |||
135 | if(client_sock != INVALID_HANDLE) | ||
136 | { | ||
137 | printf("Client connected!\r\n"); | ||
138 | if(setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv))) | ||
139 | { | ||
140 | error("failed to set timeout for recv\r\n"); | ||
141 | close(client_sock); | ||
142 | close(listen_sock); | ||
143 | exit(EXIT_FAILURE); | ||
144 | } | ||
145 | socket_connected = 1; | ||
146 | } | ||
147 | |||
148 | return client_sock; | ||
149 | } | ||
150 | |||
151 | // ************************************************** // | ||
152 | // | ||
153 | // Function Name: send_data | ||
154 | // | ||
155 | // Description: | ||
156 | // Send the binary logs to the remote | ||
157 | // client that is currently connected | ||
158 | // | ||
159 | // | ||
160 | // ************************************************** // | ||
161 | void send_data(int client_sock, char *buffer, int buf_size) | ||
162 | { | ||
163 | int sent_bytes = 0; | ||
164 | // Send the buffer to the remote client | ||
165 | if(socket_connected) | ||
166 | { | ||
167 | sent_bytes = 0; | ||
168 | while( buf_size > 0 ) | ||
169 | { | ||
170 | sent_bytes = send(client_sock,(char *)(buffer + sent_bytes),buf_size,0); | ||
171 | if (sent_bytes < 0) | ||
172 | { | ||
173 | printf("Send failed! %d %d\n", buf_size, client_sock); | ||
174 | close(client_sock); | ||
175 | socket_connected = 0; | ||
176 | break; | ||
177 | } | ||
178 | buf_size -= sent_bytes; | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | |||
183 | // ************************************************** // | ||
184 | // | ||
185 | // Function Name: keep_alive | ||
186 | // | ||
187 | // Description: | ||
188 | // Verify that the remote client is | ||
189 | // alive by receiving keep alive data | ||
190 | // | ||
191 | // | ||
192 | // ************************************************** // | ||
193 | void keep_alive(int client_sock) | ||
194 | { | ||
195 | char ka_buff; | ||
196 | int n = 0; | ||
197 | // Verify keep alive | ||
198 | if(socket_connected) | ||
199 | { | ||
200 | n = recv(client_sock, &ka_buff, 1, 0); | ||
201 | if (n < 0) | ||
202 | { | ||
203 | error("Client disconnected"); | ||
204 | close(client_sock); | ||
205 | socket_connected = 0; | ||
206 | } | ||
207 | } | ||
208 | } | ||
209 | |||
210 | // ************************************************** // | ||
211 | // | ||
212 | // Function Name: open_fwlog | ||
213 | // | ||
214 | // Description: | ||
215 | // Wait until the fwlog file is created | ||
216 | // and open it for read access | ||
217 | // | ||
218 | // Return: | ||
219 | // file handle to fwlog | ||
220 | // | ||
221 | // ************************************************** // | ||
222 | int open_fwlog(int fp_fwlog, char *file_path) | ||
223 | { | ||
224 | if(fp_fwlog == INVALID_HANDLE) | ||
225 | { | ||
226 | fp_fwlog = open(file_path, O_RDONLY); | ||
227 | } | ||
228 | |||
229 | return fp_fwlog; | ||
230 | } | ||
231 | |||
232 | // ************************************************** // | ||
233 | // | ||
234 | // Function Name: read_file | ||
235 | // | ||
236 | // Description: | ||
237 | // read the binary logs from the file | ||
238 | // into the buffer | ||
239 | // | ||
240 | // Return: | ||
241 | // file handle | ||
242 | // | ||
243 | // ************************************************** // | ||
244 | int read_file(int fp_file, char *buffer) | ||
245 | { | ||
246 | int n = 0; | ||
247 | |||
248 | bzero(buffer,BUFFER_SIZE); | ||
249 | n = read(fp_file,buffer,BUFFER_SIZE); | ||
250 | if (n < 0) | ||
251 | { | ||
252 | error("reading from file\r\n"); | ||
253 | return INVALID_HANDLE; | ||
254 | } | ||
255 | if (n == 0) { | ||
256 | usleep(EMPTY_SLEEP_INTERVAL); | ||
257 | } | ||
258 | return n; | ||
259 | } | ||
260 | |||
261 | void backup_file(int fp_bkp, char *buffer, int buf_size) | ||
262 | { | ||
263 | int wr_bytes = 0; | ||
264 | |||
265 | do | ||
266 | { | ||
267 | wr_bytes = write(fp_bkp, buffer, buf_size); | ||
268 | if(wr_bytes < 0) | ||
269 | { | ||
270 | error("writing to backup file!"); | ||
271 | exit(EXIT_FAILURE); | ||
272 | } | ||
273 | } | ||
274 | while (wr_bytes < buf_size); | ||
275 | } | ||
276 | |||
277 | int create_file(char *filename) | ||
278 | { | ||
279 | int fp_bkplog; | ||
280 | #ifdef ANDROID | ||
281 | fp_bkplog = open(filename, O_RDWR|O_TRUNC|O_CREAT, S_IRUSR|S_IWUSR); | ||
282 | #else | ||
283 | fp_bkplog = open(filename, O_RDWR|O_TRUNC|O_CREAT, S_IREAD|S_IWRITE); | ||
284 | #endif | ||
285 | if (fp_bkplog == INVALID_HANDLE) | ||
286 | { | ||
287 | error("Could not open output log file"); | ||
288 | exit(EXIT_FAILURE); | ||
289 | } | ||
290 | |||
291 | return fp_bkplog; | ||
292 | } | ||
293 | /* | ||
294 | void core_dump_thread( void *ptr) | ||
295 | { | ||
296 | char buffer[BUFFER_SIZE + 1] = {0}; // +1 for safety | ||
297 | int fp_fwdump = INVALID_HANDLE; | ||
298 | int fp_fwdumpbkp = INVALID_HANDLE; | ||
299 | int buf_size = 0; | ||
300 | |||
301 | while(1) | ||
302 | { | ||
303 | if(fp_fwdump == INVALID_HANDLE) | ||
304 | { | ||
305 | fp_fwdump = open(fp_fwdump, O_RDONLY); | ||
306 | continue; | ||
307 | } | ||
308 | |||
309 | if(fp_fwdumpbkp == INVALID_HANDLE) | ||
310 | { | ||
311 | fp_fwdumpbkp = open(filename, O_RDWR|O_TRUNC|O_CREAT, S_IREAD|S_IWRITE); | ||
312 | continue; | ||
313 | } | ||
314 | |||
315 | // Read the core_dump sysfs file - This is a blocking function | ||
316 | buf_size = read_file(fp_fwdump, buffer); | ||
317 | |||
318 | while( (buf_size = read_file(fp_fwdump, buffer)) != 0) | ||
319 | { | ||
320 | backup_file(fp_fwdumpbkp, buffer, buf_size); | ||
321 | } | ||
322 | |||
323 | close(fp_fwdumpbkp); | ||
324 | close(fp_fwdump); | ||
325 | } | ||
326 | pthread_exit(0); | ||
327 | } | ||
328 | */ | ||
329 | |||
330 | // ************************************************** // | ||
331 | // | ||
332 | // Function Name: main | ||
333 | // | ||
334 | // Description: | ||
335 | // | ||
336 | // | ||
337 | // | ||
338 | // | ||
339 | // ************************************************** // | ||
340 | int main(int argc, char *argv[]) | ||
341 | { | ||
342 | // int listen_sock, client_sock = INVALID_HANDLE; | ||
343 | char buffer[BUFFER_SIZE + 1] = {0}; // +1 for safety | ||
344 | int buf_size = 0; | ||
345 | int fp_fwlog = INVALID_HANDLE; | ||
346 | int fp_bkplog = INVALID_HANDLE; | ||
347 | char filename[MAX_PATH + 1] = {0}; // +1 for safety | ||
348 | char filename_prev[MAX_PATH + 1] = {0}; // +1 for safety | ||
349 | char filename_prev_reg[MAX_PATH + 1] = {0}; // +1 for safety | ||
350 | uint max_file_size = MAX_FILE_SIZE; | ||
351 | struct stat st; | ||
352 | |||
353 | if (argc < 3) | ||
354 | { | ||
355 | fprintf(stderr,"Usage: ./logProxy [listen port] [log file] [backup directory]\n"); | ||
356 | exit(EXIT_FAILURE); | ||
357 | } | ||
358 | |||
359 | // Max file size is an optional value | ||
360 | if(argc > 4) | ||
361 | { | ||
362 | max_file_size = atol(argv[4]); | ||
363 | } | ||
364 | |||
365 | //listen_sock = create_listen_socket(atoi(argv[1])); | ||
366 | |||
367 | // | ||
368 | // If we arrive here the listen socket was created successfully, otherwise we would have exited the process | ||
369 | // | ||
370 | |||
371 | // Create the backup file names | ||
372 | strncpy(filename,argv[3], MAX_PATH - sizeof(FILE_NAME)); | ||
373 | strncpy(filename_prev,argv[3], MAX_PATH - sizeof(FILE_NAME_PREV)); | ||
374 | strcat(filename, FILE_NAME); | ||
375 | strcat(filename_prev, FILE_NAME_PREV); | ||
376 | strncpy(filename_prev_reg, filename_prev, MAX_PATH); | ||
377 | |||
378 | fp_fwlog = open_fwlog(fp_fwlog, argv[2]); | ||
379 | fp_bkplog = create_file(filename); | ||
380 | |||
381 | |||
382 | // Create the core_dump thread | ||
383 | //pthread_create(&thread, NULL, (void *) &core_dump_thread, NULL); | ||
384 | |||
385 | // Main Loop | ||
386 | while(1) | ||
387 | { | ||
388 | // Check on the client connection status | ||
389 | // if ( (socket_enabled == 1) && | ||
390 | // (client_sock == INVALID_HANDLE || socket_connected == 0) ) | ||
391 | // { | ||
392 | // client_sock = accept_client(listen_sock); | ||
393 | // } | ||
394 | |||
395 | |||
396 | if(fp_fwlog != INVALID_HANDLE) | ||
397 | { | ||
398 | // Read the fwlog sysfs file - This is a blocking function | ||
399 | buf_size = read_file(fp_fwlog, buffer); | ||
400 | |||
401 | if(buf_size == INVALID_HANDLE) | ||
402 | { | ||
403 | error("driver unloaded: fwlog has been removed"); | ||
404 | fp_fwlog = INVALID_HANDLE; | ||
405 | continue; | ||
406 | } | ||
407 | |||
408 | // Create a new file if the log file exceeds the max size | ||
409 | stat(filename, &st); | ||
410 | if(st.st_size >= max_file_size) | ||
411 | { | ||
412 | // Prepare new backup file name | ||
413 | time_t current_time; | ||
414 | char *tmp_str; | ||
415 | int index = 0; | ||
416 | |||
417 | current_time = time(NULL); | ||
418 | tmp_str = ctime(¤t_time); | ||
419 | // Replace all spaces with '_' | ||
420 | while (tmp_str[index] != 0) { | ||
421 | if ((tmp_str[index] == ' ') || (tmp_str[index] == ':')) { | ||
422 | tmp_str[index] = '_'; | ||
423 | } // if | ||
424 | index++; | ||
425 | } // While | ||
426 | // remove last character | ||
427 | tmp_str[index-1] = 0; | ||
428 | |||
429 | strncpy(filename_prev, filename_prev_reg, MAX_PATH); | ||
430 | strcat(filename_prev, tmp_str); | ||
431 | strcat(filename_prev, ".log"); | ||
432 | |||
433 | close(fp_bkplog); | ||
434 | rename(filename, filename_prev); | ||
435 | fp_bkplog = create_file(filename); | ||
436 | } | ||
437 | |||
438 | // keep alive | ||
439 | // keep_alive(client_sock); | ||
440 | |||
441 | if(buf_size > 0) | ||
442 | { | ||
443 | // write the log data into the backup file | ||
444 | backup_file(fp_bkplog, buffer, buf_size); | ||
445 | |||
446 | // Try to send the logs to the remote client | ||
447 | // send_data(client_sock, buffer, buf_size); | ||
448 | } | ||
449 | |||
450 | } | ||
451 | else | ||
452 | { | ||
453 | // To prevent high io/cpu usage sleep between attempts | ||
454 | sleep(FILE_POLL_INTERVAL); | ||
455 | // Try to open the fwlog file | ||
456 | fp_fwlog = open_fwlog(fp_fwlog, argv[2]); | ||
457 | } | ||
458 | |||
459 | } | ||
460 | |||
461 | return 0; | ||
462 | } | ||