Tizen 2.0 Release
[framework/api/usb-accessory.git] / src / usb_accessory.c
1 /*
2  * usb-accessory
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License. 
16  */
17
18 #include "usb_accessory.h"
19 #include "usb_accessory_private.h"
20
21 struct AccCbData *accCbData;
22
23 int usb_accessory_clone(usb_accessory_h handle, usb_accessory_h* cloned_handle)
24 {
25         __USB_FUNC_ENTER__ ;
26         if (!handle) return USB_ERROR_INVALID_PARAMETER;
27         if (is_emul_bin()) {
28                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
29                 return USB_ERROR_NOT_SUPPORTED;
30         }
31         if (!cloned_handle || *cloned_handle) return USB_ERROR_INVALID_PARAMETER;
32         *cloned_handle = (usb_accessory_h)malloc(sizeof(struct usb_accessory_s));
33         snprintf((*cloned_handle)->manufacturer, strlen(handle->manufacturer), "%s", handle->manufacturer);
34         snprintf((*cloned_handle)->model, strlen(handle->model), "%s", handle->model);
35         snprintf((*cloned_handle)->description, strlen(handle->description), "%s", handle->description);
36         snprintf((*cloned_handle)->version, strlen(handle->version), "%s", handle->version);
37         snprintf((*cloned_handle)->uri, strlen(handle->uri), "%s", handle->uri);
38         snprintf((*cloned_handle)->serial, strlen(handle->serial), "%s", handle->serial);
39
40         (*cloned_handle)->accPermission = false;
41
42         __USB_FUNC_EXIT__ ;
43     return USB_ERROR_NONE;
44 }
45
46 int usb_accessory_destroy(usb_accessory_h handle)
47 {
48     __USB_FUNC_ENTER__ ;
49         if (!handle) return USB_ERROR_INVALID_PARAMETER;
50         if (is_emul_bin()) {
51                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
52                 return USB_ERROR_NOT_SUPPORTED;
53         }
54         FREE(handle);
55         __USB_FUNC_EXIT__ ;
56         return USB_ERROR_NONE;
57 }
58
59 int usb_accessory_foreach_attached(usb_accessory_attached_cb callback, void *user_data)
60 {
61         __USB_FUNC_ENTER__ ;
62         if (callback == NULL) return USB_ERROR_INVALID_PARAMETER;
63         if (is_emul_bin()) {
64                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
65                 return USB_ERROR_NOT_SUPPORTED;
66         }
67         struct usb_accessory_list *accList = NULL;
68         struct usb_accessory_list *tmpList = NULL;
69         bool ret = false;
70         accList = (struct usb_accessory_list *)malloc(sizeof(struct usb_accessory_list));
71         if (!accList) {
72                 USB_LOG("FAIL: malloc()");
73                 return USB_ERROR_OPERATION_FAILED;
74         }
75         ret = getAccList(&accList);
76         if (ret == false) {
77                 USB_LOG("FAIL: getAccList(accList)");
78                 FREE(accList);
79                 return -1;
80         }
81
82         ret = true;
83         tmpList = accList;
84         while (ret) {
85                 if (tmpList == NULL || tmpList->accessory == NULL) {
86                         break;
87                 }
88                 ret = callback(tmpList->accessory, user_data);
89                 if (ret) {
90                         tmpList = tmpList->next;
91                 }
92         }
93
94         FREE(accList);
95
96         __USB_FUNC_EXIT__ ;
97     return USB_ERROR_NONE;
98 }
99
100
101 int usb_accessory_set_connection_changed_cb(usb_accessory_connection_changed_cb callback, void* user_data)
102 {
103         __USB_FUNC_ENTER__ ;
104         if (is_emul_bin()) {
105                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
106                 return USB_ERROR_NOT_SUPPORTED;
107         }
108         int ret = -1;
109         accCbData = (struct AccCbData *)malloc(sizeof(struct AccCbData));
110         accCbData->user_data = user_data;
111         accCbData->connection_cb_func = callback;
112         ret = vconf_notify_key_changed(VCONFKEY_USB_ACCESSORY_STATUS, accessory_status_changed_cb, accCbData);
113         um_retvm_if(ret < 0, USB_ERROR_OPERATION_FAILED, "FAIL: vconf_notify_key_changed(VCONFKEY_USB_ACCESSORY_STATUS)\n");
114         __USB_FUNC_EXIT__ ;
115     return USB_ERROR_NONE;
116 }
117  
118
119 int usb_accessory_connection_unset_cb()
120 {
121         __USB_FUNC_ENTER__ ;
122         if (is_emul_bin()) {
123                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
124                 return USB_ERROR_NOT_SUPPORTED;
125         }
126         if (accCbData != NULL) {
127                 FREE(accCbData);
128                 int ret = vconf_ignore_key_changed(VCONFKEY_USB_ACCESSORY_STATUS, accessory_status_changed_cb);
129                 um_retvm_if(ret < 0, USB_ERROR_OPERATION_FAILED, "FAIL: vconf_ignore_key_changed(VCONFKEY_USB_ACCESSORY_status");
130         }
131         __USB_FUNC_EXIT__ ;
132
133     return USB_ERROR_NONE;
134 }
135  
136
137 int usb_accessory_has_permission(usb_accessory_h accessory, bool* is_granted)
138 {
139         __USB_FUNC_ENTER__ ;
140         if (!accessory) return USB_ERROR_INVALID_PARAMETER;
141         if (is_emul_bin()) {
142                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
143                 return USB_ERROR_NOT_SUPPORTED;
144         }
145         if (accessory->accPermission == true) {
146                 __USB_FUNC_EXIT__ ;
147                 return USB_ERROR_NONE;
148         } else {
149                 int ret = -1;
150                 int ipc_result = -1;
151                 int sock_remote;
152                 char buf[SOCK_STR_LEN];
153                 char *app_id = get_app_id();
154                 if(app_id == NULL) {
155                         USB_LOG("FAIL: get_app_id()\n");
156                         *is_granted = false;
157                         return USB_ERROR_NONE;
158                 }
159
160                 ret = ipc_request_client_init(&sock_remote);
161                 um_retvm_if(ret < 0, USB_ERROR_IPC_FAILED, "FAIL: ipc_request_client_init()\n");
162
163                 ret = request_to_usb_server(sock_remote, HAS_ACC_PERMISSION, buf, app_id);
164                 um_retvm_if(ret < 0, USB_ERROR_IPC_FAILED, "FAIL: request_to_usb_server()\n");
165
166                 ret = ipc_request_client_close(&sock_remote);
167                 um_retvm_if(ret < 0, USB_ERROR_IPC_FAILED, "FAIL: ipc_request_client_close()\n");
168
169                 FREE(app_id);
170
171                 USB_LOG("Permission: %s\n", buf);
172                 ipc_result = atoi(buf);
173                 if (IPC_SUCCESS == ipc_result) {
174                         accessory->accPermission = true;
175                         *is_granted = true;
176                 } else {
177                         accessory->accPermission = false;
178                         *is_granted = false;
179                 }
180                 __USB_FUNC_EXIT__ ;
181                 return USB_ERROR_NONE;
182         }
183 }
184
185
186 int usb_accessory_open(usb_accessory_h accessory, FILE **fd)
187 {
188         __USB_FUNC_ENTER__ ;
189         if (!accessory) return USB_ERROR_INVALID_PARAMETER;
190         if (is_emul_bin()) {
191                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
192                 return USB_ERROR_NOT_SUPPORTED;
193         }
194         if (accessory->accPermission == true) {
195                 *fd = fopen(USB_ACCESSORY_NODE, "r+");
196                 USB_LOG("file pointer: %d", *fd);
197         } else {
198                 USB_LOG("Permission is not allowed");
199                 *fd = NULL;
200         }
201         __USB_FUNC_EXIT__ ;
202     return USB_ERROR_NONE;
203 }
204
205
206 int usb_accessory_get_description(usb_accessory_h accessory, char** description)
207 {
208         __USB_FUNC_ENTER__ ;
209         if (!accessory) return USB_ERROR_INVALID_PARAMETER;
210         if (is_emul_bin()) {
211                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
212                 return USB_ERROR_NOT_SUPPORTED;
213         }
214         *description = strdup(accessory->description);
215         __USB_FUNC_ENTER__ ;
216     return USB_ERROR_NONE;
217 }
218
219
220 int usb_accessory_get_manufacturer(usb_accessory_h accessory, char** manufacturer)
221 {
222         __USB_FUNC_ENTER__ ;
223         if (!accessory) return USB_ERROR_INVALID_PARAMETER;
224         if (is_emul_bin()) {
225                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
226                 return USB_ERROR_NOT_SUPPORTED;
227         }
228         *manufacturer = strdup(accessory->manufacturer);
229         __USB_FUNC_ENTER__ ;
230     return USB_ERROR_NONE;
231 }
232
233
234 int usb_accessory_get_model(usb_accessory_h accessory, char** model)
235 {
236         __USB_FUNC_ENTER__ ;
237         if (!accessory) return USB_ERROR_INVALID_PARAMETER;
238         if (is_emul_bin()) {
239                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
240                 return USB_ERROR_NOT_SUPPORTED;
241         }
242         *model = strdup(accessory->model);
243         __USB_FUNC_ENTER__ ;
244     return USB_ERROR_NONE;
245 }
246
247
248 int usb_accessory_get_serial(usb_accessory_h accessory, char** serial)
249 {
250         __USB_FUNC_ENTER__ ;
251         if (!accessory) return USB_ERROR_INVALID_PARAMETER;
252         if (is_emul_bin()) {
253                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
254                 return USB_ERROR_NOT_SUPPORTED;
255         }
256         *serial = strdup(accessory->serial);
257         __USB_FUNC_ENTER__ ;
258     return USB_ERROR_NONE;
259 }
260
261
262 int usb_accessory_get_version(usb_accessory_h accessory, char** version)
263 {
264         __USB_FUNC_ENTER__ ;
265         if (!accessory) return USB_ERROR_INVALID_PARAMETER;
266         if (is_emul_bin()) {
267                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
268                 return USB_ERROR_NOT_SUPPORTED;
269         }
270         *version = strdup(accessory->version);
271         __USB_FUNC_ENTER__ ;
272     return USB_ERROR_NONE;
273 }
274
275
276 int usb_accessory_is_connected(usb_accessory_h accessory, bool* is_connected)
277 {
278         __USB_FUNC_ENTER__ ;
279         if (is_emul_bin()) {
280                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
281                 return USB_ERROR_NOT_SUPPORTED;
282         }
283         int ret = -1;
284         int val = -1;
285         ret = vconf_get_int(VCONFKEY_USB_ACCESSORY_STATUS, &val);
286         um_retvm_if(ret < 0, USB_ERROR_OPERATION_FAILED, "FAIL: vconf_get_int(VCONFKEY_USB_ACCESSORY_STATUS)\n");
287         switch (val) {
288         case VCONFKEY_USB_ACCESSORY_STATUS_CONNECTED:
289                 *is_connected = true;
290                 break;
291         case VCONFKEY_USB_ACCESSORY_STATUS_DISCONNECTED:
292                 *is_connected = false;
293                 break;
294         }
295         __USB_FUNC_EXIT__ ;
296     return USB_ERROR_NONE;
297 }
298
299 int usb_accessory_request_permission(usb_accessory_h accessory, usb_accessory_permission_response_cb callback, void* user_data)
300 {
301         __USB_FUNC_ENTER__ ;
302         if (!accessory) return USB_ERROR_INVALID_PARAMETER;
303         if (!callback) return USB_ERROR_INVALID_PARAMETER;
304         if (is_emul_bin()) {
305                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
306                 return USB_ERROR_NOT_SUPPORTED;
307         }
308         int ret = -1;
309         guint g_ret = 0;
310         int sock_remote;
311         char buf[SOCK_STR_LEN];
312         char *app_id = NULL;
313         accCbData->user_data = accessory;
314         accCbData->request_perm_cb_func = callback;
315         accCbData->accessory = accessory;
316         GError *err;
317         GIOStatus gio_ret;
318
319         int fd = ipc_noti_client_init();
320         if (fd < 0) {
321                 USB_LOG("FAIL: ipc_noti_client_init()");
322                 return USB_ERROR_IPC_FAILED;
323         }
324
325         GIOChannel *g_io_ch = g_io_channel_unix_new(fd);
326         if (!g_io_ch) {
327                 USB_LOG("FAIL: g_io_channel_unix_new()");
328                 ret = ipc_noti_client_close(&fd);
329                 if (ret < 0) USB_LOG("FAIL: ipc_noti_client_close(&fd)\n");
330                 return USB_ERROR_IPC_FAILED;
331         }
332
333         g_ret = g_io_add_watch(g_io_ch, G_IO_IN, ipc_noti_client_cb, (gpointer)accCbData);
334         if (g_ret == 0) {
335                 USB_LOG("FAIL: g_io_add_watch(g_io_ch, G_IO_IN)\n");
336                 ret = ipc_noti_client_close(&fd);
337                 if (ret < 0) USB_LOG("FAIL: ipc_noti_client_close(&fd)\n");
338                 gio_ret = g_io_channel_shutdown(g_io_ch, TRUE, &err);
339                 if (G_IO_STATUS_ERROR == gio_ret) USB_LOG("ERROR: g_io_channel_shutdown(g_io_ch)\n");
340                 g_io_channel_unref(g_io_ch);
341                 return USB_ERROR_IPC_FAILED;
342         }
343
344         ret = ipc_request_client_init(&sock_remote);
345         if(ret < 0) {
346                 USB_LOG("FAIL: ipc_request_client_init(&sock_remote)\n");
347                 ret = ipc_request_client_close(&sock_remote);
348                 if (ret < 0) USB_LOG("FAIL: ipc_request_client_close(&sock_remote)\n");
349                 ret = ipc_noti_client_close(&fd);
350                 if (ret < 0) USB_LOG("FAIL: ipc_noti_client_close(&fd)\n");
351                 gio_ret = g_io_channel_shutdown(g_io_ch, TRUE, &err);
352                 if (G_IO_STATUS_ERROR == gio_ret) USB_LOG("ERROR: g_io_channel_shutdown(g_io_ch)\n");
353                 g_io_channel_unref(g_io_ch);
354                 return USB_ERROR_IPC_FAILED;
355         }
356
357         app_id = get_app_id();
358         USB_LOG("App ID: %s", app_id);
359         if (!app_id) {
360                 USB_LOG("FAIL: get_app_id()");
361                 ret = ipc_request_client_close(&sock_remote);
362                 if (ret < 0) USB_LOG("FAIL: ipc_request_client_close(&sock_remote)\n");
363                 ret = ipc_noti_client_close(&fd);
364                 if (ret < 0) USB_LOG("FAIL: ipc_noti_client_close(&fd)\n");
365                 gio_ret = g_io_channel_shutdown(g_io_ch, TRUE, &err);
366                 if (G_IO_STATUS_ERROR == gio_ret) USB_LOG("ERROR: g_io_channel_shutdown(g_io_ch)\n");
367                 g_io_channel_unref(g_io_ch);
368                 return USB_ERROR_OPERATION_FAILED;
369         }
370
371         ret = request_to_usb_server(sock_remote, REQ_ACC_PERMISSION, buf, app_id);
372         if(ret < 0) {
373                 USB_LOG("FAIL: request_to_usb_server(REQ_ACC_PERMISSION)\n");
374                 ret = ipc_request_client_close(&sock_remote);
375                 if (ret < 0) USB_LOG("FAIL: ipc_request_client_close(&sock_remote)\n");
376                 ret = ipc_noti_client_close(&fd);
377                 if (ret < 0) USB_LOG("FAIL: ipc_noti_client_close(&fd)\n");
378                 gio_ret = g_io_channel_shutdown(g_io_ch, TRUE, &err);
379                 if (G_IO_STATUS_ERROR == gio_ret) USB_LOG("ERROR: g_io_channel_shutdown(g_io_ch)\n");
380                 g_io_channel_unref(g_io_ch);
381                 FREE(app_id);
382                 return USB_ERROR_IPC_FAILED;
383         }
384
385         FREE(app_id);
386
387         ret = ipc_request_client_close(&sock_remote);
388         if (ret < 0) {
389                 USB_LOG("FAIL: ipc_request_client_close(&sock_remote)\n");
390                 ret = ipc_noti_client_close(&fd);
391                 if (ret < 0) USB_LOG("FAIL: ipc_noti_client_close(&fd)\n");
392                 gio_ret = g_io_channel_shutdown(g_io_ch, TRUE, &err);
393                 if (G_IO_STATUS_ERROR == gio_ret) USB_LOG("ERROR: g_io_channel_shutdown(g_io_ch)\n");
394                 g_io_channel_unref(g_io_ch);
395                 return USB_ERROR_IPC_FAILED;
396         }
397
398         __USB_FUNC_EXIT__ ;
399     return USB_ERROR_NONE;
400 }