diff -ur ofono-0.41.old/drivers/huaweimodem/radio-settings.c ofono-0.41/drivers/huaweimodem/radio-settings.c
--- ofono-0.41.old/drivers/huaweimodem/radio-settings.c	2011-01-20 17:12:25.000000000 +0800
+++ ofono-0.41/drivers/huaweimodem/radio-settings.c	2011-03-31 03:05:49.981269167 +0800
@@ -42,6 +42,7 @@
 
 static const char *none_prefix[] = { NULL };
 static const char *syscfg_prefix[] = { "^SYSCFG:", NULL };
+static const char *bodysaron_prefix[] = {"^BODYSARON:", NULL };
 
 #define HUAWEI_BAND_ANY 0x3FFFFFFF
 
@@ -351,6 +352,155 @@
 	}
 }
 
+static void huawei_bodysarstate_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+	struct cb_data *cbd = user_data;
+	ofono_radio_settings_bodysar_query_cb_t callback = cbd->cb;
+	struct ofono_error error;
+        GAtResultIter iter;
+	 int temp = 0;
+
+	decode_at_error(&error, g_at_result_final_response(result));
+
+	if (!ok) {
+		callback(&error, -1, cbd->data);
+		return;
+	}
+
+	g_at_result_iter_init(&iter, result);
+
+	if (!g_at_result_iter_next(&iter, "^BODYSARON:")) {
+		CALLBACK_WITH_FAILURE(callback, -1, cbd->data);
+		return;
+	}
+
+	g_at_result_iter_next_number(&iter, &temp);
+
+	callback(&error,  temp, cbd->data);
+}
+static void huawei_query_bodysarstate(struct ofono_radio_settings *rs,
+				   ofono_radio_settings_bodysar_query_cb_t callback,
+				   void *data)
+{
+	struct radio_settings_data *rsd = ofono_radio_settings_get_data(rs);
+	struct cb_data *cbd = cb_data_new(callback, data);
+
+	if (!cbd )	goto error;
+
+	if (g_at_chat_send(rsd->chat, "AT^BODYSARON?", bodysaron_prefix,
+				huawei_bodysarstate_query_cb, cbd, g_free) > 0)
+		return;
+
+error:
+	g_free(cbd);
+	CALLBACK_WITH_FAILURE(callback,-1, data);
+}
+
+static void huawei_bodysarstate_set_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+	struct cb_data *cbd = user_data;
+	ofono_radio_settings_bodysar_set_cb_t callback = cbd->cb;
+	struct ofono_error error;
+
+	decode_at_error(&error, g_at_result_final_response(result));
+
+	callback(&error, cbd->data);	
+}
+
+static void huawei_set_bodysarstate (struct ofono_radio_settings *rs,
+				   ofono_radio_settings_bodysar_set_cb_t callback, int state,
+				   void *data)
+{
+	struct radio_settings_data *rsd = ofono_radio_settings_get_data(rs);
+	struct cb_data *cbd = cb_data_new(callback, data);
+        char buf[30];
+
+	if (!cbd )	goto error;
+
+	sprintf(buf,"AT^BODYSARON=%u", (state?1:0));
+
+	if (g_at_chat_send(rsd->chat, buf, none_prefix,
+				huawei_bodysarstate_set_cb, cbd, g_free) > 0)  
+
+		return;
+
+error:
+	g_free(cbd);
+	CALLBACK_WITH_FAILURE(callback, data);
+}
+
+static void huawei_bodysargsm_set_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+	struct cb_data *cbd = user_data;
+	ofono_radio_settings_bodysar_set_cb_t callback = cbd->cb;
+	struct ofono_error error;
+
+	decode_at_error(&error, g_at_result_final_response(result));
+
+	callback(&error, cbd->data);	
+}
+
+static void huawei_set_bodysargsm(struct ofono_radio_settings *rs,
+				ofono_radio_settings_bodysar_set_cb_t callback,
+                                int p1, int p2, int p3, int p4,	void *data)
+{
+	struct radio_settings_data *rsd = ofono_radio_settings_get_data(rs);
+	struct cb_data *cbd = cb_data_new(callback, data);
+        char buf[40];
+
+	if (!cbd ) goto error;
+
+        if ((p1>33)||(p1<15)) goto error;  // gsm power range 15-33
+        if ((p2>33)||(p2<15)) goto error;  // gsm power range 15-33
+        if ((p3>33)||(p3<15)) goto error;  // gsm power range 15-33
+        if ((p4>33)||(p4<15)) goto error;  // gsm power range 15-33
+
+        sprintf(buf,"AT^BODYSARGSM=%u,%u,%u,%u", p1, p2, p3, p4);
+
+	if (g_at_chat_send(rsd->chat, buf, none_prefix,
+				huawei_bodysargsm_set_cb, cbd, g_free) > 0)  
+		return;
+
+error:
+	g_free(cbd);
+	CALLBACK_WITH_FAILURE(callback, data);
+}
+
+static void huawei_bodysarwcdma_set_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+	struct cb_data *cbd = user_data;
+	ofono_radio_settings_bodysar_set_cb_t callback = cbd->cb;
+	struct ofono_error error;
+
+	decode_at_error(&error, g_at_result_final_response(result));
+
+	callback(&error, cbd->data);	
+}
+
+static void huawei_set_bodysarwcdma(struct ofono_radio_settings *rs,
+				ofono_radio_settings_bodysar_set_cb_t callback, int power,
+				void *data)
+{
+	struct radio_settings_data *rsd = ofono_radio_settings_get_data(rs);
+	struct cb_data *cbd = cb_data_new(callback, data);
+        char buf[30];
+
+	if (!cbd ) goto error;
+
+        if ((power>24)||(power<17)) goto error;  // wcdma power range 17-24
+
+        sprintf(buf,"AT^BODYSARWCDMA=%u",power);
+
+	if (g_at_chat_send(rsd->chat, buf, none_prefix,
+				huawei_bodysarwcdma_set_cb, cbd, g_free) > 0)  
+		return;
+
+error:
+	g_free(cbd);
+
+	CALLBACK_WITH_FAILURE(callback, data);
+}
+
 static void syscfg_support_cb(gboolean ok, GAtResult *result,
 				gpointer user_data)
 {
@@ -402,6 +552,10 @@
 	.set_rat_mode		= huawei_set_rat_mode,
 	.query_band             = huawei_query_band,
 	.set_band               = huawei_set_band,
+	.query_bodysarstate	= huawei_query_bodysarstate,
+	.set_bodysarstate	= huawei_set_bodysarstate,
+	.set_bodysargsm		= huawei_set_bodysargsm,
+	.set_bodysarwcdma	= huawei_set_bodysarwcdma,
 };
 
 void huawei_radio_settings_init(void)
只在 ofono-0.41/drivers/huaweimodem 存在：radio-settings.c~
diff -ur ofono-0.41.old/include/radio-settings.h ofono-0.41/include/radio-settings.h
--- ofono-0.41.old/include/radio-settings.h	2010-12-25 07:46:38.000000000 +0800
+++ ofono-0.41/include/radio-settings.h	2011-03-29 02:48:41.298411640 +0800
@@ -73,6 +73,10 @@
 typedef void (*ofono_radio_settings_fast_dormancy_query_cb_t)(const struct ofono_error *error,
 							ofono_bool_t enable,
 							void *data);
+typedef void (*ofono_radio_settings_bodysar_set_cb_t)(const struct ofono_error *error,
+						        void *data);
+typedef void (*ofono_radio_settings_bodysar_query_cb_t)(const struct ofono_error *error,
+						        int value, void *data);
 
 struct ofono_radio_settings_driver {
 	const char *name;
@@ -101,6 +105,18 @@
 				ofono_bool_t enable,
 				ofono_radio_settings_fast_dormancy_set_cb_t,
 				void *data);
+	void (*query_bodysarstate) (struct ofono_radio_settings *rs,
+				ofono_radio_settings_bodysar_query_cb_t cb,
+				void *data);
+	void (*set_bodysarstate) (struct ofono_radio_settings *rs,
+				ofono_radio_settings_bodysar_set_cb_t cb, int state,
+				void *data);
+	void (*set_bodysargsm) (struct ofono_radio_settings *rs,
+				ofono_radio_settings_bodysar_set_cb_t cb, int p1, int p2, int p3, int p4,  
+				void *data);
+	void (*set_bodysarwcdma) (struct ofono_radio_settings *rs,
+				ofono_radio_settings_bodysar_set_cb_t cb, int power,  
+				void *data);
 };
 
 int ofono_radio_settings_driver_register(const struct ofono_radio_settings_driver *d);
只在 ofono-0.41/include 存在：radio-settings.h~
diff -ur ofono-0.41.old/src/radio-settings.c ofono-0.41/src/radio-settings.c
--- ofono-0.41.old/src/radio-settings.c	2010-12-25 07:46:38.000000000 +0800
+++ ofono-0.41/src/radio-settings.c	2011-03-31 04:07:45.622964548 +0800
@@ -33,6 +33,12 @@
 #include "ofono.h"
 #include "common.h"
 
+#include <linux/ioctl.h>
+#include <linux/kernel.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <linux/input.h>
+
 #define RADIO_SETTINGS_FLAG_CACHED 0x1
 
 static GSList *g_drivers = NULL;
@@ -44,15 +50,55 @@
 	enum ofono_radio_band_gsm band_gsm;
 	enum ofono_radio_band_umts band_umts;
 	ofono_bool_t fast_dormancy;
+	ofono_bool_t bodysar;
 	enum ofono_radio_access_mode pending_mode;
 	enum ofono_radio_band_gsm pending_band_gsm;
 	enum ofono_radio_band_umts pending_band_umts;
 	ofono_bool_t fast_dormancy_pending;
+        ofono_bool_t bodysar_pending; 
 	const struct ofono_radio_settings_driver *driver;
 	void *driver_data;
 	struct ofono_atom *atom;
 };
 
+/** input device descriptors **/
+struct input_dev_s;
+typedef struct input_dev_s input_dev_t;
+
+typedef int (*dev_init_t)(input_dev_t *);
+typedef int (*dev_exit_t)(input_dev_t *);
+typedef int (*dev_event_cb_t)(struct input_event *, void *);
+
+typedef struct {
+    dev_init_t     init;                 /* discover, open and init device */
+    dev_exit_t     exit;                 /* clean up and close device */
+    dev_event_cb_t event;                /* handle event from device */
+} input_dev_ops_t;
+
+struct input_dev_s {
+    const char      *name;               /* device name */
+    int              fd;                 /* event file descriptor */
+    input_dev_ops_t  ops;                /* device operations */
+    void            *user_data;          /* callback user data */
+    GIOChannel      *gioc;               /* GMainLoop I/O channel */
+    gulong           gsrc;               /*       and I/O source */
+};
+
+/** private prototypes **/
+void cap_event_init(struct ofono_radio_settings *rs);
+void cap_event_exit(void);
+static int cap_init(input_dev_t *dev);
+static int cap_exit(input_dev_t *dev);
+static int cap_event(struct input_event *event, void *user_data);
+
+static input_dev_t devices[] = 
+{
+    { "gpio-keys", -1, { cap_init, cap_exit, cap_event}, NULL, NULL, 0 },
+    { NULL, -1, { NULL, NULL, NULL }, NULL, NULL, 0 }
+};
+
+char *dbuspath;
+
 static const char *radio_access_mode_to_string(enum ofono_radio_access_mode m)
 {
 	switch (m) {
@@ -222,6 +268,12 @@
 					DBUS_TYPE_BOOLEAN, &value);
 	}
 
+	if (rs->driver->query_bodysarstate) {
+		dbus_bool_t bdsar = rs->bodysar;
+		ofono_dbus_dict_append(&dict, "BodySar",
+					DBUS_TYPE_BOOLEAN, &bdsar);
+	}
+
 	dbus_message_iter_close_container(&iter, &dict);
 
 	return reply;
@@ -267,6 +319,45 @@
 	radio_set_fast_dormancy(rs, rs->fast_dormancy_pending);
 }
 
+static void radio_set_bodysar(struct ofono_radio_settings *rs,
+				ofono_bool_t bdsar)
+{
+	DBusConnection *conn = ofono_dbus_get_connection();
+	const char *path = __ofono_atom_get_path(rs->atom);
+	dbus_bool_t retBodysar = bdsar;
+
+	DBG();
+
+	if (rs->bodysar == bdsar)
+		return;
+
+	ofono_dbus_signal_property_changed(conn, path,
+						OFONO_RADIO_SETTINGS_INTERFACE,
+						"BodySar",
+						DBUS_TYPE_BOOLEAN, &retBodysar);
+	rs->bodysar = bdsar;
+}
+
+static void radio_bodysar_set_callback(const struct ofono_error *error, void *data)
+{
+
+	struct ofono_radio_settings *rs = data;
+	DBusMessage *reply;
+
+	DBG();
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+		DBG("Error setting Body SAR mode");
+		reply = __ofono_error_failed(rs->pending);
+		__ofono_dbus_pending_reply(&rs->pending, reply);
+		return;
+	}
+	
+	reply = dbus_message_new_method_return(rs->pending);
+	__ofono_dbus_pending_reply(&rs->pending, reply);
+
+	radio_set_bodysar(rs, rs->bodysar_pending);
+}
+
 static void radio_set_band(struct ofono_radio_settings *rs)
 {
 	DBusConnection *conn = ofono_dbus_get_connection();
@@ -374,6 +465,33 @@
 	__ofono_dbus_pending_reply(&rs->pending, reply);
 }
 
+static void radio_bodysar_query_callback(const struct ofono_error *error, int value,
+					void *data)
+{
+	struct ofono_radio_settings *rs = data;
+	DBusMessage *reply;
+
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+		DBG("Error during bodysarstate query");
+		reply = __ofono_error_failed(rs->pending);
+		__ofono_dbus_pending_reply(&rs->pending, reply);
+		return;
+	}
+
+	radio_set_bodysar(rs, value);
+	radio_send_properties_reply(rs);
+}
+
+static void radio_query_bodysar(struct ofono_radio_settings *rs)
+{
+	if (rs->driver->query_bodysarstate == NULL) {
+		radio_send_properties_reply(rs);
+		return;
+	}
+
+	rs->driver->query_bodysarstate(rs, radio_bodysar_query_callback, rs);
+}
+
 static void radio_fast_dormancy_query_callback(const struct ofono_error *error,
 						ofono_bool_t enable, void *data)
 {
@@ -390,7 +508,7 @@
 	}
 
 	radio_set_fast_dormancy(rs, enable);
-	radio_send_properties_reply(rs);
+	radio_query_bodysar(rs);
 }
 
 static void radio_query_fast_dormancy(struct ofono_radio_settings *rs)
@@ -596,16 +714,156 @@
 		rs->driver->set_fast_dormancy(rs, target,
 					radio_fast_dormancy_set_callback, rs);
 		return NULL;
+	} else if (g_strcmp0(property, "BodySar") == 0) {
+		dbus_bool_t value;
+		int    bdsar;
+
+		if (!rs->driver->set_bodysarstate)
+			return __ofono_error_not_implemented(msg);
+
+		if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_BOOLEAN)   
+			return __ofono_error_invalid_args(msg);
+
+		dbus_message_iter_get_basic(&var, &value);
+
+		if (rs->bodysar == value)
+			return dbus_message_new_method_return(msg);
+
+		rs->pending = dbus_message_ref(msg);
+		rs->bodysar_pending = value;
+		bdsar = value;
+		rs->driver->set_bodysarstate(rs, radio_bodysar_set_callback, bdsar, rs);
+
+		return NULL;
 	}
 
 	return __ofono_error_invalid_args(msg);
 }
 
+static void bodysargsm_set_callback(const struct ofono_error *error, void *data)
+{
+	struct ofono_radio_settings *rs = data;
+	DBusMessage *reply;
+	DBusMessageIter iter;
+        const char *result ="OK";
+
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+		DBG("Error setting GSM RF maximum power");
+		reply = __ofono_error_failed(rs->pending);
+		__ofono_dbus_pending_reply(&rs->pending, reply);
+		return;
+	}
+
+	reply = dbus_message_new_method_return(rs->pending);
+
+	dbus_message_iter_init_append(reply, &iter);
+
+        dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &result);
+
+	__ofono_dbus_pending_reply(&rs->pending, reply);
+}
+
+static DBusMessage *radio_set_bodysar_gsm(DBusConnection *conn, DBusMessage *msg,
+					void *data)
+{ 
+	struct ofono_radio_settings *rs = data;
+	DBusMessageIter iter;
+	unsigned char p1, p2, p3, p4;
+
+	if (rs->pending)
+		return __ofono_error_busy(msg);
+
+	if (!dbus_message_iter_init(msg, &iter))
+		return __ofono_error_invalid_args(msg);
+
+	if (!rs->driver->set_bodysargsm)
+		return __ofono_error_not_implemented(msg);
+
+	if (dbus_message_get_args(msg,NULL,DBUS_TYPE_BYTE,&p1, DBUS_TYPE_BYTE,&p2,
+				  DBUS_TYPE_BYTE,&p3,DBUS_TYPE_BYTE,&p4,
+                		  DBUS_TYPE_INVALID)==FALSE)
+		return __ofono_error_invalid_args(msg);
+
+        if ((p1 < 15)||(33 < p1))
+		return __ofono_error_invalid_args(msg);
+        if ((p2 < 15)||(33 < p2))
+		return __ofono_error_invalid_args(msg);
+        if ((p3 < 15)||(33 < p3))
+		return __ofono_error_invalid_args(msg);
+        if ((p4 < 15)||(33 < p4))
+		return __ofono_error_invalid_args(msg);
+
+	rs->pending = dbus_message_ref(msg);
+
+	rs->driver->set_bodysargsm(rs, bodysargsm_set_callback, p1, p2, p3, p4, rs);
+
+	return NULL;
+}
+
+static void bodysarwcdma_set_callback(const struct ofono_error *error, void *data)
+{
+	struct ofono_radio_settings *rs = data;
+	DBusMessage *reply;
+	DBusMessageIter iter;
+        const char *result ="OK";
+
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+		DBG("Error setting WCDMA RF maximum power");
+		reply = __ofono_error_failed(rs->pending);
+		__ofono_dbus_pending_reply(&rs->pending, reply);
+		return;
+	}
+
+	reply = dbus_message_new_method_return(rs->pending);
+
+	dbus_message_iter_init_append(reply, &iter);
+
+        dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &result);
+
+	__ofono_dbus_pending_reply(&rs->pending, reply);
+}
+
+static DBusMessage *radio_set_bodysar_wcdma(DBusConnection *conn, DBusMessage *msg,
+					void *data)
+{ 
+	struct ofono_radio_settings *rs = data;
+	DBusMessageIter iter;
+	unsigned char value;
+	int power;
+
+	if (rs->pending)
+		return __ofono_error_busy(msg);
+
+	if (!dbus_message_iter_init(msg, &iter))
+		return __ofono_error_invalid_args(msg);
+
+	if (!rs->driver->set_bodysarwcdma)
+		return __ofono_error_not_implemented(msg);
+
+	if (dbus_message_get_args(msg,NULL,DBUS_TYPE_BYTE,&value,DBUS_TYPE_INVALID)==FALSE)
+		return __ofono_error_invalid_args(msg);
+
+        power = value;
+
+        if ((power < 17)||(24 < power))
+		return __ofono_error_invalid_args(msg);
+
+	rs->pending = dbus_message_ref(msg);
+
+	rs->driver->set_bodysarwcdma(rs, bodysarwcdma_set_callback, power, rs);
+
+	return NULL;
+}
+
 static GDBusMethodTable radio_methods[] = {
 	{ "GetProperties",  "",    "a{sv}",  radio_get_properties,
 						G_DBUS_METHOD_FLAG_ASYNC },
 	{ "SetProperty",    "sv",  "",       radio_set_property,
 						G_DBUS_METHOD_FLAG_ASYNC },
+	{ "SetBODYSARGSM",  "yyyy", "s",     radio_set_bodysar_gsm,
+						G_DBUS_METHOD_FLAG_ASYNC },
+	{ "SetBODYSARWCDMA",  "y",  "s",     radio_set_bodysar_wcdma,
+						G_DBUS_METHOD_FLAG_ASYNC },
 	{ }
 };
 
@@ -695,6 +953,8 @@
 		break;
 	}
 
+	cap_event_init(rs);
+
 	return rs;
 }
 
@@ -733,3 +993,239 @@
 {
 	return rs->driver_data;
 }
+
+/********************
+ * find_device
+ ********************/
+static void find_device(input_dev_t *dev, char * name, int size)
+{
+    DIR           *dir, *inputdir;
+    struct dirent *de, *inputde;
+    char           path[PATH_MAX];
+
+    if ((dir = opendir("/sys/devices/platform/gpio-keys/input")) == NULL) {
+        DBG("failed to open directory /sys/devices/platform/gpio-keys/input");
+        return;
+    }
+
+    while ((de = readdir(dir)) != NULL) {
+        if (!strncmp(de->d_name, "input",5)) {
+           snprintf(path, sizeof(path), "/sys/devices/platform/gpio-keys/input/%s", de->d_name);
+	   break;
+	}
+    }
+
+    if ((inputdir = opendir(path)) == NULL) {
+        DBG("failed to open directory %s", path);
+	closedir(dir);
+        return;
+    }
+
+    while ((inputde = readdir(inputdir)) != NULL) {
+        if (!strncmp(inputde->d_name, "event",5)) {
+           snprintf(name, size, "%s", inputde->d_name);
+	   break;
+	}
+    }
+  
+    closedir(inputdir);
+    closedir(dir);
+}
+
+/********************
+ * cap_init
+ ********************/
+static int cap_init(input_dev_t *dev)
+{
+    char           path[PATH_MAX];
+    char           name[64];
+    int            fd;
+
+    find_device(dev, name, sizeof(name));
+      
+    snprintf(path, sizeof(path), "/dev/input/%s", name);
+
+    if ((fd = open(path, O_RDONLY)) < 0) {
+        DBG("failed to open %s for reading", path);
+        return FALSE;
+    }
+
+    dev->fd = fd;
+
+    return TRUE;
+}
+
+/********************
+ * cap_exit
+ ********************/
+static int cap_exit(input_dev_t *dev)
+{
+    if (dev->fd >= 0) {
+        close(dev->fd);
+        dev->fd = -1;
+    }
+    
+    return TRUE;
+}
+
+/*********************************
+ * radio_append_variant
+ *********************************/
+static void radio_append_variant(DBusMessageIter *iter,
+					const char *key, int type, void *val)
+{
+	DBusMessageIter valueiter;
+        char sig[2];
+        
+        sig[0] = type;
+	sig[1] = 0;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &key);
+	dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, sig, &valueiter);
+	dbus_message_iter_append_basic(&valueiter, type, val);
+	dbus_message_iter_close_container(iter, &valueiter);
+}
+
+/********************
+ * cap_set_bodysar
+ ********************/
+static int cap_set_bodysar(dbus_bool_t value)
+{
+	DBusConnection *conn = ofono_dbus_get_connection();
+	DBusMessage *message;
+	DBusMessageIter iter;
+	DBusPendingCall *call;
+	
+	message = dbus_message_new_method_call(OFONO_SERVICE, dbuspath,
+					OFONO_RADIO_SETTINGS_INTERFACE, "SetProperty");
+	if (message == NULL)
+		return -ENOMEM;
+
+	dbus_message_iter_init_append(message, &iter);
+
+	radio_append_variant(&iter, "BodySar", DBUS_TYPE_BOOLEAN, &value);
+
+	if (dbus_connection_send(conn, message, NULL) == FALSE) {
+		DBG("Failed to change BodySar property on %s", OFONO_RADIO_SETTINGS_INTERFACE);
+		dbus_message_unref(message);
+		return -EINVAL;
+	}
+
+	dbus_message_unref(message);
+
+	return -EINPROGRESS;
+}
+
+/********************
+ * cap_event
+ ********************/
+static int cap_event(struct input_event *event, void *user_data)
+{
+
+    if (event->type != EV_SW) {
+        return TRUE;
+    }
+
+    switch (event->code) {
+    case SW_FRONT_PROXIMITY:
+        cap_set_bodysar((event->value?TRUE:FALSE)); // 0 = off , 1 = set
+        break;
+
+    default:
+        DBG("unknown event code 0x%x", event->code);
+        break;
+    }
+    
+    return TRUE;
+}
+
+/********************
+ * event_handler
+ ********************/
+static gboolean event_handler(GIOChannel *gioc, GIOCondition mask, gpointer data)
+{
+    input_dev_t        *dev = (input_dev_t *)data;
+    struct input_event  event;
+
+    if (mask & G_IO_IN) {
+        if (read(dev->fd, &event, sizeof(event)) != sizeof(event)) {
+            DBG("accessories: failed to read %s event", dev->name);
+            return FALSE;
+        }
+
+        dev->ops.event(&event, dev->user_data);
+    }
+
+    if (mask & G_IO_HUP) {
+        DBG("accessories: %s device closed unexpectedly", dev->name);
+        return FALSE;
+    }
+
+    if (mask & G_IO_ERR) {
+        DBG("accessories: %s device had an I/O error", dev->name);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/********************
+ * add_event_handler
+ ********************/
+static int add_event_handler(input_dev_t *dev)
+{
+    GIOCondition mask;
+
+    mask = G_IO_IN | G_IO_HUP | G_IO_ERR;
+
+    dev->gioc = g_io_channel_unix_new(dev->fd);
+    dev->gsrc = g_io_add_watch(dev->gioc, mask, event_handler, dev);
+
+    return dev->gsrc != 0;
+}
+
+/********************
+ * del_event_handler
+ ********************/
+static void del_event_handler(input_dev_t *dev)
+{
+    if (dev->gsrc != 0) {
+        g_source_remove(dev->gsrc);
+        dev->gsrc = 0;
+    }
+
+    if (dev->gioc != NULL) {
+        g_io_channel_unref(dev->gioc);
+        dev->gioc = NULL;
+    }
+}
+
+/********************
+ * cap_event_init
+ ********************/
+void cap_event_init(struct ofono_radio_settings *rs)
+{
+    input_dev_t *dev;
+    
+    for (dev = devices; dev->name != NULL; dev++) {
+        if (!dev->ops.init(dev))
+            DBG("cap event could not initialize '%s'", dev->name); 
+        else  {
+            add_event_handler(dev);
+	    dbuspath = __ofono_atom_get_path(rs->atom);
+	}
+    }
+}
+
+/********************
+ * cap_event_exit
+ ********************/
+void cap_event_exit(void)
+{
+    input_dev_t *dev;
+    
+    for (dev = devices; dev->name != NULL; dev++) {
+        del_event_handler(dev);
+        dev->ops.exit(dev);
+    }
+}
只在 ofono-0.41/src 存在：radio-settings.c~
