Revert "improve plugin architecture"
[sdk/target/sdbd.git] / src / usb_linux_client.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <string.h>
21
22 #include <sys/ioctl.h>
23 #include <sys/types.h>
24 #include <dirent.h>
25 #include <errno.h>
26
27 #include "sysdeps.h"
28
29 #define   TRACE_TAG  TRACE_USB
30 #include "sdb.h"
31
32
33 struct usb_handle
34 {
35     int fd;
36     sdb_cond_t notify;
37     sdb_mutex_t lock;
38 };
39
40 static void *usb_open_thread(void *x)
41 {
42     struct usb_handle *usb = (struct usb_handle *)x;
43     int fd;
44
45     while (1) {
46         // wait until the USB device needs opening
47         sdb_mutex_lock(&usb->lock);
48         while (usb->fd != -1)
49             sdb_cond_wait(&usb->notify, &usb->lock);
50         sdb_mutex_unlock(&usb->lock);
51
52         D("[ usb_thread - opening device ]\n");
53         do {
54             /* XXX use inotify? */
55             fd = unix_open(USB_NODE_FILE, O_RDWR); /* tizen-specific */
56             if (fd < 0) {
57                 // to support older kernels
58                 //fd = unix_open("/dev/android", O_RDWR);
59                 D("[ opening %s device failed ]\n", USB_NODE_FILE);
60             }
61             if (fd < 0) {
62                 sdb_sleep_ms(1000);
63             }
64         } while (fd < 0);
65         D("[ opening device succeeded ]\n");
66
67         if (close_on_exec(fd) < 0) {
68             D("[closing fd exec failed ]\n");
69         }
70         usb->fd = fd;
71
72         D("[ usb_thread - registering device ]\n");
73         register_usb_transport(usb, 0, 1);
74     }
75
76     // never gets here
77     return 0;
78 }
79
80 // Public host/client interface
81
82 int linux_usb_write(usb_handle *h, const void *data, int len)
83 {
84     int n;
85
86     D("about to write (fd=%d, len=%d)\n", h->fd, len);
87     n = sdb_write(h->fd, data, len);
88     if(n != len) {
89         D("ERROR: fd = %d, n = %d, errno = %d\n",
90             h->fd, n, errno);
91         return -1;
92     }
93     D("[ done fd=%d ]\n", h->fd);
94     return 0;
95 }
96
97 int linux_usb_read(usb_handle *h, void *data, size_t len)
98 {
99     int n;
100
101     D("about to read (fd=%d, len=%d)\n", h->fd, len);
102     n = sdb_read(h->fd, data, len);
103     if(n != len) {
104         D("ERROR: fd = %d, n = %d, errno = %d\n",
105             h->fd, n, errno);
106         return -1;
107     }
108     D("[ done fd=%d ]\n", h->fd);
109     return 0;
110 }
111
112 void linux_usb_init()
113 {
114     usb_handle *h;
115     sdb_thread_t tid;
116 //  int fd;
117
118     h = calloc(1, sizeof(usb_handle));
119     if (h == NULL) {
120         D("failed to allocate memory of usb_handle\n");
121         return;
122     }
123
124     h->fd = -1;
125     sdb_cond_init(&h->notify, 0);
126     sdb_mutex_init(&h->lock, 0);
127
128     // Open the file /dev/android_sdb_enable to trigger
129     // the enabling of the sdb USB function in the kernel.
130     // We never touch this file again - just leave it open
131     // indefinitely so the kernel will know when we are running
132     // and when we are not.
133 #if 0 /* tizen specific */
134     fd = unix_open("/dev/android_sdb_enable", O_RDWR);
135     if (fd < 0) {
136        D("failed to open /dev/android_sdb_enable\n");
137     } else {
138         close_on_exec(fd);
139     }
140 #endif
141     D("[ usb_init - starting thread ]\n");
142     if(sdb_thread_create(&tid, usb_open_thread, h)){
143         fatal_errno("cannot create usb thread");
144     }
145 }
146
147 void linux_usb_kick(usb_handle *h)
148 {
149     D("usb_kick\n");
150     sdb_mutex_lock(&h->lock);
151     sdb_close(h->fd);
152     h->fd = -1;
153
154     // notify usb_open_thread that we are disconnected
155     sdb_cond_signal(&h->notify);
156     sdb_mutex_unlock(&h->lock);
157 }
158
159 int linux_usb_close(usb_handle *h)
160 {
161     // nothing to do here
162     return 0;
163 }
164
165 void linux_usb_cleanup()
166 {
167     // nothing to do here
168 }