@@ -151,9 +151,7 @@ static int handle_ss_info(struct qmi_result *result, struct ofono_gprs *gprs)
if (!extract_ss_info(result, &status, &tech))
return -1;
- /* DC is optional so only notify on successful extraction */
- if (extract_dc_info(result, &bearer_tech))
- ofono_gprs_bearer_notify(gprs, bearer_tech);
+ extract_dc_info(result, &bearer_tech);
return status;
}
@@ -174,6 +172,7 @@ static void ss_info_notify(struct qmi_result *result, void *user_data)
static void event_report_notify(struct qmi_result *result, void *user_data)
{
static const uint8_t RESULT_DATA_SYSTEM_STATUS = 0x24;
+ static const uint8_t RESULT_EXTENDED_DATA_BEARER_TECHNOLOGY = 0x2a;
struct ofono_gprs *gprs = user_data;
const void *tlv;
uint16_t len;
@@ -198,6 +197,21 @@ static void event_report_notify(struct qmi_result *result, void *user_data)
return;
}
+ tlv = qmi_result_get(result,
+ RESULT_EXTENDED_DATA_BEARER_TECHNOLOGY, &len);
+ if (tlv) {
+ int r = qmi_wds_parse_extended_data_bearer_technology(tlv, len);
+
+ if (r < 0) {
+ ofono_warn("extended_data_bearer_technology: %s(%d)",
+ strerror(-r), r);
+ return;
+ }
+
+ ofono_gprs_bearer_notify(gprs, r);
+ return;
+ }
+
qmi_result_print_tlvs(result);
}
@@ -75,3 +75,58 @@ int qmi_wds_parse_data_system_status(const void *dss, uint16_t len)
return -ENOENT;
}
+
+int qmi_wds_parse_extended_data_bearer_technology(const void *edbt, uint16_t len)
+{
+ uint32_t technology;
+ uint32_t rat;
+ uint32_t so;
+ int bearer;
+
+ if (len != sizeof(uint32_t) * 2 + sizeof(uint64_t))
+ return -EBADMSG;
+
+ technology = l_get_le32(edbt);
+ rat = l_get_le32(edbt + sizeof(uint32_t));
+ so = l_get_le64(edbt + sizeof(uint32_t) * 2);
+
+ if (technology != QMI_WDS_PROFILE_TYPE_3GPP)
+ return -EINVAL;
+
+ switch (rat) {
+ case QMI_WDS_RAT_WCDMA:
+ bearer = PACKET_BEARER_UMTS;
+ break;
+ case QMI_WDS_RAT_LTE:
+ bearer = PACKET_BEARER_EPS;
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ if (so & (QMI_WDS_SO_LTE_LIMITED | QMI_WDS_SO_LTE_FDD |
+ QMI_WDS_SO_LTE_TDD))
+ return PACKET_BEARER_EPS;
+
+ if (so & (QMI_WDS_SO_HSDPAPLUS | QMI_WDS_SO_DC_HSDPAPLUS |
+ QMI_WDS_SO_64_QAM | QMI_WDS_SO_HSPA))
+ return PACKET_BEARER_HSUPA_HSDPA;
+
+ if (so & (QMI_WDS_SO_HSUPA | QMI_WDS_SO_DC_HSUPA))
+ return PACKET_BEARER_HSUPA;
+
+ if (so & QMI_WDS_SO_HSDPA)
+ return PACKET_BEARER_HSDPA;
+
+ if (so & QMI_WDS_SO_WCDMA)
+ return PACKET_BEARER_UMTS;
+
+ if (so & QMI_WDS_SO_EDGE)
+ return PACKET_BEARER_EGPRS;
+
+ if (so & QMI_WDS_SO_GPRS)
+ return PACKET_BEARER_GPRS;
+
+ /* Fall back to rat */
+ return bearer;
+}
@@ -83,6 +83,43 @@ enum qmi_wds_rat_3gpp {
QMI_WDS_RAT_3GPP_NULL_BEARER = 0x8000,
};
+enum qmi_wds_rat {
+ QMI_WDS_RAT_WCDMA = 0x01,
+ QMI_WDS_RAT_GERAN = 0x02,
+ QMI_WDS_RAT_LTE = 0x03,
+ QMI_WDS_RAT_TDSCDMA = 0x04,
+ QMI_WDS_RAT_WLAN = 0x05,
+};
+
+enum qmi_wds_service_option {
+ QMI_WDS_SO_WCDMA = 0x01ULL,
+ QMI_WDS_SO_HSDPA = 0x02ULL,
+ QMI_WDS_SO_HSUPA = 0x04ULL,
+ QMI_WDS_SO_HSDPAPLUS = 0x08ULL,
+ QMI_WDS_SO_DC_HSDPAPLUS = 0x10ULL,
+ QMI_WDS_SO_64_QAM = 0x20ULL,
+ QMI_WDS_SO_HSPA = 0x40ULL,
+ QMI_WDS_SO_GPRS = 0x80ULL,
+ QMI_WDS_SO_EDGE = 0x100ULL,
+ QMI_WDS_SO_GSM = 0x200ULL,
+ QMI_WDS_SO_S2B = 0x400ULL,
+ QMI_WDS_SO_LTE_LIMITED = 0x800ULL,
+ QMI_WDS_SO_LTE_FDD = 0x1000ULL,
+ QMI_WDS_SO_LTE_TDD = 0x2000ULL,
+ QMI_WDS_SO_TDSCDMA = 0x4000ULL,
+ QMI_WDS_SO_DC_HSUPA = 0x8000ULL,
+ QMI_WDS_SO_LTE_CA_DL = 0x10000ULL,
+ QMI_WDS_SO_LTE_CA_UL = 0x20000ULL,
+ QMI_WDS_SO_S2B_LIMITED = 0x40000ULL,
+ QMI_WDS_SO_FOUR_POINT_FIVE_G = 0x80000ULL,
+ QMI_WDS_SO_FOUR_POINT_FIVE_G_PLUS = 0x100000ULL,
+ QMI_WDS_SO_5G_TDD = 0x10000000000ULL,
+ QMI_WDS_SO_5G_SUB6 = 0x20000000000ULL,
+ QMI_WDS_SO_5G_MMWAVE = 0x40000000000ULL,
+ QMI_WDS_SO_5G_NSA = 0x80000000000ULL,
+ QMI_WDS_SO_5G_SA = 0x100000000000ULL,
+};
+
enum qmi_wds_command {
QMI_WDS_RESET = 0x00,
QMI_WDS_EVENT_REPORT = 0x01,
@@ -128,3 +165,5 @@ int qmi_wds_auth_from_ofono(enum ofono_gprs_auth_method method);
int qmi_wds_pdp_type_from_ofono(enum ofono_gprs_proto proto);
int qmi_wds_parse_data_system_status(const void *dss, uint16_t len);
+int qmi_wds_parse_extended_data_bearer_technology(const void *edbt,
+ uint16_t len);