static void cgreg_notify(GAtResult *result, gpointer user_data) { struct ofono_gprs *gprs = user_data; int status; struct gprs_data *gd = ofono_gprs_get_data(gprs); if (at_util_parse_reg_unsolicited(result, "+CGREG:", &status, NULL, NULL, NULL, gd->vendor) == FALSE) return; /* * Telit AT modem firmware (tested with UE910-EUR) generates * +CGREG: 0\r\n\r\n+CGEV: NW DETACH * after a context is de-activated and ppp connection closed. * Then, after a random amount of time (observed from a few seconds * to a few hours), an unsolicited +CGREG: 1 arrives. * Attempt to fix the problem, by sending AT+CGATT=1 once. * This does not re-activate the context, but if a network connection * is still correct, will generate an immediate +CGREG: 1. */ if (gd->vendor == OFONO_VENDOR_TELIT) { if (gd->attached && !status && !gd->telit_try_reattach) { DBG("Trying to re-attach gprs network"); gd->telit_try_reattach = TRUE; g_at_chat_send(gd->chat, "AT+CGATT=1", none_prefix, NULL, NULL, NULL); return; } gd->telit_try_reattach = FALSE; } ofono_gprs_status_notify(gprs, status); }
static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data) { struct cb_data *cbd = user_data; ofono_gprs_status_cb_t cb = cbd->cb; struct ofono_gprs *gprs = cbd->user; struct gprs_data *gd = ofono_gprs_get_data(gprs); struct ofono_error error; int status, lac, ci, tech; int max_cids = 1; if (message->error == RIL_E_SUCCESS) { decode_ril_error(&error, "OK"); } else { ofono_error("ril_data_reg_cb: reply failure: %s", ril_error_to_string(message->error)); decode_ril_error(&error, "FAIL"); error.error = message->error; status = -1; goto error; } if (ril_util_parse_reg(message, &status, &lac, &ci, &tech, &max_cids) == FALSE) { ofono_error("Failure parsing data registration response."); decode_ril_error(&error, "FAIL"); status = -1; goto error; } if (gd->status == -1) { DBG("calling ofono_gprs_register..."); ofono_gprs_register(gprs); g_ril_register(gd->ril, RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, ril_gprs_state_change, gprs); } if (max_cids > gd->max_cids) { DBG("Setting max cids to %d", max_cids); gd->max_cids = max_cids; ofono_gprs_set_cid_range(gprs, 1, max_cids); } if (gd->status != status) { DBG("gd->status: %d status: %d", gd->status, status); ofono_gprs_status_notify(gprs, status); } gd->status = status; gd->tech = tech; error: if (cb) cb(&error, status, cbd->data); }
static void cgreg_notify(GAtResult *result, gpointer user_data) { struct ofono_gprs *gprs = user_data; int status; struct gprs_data *gd = ofono_gprs_get_data(gprs); if (at_util_parse_reg_unsolicited(result, "+CGREG:", &status, NULL, NULL, NULL, gd->vendor) == FALSE) return; ofono_gprs_status_notify(gprs, status); }
static gboolean ril_fake_response(gpointer user_data) { struct cb_data *cbd = user_data; struct ofono_gprs *gprs = cbd->user; struct gprs_data *gd = ofono_gprs_get_data(gprs); DBG(""); gd->fake_timer_id = 0; ofono_gprs_status_notify(gprs, gd->true_status); g_free(cbd); /* == gd->fake_cbd */ gd->fake_cbd = NULL; return FALSE; }
static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data) { struct cb_data *cbd = user_data; ofono_gprs_status_cb_t cb = cbd->cb; struct ofono_gprs *gprs = cbd->user; struct ril_gprs_data *gd = ofono_gprs_get_data(gprs); struct reply_data_reg_state *reply; gboolean attached = FALSE; gboolean notify_status = FALSE; int old_status; old_status = gd->rild_status; if (message->error == RIL_E_SUCCESS) { reply = g_ril_reply_parse_data_reg_state(gd->ril, message); if (reply == NULL) { if (cb) CALLBACK_WITH_FAILURE(cb, -1, cbd->data); return; } } else { /* * If we get a RIL error (say, radio not available) it is better * to return unknown values than to call cb with failure status. * If we do the last, ConnectionManager would not be created if * this is the first time we retrieve data status, or we can * even create infinite loops as the status in gprs atom would * not be refreshed. When we finally register we will get events * so we will try to retrieve data state again. */ ofono_error("%s: DATA_REGISTRATION_STATE reply failure: %s", __func__, ril_error_to_string(message->error)); reply = g_malloc0(sizeof(*reply)); reply->reg_state.status = NETWORK_REGISTRATION_STATUS_UNKNOWN; reply->reg_state.tech = RADIO_TECH_UNKNOWN; } /* * There are three cases that can result in this callback * running: * * 1) The driver's probe() method was called, and thus an * internal call to ril_gprs_registration_status() is * generated. No ofono cb exists. * * 2) ril_gprs_state_change() is called due to an unsolicited * event from RILD. No ofono cb exists. * * 3) The ofono code code calls the driver's attached_status() * function. A valid ofono cb exists. */ if (gd->rild_status != reply->reg_state.status) { gd->rild_status = reply->reg_state.status; if (cb == NULL) notify_status = TRUE; } /* * Override the actual status based upon the desired * attached status set by the core GPRS code ( controlled * by the ConnnectionManager's 'Powered' property ). */ attached = (reply->reg_state.status == NETWORK_REGISTRATION_STATUS_REGISTERED || reply->reg_state.status == NETWORK_REGISTRATION_STATUS_ROAMING); if (attached && gd->ofono_attached == FALSE) { DBG("attached=true; ofono_attached=false; return !REGISTERED"); reply->reg_state.status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED; /* * Further optimization so that if ril_status == * NOT_REGISTERED, ofono_attached == false, and status == * ROAMING | REGISTERED, then notify gets cleared... * * As is, this results in unecessary status notify calls * when nothing has changed. */ if (notify_status && reply->reg_state.status == old_status) notify_status = FALSE; } if (old_status == -1) { ofono_gprs_register(gprs); /* Different rild implementations use different events here */ g_ril_register(gd->ril, gd->state_changed_unsol, ril_gprs_state_change, gprs); if (reply->max_cids == 0) gd->max_cids = RIL_MAX_NUM_ACTIVE_DATA_CALLS; else if (reply->max_cids < RIL_MAX_NUM_ACTIVE_DATA_CALLS) gd->max_cids = reply->max_cids; else gd->max_cids = RIL_MAX_NUM_ACTIVE_DATA_CALLS; DBG("Setting max cids to %d", gd->max_cids); ofono_gprs_set_cid_range(gprs, 1, gd->max_cids); /* * This callback is a result of the inital call * to probe(), so should return after registration. */ g_free(reply); return; } /* Just need to notify ofono if it's already attached */ if (notify_status) { /* * If network disconnect has occurred, call detached_notify() * instead of status_notify(). */ if (!attached && (old_status == NETWORK_REGISTRATION_STATUS_REGISTERED || old_status == NETWORK_REGISTRATION_STATUS_ROAMING)) { DBG("calling ofono_gprs_detached_notify()"); ofono_gprs_detached_notify(gprs); reply->reg_state.tech = RADIO_TECH_UNKNOWN; } else { DBG("calling ofono_gprs_status_notify()"); ofono_gprs_status_notify(gprs, reply->reg_state.status); } } gd->tech = reply->reg_state.tech; ofono_gprs_bearer_notify(gprs, ril_tech_to_bearer_tech(reply->reg_state.tech)); if (cb) CALLBACK_WITH_SUCCESS(cb, reply->reg_state.status, cbd->data); g_free(reply); }
static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data) { struct cb_data *cbd = user_data; ofono_gprs_status_cb_t cb = cbd->cb; struct ofono_gprs *gprs = cbd->user; struct ril_gprs_data *gd = ofono_gprs_get_data(gprs); struct reply_data_reg_state *reply; gboolean attached = FALSE; gboolean notify_status = FALSE; int old_status; old_status = gd->rild_status; if (message->error != RIL_E_SUCCESS) { ofono_error("%s: DATA_REGISTRATION_STATE reply failure: %s", __func__, ril_error_to_string(message->error)); goto error; } if ((reply = g_ril_reply_parse_data_reg_state(gd->ril, message)) == NULL) goto error; /* * There are three cases that can result in this callback * running: * * 1) The driver's probe() method was called, and thus an * internal call to ril_gprs_registration_status() is * generated. No ofono cb exists. * * 2) ril_gprs_state_change() is called due to an unsolicited * event from RILD. No ofono cb exists. * * 3) The ofono code code calls the driver's attached_status() * function. A valid ofono cb exists. */ if (gd->rild_status != reply->reg_state.status) { gd->rild_status = reply->reg_state.status; if (cb == NULL) notify_status = TRUE; } /* * Override the actual status based upon the desired * attached status set by the core GPRS code ( controlled * by the ConnnectionManager's 'Powered' property ). */ attached = (reply->reg_state.status == NETWORK_REGISTRATION_STATUS_REGISTERED || reply->reg_state.status == NETWORK_REGISTRATION_STATUS_ROAMING); if (attached && gd->ofono_attached == FALSE) { DBG("attached=true; ofono_attached=false; return !REGISTERED"); reply->reg_state.status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED; /* * Further optimization so that if ril_status == * NOT_REGISTERED, ofono_attached == false, and status == * ROAMING | REGISTERED, then notify gets cleared... * * As is, this results in unecessary status notify calls * when nothing has changed. */ if (notify_status && reply->reg_state.status == old_status) notify_status = FALSE; } if (old_status == -1) { ofono_gprs_register(gprs); /* Different rild implementations use different events here */ g_ril_register(gd->ril, gd->state_changed_unsol, ril_gprs_state_change, gprs); if (reply->max_cids == 0) gd->max_cids = RIL_MAX_NUM_ACTIVE_DATA_CALLS; else if (reply->max_cids < RIL_MAX_NUM_ACTIVE_DATA_CALLS) gd->max_cids = reply->max_cids; else gd->max_cids = RIL_MAX_NUM_ACTIVE_DATA_CALLS; DBG("Setting max cids to %d", gd->max_cids); ofono_gprs_set_cid_range(gprs, 1, gd->max_cids); /* * This callback is a result of the inital call * to probe(), so should return after registration. */ g_free(reply); return; } /* Just need to notify ofono if it's already attached */ if (notify_status) { /* * If network disconnect has occurred, call detached_notify() * instead of status_notify(). */ if (!attached && (old_status == NETWORK_REGISTRATION_STATUS_REGISTERED || old_status == NETWORK_REGISTRATION_STATUS_ROAMING)) { DBG("calling ofono_gprs_detached_notify()"); ofono_gprs_detached_notify(gprs); reply->reg_state.tech = RADIO_TECH_UNKNOWN; } else { DBG("calling ofono_gprs_status_notify()"); ofono_gprs_status_notify(gprs, reply->reg_state.status); } } if (gd->tech != reply->reg_state.tech) { gd->tech = reply->reg_state.tech; ofono_gprs_bearer_notify(gprs, ril_tech_to_bearer_tech(reply->reg_state.tech)); } if (cb) CALLBACK_WITH_SUCCESS(cb, reply->reg_state.status, cbd->data); g_free(reply); return; error: /* * For some modems DATA_REGISTRATION_STATE will return an error until we * are registered in the voice network. */ if (old_status == -1 && message->error == RIL_E_GENERIC_FAILURE) gd->status_retry_cb_id = g_timeout_add(GET_STATUS_TIMER_MS, ril_get_status_retry, gprs); if (cb) CALLBACK_WITH_FAILURE(cb, -1, cbd->data); }
static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data) { struct cb_data *cbd = user_data; ofono_gprs_status_cb_t cb = cbd->cb; struct ofono_gprs *gprs = cbd->user; struct gprs_data *gd = ofono_gprs_get_data(gprs); struct ofono_error error; gboolean attached; int status, lac, ci, tech; int max_cids = 1; if (message->error == RIL_E_SUCCESS) { decode_ril_error(&error, "OK"); } else { ofono_error("ril_data_reg_cb: reply failure: %s", ril_error_to_string(message->error)); decode_ril_error(&error, "FAIL"); error.error = message->error; status = -1; goto error; } if (ril_util_parse_reg(gd->ril, message, &status, &lac, &ci, &tech, &max_cids) == FALSE) { ofono_error("Failure parsing data registration response."); decode_ril_error(&error, "FAIL"); status = -1; goto error; } if (gd->rild_status == -1) { ofono_gprs_register(gprs); /* RILD tracks data network state together with voice */ g_ril_register(gd->ril, RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, ril_gprs_state_change, gprs); } if (max_cids > gd->max_cids) { DBG("Setting max cids to %d", max_cids); gd->max_cids = max_cids; ofono_gprs_set_cid_range(gprs, 1, max_cids); } /* We need to notify core always to cover situations when * connection drops temporarily for example when user is * taking CS voice call from LTE or changing technology * preference */ if (gd->rild_status != status) ofono_gprs_status_notify(gprs, status); gd->rild_status = status; /* * Override the actual status based upon the desired * attached status set by the core GPRS code ( controlled * by the ConnnectionManager's 'Powered' property ). */ attached = (status == NETWORK_REGISTRATION_STATUS_REGISTERED || status == NETWORK_REGISTRATION_STATUS_ROAMING); if (attached && gd->ofono_attached == FALSE) { DBG("attached=true; ofono_attached=false; return !REGISTERED"); status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED; } error: if (cb) cb(&error, status, cbd->data); }
static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data) { struct cb_data *cbd = user_data; ofono_gprs_status_cb_t cb = cbd->cb; struct ofono_gprs *gprs = cbd->user; struct gprs_data *gd = ofono_gprs_get_data(gprs); struct ofono_error error; int status, lac, ci, tech; int max_cids = 1; DBG(""); if (gd && message->error == RIL_E_SUCCESS) { decode_ril_error(&error, "OK"); } else { ofono_error("ril_data_reg_cb: reply failure: %s", ril_error_to_string(message->error)); decode_ril_error(&error, "FAIL"); error.error = message->error; status = -1; goto error; } if (ril_util_parse_reg(gd->ril, message, &status, &lac, &ci, &tech, &max_cids) == FALSE) { ofono_error("Failure parsing data registration response."); decode_ril_error(&error, "FAIL"); status = -1; goto error; } if ((gd->fake_timer_id > 0) && ((status == NETWORK_REGISTRATION_STATUS_REGISTERED || status == NETWORK_REGISTRATION_STATUS_ROAMING) || !gd->ofono_attached)) { remove_fake_timer(gd); gd->true_status = -1; } if (status > 10) status = status - 10; if (!registered) { ofono_gprs_register(gprs); registered = TRUE; } if (max_cids > gd->max_cids) { DBG("Setting max cids to %d", max_cids); gd->max_cids = max_cids; ofono_gprs_set_cid_range(gprs, 1, max_cids); } ofono_info("data registration status is %d", status); if (status == NETWORK_REGISTRATION_STATUS_ROAMING) status = check_if_really_roaming(status); DBG(" attached:%d, status:%d", gd->ofono_attached, status); if (!gd->ofono_attached) { if (status == NETWORK_REGISTRATION_STATUS_ROAMING) { if (!gd->notified && cb) { if (ril_roaming_allowed() == FALSE) ofono_gprs_detached_notify(gprs); /* * This prevents core ending * into eternal loop with driver */ decode_ril_error(&error, "FAIL"); ofono_gprs_status_notify(gprs, status); } } else { if (status == NETWORK_REGISTRATION_STATUS_SEARCHING && !gd->notified && cb) /* * This is a hack that prevents core ending * into eternal loop with driver */ decode_ril_error(&error, "FAIL"); ofono_gprs_status_notify(gprs, status); } if (cb) gd->notified = TRUE; gd->rild_status = status; goto error; } if (status == NETWORK_REGISTRATION_STATUS_ROAMING || status == NETWORK_REGISTRATION_STATUS_REGISTERED) { ofono_gprs_status_notify(gprs, status); gd->rild_status = status; } else { if (gd->fake_timer_id <= 0) { gd->fake_cbd = cb_data_new(NULL, NULL); gd->fake_cbd->user = gprs; DBG("Start rilmodem fake status timer"); gd->fake_timer_id = g_timeout_add_seconds( FAKE_STATE_TIMER, ril_fake_response, gd->fake_cbd); } gd->true_status = status; if (gd->rild_status == NETWORK_REGISTRATION_STATUS_ROAMING) status = NETWORK_REGISTRATION_STATUS_ROAMING; else status = NETWORK_REGISTRATION_STATUS_REGISTERED; gd->rild_status = status; } error: ofono_info("data registration status is %d", status); if (cb) cb(&error, status, cbd->data); }