RFKILL_TYPE_UWB,
RFKILL_TYPE_WIMAX,
RFKILL_TYPE_WWAN,
+ RFKILL_TYPE_GPS,
+ RFKILL_TYPE_FM,
};
enum rfkill_operation {
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;
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);
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,
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;
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,
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);
}
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;
}
DBG("");
g_hash_table_destroy(device_table);
+ g_hash_table_destroy(rfkill_table);
dbus_connection_unref(connection);
}