system/core
修订版 | f7631d3a9c500aeed76bc5d984e4cc688f803e3c (tree) |
---|---|
时间 | 2009-11-14 04:44:00 |
作者 | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
vold: rfkill bootstrapping
Simulate rfkill add uevents to change permission of bluetooth devices on boot.
This is better since it works after suspend and wakeup.
Also revert back rfkill handling in hotplug.
@@ -1,7 +1,13 @@ | ||
1 | 1 | /* |
2 | 2 | * Simple hotplug tool |
3 | 3 | * |
4 | - * by Chih-Wei Huang <cwhuang@linux.org.tw> 2009/11/06 | |
4 | + * Copyright (C) 2009 The Android-x86 Open Source Project | |
5 | + * | |
6 | + * Author: Chih-Wei Huang <cwhuang@linux.org.tw> | |
7 | + * | |
8 | + * Licensed under the Apache License, Version 2.0. | |
9 | + * | |
10 | + * Last updated: 2009/11/14 | |
5 | 11 | * |
6 | 12 | */ |
7 | 13 |
@@ -12,8 +18,6 @@ | ||
12 | 18 | #include <sys/stat.h> |
13 | 19 | #include <unistd.h> |
14 | 20 | |
15 | -#include "private/android_filesystem_config.h" | |
16 | - | |
17 | 21 | #define HOTPLUG_LOG "/tmp/hotplug.log" |
18 | 22 | #define FIRMWARE_PATH "/system/lib/firmware" |
19 | 23 |
@@ -60,25 +64,6 @@ static int load_firmware() | ||
60 | 64 | return ret; |
61 | 65 | } |
62 | 66 | |
63 | -static int set_rfkill() | |
64 | -{ | |
65 | - int ret = -1; | |
66 | - if (strcmp(getenv("RFKILL_TYPE"), "bluetooth") == 0) { | |
67 | - chdir("/sys"); | |
68 | - chdir(getenv("DEVPATH") + 1); | |
69 | - ret = chown("state", AID_BLUETOOTH, AID_BLUETOOTH); | |
70 | - ret |= chmod("state", S_IRUSR|S_IRGRP|S_IWUSR|S_IWGRP); | |
71 | -#if 0 /* we may not need the hack */ | |
72 | - if (!strncmp(getenv("RFKILL_NAME"), "hci", 3) && !strcmp(getenv("RFKILL_STATE"), "0")) { | |
73 | - int fd = open("state", O_WRONLY); | |
74 | - if (fd >= 0) | |
75 | - ret |= !(write(fd, "1", 1) == 1); | |
76 | - } | |
77 | -#endif | |
78 | - } | |
79 | - return ret; | |
80 | -} | |
81 | - | |
82 | 67 | int hotplug_main(int argc, char **argv) |
83 | 68 | { |
84 | 69 | int ret = -1; |
@@ -108,8 +93,6 @@ int hotplug_main(int argc, char **argv) | ||
108 | 93 | if (strcmp(action, "add") == 0) { |
109 | 94 | if (strcmp(argv[1], "firmware") == 0) |
110 | 95 | ret = load_firmware(); |
111 | - else if (strcmp(argv[1], "rfkill") == 0) | |
112 | - ret = set_rfkill(); | |
113 | 96 | } |
114 | 97 | } |
115 | 98 | return ret; |
@@ -3,7 +3,7 @@ LOCAL_PATH:= $(call my-dir) | ||
3 | 3 | include $(CLEAR_VARS) |
4 | 4 | |
5 | 5 | LOCAL_SRC_FILES:= \ |
6 | - vold.c \ | |
6 | + vold.c \ | |
7 | 7 | cmd_dispatch.c \ |
8 | 8 | uevent.c \ |
9 | 9 | mmc.c \ |
@@ -19,6 +19,7 @@ LOCAL_SRC_FILES:= \ | ||
19 | 19 | logwrapper.c \ |
20 | 20 | ProcessKiller.c\ |
21 | 21 | switch.c \ |
22 | + rfkill.c \ | |
22 | 23 | format.c \ |
23 | 24 | devmapper.c |
24 | 25 |
@@ -27,9 +27,9 @@ | ||
27 | 27 | |
28 | 28 | void *read_file(char *filename, ssize_t *_size) |
29 | 29 | { |
30 | - int ret, fd; | |
30 | + int fd; | |
31 | 31 | struct stat sb; |
32 | - ssize_t size; | |
32 | + ssize_t size, ret; | |
33 | 33 | void *buffer = NULL; |
34 | 34 | |
35 | 35 | /* open the file */ |
@@ -43,12 +43,13 @@ void *read_file(char *filename, ssize_t *_size) | ||
43 | 43 | size = sb.st_size; |
44 | 44 | |
45 | 45 | /* allocate memory for it to be read into */ |
46 | - buffer = malloc(size); | |
46 | + buffer = malloc(size + 1); | |
47 | 47 | if (!buffer) |
48 | 48 | goto bail; |
49 | 49 | |
50 | 50 | /* slurp it into our buffer */ |
51 | 51 | ret = read(fd, buffer, size); |
52 | + ((char *)buffer)[ret] = '\0'; | |
52 | 53 | if (ret != size) |
53 | 54 | goto bail; |
54 | 55 |
@@ -0,0 +1,57 @@ | ||
1 | +/* | |
2 | + * Copyright (C) 2009 The Android-x86 Open Source Project | |
3 | + * | |
4 | + * Author: Chih-Wei Huang <cwhuang@linux.org.tw> | |
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 "vold.h" | |
20 | + | |
21 | +#include <dirent.h> | |
22 | +#include <errno.h> | |
23 | + | |
24 | +#define DEBUG_RFKILL_BOOTSTRAP 0 | |
25 | + | |
26 | +#define SYSFS_CLASS_RFKILL_PATH "/sys/class/rfkill" | |
27 | + | |
28 | +/* | |
29 | + * Bootstrap rfkill interfaces | |
30 | + */ | |
31 | +int rfkill_bootstrap() | |
32 | +{ | |
33 | + DIR *d; | |
34 | + struct dirent *de; | |
35 | + | |
36 | + if (!(d = opendir(SYSFS_CLASS_RFKILL_PATH))) { | |
37 | + LOG_ERROR("Unable to open '%s' (%s)", SYSFS_CLASS_RFKILL_PATH, | |
38 | + strerror(errno)); | |
39 | + return -errno; | |
40 | + } | |
41 | + | |
42 | + while ((de = readdir(d))) | |
43 | + if (de->d_name[0] != '.') { | |
44 | + char path[SYSFS_PATH_MAX]; | |
45 | + sprintf(path, "%s/%s", SYSFS_CLASS_RFKILL_PATH, de->d_name); | |
46 | +#if DEBUG_RFKILL_BOOTSTRAP | |
47 | + LOG_VOL("Simulate add: %s", de->d_name); | |
48 | +#endif | |
49 | + if (simulate_add_device("rfkill", path + 4)) { | |
50 | + LOG_ERROR("Simulate add device %s error: %s", path, | |
51 | + strerror(errno)); | |
52 | + } | |
53 | + } | |
54 | + | |
55 | + closedir(d); | |
56 | + return 0; | |
57 | +} |
@@ -30,6 +30,8 @@ | ||
30 | 30 | #include "volmgr.h" |
31 | 31 | #include "media.h" |
32 | 32 | |
33 | +#include "private/android_filesystem_config.h" | |
34 | + | |
33 | 35 | #define DEBUG_UEVENT 1 |
34 | 36 | |
35 | 37 | #define UEVENT_PARAMS_MAX 32 |
@@ -62,6 +64,7 @@ static int handle_block_event(struct uevent *); | ||
62 | 64 | static int handle_bdi_event(struct uevent *); |
63 | 65 | static void _cb_blkdev_ok_to_destroy(blkdev_t *dev); |
64 | 66 | static int handle_scsi_event(struct uevent *event); |
67 | +static int handle_rfkill_event(struct uevent *event); | |
65 | 68 | |
66 | 69 | static struct uevent_dispatch dispatch_table[] = { |
67 | 70 | { "switch", handle_switch_event }, |
@@ -71,6 +74,7 @@ static struct uevent_dispatch dispatch_table[] = { | ||
71 | 74 | { "bdi", handle_bdi_event }, |
72 | 75 | { "power_supply", handle_powersupply_event }, |
73 | 76 | { "scsi", handle_scsi_event }, |
77 | + { "rfkill", handle_rfkill_event }, | |
74 | 78 | { NULL, NULL } |
75 | 79 | }; |
76 | 80 |
@@ -135,7 +139,7 @@ int process_uevent_message(int socket) | ||
135 | 139 | return rc; |
136 | 140 | } |
137 | 141 | |
138 | -int simulate_uevent(char *subsys, char *path, char *action, char **params) | |
142 | +int simulate_uevent(const char *subsys, const char *path, const char *action, char **params) | |
139 | 143 | { |
140 | 144 | struct uevent *event; |
141 | 145 | char tmp[255]; |
@@ -174,6 +178,28 @@ int simulate_uevent(char *subsys, char *path, char *action, char **params) | ||
174 | 178 | return rc; |
175 | 179 | } |
176 | 180 | |
181 | +int simulate_add_device(const char *subsys, const char *path) | |
182 | +{ | |
183 | + int i; | |
184 | + char line[1024]; | |
185 | + char devpath[SYSFS_PATH_MAX] = "DEVPATH="; | |
186 | + char *uevent, *saveptr, *uevent_params[UEVENT_PARAMS_MAX]; | |
187 | + | |
188 | + if (!read_sysfs_var(line, sizeof(line), path, "uevent")) { | |
189 | + LOGE("Unable to open '/sys%s/%s' (%s)", path, "uevent", strerror(errno)); | |
190 | + return -errno; | |
191 | + } | |
192 | + | |
193 | + strcat(devpath, path); | |
194 | + uevent_params[0] = devpath; | |
195 | + for (i = 1, uevent = line; i < UEVENT_PARAMS_MAX - 1; ++i, uevent = NULL) | |
196 | + if (!(uevent_params[i] = strtok_r(uevent, "\n", &saveptr))) | |
197 | + break; | |
198 | + uevent_params[i] = NULL; | |
199 | + | |
200 | + return simulate_uevent(subsys, path, "add", uevent_params); | |
201 | +} | |
202 | + | |
177 | 203 | static int dispatch_uevent(struct uevent *event) |
178 | 204 | { |
179 | 205 | int i; |
@@ -244,7 +270,7 @@ static char *get_uevent_param(struct uevent *event, char *param_name) | ||
244 | 270 | } |
245 | 271 | |
246 | 272 | LOGE("get_uevent_param(): No parameter '%s' found", param_name); |
247 | - return NULL; | |
273 | + return ""; /* return a valid pointer to avoid checking */ | |
248 | 274 | } |
249 | 275 | |
250 | 276 | /* |
@@ -466,6 +492,21 @@ static int handle_scsi_event(struct uevent *event) | ||
466 | 492 | return 0; |
467 | 493 | } |
468 | 494 | |
495 | +static int handle_rfkill_event(struct uevent *event) | |
496 | +{ | |
497 | + if (event->action == action_add) { | |
498 | + const char *type = get_uevent_param(event, "RFKILL_TYPE"); | |
499 | + if (!strncmp(type, "bluetooth", 9)) { | |
500 | + char path[SYSFS_PATH_MAX]; | |
501 | + snprintf(path, sizeof(path), "/sys%s/state", event->path); | |
502 | + chown(path, AID_BLUETOOTH, AID_BLUETOOTH); | |
503 | + chmod(path, S_IRUSR|S_IRGRP|S_IWUSR|S_IWGRP); | |
504 | + LOG_VOL("Change permission for %s", path); | |
505 | + } | |
506 | + } | |
507 | + return 0; | |
508 | +} | |
509 | + | |
469 | 510 | static void _cb_blkdev_ok_to_destroy(blkdev_t *dev) |
470 | 511 | { |
471 | 512 | media_t *media = media_lookup_by_dev(dev); |
@@ -253,32 +253,5 @@ static int usb_bootstrap_sdx(const char *sysfs_path) | ||
253 | 253 | |
254 | 254 | static int usb_bootstrap_sdx_partition(const char *sysfs_path) |
255 | 255 | { |
256 | - int i; | |
257 | - char *uevent_params[5]; | |
258 | - char tmp[SYSFS_PATH_MAX]; | |
259 | - FILE *fp; | |
260 | - char line[1024]; | |
261 | - char *uevent, *saveptr; | |
262 | - const char *devpath = sysfs_path + 4; | |
263 | - | |
264 | -#if DEBUG_USB_BOOTSTRAP | |
265 | - LOG_VOL("usb_bootstrap_sdx_partition(%s):", devpath); | |
266 | -#endif | |
267 | - | |
268 | - if (!read_sysfs_var(line, sizeof(line), devpath, "uevent")) { | |
269 | - LOGE("Unable to open '%s/%s' (%s)", sysfs_path, "uevent", strerror(errno)); | |
270 | - return -errno; | |
271 | - } | |
272 | - sprintf(tmp, "DEVPATH=%s", devpath); | |
273 | - uevent_params[0] = tmp; | |
274 | - for (i = 1, uevent = line; i < 4; ++i, uevent = NULL) | |
275 | - if (!(uevent_params[i] = strtok_r(uevent, "\n", &saveptr))) | |
276 | - break; | |
277 | - uevent_params[i] = NULL; | |
278 | - | |
279 | - if (simulate_uevent("block", tmp + 8, "add", uevent_params) < 0) { | |
280 | - LOGE("Error simulating uevent (%s)", strerror(errno)); | |
281 | - return -errno; | |
282 | - } | |
283 | - return 0; | |
256 | + return simulate_add_device("block", sysfs_path + 4); | |
284 | 257 | } |
@@ -123,10 +123,14 @@ int main(int argc, char **argv) | ||
123 | 123 | // Switch |
124 | 124 | switch_bootstrap(); |
125 | 125 | |
126 | + // Rfkill interfaces | |
127 | + rfkill_bootstrap(); | |
128 | + | |
126 | 129 | bootstrap = 0; |
127 | 130 | |
128 | - //USB drive | |
131 | + // USB drive | |
129 | 132 | usb_bootstrap(); |
133 | + | |
130 | 134 | /* |
131 | 135 | * Main loop |
132 | 136 | */ |
@@ -81,7 +81,8 @@ int process_inotify_event(int fd); | ||
81 | 81 | int inotify_bootstrap(void); |
82 | 82 | |
83 | 83 | int process_uevent_message(int socket); |
84 | -int simulate_uevent(char *subsystem, char *path, char *action, char **params); | |
84 | +int simulate_uevent(const char *subsys, const char *path, const char *action, char **params); | |
85 | +int simulate_add_device(const char *subsys, const char *path); | |
85 | 86 | |
86 | 87 | int mmc_bootstrap(void); |
87 | 88 | int usb_bootstrap(void); |
@@ -91,6 +92,8 @@ int volmgr_bootstrap(void); | ||
91 | 92 | |
92 | 93 | int switch_bootstrap(void); |
93 | 94 | |
95 | +int rfkill_bootstrap(void); | |
96 | + | |
94 | 97 | void *read_file(char *filename, ssize_t *_size); |
95 | 98 | char *truncate_sysfs_path(char *path, int num_elements_to_remove, char *buffer, int buffer_size); |
96 | 99 | char *read_sysfs_var(char *buffer, size_t maxlen, const char *devpath, const char *var); |
@@ -101,6 +101,7 @@ static boolean _check_mounted(const char *mp, int idx) | ||
101 | 101 | char rest[256]; |
102 | 102 | FILE *fp; |
103 | 103 | char line[1024]; |
104 | + const char *devname; | |
104 | 105 | boolean ret = false; |
105 | 106 | |
106 | 107 | if (mp == NULL) |
@@ -113,18 +114,17 @@ static boolean _check_mounted(const char *mp, int idx) | ||
113 | 114 | |
114 | 115 | while (fgets(line, sizeof(line), fp)) { |
115 | 116 | sscanf(line, "%255s %255s %255s\n", device, mount_path, rest); |
116 | - if (idx == 1) { | |
117 | - char *devname = strrchr(device, '/'); | |
118 | - if (!devname || strcmp(++devname, mp)) | |
119 | - continue; | |
120 | - } else if (idx == 2) { | |
121 | - if (strcmp(mount_path, mp)) | |
122 | - continue; | |
123 | - } | |
117 | + if (idx == 1) | |
118 | + ret = (devname = strrchr(device, '/')) && !strcmp(++devname, mp); | |
119 | + else if (idx == 2) | |
120 | + ret = !strcmp(mount_path, mp); | |
121 | + else | |
122 | + break; | |
124 | 123 | |
125 | - LOGI("%s is already mounted", mp); | |
126 | - ret = true; | |
127 | - break; | |
124 | + if (ret) { | |
125 | + LOGI("%s is already mounted", mp); | |
126 | + break; | |
127 | + } | |
128 | 128 | } |
129 | 129 | |
130 | 130 | fclose(fp); |