Esempio n. 1
0
void __connman_technology_notify_regdom_by_device(struct connman_device *device,
						int result, const char *alpha2)
{
	connman_bool_t regdom_set = FALSE;
	struct connman_technology *technology;
	enum connman_service_type type;
	GSList *tech_drivers;

	type = __connman_device_get_service_type(device);
	technology = technology_find(type);

	if (technology == NULL)
		return;

	if (result < 0) {

		for (tech_drivers = technology->driver_list;
		     tech_drivers != NULL;
		     tech_drivers = g_slist_next(tech_drivers)) {
			struct connman_technology_driver *driver =
				tech_drivers->data;

			if (driver->set_regdom != NULL) {
				driver->set_regdom(technology, alpha2);
				regdom_set = TRUE;
			}

		}

		if (regdom_set == FALSE)
			alpha2 = NULL;
	}

	connman_technology_regdom_notify(technology, alpha2);
}
Esempio n. 2
0
int __connman_technology_remove_device(struct connman_device *device)
{
	struct connman_technology *technology;
	enum connman_service_type type;

	DBG("device %p", device);

	type = __connman_device_get_service_type(device);

	technology = technology_find(type);
	if (technology == NULL) {
		techless_device_list = g_slist_remove(techless_device_list,
								device);
		return -ENXIO;
	}

	technology->device_list = g_slist_remove(technology->device_list,
								device);

	if (technology->tethering == TRUE)
		set_tethering(technology, FALSE);

	technology_put(technology);

	return 0;
}
Esempio n. 3
0
void __connman_technology_scan_stopped(struct connman_device *device)
{
	int count = 0;
	struct connman_technology *technology;
	enum connman_service_type type;
	GSList *list;

	type = __connman_device_get_service_type(device);
	technology = technology_find(type);

	DBG("technology %p device %p", technology, device);

	if (technology == NULL)
		return;

	for (list = technology->device_list; list != NULL; list = list->next) {
		struct connman_device *other_device = list->data;

		if (device == other_device)
			continue;

		if (__connman_device_get_service_type(other_device) != type)
			continue;

		if (connman_device_get_scanning(other_device) == TRUE)
			count += 1;
	}

	if (count == 0)
		reply_scan_pending(technology, 0);
}
Esempio n. 4
0
int __connman_technology_remove_rfkill(unsigned int index,
					enum connman_service_type type)
{
	struct connman_technology *technology;
	struct connman_rfkill *rfkill;

	DBG("index %u", index);

	rfkill = g_hash_table_lookup(rfkill_list, GINT_TO_POINTER(index));
	if (rfkill == NULL)
		return -ENXIO;

	g_hash_table_remove(rfkill_list, GINT_TO_POINTER(index));

	technology = technology_find(type);
	if (technology == NULL)
		return -ENXIO;

	technology_apply_rfkill_change(technology,
		technology->softblocked, !technology->hardblocked, FALSE);

	technology_put(technology);

	return 0;
}
Esempio n. 5
0
void __connman_technology_remove_interface(enum connman_service_type type,
				int index, const char *name, const char *ident)
{
	struct connman_technology *technology;

	switch (type) {
	case CONNMAN_SERVICE_TYPE_UNKNOWN:
	case CONNMAN_SERVICE_TYPE_SYSTEM:
		return;
	case CONNMAN_SERVICE_TYPE_ETHERNET:
	case CONNMAN_SERVICE_TYPE_WIFI:
	case CONNMAN_SERVICE_TYPE_WIMAX:
	case CONNMAN_SERVICE_TYPE_BLUETOOTH:
	case CONNMAN_SERVICE_TYPE_CELLULAR:
	case CONNMAN_SERVICE_TYPE_GPS:
	case CONNMAN_SERVICE_TYPE_VPN:
	case CONNMAN_SERVICE_TYPE_GADGET:
		break;
	}

	connman_info("Remove interface %s [ %s ]", name,
				__connman_service_type2string(type));

	technology = technology_find(type);

	if (technology == NULL || technology->driver == NULL)
		return;

	if (technology->driver->remove_interface)
		technology->driver->remove_interface(technology, index);

	technology_put(technology);
}
Esempio n. 6
0
int __connman_technology_disabled(enum connman_service_type type)
{
	struct connman_technology *technology;

	technology = technology_find(type);
	if (technology == NULL)
		return -ENXIO;

	if (technology->pending_reply != NULL) {
		g_dbus_send_reply(connection, technology->pending_reply, DBUS_TYPE_INVALID);
		dbus_message_unref(technology->pending_reply);
		g_source_remove(technology->pending_timeout);
		technology->pending_reply = NULL;
		technology->pending_timeout = 0;
	}

	if (__sync_fetch_and_sub(&technology->enabled, 1) != 1)
		return 0;

	__connman_notifier_disable(type);
	technology->state = CONNMAN_TECHNOLOGY_STATE_OFFLINE;
	state_changed(technology);

	return 0;
}
Esempio n. 7
0
int __connman_technology_disable(enum connman_service_type type, DBusMessage *msg)
{
	struct connman_technology *technology;
	GSList *list;
	int err = 0;
	int ret = -ENODEV;
	DBusMessage *reply;

	DBG("type %d disable", type);

	technology = technology_find(type);
	if (technology == NULL) {
		err = -ENXIO;
		goto done;
	}

	if (technology->pending_reply != NULL) {
		err = -EBUSY;
		goto done;
	}

	if (technology->tethering == TRUE)
		set_tethering(technology, FALSE);

	if (msg != NULL) {
		technology->enable_persistent = FALSE;
		save_state(technology);
	}

	__connman_rfkill_block(technology->type, TRUE);

	for (list = technology->device_list; list; list = list->next) {
		struct connman_device *device = list->data;

		err = __connman_device_disable(device);
		if (err == 0)
			ret = 0;
	}

done:
	if (ret == 0) {
		if (msg != NULL)
			g_dbus_send_reply(connection, msg, DBUS_TYPE_INVALID);
		return ret;
	}

	if (msg != NULL) {
		if (err == -EINPROGRESS) {
			technology->pending_reply = dbus_message_ref(msg);
			technology->pending_timeout = g_timeout_add_seconds(10,
					technology_pending_reply, technology);
		} else {
			reply = __connman_error_failed(msg, -err);
			if (reply != NULL)
				g_dbus_send_message(connection, reply);
		}
	}

	return err;
}
Esempio n. 8
0
int __connman_technology_enabled(enum connman_service_type type)
{
	struct connman_technology *technology;

	technology = technology_find(type);
	if (technology == NULL)
		return -ENXIO;

	if (technology->rfkill_driven == TRUE)
		return 0;

	return technology_enabled(technology);
}
Esempio n. 9
0
int __connman_technology_update_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 soft %u hard %u", index, softblock, hardblock);

	rfkill = g_hash_table_lookup(rfkill_list, GINT_TO_POINTER(index));
	if (rfkill == NULL)
		return -ENXIO;

	if (rfkill->softblock == softblock &&
				rfkill->hardblock == hardblock)
		return 0;

	rfkill->softblock = softblock;
	rfkill->hardblock = hardblock;

	technology = technology_find(type);
	/* If there is no driver for this type, ignore it. */
	if (technology == NULL)
		return -ENXIO;

	/* If hardblocked, there is no need to handle softblocked state */
	if (technology_apply_rfkill_change(technology,
				softblock, hardblock, FALSE) == TRUE)
		return 0;

	if (global_offlinemode == TRUE)
		return 0;

	/*
	 * Depending on softblocked state we unblock/block according to
	 * persistent state.
	 */
	if (technology->softblocked == TRUE &&
				technology->enable_persistent == TRUE)
		return __connman_rfkill_block(type, FALSE);
	else if (technology->softblocked == FALSE &&
				technology->enable_persistent == FALSE)
		return __connman_rfkill_block(type, TRUE);

	return 0;
}
Esempio n. 10
0
void __connman_technology_set_connected(enum connman_service_type type,
		connman_bool_t connected)
{
	struct connman_technology *technology;

	technology = technology_find(type);
	if (technology == NULL)
		return;

	DBG("technology %p connected %d", technology, connected);

	technology->connected = connected;

	connman_dbus_property_changed_basic(technology->path,
			CONNMAN_TECHNOLOGY_INTERFACE, "Connected",
			DBUS_TYPE_BOOLEAN, &connected);
}
Esempio n. 11
0
void __connman_technology_add_interface(enum connman_service_type type,
				int index, const char *name, const char *ident)
{
	struct connman_technology *technology;
	GSList *tech_drivers;
	struct connman_technology_driver *driver;

	switch (type) {
	case CONNMAN_SERVICE_TYPE_UNKNOWN:
	case CONNMAN_SERVICE_TYPE_SYSTEM:
		return;
	case CONNMAN_SERVICE_TYPE_ETHERNET:
	case CONNMAN_SERVICE_TYPE_WIFI:
	case CONNMAN_SERVICE_TYPE_BLUETOOTH:
	case CONNMAN_SERVICE_TYPE_CELLULAR:
	case CONNMAN_SERVICE_TYPE_GPS:
	case CONNMAN_SERVICE_TYPE_VPN:
	case CONNMAN_SERVICE_TYPE_GADGET:
		break;
	}

	connman_info("Adding interface %s [ %s ]", name,
				__connman_service_type2string(type));

	technology = technology_find(type);

	if (technology == NULL)
		return;

	for (tech_drivers = technology->driver_list; tech_drivers != NULL;
	     tech_drivers = g_slist_next(tech_drivers)) {
		driver = tech_drivers->data;

		if(driver->add_interface != NULL)
			driver->add_interface(technology, index, name, ident);
	}

	/*
	 * At this point we can try to enable tethering automatically as
	 * now the interfaces are set properly.
	 */
	if (technology->tethering_persistent == TRUE)
		enable_tethering(technology);
}
Esempio n. 12
0
int __connman_technology_enabled(enum connman_service_type type)
{
	struct connman_technology *technology;

	technology = technology_find(type);
	if (technology == NULL)
		return -ENXIO;

	DBG("technology %p type %s rfkill %d enabled %d", technology,
		get_name(type), technology->rfkill_driven,
		technology->enabled);

	if (technology->rfkill_driven == TRUE) {
		if (technology->tethering_persistent == TRUE)
			enable_tethering(technology);
		return 0;
	}

	return technology_enabled(technology);
}
Esempio n. 13
0
int __connman_technology_disabled(enum connman_service_type type)
{
	struct connman_technology *technology;
	GSList *list;

	technology = technology_find(type);
	if (technology == NULL)
		return -ENXIO;

	if (technology->rfkill_driven == TRUE)
		return 0;

	for (list = technology->device_list; list != NULL; list = list->next) {
		struct connman_device *device = list->data;

		if (connman_device_get_powered(device) == TRUE)
			return 0;
	}

	return technology_disabled(technology);
}
Esempio n. 14
0
int __connman_technology_update_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 soft %u hard %u", index, softblock, hardblock);

	technology = technology_find(type);
	if (technology == NULL)
		return -ENXIO;

	rfkill = g_hash_table_lookup(technology->rfkill_list, &index);
	if (rfkill == NULL)
		return -ENXIO;

	if (rfkill->softblock == softblock &&
		rfkill->hardblock == hardblock)
		return 0;

	rfkill->softblock = softblock;
	rfkill->hardblock = hardblock;

	if (hardblock) {
		DBG("%s is switched off.", get_name(type));
		return 0;
	}

	if (!global_offlinemode) {
		if (technology->enable_persistent && softblock)
			return __connman_rfkill_block(type, FALSE);
		if (!technology->enable_persistent && !softblock)
			return __connman_rfkill_block(type, TRUE);
	}

	return 0;
}
Esempio n. 15
0
int __connman_technology_remove_rfkill(unsigned int index,
					enum connman_service_type type)
{
	struct connman_technology *technology;
	struct connman_rfkill *rfkill;

	DBG("index %u", index);

	technology = technology_find(type);
	if (technology == NULL)
		return -ENXIO;

	rfkill = g_hash_table_lookup(technology->rfkill_list, &index);
	if (rfkill == NULL)
		return -ENXIO;

	g_hash_table_remove(technology->rfkill_list, &index);

	technology_put(technology);

	return 0;
}
Esempio n. 16
0
connman_bool_t connman_technology_get_wifi_tethering(const char **ssid,
							const char **psk)
{
	struct connman_technology *technology;

	if (ssid == NULL || psk == NULL)
		return FALSE;

	*ssid = *psk = NULL;

	technology = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
	if (technology == NULL)
		return FALSE;

	if (technology->tethering == FALSE)
		return FALSE;

	*ssid = technology->tethering_ident;
	*psk = technology->tethering_passphrase;

	return TRUE;
}
Esempio n. 17
0
int __connman_technology_remove_device(struct connman_device *device)
{
	struct connman_technology *technology;
	enum connman_service_type type;

	DBG("device %p", device);

	type = __connman_device_get_service_type(device);
	__connman_notifier_unregister(type);

	technology = technology_find(type);
	if (technology == NULL)
		return -ENXIO;

	technology->device_list = g_slist_remove(technology->device_list,
								device);
	if (technology->device_list == NULL) {
		technology->state = CONNMAN_TECHNOLOGY_STATE_OFFLINE;
		state_changed(technology);
	}

	return 0;
}
Esempio n. 18
0
void __connman_technology_remove_interface(enum connman_service_type type,
				int index, const char *name, const char *ident)
{
	struct connman_technology *technology;
	GSList *tech_drivers;
	struct connman_technology_driver *driver;

	switch (type) {
	case CONNMAN_SERVICE_TYPE_UNKNOWN:
	case CONNMAN_SERVICE_TYPE_SYSTEM:
		return;
	case CONNMAN_SERVICE_TYPE_ETHERNET:
	case CONNMAN_SERVICE_TYPE_WIFI:
	case CONNMAN_SERVICE_TYPE_BLUETOOTH:
	case CONNMAN_SERVICE_TYPE_CELLULAR:
	case CONNMAN_SERVICE_TYPE_GPS:
	case CONNMAN_SERVICE_TYPE_VPN:
	case CONNMAN_SERVICE_TYPE_GADGET:
		break;
	}

	connman_info("Remove interface %s [ %s ]", name,
				__connman_service_type2string(type));

	technology = technology_find(type);

	if (technology == NULL)
		return;

	for (tech_drivers = technology->driver_list; tech_drivers != NULL;
	     tech_drivers = g_slist_next(tech_drivers)) {
		driver = tech_drivers->data;

		if(driver->remove_interface != NULL)
			driver->remove_interface(technology, index);
	}
}
Esempio n. 19
0
void __connman_technology_notify_regdom_by_device(struct connman_device *device,
        int result, const char *alpha2)
{
    struct connman_technology *technology;
    enum connman_service_type type;

    type = __connman_device_get_service_type(device);
    technology = technology_find(type);

    if (technology == NULL)
        return;

    if (result < 0) {
        if (technology->driver != NULL &&
                technology->driver->set_regdom != NULL) {
            technology->driver->set_regdom(technology, alpha2);
            return;
        }

        alpha2 = NULL;
    }

    connman_technology_regdom_notify(technology, alpha2);
}
Esempio n. 20
0
static struct connman_technology *technology_get(enum connman_service_type type)
{
	GSList *tech_drivers = NULL;
	struct connman_technology_driver *driver;
	struct connman_technology *technology;
	const char *str;
	GSList *list;

	DBG("type %d", type);

	str = __connman_service_type2string(type);
	if (str == NULL)
		return NULL;

	technology = technology_find(type);
	if (technology != NULL) {
		__sync_fetch_and_add(&technology->refcount, 1);
		return technology;
	}

	/* First check if we have a driver for this technology type */
	for (list = driver_list; list; list = list->next) {
		driver = list->data;

		if (driver->type == type) {
			DBG("technology %p driver %p", technology, driver);
			tech_drivers = g_slist_append(tech_drivers, driver);
		}
	}

	if (tech_drivers == NULL) {
		DBG("No matching drivers found for %s.",
				__connman_service_type2string(type));
		return NULL;
	}

	technology = g_try_new0(struct connman_technology, 1);
	if (technology == NULL)
		return NULL;

	technology->refcount = 1;

	technology->rfkill_driven = FALSE;
	technology->softblocked = FALSE;
	technology->hardblocked = FALSE;

	technology->type = type;
	technology->path = g_strdup_printf("%s/technology/%s",
							CONNMAN_PATH, str);

	technology->device_list = NULL;

	technology->pending_reply = NULL;

	technology_load(technology);

	if (technology_dbus_register(technology) == FALSE) {
		g_free(technology);
		return NULL;
	}

	technology_list = g_slist_prepend(technology_list, technology);

	technology->driver_list = tech_drivers;

	for (list = tech_drivers; list != NULL; list = g_slist_next(list)) {
		driver = list->data;

		if (driver->probe != NULL && driver->probe(technology) < 0)
			DBG("Driver probe failed for technology %p",
					technology);
	}

	DBG("technology %p", technology);

	return technology;
}
Esempio n. 21
0
int __connman_technology_enable(enum connman_service_type type, DBusMessage *msg)
{
	struct connman_technology *technology;
	GSList *list;
	int err = 0;
	int ret = -ENODEV;
	DBusMessage *reply;

	DBG("type %d enable", type);

	technology = technology_find(type);
	if (technology == NULL) {
		err = -ENXIO;
		goto done;
	}

	if (technology->pending_reply != NULL) {
		err = -EBUSY;
		goto done;
	}

	if (msg != NULL) {
		/*
		 * This is a bit of a trick. When msg is not NULL it means
		 * thats technology_enable was invoked from the manager API. Hence we save
		 * the state here.
		 */
		technology->enable_persistent = TRUE;
		save_state(technology);
	}

	__connman_rfkill_block(technology->type, FALSE);

	/*
	 * An empty device list means that devices in the technology
	 * were rfkill blocked. The unblock above will enable the devs.
	 */
	if (technology->device_list == NULL)
		return 0;

	for (list = technology->device_list; list; list = list->next) {
		struct connman_device *device = list->data;

		err = __connman_device_enable(device);
		/*
		 * err = 0 : Device was enabled right away.
		 * If atleast one device gets enabled, we consider
		 * the technology to be enabled.
		 */
		if (err == 0)
			ret = 0;
	}

done:
	if (ret == 0) {
		if (msg != NULL)
			g_dbus_send_reply(connection, msg, DBUS_TYPE_INVALID);
		return ret;
	}

	if (msg != NULL) {
		if (err == -EINPROGRESS) {
			technology->pending_reply = dbus_message_ref(msg);
			technology->pending_timeout = g_timeout_add_seconds(10,
					technology_pending_reply, technology);
		} else {
			reply = __connman_error_failed(msg, -err);
			if (reply != NULL)
				g_dbus_send_message(connection, reply);
		}
	}

	return err;
}
Esempio n. 22
0
static struct connman_technology *technology_get(enum connman_service_type type)
{
	struct connman_technology *technology;
	struct connman_technology_driver *driver = NULL;
	const char *str;
	GSList *list;
	int err;

	DBG("type %d", type);

	str = __connman_service_type2string(type);
	if (str == NULL)
		return NULL;

	technology = technology_find(type);
	if (technology != NULL)
		return technology;

	/* First check if we have a driver for this technology type */
	for (list = driver_list; list; list = list->next) {
		driver = list->data;

		if (driver->type == type)
			break;
		else
			driver = NULL;
	}

	if (driver == NULL) {
		DBG("No matching driver found for %s.",
				__connman_service_type2string(type));
		return NULL;
	}

	technology = g_try_new0(struct connman_technology, 1);
	if (technology == NULL)
		return NULL;

	technology->refcount = 1;

	technology->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->pending_reply = NULL;
	technology->state = CONNMAN_TECHNOLOGY_STATE_OFFLINE;

	load_state(technology);

	if (g_dbus_register_interface(connection, technology->path,
					CONNMAN_TECHNOLOGY_INTERFACE,
					technology_methods, technology_signals,
					NULL, technology, NULL) == FALSE) {
		connman_error("Failed to register %s", technology->path);
		g_free(technology);
		return NULL;
	}

	technology_list = g_slist_append(technology_list, technology);

	technologies_changed();

	technology->driver = driver;
	err = driver->probe(technology);
	if (err != 0)
		DBG("Driver probe failed for technology %p", technology);

	DBG("technology %p", technology);

	return technology;
}