patch tizen_2.0_build
[framework/api/usb-accessory.git] / src / usb_accessory.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 "usb_accessory.h"
18 #include "usb_accessory_private.h"
19
20 struct AccCbData *accCbData;
21
22 int usb_accessory_clone(usb_accessory_h handle, usb_accessory_h* cloned_handle)
23 {
24         __USB_FUNC_ENTER__ ;
25         if (!handle) return USB_ERROR_INVALID_PARAMETER;
26         if (!cloned_handle || *cloned_handle) return USB_ERROR_INVALID_PARAMETER;
27         *cloned_handle = (usb_accessory_h)malloc(sizeof(struct usb_accessory_s));
28         snprintf((*cloned_handle)->manufacturer, strlen(handle->manufacturer), "%s", handle->manufacturer);
29         snprintf((*cloned_handle)->model, strlen(handle->model), "%s", handle->model);
30         snprintf((*cloned_handle)->description, strlen(handle->description), "%s", handle->description);
31         snprintf((*cloned_handle)->version, strlen(handle->version), "%s", handle->version);
32         snprintf((*cloned_handle)->uri, strlen(handle->uri), "%s", handle->uri);
33         snprintf((*cloned_handle)->serial, strlen(handle->serial), "%s", handle->serial);
34
35         (*cloned_handle)->accPermission = false;
36
37         __USB_FUNC_EXIT__ ;
38     return USB_ERROR_NONE;
39 }
40
41 int usb_accessory_destroy(usb_accessory_h handle)
42 {
43     __USB_FUNC_ENTER__ ;
44         if (!handle) return USB_ERROR_INVALID_PARAMETER;
45         FREE(handle);
46         __USB_FUNC_EXIT__ ;
47         return USB_ERROR_NONE;
48 }
49
50 int usb_accessory_foreach_attached(usb_accessory_attached_cb callback, void *user_data)
51 {
52         __USB_FUNC_ENTER__ ;
53         struct usb_accessory_list *accList = NULL;
54         struct usb_accessory_list *tmpList = NULL;
55         bool ret = false;
56         ret = getAccList(&accList);
57         um_retvm_if(ret == false, -1, "FAIL: getAccList(accList)\n");
58         um_retvm_if(accList == NULL, -1, "ERROR: accList == NULL\n");
59
60         ret = true;
61         tmpList = accList;
62         while (ret) {
63                 if (tmpList == NULL || tmpList->accessory == NULL) {
64                         break;
65                 }
66                 ret = callback(tmpList->accessory, user_data);
67                 if (ret) {
68                         tmpList = tmpList->next;
69                 }
70         }
71
72         ret = freeAccList(accList);
73         um_retvm_if(ret == false, USB_ERROR_OPERATION_FAILED, "FAIL: freeAccList(accList)\n");
74
75         __USB_FUNC_EXIT__ ;
76     return USB_ERROR_NONE;
77 }
78
79
80 int usb_accessory_set_connection_changed_cb(usb_accessory_connection_changed_cb callback, void* user_data)
81 {
82         __USB_FUNC_ENTER__ ;
83         int ret = -1;
84         accCbData = (struct AccCbData *)malloc(sizeof(struct AccCbData));
85         accCbData->user_data = user_data;
86         accCbData->connection_cb_func = callback;
87         ret = vconf_notify_key_changed(VCONFKEY_USB_ACCESSORY_STATUS, accessory_status_changed_cb, accCbData);
88         um_retvm_if(ret < 0, USB_ERROR_OPERATION_FAILED, "FAIL: vconf_notify_key_changed(VCONFKEY_USB_ACCESSORY_STATUS)\n");
89         __USB_FUNC_EXIT__ ;
90     return USB_ERROR_NONE;
91 }
92  
93
94 int usb_accessory_connection_unset_cb()
95 {
96         __USB_FUNC_ENTER__ ;
97         if (accCbData != NULL) {
98                 FREE(accCbData);
99                 int ret = vconf_ignore_key_changed(VCONFKEY_USB_ACCESSORY_STATUS, accessory_status_changed_cb);
100                 um_retvm_if(ret < 0, USB_ERROR_OPERATION_FAILED, "FAIL: vconf_ignore_key_changed(VCONFKEY_USB_ACCESSORY_status");
101         }
102         __USB_FUNC_EXIT__ ;
103
104     return USB_ERROR_NONE;
105 }
106  
107
108 int usb_accessory_has_permission(usb_accessory_h accessory, bool* is_granted)
109 {
110         __USB_FUNC_ENTER__ ;
111         if (!accessory) return USB_ERROR_INVALID_PARAMETER;
112         if (accessory->accPermission == true) {
113                 __USB_FUNC_EXIT__ ;
114                 return USB_ERROR_NONE;
115         } else {
116                 int ret = -1;
117                 int ipc_result = -1;
118                 int sock_remote;
119                 char buf[SOCK_STR_LEN];
120                 char *app_id = get_app_id();
121                 if(app_id == NULL) {
122                         USB_LOG("FAIL: get_app_id()\n");
123                         *is_granted = false;
124                         return USB_ERROR_NONE;
125                 }
126
127                 ret = ipc_request_client_init(&sock_remote);
128                 um_retvm_if(ret < 0, USB_ERROR_PERMISSION_DENIED, "FAIL: ipc_request_client_init(&sock_remote)\n");
129
130                 ret = request_to_usb_server(sock_remote, HAS_PERMISSION, buf, app_id);
131                 um_retvm_if(ret < 0, USB_ERROR_PERMISSION_DENIED, "FAIL: request_to_usb_server(HAS_PERMISSION)\n");
132
133                 ret = ipc_request_client_close(&sock_remote);
134                 um_retvm_if(ret < 0, USB_ERROR_PERMISSION_DENIED, "FAIL: ipc_request_client_close(&sock_remote)\n");
135
136                 FREE(app_id);
137
138                 USB_LOG("Permission: %s\n", buf);
139                 ipc_result = atoi(buf);
140                 if (IPC_SUCCESS == ipc_result) {
141                         accessory->accPermission = true;
142                         *is_granted = true;
143                 } else {
144                         accessory->accPermission = false;
145                         *is_granted = false;
146                 }
147                 __USB_FUNC_EXIT__ ;
148                 return USB_ERROR_NONE;
149         }
150 }
151
152
153 int usb_accessory_open(usb_accessory_h accessory, FILE **fd)
154 {
155         __USB_FUNC_ENTER__ ;
156         if (!accessory) return USB_ERROR_INVALID_PARAMETER;
157         if (accessory->accPermission == true) {
158                 *fd = fopen(USB_ACCESSORY_NODE, "r+");
159                 USB_LOG("file pointer: %d", *fd);
160         } else {
161                 USB_LOG("Permission is not allowed");
162                 *fd = NULL;
163         }
164         __USB_FUNC_EXIT__ ;
165     return USB_ERROR_NONE;
166 }
167
168
169 int usb_accessory_get_description(usb_accessory_h accessory, char** description)
170 {
171         __USB_FUNC_ENTER__ ;
172         if (!accessory) return USB_ERROR_INVALID_PARAMETER;
173         *description = strdup(accessory->description);
174         __USB_FUNC_ENTER__ ;
175     return USB_ERROR_NONE;
176 }
177
178
179 int usb_accessory_get_manufacturer(usb_accessory_h accessory, char** manufacturer)
180 {
181         __USB_FUNC_ENTER__ ;
182         if (!accessory) return USB_ERROR_INVALID_PARAMETER;
183         *manufacturer = strdup(accessory->manufacturer);
184         __USB_FUNC_ENTER__ ;
185     return USB_ERROR_NONE;
186 }
187
188
189 int usb_accessory_get_model(usb_accessory_h accessory, char** model)
190 {
191         __USB_FUNC_ENTER__ ;
192         if (!accessory) return USB_ERROR_INVALID_PARAMETER;
193         *model = strdup(accessory->model);
194         __USB_FUNC_ENTER__ ;
195     return USB_ERROR_NONE;
196 }
197
198
199 int usb_accessory_get_serial(usb_accessory_h accessory, char** serial)
200 {
201         __USB_FUNC_ENTER__ ;
202         if (!accessory) return USB_ERROR_INVALID_PARAMETER;
203         *serial = strdup(accessory->serial);
204         __USB_FUNC_ENTER__ ;
205     return USB_ERROR_NONE;
206 }
207
208
209 int usb_accessory_get_version(usb_accessory_h accessory, char** version)
210 {
211         __USB_FUNC_ENTER__ ;
212         if (!accessory) return USB_ERROR_INVALID_PARAMETER;
213         *version = strdup(accessory->version);
214         __USB_FUNC_ENTER__ ;
215     return USB_ERROR_NONE;
216 }
217
218
219 int usb_accessory_is_connected(usb_accessory_h accessory, bool* is_connected)
220 {
221         __USB_FUNC_ENTER__ ;
222         int ret = -1;
223         int val = -1;
224         ret = vconf_get_int(VCONFKEY_USB_ACCESSORY_STATUS, &val);
225         um_retvm_if(ret < 0, USB_ERROR_OPERATION_FAILED, "FAIL: vconf_get_int(VCONFKEY_USB_ACCESSORY_STATUS)\n");
226         switch (val) {
227         case VCONFKEY_USB_ACCESSORY_STATUS_CONNECTED:
228                 *is_connected = true;
229                 break;
230         case VCONFKEY_USB_ACCESSORY_STATUS_DISCONNECTED:
231                 *is_connected = false;
232                 break;
233         }
234         __USB_FUNC_EXIT__ ;
235     return USB_ERROR_NONE;
236 }
237
238 int usb_accessory_request_permission(usb_accessory_h accessory, usb_accessory_permission_response_cb callback, void* user_data)
239 {
240         __USB_FUNC_ENTER__ ;
241         if (!accessory) return USB_ERROR_INVALID_PARAMETER;
242         if (!callback) return USB_ERROR_INVALID_PARAMETER;
243         int ret = -1;
244         guint g_ret = 0;
245         int sock_remote;
246         char buf[SOCK_STR_LEN];
247         char *app_id = get_app_id();
248         accCbData->user_data = accessory;
249         accCbData->request_perm_cb_func = callback;
250         accCbData->accessory = accessory;
251         GError *err;
252         GIOStatus gio_ret;
253
254         int fd = ipc_noti_client_init();
255         GIOChannel *g_io_ch = g_io_channel_unix_new(fd);
256         g_ret = g_io_add_watch(g_io_ch, G_IO_IN, ipc_noti_client_cb, (gpointer)accCbData);
257         um_retvm_if (0 == g_ret, USB_ERROR_PERMISSION_DENIED, "FAIL: g_io_add_watch(g_io_ch, G_IO_IN)\n");
258
259         ret = ipc_request_client_init(&sock_remote);
260         if(ret < 0) {
261                 USB_LOG("FAIL: ipc_request_client_init(&sock_remote)\n");
262                 ret = ipc_request_client_close(&sock_remote);
263                 if (ret < 0) USB_LOG("FAIL: ipc_request_client_close(&sock_remote)\n");
264                 ret = ipc_noti_client_close(&fd);
265                 if (ret < 0) USB_LOG("FAIL: ipc_noti_client_close(&fd)\n");
266                 gio_ret = g_io_channel_shutdown(g_io_ch, TRUE, &err);
267                 if (G_IO_STATUS_ERROR == gio_ret) USB_LOG("ERROR: g_io_channel_shutdown(g_io_ch)\n");
268                 g_io_channel_unref(g_io_ch);
269                 FREE(app_id);
270                 return USB_ERROR_PERMISSION_DENIED;
271         }
272
273         ret = request_to_usb_server(sock_remote, REQUEST_PERMISSION, buf, app_id);
274         if(ret < 0) {
275                 USB_LOG("FAIL: request_to_usb_server(REQUEST_PERMISSION)\n");
276                 ret = ipc_request_client_close(&sock_remote);
277                 if (ret < 0) USB_LOG("FAIL: ipc_request_client_close(&sock_remote)\n");
278                 ret = ipc_noti_client_close(&fd);
279                 if (ret < 0) USB_LOG("FAIL: ipc_noti_client_close(&fd)\n");
280                 gio_ret = g_io_channel_shutdown(g_io_ch, TRUE, &err);
281                 if (G_IO_STATUS_ERROR == gio_ret) USB_LOG("ERROR: g_io_channel_shutdown(g_io_ch)\n");
282                 g_io_channel_unref(g_io_ch);
283                 FREE(app_id);
284                 return USB_ERROR_PERMISSION_DENIED;
285         }
286
287         FREE(app_id);
288
289         ret = ipc_request_client_close(&sock_remote);
290         if (ret < 0) {
291                 USB_LOG("FAIL: ipc_request_client_close(&sock_remote)\n");
292                 ret = ipc_noti_client_close(&fd);
293                 if (ret < 0) USB_LOG("FAIL: ipc_noti_client_close(&fd)\n");
294                 gio_ret = g_io_channel_shutdown(g_io_ch, TRUE, &err);
295                 if (G_IO_STATUS_ERROR == gio_ret) USB_LOG("ERROR: g_io_channel_shutdown(g_io_ch)\n");
296                 g_io_channel_unref(g_io_ch);
297                 return USB_ERROR_PERMISSION_DENIED;
298         }
299
300         __USB_FUNC_EXIT__ ;
301     return USB_ERROR_NONE;
302 }