tizen 2.3 release
[framework/system/deviced.git] / src / usb / usb-client-config.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <vconf.h>
20 #include <stdbool.h>
21 #include <stdlib.h>
22 #include "core/log.h"
23 #include "core/list.h"
24 #include "usb-client.h"
25 #include "core/config-parser.h"
26
27 #define BUF_MAX 128
28
29 #define USB_CLIENT_CONFIGURATION    "/etc/deviced/usb-client-configuration.conf"
30 #define USB_CLIENT_OPERATION        "/etc/deviced/usb-client-operation.conf"
31
32 #define SECTION_ROOT_PATH  "RootPath"
33 #define NAME_PATH          "path"
34
35 struct operation_data {
36         char *action;
37         char *mode;
38 };
39
40 struct usb_client_mode {
41         int mode;
42         char *name;
43 };
44
45 struct usb_client_mode usb_mode_match[] = {
46         { SET_USB_NONE             ,    "None"      },
47         { SET_USB_DEFAULT          ,    "Default"   },
48         { SET_USB_SDB              ,    "Sdb"       },
49         { SET_USB_SDB_DIAG         ,    "SdbDiag"   },
50         { SET_USB_RNDIS            ,    "Rndis"     },
51         { SET_USB_RNDIS_TETHERING  ,    "Rndis"     },
52         { SET_USB_RNDIS_DIAG       ,    "RndisDiag" },
53         { SET_USB_RNDIS_SDB        ,    "RndisSdb"  },
54         { SET_USB_DIAG_SDB         ,    "DiagSdb"   },
55         { SET_USB_DIAG_RMNET       ,    "DiagRmnet" },
56 };
57
58 static dd_list *oper_list;       /* Operations for USB mode */
59 static dd_list *conf_list;       /* Configurations for usb mode */
60 static char root_path[BUF_MAX] = {0,};
61
62
63 int get_operations_list(dd_list **list)
64 {
65         if (!list)
66                 return -EINVAL;
67
68         *list = oper_list;
69         return 0;
70 }
71
72 int get_configurations_list(dd_list **list)
73 {
74         if (!list)
75                 return -EINVAL;
76
77         *list = conf_list;
78         return 0;
79 }
80
81 int get_root_path(char **path)
82 {
83         if (strlen(root_path) <= 0)
84                 return -EINVAL;
85
86         *path = root_path;
87         return 0;
88 }
89
90 static int find_usb_mode_str(int usb_mode, char **name)
91 {
92         int i;
93
94         if (!name)
95                 return -EINVAL;
96
97         for (i = 0 ; i < ARRAY_SIZE(usb_mode_match) ; i++) {
98                 if (usb_mode == usb_mode_match[i].mode) {
99                         *name = usb_mode_match[i].name;
100                         return 0;
101                 }
102         }
103
104         _E("Failed to find usb mode (%d)", usb_mode);
105         return -EINVAL;
106 }
107
108 static int load_configuration_config(struct parse_result *result, void *user_data)
109 {
110         char *name = user_data;
111         int i;
112         size_t res_sec_len, res_name_len, name_len;
113         size_t root_path_len, path_len;
114         struct usb_configuration *conf;
115
116         if (!result)
117                 return -EINVAL;
118
119         res_sec_len = strlen(result->section);
120
121         root_path_len = strlen(SECTION_ROOT_PATH);
122         if (res_sec_len == root_path_len
123                         && !strncmp(result->section, SECTION_ROOT_PATH, res_sec_len)) {
124
125                 res_name_len = strlen(result->name);
126                 path_len = strlen(NAME_PATH);
127                 if (res_name_len == path_len
128                                 && !strncmp(result->name, NAME_PATH, res_name_len))
129                         snprintf(root_path, sizeof(root_path), "%s", result->value);
130
131                 return 0;
132         }
133
134         name_len = strlen(name);
135         if (res_sec_len != name_len
136                         || strncmp(result->section, name, res_sec_len))
137                 return 0;
138
139         conf = (struct usb_configuration *)malloc(sizeof(struct usb_configuration));
140         if (!conf) {
141                 _E("malloc() failed");
142                 return -ENOMEM;
143         }
144
145         snprintf(conf->name, sizeof(conf->name), "%s", result->name);
146         snprintf(conf->value, sizeof(conf->value), "%s", result->value);
147
148         DD_LIST_APPEND(conf_list, conf);
149         _I("USB configuration: name(%s), value(%s)", conf->name, conf->value);
150
151         return 0;
152 }
153
154 int make_configuration_list(int usb_mode)
155 {
156         int i, ret = 0;
157         char *name = NULL;
158
159         ret = find_usb_mode_str(usb_mode, &name);
160         if (ret < 0) {
161                 _E("Failed to get usb mode string (%d)", ret);
162                 return ret;
163         }
164
165         ret = config_parse(USB_CLIENT_CONFIGURATION, load_configuration_config, name);
166         if (ret < 0)
167                 _E("Failed to load usb configurations");
168
169         return ret;
170 }
171
172 void release_configuration_list(void)
173 {
174         dd_list *l;
175         struct usb_configuration *conf;
176
177         if (!conf_list)
178                 return;
179
180         DD_LIST_FOREACH(conf_list, l, conf) {
181                 if (conf)
182                         free(conf);
183         }
184
185         DD_LIST_FREE_LIST(conf_list);
186         conf_list = NULL;
187 }
188
189 /* Getting operations for each usb mode */
190 static int load_operation_config(struct parse_result *result, void *user_data)
191 {
192         struct operation_data *op_data = user_data;
193         int i;
194         size_t res_sec_len, res_name_len, mode_len, action_len;
195         struct usb_operation *oper;
196
197         if (!result)
198                 return -EINVAL;
199
200         res_sec_len = strlen(result->section);
201         mode_len = strlen(op_data->mode);
202         if (res_sec_len != mode_len
203                         || strncmp(result->section, op_data->mode, res_sec_len))
204                 return 0;
205
206         res_name_len = strlen(result->name);
207         action_len = strlen(op_data->action);
208         if (res_name_len != action_len
209                         || strncmp(result->name, op_data->action, res_name_len))
210                 return 0;
211
212         oper = (struct usb_operation *)malloc(sizeof(struct usb_operation));
213         if (!oper) {
214                 _E("malloc() failed");
215                 return -ENOMEM;
216         }
217
218         snprintf(oper->name, sizeof(oper->name), "%s", result->name);
219         snprintf(oper->oper, sizeof(oper->oper), "%s", result->value);
220
221         DD_LIST_APPEND(oper_list, oper);
222         _I("USB operation: name(%s), value(%s)", oper->name, oper->oper);
223
224         return 0;
225 }
226
227 int make_operation_list(int usb_mode, char *action)
228 {
229         int ret = 0;
230         char *mode;
231         struct operation_data op_data;
232
233         if (!action)
234                 return -EINVAL;
235
236         ret = find_usb_mode_str(usb_mode, &mode);
237         if (ret < 0) {
238                 _E("Failed to get usb mode string (%d)", ret);
239                 return ret;
240         }
241
242         op_data.action = action;
243         op_data.mode = mode;
244
245         ret = config_parse(USB_CLIENT_OPERATION, load_operation_config, &op_data);
246         if (ret < 0)
247                 _E("Failed to load usb configurations");
248
249         return ret;
250 }
251
252 void release_operations_list(void)
253 {
254         dd_list *l;
255         struct usb_operation *oper;
256
257         if (!oper_list)
258                 return;
259
260         DD_LIST_FOREACH(oper_list, l, oper) {
261                 if (oper)
262                         free(oper);
263         }
264
265         DD_LIST_FREE_LIST(oper_list);
266         oper_list = NULL;
267 }