@@ -68,28 +68,6 @@ static bool extract_ss_info(struct qmi_result *result, int *status, int *tech)
return true;
}
-static bool extract_dc_info(struct qmi_result *result, int *bearer_tech)
-{
- const struct qmi_nas_data_capability *dc;
- uint16_t len;
- int i;
-
- DBG("");
-
- dc = qmi_result_get(result, QMI_NAS_RESULT_DATA_CAPABILITY_STATUS, &len);
- if (!dc)
- return false;
-
- *bearer_tech = -1;
- for (i = 0; i < dc->cap_count; i++) {
- DBG("radio tech in use %d", dc->cap[i]);
-
- *bearer_tech = qmi_nas_cap_to_bearer_tech(dc->cap[i]);
- }
-
- return true;
-}
-
static void get_lte_attach_param_cb(struct qmi_result *result, void *user_data)
{
struct ofono_gprs *gprs = user_data;
@@ -144,15 +122,12 @@ static int handle_ss_info(struct qmi_result *result, struct ofono_gprs *gprs)
{
int status;
int tech;
- int bearer_tech;
DBG("");
if (!extract_ss_info(result, &status, &tech))
return -1;
- extract_dc_info(result, &bearer_tech);
-
return status;
}
@@ -19,6 +19,8 @@
*
*/
+#include <ell/ell.h>
+
#include "nas.h"
#include "src/common.h"
@@ -37,6 +39,70 @@ int qmi_nas_rat_to_tech(uint8_t rat)
return -1;
}
+static const char *qmi_nas_data_capability_to_string(
+ enum qmi_nas_data_capability cap)
+{
+ switch(cap) {
+ case QMI_NAS_DATA_CAPABILITY_NONE:
+ return "none";
+ case QMI_NAS_DATA_CAPABILITY_GPRS:
+ return "gprs";
+ case QMI_NAS_DATA_CAPABILITY_EDGE:
+ return "edge";
+ case QMI_NAS_DATA_CAPABILITY_HSDPA:
+ return "hsdpa";
+ case QMI_NAS_DATA_CAPABILITY_HSUPA:
+ return "hsupa";
+ case QMI_NAS_DATA_CAPABILITY_WCDMA:
+ return "wcdma";
+ case QMI_NAS_DATA_CAPABILITY_GSM:
+ return "gsm";
+ case QMI_NAS_DATA_CAPABILITY_LTE:
+ return "lte";
+ case QMI_NAS_DATA_CAPABILITY_HSDPA_PLUS:
+ return "hsdpa-plus";
+ case QMI_NAS_DATA_CAPABILITY_DC_HSDPA_PLUS:
+ return "dc-hsdpa-plus";
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+char **qmi_nas_data_capability_status_to_string_list(const void *tlv,
+ uint16_t len)
+{
+ uint8_t num;
+ uint8_t cap;
+ uint8_t i;
+ char **ret;
+
+ if (len < 1)
+ return NULL;
+
+ num = l_get_u8(tlv);
+ if (len != num + 1)
+ return NULL;
+
+ ret = l_new(char *, num + 1);
+ tlv += 1;
+
+ for (i = 0; i < num; i++) {
+ const char *v;
+
+ cap = l_get_u8(tlv + i);
+ v = qmi_nas_data_capability_to_string(cap);
+
+ if (v)
+ ret[i] = l_strdup(v);
+ else
+ ret[i] = l_strdup_printf("0x%02x", cap);
+ }
+
+ return ret;
+}
+
int qmi_nas_cap_to_bearer_tech(int cap_tech)
{
@@ -48,16 +114,12 @@ int qmi_nas_cap_to_bearer_tech(int cap_tech)
return PACKET_BEARER_GPRS;
case QMI_NAS_DATA_CAPABILITY_EDGE:
return PACKET_BEARER_EGPRS;
- case QMI_NAS_DATA_CAPABILITY_EVDO_REV_0:
- case QMI_NAS_DATA_CAPABILITY_EVDO_REV_A:
- case QMI_NAS_DATA_CAPABILITY_EVDO_REV_B:
- return PACKET_BEARER_UMTS;
case QMI_NAS_DATA_CAPABILITY_HSDPA:
return PACKET_BEARER_HSDPA;
case QMI_NAS_DATA_CAPABILITY_HSUPA:
return PACKET_BEARER_HSUPA;
- case QMI_NAS_DATA_CAPABILITY_HSDPA_PLUS:
- case QMI_NAS_DATA_CAPABILITY_DC_HSDPA_PLUS:
+ case QMI_NAS_DATA_CAPABILITY_HSDPA_PLUS:
+ case QMI_NAS_DATA_CAPABILITY_DC_HSDPA_PLUS:
/*
* HSPAP is HSPA+; which ofono doesn't define;
* so, if differentiating HSPA and HSPA+ is
@@ -107,27 +107,6 @@ struct qmi_nas_serving_system {
} __attribute__((__packed__));
#define QMI_NAS_RESULT_ROAMING_STATUS 0x10 /* uint8 */
-#define QMI_NAS_RESULT_DATA_CAPABILITY_STATUS 0x11 /* uint8 */
-struct qmi_nas_data_capability {
- uint8_t cap_count;
- uint8_t cap[0];
-} __attribute__((__packed__));
-
-#define QMI_NAS_DATA_CAPABILITY_NONE 0x00
-#define QMI_NAS_DATA_CAPABILITY_GPRS 0x01
-#define QMI_NAS_DATA_CAPABILITY_EDGE 0x02
-#define QMI_NAS_DATA_CAPABILITY_HSDPA 0x03
-#define QMI_NAS_DATA_CAPABILITY_HSUPA 0x04
-#define QMI_NAS_DATA_CAPABILITY_WCDMA 0x05
-#define QMI_NAS_DATA_CAPABILITY_CDMA 0x06
-#define QMI_NAS_DATA_CAPABILITY_EVDO_REV_0 0x07
-#define QMI_NAS_DATA_CAPABILITY_EVDO_REV_A 0x08
-#define QMI_NAS_DATA_CAPABILITY_GSM 0x09
-#define QMI_NAS_DATA_CAPABILITY_EVDO_REV_B 0x0A
-#define QMI_NAS_DATA_CAPABILITY_LTE 0x0B
-#define QMI_NAS_DATA_CAPABILITY_HSDPA_PLUS 0x0C
-#define QMI_NAS_DATA_CAPABILITY_DC_HSDPA_PLUS 0x0D
-
#define QMI_NAS_RESULT_CURRENT_PLMN 0x12
struct qmi_nas_current_plmn {
uint16_t mcc;
@@ -180,6 +159,19 @@ struct qmi_nas_home_network {
#define QMI_NAS_RESULT_SYSTEM_SELECTION_PREF_MODE 0x11
+enum qmi_nas_data_capability {
+ QMI_NAS_DATA_CAPABILITY_NONE = 0x00,
+ QMI_NAS_DATA_CAPABILITY_GPRS = 0x01,
+ QMI_NAS_DATA_CAPABILITY_EDGE = 0x02,
+ QMI_NAS_DATA_CAPABILITY_HSDPA = 0x03,
+ QMI_NAS_DATA_CAPABILITY_HSUPA = 0x04,
+ QMI_NAS_DATA_CAPABILITY_WCDMA = 0x05,
+ QMI_NAS_DATA_CAPABILITY_GSM = 0x09,
+ QMI_NAS_DATA_CAPABILITY_LTE = 0x0B,
+ QMI_NAS_DATA_CAPABILITY_HSDPA_PLUS = 0x0C,
+ QMI_NAS_DATA_CAPABILITY_DC_HSDPA_PLUS = 0x0D,
+};
+
enum qmi_nas_command {
/* Reset NAS service state variables */
QMI_NAS_RESET = 0x00,
@@ -231,4 +223,7 @@ enum qmi_nas_command {
};
int qmi_nas_rat_to_tech(uint8_t rat);
+
+char **qmi_nas_data_capability_status_to_string_list(const void *tlv,
+ uint16_t len);
int qmi_nas_cap_to_bearer_tech(int cap_tech);
@@ -94,11 +94,13 @@ static bool extract_ss_info(struct qmi_result *result, int *status,
enum roaming_status *roaming,
struct ofono_network_operator *operator)
{
+ static const uint8_t RESULT_DATA_CAPABILITY_STATUS = 0x11;
const struct qmi_nas_serving_system *ss;
const struct qmi_nas_current_plmn *plmn;
uint8_t i, roaming_status;
uint16_t value16, len, opname_len;
uint32_t value32;
+ const void *dcs;
DBG("");
@@ -163,6 +165,19 @@ static bool extract_ss_info(struct qmi_result *result, int *status,
DBG("%s (%s:%s)", operator->name, operator->mcc, operator->mnc);
}
+ dcs = qmi_result_get(result, RESULT_DATA_CAPABILITY_STATUS, &len);
+ if (dcs) {
+ _auto_(l_strv_free) char **techs =
+ qmi_nas_data_capability_status_to_string_list(dcs, len);
+
+ if (techs) {
+ _auto_(l_free) char *joined =
+ l_strjoinv(techs, ',');
+
+ DBG("radio techs in use: %s", joined);
+ }
+ }
+
if (qmi_result_get_uint16(result, QMI_NAS_RESULT_LOCATION_AREA_CODE,
&value16))
*lac = value16;