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 cgcontrdp_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 *laddrnetmask = NULL; const char *gw = NULL; const char *dns[3] = { NULL, NULL, NULL }; char buf[64]; DBG("ok %d", ok); if (!ok) { struct ofono_error error; decode_at_error(&error, g_at_result_final_response(result)); gcd->cb(&error, gcd->cb_data); return; } g_at_result_iter_init(&iter, result); while (g_at_result_iter_next(&iter, "+CGCONTRDP:")) { /* skip cid, bearer_id, apn */ g_at_result_iter_skip_next(&iter); g_at_result_iter_skip_next(&iter); g_at_result_iter_skip_next(&iter); if (!g_at_result_iter_next_string(&iter, &laddrnetmask)) break; if (!g_at_result_iter_next_string(&iter, &gw)) break; if (!g_at_result_iter_next_string(&iter, &dns[0])) break; if (!g_at_result_iter_next_string(&iter, &dns[1])) break; } set_gprs_context_interface(gc); if (!laddrnetmask || set_address_and_netmask(gc, laddrnetmask) < 0) { CALLBACK_WITH_FAILURE(gcd->cb, gcd->cb_data); return; } if (gw) ofono_gprs_context_set_ipv4_gateway(gc, gw); if (dns[0]) ofono_gprs_context_set_ipv4_dns_servers(gc, dns); /* * Some older versions of Toby L2 need to issue AT+UIPADDR to get the * the correct gateway and netmask. The newer version will return an * empty ok reply. */ snprintf(buf, sizeof(buf), "AT+UIPADDR=%u", gcd->active_context); if (g_at_chat_send(gcd->chat, buf, uipaddr_prefix, uipaddr_cb, gc, NULL) > 0) return; /* Even if UIPADDR failed, we still have enough data. */ CALLBACK_WITH_SUCCESS(gcd->cb, gcd->cb_data); }
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); }