/
usb_moded-android.c
209 lines (175 loc) · 5.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
@file usb_moded-android.c
Copyright (C) 2013 Jolla. All rights reserved.
@author: Philippe De Swert <philippe.deswert@jollamobile.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the Lesser GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the Lesser GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include <stdio.h>
#include <glib.h>
26
#include "usb_moded.h"
27
28
29
30
#include "usb_moded-android.h"
#include "usb_moded-log.h"
#include "usb_moded-modesetting.h"
#include "usb_moded-config.h"
31
#include "usb_moded-mac.h"
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/** Read android serial number from kernel command line
*/
static gchar *get_android_serial(void)
{
static const char path[] = "/proc/cmdline";
static const char find[] = "androidboot.serialno=";
static const char pbrk[] = " \t\r\n,";
char *res = 0;
FILE *file = 0;
size_t size = 0;
char *data = 0;
if( !(file = fopen(path, "r")) ) {
log_warning("%s: %s: %m", path, "can't open");
goto EXIT;
}
if( getline(&data, &size, file) < 0 ) {
log_warning("%s: %s: %m", path, "can't read");
goto EXIT;
}
char *beg = strstr(data, find);
if( !beg ) {
log_warning("%s: no serial found", path);
goto EXIT;
}
beg += sizeof find - 1;
size_t len = strcspn(beg, pbrk);
if( len < 1 ) {
log_warning("%s: empty serial found", path);
goto EXIT;
}
res = g_strndup(beg, len);
EXIT:
free(data);
if( file )
fclose(file);
return res;
}
82
83
84
85
/** initialize the basic android values
*/
void android_init_values(void)
{
86
87
gchar *text;
88
89
/* If the directory is not there, no point emitting warnings
* about every file that is not going to be there either. */
90
91
92
93
94
if( access("/sys/class/android_usb/android0", F_OK) != 0 )
{
goto EXIT;
}
95
96
97
98
/* Disable */
write_to_file("/sys/class/android_usb/android0/enable", "0");
/* Configure */
99
100
101
102
103
if( (text = get_android_serial()) )
{
write_to_file("/sys/class/android_usb/android0/iSerial", text);
g_free(text);
}
104
105
106
107
108
text = get_android_manufacturer();
if(text)
{
write_to_file("/sys/class/android_usb/android0/iManufacturer", text);
109
g_free(text);
110
}
111
text = get_android_vendor_id();
112
113
114
if(text)
{
write_to_file("/sys/class/android_usb/android0/idVendor", text);
115
g_free(text);
116
}
117
118
119
120
text = get_android_product();
if(text)
{
write_to_file("/sys/class/android_usb/android0/iProduct", text);
121
g_free(text);
122
}
123
124
125
126
text = get_android_product_id();
if(text)
{
write_to_file("/sys/class/android_usb/android0/idProduct", text);
127
g_free(text);
128
}
129
130
131
132
text = read_mac();
if(text)
{
write_to_file("/sys/class/android_usb/f_rndis/ethaddr", text);
133
g_free(text);
134
}
135
136
/* For rndis to be discovered correctly in M$ Windows (vista and later) */
write_to_file("/sys/class/android_usb/f_rndis/wceis", "1");
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* Some devices can have enumeration issues due to incomplete
* configuration on the 1st connect after bootup. Briefly setting
* up for example mass_storage function can be utilized as a
* workaround in such cases. */
if(!init_done_p()) {
const char *function = get_android_bootup_function();
if(function) {
write_to_file("/sys/class/android_usb/android0/functions", function);
write_to_file("/sys/class/android_usb/android0/enable", "1");
write_to_file("/sys/class/android_usb/android0/enable", "0");
}
}
/* Clear functions and enable */
write_to_file("/sys/class/android_usb/android0/functions", "none");
154
write_to_file("/sys/class/android_usb/android0/enable", "1");
155
156
157
EXIT:
return;
158
159
}
160
161
162
163
164
165
166
167
/* Set a charging mode for the android gadget
*
* @return 0 if successful, 1 on failure
*/
int set_android_charging_mode(void)
{
int ret = 0;
168
/* disable, set functions to "mass_storage", re-enable */
169
write_to_file("/sys/class/android_usb/android0/enable", "0");
170
write_to_file("/sys/class/android_usb/android0/idProduct", "0AFE"); /* TODO: make configurable */
171
write_to_file("/sys/class/android_usb/android0/functions", "mass_storage");
172
173
174
175
176
ret = write_to_file("/sys/class/android_usb/android0/enable", "1");
if(ret < 0)
return(1);
else
return(ret);
177
}
178
179
180
181
182
183
184
185
186
187
/* Set a product id for the android gadget
*
* @return 0 if successful, 1 on failure
*/
int set_android_productid(char *id)
{
int ret = 0;
/* disable, set functions to "mass_storage", re-enable */
188
ret = write_to_file("/sys/class/android_usb/android0/idProduct", id);
189
190
191
192
193
if(ret < 0)
return(1);
else
return(ret);
}
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/* Set a vendor id for the android gadget
*
* @return 0 if successful, 1 on failure
*/
int set_android_vendorid(char *id)
{
int ret = 0;
/* disable, set functions to "mass_storage", re-enable */
ret = write_to_file("/sys/class/android_usb/android0/idVendor", id);
if(ret < 0)
return(1);
else
return(ret);
}