Fix bug in group handling
[platform/core/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
27         if (is_emul_bin()) {
28                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
29                 return USB_ERROR_NOT_SUPPORTED;
30         }
31
32         if (!handle)
33                 return USB_ERROR_INVALID_PARAMETER;
34
35         if (!cloned_handle || *cloned_handle)
36                 return USB_ERROR_INVALID_PARAMETER;
37
38         *cloned_handle = (usb_accessory_h)malloc(sizeof(struct usb_accessory_s));
39         if (!(*cloned_handle)) {
40                 USB_LOG("FAIL: malloc()");
41                 return USB_ERROR_OPERATION_FAILED;
42         }
43
44         (*cloned_handle)->manufacturer = strdup(handle->manufacturer);
45         (*cloned_handle)->model = strdup(handle->model);
46         (*cloned_handle)->description = strdup(handle->description);
47         (*cloned_handle)->version = strdup(handle->version);
48         (*cloned_handle)->uri = strdup(handle->uri);
49         (*cloned_handle)->serial = strdup(handle->serial);
50         (*cloned_handle)->accPermission = false;
51
52         __USB_FUNC_EXIT__ ;
53     return USB_ERROR_NONE;
54 }
55
56 int usb_accessory_destroy(usb_accessory_h handle)
57 {
58         __USB_FUNC_ENTER__ ;
59
60         if (is_emul_bin()) {
61                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
62                 return USB_ERROR_NOT_SUPPORTED;
63         }
64
65         if (!handle)
66                 return USB_ERROR_INVALID_PARAMETER;
67
68         free_accessory(handle);
69
70         __USB_FUNC_EXIT__ ;
71         return USB_ERROR_NONE;
72 }
73
74 int usb_accessory_foreach_attached(usb_accessory_attached_cb callback, void *user_data)
75 {
76         __USB_FUNC_ENTER__ ;
77
78         struct usb_accessory_list *accList;
79         struct usb_accessory_list *tmpList;
80         bool ret;
81
82         if (is_emul_bin()) {
83                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
84                 return USB_ERROR_NOT_SUPPORTED;
85         }
86
87         if (!callback)
88                 return USB_ERROR_INVALID_PARAMETER;
89
90         accList = (struct usb_accessory_list *)malloc(sizeof(struct usb_accessory_list));
91         if (!accList) {
92                 USB_LOG("FAIL: malloc()");
93                 return USB_ERROR_OPERATION_FAILED;
94         }
95
96         ret = get_acc_list(&accList);
97         if (!ret) {
98                 USB_LOG("FAIL: getAccList()");
99                 free_acc_list(accList);
100                 return USB_ERROR_OPERATION_FAILED;
101         }
102
103         ret = true;
104         tmpList = accList;
105         while (ret) {
106                 if (!tmpList || !(tmpList->accessory)) {
107                         break;
108                 }
109                 ret = callback(tmpList->accessory, user_data);
110                 if (ret) {
111                         tmpList = tmpList->next;
112                 }
113         }
114
115         free_acc_list(accList);
116
117         __USB_FUNC_EXIT__ ;
118         return USB_ERROR_NONE;
119 }
120
121 int usb_accessory_set_connection_changed_cb(usb_accessory_connection_changed_cb callback,
122                                                 void* user_data)
123 {
124         __USB_FUNC_ENTER__ ;
125
126         int ret;
127
128         if (is_emul_bin()) {
129                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
130                 return USB_ERROR_NOT_SUPPORTED;
131         }
132
133         if (!callback)
134                 return USB_ERROR_INVALID_PARAMETER;
135
136         accCbData = (struct AccCbData *)malloc(sizeof(struct AccCbData));
137         if (!accCbData) {
138                 USB_LOG("FAIL: malloc()");
139                 return USB_ERROR_OPERATION_FAILED;
140         }
141
142         accCbData->user_data = user_data;
143         accCbData->connection_cb_func = callback;
144
145         ret = vconf_notify_key_changed(VCONFKEY_USB_ACCESSORY_STATUS,
146                                         accessory_status_changed_cb, accCbData);
147         if (ret < 0) {
148                 USB_LOG("FAIL: vconf_notify_key_changed()");
149                 return USB_ERROR_OPERATION_FAILED;
150         }
151
152         __USB_FUNC_EXIT__ ;
153         return USB_ERROR_NONE;
154 }
155
156 int usb_accessory_connection_unset_cb()
157 {
158         __USB_FUNC_ENTER__ ;
159
160         int ret;
161
162         if (is_emul_bin()) {
163                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
164                 return USB_ERROR_NOT_SUPPORTED;
165         }
166
167         FREE(accCbData);
168
169         ret = vconf_ignore_key_changed(VCONFKEY_USB_ACCESSORY_STATUS, accessory_status_changed_cb);
170         if (ret < 0) {
171                 USB_LOG("FAIL: vconf_ignore_key_changed()");
172                 return USB_ERROR_OPERATION_FAILED;
173         }
174
175         __USB_FUNC_EXIT__ ;
176         return USB_ERROR_NONE;
177 }
178
179 int usb_accessory_has_permission(usb_accessory_h accessory, bool* is_granted)
180 {
181         __USB_FUNC_ENTER__ ;
182
183         int ret;
184         int ipcResult;
185         int sockRemote;
186         char buf[SOCK_STR_LEN];
187         char *appId;
188
189         if (is_emul_bin()) {
190                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
191                 return USB_ERROR_NOT_SUPPORTED;
192         }
193
194         if (!accessory)
195                 return USB_ERROR_INVALID_PARAMETER;
196
197         if (accessory->accPermission) {
198                 __USB_FUNC_EXIT__ ;
199                 return USB_ERROR_NONE;
200         }
201
202         appId = get_app_id();
203         if(!appId) {
204                 USB_LOG("FAIL: get_app_id()");
205                 *is_granted = false;
206                 return USB_ERROR_NONE;
207         }
208
209         sockRemote = ipc_request_client_init();
210         if (sockRemote < 0) {
211                 USB_LOG("FAIL: ipc_request_client_init()");
212                 FREE(appId);
213                 return USB_ERROR_IPC_FAILED;
214         }
215
216         ret = request_to_usb_server(sockRemote, HAS_ACC_PERMISSION, appId, buf, sizeof(buf));
217         if (ret < 0) {
218                 USB_LOG("FAIL: request_to_usb_server()");
219                 close(sockRemote);
220                 FREE(appId);
221                 return USB_ERROR_IPC_FAILED;
222         }
223
224         close(sockRemote);
225         FREE(appId);
226
227         USB_LOG("Permission: %s", buf);
228         ipcResult = atoi(buf);
229         if (IPC_SUCCESS == ipcResult) {
230                 accessory->accPermission = true;
231                 *is_granted = true;
232         } else {
233                 accessory->accPermission = false;
234                 *is_granted = false;
235         }
236         __USB_FUNC_EXIT__ ;
237         return USB_ERROR_NONE;
238 }
239
240 int usb_accessory_open(usb_accessory_h accessory, FILE **fd)
241 {
242         __USB_FUNC_ENTER__ ;
243
244         if (is_emul_bin()) {
245                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
246                 return USB_ERROR_NOT_SUPPORTED;
247         }
248
249         if (!accessory)
250                 return USB_ERROR_INVALID_PARAMETER;
251
252         if (accessory->accPermission) {
253                 *fd = fopen(USB_ACCESSORY_NODE, "r+");
254                 USB_LOG("file pointer: %d", *fd);
255         } else {
256                 USB_LOG("Permission is not allowed");
257                 *fd = NULL;
258         }
259
260         __USB_FUNC_EXIT__ ;
261         return USB_ERROR_NONE;
262 }
263
264
265 int usb_accessory_get_description(usb_accessory_h accessory, char** description)
266 {
267         __USB_FUNC_ENTER__ ;
268
269         if (is_emul_bin()) {
270                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
271                 return USB_ERROR_NOT_SUPPORTED;
272         }
273
274         if (!accessory)
275                 return USB_ERROR_INVALID_PARAMETER;
276
277         *description = strdup(accessory->description);
278
279         __USB_FUNC_ENTER__ ;
280         return USB_ERROR_NONE;
281 }
282
283
284 int usb_accessory_get_manufacturer(usb_accessory_h accessory, char** manufacturer)
285 {
286         __USB_FUNC_ENTER__ ;
287
288         if (is_emul_bin()) {
289                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
290                 return USB_ERROR_NOT_SUPPORTED;
291         }
292
293         if (!accessory)
294                 return USB_ERROR_INVALID_PARAMETER;
295
296         *manufacturer = strdup(accessory->manufacturer);
297
298         __USB_FUNC_ENTER__ ;
299         return USB_ERROR_NONE;
300 }
301
302
303 int usb_accessory_get_model(usb_accessory_h accessory, char** model)
304 {
305         __USB_FUNC_ENTER__ ;
306
307         if (is_emul_bin()) {
308                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
309                 return USB_ERROR_NOT_SUPPORTED;
310         }
311
312         if (!accessory)
313                 return USB_ERROR_INVALID_PARAMETER;
314
315         *model = strdup(accessory->model);
316
317         __USB_FUNC_ENTER__ ;
318         return USB_ERROR_NONE;
319 }
320
321
322 int usb_accessory_get_serial(usb_accessory_h accessory, char** serial)
323 {
324         __USB_FUNC_ENTER__ ;
325
326         if (is_emul_bin()) {
327                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
328                 return USB_ERROR_NOT_SUPPORTED;
329         }
330
331         if (!accessory)
332                 return USB_ERROR_INVALID_PARAMETER;
333
334         *serial = strdup(accessory->serial);
335
336         __USB_FUNC_ENTER__ ;
337         return USB_ERROR_NONE;
338 }
339
340
341 int usb_accessory_get_version(usb_accessory_h accessory, char** version)
342 {
343         __USB_FUNC_ENTER__ ;
344
345         if (is_emul_bin()) {
346                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
347                 return USB_ERROR_NOT_SUPPORTED;
348         }
349
350         if (!accessory)
351                 return USB_ERROR_INVALID_PARAMETER;
352
353         *version = strdup(accessory->version);
354
355         __USB_FUNC_ENTER__ ;
356         return USB_ERROR_NONE;
357 }
358
359 int usb_accessory_is_connected(usb_accessory_h accessory, bool* is_connected)
360 {
361         __USB_FUNC_ENTER__ ;
362
363         int ret;
364         int val;
365
366         if (is_emul_bin()) {
367                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
368                 return USB_ERROR_NOT_SUPPORTED;
369         }
370
371         ret = vconf_get_int(VCONFKEY_USB_ACCESSORY_STATUS, &val);
372         if (ret < 0) {
373                 USB_LOG("FAIL: vconf_get_int()");
374                 return USB_ERROR_OPERATION_FAILED;
375         }
376
377         switch (val) {
378         case VCONFKEY_USB_ACCESSORY_STATUS_CONNECTED:
379                 *is_connected = true;
380                 break;
381         case VCONFKEY_USB_ACCESSORY_STATUS_DISCONNECTED:
382                 *is_connected = false;
383                 break;
384         default:
385                 USB_LOG("vconf key value is improper");
386                 return USB_ERROR_OPERATION_FAILED;
387         }
388
389         __USB_FUNC_EXIT__ ;
390         return USB_ERROR_NONE;
391 }
392
393 int usb_accessory_request_permission(usb_accessory_h accessory,
394                                 usb_accessory_permission_response_cb callback,
395                                 void* user_data)
396 {
397         __USB_FUNC_ENTER__ ;
398
399         int ret;
400         guint gret;
401         int fd;
402         int sockRemote;
403         char buf[SOCK_STR_LEN];
404         char *appId;
405         GError *err;
406         GIOStatus gioret;
407         GIOChannel *gioCh;
408
409         if (is_emul_bin()) {
410                 USB_LOG("FAIL:USB Accessory is not available with emulator.");
411                 return USB_ERROR_NOT_SUPPORTED;
412         }
413
414         if (!accessory)
415                 return USB_ERROR_INVALID_PARAMETER;
416         if (!callback)
417                 return USB_ERROR_INVALID_PARAMETER;
418         if (!accCbData)
419                 return USB_ERROR_INVALID_PARAMETER;
420
421         accCbData->user_data = accessory;
422         accCbData->request_perm_cb_func = callback;
423         accCbData->accessory = accessory;
424
425         fd = ipc_noti_client_init();
426         if (fd < 0) {
427                 USB_LOG("FAIL: ipc_noti_client_init()");
428                 goto out_ipc_fail;
429         }
430
431         gioCh = g_io_channel_unix_new(fd);
432         if (!gioCh) {
433                 USB_LOG("FAIL: g_io_channel_unix_new()");
434                 goto out_ipc_noti;
435         }
436
437         gret = g_io_add_watch(gioCh, G_IO_IN, ipc_noti_client_cb, (gpointer)accCbData);
438         if (gret == 0) {
439                 USB_LOG("FAIL: g_io_add_watch(g_io_ch, G_IO_IN)");
440                 goto out_gio_unref;
441         }
442
443         sockRemote = ipc_request_client_init();
444         if(sockRemote < 0) {
445                 USB_LOG("FAIL: ipc_request_client_init(&sock_remote)");
446                 goto out_gio_unref;
447         }
448
449         appId = get_app_id();
450         USB_LOG("App ID: %s", appId);
451         if (!appId) {
452                 USB_LOG("FAIL: get_app_id()");
453                 goto out_ipc_request;
454         }
455
456         ret = request_to_usb_server(sockRemote, REQ_ACC_PERMISSION, appId, buf, sizeof(buf));
457         if(ret < 0) {
458                 USB_LOG("FAIL: request_to_usb_server(REQ_ACC_PERMISSION)");
459                 goto out_app_id;
460         }
461
462         FREE(appId);
463         close(sockRemote);
464
465         __USB_FUNC_EXIT__ ;
466         return USB_ERROR_NONE;
467
468 out_app_id:
469         FREE(appId);
470 out_ipc_request:
471         close(sockRemote);
472 out_gio_unref:
473         gioret = g_io_channel_shutdown(gioCh, TRUE, &err);
474         if (G_IO_STATUS_ERROR == gioret)
475                 USB_LOG("ERROR: g_io_channel_shutdown()");
476         g_io_channel_unref(gioCh);
477 out_ipc_noti:
478         close(fd);
479 out_ipc_fail:
480         __USB_FUNC_EXIT__ ;
481         return USB_ERROR_IPC_FAILED;
482 }