static void ublox_gprs_context_remove(struct ofono_gprs_context *gc) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); DBG(""); ofono_gprs_context_set_data(gc, NULL); g_at_chat_unref(gcd->chat); memset(gcd, 0, sizeof(*gcd)); g_free(gcd); }
static void at_gprs_deactivate_primary(struct ofono_gprs_context *gc, unsigned int id, ofono_gprs_context_cb_t cb, void *data) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); DBG(""); gcd->state = STATE_DISABLING; gcd->down_cb = cb; gcd->cb_data = data; g_at_ppp_shutdown(gcd->ppp); }
static void ublox_gprs_read_settings(struct ofono_gprs_context *gc, unsigned int cid, ofono_gprs_context_cb_t cb, void *data) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); DBG("cid %u", cid); gcd->active_context = cid; gcd->cb = cb; gcd->cb_data = data; ublox_read_settings(gc); }
static void at_gprs_context_remove(struct ofono_gprs_context *gc) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); DBG(""); if (gcd->state != STATE_IDLE && gcd->ppp) { g_at_ppp_unref(gcd->ppp); g_at_chat_resume(gcd->chat); } ofono_gprs_context_set_data(gc, NULL); g_free(gcd); }
static void ste_cgdcont_cb(gboolean ok, GAtResult *result, gpointer user_data) { struct cb_data *cbd = user_data; ofono_gprs_context_up_cb_t cb = cbd->cb; struct ofono_gprs_context *gc = cbd->user; struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); struct cb_data *ncbd = NULL; char buf[128]; struct conn_info *conn; GSList *l; if (!ok) { struct ofono_error error; gcd->active_context = 0; decode_at_error(&error, g_at_result_final_response(result)); cb(&error, NULL, 0, NULL, NULL, NULL, NULL, cbd->data); return; } ncbd = g_memdup(cbd, sizeof(struct cb_data)); l = g_slist_find_custom(g_caif_devices, GUINT_TO_POINTER(0), conn_compare_by_cid); if (!l) { DBG("at_cgdcont_cb, no more available devices"); goto error; } conn = l->data; conn->cid = gcd->active_context; snprintf(buf, sizeof(buf), "AT*EPPSD=1,%u,%u", conn->channel_id, conn->cid); if (g_at_chat_send(gcd->chat, buf, NULL, ste_eppsd_up_cb, ncbd, g_free) > 0) return; error: if (ncbd) g_free(ncbd); gcd->active_context = 0; CALLBACK_WITH_FAILURE(cb, NULL, 0, NULL, NULL, NULL, NULL, cbd->data); }
static void ublox_gprs_deactivate_primary(struct ofono_gprs_context *gc, unsigned int cid, ofono_gprs_context_cb_t cb, void *data) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); char buf[64]; DBG("cid %u", cid); gcd->cb = cb; gcd->cb_data = data; snprintf(buf, sizeof(buf), "AT+CGACT=0,%u", gcd->active_context); g_at_chat_send(gcd->chat, buf, none_prefix, cgact_disable_cb, gc, NULL); }
static void cgact_disable_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); DBG("ok %d", ok); if (!ok) { CALLBACK_WITH_FAILURE(gcd->cb, gcd->cb_data); return; } gcd->active_context = 0; CALLBACK_WITH_SUCCESS(gcd->cb, gcd->cb_data); }
static void phonesim_activate_primary(struct ofono_gprs_context *gc, const struct ofono_gprs_primary_context *ctx, ofono_gprs_context_cb_t cb, void *data) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); struct cb_data *cbd = cb_data_new(cb, data); char buf[OFONO_GPRS_MAX_APN_LENGTH + 128]; int len = 0; cbd->user = gc; gcd->proto = ctx->proto; switch (ctx->proto) { case OFONO_GPRS_PROTO_IP: len = snprintf(buf, sizeof(buf), "AT+CGDCONT=%u,\"IP\"", ctx->cid); break; case OFONO_GPRS_PROTO_IPV6: len = snprintf(buf, sizeof(buf), "AT+CGDCONT=%u,\"IPV6\"", ctx->cid); break; case OFONO_GPRS_PROTO_IPV4V6: len = snprintf(buf, sizeof(buf), "AT+CGDCONT=%u,\"IPV4V6\"", ctx->cid); break; } if (ctx->apn) snprintf(buf + len, sizeof(buf) - len - 3, ",\"%s\"", ctx->apn); /* Assume always succeeds */ if (g_at_chat_send(gcd->chat, buf, none_prefix, NULL, NULL, NULL) == 0) goto error; sprintf(buf, "AT+CGACT=1,%u", ctx->cid); if (g_at_chat_send(gcd->chat, buf, none_prefix, at_cgact_up_cb, cbd, g_free) > 0) return; error: g_free(cbd); CALLBACK_WITH_FAILURE(cb, data); }
static void mbm_state_changed(struct ofono_gprs_context *gc, int state) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); if (gcd->active_context == 0) return; switch (state) { case MBM_E2NAP_DISCONNECTED: DBG("MBM Context: disconnected"); if (gcd->mbm_state == MBM_DISABLING) { CALLBACK_WITH_SUCCESS(gcd->down_cb, gcd->cb_data); gcd->down_cb = NULL; } else if (gcd->mbm_state == MBM_ENABLING) { CALLBACK_WITH_FAILURE(gcd->up_cb, NULL, 0, NULL, NULL, NULL, NULL, gcd->cb_data); gcd->up_cb = NULL; } else { ofono_gprs_context_deactivated(gc, gcd->active_context); } gcd->mbm_state = MBM_NONE; gcd->cb_data = NULL; gcd->active_context = 0; break; case MBM_E2NAP_CONNECTED: DBG("MBM Context: connected"); if (gcd->mbm_state == MBM_ENABLING) mbm_get_ip_details(gc); break; case MBM_E2NAP_CONNECTING: DBG("MBM Context: connecting"); break; default: break; }; gcd->enap = state; }
static void ril_gprs_context_remove(struct ofono_gprs_context *gc) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); DBG(""); if (gcd->state != STATE_IDLE) ril_gprs_context_detach_shutdown(gc, 0); ofono_gprs_context_set_data(gc, NULL); if (gcd->regid != -1) g_ril_unregister(gcd->ril, gcd->regid); g_ril_unref(gcd->ril); g_free(gcd); }
static void hso_gprs_activate_primary(struct ofono_gprs_context *gc, const struct ofono_gprs_primary_context *ctx, ofono_gprs_context_cb_t cb, void *data) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); struct cb_data *cbd = cb_data_new(cb, data); char buf[AUTH_BUF_LENGTH]; int len; /* IPv6 support not implemented */ if (ctx->proto != OFONO_GPRS_PROTO_IP) goto error; gcd->active_context = ctx->cid; cbd->user = gc; if (ctx->username[0] && ctx->password[0]) snprintf(buf, sizeof(buf), "AT$QCPDPP=%u,1,\"%s\",\"%s\"", ctx->cid, ctx->password, ctx->username); else if (ctx->password[0]) snprintf(buf, sizeof(buf), "AT$QCPDPP=%u,2,,\"%s\"", ctx->cid, ctx->password); else snprintf(buf, sizeof(buf), "AT$QCPDPP=%u,0", ctx->cid); if (g_at_chat_send(gcd->chat, buf, none_prefix, NULL, NULL, NULL) == 0) goto error; len = snprintf(buf, sizeof(buf), "AT+CGDCONT=%u,\"IP\"", ctx->cid); if (ctx->apn) snprintf(buf + len, sizeof(buf) - len - 3, ",\"%s\"", ctx->apn); if (g_at_chat_send(gcd->chat, buf, none_prefix, hso_cgdcont_cb, cbd, g_free) > 0) return; error: g_free(cbd); CALLBACK_WITH_FAILURE(cb, data); }
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]; dns[0] = dns1; dns[1] = dns2; dns[2] = 0; gcd->state = STATE_ACTIVE; CALLBACK_WITH_SUCCESS(gcd->up_cb, interface, TRUE, local, STATIC_IP_NETMASK, NULL, dns, gcd->cb_data); }
static void mbm_gprs_activate_primary(struct ofono_gprs_context *gc, const struct ofono_gprs_primary_context *ctx, ofono_gprs_context_up_cb_t cb, void *data) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); struct cb_data *cbd = cb_data_new(cb, data); char buf[AUTH_BUF_LENGTH]; int len; if (!cbd) goto error; gcd->active_context = ctx->cid; cbd->user = gc; len = snprintf(buf, sizeof(buf), "AT+CGDCONT=%u,\"IP\"", ctx->cid); if (ctx->apn) snprintf(buf + len, sizeof(buf) - len - 3, ",\"%s\"", ctx->apn); if (g_at_chat_send(gcd->chat, buf, none_prefix, mbm_cgdcont_cb, cbd, g_free) == 0) goto error; /* * Set username and password, this should be done after CGDCONT * or an error can occur. We don't bother with error checking * here * */ snprintf(buf, sizeof(buf), "AT*EIAAUW=%d,1,\"%s\",\"%s\"", ctx->cid, ctx->username, ctx->password); g_at_chat_send(gcd->chat, buf, none_prefix, NULL, NULL, NULL); return; error: if (cbd) g_free(cbd); CALLBACK_WITH_FAILURE(cb, NULL, 0, NULL, NULL, NULL, NULL, 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 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); }
static void mbm_enap_poll_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 state; g_at_result_iter_init(&iter, result); if (g_at_result_iter_next(&iter, "*ENAP:") == FALSE) return; g_at_result_iter_next_number(&iter, &state); mbm_state_changed(gc, state); if ((state == MBM_E2NAP_CONNECTED && gcd->mbm_state == MBM_DISABLING) || state == MBM_E2NAP_CONNECTING) gcd->enap_source = g_timeout_add_seconds(1, mbm_enap_poll, gc); }
static void cgact_enable_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); DBG("ok %d", ok); if (!ok) { struct ofono_error error; gcd->active_context = 0; decode_at_error(&error, g_at_result_final_response(result)); gcd->cb(&error, gcd->cb_data); return; } ublox_read_settings(gc); }
static void at_owancall_down_cb(gboolean ok, GAtResult *result, 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; /* Now we have to wait for the unsolicited notification to arrive */ if (ok && gcd->owancall != 0) { gcd->hso_state = HSO_DISABLING; gcd->cb = cb; gcd->cb_data = cbd->data; return; } decode_at_error(&error, g_at_result_final_response(result)); cb(&error, cbd->data); }
static void hso_gprs_deactivate_primary(struct ofono_gprs_context *gc, unsigned int cid, ofono_gprs_context_cb_t cb, void *data) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); struct cb_data *cbd = cb_data_new(cb, data); char buf[128]; cbd->user = gc; snprintf(buf, sizeof(buf), "AT_OWANCALL=%u,0,1", cid); if (g_at_chat_send(gcd->chat, buf, none_prefix, at_owancall_down_cb, cbd, g_free) > 0) return; g_free(cbd); CALLBACK_WITH_FAILURE(cb, data); }
static void phonesim_deactivate_primary(struct ofono_gprs_context *gc, unsigned int id, ofono_gprs_context_cb_t cb, void *data) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); struct cb_data *cbd = cb_data_new(cb, data); char buf[128]; cbd->user = gc; snprintf(buf, sizeof(buf), "AT+CGACT=0,%u", id); if (g_at_chat_send(gcd->chat, buf, none_prefix, at_cgact_down_cb, cbd, g_free) > 0) return; g_free(cbd); CALLBACK_WITH_FAILURE(cb, data); }
static void ste_eppsd_down_cb(gboolean ok, GAtResult *result, 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 conn_info *conn; GSList *l; if (!ok) goto error; l = g_slist_find_custom(g_caif_devices, GUINT_TO_POINTER(gcd->active_context), conn_compare_by_cid); if (!l) { DBG("Did not find data (used caif device) for" "connection with cid; %d", gcd->active_context); goto error; } conn = l->data; if (!caif_if_remove(conn->interface, conn->channel_id)) { DBG("Failed to remove caif interface %s.", conn->interface); } conn->cid = 0; decode_at_error(&error, g_at_result_final_response(result)); cb(&error, cbd->data); return; error: CALLBACK_WITH_FAILURE(cb, cbd->data); }
static void at_owancall_up_cb(gboolean ok, GAtResult *result, 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; if (ok) { gcd->hso_state = HSO_ENABLING; gcd->cb = cb; gcd->cb_data = cbd->data; return; } gcd->active_context = 0; decode_at_error(&error, g_at_result_final_response(result)); cb(&error, cbd->data); }
static void mbm_get_ip_details(struct ofono_gprs_context *gc) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); struct ofono_modem *modem; const char *interface; if (gcd->have_e2ipcfg) { g_at_chat_send(gcd->chat, "AT*E2IPCFG?", e2ipcfg_prefix, mbm_e2ipcfg_cb, gc, NULL); return; } modem = ofono_gprs_context_get_modem(gc); interface = ofono_modem_get_string(modem, "NetworkInterface"); CALLBACK_WITH_SUCCESS(gcd->up_cb, interface, FALSE, NULL, NULL, NULL, NULL, gcd->cb_data); gcd->mbm_state = MBM_NONE; gcd->up_cb = NULL; gcd->cb_data = NULL; }
static void at_cgdata_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); if (!ok) { struct ofono_error error; ofono_info("Unable to enter data state"); gcd->active_context = 0; gcd->state = STATE_IDLE; decode_at_error(&error, g_at_result_final_response(result)); gcd->up_cb(&error, NULL, 0, NULL, NULL, NULL, NULL, gcd->cb_data); return; } setup_ppp(gc); }
static void ste_gprs_deactivate_primary(struct ofono_gprs_context *gc, unsigned int id, ofono_gprs_context_cb_t cb, void *data) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); struct cb_data *cbd = cb_data_new(cb, data); struct conn_info *conn; char buf[64]; GSList *l; if (!cbd) goto error; gcd->active_context = id; cbd->user = gc; l = g_slist_find_custom(g_caif_devices, GUINT_TO_POINTER(id), conn_compare_by_cid); if (!l) { DBG("at_gprs_deactivate_primary, did not find" "data (channel id) for connection with cid; %d", id); goto error; } conn = l->data; snprintf(buf, sizeof(buf), "AT*EPPSD=0,%u,%u", conn->channel_id, id); if (g_at_chat_send(gcd->chat, buf, none_prefix, ste_eppsd_down_cb, cbd, g_free) > 0) return; error: if (cbd) g_free(cbd); CALLBACK_WITH_FAILURE(cb, data); }
static void mbm_gprs_deactivate_primary(struct ofono_gprs_context *gc, unsigned int cid, ofono_gprs_context_cb_t cb, void *data) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); struct cb_data *cbd = cb_data_new(cb, data); if (!cbd) goto error; cbd->user = gc; if (g_at_chat_send(gcd->chat, "AT*ENAP=0", none_prefix, at_enap_down_cb, cbd, g_free) > 0) return; error: if (cbd) g_free(cbd); CALLBACK_WITH_FAILURE(cb, data); }
static void ublox_send_cgdcont(struct ofono_gprs_context *gc, const char *apn, const char *username, const char *password, enum ofono_gprs_auth_method auth_method) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); char buf[OFONO_GPRS_MAX_APN_LENGTH + 128]; size_t u_len, p_len; int len; len = snprintf(buf, sizeof(buf), "AT+CGDCONT=%u,\"IP\"", gcd->active_context); if (apn) snprintf(buf + len, sizeof(buf) - len - 3, ",\"%s\"", apn); if (g_at_chat_send(gcd->chat, buf, none_prefix, cgdcont_cb, gc, NULL) == 0) goto error; u_len = strlen(username); p_len = strlen(password); if (u_len && p_len) { if (u_len >= UBLOX_MAX_USER_LEN || p_len >= UBLOX_MAX_PASS_LEN) { ofono_error("Toby L2: user or password length too big"); goto error; } ublox_send_uauthreq(gc, username, password, auth_method); } return; error: CALLBACK_WITH_FAILURE(gcd->cb, gcd->cb_data); }
static void cgev_notify(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 *event; g_at_result_iter_init(&iter, result); if (!g_at_result_iter_next(&iter, "+CGEV:")) return; if (!g_at_result_iter_next_unquoted_string(&iter, &event)) return; if (g_str_has_prefix(event, "NW REACT ") || g_str_has_prefix(event, "NW DEACT ") || g_str_has_prefix(event, "ME DEACT ")) { /* Ask what primary contexts are active now */ g_at_chat_send(gcd->chat, "AT+CGACT?", cgact_prefix, ste_cgact_read_cb, gc, NULL); } }
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_deactivate_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); gint id = gcd->active_ctx_cid; ofono_info("deactivating data call"); /* Reply has no data... */ if (message->error == RIL_E_SUCCESS) { g_ril_print_response_no_args(gcd->ril, message); set_context_disconnected(gcd); /* If the deactivate was a result of a shutdown, * there won't be call back, so _deactivated() * needs to be called directly. */ if (cb) CALLBACK_WITH_SUCCESS(cb, cbd->data); else ofono_gprs_context_deactivated(gc, id); } else { ofono_error("%s: replay failure: %s", __func__, ril_error_to_string(message->error)); if (cb) CALLBACK_WITH_FAILURE(cb, cbd->data); } }
static void at_enap_down_cb(gboolean ok, GAtResult *result, 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; /* Now we have to wait for the unsolicited notification to arrive */ if (ok && gcd->enap != 0) { gcd->mbm_state = MBM_DISABLING; gcd->down_cb = cb; gcd->cb_data = cbd->data; if (gcd->have_e2nap == FALSE) g_at_chat_send(gcd->chat, "AT*ENAP?", enap_prefix, mbm_enap_poll_cb, gc, NULL); return; } decode_at_error(&error, g_at_result_final_response(result)); cb(&error, cbd->data); }