tizen 2.3 release
[framework/system/deviced.git] / src / usb / usb-client-set.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2013 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 "core/log.h"
22 #include "core/devices.h"
23 #include "core/launch.h"
24 #include "usb-client.h"
25
26 #define BUF_MAX 256
27
28 #define TICKER_TYPE_DEFAULT "usb-client-default"
29 #define TICKER_TYPE_SSH     "usb-client-ssh"
30
31 #ifdef TIZEN_ENGINEER_MODE
32 const static bool eng_mode = true;
33 #else
34 const static bool eng_mode = false;
35 #endif
36
37 static int debug = 0;
38
39 static int write_sysfs(char *path, char *value)
40 {
41         FILE *fp;
42         int ret;
43         char *conf;
44
45         if (strlen(path) == 0)
46                 return -ENOMEM;
47
48         if (strlen(value) > 0)
49                 conf = value;
50         else
51                 conf = " ";
52
53         fp = fopen(path, "w");
54         if (!fp) {
55                 _E("FAIL: fopen(%s)", path);
56                 return -ENOMEM;
57         }
58
59         ret = fwrite(conf, sizeof(char), strlen(conf), fp);
60         if (ret < strlen(conf)) {
61                 _E("FAIL: fwrite(%s)", conf);
62                 ret = -ENOMEM;
63         }
64
65         if (fclose(fp) != 0)
66                 _E("FAIL: fclose()");
67         return ret;
68 }
69
70 static int set_configurations_to_sysfs(dd_list *list)
71 {
72         dd_list *l;
73         struct usb_configuration *conf;
74         int ret;
75         char *root_path, path[BUF_MAX];
76
77         if (!list)
78                 return -EINVAL;
79
80         ret = get_root_path(&root_path);
81         if (ret < 0) {
82                 _E("Failed to get root path for usb configuration (%d)", ret);
83                 return ret;
84         }
85
86         DD_LIST_FOREACH(list, l, conf) {
87                 snprintf(path, sizeof(path), "%s/%s", root_path, conf->name);
88                 _I("Usb conf: (%s, %s)", path, conf->value);
89                 ret = write_sysfs(path, conf->value);
90                 if (ret < 0) {
91                         _E("FAIL: write_sysfs(%s, %s)", path, conf->value);
92                         return ret;
93                 }
94         }
95         return 0;
96 }
97
98 static void run_operations_for_usb_mode(dd_list *list)
99 {
100         dd_list *l;
101         int ret, argc;
102         struct usb_operation *oper;
103
104         if (!list)
105                 return ;
106
107         DD_LIST_FOREACH(list, l, oper) {
108                 ret = launch_app_cmd(oper->oper);
109                 _I("operation: %s(%d)", oper->oper, ret);
110         }
111 }
112
113 void unset_client_mode(int mode, bool change)
114 {
115         int ret;
116         dd_list *conf_list;
117         dd_list *oper_list;
118
119         if (!change)
120                 update_current_usb_mode(SET_USB_NONE);
121
122         if (update_usb_state(VCONFKEY_SYSMAN_USB_DISCONNECTED) < 0)
123                 _E("FAIL: update_usb_state(%d)", VCONFKEY_SYSMAN_USB_DISCONNECTED);
124
125         ret = make_configuration_list(SET_USB_NONE);
126         if (ret == 0) {
127                 ret = get_configurations_list(&conf_list);
128                 if (ret == 0) {
129                         ret = set_configurations_to_sysfs(conf_list);
130                         if (ret < 0)
131                                 _E("FAIL: set_configurations_to_sysfs()");
132                 }
133         }
134         release_configuration_list();
135
136         ret = make_operation_list(mode, USB_CON_STOP);
137         if (ret == 0) {
138                 ret = get_operations_list(&oper_list);
139                 if (ret == 0)
140                         run_operations_for_usb_mode(oper_list);
141         }
142         release_operations_list();
143 }
144
145 static int get_selected_mode_by_debug_mode(int mode)
146 {
147         int ret;
148
149         debug = get_debug_mode();
150
151         switch (mode) {
152         case SET_USB_DEFAULT:
153                 if (debug == 1) /* debug on */
154                         mode = SET_USB_SDB;
155                 break;
156         case SET_USB_SDB:
157         case SET_USB_SDB_DIAG:
158                 if (debug == 0) /* debug off */
159                         mode = SET_USB_DEFAULT;
160                 break;
161         default:
162                 break;
163         }
164
165         return mode;
166 }
167
168 static bool get_usb_tethering_state(void)
169 {
170         int state;
171         int ret;
172
173         if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &state) == 0
174                         && (state & VCONFKEY_MOBILE_HOTSPOT_MODE_USB)) {
175                 _I("USB tethering is on");
176                 return true;
177         }
178
179         _I("USB tethering is off");
180         return false;
181 }
182
183 static bool check_usb_tethering(int sel_mode)
184 {
185         bool state;
186
187         state = get_usb_tethering_state();
188
189         if (state == false)
190                 return state;
191
192         switch (sel_mode) {
193         case SET_USB_RNDIS_TETHERING:
194         case SET_USB_RNDIS:
195                 return false;
196         default:
197                 break;
198         }
199
200         if (change_selected_usb_mode(SET_USB_RNDIS_TETHERING) != 0) {
201                 _E("Failed to set usb selected mode (%d)", SET_USB_RNDIS_TETHERING);
202                 return false;
203         }
204
205         return true;
206 }
207
208 static int turn_on_debug(void)
209 {
210         debug = 1;
211         return vconf_set_bool(VCONFKEY_SETAPPL_USB_DEBUG_MODE_BOOL, debug);
212 }
213
214 static int check_first_eng_mode(int sel_mode)
215 {
216         static bool first = true;
217
218         if (!eng_mode || !first)
219                 return sel_mode;
220
221         first = false;
222
223         if (sel_mode == SET_USB_DEFAULT) {
224                 sel_mode = SET_USB_SDB;
225                 if (turn_on_debug() != 0)
226                         _E("Failed to turn on debug toggle");
227         }
228
229         return sel_mode;
230 }
231
232 static int decide_selected_mode(int sel_mode, int cur_mode)
233 {
234         int mode;
235
236         if (check_usb_tethering(sel_mode))
237                 return -ECANCELED;
238
239         mode = check_first_eng_mode(sel_mode);
240
241         mode = get_selected_mode_by_debug_mode(mode);
242
243         if (mode == cur_mode) {
244                 _I("Selected usb mode (%d) is same with current usb mode (%d)", mode, cur_mode);
245                 return -ECANCELED;
246         }
247
248         _I("Selected mode decided is (%d)", mode);
249
250         return mode;
251 }
252
253 void change_client_setting(int options)
254 {
255         int sel_mode;
256         int cur_mode;
257         bool tethering;
258         int ret;
259         char *action;
260         dd_list *conf_list;
261         dd_list *oper_list;
262
263         if (control_status() == DEVICE_OPS_STATUS_STOP) {
264                 launch_syspopup(USB_RESTRICT);
265                 return;
266         }
267
268         sel_mode = get_selected_usb_mode();
269         cur_mode = get_current_usb_mode();
270
271         sel_mode = decide_selected_mode(sel_mode, cur_mode);
272         if (sel_mode == -ECANCELED)
273                 return;
274         else if (sel_mode <= 0) {
275                 _E("Failed to get selected mode");
276                 return;
277         }
278
279         if (options & SET_CONFIGURATION) {
280                 if (cur_mode != SET_USB_NONE) {
281                         unset_client_mode(cur_mode, true);
282                 }
283
284                 ret = make_configuration_list(sel_mode);
285                 if (ret < 0) {
286                         _E("FAIL: make_configuration_list(%d)", sel_mode);
287                         goto out;
288                 }
289
290                 ret = get_configurations_list(&conf_list);
291                 if (ret < 0) {
292                         _E("failed to get configuration list");
293                         goto out;
294                 }
295
296                 ret = set_configurations_to_sysfs(conf_list);
297                 if (ret < 0) {
298                         _E("FAIL: set_configurations_to_sysfs()");
299                         goto out;
300                 }
301         }
302
303         if (options & SET_OPERATION) {
304                 ret = make_operation_list(sel_mode, USB_CON_START);
305                 if (ret < 0) {
306                         _E("FAIL: make_operation_list()");
307                         goto out;
308                 }
309
310                 ret = get_operations_list(&oper_list);
311                 if (ret < 0) {
312                         _E("failed to get operation list");
313                         goto out;
314                 }
315
316                 if (update_usb_state(VCONFKEY_SYSMAN_USB_AVAILABLE) < 0)
317                         _E("FAIL: update_usb_state(%d)", VCONFKEY_SYSMAN_USB_AVAILABLE);
318
319                 update_current_usb_mode(sel_mode);
320
321                 run_operations_for_usb_mode(oper_list);
322         }
323
324         if (options & SET_NOTIFICATION) {
325                 /* Do nothing */
326         }
327
328         ret = 0;
329
330 out:
331         release_operations_list();
332         release_configuration_list();
333
334         if (ret < 0)
335                 launch_syspopup(USB_ERROR);
336
337         return;
338 }
339
340 void client_mode_changed(keynode_t* key, void *data)
341 {
342         int ret;
343
344         if (get_wait_configured())
345                 return;
346
347         change_client_setting(SET_CONFIGURATION | SET_OPERATION | SET_NOTIFICATION);
348 }
349
350 void debug_mode_changed(keynode_t* key, void *data)
351 {
352         int new_debug;
353         int cur_mode;
354         int sel_mode;
355
356         if (control_status() == DEVICE_OPS_STATUS_STOP)
357                 return;
358
359         new_debug = get_debug_mode();
360         _I("old debug(%d), new debug(%d)", debug, new_debug);
361         if (debug == new_debug)
362                 return;
363
364         cur_mode = get_current_usb_mode();
365         _I("cur_mode(%d)", cur_mode);
366
367         switch (cur_mode) {
368         case SET_USB_DEFAULT:
369         case SET_USB_SDB:
370         case SET_USB_SDB_DIAG:
371                 if (new_debug == 0)
372                         sel_mode = SET_USB_DEFAULT;
373                 else
374                         sel_mode = SET_USB_SDB;
375                 break;
376         default:
377                 return ;
378         }
379
380         if (change_selected_usb_mode(sel_mode) != 0)
381                 _E("FAIL: change_selected_usb_mode(%d)", sel_mode);
382
383         return;
384 }
385
386 /* USB tethering */
387 static int turn_on_usb_tethering(void)
388 {
389         int cur_mode;
390         int sel_mode;
391         int ret;
392
393         cur_mode = get_current_usb_mode();
394         sel_mode = get_selected_usb_mode();
395
396         switch (cur_mode) {
397         case SET_USB_RNDIS:
398         case SET_USB_RNDIS_TETHERING:
399                 return 0;
400         default:
401                 break;
402         }
403
404         switch (sel_mode) {
405         case SET_USB_RNDIS:
406         case SET_USB_RNDIS_TETHERING:
407                 break;
408         default:
409                 sel_mode = SET_USB_RNDIS_TETHERING;
410                 break;
411         }
412
413         ret = change_selected_usb_mode(sel_mode);
414         if (ret != 0)
415                 _E("FAIL: change_selected_usb_mode(%d)", sel_mode);
416
417         return ret;
418 }
419
420 static int turn_off_usb_tethering(void)
421 {
422         int cur_mode;
423         int sel_mode;
424         int ret;
425
426         cur_mode = get_current_usb_mode();
427
428         switch(cur_mode) {
429         case SET_USB_RNDIS:
430         case SET_USB_RNDIS_TETHERING:
431                 sel_mode = get_default_mode();
432                 ret = change_selected_usb_mode(sel_mode);
433                 if (ret != 0)
434                         _E("FAIL: change_selected_usb_mode(%d)", sel_mode);
435                 return ret;
436
437         default:
438                 return 0;
439         }
440 }
441
442 void tethering_status_changed(keynode_t* key, void *data)
443 {
444         bool usb_tethering;
445         int ret;
446
447         if (control_status() == DEVICE_OPS_STATUS_STOP)
448                 return;
449
450         usb_tethering = get_usb_tethering_state();
451         if (usb_tethering)
452                 ret = turn_on_usb_tethering();
453         else
454                 ret = turn_off_usb_tethering();
455
456         if (ret != 0)
457                 _E("Failed to change tethering mode");
458
459         return;
460 }