static void ppp_connect(const char *interface, const char *local, const char *remote, const char *dns1, const char *dns2, gpointer user_data) { struct ofono_gprs_context *gc = user_data; struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); const char *dns[3]; DBG(""); dns[0] = dns1; dns[1] = dns2; dns[2] = 0; ofono_info("IP: %s", local); ofono_info("DNS: %s, %s", dns1, dns2); gcd->state = STATE_ACTIVE; ofono_gprs_context_set_interface(gc, interface); ofono_gprs_context_set_ipv4_address(gc, local, TRUE); ofono_gprs_context_set_ipv4_netmask(gc, STATIC_IP_NETMASK); ofono_gprs_context_set_ipv4_dns_servers(gc, dns); CALLBACK_WITH_SUCCESS(gcd->cb, gcd->cb_data); }
/* * CGCONTRDP returns addr + netmask in the same string in the form * of "a.b.c.d.m.m.m.m" for IPv4. IPv6 is not supported so we ignore it. */ static int set_address_and_netmask(struct ofono_gprs_context *gc, const char *addrnetmask) { char *dup = strdup(addrnetmask); char *s = dup; const char *addr = s; const char *netmask = NULL; int ret = -EINVAL; int i; /* Count 7 dots for ipv4, less or more means error. */ for (i = 0; i < 8; i++, s++) { s = strchr(s, '.'); if (!s) break; if (i == 3) { /* set netmask ptr and break the string */ netmask = s + 1; s[0] = 0; } } if (i == 7) { ofono_gprs_context_set_ipv4_address(gc, addr, 1); ofono_gprs_context_set_ipv4_netmask(gc, netmask); ret = 0; } free(dup); return ret; }
static void uipaddr_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; const char *gw = NULL; const char *netmask = NULL; DBG("ok %d", ok); if (!ok) { CALLBACK_WITH_SUCCESS(gcd->cb, gcd->cb_data); return; } g_at_result_iter_init(&iter, result); while (g_at_result_iter_next(&iter, "+UIPADDR:")) { g_at_result_iter_skip_next(&iter); g_at_result_iter_skip_next(&iter); if (!g_at_result_iter_next_string(&iter, &gw)) break; if (!g_at_result_iter_next_string(&iter, &netmask)) break; } if (gw) ofono_gprs_context_set_ipv4_gateway(gc, gw); if (netmask) ofono_gprs_context_set_ipv4_netmask(gc, netmask); CALLBACK_WITH_SUCCESS(gcd->cb, gcd->cb_data); }
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); }
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; }
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); }