* [PATCH v2 2/8] qmi: gprs: use Extended Data Bearer Technology
2024-05-06 21:57 [PATCH v2 1/8] qmi: wds: Fix up enum naming Denis Kenzior
@ 2024-05-06 21:57 ` Denis Kenzior
2024-05-06 21:57 ` [PATCH v2 3/8] qmi: netreg: Print network capability Denis Kenzior
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Denis Kenzior @ 2024-05-06 21:57 UTC (permalink / raw)
To: ofono; +Cc: Denis Kenzior
This TLV is reported by WDS "Event Report" indication and contains a
better representation of the current bearer compared to the Data Service
Capability TLV reported in the NAS Serving System indication.
TLV:
type = "Extended Data Bearer Technology" (0x2a)
length = 16
value = 00:00:00:00:03:00:00:00:00:10:00:00:00:00:00:00
translated = [ data_bearer_technology = '3gpp'
radio_access_technology = '3gpp-lte'
extended_data_bearer_technology_3gpp = 'lte-fdd'
...]
TLV:
type = "Data Service Capability" (0x11)
length = 2
value = 01:0B
translated = { [0] = 'lte '}
Some of the 5G and more esoteric technologies are not yet handled in
this commit. Support for these technologies needs to be added in the
core first.
Modify the logic in the gprs driver to use this new mechanism.
---
drivers/qmimodem/gprs.c | 20 ++++++++++++---
drivers/qmimodem/wds.c | 55 +++++++++++++++++++++++++++++++++++++++++
drivers/qmimodem/wds.h | 39 +++++++++++++++++++++++++++++
3 files changed, 111 insertions(+), 3 deletions(-)
diff --git a/drivers/qmimodem/gprs.c b/drivers/qmimodem/gprs.c
index ebb235545e21..e406eba3b19a 100644
--- a/drivers/qmimodem/gprs.c
+++ b/drivers/qmimodem/gprs.c
@@ -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);
}
diff --git a/drivers/qmimodem/wds.c b/drivers/qmimodem/wds.c
index 77e22f443db0..ced0c5e5308d 100644
--- a/drivers/qmimodem/wds.c
+++ b/drivers/qmimodem/wds.c
@@ -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;
+}
diff --git a/drivers/qmimodem/wds.h b/drivers/qmimodem/wds.h
index 218587c3e437..026402e7a3f6 100644
--- a/drivers/qmimodem/wds.h
+++ b/drivers/qmimodem/wds.h
@@ -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);
--
2.45.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 3/8] qmi: netreg: Print network capability
2024-05-06 21:57 [PATCH v2 1/8] qmi: wds: Fix up enum naming Denis Kenzior
2024-05-06 21:57 ` [PATCH v2 2/8] qmi: gprs: use Extended Data Bearer Technology Denis Kenzior
@ 2024-05-06 21:57 ` Denis Kenzior
2024-05-06 21:57 ` [PATCH v2 4/8] qmi: gprs: Remove IP Support Type parsing Denis Kenzior
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Denis Kenzior @ 2024-05-06 21:57 UTC (permalink / raw)
To: ofono; +Cc: Denis Kenzior
Since gprs driver no longer uses DATA_CAPABILITY_STATUS TLV to report
the bearer to the core, move the parsing of this element to
network-registration atom driver. Introduce a new utility to convert
the DATA_CAPABILITY_STATUS TLV to a string list. For now, simply print
the capability when this TLV is received.
While here, eliminate CDMA specific enumerations as they're now
obsolete.
---
drivers/qmimodem/gprs.c | 25 ---------
drivers/qmimodem/nas.c | 74 +++++++++++++++++++++++--
drivers/qmimodem/nas.h | 37 ++++++-------
drivers/qmimodem/network-registration.c | 15 +++++
4 files changed, 99 insertions(+), 52 deletions(-)
diff --git a/drivers/qmimodem/gprs.c b/drivers/qmimodem/gprs.c
index e406eba3b19a..3ee0ce36307c 100644
--- a/drivers/qmimodem/gprs.c
+++ b/drivers/qmimodem/gprs.c
@@ -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;
}
diff --git a/drivers/qmimodem/nas.c b/drivers/qmimodem/nas.c
index 630f901d8eb6..6146958cb869 100644
--- a/drivers/qmimodem/nas.c
+++ b/drivers/qmimodem/nas.c
@@ -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
diff --git a/drivers/qmimodem/nas.h b/drivers/qmimodem/nas.h
index cb0a927bf049..937486282dbc 100644
--- a/drivers/qmimodem/nas.h
+++ b/drivers/qmimodem/nas.h
@@ -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);
diff --git a/drivers/qmimodem/network-registration.c b/drivers/qmimodem/network-registration.c
index 2e2e4a10dbf8..9041199b0b53 100644
--- a/drivers/qmimodem/network-registration.c
+++ b/drivers/qmimodem/network-registration.c
@@ -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;
--
2.45.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 4/8] qmi: gprs: Remove IP Support Type parsing
2024-05-06 21:57 [PATCH v2 1/8] qmi: wds: Fix up enum naming Denis Kenzior
2024-05-06 21:57 ` [PATCH v2 2/8] qmi: gprs: use Extended Data Bearer Technology Denis Kenzior
2024-05-06 21:57 ` [PATCH v2 3/8] qmi: netreg: Print network capability Denis Kenzior
@ 2024-05-06 21:57 ` Denis Kenzior
2024-05-06 21:57 ` [PATCH v2 5/8] qmi: gprs: Remove magic number use Denis Kenzior
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Denis Kenzior @ 2024-05-06 21:57 UTC (permalink / raw)
To: ofono; +Cc: Denis Kenzior
This code was only used to print a message to log. Remove it for now.
The IP type will actually be used by gprs-context driver to determine
whether IPv4, IPv6 or Dual IP family interface should be activated.
---
drivers/qmimodem/gprs.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/qmimodem/gprs.c b/drivers/qmimodem/gprs.c
index 3ee0ce36307c..fce975def9c2 100644
--- a/drivers/qmimodem/gprs.c
+++ b/drivers/qmimodem/gprs.c
@@ -74,7 +74,6 @@ static void get_lte_attach_param_cb(struct qmi_result *result, void *user_data)
struct gprs_data *data = ofono_gprs_get_data(gprs);
char *apn = NULL;
uint16_t error;
- uint8_t iptype;
DBG("");
@@ -90,9 +89,6 @@ static void get_lte_attach_param_cb(struct qmi_result *result, void *user_data)
goto noapn;
}
- if (qmi_result_get_uint8(result, 0x11, &iptype))
- ofono_info("LTE attach IP type: %hhd", iptype);
-
ofono_gprs_cid_activated(gprs, data->default_profile, apn);
l_free(apn);
--
2.45.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 5/8] qmi: gprs: Remove magic number use
2024-05-06 21:57 [PATCH v2 1/8] qmi: wds: Fix up enum naming Denis Kenzior
` (2 preceding siblings ...)
2024-05-06 21:57 ` [PATCH v2 4/8] qmi: gprs: Remove IP Support Type parsing Denis Kenzior
@ 2024-05-06 21:57 ` Denis Kenzior
2024-05-06 21:58 ` [PATCH v2 6/8] qmi: gprs-context: Split out IPv4 setting processing Denis Kenzior
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Denis Kenzior @ 2024-05-06 21:57 UTC (permalink / raw)
To: ofono; +Cc: Denis Kenzior
---
drivers/qmimodem/gprs.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/qmimodem/gprs.c b/drivers/qmimodem/gprs.c
index fce975def9c2..2a0d52317cbb 100644
--- a/drivers/qmimodem/gprs.c
+++ b/drivers/qmimodem/gprs.c
@@ -70,6 +70,7 @@ static bool extract_ss_info(struct qmi_result *result, int *status, int *tech)
static void get_lte_attach_param_cb(struct qmi_result *result, void *user_data)
{
+ static const uint8_t PARAM_APN = 0x10;
struct ofono_gprs *gprs = user_data;
struct gprs_data *data = ofono_gprs_get_data(gprs);
char *apn = NULL;
@@ -83,7 +84,7 @@ static void get_lte_attach_param_cb(struct qmi_result *result, void *user_data)
}
/* APN */
- apn = qmi_result_get_string(result, 0x10);
+ apn = qmi_result_get_string(result, PARAM_APN);
if (!apn) {
DBG("Default profile has no APN setting");
goto noapn;
--
2.45.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 6/8] qmi: gprs-context: Split out IPv4 setting processing
2024-05-06 21:57 [PATCH v2 1/8] qmi: wds: Fix up enum naming Denis Kenzior
` (3 preceding siblings ...)
2024-05-06 21:57 ` [PATCH v2 5/8] qmi: gprs: Remove magic number use Denis Kenzior
@ 2024-05-06 21:58 ` Denis Kenzior
2024-05-06 21:58 ` [PATCH v2 7/8] qmi: gprs-context: Parse IPv6 context settings Denis Kenzior
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Denis Kenzior @ 2024-05-06 21:58 UTC (permalink / raw)
To: ofono; +Cc: Denis Kenzior
Prepare to support IPv6 bearers by moving IPv4 bearer context processing
into its own function. get_settings_ipv4() will be called if the
reported IP Family TLV reports ipv4.
---
drivers/qmimodem/gprs-context.c | 69 ++++++++++++++++++++-------------
1 file changed, 43 insertions(+), 26 deletions(-)
diff --git a/drivers/qmimodem/gprs-context.c b/drivers/qmimodem/gprs-context.c
index 9ac57c893725..99d42e7b5e1f 100644
--- a/drivers/qmimodem/gprs-context.c
+++ b/drivers/qmimodem/gprs-context.c
@@ -78,44 +78,20 @@ static void pkt_status_notify(struct qmi_result *result, void *user_data)
}
}
-static void get_settings_cb(struct qmi_result *result, void *user_data)
+static void get_settings_ipv4(struct ofono_gprs_context *gc,
+ struct qmi_result *result)
{
- static const uint8_t RESULT_PDP_TYPE = 0x11; /* uint8 */
- static const uint8_t RESULT_APN = 0x14; /* string */
static const uint8_t RESULT_PRIMARY_DNS = 0x15;
static const uint8_t RESULT_SECONDARY_DNS = 0x16;
static const uint8_t RESULT_IP_ADDRESS = 0x1e;
static const uint8_t RESULT_GATEWAY = 0x20;
static const uint8_t RESULT_GATEWAY_NETMASK = 0x21;
- static const uint8_t RESULT_IP_FAMILY = 0x2b; /* uint8 */
- struct cb_data *cbd = user_data;
- ofono_gprs_context_cb_t cb = cbd->cb;
- struct ofono_gprs_context *gc = cbd->user;
- uint8_t pdp_type, ip_family;
uint32_t ip_addr;
struct in_addr addr;
char* straddr;
- char* apn;
const char *dns[3] = { NULL, NULL, NULL };
char dns_buf[2][INET_ADDRSTRLEN];
- DBG("");
-
- if (qmi_result_set_error(result, NULL))
- goto done;
-
- apn = qmi_result_get_string(result, RESULT_APN);
- if (apn) {
- DBG("APN: %s", apn);
- l_free(apn);
- }
-
- if (qmi_result_get_uint8(result, RESULT_PDP_TYPE, &pdp_type))
- DBG("PDP type %d", pdp_type);
-
- if (qmi_result_get_uint8(result, RESULT_IP_FAMILY, &ip_family))
- DBG("IP family %d", ip_family);
-
if (qmi_result_get_uint32(result, RESULT_IP_ADDRESS, &ip_addr)) {
addr.s_addr = htonl(ip_addr);
straddr = inet_ntoa(addr);
@@ -151,6 +127,47 @@ static void get_settings_cb(struct qmi_result *result, void *user_data)
if (dns[0])
ofono_gprs_context_set_ipv4_dns_servers(gc, dns);
+}
+
+static void get_settings_cb(struct qmi_result *result, void *user_data)
+{
+ static const uint8_t RESULT_PDP_TYPE = 0x11; /* uint8 */
+ static const uint8_t RESULT_APN = 0x14; /* string */
+ static const uint8_t RESULT_IP_FAMILY = 0x2b; /* uint8 */
+ struct cb_data *cbd = user_data;
+ ofono_gprs_context_cb_t cb = cbd->cb;
+ struct ofono_gprs_context *gc = cbd->user;
+ uint8_t pdp_type, ip_family;
+ char* apn;
+
+ DBG("");
+
+ if (qmi_result_set_error(result, NULL))
+ goto done;
+
+ apn = qmi_result_get_string(result, RESULT_APN);
+ if (apn) {
+ DBG("APN: %s", apn);
+ l_free(apn);
+ }
+
+ if (qmi_result_get_uint8(result, RESULT_PDP_TYPE, &pdp_type))
+ DBG("PDP type %d", pdp_type);
+
+ if (!qmi_result_get_uint8(result, RESULT_IP_FAMILY, &ip_family)) {
+ ofono_error("No IP family in results");
+ goto done;
+ }
+
+ switch (ip_family) {
+ case QMI_WDS_IP_FAMILY_IPV4:
+ get_settings_ipv4(gc, result);
+ break;
+ case QMI_WDS_IP_FAMILY_IPV6:
+ break;
+ default:
+ break;
+ }
done:
CALLBACK_WITH_SUCCESS(cb, cbd->data);
--
2.45.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 7/8] qmi: gprs-context: Parse IPv6 context settings
2024-05-06 21:57 [PATCH v2 1/8] qmi: wds: Fix up enum naming Denis Kenzior
` (4 preceding siblings ...)
2024-05-06 21:58 ` [PATCH v2 6/8] qmi: gprs-context: Split out IPv4 setting processing Denis Kenzior
@ 2024-05-06 21:58 ` Denis Kenzior
2024-05-06 21:58 ` [PATCH v2 8/8] qmi: gprs-context: Obtain initial bearer IP support Denis Kenzior
2024-05-06 23:20 ` [PATCH v2 1/8] qmi: wds: Fix up enum naming patchwork-bot+ofono
7 siblings, 0 replies; 9+ messages in thread
From: Denis Kenzior @ 2024-05-06 21:58 UTC (permalink / raw)
To: ofono; +Cc: Denis Kenzior
Similarly to get_settings_ipv4, add get_settings_ipv6 function which
will parse the relevant TLVs present when GET_SETTINGS response
indicates IPv6 family is in use.
---
drivers/qmimodem/gprs-context.c | 58 +++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/drivers/qmimodem/gprs-context.c b/drivers/qmimodem/gprs-context.c
index 99d42e7b5e1f..21ef1237758e 100644
--- a/drivers/qmimodem/gprs-context.c
+++ b/drivers/qmimodem/gprs-context.c
@@ -78,6 +78,63 @@ static void pkt_status_notify(struct qmi_result *result, void *user_data)
}
}
+static void get_settings_ipv6(struct ofono_gprs_context *gc,
+ struct qmi_result *result)
+{
+ static const uint8_t RESULT_IP_ADDRESS = 0x25;
+ static const uint8_t RESULT_GATEWAY = 0x26;
+ static const uint8_t RESULT_PRIMARY_DNS = 0x27;
+ static const uint8_t RESULT_SECONDARY_DNS = 0x28;
+ static const uint8_t RESULT_MTU = 0x29;
+ const char *dns[3] = { NULL, NULL, NULL };
+ char dns1str[INET6_ADDRSTRLEN];
+ char dns2str[INET6_ADDRSTRLEN];
+ char ipv6str[INET6_ADDRSTRLEN];
+ const void *tlv;
+ uint16_t len;
+ uint32_t mtu;
+
+ tlv = qmi_result_get(result, RESULT_IP_ADDRESS, &len);
+ if (tlv && len == sizeof(struct in6_addr) + 1) {
+ const struct in6_addr *ip = tlv;
+ uint8_t prefix_len = l_get_u8(ip + 1);
+
+ inet_ntop(AF_INET6, ip, ipv6str, sizeof(ipv6str));
+ ofono_gprs_context_set_ipv6_address(gc, ipv6str);
+ ofono_gprs_context_set_ipv6_prefix_length(gc, prefix_len);
+ }
+
+ tlv = qmi_result_get(result, RESULT_GATEWAY, &len);
+ if (tlv && len == sizeof(struct in6_addr) + 1) {
+ const struct in6_addr *gw = tlv;
+
+ inet_ntop(AF_INET6, gw, ipv6str, sizeof(ipv6str));
+ ofono_gprs_context_set_ipv6_gateway(gc, ipv6str);
+ }
+
+ tlv = qmi_result_get(result, RESULT_PRIMARY_DNS, &len);
+ if (tlv && len == sizeof(struct in6_addr)) {
+ const struct in6_addr *dns1 = tlv;
+
+ inet_ntop(AF_INET6, dns1, dns1str, sizeof(dns1str));
+ dns[0] = dns1str;
+ }
+
+ tlv = qmi_result_get(result, RESULT_SECONDARY_DNS, &len);
+ if (tlv && len == sizeof(struct in6_addr)) {
+ const struct in6_addr *dns2 = tlv;
+
+ inet_ntop(AF_INET6, dns2, dns2str, sizeof(dns2str));
+ dns[1] = dns2str;
+ }
+
+ if (dns[0])
+ ofono_gprs_context_set_ipv6_dns_servers(gc, dns);
+
+ if (qmi_result_get_uint32(result, RESULT_MTU, &mtu))
+ DBG("MTU: %u", mtu);
+}
+
static void get_settings_ipv4(struct ofono_gprs_context *gc,
struct qmi_result *result)
{
@@ -164,6 +221,7 @@ static void get_settings_cb(struct qmi_result *result, void *user_data)
get_settings_ipv4(gc, result);
break;
case QMI_WDS_IP_FAMILY_IPV6:
+ get_settings_ipv6(gc, result);
break;
default:
break;
--
2.45.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 8/8] qmi: gprs-context: Obtain initial bearer IP support
2024-05-06 21:57 [PATCH v2 1/8] qmi: wds: Fix up enum naming Denis Kenzior
` (5 preceding siblings ...)
2024-05-06 21:58 ` [PATCH v2 7/8] qmi: gprs-context: Parse IPv6 context settings Denis Kenzior
@ 2024-05-06 21:58 ` Denis Kenzior
2024-05-06 23:20 ` [PATCH v2 1/8] qmi: wds: Fix up enum naming patchwork-bot+ofono
7 siblings, 0 replies; 9+ messages in thread
From: Denis Kenzior @ 2024-05-06 21:58 UTC (permalink / raw)
To: ofono; +Cc: Denis Kenzior
.read_settings is used by the core to setup the network interface for
the initial bearer. This initial bearer is typically an internet
context, but can be something else, depending on the carrier. The
initial bearer might also be configured by the network itself, and can
be IPv4, IPv6 or dual stack. Have the gprs-context driver query the
initial attach parameters to obtain this information, and only then
invoke the WDS Start Network command.
Supporting Dual Stack contexts requires multiple WDS handles to be
allocated, with each handle issuing a Start Network request with a
different IP family preference. This is currently not supported by the
underlying QMUX/QRTR transport. For now, choose invoke Start Network
with IPv4 family preference for IPV4 and Dual Stack contexts, and IPv6
famiily preference for IPv6 contexts.
---
drivers/qmimodem/gprs-context.c | 64 ++++++++++++++++++++++++++++-----
drivers/qmimodem/wds.h | 6 ++++
2 files changed, 61 insertions(+), 9 deletions(-)
diff --git a/drivers/qmimodem/gprs-context.c b/drivers/qmimodem/gprs-context.c
index 21ef1237758e..e04821c3ca6d 100644
--- a/drivers/qmimodem/gprs-context.c
+++ b/drivers/qmimodem/gprs-context.c
@@ -282,6 +282,55 @@ error:
CALLBACK_WITH_FAILURE(cb, cbd->data);
}
+static void get_lte_attach_param_cb(struct qmi_result *result, void *user_data)
+{
+ static const uint8_t RESULT_IP_SUPPORT_TYPE = 0x11;
+ 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 *data = ofono_gprs_context_get_data(gc);
+ uint16_t error;
+ uint8_t iptype;
+ struct qmi_param *param;
+ uint8_t ip_family;
+
+ DBG("");
+
+ if (qmi_result_set_error(result, &error))
+ goto error;
+
+ if (!qmi_result_get_uint8(result, RESULT_IP_SUPPORT_TYPE, &iptype))
+ goto error;
+
+ switch (iptype) {
+ case QMI_WDS_IP_SUPPORT_IPV4:
+ ip_family = QMI_WDS_IP_FAMILY_IPV4;
+ break;
+ case QMI_WDS_IP_SUPPORT_IPV6:
+ ip_family = QMI_WDS_IP_FAMILY_IPV6;
+ break;
+ case QMI_WDS_IP_SUPPORT_IPV4V6:
+ ip_family = QMI_WDS_IP_FAMILY_IPV4;
+ break;
+ default:
+ goto error;
+ }
+
+ param = qmi_param_new_uint8(QMI_WDS_PARAM_IP_FAMILY, ip_family);
+
+ if (qmi_service_send(data->wds, QMI_WDS_START_NETWORK, param,
+ start_net_cb, cbd, cb_data_unref) > 0) {
+ cb_data_ref(cbd);
+ return;
+ }
+
+ qmi_param_free(param);
+
+error:
+ data->active_context = 0;
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+}
+
/*
* This function gets called for "automatic" contexts, those which are
* not activated via activate_primary. For these, we will still need
@@ -299,18 +348,15 @@ static void qmi_gprs_read_settings(struct ofono_gprs_context* gc,
DBG("cid %u", cid);
- data->active_context = cid;
-
- cbd->user = gc;
-
- if (qmi_service_send(data->wds, QMI_WDS_START_NETWORK, NULL,
- start_net_cb, cbd, cb_data_unref) > 0)
+ if (qmi_service_send(data->wds, QMI_WDS_GET_LTE_ATTACH_PARAMETERS,
+ NULL, get_lte_attach_param_cb, cbd,
+ cb_data_unref) > 0) {
+ data->active_context = cid;
+ cbd->user = gc;
return;
-
- data->active_context = 0;
+ }
CALLBACK_WITH_FAILURE(cb, cbd->data);
-
l_free(cbd);
}
diff --git a/drivers/qmimodem/wds.h b/drivers/qmimodem/wds.h
index 026402e7a3f6..a308767177a3 100644
--- a/drivers/qmimodem/wds.h
+++ b/drivers/qmimodem/wds.h
@@ -46,6 +46,12 @@ enum qmi_wds_pdp_type {
QMI_WDS_PDP_TYPE_IPV4V6 = 0x03,
};
+enum qmi_wds_ip_support {
+ QMI_WDS_IP_SUPPORT_IPV4 = 0x00,
+ QMI_WDS_IP_SUPPORT_IPV6 = 0x01,
+ QMI_WDS_IP_SUPPORT_IPV4V6 = 0x02,
+};
+
enum qmi_wds_ip_family {
QMI_WDS_IP_FAMILY_UNKNOWN = 0,
QMI_WDS_IP_FAMILY_IPV4 = 4,
--
2.45.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH v2 1/8] qmi: wds: Fix up enum naming
2024-05-06 21:57 [PATCH v2 1/8] qmi: wds: Fix up enum naming Denis Kenzior
` (6 preceding siblings ...)
2024-05-06 21:58 ` [PATCH v2 8/8] qmi: gprs-context: Obtain initial bearer IP support Denis Kenzior
@ 2024-05-06 23:20 ` patchwork-bot+ofono
7 siblings, 0 replies; 9+ messages in thread
From: patchwork-bot+ofono @ 2024-05-06 23:20 UTC (permalink / raw)
To: Denis Kenzior; +Cc: ofono
Hello:
This series was applied to ofono.git (master)
by Denis Kenzior <denkenz@gmail.com>:
On Mon, 6 May 2024 16:57:55 -0500 you wrote:
> Fixes: e075175baff2 ("qmi: wds: add utility to parse Data System Status tlv")
> ---
> drivers/qmimodem/wds.h | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
Here is the summary with links:
- [v2,1/8] qmi: wds: Fix up enum naming
https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=96ae5482cedf
- [v2,2/8] qmi: gprs: use Extended Data Bearer Technology
https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=f4873f08bed9
- [v2,3/8] qmi: netreg: Print network capability
https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=2c9fec539eba
- [v2,4/8] qmi: gprs: Remove IP Support Type parsing
https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=5d92ffde0dbe
- [v2,5/8] qmi: gprs: Remove magic number use
https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=cbb0a7df113d
- [v2,6/8] qmi: gprs-context: Split out IPv4 setting processing
https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=cfd311c6e584
- [v2,7/8] qmi: gprs-context: Parse IPv6 context settings
https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=2d1e5e573ca8
- [v2,8/8] qmi: gprs-context: Obtain initial bearer IP support
https://git.kernel.org/pub/scm/network/ofono/ofono.git/?id=10e045b86485
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 9+ messages in thread