gboolean g_ril_request_deactivate_data_call(GRil *gril, const struct req_deactivate_data_call *req, struct parcel *rilp, struct ofono_error *error) { gchar *cid_str = NULL; gchar *reason_str = NULL; if (req->reason != RIL_DEACTIVATE_DATA_CALL_NO_REASON && req->reason != RIL_DEACTIVATE_DATA_CALL_RADIO_SHUTDOWN) { goto error; } parcel_init(rilp); parcel_w_int32(rilp, DEACTIVATE_DATA_CALL_NUM_PARAMS); cid_str = g_strdup_printf("%d", req->cid); parcel_w_string(rilp, cid_str); /* * TODO: airplane-mode; change reason to '1', * which means "radio power off". */ reason_str = g_strdup_printf("%d", req->reason); parcel_w_string(rilp, reason_str); g_ril_append_print_buf(gril, "(%s,%s)", cid_str, reason_str); g_free(cid_str); g_free(reason_str); OFONO_NO_ERROR(error); return TRUE; error: OFONO_EINVAL(error); return FALSE; }
gboolean g_ril_request_setup_data_call(GRil *gril, const struct req_setup_data_call *req, struct parcel *rilp, struct ofono_error *error) { const gchar *protocol_str; gchar *tech_str; gchar *auth_str; gchar *profile_str; size_t apn_len; DBG(""); if (req->tech < RADIO_TECH_GPRS || req->tech > RADIO_TECH_GSM) { ofono_error("%s: Invalid tech value: %d", __func__, req->tech); goto error; } /* * TODO(OEM): This code doesn't currently support * OEM data profiles. If a use case exist, then * this code will need to be modified. */ switch (req->data_profile) { case RIL_DATA_PROFILE_DEFAULT: profile_str = DATA_PROFILE_DEFAULT_STR; break; case RIL_DATA_PROFILE_TETHERED: profile_str = DATA_PROFILE_TETHERED_STR; break; case RIL_DATA_PROFILE_IMS: profile_str = DATA_PROFILE_IMS_STR; break; case RIL_DATA_PROFILE_FOTA: profile_str = DATA_PROFILE_FOTA_STR; break; case RIL_DATA_PROFILE_CBS: profile_str = DATA_PROFILE_CBS_STR; break; default: ofono_error("%s, invalid data_profile value: %d", __func__, req->data_profile); goto error; } if (req->apn == NULL) goto error; apn_len = strlen(req->apn); if (apn_len == 0 || apn_len > 100) { ofono_error("%s: invalid apn length: %d", __func__, (int) apn_len); goto error; } if (req->auth_type > RIL_AUTH_BOTH) { ofono_error("%s: Invalid auth type: %d", __func__, req->auth_type); goto error; } protocol_str = ril_ofono_protocol_to_ril_string(req->protocol); if (protocol_str == NULL) { ofono_error("%s: Invalid protocol: %d", __func__, req->protocol); goto error; } parcel_init(rilp); parcel_w_int32(rilp, SETUP_DATA_CALL_PARAMS); tech_str = g_strdup_printf("%d", req->tech); parcel_w_string(rilp, (char *) tech_str); parcel_w_string(rilp, (char *) profile_str); parcel_w_string(rilp, (char *) req->apn); parcel_w_string(rilp, (char *) req->username); parcel_w_string(rilp, (char *) req->password); auth_str = g_strdup_printf("%d", req->auth_type); parcel_w_string(rilp, (char *) auth_str); parcel_w_string(rilp, (char *) protocol_str); g_ril_append_print_buf(gril, "(%s,%s,%s,%s,%s,%s,%s)", tech_str, profile_str, req->apn, req->username, req->password, auth_str, protocol_str); g_free(tech_str); g_free(auth_str); OFONO_NO_ERROR(error); return TRUE; error: OFONO_EINVAL(error); return FALSE; }
struct reply_setup_data_call *g_ril_reply_parse_data_call(GRil *gril, struct ril_msg *message, struct ofono_error *error) { struct parcel rilp; int num = 0; int protocol; char *type = NULL, *raw_ip_addrs = NULL; char *dnses = NULL, *raw_gws = NULL; struct reply_setup_data_call *reply = g_new0(struct reply_setup_data_call, 1); OFONO_NO_ERROR(error); reply->cid = -1; /* TODO: * Cleanup duplicate code between this function and * ril_util_parse_data_call_list(). */ /* valid size: 36 (34 if HCRADIO defined) */ if (message->buf_len < MIN_DATA_CALL_REPLY_SIZE) { /* TODO: make a macro for error logging */ ofono_error("%s: reply too small: %d", __func__, (int) message->buf_len); OFONO_EINVAL(error); goto error; } g_ril_init_parcel(message, &rilp); /* * ril.h documents the reply to a RIL_REQUEST_SETUP_DATA_CALL * as being a RIL_Data_Call_Response_v6 struct, however in * reality, the response actually includes the version of the * struct, followed by an array of calls, so the array size * also has to be read after the version. * * TODO: What if there's more than 1 call in the list?? */ /* * TODO: consider using 'unused' variable; however if we * do this, the alternative is a few more append_print_buf * calls ( which become no-ops if tracing isn't enabled. */ reply->version = parcel_r_int32(&rilp); num = parcel_r_int32(&rilp); if (num != 1) { ofono_error("%s: too many calls: %d", __func__, num); OFONO_EINVAL(error); goto error; } reply->status = parcel_r_int32(&rilp); reply->retry_time = parcel_r_int32(&rilp); reply->cid = parcel_r_int32(&rilp); reply->active = parcel_r_int32(&rilp); type = parcel_r_string(&rilp); reply->ifname = parcel_r_string(&rilp); raw_ip_addrs = parcel_r_string(&rilp); dnses = parcel_r_string(&rilp); raw_gws = parcel_r_string(&rilp); g_ril_append_print_buf(gril, "{version=%d,num=%d [status=%d,retry=%d," "cid=%d,active=%d,type=%s,ifname=%s,address=%s" ",dns=%s,gateways=%s]}", reply->version, num, reply->status, reply->retry_time, reply->cid, reply->active, type, reply->ifname, raw_ip_addrs, dnses, raw_gws); g_ril_print_response(gril, message); protocol = ril_protocol_string_to_ofono_protocol(type); if (protocol < 0) { ofono_error("%s: Invalid type(protocol) specified: %s", __func__, type); OFONO_EINVAL(error); goto error; } reply->protocol = (guint) protocol; if (reply->ifname == NULL || strlen(reply->ifname) == 0) { ofono_error("%s: No interface specified: %s", __func__, reply->ifname); OFONO_EINVAL(error); goto error; } /* 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. * * For now split into a maximum of three, and only use * the first address for the remaining operations. */ if (raw_ip_addrs) reply->ip_addrs = g_strsplit(raw_ip_addrs, " ", 3); else reply->ip_addrs = NULL; /* TODO: I'm not sure it's possible to specify a zero-length * in a parcel in a parcel. If *not*, then this can be * simplified. */ if (reply->ip_addrs == NULL || (sizeof(reply->ip_addrs) == 0)) { ofono_error("%s no IP address: %s", __func__, raw_ip_addrs); OFONO_EINVAL(error); goto error; } /* * RILD can return multiple addresses; oFono only supports * setting a single IPv4 gateway. */ if (raw_gws) reply->gateways = g_strsplit(raw_gws, " ", 3); else reply->gateways = NULL; if (reply->gateways == NULL || (sizeof(reply->gateways) == 0)) { ofono_error("%s: no gateways: %s", __func__, raw_gws); OFONO_EINVAL(error); goto error; } /* Split DNS addresses */ if (dnses) reply->dns_addresses = g_strsplit(dnses, " ", 3); else reply->dns_addresses = NULL; if (reply->dns_addresses == NULL || (sizeof(reply->dns_addresses) == 0)) { ofono_error("%s: no DNS: %s", __func__, dnses); OFONO_EINVAL(error); goto error; } error: g_free(type); g_free(raw_ip_addrs); g_free(dnses); g_free(raw_gws); return reply; }
gboolean g_ril_request_setup_data_call(GRil *gril, const struct req_setup_data_call *req, struct parcel *rilp, struct ofono_error *error) { const gchar *protocol_str; gchar *tech_str; gchar *auth_str; gchar *profile_str; int num_param = SETUP_DATA_CALL_PARAMS; DBG(""); if (g_ril_vendor(gril) == OFONO_RIL_VENDOR_MTK) num_param = SETUP_DATA_CALL_PARAMS + 1; /* * Radio technology to use: 0-CDMA, 1-GSM/UMTS, 2... * values > 2 are (RADIO_TECH + 2) */ if (req->tech < 1 || req->tech > (RADIO_TECH_GSM + 2)) { ofono_error("%s: Invalid tech value: %d", __func__, req->tech); goto error; } /* * TODO(OEM): This code doesn't currently support * OEM data profiles. If a use case exist, then * this code will need to be modified. */ switch (req->data_profile) { case RIL_DATA_PROFILE_DEFAULT: profile_str = DATA_PROFILE_DEFAULT_STR; break; case RIL_DATA_PROFILE_TETHERED: profile_str = DATA_PROFILE_TETHERED_STR; break; case RIL_DATA_PROFILE_IMS: profile_str = DATA_PROFILE_IMS_STR; break; case RIL_DATA_PROFILE_FOTA: profile_str = DATA_PROFILE_FOTA_STR; break; case RIL_DATA_PROFILE_CBS: profile_str = DATA_PROFILE_CBS_STR; break; case RIL_DATA_PROFILE_MTK_MMS: if (g_ril_vendor(gril) == OFONO_RIL_VENDOR_MTK) { profile_str = DATA_PROFILE_MTK_MMS_STR; break; } default: ofono_error("%s, invalid data_profile value: %d", __func__, req->data_profile); goto error; } if (req->apn == NULL) goto error; if (req->auth_type > RIL_AUTH_BOTH) { ofono_error("%s: Invalid auth type: %d", __func__, req->auth_type); goto error; } protocol_str = ril_ofono_protocol_to_ril_string(req->protocol); if (protocol_str == NULL) { ofono_error("%s: Invalid protocol: %d", __func__, req->protocol); goto error; } parcel_init(rilp); parcel_w_int32(rilp, num_param); tech_str = g_strdup_printf("%d", req->tech); parcel_w_string(rilp, tech_str); parcel_w_string(rilp, profile_str); parcel_w_string(rilp, req->apn); parcel_w_string(rilp, req->username); parcel_w_string(rilp, req->password); auth_str = g_strdup_printf("%d", req->auth_type); parcel_w_string(rilp, auth_str); parcel_w_string(rilp, protocol_str); g_ril_append_print_buf(gril, "(%s,%s,%s,%s,%s,%s,%s", tech_str, profile_str, req->apn, req->username, req->password, auth_str, protocol_str); if (g_ril_vendor(gril) == OFONO_RIL_VENDOR_MTK) { /* MTK request_cid parameter */ char cid_str[MAX_CID_DIGITS + 1]; snprintf(cid_str, sizeof(cid_str), "%u", req->req_cid); parcel_w_string(rilp, cid_str); g_ril_append_print_buf(gril, "%s,%s", print_buf, cid_str); } g_ril_append_print_buf(gril, "%s)", print_buf); g_free(tech_str); g_free(auth_str); OFONO_NO_ERROR(error); return TRUE; error: OFONO_EINVAL(error); return FALSE; }