OSDN Git Service

Set rfkill power off if turning BT on fails.
[android-x86/system-bluetooth.git] / tools / asocket_test.c
1 /*
2 ** Copyright 2009 The Android Open Source Project
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 **     http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16
17 /** socket testing  */
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <errno.h>
22 #include <sys/uio.h>
23 #include <unistd.h>
24
25 #include <pthread.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include <sys/socket.h>
31 #include <sys/ioctl.h>
32 #include <sys/poll.h>
33 #include <sys/un.h>
34 #include <netinet/in.h>
35
36 #include <bluetooth/bluetooth.h>
37 #include <bluetooth/rfcomm.h>
38 #include <bluetooth/sco.h>
39 #include <bluetooth/l2cap.h>
40
41 #include "cutils/abort_socket.h"
42
43 enum sock_type {
44     UNIX = 0,
45     RFCOMM,
46     SCO,
47     L2CAP,
48     TCP,
49 };
50
51 struct thread_args {
52     int fd;
53     int type;
54     int delay;
55 };
56
57 struct sockaddr_un  local_addr_un  = {AF_UNIX, "/data/foo"};
58 struct sockaddr_rc  local_addr_rc  = {AF_BLUETOOTH, *BDADDR_ANY, 4};
59 struct sockaddr_sco local_addr_sco = {AF_BLUETOOTH, *BDADDR_LOCAL};
60 struct sockaddr_l2  local_addr_l2  = {AF_BLUETOOTH, htobs(0x1001), *BDADDR_ANY, 0};
61 struct sockaddr_in  local_addr_in  = {AF_INET, 9999, {0}, {0}};
62
63 struct sockaddr_un  remote_addr_un  ;
64 struct sockaddr_rc  remote_addr_rc  ;
65 struct sockaddr_sco remote_addr_sco ;
66 struct sockaddr_l2  remote_addr_l2  ;
67 struct sockaddr_in  remote_addr_in  ;
68
69 static void print_events(int events) {
70     if (events & POLLIN) printf("POLLIN ");
71     if (events & POLLPRI) printf("POLLPRI ");
72     if (events & POLLOUT) printf("POLLOUT ");
73     if (events & POLLERR) printf("POLLERR ");
74     if (events & POLLHUP) printf("POLLHUP ");
75     if (events & POLLNVAL) printf("POLLNVAL ");
76     printf("\n");
77 }
78
79 static void print_fds(struct pollfd *ufds, nfds_t nfds) {
80     unsigned int i;
81     for (i=0; i<nfds; i++)
82         printf("%d ", ufds[i].fd);
83 }
84
85 static int _socket(int type) {
86     int ret;
87     int family = -1;
88     int typ = -1;
89     int protocol = -1;
90
91     switch (type) {
92     case UNIX:
93         family = PF_UNIX;
94         typ = SOCK_STREAM;
95         protocol = 0;
96         break;
97     case RFCOMM:
98         family = PF_BLUETOOTH;
99         typ = SOCK_STREAM;
100         protocol = BTPROTO_RFCOMM;
101         break;
102     case SCO:
103         family = PF_BLUETOOTH;
104         typ = SOCK_SEQPACKET;
105         protocol = BTPROTO_SCO;
106         break;
107     case L2CAP:
108         family = PF_BLUETOOTH;
109         typ = SOCK_SEQPACKET;
110         protocol = BTPROTO_L2CAP;
111         break;
112     case TCP:
113         family = PF_INET;
114         typ = SOCK_STREAM;
115         protocol = 0;
116         break;
117     }
118
119     printf("%d: socket()\n", gettid());
120     ret = socket(family, typ, protocol);
121     printf("%d: socket() = %d\n", gettid(), ret);
122     if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
123
124     return ret;
125 }
126
127 static int _close(int fd, int type) {
128     int ret;
129
130     printf("%d: close(%d)\n", gettid(), fd);
131     ret = close(fd);
132     printf("%d: close(%d) = %d\n", gettid(), fd, ret);
133     if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
134
135     return ret;
136 }
137
138 static int _bind(int fd, int type) {
139     int len = 0;
140     int ret;
141     struct sockaddr *addr = NULL;
142
143     switch (type) {
144     case UNIX:
145         unlink(local_addr_un.sun_path);
146         addr = (struct sockaddr *) &local_addr_un;
147         len = sizeof(local_addr_un);
148         break;
149     case RFCOMM:
150         addr = (struct sockaddr *) &local_addr_rc;
151         len = sizeof(local_addr_rc);
152         break;
153     case SCO:
154         addr = (struct sockaddr *) &local_addr_sco;
155         len = sizeof(local_addr_sco);
156         break;
157     case L2CAP:
158         addr = (struct sockaddr *) &local_addr_l2;
159         len = sizeof(local_addr_l2);
160         break;
161     case TCP:
162         addr = (struct sockaddr *) &local_addr_in;
163         len = sizeof(local_addr_in);
164         break;
165     }
166
167     printf("%d: bind(%d)\n", gettid(), fd);
168     ret = bind(fd, addr, len);
169     printf("%d: bind(%d) = %d\n", gettid(), fd, ret);
170     if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
171
172     return ret;
173 }
174
175 static int _listen(int fd, int type) {
176     int ret;
177
178     printf("%d: listen(%d)\n", gettid(), fd);
179     ret = listen(fd, 1);
180     printf("%d: listen(%d) = %d\n", gettid(), fd, ret);
181     if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
182
183     return ret;
184 }
185
186 static int _read(int fd) {
187     int ret;
188     char buf;
189
190     printf("%d: read(%d)\n", gettid(), fd);
191     ret = read(fd, &buf, 1);
192     printf("%d: read(%d) = %d [%d]\n", gettid(), fd, ret, (int)buf);
193     if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
194
195     return ret;
196 }
197
198
199 static int _accept(int fd, int type) {
200     int ret;
201     int len;
202     struct sockaddr *addr = NULL;
203
204     switch (type) {
205     case UNIX:
206         addr = (struct sockaddr *) &remote_addr_un;
207         len = sizeof(remote_addr_un);
208         break;
209     case RFCOMM:
210         addr = (struct sockaddr *) &remote_addr_rc;
211         len = sizeof(remote_addr_rc);
212         break;
213     case SCO:
214         addr = (struct sockaddr *) &remote_addr_sco;
215         len = sizeof(remote_addr_sco);
216         break;
217     case L2CAP:
218         addr = (struct sockaddr *) &remote_addr_l2;
219         len = sizeof(remote_addr_l2);
220         break;
221     case TCP:
222         addr = (struct sockaddr *) &remote_addr_in;
223         len = sizeof(remote_addr_in);
224         break;
225     }
226
227     printf("%d: accept(%d)\n", gettid(), fd);
228     ret = accept(fd, addr, &len);
229     printf("%d: accept(%d) = %d\n", gettid(), fd, ret);
230     if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
231     else {
232         printf("\tlen = %d\n", len);
233     }
234
235     return ret;
236 }
237
238 static int _connect(int fd, int type) {
239     int ret;
240     int len = 0;
241     struct sockaddr *addr = NULL;
242
243     switch (type) {
244     case UNIX:
245         addr = (struct sockaddr *) &local_addr_un;
246         len = sizeof(local_addr_un);
247         break;
248     case RFCOMM:
249         addr = (struct sockaddr *) &local_addr_rc;
250         len = sizeof(local_addr_rc);
251         break;
252     case SCO:
253         addr = (struct sockaddr *) &local_addr_sco;
254         len = sizeof(local_addr_sco);
255         break;
256     case L2CAP:
257         addr = (struct sockaddr *) &local_addr_l2;
258         len = sizeof(local_addr_l2);
259         break;
260     case TCP:
261         addr = (struct sockaddr *) &local_addr_in;
262         len = sizeof(local_addr_in);
263         break;
264     }
265
266     printf("%d: connect(%d)\n", gettid(), fd);
267     ret = connect(fd, addr, len);
268     printf("%d: connect(%d) = %d\n", gettid(), fd, ret);
269     if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
270
271     return ret;
272 }
273
274 static int _write(int fd, int type) {
275     int ret;
276     char buf = 69;
277
278     printf("%d: write(%d)\n", gettid(), fd);
279     ret = write(fd, &buf, 1);
280     printf("%d: write(%d) = %d\n", gettid(), fd, ret);
281     if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
282
283     return ret;
284 }
285
286 static int _shutdown(int fd, int how) {
287     int ret;
288
289     printf("%d: shutdown(%d)\n", gettid(), fd);
290     ret = shutdown(fd, how);
291     printf("%d: shutdown(%d) = %d\n", gettid(), fd, ret);
292     if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
293
294     return ret;
295 }
296
297 static int _poll(struct pollfd *ufds, nfds_t nfds, int timeout) {
298     int ret;
299     unsigned int i;
300
301     printf("%d: poll(", gettid());
302     print_fds(ufds, nfds);
303     printf(")\n");
304     ret = poll(ufds, nfds, timeout);
305     printf("%d: poll() = %d\n", gettid(), ret);
306     if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
307     if (ret > 0) {
308         for (i=0; i<nfds; i++) {
309             if (ufds[i].revents) {
310                 printf("\tfd %d ", ufds[i].fd); print_events(ufds[i].revents);
311             }
312         }
313     }
314     return ret;
315 }
316
317 static void thread_delay_close(struct thread_args *args) {
318     printf("%d: START\n", gettid());
319     sleep(args->delay);
320     _close(args->fd, args->type);
321     printf("%d: END\n", gettid());
322 }
323
324 static void thread_poll(void *args) {
325     int fd = (int)args;
326     struct pollfd pfd;
327     printf("%d: START\n", gettid());
328     pfd.fd = fd;
329     pfd.events = 0;
330     _poll(&pfd, 1, -1);
331     printf("%d: END\n", gettid());
332 }
333
334 static void thread_read(void *args) {
335     int fd = (int)args;
336     printf("%d: START\n", gettid());
337     _read(fd);
338     printf("%d: END\n", gettid());
339 }
340
341 static void thread_pollin(void *args) {
342     int fd = (int)args;
343     struct pollfd pfd;
344     printf("%d: START\n", gettid());
345     pfd.fd = fd;
346     pfd.events = POLLIN;
347     _poll(&pfd, 1, -1);
348     printf("%d: END\n", gettid());
349 }
350
351 static void thread_shutdown(int fd) {
352     printf("%d: START\n", gettid());
353     sleep(4);
354     _shutdown(fd, SHUT_RDWR);
355     printf("%d: END\n", gettid());
356 }
357
358 static void thread_accept(struct thread_args *args) {
359     printf("%d: START\n", gettid());
360     sleep(args->delay);
361     _accept(args->fd, args->type);
362     printf("%d: END\n", gettid());
363 }
364
365 static void thread_connect(struct thread_args *args) {
366     printf("%d: START\n", gettid());
367     sleep(args->delay);
368     _connect(args->fd, args->type);
369     printf("%d: END\n", gettid());
370 }
371
372 static void thread_delay_close_write(struct thread_args *args) {
373     printf("%d: START\n", gettid());
374     sleep(args->delay);
375     _close(args->fd, args->type);
376     sleep(args->delay);
377     _write(args->fd, args->type);
378     printf("%d: END\n", gettid());
379 }
380
381 static void thread_accept_write(struct thread_args *args) {
382     printf("%d: START\n", gettid());
383     sleep(args->delay);
384     _accept(args->fd, args->type);
385     sleep(args->delay);
386     _write(args->fd, args->type);
387     printf("%d: END\n", gettid());
388 }
389
390 static void thread_delay_connect(struct thread_args *args) {
391     printf("%d: START\n", gettid());
392     sleep(args->delay);
393     args->fd = _socket(args->type);
394     _connect(args->fd, args->type);
395     printf("%d: END\n", gettid());
396 }
397
398 static int do_accept_accept_accept(int type) {
399     int fd;
400
401     fd = _socket(type);
402     if (fd < 0) goto error;
403
404     if (_bind(fd, type) < 0) goto error;
405
406     if (_listen(fd, type) < 0) goto error;
407
408     while (1) {
409         _accept(fd, type);
410     }
411
412     return 0;
413
414 error:
415     return -1;
416 }
417
418 static int do_accept_and_close(int type) {
419     int fd;
420     pthread_t thread;
421     struct thread_args args = {-1, type, 1};
422
423     fd = _socket(type);
424     if (fd < 0) goto error;
425
426     if (_bind(fd, type) < 0) goto error;
427
428     if (_listen(fd, type) < 0) goto error;
429
430     args.fd = fd;
431     pthread_create(&thread, NULL, (void *)thread_delay_close, (void *)&args);
432
433     _accept(fd, type);
434
435     pthread_join(thread, NULL);
436
437     return 0;
438
439 error:
440     return -1;
441 }
442
443 static int do_accept_shutdown(int type) {
444     int fd;
445     pthread_t thread;
446     struct thread_args args = {-1, type, 0};
447
448     fd = _socket(type);
449     if (fd < 0) goto error;
450
451     if (_bind(fd, type) < 0) goto error;
452
453     if (_listen(fd, type) < 0) goto error;
454
455     args.fd = fd;
456     pthread_create(&thread, NULL, (void *)thread_accept, (void *)&args);
457
458     sleep(4);
459     _shutdown(fd, SHUT_RDWR);
460
461     pthread_join(thread, NULL);
462
463     _close(fd, type);
464
465     return 0;
466
467 error:
468     return -1;
469 }
470
471 static int do_connect_shutdown(int type) {
472     int fd;
473     pthread_t thread;
474     struct thread_args args = {-1, type, 0};
475
476     fd = _socket(type);
477     if (fd < 0) goto error;
478
479     args.fd = fd;
480     pthread_create(&thread, NULL, (void *)thread_connect, (void *)&args);
481
482     sleep(4);
483     _shutdown(fd, SHUT_RDWR);
484
485     pthread_join(thread, NULL);
486
487     _close(fd, type);
488
489     return 0;
490
491 error:
492     return -1;
493 }
494
495 // accept in one thread. close then write in another
496 static int do_accept_close_write(int type) {
497     int fd;
498     pthread_t thread;
499     struct thread_args args = {-1, type, 1};
500
501     fd = _socket(type);
502     if (fd < 0) goto error;
503
504     if (_bind(fd, type) < 0) goto error;
505
506     if (_listen(fd, type) < 0) goto error;
507
508     args.fd = fd;
509     pthread_create(&thread, NULL, (void *)thread_delay_close_write, (void *)&args);
510
511     _accept(fd, type);
512
513     pthread_join(thread, NULL);
514
515     return 0;
516
517 error:
518     return -1;
519 }
520
521 static int do_poll_poll_poll_shutdown(int type) {
522     const int MAX_T = 32;
523     int fd;
524     pthread_t t[MAX_T];
525     int i;
526
527     fd = _socket(type);
528
529     for (i=0; i<MAX_T; i++)
530         pthread_create(&t[i], NULL, (void *)thread_poll, (void *)fd);
531
532     sleep(1);
533
534     _shutdown(fd, SHUT_RDWR);
535
536     for (i=0; i<MAX_T; i++)
537         pthread_join(t[i], NULL);
538
539     _close(fd, type);
540
541     return 0;
542 }
543
544 static int do_poll_poll_poll_close(int type) {
545     const int MAX_T = 32;
546     int fd;
547     pthread_t t[MAX_T];
548     int i;
549
550     fd = _socket(type);
551
552     for (i=0; i<MAX_T; i++)
553         pthread_create(&t[i], NULL, (void *)thread_poll, (void *)fd);
554
555     sleep(1);
556
557     _close(fd, type);
558
559     for (i=0; i<MAX_T; i++)
560         pthread_join(t[i], NULL);
561
562     return 0;
563 }
564
565 static int do_read_read_read_close(int type) {
566     const int MAX_T = 32;
567     int fd;
568     pthread_t t[MAX_T];
569     int i;
570
571     fd = _socket(type);
572
573     for (i=0; i<MAX_T; i++)
574         pthread_create(&t[i], NULL, (void *)thread_read, (void *)fd);
575
576     sleep(1);
577
578     _close(fd, type);
579
580     for (i=0; i<MAX_T; i++)
581         pthread_join(t[i], NULL);
582
583     return 0;
584 }
585
586 static int do_read_read_read_shutdown(int type) {
587     const int MAX_T = 32;
588     int fd;
589     pthread_t t[MAX_T];
590     int i;
591
592     fd = _socket(type);
593
594     for (i=0; i<MAX_T; i++)
595         pthread_create(&t[i], NULL, (void *)thread_read, (void *)fd);
596
597     sleep(1);
598
599     _shutdown(fd, SHUT_RDWR);
600
601     for (i=0; i<MAX_T; i++)
602         pthread_join(t[i], NULL);
603
604     _close(fd, type);
605
606     return 0;
607 }
608
609 static int do_connected_read1_shutdown1(int type) {
610     int fd1, fd2;
611     pthread_t t1;
612     pthread_t t2;
613     struct thread_args a1 = {-1, type, 0};
614     struct thread_args a2 = {-1, type, 2};
615
616     fd1 = _socket(type);
617     if (fd1 < 0) goto error;
618
619     if (_bind(fd1, type) < 0) goto error;
620
621     if (_listen(fd1, type) < 0) goto error;
622
623     a1.fd = fd1;
624     pthread_create(&t1, NULL, (void *)thread_accept_write, (void *)&a1);
625
626     fd2 = _socket(type);
627     if (_connect(fd2, type)) goto error;
628
629     pthread_create(&t2, NULL, (void *)thread_shutdown, (void *)&fd2);
630     
631     while (1) if (_read(fd2)) break;
632
633     pthread_join(t1, NULL);
634     pthread_join(t2, NULL);
635
636     return 0;
637
638 error:
639     return -1;
640 }
641
642 // accept in one thread, connect from two different threads
643 static int do_accept_connect_connect(int type) {
644     int fd;
645     pthread_t t1;
646     pthread_t t2;
647     struct thread_args a1 = {-1, type, 1};
648     struct thread_args a2 = {-1, type, 2};
649
650     fd = _socket(type);
651     if (fd < 0) goto error;
652
653     if (_bind(fd, type) < 0) goto error;
654
655     if (_listen(fd, type) < 0) goto error;
656
657     pthread_create(&t1, NULL, (void *)thread_delay_connect, (void *)&a1);
658     pthread_create(&t2, NULL, (void *)thread_delay_connect, (void *)&a2);
659
660     _accept(fd, type);
661
662     pthread_join(t1, NULL);
663     pthread_join(t2, NULL);
664
665     return 0;
666
667 error:
668     return -1;
669 }
670
671 struct {
672     char *name;
673     int (*ptr)(int);
674 } action_table[]  = {
675     {"accept_accept_accept", do_accept_accept_accept},
676     {"accept_and_close", do_accept_and_close},
677     {"accept_shutdown", do_accept_shutdown},
678     {"connect_shutdown", do_connect_shutdown},
679     {"accept_close_write", do_accept_close_write},
680     {"accept_connect_connect", do_accept_connect_connect},
681     {"poll_poll_poll_shutdown", do_poll_poll_poll_shutdown},
682     {"poll_poll_poll_close", do_poll_poll_poll_close},
683     {"read_read_read_shutdown", do_read_read_read_shutdown},
684     {"read_read_read_close", do_read_read_read_close},
685     {"connected_read1_shutdown1", do_connected_read1_shutdown1},
686     {NULL, NULL},
687 };
688
689 struct {
690     char *name;
691     enum sock_type type;
692 } type_table[]  = {
693     {"unix", UNIX},
694     {"rfcomm", RFCOMM},
695     {"sco", SCO},
696     {"l2cap", L2CAP},
697     {"tcp", TCP},
698     {NULL, -1},
699 };
700
701 static void usage() {
702     int i;
703
704     printf("socktest TYPE ACTION\n");
705     printf("\nTYPE:\n");
706     for (i = 0; type_table[i].name; i++) {
707         printf("\t%s\n", type_table[i].name);
708     }
709     printf("\nACTION:\n");
710     for (i = 0; action_table[i].name; i++) {
711         printf("\t%s\n", action_table[i].name);
712     }
713 }
714
715 int main(int argc, char **argv) {
716     int i;
717     int type = -1;
718
719     if (argc != 3) {
720         usage();
721         return -1;
722     }
723     for (i = 0; type_table[i].name; i++) {
724         if (!strcmp(argv[1], type_table[i].name)) {
725             type = type_table[i].type;
726             break;
727         }
728     }
729     if (type == -1) {
730         usage();
731         return -1;
732     }
733     for (i = 0; action_table[i].name; i++) {
734         if (!strcmp(argv[2], action_table[i].name)) {
735             printf("TYPE = %s ACTION = %s\n", type_table[type].name,
736                     action_table[i].name);
737             return (*action_table[i].ptr)(type);
738         }
739     }
740     usage();
741     return -1;
742 }