Esempio n. 1
0
static void cgreg_notify(GAtResult *result, gpointer user_data)
{
	struct ofono_gprs *gprs = user_data;
	int status;
	struct gprs_data *gd = ofono_gprs_get_data(gprs);

	if (at_util_parse_reg_unsolicited(result, "+CGREG:", &status,
				NULL, NULL, NULL, gd->vendor) == FALSE)
		return;

	/*
	 * Telit AT modem firmware (tested with UE910-EUR) generates
	 * +CGREG: 0\r\n\r\n+CGEV: NW DETACH
	 * after a context is de-activated and ppp connection closed.
	 * Then, after a random amount of time (observed from a few seconds
	 * to a few hours), an unsolicited +CGREG: 1 arrives.
	 * Attempt to fix the problem, by sending AT+CGATT=1 once.
	 * This does not re-activate the context, but if a network connection
	 * is still correct, will generate an immediate +CGREG: 1.
	 */
	if (gd->vendor == OFONO_VENDOR_TELIT) {
		if (gd->attached && !status && !gd->telit_try_reattach) {
			DBG("Trying to re-attach gprs network");
			gd->telit_try_reattach = TRUE;
			g_at_chat_send(gd->chat, "AT+CGATT=1", none_prefix,
					NULL, NULL, NULL);
			return;
		}

		gd->telit_try_reattach = FALSE;
	}

	ofono_gprs_status_notify(gprs, status);
}
Esempio n. 2
0
static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_gprs_status_cb_t cb = cbd->cb;
	struct ofono_gprs *gprs = cbd->user;
	struct gprs_data *gd = ofono_gprs_get_data(gprs);
	struct ofono_error error;
	int status, lac, ci, tech;
	int max_cids = 1;

	if (message->error == RIL_E_SUCCESS) {
		decode_ril_error(&error, "OK");
	} else {
		ofono_error("ril_data_reg_cb: reply failure: %s",
				ril_error_to_string(message->error));
		decode_ril_error(&error, "FAIL");
		error.error = message->error;
		status = -1;
		goto error;
	}

	if (ril_util_parse_reg(message, &status,
				&lac, &ci, &tech, &max_cids) == FALSE) {
		ofono_error("Failure parsing data registration response.");
		decode_ril_error(&error, "FAIL");
		status = -1;
		goto error;
	}

	if (gd->status == -1) {
		DBG("calling ofono_gprs_register...");
		ofono_gprs_register(gprs);

		g_ril_register(gd->ril, RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,
				ril_gprs_state_change, gprs);
	}

	if (max_cids > gd->max_cids) {
		DBG("Setting max cids to %d", max_cids);
		gd->max_cids = max_cids;
		ofono_gprs_set_cid_range(gprs, 1, max_cids);
	}

	if (gd->status != status) {
		DBG("gd->status: %d status: %d", gd->status, status);
		ofono_gprs_status_notify(gprs, status);
	}

	gd->status = status;
	gd->tech = tech;

error:
	if (cb)
		cb(&error, status, cbd->data);
}
Esempio n. 3
0
File: gprs.c Progetto: yongsu/oFono
static void cgreg_notify(GAtResult *result, gpointer user_data)
{
	struct ofono_gprs *gprs = user_data;
	int status;
	struct gprs_data *gd = ofono_gprs_get_data(gprs);

	if (at_util_parse_reg_unsolicited(result, "+CGREG:", &status,
				NULL, NULL, NULL, gd->vendor) == FALSE)
		return;

	ofono_gprs_status_notify(gprs, status);
}
Esempio n. 4
0
static gboolean ril_fake_response(gpointer user_data)
{
	struct cb_data *cbd = user_data;
	struct ofono_gprs *gprs = cbd->user;
	struct gprs_data *gd = ofono_gprs_get_data(gprs);

	DBG("");

	gd->fake_timer_id = 0;
	ofono_gprs_status_notify(gprs, gd->true_status);
	g_free(cbd); /* == gd->fake_cbd */
	gd->fake_cbd = NULL;
	return FALSE;
}
Esempio n. 5
0
static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_gprs_status_cb_t cb = cbd->cb;
	struct ofono_gprs *gprs = cbd->user;
	struct ril_gprs_data *gd = ofono_gprs_get_data(gprs);
	struct reply_data_reg_state *reply;
	gboolean attached = FALSE;
	gboolean notify_status = FALSE;
	int old_status;

	old_status = gd->rild_status;

	if (message->error == RIL_E_SUCCESS) {
		reply = g_ril_reply_parse_data_reg_state(gd->ril, message);
		if (reply == NULL) {
			if (cb)
				CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
			return;
		}
	} else {
		/*
		 * If we get a RIL error (say, radio not available) it is better
		 * to return unknown values than to call cb with failure status.
		 * If we do the last, ConnectionManager would not be created if
		 * this is the first time we retrieve data status, or we can
		 * even create infinite loops as the status in gprs atom would
		 * not be refreshed. When we finally register we will get events
		 * so we will try to retrieve data state again.
		 */
		ofono_error("%s: DATA_REGISTRATION_STATE reply failure: %s",
				__func__,
				ril_error_to_string(message->error));

		reply = g_malloc0(sizeof(*reply));
		reply->reg_state.status = NETWORK_REGISTRATION_STATUS_UNKNOWN;
		reply->reg_state.tech = RADIO_TECH_UNKNOWN;
	}

	/*
	 * There are three cases that can result in this callback
	 * running:
	 *
	 * 1) The driver's probe() method was called, and thus an
	 *    internal call to ril_gprs_registration_status() is
	 *    generated.  No ofono cb exists.
	 *
	 * 2) ril_gprs_state_change() is called due to an unsolicited
	 *    event from RILD.  No ofono cb exists.
	 *
	 * 3) The ofono code code calls the driver's attached_status()
	 *    function.  A valid ofono cb exists.
	 */

	if (gd->rild_status != reply->reg_state.status) {
		gd->rild_status = reply->reg_state.status;

		if (cb == NULL)
			notify_status = TRUE;
	}

	/*
	 * Override the actual status based upon the desired
	 * attached status set by the core GPRS code ( controlled
	 * by the ConnnectionManager's 'Powered' property ).
	 */
	attached = (reply->reg_state.status ==
				NETWORK_REGISTRATION_STATUS_REGISTERED ||
			reply->reg_state.status ==
				NETWORK_REGISTRATION_STATUS_ROAMING);

	if (attached && gd->ofono_attached == FALSE) {
		DBG("attached=true; ofono_attached=false; return !REGISTERED");
		reply->reg_state.status =
			NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;

		/*
		 * Further optimization so that if ril_status ==
		 * NOT_REGISTERED, ofono_attached == false, and status ==
		 * ROAMING | REGISTERED, then notify gets cleared...
		 *
		 * As is, this results in unecessary status notify calls
		 * when nothing has changed.
		 */
		if (notify_status && reply->reg_state.status == old_status)
			notify_status = FALSE;
	}

	if (old_status == -1) {
		ofono_gprs_register(gprs);

		/* Different rild implementations use different events here */
		g_ril_register(gd->ril,
				gd->state_changed_unsol,
				ril_gprs_state_change, gprs);

		if (reply->max_cids == 0)
			gd->max_cids = RIL_MAX_NUM_ACTIVE_DATA_CALLS;
		else if (reply->max_cids < RIL_MAX_NUM_ACTIVE_DATA_CALLS)
			gd->max_cids = reply->max_cids;
		else
			gd->max_cids = RIL_MAX_NUM_ACTIVE_DATA_CALLS;

		DBG("Setting max cids to %d", gd->max_cids);
		ofono_gprs_set_cid_range(gprs, 1, gd->max_cids);

		/*
		 * This callback is a result of the inital call
		 * to probe(), so should return after registration.
		 */
		g_free(reply);

		return;
	}

	/* Just need to notify ofono if it's already attached */
	if (notify_status) {

		/*
		 * If network disconnect has occurred, call detached_notify()
		 * instead of status_notify().
		 */
		if (!attached &&
			(old_status == NETWORK_REGISTRATION_STATUS_REGISTERED ||
				old_status ==
					NETWORK_REGISTRATION_STATUS_ROAMING)) {
			DBG("calling ofono_gprs_detached_notify()");
			ofono_gprs_detached_notify(gprs);
			reply->reg_state.tech = RADIO_TECH_UNKNOWN;
		} else {
			DBG("calling ofono_gprs_status_notify()");
			ofono_gprs_status_notify(gprs, reply->reg_state.status);
		}
	}

	gd->tech = reply->reg_state.tech;
	ofono_gprs_bearer_notify(gprs,
				ril_tech_to_bearer_tech(reply->reg_state.tech));

	if (cb)
		CALLBACK_WITH_SUCCESS(cb, reply->reg_state.status, cbd->data);

	g_free(reply);
}
Esempio n. 6
0
File: gprs.c Progetto: morphis/ofono
static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_gprs_status_cb_t cb = cbd->cb;
	struct ofono_gprs *gprs = cbd->user;
	struct ril_gprs_data *gd = ofono_gprs_get_data(gprs);
	struct reply_data_reg_state *reply;
	gboolean attached = FALSE;
	gboolean notify_status = FALSE;
	int old_status;

	old_status = gd->rild_status;

	if (message->error != RIL_E_SUCCESS) {
		ofono_error("%s: DATA_REGISTRATION_STATE reply failure: %s",
				__func__,
				ril_error_to_string(message->error));
		goto error;
	}

	if ((reply = g_ril_reply_parse_data_reg_state(gd->ril, message))
			== NULL)
		goto error;

	/*
	 * There are three cases that can result in this callback
	 * running:
	 *
	 * 1) The driver's probe() method was called, and thus an
	 *    internal call to ril_gprs_registration_status() is
	 *    generated.  No ofono cb exists.
	 *
	 * 2) ril_gprs_state_change() is called due to an unsolicited
	 *    event from RILD.  No ofono cb exists.
	 *
	 * 3) The ofono code code calls the driver's attached_status()
	 *    function.  A valid ofono cb exists.
	 */

	if (gd->rild_status != reply->reg_state.status) {
		gd->rild_status = reply->reg_state.status;

		if (cb == NULL)
			notify_status = TRUE;
	}

	/*
	 * Override the actual status based upon the desired
	 * attached status set by the core GPRS code ( controlled
	 * by the ConnnectionManager's 'Powered' property ).
	 */
	attached = (reply->reg_state.status ==
				NETWORK_REGISTRATION_STATUS_REGISTERED ||
			reply->reg_state.status ==
				NETWORK_REGISTRATION_STATUS_ROAMING);

	if (attached && gd->ofono_attached == FALSE) {
		DBG("attached=true; ofono_attached=false; return !REGISTERED");
		reply->reg_state.status =
			NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;

		/*
		 * Further optimization so that if ril_status ==
		 * NOT_REGISTERED, ofono_attached == false, and status ==
		 * ROAMING | REGISTERED, then notify gets cleared...
		 *
		 * As is, this results in unecessary status notify calls
		 * when nothing has changed.
		 */
		if (notify_status && reply->reg_state.status == old_status)
			notify_status = FALSE;
	}

	if (old_status == -1) {
		ofono_gprs_register(gprs);

		/* Different rild implementations use different events here */
		g_ril_register(gd->ril,
				gd->state_changed_unsol,
				ril_gprs_state_change, gprs);

		if (reply->max_cids == 0)
			gd->max_cids = RIL_MAX_NUM_ACTIVE_DATA_CALLS;
		else if (reply->max_cids < RIL_MAX_NUM_ACTIVE_DATA_CALLS)
			gd->max_cids = reply->max_cids;
		else
			gd->max_cids = RIL_MAX_NUM_ACTIVE_DATA_CALLS;

		DBG("Setting max cids to %d", gd->max_cids);
		ofono_gprs_set_cid_range(gprs, 1, gd->max_cids);

		/*
		 * This callback is a result of the inital call
		 * to probe(), so should return after registration.
		 */
		g_free(reply);

		return;
	}

	/* Just need to notify ofono if it's already attached */
	if (notify_status) {

		/*
		 * If network disconnect has occurred, call detached_notify()
		 * instead of status_notify().
		 */
		if (!attached &&
			(old_status == NETWORK_REGISTRATION_STATUS_REGISTERED ||
				old_status ==
					NETWORK_REGISTRATION_STATUS_ROAMING)) {
			DBG("calling ofono_gprs_detached_notify()");
			ofono_gprs_detached_notify(gprs);
			reply->reg_state.tech = RADIO_TECH_UNKNOWN;
		} else {
			DBG("calling ofono_gprs_status_notify()");
			ofono_gprs_status_notify(gprs, reply->reg_state.status);
		}
	}

	if (gd->tech != reply->reg_state.tech) {
		gd->tech = reply->reg_state.tech;

		ofono_gprs_bearer_notify(gprs,
				ril_tech_to_bearer_tech(reply->reg_state.tech));
	}

	if (cb)
		CALLBACK_WITH_SUCCESS(cb, reply->reg_state.status, cbd->data);

	g_free(reply);

	return;
error:

	/*
	 * For some modems DATA_REGISTRATION_STATE will return an error until we
	 * are registered in the voice network.
	 */
	if (old_status == -1 && message->error == RIL_E_GENERIC_FAILURE)
		gd->status_retry_cb_id =
			g_timeout_add(GET_STATUS_TIMER_MS,
					ril_get_status_retry, gprs);

	if (cb)
		CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
}
Esempio n. 7
0
File: gprs.c Progetto: saukko/ofono
static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_gprs_status_cb_t cb = cbd->cb;
	struct ofono_gprs *gprs = cbd->user;
	struct gprs_data *gd = ofono_gprs_get_data(gprs);
	struct ofono_error error;
	gboolean attached;
	int status, lac, ci, tech;
	int max_cids = 1;

	if (message->error == RIL_E_SUCCESS) {
		decode_ril_error(&error, "OK");
	} else {
		ofono_error("ril_data_reg_cb: reply failure: %s",
				ril_error_to_string(message->error));
		decode_ril_error(&error, "FAIL");
		error.error = message->error;
		status = -1;
		goto error;
	}

	if (ril_util_parse_reg(gd->ril, message, &status,
				&lac, &ci, &tech, &max_cids) == FALSE) {
		ofono_error("Failure parsing data registration response.");
		decode_ril_error(&error, "FAIL");
		status = -1;
		goto error;
	}

	if (gd->rild_status == -1) {
		ofono_gprs_register(gprs);

		/* RILD tracks data network state together with voice */
		g_ril_register(gd->ril, RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,
				ril_gprs_state_change, gprs);
	}

	if (max_cids > gd->max_cids) {
		DBG("Setting max cids to %d", max_cids);
		gd->max_cids = max_cids;
		ofono_gprs_set_cid_range(gprs, 1, max_cids);
	}

	/* We need to notify core always to cover situations when
	 * connection drops temporarily for example when user is
	 * taking CS voice call from LTE or changing technology
	 * preference */
	if (gd->rild_status != status)
		ofono_gprs_status_notify(gprs, status);

	gd->rild_status = status;

	/*
	 * Override the actual status based upon the desired
	 * attached status set by the core GPRS code ( controlled
	 * by the ConnnectionManager's 'Powered' property ).
	 */
	attached = (status == NETWORK_REGISTRATION_STATUS_REGISTERED ||
			status == NETWORK_REGISTRATION_STATUS_ROAMING);

	if (attached && gd->ofono_attached == FALSE) {
		DBG("attached=true; ofono_attached=false; return !REGISTERED");
		status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;
	}

error:
	if (cb)
		cb(&error, status, cbd->data);
}
Esempio n. 8
0
static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_gprs_status_cb_t cb = cbd->cb;
	struct ofono_gprs *gprs = cbd->user;
	struct gprs_data *gd = ofono_gprs_get_data(gprs);
	struct ofono_error error;
	int status, lac, ci, tech;
	int max_cids = 1;

	DBG("");

	if (gd && message->error == RIL_E_SUCCESS) {
		decode_ril_error(&error, "OK");
	} else {
		ofono_error("ril_data_reg_cb: reply failure: %s",
				ril_error_to_string(message->error));
		decode_ril_error(&error, "FAIL");
		error.error = message->error;
		status = -1;
		goto error;
	}

	if (ril_util_parse_reg(gd->ril, message, &status,
				&lac, &ci, &tech, &max_cids) == FALSE) {
		ofono_error("Failure parsing data registration response.");
		decode_ril_error(&error, "FAIL");
		status = -1;
		goto error;
	}

	if ((gd->fake_timer_id > 0)
			&& ((status == NETWORK_REGISTRATION_STATUS_REGISTERED
				|| status == NETWORK_REGISTRATION_STATUS_ROAMING)
				|| !gd->ofono_attached)) {
		remove_fake_timer(gd);
		gd->true_status = -1;
	}

	if (status > 10)
		status = status - 10;

	if (!registered) {
		ofono_gprs_register(gprs);
		registered = TRUE;
	}

	if (max_cids > gd->max_cids) {
		DBG("Setting max cids to %d", max_cids);
		gd->max_cids = max_cids;
		ofono_gprs_set_cid_range(gprs, 1, max_cids);
	}

	ofono_info("data registration status is %d", status);

	if (status == NETWORK_REGISTRATION_STATUS_ROAMING)
		status = check_if_really_roaming(status);

	DBG(" attached:%d, status:%d", gd->ofono_attached, status);

	if (!gd->ofono_attached) {
		if (status == NETWORK_REGISTRATION_STATUS_ROAMING) {
			if (!gd->notified && cb) {
				if (ril_roaming_allowed() == FALSE)
					ofono_gprs_detached_notify(gprs);

				/*
				 * This prevents core ending
				 * into eternal loop with driver
				 */
				decode_ril_error(&error, "FAIL");

				ofono_gprs_status_notify(gprs, status);
			}
		} else {
			if (status == NETWORK_REGISTRATION_STATUS_SEARCHING &&
								!gd->notified &&
								cb)
				/*
				 * This is a hack that prevents core ending
				 * into eternal loop with driver
				 */
				decode_ril_error(&error, "FAIL");

			ofono_gprs_status_notify(gprs, status);
		}

		if (cb)
			gd->notified = TRUE;

		gd->rild_status = status;
		goto error;
	}

	if (status == NETWORK_REGISTRATION_STATUS_ROAMING ||
		status == NETWORK_REGISTRATION_STATUS_REGISTERED) {
			ofono_gprs_status_notify(gprs, status);
			gd->rild_status = status;
	} else {
		if (gd->fake_timer_id <= 0) {
			gd->fake_cbd = cb_data_new(NULL, NULL);
			gd->fake_cbd->user = gprs;
			DBG("Start rilmodem fake status timer");
			gd->fake_timer_id = g_timeout_add_seconds(
						FAKE_STATE_TIMER,
						ril_fake_response, gd->fake_cbd);
		}

		gd->true_status = status;

		if (gd->rild_status == NETWORK_REGISTRATION_STATUS_ROAMING)
			status = NETWORK_REGISTRATION_STATUS_ROAMING;
		else
			status = NETWORK_REGISTRATION_STATUS_REGISTERED;

		gd->rild_status = status;
	}

error:
	ofono_info("data registration status is %d", status);

	if (cb)
		cb(&error, status, cbd->data);
}