Initialize Tizen 2.3
[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 struct ticker_data {
38         char *name;
39         int type;
40 };
41
42 static int debug = 0;
43
44 static int write_sysfs(char *path, char *value)
45 {
46         FILE *fp;
47         int ret;
48
49         if (!path || !value)
50                 return -ENOMEM;
51
52         fp = fopen(path, "w");
53         if (!fp) {
54                 _E("FAIL: fopen(%s)", path);
55                 return -ENOMEM;
56         }
57
58         ret = fwrite(value, sizeof(char), strlen(value), fp);
59         if (ret < strlen(value)) {
60                 _E("FAIL: fwrite(%s)", value);
61                 ret = -ENOMEM;
62                 goto out;
63         }
64
65 out:
66         if (fclose(fp) != 0)
67                 _E("FAIL: fclose()");
68         return ret;
69 }
70
71 static int set_configurations_to_sysfs(dd_list *list)
72 {
73         dd_list *l;
74         struct xmlConfiguration *conf;
75         int ret;
76
77         if (!list)
78                 return -EINVAL;
79
80         DD_LIST_FOREACH(list, l, conf) {
81                 if (!(conf->value))
82                         continue;
83
84                 ret = write_sysfs(conf->path, conf->value);
85                 if (ret < 0) {
86                         _E("FAIL: write_sysfs(%s, %s)", conf->path, conf->value);
87                         return ret;
88                 }
89         }
90         return 0;
91 }
92
93 static void run_operations_for_usb_mode(dd_list *list)
94 {
95         dd_list *l;
96         int ret;
97         struct xmlOperation *oper;
98
99         if (!list)
100                 return ;
101
102          DD_LIST_FOREACH(list, l, oper) {
103                  ret = launch_app_cmd(oper->oper);
104                  _I("operation: %s(%d)", oper->oper, ret);
105          }
106 }
107
108 void unset_client_mode(int mode, bool change)
109 {
110         int ret;
111         dd_list *conf_list;
112         dd_list *oper_list;
113
114         if (!change)
115                 update_current_usb_mode(SET_USB_NONE);
116
117         if (update_usb_state(VCONFKEY_SYSMAN_USB_DISCONNECTED) < 0)
118                 _E("FAIL: update_usb_state(%d)", VCONFKEY_SYSMAN_USB_DISCONNECTED);
119
120         ret = make_configuration_list(SET_USB_NONE);
121         if (ret == 0) {
122                 ret = get_configurations_list(&conf_list);
123                 if (ret == 0) {
124                         ret = set_configurations_to_sysfs(conf_list);
125                         if (ret < 0)
126                                 _E("FAIL: set_configurations_to_sysfs()");
127                 }
128         }
129
130         ret = make_operation_list(mode, USB_CON_UNSET);
131         if (ret == 0) {
132                 ret = get_operations_list(&oper_list);
133                 if (ret == 0)
134                         run_operations_for_usb_mode(oper_list);
135         }
136
137         release_operations_list();
138 }
139
140 static void launch_ticker_notification(int cur_mode, int sel_mode)
141 {
142         struct ticker_data ticker;
143         const struct device_ops *ticker_ops;
144
145         switch(sel_mode) {
146         case SET_USB_DEFAULT:
147         case SET_USB_SDB:
148         case SET_USB_SDB_DIAG:
149                 if (cur_mode == SET_USB_DEFAULT
150                                 || cur_mode == SET_USB_SDB
151                                 || cur_mode == SET_USB_SDB_DIAG)
152                         return;
153
154                 ticker.name = TICKER_TYPE_DEFAULT;
155                 ticker.type = 0; /* WITHOUT_QUEUE */
156                 break;
157         case SET_USB_RNDIS:
158         case SET_USB_RNDIS_DIAG:
159         case SET_USB_RNDIS_SDB:
160                 if (cur_mode == SET_USB_RNDIS
161                                 || cur_mode == SET_USB_RNDIS_TETHERING
162                                 || cur_mode == SET_USB_RNDIS_DIAG
163                                 || cur_mode == SET_USB_RNDIS_SDB)
164                         return;
165
166                 ticker.name = TICKER_TYPE_SSH;
167                 ticker.type = 0; /* WITHOUT_QUEUE */
168                 break;
169         case SET_USB_NONE:
170         case SET_USB_RNDIS_TETHERING:
171         default:
172                 return;
173         }
174
175         ticker_ops = find_device("ticker");
176
177         if (get_cradle_status() > 0)
178                 return;
179
180         if (ticker_ops && ticker_ops->init)
181                 ticker_ops->init(&ticker);
182         else
183                 _E("cannot find \"ticker\" ops");
184 }
185
186 static int get_selected_mode_by_debug_mode(int mode)
187 {
188         int ret;
189
190         debug = get_debug_mode();
191
192         switch (mode) {
193         case SET_USB_DEFAULT:
194                 if (debug == 1) /* debug on */
195                         mode = SET_USB_SDB;
196                 break;
197         case SET_USB_SDB:
198         case SET_USB_SDB_DIAG:
199                 if (debug == 0) /* debug off */
200                         mode = SET_USB_DEFAULT;
201                 break;
202         default:
203                 break;
204         }
205
206         return mode;
207 }
208
209 static bool get_usb_tethering_state(void)
210 {
211         int state;
212         int ret;
213
214         if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &state) == 0
215                         && (state & VCONFKEY_MOBILE_HOTSPOT_MODE_USB)) {
216                 _I("USB tethering is on");
217                 return true;
218         }
219
220         _I("USB tethering is off");
221         return false;
222 }
223
224 static bool check_usb_tethering(int sel_mode)
225 {
226         bool state;
227
228         state = get_usb_tethering_state();
229
230         if (state == false)
231                 return state;
232
233         switch (sel_mode) {
234         case SET_USB_RNDIS_TETHERING:
235         case SET_USB_RNDIS:
236                 return false;
237         default:
238                 break;
239         }
240
241         if (change_selected_usb_mode(SET_USB_RNDIS_TETHERING) != 0) {
242                 _E("Failed to set usb selected mode (%d)", SET_USB_RNDIS_TETHERING);
243                 return false;
244         }
245
246         return true;
247 }
248
249 static int turn_on_debug(void)
250 {
251         debug = 1;
252         return vconf_set_bool(VCONFKEY_SETAPPL_USB_DEBUG_MODE_BOOL, debug);
253 }
254
255 static int check_first_eng_mode(int sel_mode)
256 {
257         static bool first = true;
258
259         if (!eng_mode || !first)
260                 return sel_mode;
261
262         first = false;
263
264         if (sel_mode == SET_USB_DEFAULT) {
265                 sel_mode = SET_USB_SDB;
266                 if (turn_on_debug() != 0)
267                         _E("Failed to turn on debug toggle");
268         }
269
270         return sel_mode;
271 }
272
273 static int decide_selected_mode(int sel_mode, int cur_mode)
274 {
275         int mode;
276
277         if (check_usb_tethering(sel_mode))
278                 return -ECANCELED;
279
280         mode = check_first_eng_mode(sel_mode);
281
282         mode = get_selected_mode_by_debug_mode(mode);
283
284         if (mode == cur_mode) {
285                 _I("Selected usb mode (%d) is same with current usb mode (%d)", mode, cur_mode);
286                 return -ECANCELED;
287         }
288
289         _I("Selected mode decided is (%d)", mode);
290
291         return mode;
292 }
293
294 void change_client_setting(int options)
295 {
296         int sel_mode;
297         int cur_mode;
298         bool tethering;
299         int ret;
300         char *action;
301         dd_list *conf_list;
302         dd_list *oper_list;
303
304         if (control_status() == DEVICE_OPS_STATUS_STOP) {
305                 launch_syspopup(USB_RESTRICT);
306                 return;
307         }
308
309         sel_mode = get_selected_usb_mode();
310         cur_mode = get_current_usb_mode();
311
312         sel_mode = decide_selected_mode(sel_mode, cur_mode);
313         if (sel_mode == -ECANCELED)
314                 return;
315         else if (sel_mode <= 0) {
316                 _E("Failed to get selected mode");
317                 return;
318         }
319
320         if (options & SET_CONFIGURATION) {
321                 if (cur_mode != SET_USB_NONE) {
322                         unset_client_mode(cur_mode, true);
323                 }
324
325                 ret = make_configuration_list(sel_mode);
326                 if (ret < 0) {
327                         _E("FAIL: make_configuration_list(%d)", sel_mode);
328                         goto out_configuration;
329                 }
330
331                 ret = get_configurations_list(&conf_list);
332                 if (ret < 0) {
333                         _E("failed to get configuration list");
334                         goto out_configuration;
335                 }
336
337                 ret = set_configurations_to_sysfs(conf_list);
338                 if (ret < 0) {
339                         _E("FAIL: set_configurations_to_sysfs()");
340                         goto out_configuration;
341                 }
342         }
343
344         if (options & SET_OPERATION) {
345                 ret = make_operation_list(sel_mode, USB_CON_SET);
346                 if (ret < 0) {
347                         _E("FAIL: make_operation_list()");
348                         goto out_operation;
349                 }
350
351                 ret = get_operations_list(&oper_list);
352                 if (ret < 0) {
353                         _E("failed to get operation list");
354                         goto out_operation;
355                 }
356
357                 if (update_usb_state(VCONFKEY_SYSMAN_USB_AVAILABLE) < 0)
358                         _E("FAIL: update_usb_state(%d)", VCONFKEY_SYSMAN_USB_AVAILABLE);
359
360                 update_current_usb_mode(sel_mode);
361
362                 run_operations_for_usb_mode(oper_list);
363         }
364
365         if (options & SET_NOTIFICATION) {
366                 launch_ticker_notification(cur_mode, sel_mode);
367         }
368
369         ret = 0;
370
371 out_operation:
372         release_operations_list();
373
374 out_configuration:
375         if (make_configuration_list(SET_USB_NONE) < 0)
376                 _E("Release configurations info error");
377
378         if (ret < 0)
379                 launch_syspopup(USB_ERROR);
380
381         return;
382 }
383
384 void client_mode_changed(keynode_t* key, void *data)
385 {
386         int ret;
387
388         if (get_wait_configured())
389                 return;
390
391         change_client_setting(SET_CONFIGURATION | SET_OPERATION | SET_NOTIFICATION);
392 }
393
394 #if 0
395 void client_mode_changed(keynode_t* key, void *data)
396 {
397         int sel_mode;
398         int cur_mode;
399         int ret;
400         char *action;
401         dd_list *conf_list;
402         dd_list *oper_list;
403
404         if (control_status() == DEVICE_OPS_STATUS_STOP) {
405                 launch_syspopup(USB_RESTRICT);
406                 return;
407         }
408
409         sel_mode = get_selected_usb_mode();
410         if (sel_mode <= SET_USB_NONE) {
411                 _E("Getting selected usb mode error(%d)", sel_mode);
412                 return;
413         }
414
415         if (check_usb_tethering()) {
416                 _I("Turning on the usb tethering");
417                 return;
418         }
419
420         ret = check_debug_mode(sel_mode);
421         if (ret != 0)
422                 return;
423
424         sel_mode = check_first_eng_mode(sel_mode);
425
426         cur_mode = get_current_usb_mode();
427         if (cur_mode < SET_USB_NONE) {
428                 _E("Getting current usb mode error(%d)", cur_mode);
429                 return ;
430         }
431
432         if (cur_mode == sel_mode) {
433                 _I("Current usb mode(%d) is same with selected usb mode(%d)", cur_mode, sel_mode);
434                 return ;
435         }
436
437         if (cur_mode != SET_USB_NONE) {
438                 unset_client_mode(cur_mode);
439         }
440
441         ret = make_configuration_list(sel_mode);
442         if (ret < 0) {
443                 _E("FAIL: make_configuration_list(%d)", sel_mode);
444                 goto out;
445         }
446
447         ret = make_operation_list(sel_mode, USB_CON_SET);
448         if (ret < 0) {
449                 _E("FAIL: make_operation_list()");
450                 goto out;
451         }
452
453         ret = get_configurations_list(&conf_list);
454         if (ret < 0) {
455                 _E("failed to get configuration list");
456                 goto out;
457         }
458
459         ret = get_operations_list(&oper_list);
460         if (ret < 0) {
461                 _E("failed to get operation list");
462                 goto out;
463         }
464
465         ret = set_configurations_to_sysfs(conf_list);
466         if (ret < 0) {
467                 _E("FAIL: set_configurations_to_sysfs()");
468                 goto out;
469         }
470
471         update_current_usb_mode(sel_mode);
472
473         run_operations_for_usb_mode(oper_list);
474
475         launch_ticker_notification(cur_mode, sel_mode);
476
477         ret = 0;
478
479 out:
480         if (ret < 0)
481                 launch_syspopup(USB_ERROR);
482
483         release_operations_list();
484         ret = make_configuration_list(SET_USB_NONE);
485         if (ret < 0)
486                 _E("release configurations info error");
487         return;
488 }
489 #endif
490
491 void debug_mode_changed(keynode_t* key, void *data)
492 {
493         int new_debug;
494         int cur_mode;
495         int sel_mode;
496
497         if (control_status() == DEVICE_OPS_STATUS_STOP)
498                 return;
499
500         new_debug = get_debug_mode();
501         _I("old debug(%d), new debug(%d)", debug, new_debug);
502         if (debug == new_debug)
503                 return;
504
505         cur_mode = get_current_usb_mode();
506         _I("cur_mode(%d)", cur_mode);
507
508         switch (cur_mode) {
509         case SET_USB_DEFAULT:
510         case SET_USB_SDB:
511         case SET_USB_SDB_DIAG:
512                 if (new_debug == 0)
513                         sel_mode = SET_USB_DEFAULT;
514                 else
515                         sel_mode = SET_USB_SDB;
516                 break;
517         default:
518                 return ;
519         }
520
521         if (change_selected_usb_mode(sel_mode) != 0)
522                 _E("FAIL: change_selected_usb_mode(%d)", sel_mode);
523
524         return;
525 }
526
527 /* USB tethering */
528 static int turn_on_usb_tethering(void)
529 {
530         int cur_mode;
531         int sel_mode;
532         int ret;
533
534         cur_mode = get_current_usb_mode();
535         sel_mode = get_selected_usb_mode();
536
537         switch (cur_mode) {
538         case SET_USB_RNDIS:
539         case SET_USB_RNDIS_TETHERING:
540                 return 0;
541         default:
542                 break;
543         }
544
545         switch (sel_mode) {
546         case SET_USB_RNDIS:
547         case SET_USB_RNDIS_TETHERING:
548                 break;
549         default:
550                 sel_mode = SET_USB_RNDIS_TETHERING;
551                 break;
552         }
553
554         ret = change_selected_usb_mode(sel_mode);
555         if (ret != 0)
556                 _E("FAIL: change_selected_usb_mode(%d)", sel_mode);
557
558         return ret;
559 }
560
561 static int turn_off_usb_tethering(void)
562 {
563         int cur_mode;
564         int sel_mode;
565         int ret;
566
567         cur_mode = get_current_usb_mode();
568
569         switch(cur_mode) {
570         case SET_USB_RNDIS:
571         case SET_USB_RNDIS_TETHERING:
572                 sel_mode = get_default_mode();
573                 ret = change_selected_usb_mode(sel_mode);
574                 if (ret != 0)
575                         _E("FAIL: change_selected_usb_mode(%d)", sel_mode);
576                 return ret;
577
578         default:
579                 return 0;
580         }
581 }
582
583 void tethering_status_changed(keynode_t* key, void *data)
584 {
585         bool usb_tethering;
586         int ret;
587
588         if (control_status() == DEVICE_OPS_STATUS_STOP)
589                 return;
590
591         usb_tethering = get_usb_tethering_state();
592         if (usb_tethering)
593                 ret = turn_on_usb_tethering();
594         else
595                 ret = turn_off_usb_tethering();
596
597         if (ret != 0)
598                 _E("Failed to change tethering mode");
599
600         return;
601 }