コード例 #1
0
ファイル: radio-settings.c プロジェクト: ubports/ofono
static void get_rs_with_mode(struct ofono_modem *modem, void *data)
{
	struct switch_data *sd = data;
	struct radio_data *rd_ref = sd->rd_1;
	struct ofono_atom *atom;
	struct ofono_radio_settings *rs;
	struct radio_data *rd;
	const char *standby_group, *modem_group;

	atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_RADIO_SETTINGS);
	if (atom == NULL)
		return;

	rs = __ofono_atom_get_data(atom);
	rd = ofono_radio_settings_get_data(rs);
	if (rd == rd_ref)
		return;

	standby_group = ofono_modem_get_string(rd_ref->modem, "StandbyGroup");
	if (standby_group == NULL)
		return;

	modem_group = ofono_modem_get_string(modem, "StandbyGroup");
	if (g_strcmp0(standby_group, modem_group) != 0)
		return;

	if ((rd->available_rats & sd->mode_to_switch) == 0)
		return;

	sd->rd_2 = rd;
}
コード例 #2
0
ファイル: ifx.c プロジェクト: AndriusA/ofono
static int ifx_enable(struct ofono_modem *modem)
{
	struct ifx_data *data = ofono_modem_get_data(modem);
	const char *device, *ldisc;
	GAtSyntax *syntax;
	GAtChat *chat;

	DBG("%p", modem);

	device = ofono_modem_get_string(modem, "Device");
	if (device == NULL)
		return -EINVAL;

	DBG("%s", device);

	ldisc = ofono_modem_get_string(modem, "LineDiscipline");
	if (ldisc != NULL) {
		data->mux_ldisc = atoi(ldisc);
		ofono_info("Using multiplexer line discipline %d",
							data->mux_ldisc);
	}

	data->device = g_at_tty_open(device, NULL);
	if (data->device == NULL)
		return -EIO;

	syntax = g_at_syntax_new_gsmv1();
	chat = g_at_chat_new(data->device, syntax);
	g_at_syntax_unref(syntax);

	if (chat == NULL) {
		g_io_channel_unref(data->device);
		return -EIO;
	}

	if (getenv("OFONO_AT_DEBUG"))
		g_at_chat_set_debug(chat, ifx_debug, "Master: ");

	g_at_chat_send(chat, "ATE0 +CMEE=1", NULL,
					NULL, NULL, NULL);

	/* Enable multiplexer */
	data->frame_size = 1509;

	g_at_chat_send(chat, "AT+CMUX=0,0,,1509,10,3,30,,", NULL,
					mux_setup_cb, modem, NULL);

	data->mux_init_timeout = g_timeout_add_seconds(5, mux_timeout_cb,
								modem);

	data->dlcs[AUX_DLC] = chat;

	return -EINPROGRESS;
}
コード例 #3
0
ファイル: location-reporting.c プロジェクト: Conjuror/ofono
static int enable_data_stream(struct ofono_location_reporting *lr)
{
	struct ofono_modem *modem;
	const char *gps_dev;
	GIOChannel *channel;
	GIOStatus status;
	gsize written;
	int fd;

	modem = ofono_location_reporting_get_modem(lr);
	gps_dev = ofono_modem_get_string(modem, "GPSDevice");

	channel = g_at_tty_open(gps_dev, NULL);
	if (channel == NULL)
		return -1;

	fd = g_io_channel_unix_get_fd(channel);
	status = g_io_channel_write_chars(channel, "AT*E2GPSNPD\r\n", -1,
								&written, NULL);

	g_io_channel_set_close_on_unref(channel, FALSE);
	g_io_channel_unref(channel);

	if (status != G_IO_STATUS_NORMAL || written != 13) {
		close(fd);

		return -1;
	}

	return fd;
}
コード例 #4
0
ファイル: telit.c プロジェクト: Conjuror/ofono
static GAtChat *open_device(struct ofono_modem *modem,
				const char *key, char *debug)
{
	const char *device;
	GAtSyntax *syntax;
	GIOChannel *channel;
	GAtChat *chat;

	device = ofono_modem_get_string(modem, key);
	if (device == NULL)
		return NULL;

	DBG("%s %s", key, device);

	channel = g_at_tty_open(device, NULL);
	if (channel == NULL)
		return NULL;

	syntax = g_at_syntax_new_gsmv1();
	chat = g_at_chat_new(channel, syntax);
	g_at_syntax_unref(syntax);
	g_io_channel_unref(channel);

	if (chat == NULL)
		return NULL;

	if (getenv("OFONO_AT_DEBUG"))
		g_at_chat_set_debug(chat, telit_debug, debug);

	return chat;
}
コード例 #5
0
ファイル: sap.c プロジェクト: AndriusA/ofono
/* power up hardware */
static int sap_enable(struct ofono_modem *modem)
{
	struct sap_data *data = ofono_modem_get_data(modem);
	DBusPendingCall *call;
	int status;
	const char *str = "sap";
	const char *server_path = ofono_modem_get_string(modem, "ServerPath");

	DBG("%p", modem);

	status = bluetooth_send_with_reply(server_path, BLUEZ_SERIAL_INTERFACE,
					"ConnectFD", &call, sap_connect_reply,
					modem, NULL, DBUS_TIMEOUT,
					DBUS_TYPE_STRING, &str,
					DBUS_TYPE_INVALID);

    DBG("bt send status %d", status);

	if (status < 0)
		return -EINVAL;

	data->call = call;

	return -EINPROGRESS;
}
コード例 #6
0
static int enable_data_stream(struct ofono_location_reporting *lr)
{
	struct ofono_modem *modem;
	const char *gps_dev;
	GHashTable *options;
	GIOChannel *channel;
	int fd;

	modem = ofono_location_reporting_get_modem(lr);
	gps_dev = ofono_modem_get_string(modem, "GPS");

	options = g_hash_table_new(g_str_hash, g_str_equal);
	if (options == NULL)
		return -1;

	g_hash_table_insert(options, "Baud", "115200");

	channel = g_at_tty_open(gps_dev, options);

	g_hash_table_destroy(options);

	if (channel == NULL)
		return -1;

	fd = g_io_channel_unix_get_fd(channel);

	g_io_channel_set_close_on_unref(channel, FALSE);
	g_io_channel_unref(channel);

	return fd;
}
コード例 #7
0
ファイル: cinterion.c プロジェクト: Herrie82/ofono-fix2
static int cinterion_enable(struct ofono_modem *modem)
{
	GAtChat *chat;
	GIOChannel *channel;
	GAtSyntax *syntax;
	GHashTable *options;
	const char *device;

	DBG("%p", modem);

	options = g_hash_table_new(g_str_hash, g_str_equal);
	if (options == NULL)
		return -ENOMEM;

	device = ofono_modem_get_string(modem, "Device");
	if (device == NULL)
		return -EINVAL;

	g_hash_table_insert(options, "Baud", "115200");
	g_hash_table_insert(options, "StopBits", "1");
	g_hash_table_insert(options, "DataBits", "8");
	g_hash_table_insert(options, "Parity", "none");
	g_hash_table_insert(options, "XonXoff", "off");
	g_hash_table_insert(options, "RtsCts", "on");
	g_hash_table_insert(options, "Local", "on");
	g_hash_table_insert(options, "Read", "on");

	channel = g_at_tty_open(device, options);
	g_hash_table_destroy(options);

	if (channel == NULL)
		return -EIO;

	/*
         * (Cinterion plugin is based on tc65 plugin. Comment left in but may
         * not be applicable in the general case)
         *
         * TC65 works almost as the 27.007 says. But for example after
	 * AT+CRSM the modem replies with the data in the queried EF and
	 * writes three pairs of <CR><LF> after the data and before OK.
	 */
	syntax = g_at_syntax_new_gsm_permissive();

	chat = g_at_chat_new(channel, syntax);
	g_at_syntax_unref(syntax);
	g_io_channel_unref(channel);

	if (chat == NULL)
		return -ENOMEM;

	if (getenv("OFONO_AT_DEBUG"))
		g_at_chat_set_debug(chat, cinterion_debug, "");

	ofono_modem_set_data(modem, chat);

	return 0;
}
コード例 #8
0
ファイル: gprs-context.c プロジェクト: endocode/ofono
static void set_gprs_context_interface(struct ofono_gprs_context *gc)
{
	struct ofono_modem *modem;
	const char *interface;

	/* read interface name read at detection time */
	modem = ofono_gprs_context_get_modem(gc);
	interface = ofono_modem_get_string(modem, "NetworkInterface");
	ofono_gprs_context_set_interface(gc, interface);
}
コード例 #9
0
ファイル: hfp_hf_bluez5.c プロジェクト: morphis/ofono
static ofono_bool_t device_path_compare(struct ofono_modem *modem,
					void *userdata)
{
	const char *path = userdata;
	const char *value = ofono_modem_get_string(modem, "DevicePath");

	if (value == NULL)
		return FALSE;

	return g_str_equal(path, value);
}
コード例 #10
0
ファイル: hfp_hf_bluez5.c プロジェクト: EdgarChen/oFono
static void hfp_pre_sim(struct ofono_modem *modem)
{
	struct hfp *hfp = ofono_modem_get_data(modem);
	char *address = (char *) ofono_modem_get_string(modem, "Remote");

	DBG("%p", modem);

	ofono_devinfo_create(modem, 0, "hfpmodem", address);
	ofono_voicecall_create(modem, 0, "hfpmodem", &hfp->info);
	ofono_netreg_create(modem, 0, "hfpmodem", &hfp->info);
	ofono_handsfree_create(modem, 0, "hfpmodem", &hfp->info);
	ofono_call_volume_create(modem, 0, "hfpmodem", &hfp->info);
}
コード例 #11
0
ファイル: phonesim.c プロジェクト: jkangas/ofono-1
static int localhfp_enable(struct ofono_modem *modem)
{
	struct hfp_slc_info *info = ofono_modem_get_data(modem);
	GIOChannel *io;
	GAtSyntax *syntax;
	GAtChat *chat;
	const char *address;
	int sk, port;

	address = ofono_modem_get_string(modem, "Address");
	if (address == NULL)
		return -EINVAL;

	port = ofono_modem_get_integer(modem, "Port");
	if (port < 0)
		return -EINVAL;

	sk = connect_socket(address, port);
	if (sk < 0)
		return sk;

	io = g_io_channel_unix_new(sk);
	if (io == NULL) {
		close(sk);
		return -ENOMEM;
	}

	syntax = g_at_syntax_new_gsmv1();
	chat = g_at_chat_new(io, syntax);
	g_at_syntax_unref(syntax);
	g_io_channel_unref(io);

	if (chat == NULL)
		return -ENOMEM;

	if (getenv("OFONO_AT_DEBUG"))
		g_at_chat_set_debug(chat, phonesim_debug, "LocalHfp: ");

	g_at_chat_set_disconnect_function(chat, slc_failed, modem);

	hfp_slc_info_init(info, HFP_VERSION_LATEST);
	info->chat = chat;
	hfp_slc_establish(info, slc_established, slc_failed, modem);

	return -EINPROGRESS;
}
コード例 #12
0
ファイル: hfp_hf_bluez5.c プロジェクト: morphis/ofono
/* power up hardware */
static int hfp_enable(struct ofono_modem *modem)
{
	const char *path;

	DBG("%p", modem);

	path = ofono_modem_get_string(modem, "DevicePath");

	/*
	 * We call Device1.ConnectProfile() with our UUID, and we hope for the
	 * NewConnection() method to be called, if ConnectProfile() fails we
	 * force the modem to powered off
	 */
	bt_connect_profile(ofono_dbus_get_connection(), path, HFP_AG_UUID,
							connect_cb, modem);

	return -EINPROGRESS;
}
コード例 #13
0
ファイル: telit.c プロジェクト: AndriusA/ofono
static GAtChat *open_device(struct ofono_modem *modem,
				const char *key, char *debug)
{
	const char *device;
	GAtSyntax *syntax;
	GIOChannel *channel;
	GAtChat *chat;
	GHashTable *options;

	device = ofono_modem_get_string(modem, key);
	if (device == NULL)
		return NULL;

	DBG("%s %s", key, device);

	options = g_hash_table_new(g_str_hash, g_str_equal);
	if (options == NULL)
		return NULL;

	g_hash_table_insert(options, "Baud", "115200");

	channel = g_at_tty_open(device, options);

	g_hash_table_destroy(options);

	if (channel == NULL)
		return NULL;

	syntax = g_at_syntax_new_gsmv1();
	chat = g_at_chat_new(channel, syntax);
	g_at_syntax_unref(syntax);
	g_io_channel_unref(channel);

	if (chat == NULL)
		return NULL;

	if (getenv("OFONO_AT_DEBUG"))
		g_at_chat_set_debug(chat, telit_debug, debug);

	return chat;
}
コード例 #14
0
ファイル: gprs-context.c プロジェクト: yongsu/oFono
static void mbm_get_ip_details(struct ofono_gprs_context *gc)
{
	struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
	struct ofono_modem *modem;
	const char *interface;

	if (gcd->have_e2ipcfg) {
		g_at_chat_send(gcd->chat, "AT*E2IPCFG?", e2ipcfg_prefix,
				mbm_e2ipcfg_cb, gc, NULL);
		return;
	}

	modem = ofono_gprs_context_get_modem(gc);
	interface = ofono_modem_get_string(modem, "NetworkInterface");
	CALLBACK_WITH_SUCCESS(gcd->up_cb, interface, FALSE, NULL, NULL,
			NULL, NULL, gcd->cb_data);

	gcd->mbm_state = MBM_NONE;
	gcd->up_cb = NULL;
	gcd->cb_data = NULL;
}
コード例 #15
0
ファイル: atgen.c プロジェクト: yongsu/oFono
static int atgen_enable(struct ofono_modem *modem)
{
    GAtChat *chat;
    GIOChannel *channel;
    GAtSyntax *syntax;
    const char *device;
    const char *value;
    GHashTable *options;
    int i;

    DBG("%p", modem);

    device = ofono_modem_get_string(modem, "Device");
    if (!device)
        return -EINVAL;

    options = g_hash_table_new_full(g_str_hash, g_str_equal,
                                    g_free, g_free);
    if (!options)
        return -ENOMEM;

    for (i = 0; tty_opts[i]; i++) {
        value = ofono_modem_get_string(modem, tty_opts[i]);

        if (value == NULL)
            continue;

        g_hash_table_insert(options, g_strdup(tty_opts[i]),
                            g_strdup(value));
    }

    channel = g_at_tty_open(device, options);

    g_hash_table_destroy(options);

    if (!channel) {
        return -EIO;
    }

    value = ofono_modem_get_string(modem, "GsmSyntax");
    if (value) {
        if (g_str_equal(value, "V1"))
            syntax = g_at_syntax_new_gsmv1();
        else if (g_str_equal(value, "Permissive"))
            syntax = g_at_syntax_new_gsm_permissive();
        else
            return -EINVAL;
    } else {
        syntax = g_at_syntax_new_gsmv1();
    }

    chat = g_at_chat_new(channel, syntax);
    g_at_syntax_unref(syntax);
    g_io_channel_unref(channel);

    if (!chat)
        return -ENOMEM;

    if (getenv("OFONO_AT_DEBUG"))
        g_at_chat_set_debug(chat, atgen_debug, NULL);

    ofono_modem_set_data(modem, chat);

    return 0;
}
コード例 #16
0
ファイル: gprs-context.c プロジェクト: AndriusA/ofono
static void owandata_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
	struct ofono_gprs_context *gc = user_data;
	struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
	GAtResultIter iter;
	int cid;
	const char *ip = NULL;
	const char *gateway = NULL;
	const char *dns1 = NULL;
	const char *dns2 = NULL;
	const char *dns[3];
	struct ofono_modem *modem;
	const char *interface;

	if (!ok)
		return;

	g_at_result_iter_init(&iter, result);

	if (g_at_result_iter_next(&iter, "_OWANDATA:") == FALSE)
		return;

	g_at_result_iter_next_number(&iter, &cid);
	g_at_result_iter_next_unquoted_string(&iter, &ip);
	g_at_result_iter_next_unquoted_string(&iter, &gateway);
	g_at_result_iter_next_unquoted_string(&iter, &dns1);
	g_at_result_iter_next_unquoted_string(&iter, &dns2);

	if (ip && ip[0] == ' ')
		ip += 1;

	if (gateway && gateway[0] == ' ')
		gateway += 1;

	if (dns1 && dns1[0] == ' ')
		dns1 += 1;

	if (dns2 && dns2[0] == ' ')
		dns2 += 1;

	/* Don't bother reporting the same DNS twice */
	if (g_str_equal(dns1, dns2))
		dns2 = NULL;

	dns[0] = dns1;
	dns[1] = dns2;
	dns[2] = 0;

	modem = ofono_gprs_context_get_modem(gc);
	interface = ofono_modem_get_string(modem, "NetworkInterface");

	ofono_info("Got the following parameters for context: %d", cid);
	ofono_info("IP: %s, Gateway: %s", ip, gateway);
	ofono_info("DNS: %s, %s", dns1, dns2);

	ofono_gprs_context_set_interface(gc, interface);
	ofono_gprs_context_set_ipv4_address(gc, ip, TRUE);
	ofono_gprs_context_set_ipv4_netmask(gc, STATIC_IP_NETMASK);
	ofono_gprs_context_set_ipv4_gateway(gc, gateway);
	ofono_gprs_context_set_ipv4_dns_servers(gc, dns);

	CALLBACK_WITH_SUCCESS(gcd->cb, gcd->cb_data);

	gcd->hso_state = HSO_NONE;
	gcd->cb = NULL;
	gcd->cb_data = NULL;
}
コード例 #17
0
ファイル: phonesim.c プロジェクト: jkangas/ofono-1
static int phonesim_enable(struct ofono_modem *modem)
{
	struct phonesim_data *data = ofono_modem_get_data(modem);
	GIOChannel *io;
	GAtSyntax *syntax;
	const char *address, *value;
	int sk, port;

	DBG("%p", modem);

	address = ofono_modem_get_string(modem, "Address");
	if (address == NULL)
		return -EINVAL;

	port = ofono_modem_get_integer(modem, "Port");
	if (port < 0)
		return -EINVAL;

	value = ofono_modem_get_string(modem, "Modem");
	if (!g_strcmp0(value, "calypso"))
		data->calypso = TRUE;

	value = ofono_modem_get_string(modem, "Multiplexer");
	if (!g_strcmp0(value, "internal"))
		data->use_mux = TRUE;

	sk = connect_socket(address, port);
	if (sk < 0)
		return sk;

	io = g_io_channel_unix_new(sk);
	if (io == NULL) {
		close(sk);
		return -ENOMEM;
	}

	if (data->calypso)
		syntax = g_at_syntax_new_gsm_permissive();
	else
		syntax = g_at_syntax_new_gsmv1();

	data->chat = g_at_chat_new(io, syntax);

	g_at_syntax_unref(syntax);
	g_io_channel_unref(io);

	if (data->chat == NULL)
		return -ENOMEM;

	if (getenv("OFONO_AT_DEBUG"))
		g_at_chat_set_debug(data->chat, phonesim_debug, "");

	g_at_chat_set_disconnect_function(data->chat,
						phonesim_disconnected, modem);

	if (data->calypso) {
		g_at_chat_set_wakeup_command(data->chat, "AT\r", 500, 5000);

		g_at_chat_send(data->chat, "ATE0", NULL, NULL, NULL, NULL);

		g_at_chat_send(data->chat, "AT%CUNS=0",
				NULL, NULL, NULL, NULL);
	}

	if (data->use_mux) {
		g_at_chat_send(data->chat, "ATE0", NULL, NULL, NULL, NULL);

		g_at_mux_setup_gsm0710(data->chat, mux_setup, modem, NULL);

		g_at_chat_unref(data->chat);
		data->chat = NULL;

		return -EINPROGRESS;
	}

	g_at_chat_send(data->chat, "AT+CSCS=\"GSM\"", none_prefix,
			NULL, NULL, NULL);

	g_at_chat_register(data->chat, "+CRST:",
				crst_notify, FALSE, modem, NULL);

	g_at_chat_register(data->chat, "+CBC:",
				cbc_notify, FALSE, modem, NULL);

	g_at_chat_send(data->chat, "AT+CBC", none_prefix, NULL, NULL, NULL);

	data->hfp_watch = __ofono_modem_add_atom_watch(modem,
					OFONO_ATOM_TYPE_EMULATOR_HFP,
					emulator_hfp_watch, data, NULL);

	return 0;
}
コード例 #18
0
ファイル: gprs-context.c プロジェクト: yongsu/oFono
static void mbm_e2ipcfg_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
	struct ofono_gprs_context *gc = user_data;
	struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
	GAtResultIter iter;
	int numdns = 0;
	int type;
	const char *str;
	const char *ip = NULL;
	const char *gateway = NULL;
	const char *dns[MAX_DNS + 1];
	struct ofono_modem *modem;
	const char *interface;
	gboolean success = FALSE;

	if (!ok)
		goto out;

	g_at_result_iter_init(&iter, result);

	if (g_at_result_iter_next(&iter, "*E2IPCFG:") == FALSE)
		return;

	while (g_at_result_iter_open_list(&iter)) {
		if (g_at_result_iter_next_number(&iter, &type) == FALSE)
			break;

		if (g_at_result_iter_next_string(&iter, &str) == FALSE)
			break;

		switch (type) {
		case 1:
			ip = str;
			break;
		case 2:
			gateway = str;
			break;
		case 3:
			if (numdns < MAX_DNS)
				dns[numdns++] = str;
			break;
		default:
			break;
		}

		if (g_at_result_iter_close_list(&iter) == FALSE)
			break;
	}

	dns[numdns] = NULL;

	if (ip && gateway && numdns)
		success = TRUE;

out:
	modem = ofono_gprs_context_get_modem(gc);
	interface = ofono_modem_get_string(modem, "NetworkInterface");

	CALLBACK_WITH_SUCCESS(gcd->up_cb, interface, success, ip,
					STATIC_IP_NETMASK, gateway,
					success ? dns : NULL, gcd->cb_data);
	gcd->mbm_state = MBM_NONE;
	gcd->up_cb = NULL;
	gcd->cb_data = NULL;
}
コード例 #19
0
ファイル: u8500.c プロジェクト: Conjuror/ofono
static int u8500_probe(struct ofono_modem *modem)
{
	const char *ifname = ofono_modem_get_string(modem, "Interface");
	unsigned address = ofono_modem_get_integer(modem, "Address");
	GIsiModem *isimodem;
	GIsiClient *client = NULL;
	GIsiPhonetNetlink *link = NULL;
	struct isi_data *isi = NULL;

	if (ifname == NULL)
		return -EINVAL;

	DBG("(%p) with %s", modem, ifname);

	isimodem = g_isi_modem_create_by_name(ifname);
	if (isimodem == NULL) {
		DBG("Interface=%s: %s", ifname, strerror(errno));
		return -errno;
	}

	g_isi_modem_set_userdata(isimodem, modem);

	if (getenv("OFONO_ISI_DEBUG"))
		g_isi_modem_set_debug(isimodem, ofono_debug);

	if (getenv("OFONO_ISI_TRACE"))
		g_isi_modem_set_trace(isimodem, isi_trace);

	if (g_isi_pn_netlink_by_modem(isimodem)) {
		DBG("%s: %s", ifname, strerror(EBUSY));
		errno = EBUSY;
		goto error;
	}

	link = g_isi_pn_netlink_start(isimodem, phonet_status_cb, modem);
	if (link == NULL) {
		DBG("%s: %s", ifname, strerror(errno));
		goto error;
	}

	if (address) {
		int error = g_isi_pn_netlink_set_address(isimodem, address);
		if (error && error != -EEXIST) {
			DBG("g_isi_pn_netlink_set_address(): %s\n",
				strerror(-error));
			errno = -error;
			goto error;
		}
	}

	isi = g_try_new0(struct isi_data, 1);
	if (isi == NULL) {
		errno = ENOMEM;
		goto error;
	}

	client = g_isi_client_create(isimodem, PN_MODEM_MCE);
	if (!client)
		goto error;

	g_isi_modem_set_device(isimodem, PN_DEV_MODEM);

	isi->modem = isimodem;
	isi->ifname = ifname;
	isi->link = link;
	isi->reported = -1;
	isi->client = client;

	ofono_modem_set_data(modem, isi);
	return 0;

error:
	g_isi_pn_netlink_stop(link);
	g_isi_client_destroy(client);
	g_isi_modem_destroy(isimodem);
	g_free(isi);

	return -errno;
}