summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2010-01-26 08:16:47 +0100
committerMarcel Holtmann <marcel@holtmann.org>2010-01-26 08:16:47 +0100
commit03cd2c324472088e5dbd2d7e7998cefabe15335a (patch)
tree1b1276858fa0c8d29be828c4eb9f164147851a62
parentf87a0929056d12adfd1e29e77e52b24eb8c5bb26 (diff)
downloadconnman-03cd2c324472088e5dbd2d7e7998cefabe15335a.tar.gz
connman-03cd2c324472088e5dbd2d7e7998cefabe15335a.tar.bz2
connman-03cd2c324472088e5dbd2d7e7998cefabe15335a.zip
Add available RFKILL switches to list of technologies
-rw-r--r--src/connman.h8
-rw-r--r--src/rfkill.c42
-rw-r--r--src/technology.c95
3 files changed, 138 insertions, 7 deletions
diff --git a/src/connman.h b/src/connman.h
index d399634d..be160abe 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -273,6 +273,14 @@ void __connman_technology_list(DBusMessageIter *iter, void *user_data);
int __connman_technology_add_device(struct connman_device *device);
int __connman_technology_remove_device(struct connman_device *device);
+int __connman_technology_add_rfkill(unsigned int index,
+ enum connman_service_type type,
+ connman_bool_t softblock,
+ connman_bool_t hardblock);
+int __connman_technology_update_rfkill(unsigned int index,
+ connman_bool_t softblock,
+ connman_bool_t hardblock);
+int __connman_technology_remove_rfkill(unsigned int index);
int __connman_device_init(void);
void __connman_device_cleanup(void);
diff --git a/src/rfkill.c b/src/rfkill.c
index f68ee0eb..37923054 100644
--- a/src/rfkill.c
+++ b/src/rfkill.c
@@ -39,6 +39,8 @@ enum rfkill_type {
RFKILL_TYPE_UWB,
RFKILL_TYPE_WIMAX,
RFKILL_TYPE_WWAN,
+ RFKILL_TYPE_GPS,
+ RFKILL_TYPE_FM,
};
enum rfkill_operation {
@@ -56,12 +58,29 @@ struct rfkill_event {
uint8_t hard;
};
+static enum connman_service_type convert_type(uint8_t type)
+{
+ switch (type) {
+ case RFKILL_TYPE_WLAN:
+ return CONNMAN_SERVICE_TYPE_WIFI;
+ case RFKILL_TYPE_BLUETOOTH:
+ return CONNMAN_SERVICE_TYPE_BLUETOOTH;
+ case RFKILL_TYPE_WIMAX:
+ return CONNMAN_SERVICE_TYPE_WIMAX;
+ case RFKILL_TYPE_WWAN:
+ return CONNMAN_SERVICE_TYPE_CELLULAR;
+ }
+
+ return CONNMAN_SERVICE_TYPE_UNKNOWN;
+}
+
static GIOStatus rfkill_process(GIOChannel *chan)
{
GIOStatus status = G_IO_STATUS_NORMAL;
unsigned char buf[32];
struct rfkill_event *event = (void *) buf;
char sysname[32];
+ enum connman_service_type type;
connman_bool_t blocked;
gsize len;
@@ -78,9 +97,26 @@ static GIOStatus rfkill_process(GIOChannel *chan)
if (len != sizeof(struct rfkill_event))
return status;
- DBG("idx %u type %u op %u soft %u hard %u",
- event->idx, event->type, event->op,
- event->soft, event->hard);
+ DBG("idx %u type %u op %u soft %u hard %u", event->idx,
+ event->type, event->op,
+ event->soft, event->hard);
+
+ switch (event->op) {
+ case RFKILL_OP_ADD:
+ type = convert_type(event->type);
+ __connman_technology_add_rfkill(event->idx, type,
+ event->soft, event->hard);
+ break;
+ case RFKILL_OP_DEL:
+ __connman_technology_remove_rfkill(event->idx);
+ break;
+ case RFKILL_OP_CHANGE:
+ __connman_technology_update_rfkill(event->idx, event->soft,
+ event->hard);
+ break;
+ default:
+ break;
+ }
snprintf(sysname, sizeof(sysname) - 1, "rfkill%d", event->idx);
diff --git a/src/technology.c b/src/technology.c
index 2f79281a..fcfd9d8f 100644
--- a/src/technology.c
+++ b/src/technology.c
@@ -29,9 +29,15 @@
static DBusConnection *connection;
+static GHashTable *rfkill_table;
static GHashTable *device_table;
static GSList *technology_list = NULL;
+struct connman_rfkill {
+ unsigned int index;
+ enum connman_service_type type;
+};
+
enum connman_technology_state {
CONNMAN_TECHNOLOGY_STATE_UNKNOWN = 0,
CONNMAN_TECHNOLOGY_STATE_OFFLINE = 1,
@@ -45,9 +51,17 @@ struct connman_technology {
enum connman_service_type type;
enum connman_technology_state state;
char *path;
+ GHashTable *rfkill_list;
GSList *device_list;
};
+static void free_rfkill(gpointer data)
+{
+ struct connman_rfkill *rfkill = data;
+
+ g_free(rfkill);
+}
+
void __connman_technology_list(DBusMessageIter *iter, void *user_data)
{
GSList *list;
@@ -241,6 +255,12 @@ static struct connman_technology *technology_get(enum connman_service_type type)
technology->path = g_strdup_printf("%s/technology/%s",
CONNMAN_PATH, str);
+ technology->rfkill_list = g_hash_table_new_full(g_int_hash, g_int_equal,
+ NULL, free_rfkill);
+ technology->device_list = NULL;
+
+ technology->state = CONNMAN_TECHNOLOGY_STATE_OFFLINE;
+
if (g_dbus_register_interface(connection, technology->path,
CONNMAN_TECHNOLOGY_INTERFACE,
technology_methods, technology_signals,
@@ -274,16 +294,17 @@ static void technology_put(struct connman_technology *technology)
g_dbus_unregister_interface(connection, technology->path,
CONNMAN_TECHNOLOGY_INTERFACE);
+ g_slist_free(technology->device_list);
+ g_hash_table_destroy(technology->rfkill_list);
+
g_free(technology->path);
g_free(technology);
}
-static void unregister_device(gpointer data)
+static void unregister_technology(gpointer data)
{
struct connman_technology *technology = data;
- DBG("technology %p", technology);
-
technology_put(technology);
}
@@ -338,14 +359,79 @@ int __connman_technology_remove_device(struct connman_device *device)
return 0;
}
+int __connman_technology_add_rfkill(unsigned int index,
+ enum connman_service_type type,
+ connman_bool_t softblock,
+ connman_bool_t hardblock)
+{
+ struct connman_technology *technology;
+ struct connman_rfkill *rfkill;
+
+ DBG("index %u type %d soft %u hard %u", index, type,
+ softblock, hardblock);
+
+ rfkill = g_try_new0(struct connman_rfkill, 1);
+ if (rfkill == NULL)
+ return -ENOMEM;
+
+ rfkill->index = index;
+ rfkill->type = type;
+
+ technology = technology_get(type);
+ if (technology == NULL) {
+ g_free(rfkill);
+ return -ENXIO;
+ }
+
+ g_hash_table_replace(rfkill_table, &index, technology);
+
+ g_hash_table_replace(technology->rfkill_list, &index, rfkill);
+
+ return 0;
+}
+
+int __connman_technology_update_rfkill(unsigned int index,
+ connman_bool_t softblock,
+ connman_bool_t hardblock)
+{
+ struct connman_technology *technology;
+
+ DBG("index %u soft %u hard %u", index, softblock, hardblock);
+
+ technology = g_hash_table_lookup(rfkill_table, &index);
+ if (technology == NULL)
+ return -ENXIO;
+
+ return 0;
+}
+
+int __connman_technology_remove_rfkill(unsigned int index)
+{
+ struct connman_technology *technology;
+
+ DBG("index %u", index);
+
+ technology = g_hash_table_lookup(rfkill_table, &index);
+ if (technology == NULL)
+ return -ENXIO;
+
+ g_hash_table_remove(technology->rfkill_list, &index);
+
+ g_hash_table_remove(rfkill_table, &index);
+
+ return 0;
+}
+
int __connman_technology_init(void)
{
DBG("");
connection = connman_dbus_get_connection();
+ rfkill_table = g_hash_table_new_full(g_int_hash, g_int_equal,
+ NULL, unregister_technology);
device_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, unregister_device);
+ NULL, unregister_technology);
return 0;
}
@@ -355,6 +441,7 @@ void __connman_technology_cleanup(void)
DBG("");
g_hash_table_destroy(device_table);
+ g_hash_table_destroy(rfkill_table);
dbus_connection_unref(connection);
}