Example #1
0
static void ril_gprs_context_call_list_changed(struct ril_msg *message,
						gpointer user_data)
{
	struct ofono_gprs_context *gc = user_data;
	struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
	struct data_call *call = NULL;
	struct unsol_data_call_list *unsol;
	gboolean active_cid_found = FALSE;
	gboolean disconnect = FALSE;
	GSList *iterator = NULL;
	struct ofono_error error;

	unsol = g_ril_unsol_parse_data_call_list(gcd->ril, message, &error);

	if (error.type != OFONO_ERROR_TYPE_NO_ERROR)
		goto error;

	DBG("number of call in call_list_changed is: %d", unsol->num);

	for (iterator = unsol->call_list; iterator; iterator = iterator->next) {
		call = (struct data_call *) iterator->data;

		if (call->cid == gcd->active_rild_cid) {
			active_cid_found = TRUE;

			if (call->active == 0) {
				disconnect = TRUE;
				ofono_gprs_context_deactivated(gc, gcd->active_ctx_cid);
			}

			break;
		}
	}

	if (disconnect || active_cid_found == FALSE) {
		ofono_error("Clearing active context");
		set_context_disconnected(gcd);
	}

error:
	g_ril_unsol_free_data_call_list(unsol);
}
Example #2
0
static void get_active_data_calls_cb(struct ril_msg *message,
					gpointer user_data)
{
	struct ofono_gprs *gprs = user_data;
	struct ril_gprs_data *gd = ofono_gprs_get_data(gprs);
	struct ril_data_call_list *call_list = NULL;
	GSList *iterator;
	struct ril_data_call *call;

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

	/* reply can be NULL when there are no existing data calls */
	call_list = g_ril_unsol_parse_data_call_list(gd->ril, message);
	if (call_list == NULL)
		goto end;

	/*
	 * We disconnect from previous calls here, which might be needed
	 * because of a previous ofono abort, as some rild implementations do
	 * not disconnect the calls even after the ril socket is closed.
	 */
	for (iterator = call_list->calls; iterator; iterator = iterator->next) {
		call = iterator->data;
		DBG("Standing data call with cid %d", call->cid);
		if (drop_data_call(gprs, call->cid) == 0)
			++(gd->pending_deact_req);
	}

	g_ril_unsol_free_data_call_list(call_list);

end:
	if (gd->pending_deact_req == 0)
		ril_gprs_registration_status(gprs, NULL, NULL);
}
Example #3
0
/*
 * This function handles RIL_UNSOL_DATA_CALL_LIST_CHANGED messages,
 * as well as RIL_REQUEST_DATA_CALL_LIST/SETUP_DATA_CALL replies, as
 * all have the same payload.
 */
struct ril_data_call_list *g_ril_unsol_parse_data_call_list(GRil *gril,
						const struct ril_msg *message)
{
	struct ril_data_call *call;
	struct parcel rilp;
	struct ril_data_call_list *reply = NULL;
	unsigned int active, cid, i, num_calls, retry, status;
	char *type = NULL, *ifname = NULL, *raw_addrs = NULL;
	char *raw_dns = NULL, *raw_gws = NULL;

	DBG("");

	/* Can happen for RIL_REQUEST_DATA_CALL_LIST replies */
	if (message->buf_len < MIN_DATA_CALL_LIST_SIZE) {
		if (message->req == RIL_REQUEST_SETUP_DATA_CALL) {
			ofono_error("%s: message too small: %d",
					__func__,
					(int) message->buf_len);
			goto error;
		} else {
			g_ril_append_print_buf(gril, "{");
			goto done;
		}
	}

	reply = g_try_new0(struct ril_data_call_list, 1);
	if (reply == NULL) {
		ofono_error("%s: out of memory", __func__);
		goto error;
	}

	g_ril_init_parcel(message, &rilp);

	/*
	 * ril.h documents the reply to a RIL_REQUEST_DATA_CALL_LIST
	 * as being an array of  RIL_Data_Call_Response_v6 structs,
	 * however in reality, the response also includes a version
	 * to start.
	 */
	reply->version = parcel_r_int32(&rilp);
	num_calls = parcel_r_int32(&rilp);

	g_ril_append_print_buf(gril,
				"{version=%d,num=%d",
				reply->version,
				num_calls);

	for (i = 0; i < num_calls; i++) {
		status = parcel_r_int32(&rilp);
		retry = parcel_r_int32(&rilp);          /* ignore */
		cid = parcel_r_int32(&rilp);
		active = parcel_r_int32(&rilp);
		type = parcel_r_string(&rilp);
		ifname = parcel_r_string(&rilp);
		raw_addrs = parcel_r_string(&rilp);
		raw_dns = parcel_r_string(&rilp);
		raw_gws = parcel_r_string(&rilp);

		/* malformed check */
		if (rilp.malformed) {
			ofono_error("%s: malformed parcel received", __func__);
			goto error;
		}

		g_ril_append_print_buf(gril,
					"%s [status=%d,retry=%d,cid=%d,"
					"active=%d,type=%s,ifname=%s,"
					"address=%s,dns=%s,gateways=%s]",
					print_buf,
					status,
					retry,
					cid,
					active,
					type,
					ifname,
					raw_addrs,
					raw_dns,
					raw_gws);

		call = g_try_new0(struct ril_data_call, 1);
		if (call == NULL) {
			ofono_error("%s: out of memory", __func__);
			goto error;
		}

		call->status = status;
		call->cid = cid;
		call->active = active;

		if (message->req == RIL_REQUEST_SETUP_DATA_CALL &&
			status == PDP_FAIL_NONE &&
			handle_settings(call, type, ifname, raw_addrs,
					raw_dns, raw_gws) == FALSE)
			goto error;

		g_free(type);
		g_free(ifname);
		g_free(raw_addrs);
		g_free(raw_dns);
		g_free(raw_gws);

		reply->calls =
			g_slist_insert_sorted(reply->calls, call,
						data_call_compare);
	}

done:
	g_ril_append_print_buf(gril, "%s}", print_buf);

	if (message->unsolicited)
		g_ril_print_unsol(gril, message);
	else
		g_ril_print_response(gril, message);

	return reply;

error:
	g_free(type);
	g_free(ifname);
	g_free(raw_addrs);
	g_free(raw_dns);
	g_free(raw_gws);
	g_ril_unsol_free_data_call_list(reply);

	return NULL;
}
Example #4
0
static void ril_gprs_context_call_list_changed(struct ril_msg *message,
						gpointer user_data)
{
	struct ofono_gprs_context *gc = user_data;
	struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
	struct data_call *call = NULL;
	struct unsol_data_call_list *unsol;
	gboolean disconnect = FALSE;
	GSList *iterator = NULL;
	struct ofono_error error;

	unsol = g_ril_unsol_parse_data_call_list(gcd->ril, message, &error);

	if (error.type != OFONO_ERROR_TYPE_NO_ERROR)
		goto error;

	DBG("number of call in call_list_changed is: %d", unsol->num);

	for (iterator = unsol->call_list; iterator; iterator = iterator->next) {
		call = (struct data_call *) iterator->data;

		if (call->status != 0)
			ofono_info("data call status:%d", call->status);

		if (call->active == DATA_CALL_INACTIVE) {
			disconnect = TRUE;
			ofono_gprs_context_deactivated(gc, gcd->active_ctx_cid);
			break;
		}

		if (call->active == DATA_CALL_ACTIVE) {
			char **split_ip_addr = NULL;
			const char **dns_addresses;

			if (call->ifname) {
				ofono_gprs_context_set_interface(gc,
								call->ifname);
			}

			if (call->addresses) {
				ofono_gprs_context_set_ipv4_netmask(gc,
					ril_util_get_netmask(call->addresses));

				split_ip_addr = g_strsplit(call->addresses,
									"/", 2);
				ofono_gprs_context_set_ipv4_address(gc,
							split_ip_addr[0], TRUE);
			}

			if (call->gateways) {
				ofono_gprs_context_set_ipv4_gateway(gc,
								call->gateways);
			}


			if (call->dnses)
				DBG("dnses:%s", call->dnses);

			dns_addresses =
				(const char **)(call->dnses ?
				g_strsplit((const gchar*)call->dnses, " ", 3)
									: NULL);

			ofono_gprs_context_set_ipv4_dns_servers(gc,
								dns_addresses);
			break;
		}
	}

	if (disconnect) {
		ofono_error("Clearing active context");
		set_context_disconnected(gcd);
	}

error:
	g_ril_unsol_free_data_call_list(unsol);
}