Пример #1
0
static void at_csms_query_cb(gboolean ok, GAtResult *result,
				gpointer user_data)
{
	struct ofono_sms *sms = user_data;
	struct sms_data *data = ofono_sms_get_data(sms);
	gboolean cnma_supported = FALSE;
	GAtResultIter iter;
	int status_min, status_max;
	char buf[128];

	if (!ok)
		return at_sms_not_supported(sms);

	g_at_result_iter_init(&iter, result);

	if (!g_at_result_iter_next(&iter, "+CSMS:"))
		goto out;

	if (!g_at_result_iter_open_list(&iter))
		goto out;

	while (g_at_result_iter_next_range(&iter, &status_min, &status_max))
		if (status_min <= 1 && 1 <= status_max)
			cnma_supported = TRUE;

	DBG("CSMS query parsed successfully");

out:
	snprintf(buf, sizeof(buf), "AT+CSMS=%d", cnma_supported ? 1 : 0);
	g_at_chat_send(data->chat, buf, csms_prefix,
			at_csms_set_cb, sms, NULL);
}
Пример #2
0
static void cind_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
	struct slc_establish_data *sed = user_data;
	struct hfp_slc_info *info = sed->info;
	GAtResultIter iter;
	const char *str;
	int index;
	int min, max;

	if (!ok)
		goto error;

	g_at_result_iter_init(&iter, result);
	if (!g_at_result_iter_next(&iter, "+CIND:"))
		goto error;

	index = 1;

	while (g_at_result_iter_open_list(&iter)) {
		if (!g_at_result_iter_next_string(&iter, &str))
			goto error;

		if (!g_at_result_iter_open_list(&iter))
			goto error;

		while (g_at_result_iter_next_range(&iter, &min, &max))
			;

		if (!g_at_result_iter_close_list(&iter))
			goto error;

		if (!g_at_result_iter_close_list(&iter))
			goto error;

		if (g_str_equal("service", str) == TRUE)
			info->cind_pos[HFP_INDICATOR_SERVICE] = index;
		else if (g_str_equal("call", str) == TRUE)
			info->cind_pos[HFP_INDICATOR_CALL] = index;
		else if (g_str_equal("callsetup", str) == TRUE)
			info->cind_pos[HFP_INDICATOR_CALLSETUP] = index;
		else if (g_str_equal("callheld", str) == TRUE)
			info->cind_pos[HFP_INDICATOR_CALLHELD] = index;
		else if (g_str_equal("signal", str) == TRUE)
			info->cind_pos[HFP_INDICATOR_SIGNAL] = index;
		else if (g_str_equal("roam", str) == TRUE)
			info->cind_pos[HFP_INDICATOR_ROAM] = index;
		else if (g_str_equal("battchg", str) == TRUE)
			info->cind_pos[HFP_INDICATOR_BATTCHG] = index;

		index += 1;
	}

	slc_establish_data_ref(sed);
	g_at_chat_send(info->chat, "AT+CIND?", cind_prefix,
			cind_status_cb, sed, slc_establish_data_unref);
	return;

error:
	slc_failed(sed);
}
Пример #3
0
static void at_cgdcont_test_cb(gboolean ok, GAtResult *result,
				gpointer user_data)
{
	struct ofono_gprs *gprs = user_data;
	struct gprs_data *gd = ofono_gprs_get_data(gprs);
	GAtResultIter iter;
	int min, max;
	const char *pdp_type;
	gboolean found = FALSE;

	if (!ok)
		goto error;

	g_at_result_iter_init(&iter, result);

	while (!found && g_at_result_iter_next(&iter, "+CGDCONT:")) {
		gboolean in_list = FALSE;

		if (!g_at_result_iter_open_list(&iter))
			continue;

		if (g_at_result_iter_next_range(&iter, &min, &max) == FALSE)
			continue;

		if (!g_at_result_iter_close_list(&iter))
			continue;

		if (g_at_result_iter_open_list(&iter))
			in_list = TRUE;

		if (!g_at_result_iter_next_string(&iter, &pdp_type))
			continue;

		if (in_list && !g_at_result_iter_close_list(&iter))
			continue;

		/* We look for IP PDPs */
		if (g_str_equal(pdp_type, "IP"))
			found = TRUE;
	}

	if (found == FALSE)
		goto error;

	ofono_gprs_set_cid_range(gprs, min, max);

	g_at_chat_send(gd->chat, "AT+CGREG=?", cgreg_prefix,
			at_cgreg_test_cb, gprs, NULL);

	return;

error:
	ofono_info("GPRS not supported on this device");
	ofono_gprs_remove(gprs);
}
Пример #4
0
static void at_cgreg_test_cb(gboolean ok, GAtResult *result,
				gpointer user_data)
{
	struct ofono_gprs *gprs = user_data;
	struct gprs_data *gd = ofono_gprs_get_data(gprs);
	gint range[2];
	GAtResultIter iter;
	int cgreg1 = 0;
	int cgreg2 = 0;
	const char *cmd;

	if (!ok)
		goto error;

	g_at_result_iter_init(&iter, result);

	if (!g_at_result_iter_next(&iter, "+CGREG:"))
		goto error;

	if (!g_at_result_iter_open_list(&iter))
		goto error;

	while (g_at_result_iter_next_range(&iter, &range[0], &range[1])) {
		if (1 >= range[0] && 1 <= range[1])
			cgreg1 = 1;
		if (2 >= range[0] && 2 <= range[1])
			cgreg2 = 1;
	}

	g_at_result_iter_close_list(&iter);

	if (cgreg2)
		cmd = "AT+CGREG=2";
	else if (cgreg1)
		cmd = "AT+CGREG=1";
	else
		goto error;

	g_at_chat_send(gd->chat, cmd, none_prefix, NULL, NULL, NULL);
	g_at_chat_send(gd->chat, "AT+CGAUTO=0", none_prefix, NULL, NULL, NULL);

	/* ST-E modem does not support AT+CGEREP = 2,1 */
	if (gd->vendor == OFONO_VENDOR_STE)
		g_at_chat_send(gd->chat, "AT+CGEREP=1,0", none_prefix,
			gprs_initialized, gprs, NULL);
	else
		g_at_chat_send(gd->chat, "AT+CGEREP=2,1", none_prefix,
			gprs_initialized, gprs, NULL);
	return;

error:
	ofono_info("GPRS not supported on this device");
	ofono_gprs_remove(gprs);
}
Пример #5
0
static void at_creg_test_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
	struct ofono_netreg *netreg = user_data;
	struct netreg_data *nd = ofono_netreg_get_data(netreg);
	gint range[2];
	GAtResultIter iter;
	int creg1 = 0;
	int creg2 = 0;

	if (!ok)
		goto error;

	g_at_result_iter_init(&iter, result);

	if (!g_at_result_iter_next(&iter, "+CREG:"))
		goto error;

	if (!g_at_result_iter_open_list(&iter))
		goto error;

	while (g_at_result_iter_next_range(&iter, &range[0], &range[1])) {
		if (1 >= range[0] && 1 <= range[1])
			creg1 = 1;
		if (2 >= range[0] && 2 <= range[1])
			creg2 = 1;
	}

	g_at_result_iter_close_list(&iter);

	if (creg2) {
		g_at_chat_send(nd->chat, "AT+CREG=2", none_prefix,
				at_creg_set_cb, netreg, NULL);
		return;
	}

	if (creg1) {
		g_at_chat_send(nd->chat, "AT+CREG=1", none_prefix,
				at_creg_set_cb, netreg, NULL);
		return;
	}

error:
	ofono_error("Unable to initialize Network Registration");
	ofono_netreg_remove(netreg);
}
Пример #6
0
static void at_cnmi_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
	struct ofono_sms *sms = user_data;
	struct sms_data *data = ofono_sms_get_data(sms);
	GAtResultIter iter;
	int cnmi_opts[5]; /* See 27.005 Section 3.4.1 */
	int opt;
	int mode;
	gboolean supported = FALSE;
	char buf[128];

	if (!ok)
		goto out;

	memset(cnmi_opts, 0, sizeof(cnmi_opts));

	g_at_result_iter_init(&iter, result);

	if (!g_at_result_iter_next(&iter, "+CNMI:"))
		goto out;

	for (opt = 0; opt < 5; opt++) {
		int min, max;

		if (!g_at_result_iter_open_list(&iter))
			goto out;

		while (g_at_result_iter_next_range(&iter, &min, &max)) {
			for (mode = min; mode <= max; mode++)
				cnmi_opts[opt] |= 1 << mode;
		}

		if (!g_at_result_iter_close_list(&iter))
			goto out;
	}

	if (build_cnmi_string(buf, cnmi_opts, data))
		supported = TRUE;

	/* support for ack pdu is not working */
	switch (data->vendor) {
	case OFONO_VENDOR_IFX:
	case OFONO_VENDOR_GOBI:
	case OFONO_VENDOR_HUAWEI:
	case OFONO_VENDOR_NOVATEL:
	case OFONO_VENDOR_OPTION_HSO:
		goto out;
	default:
		break;
	}

	if (data->cnma_enabled)
		construct_ack_pdu(data);

out:
	if (!supported)
		return at_sms_not_supported(sms);

	g_at_chat_send(data->chat, buf, cnmi_prefix,
			at_cnmi_set_cb, sms, NULL);
}
Пример #7
0
static void at_cgreg_test_cb(gboolean ok, GAtResult *result,
				gpointer user_data)
{
	struct ofono_gprs *gprs = user_data;
	struct gprs_data *gd = ofono_gprs_get_data(gprs);
	gint range[2];
	GAtResultIter iter;
	int cgreg1 = 0;
	int cgreg2 = 0;
	const char *cmd;

	if (!ok)
		goto error;

	g_at_result_iter_init(&iter, result);

retry:
	if (!g_at_result_iter_next(&iter, "+CGREG:"))
		goto error;

	if (!g_at_result_iter_open_list(&iter))
		goto retry;

	while (g_at_result_iter_next_range(&iter, &range[0], &range[1])) {
		if (1 >= range[0] && 1 <= range[1])
			cgreg1 = 1;
		if (2 >= range[0] && 2 <= range[1])
			cgreg2 = 1;
	}

	g_at_result_iter_close_list(&iter);

	if (cgreg2)
		cmd = "AT+CGREG=2";
	else if (cgreg1)
		cmd = "AT+CGREG=1";
	else
		goto error;

	g_at_chat_send(gd->chat, cmd, none_prefix, NULL, NULL, NULL);
	g_at_chat_send(gd->chat, "AT+CGAUTO=0", none_prefix, NULL, NULL, NULL);

	switch (gd->vendor) {
	case OFONO_VENDOR_MBM:
		/* Ericsson MBM and ST-E modems don't support AT+CGEREP=2,1 */
		g_at_chat_send(gd->chat, "AT+CGEREP=1,0", none_prefix,
			gprs_initialized, gprs, NULL);
		break;
	case OFONO_VENDOR_NOKIA:
		/* Nokia data cards don't support AT+CGEREP=1,0 either */
		g_at_chat_send(gd->chat, "AT+CGEREP=1", none_prefix,
			gprs_initialized, gprs, NULL);
		break;
	default:
		g_at_chat_send(gd->chat, "AT+CGEREP=2,1", none_prefix,
			gprs_initialized, gprs, NULL);
		break;
	}

	return;

error:
	ofono_info("GPRS not supported on this device");
	ofono_gprs_remove(gprs);
}
Пример #8
0
static void mux_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
	struct mux_setup_data *msd = user_data;
	struct mux_setup_data *nmsd;
	GAtResultIter iter;
	int min, max;
	int speed;
	char buf[64];

	/* CMUX query not supported, abort */
	if (!ok)
		goto error;

	g_at_result_iter_init(&iter, result);

	if (!g_at_result_iter_next(&iter, "+CMUX:"))
		goto error;

	/* Mode */
	if (!g_at_result_iter_open_list(&iter))
		goto error;

	if (!g_at_result_iter_next_range(&iter, &min, &max))
		goto error;

	if (!g_at_result_iter_close_list(&iter))
		goto error;

	if (min <= 1 && 1 <= max)
		msd->mode = 1;
	else if (min <= 0 && 0 <= max)
		msd->mode = 0;
	else
		goto error;

	/* Subset */
	if (!g_at_result_iter_open_list(&iter))
		goto error;

	if (!g_at_result_iter_next_range(&iter, &min, &max))
		goto error;

	if (!g_at_result_iter_close_list(&iter))
		goto error;

	if (min > 0)
		goto error;

	/* Speed, pick highest */
	if (g_at_result_iter_open_list(&iter)) {
		if (!g_at_result_iter_next_range(&iter, &min, &max))
			goto error;

		if (!g_at_result_iter_close_list(&iter))
			goto error;

		speed = max;
	} else {
		if (!g_at_result_iter_skip_next(&iter))
			goto error;

		/* not available/used */
		speed = -1;
	}

	/* Frame size, pick defaults */
	if (!g_at_result_iter_open_list(&iter))
		goto error;

	if (!g_at_result_iter_next_range(&iter, &min, &max))
		goto error;

	if (!g_at_result_iter_close_list(&iter))
		goto error;

	if (msd->mode == 0) {
		if (min > 31 || max < 31)
			goto error;

		msd->frame_size = 31;
	} else if (msd->mode == 1) {
		if (min > 64 || max < 64)
			goto error;

		msd->frame_size = 64;
	} else
		goto error;

	nmsd = g_memdup(msd, sizeof(struct mux_setup_data));
	g_at_chat_ref(nmsd->chat);

	if (speed < 0)
		sprintf(buf, "AT+CMUX=%u,0,,%u", msd->mode, msd->frame_size);
	else
		sprintf(buf, "AT+CMUX=%u,0,%u,%u", msd->mode, speed,
							msd->frame_size);

	if (g_at_chat_send(msd->chat, buf, none_prefix,
				mux_setup_cb, nmsd, msd_free) > 0)
		return;

	msd_free(nmsd);

error:
	msd->func(NULL, msd->user);

	if (msd->destroy)
		msd->destroy(msd->user);
}
Пример #9
0
static void cind_support_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
	struct ofono_netreg *netreg = user_data;
	struct netreg_data *nd = ofono_netreg_get_data(netreg);
	GAtResultIter iter;
	const char *str;
	int index;
	int min = 0;
	int max = 0;
	int tmp_min, tmp_max, invalid;

	if (!ok)
		goto error;

	g_at_result_iter_init(&iter, result);
	if (!g_at_result_iter_next(&iter, "+CIND:"))
		goto error;

	index = 1;

	/*
	 * Telit encapsulates the CIND=? tokens with braces
	 * so we need to skip them
	 */
	if (nd->vendor == OFONO_VENDOR_TELIT)
		g_at_result_iter_open_list(&iter);

	while (g_at_result_iter_open_list(&iter)) {
		/* Reset invalid default value for every token */
		invalid = 99;

		if (!g_at_result_iter_next_string(&iter, &str))
			goto error;

		if (!g_at_result_iter_open_list(&iter))
			goto error;

		while (g_at_result_iter_next_range(&iter, &tmp_min, &tmp_max)) {
			if (tmp_min != tmp_max) {
				min = tmp_min;
				max = tmp_max;
			} else
				invalid = tmp_min;
		}

		if (!g_at_result_iter_close_list(&iter))
			goto error;

		if (!g_at_result_iter_close_list(&iter))
			goto error;

		if (g_str_equal("signal", str) == TRUE) {
			nd->signal_index = index;
			nd->signal_min = min;
			nd->signal_max = max;
			nd->signal_invalid = invalid;
		}

		index += 1;
	}

	if (nd->vendor == OFONO_VENDOR_TELIT)
		g_at_result_iter_close_list(&iter);

	if (nd->signal_index == 0)
		goto error;

	g_at_chat_send(nd->chat, "AT+CMER=3,0,0,1", NULL,
			NULL, NULL, NULL);
	g_at_chat_register(nd->chat, "+CIEV:",
				ciev_notify, FALSE, netreg, NULL);
	g_at_chat_register(nd->chat, "+CREG:",
				creg_notify, FALSE, netreg, NULL);

	ofono_netreg_register(netreg);
	return;

error:
	ofono_error("This driver is not setup with Signal Strength reporting"
			" via CIND indications, please write proper netreg"
			" handling for this device");

	ofono_netreg_remove(netreg);
}