Exemplo n.º 1
0
static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
{
	struct cb_data *cbd = user_data;
	ofono_gprs_context_cb_t cb = cbd->cb;
	struct ofono_gprs_context *gc = cbd->user;
	struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
	struct ofono_error error;
	struct reply_setup_data_call *reply = NULL;
	char **split_ip_addr = NULL;

	ofono_info("setting up data call");

	if (message->error != RIL_E_SUCCESS) {
		ofono_error("GPRS context: Reply failure: %s",
			    ril_error_to_string(message->error));

		error.type = OFONO_ERROR_TYPE_FAILURE;
		error.error = message->error;

		set_context_disconnected(gcd);
		goto error;
	}

	reply = g_ril_reply_parse_data_call(gcd->ril, message, &error);

	gcd->active_rild_cid = reply->cid;

	if (error.type != OFONO_ERROR_TYPE_NO_ERROR) {
		if (gcd->active_rild_cid != -1) {
			ofono_error("no active context. disconnect");
			disconnect_context(gc);
		}
		goto error;
	}

	if (reply->status != 0) {
		ofono_error("%s: reply->status is non-zero: %d",
				__func__,
				reply->status);

		error.type = OFONO_ERROR_TYPE_FAILURE;
		error.error = reply->status;

		set_context_disconnected(gcd);
		goto error;
	}

	/*
	 * TODO: consier moving this into parse_data_reply
	 *
	 * Note - the address may optionally include a prefix size
	 * ( Eg. "/30" ).  As this confuses NetworkManager, we
	 * explicitly strip any prefix after calculating the netmask.
	 */
	split_ip_addr = g_strsplit(reply->ip_addrs[0], "/", 2);

	/* TODO: see note above re: invalid messages... */
	if (split_ip_addr[0] == NULL) {
		ofono_error("%s: invalid IP address field returned: %s",
				__func__,
				reply->ip_addrs[0]);

		error.type = OFONO_ERROR_TYPE_FAILURE;
		error.error = EINVAL;

		set_context_disconnected(gcd);
		goto error;
	}

	gcd->state = STATE_ACTIVE;

	ofono_gprs_context_set_interface(gc, reply->ifname);

	/* TODO:
	 * RILD can return multiple addresses; oFono only supports
	 * setting a single IPv4 address.  At this time, we only
	 * use the first address.  It's possible that a RIL may
	 * just specify the end-points of the point-to-point
	 * connection, in which case this code will need to
	 * changed to handle such a device.
	 */
	ofono_gprs_context_set_ipv4_netmask(gc,
			ril_util_get_netmask(reply->ip_addrs[0]));

	ofono_gprs_context_set_ipv4_address(gc, split_ip_addr[0], TRUE);
	ofono_gprs_context_set_ipv4_gateway(gc, reply->gateways[0]);

	ofono_gprs_context_set_ipv4_dns_servers(gc,
						(const char **) reply->dns_addresses);

error:
	g_ril_reply_free_setup_data_call(reply);
	g_strfreev(split_ip_addr);

	cb(&error, cbd->data);
}
Exemplo n.º 2
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);
}