tizen 2.3 release
[framework/system/deviced.git] / src / devicectl / usb.c
1 /*
2  * devicectl
3  *
4  * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
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
20 #include <stdio.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <core/common.h>
25 #include <core/launch.h>
26 #include "usb.h"
27
28 #define USB_SDB "sdb"
29 #define USB_SSH "ssh"
30
31 #define ARG_MAX 10
32 #define CMD_MAX 128
33
34 static struct usb_sysfs {
35         char *path;
36         char *value;
37 } usb_confs[] = {
38         { "/sys/class/usb_mode/usb0/enable",          "0"    },
39         { "/sys/class/usb_mode/usb0/idVendor",        "04e8" },
40         { "/sys/class/usb_mode/usb0/idProduct",       NULL   },
41         { "/sys/class/usb_mode/usb0/funcs_fconf",     NULL   },
42         { "/sys/class/usb_mode/usb0/funcs_sconf",     NULL   },
43         { "/sys/class/usb_mode/usb0/bDeviceClass",    "239"  },
44         { "/sys/class/usb_mode/usb0/bDeviceSubClass", "2"    },
45         { "/sys/class/usb_mode/usb0/bDeviceProtocol", "1"    },
46         { "/sys/class/usb_mode/usb0/enable",          "1"    },
47 };
48
49 static int launch_app(char **argv)
50 {
51         pid_t pid;
52
53         if (!argv || !argv[0])
54                 return -EINVAL;
55
56         pid = fork();
57
58         if (pid < 0) {
59                 printf("fork() failed\n");
60                 return -ENOMEM;
61         }
62
63         if (pid > 0) { /*parent*/
64                 return pid;
65         }
66
67         /*child*/
68
69         if (execvp(argv[0], argv) < 0)
70                 printf("execvp failed (%d)\n", errno);
71
72         return 0;
73 }
74
75 static int write_sysfs(char *path, char *value)
76 {
77         FILE *fp;
78         int ret;
79
80         if (!path || !value)
81                 return -ENOMEM;
82
83         fp = fopen(path, "w");
84         if (!fp) {
85                 printf("FAIL: fopen(%s)\n", path);
86                 return -ENOMEM;
87         }
88
89         ret = fwrite(value, sizeof(char), strlen(value), fp);
90         fclose(fp);
91         if (ret < strlen(value)) {
92                 printf("FAIL: fwrite(%s)\n", value);
93                 ret = -ENOMEM;
94         }
95
96         return ret;
97 }
98
99 static int set_usb_configuration(char *idproduct, char *fconf, char *sconf)
100 {
101         int i, ret;
102
103         usb_confs[2].value = idproduct;
104         usb_confs[3].value = fconf;
105         usb_confs[4].value = sconf;
106
107         for (i = 0 ; i < ARRAY_SIZE(usb_confs) ; i++) {
108                 ret = write_sysfs(usb_confs[i].path, usb_confs[i].value);
109                 if (ret < 0) {
110                         printf("usb setting fails (%s), (%s)\n", usb_confs[i].path, usb_confs[i].value);
111                         return ret;
112                 }
113         }
114
115         return 0;
116 }
117
118 static int divide_cmd(char **command, int len, char *cmd)
119 {
120         char *param, *next, *term;
121         int cnt = 0;
122
123         if (!cmd)
124                 return -EINVAL;
125
126         term = strchr(cmd, '\0');
127         if (!term)
128                 return -EINVAL;
129
130         memset(command, 0, len);
131
132         param = cmd;
133         while (1) {
134                 if (*param == '\0')
135                         break;
136                 if (*param == ' ') {
137                         param++;
138                         continue;
139                 }
140
141                 next = strchr(param, ' ');
142                 if (!next) {
143                         command[cnt++] = param;
144                         break;
145                 }
146
147                 if (next == param) {
148                         param++;
149                         continue;
150                 }
151
152                 *next = '\0';
153                 command[cnt++] = param;
154                 param = next + 1;
155         }
156
157         return 0;
158 }
159
160 static int run_cmd(char *cmd)
161 {
162         int ret;
163         char *command[ARG_MAX];
164         char in_cmd[CMD_MAX];
165
166         if (!cmd)
167                 return -EINVAL;
168
169         snprintf(in_cmd, sizeof(in_cmd), "%s", cmd);
170
171         ret = divide_cmd(command, sizeof(command), in_cmd);
172         if (ret < 0)
173                 return ret;
174
175         ret = launch_app(command);
176         if (ret < 0)
177                 return ret;
178
179         return 0;
180
181 }
182
183 static int load_sdb(void)
184 {
185         int ret;
186         char *cmd[ARG_MAX];
187
188         ret = set_usb_configuration("6860", "mtp", "mtp,acm,sdb");
189         if (ret < 0)
190                 return ret;
191
192         return run_cmd("/usr/bin/systemctl start sdbd.service");
193 }
194
195 static int load_ssh(void)
196 {
197         int ret;
198
199         ret = set_usb_configuration("6863", "rndis", " ");
200         if (ret < 0)
201                 return ret;
202
203         ret = run_cmd("/sbin/ifconfig usb0 192.168.129.3 up");
204         if (ret < 0)
205                 return ret;
206
207         ret = run_cmd("/sbin/route add -net 192.168.129.0 netmask 255.255.255.0 dev usb0");
208         if (ret < 0)
209                 return ret;
210
211         ret = run_cmd("/usr/bin/systemctl start sshd.service");
212         if (ret < 0)
213                 return ret;
214
215         return 0;
216 }
217
218 static int unload_sdb(void)
219 {
220         int ret;
221
222         ret = write_sysfs(usb_confs[0].path, usb_confs[0].value);
223         if (ret < 0)
224                 return ret;
225
226         ret = run_cmd("/usr/bin/systemctl stop sdbd.service");
227         if (ret < 0)
228                 return ret;
229
230         return 0;
231 }
232
233 static int unload_ssh(void)
234 {
235         int ret;
236
237         ret = write_sysfs(usb_confs[0].path, usb_confs[0].value);
238         if (ret < 0)
239                 return ret;
240
241         ret = run_cmd("/sbin/ifconfig usb0 down");
242         if (ret < 0)
243                 return ret;
244
245         ret = run_cmd("/usr/bin/systemctl stop sshd.service");
246         if (ret < 0)
247                 return ret;
248
249         return 0;
250 }
251
252 int load_usb_mode(char *opt)
253 {
254         if (!opt) {
255                 printf("Failed: Forth parameter is NULL\n");
256                 return -EINVAL;
257         }
258
259         if (!strncmp(opt, USB_SDB, strlen(opt)))
260                 return load_sdb();
261
262         if (!strncmp(opt, USB_SSH, strlen(opt)))
263                 return load_ssh();
264
265         printf("Failed: Forth parameter is invalid (%s)\n", opt);
266         return -EINVAL;
267 }
268
269 int unload_usb_mode(char *opt)
270 {
271         if (!opt) {
272                 printf("Failed: Forth parameter is NULL\n");
273                 return -EINVAL;
274         }
275
276         if (!strncmp(opt, USB_SDB, strlen(opt)))
277                 return unload_sdb();
278
279         if (!strncmp(opt, USB_SSH, strlen(opt)))
280                 return unload_ssh();
281
282         printf("Failed: Forth parameter is invalid (%s)\n", opt);
283         return -EINVAL;
284 }