usb_linux_client.c revision 35237d135807af84bf9b0e5b8d7f8633e58db6f5
14a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall/*
24a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * Copyright (C) 2007 The Android Open Source Project
34a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall *
44a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * Licensed under the Apache License, Version 2.0 (the "License");
54a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * you may not use this file except in compliance with the License.
64a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * You may obtain a copy of the License at
74a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall *
84a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall *      http://www.apache.org/licenses/LICENSE-2.0
94a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall *
104a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * Unless required by applicable law or agreed to in writing, software
114a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * distributed under the License is distributed on an "AS IS" BASIS,
124a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * See the License for the specific language governing permissions and
144a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * limitations under the License.
154a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall */
164a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
174a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#include <stdio.h>
184a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#include <stdlib.h>
194a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#include <unistd.h>
204a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#include <string.h>
21fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall
22db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall#include <sys/ioctl.h>
234a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#include <sys/types.h>
244a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#include <dirent.h>
25db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall#include <errno.h>
26db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
27db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall#include "sysdeps.h"
28db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
29db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall#define   TRACE_TAG  TRACE_USB
30db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall#include "adb.h"
31db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
32db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
33db7da58e8d2aa021060098057f944ef754be06e3JP Abgrallstruct usb_handle
34db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall{
35db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    int fd;
36db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    adb_cond_t notify;
37db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    adb_mutex_t lock;
38db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall};
39db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
40db7da58e8d2aa021060098057f944ef754be06e3JP Abgrallvoid usb_cleanup()
41db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall{
42db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    // nothing to do here
43db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall}
44db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
45db7da58e8d2aa021060098057f944ef754be06e3JP Abgrallstatic void *usb_open_thread(void *x)
46db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall{
47db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    struct usb_handle *usb = (struct usb_handle *)x;
48fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall    int fd;
490031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall
500031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    while (1) {
510031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        // wait until the USB device needs opening
520031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall        adb_mutex_lock(&usb->lock);
53fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        while (usb->fd != -1)
54fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall            adb_cond_wait(&usb->notify, &usb->lock);
550dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall        adb_mutex_unlock(&usb->lock);
568a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
57fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        D("[ usb_thread - opening device ]\n");
58fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall        do {
590dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            /* XXX use inotify? */
608a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            fd = unix_open("/dev/android_adb", O_RDWR);
610dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall            if (fd < 0) {
620dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall                // to support older kernels
63fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall                fd = unix_open("/dev/android", O_RDWR);
64fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall            }
654a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall            if (fd < 0) {
668a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall                adb_sleep_ms(1000);
678a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            }
68c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        } while (fd < 0);
69c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall        D("[ opening device succeeded ]\n");
708a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
718a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        close_on_exec(fd);
728a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        usb->fd = fd;
738a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
748a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        D("[ usb_thread - registering device ]\n");
758a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        register_usb_transport(usb, 0);
760dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    }
77db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
78db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    // never gets here
79db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    return 0;
80db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall}
81a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall
82db7da58e8d2aa021060098057f944ef754be06e3JP Abgrallint usb_write(usb_handle *h, const void *data, int len)
838e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey{
848e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    int n;
858e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey
868e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    D("[ write %d ]\n", len);
878e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    n = adb_write(h->fd, data, len);
888e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    if(n != len) {
894a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall        D("ERROR: n = %d, errno = %d (%s)\n",
908a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall            n, errno, strerror(errno));
918a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        return -1;
928a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    }
938a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    D("[ done ]\n");
948a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    return 0;
958a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall}
968a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
978a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrallint usb_read(usb_handle *h, void *data, int len)
98db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall{
9926e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    int n;
10026e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall
10126e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    D("[ read %d ]\n", len);
10226e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    n = adb_read(h->fd, data, len);
10326e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    if(n != len) {
10426e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall        D("ERROR: n = %d, errno = %d (%s)\n",
1051fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall            n, errno, strerror(errno));
1061fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall        return -1;
1071fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall    }
1081fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall    return 0;
1091fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall}
11026e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall
1114a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrallvoid usb_init()
11226e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall{
11326e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    usb_handle *h;
1140dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    adb_thread_t tid;
1150dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    int fd;
11626e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall
1170dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    h = calloc(1, sizeof(usb_handle));
1188a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    h->fd = -1;
119c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    adb_cond_init(&h->notify, 0);
1208a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    adb_mutex_init(&h->lock, 0);
1210dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
12226e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    // Open the file /dev/android_adb_enable to trigger
1230dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    // the enabling of the adb USB function in the kernel.
1241fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall    // We never touch this file again - just leave it open
1251fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall    // indefinitely so the kernel will know when we are running
1261fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall    // and when we are not.
1271fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall    fd = unix_open("/dev/android_adb_enable", O_RDWR);
1281fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall    if (fd < 0) {
12926e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall       D("failed to open /dev/android_adb_enable\n");
13026e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    } else {
13126e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall        close_on_exec(fd);
1320dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    }
1338a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1348a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    D("[ usb_init - starting thread ]\n");
1358a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    if(adb_thread_create(&tid, usb_open_thread, h)){
1368a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        fatal_errno("cannot create usb thread");
1378a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    }
13811b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall}
139db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
140db7da58e8d2aa021060098057f944ef754be06e3JP Abgrallvoid usb_kick(usb_handle *h)
141a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall{
14211b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall    D("usb_kick\n");
143a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall    adb_mutex_lock(&h->lock);
1440031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    adb_close(h->fd);
145db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    h->fd = -1;
146db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
147db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    // notify usb_open_thread that we are disconnected
148db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    adb_cond_signal(&h->notify);
149db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    adb_mutex_unlock(&h->lock);
150db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall}
151db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
152c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrallint usb_close(usb_handle *h)
153c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall{
154c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    // nothing to do here
155c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    return 0;
156c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall}
157c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall