fixeria has submitted this change. ( 
https://gerrit.osmocom.org/c/osmo-hlr/+/33528 )

Change subject: USSD: fix handling of ussd-DataCodingScheme != 0x0f
......................................................................

USSD: fix handling of ussd-DataCodingScheme != 0x0f

The usual Data Coding Scheme value in the mobile-originated USSD
request (processUnstructuredSS-Request) is 0x0f, which means:

  0000 .... = Coding Group: Coding Group 0 (Language using the GSM 7 bit 
default alphabet)
  .... 1111 = Language: unspecified

However some modems are known to use a different default value, if
not specified explicitly (AT+CUSD has optional DCS parameter):

  0000 .... = Coding Group: Coding Group 0 (Language using the GSM 7 bit 
default alphabet)
  .... 0000 = Language: German (0)

In function rx_proc_ss_req(), we should not be using req.ussd_text,
because this field has been deprecated and may contain unexpected
data.  For example, in the abovementioned case it would contain the
7 bit encoded ussd-String 'aa510c061b01'O and osmo-hlr would indeed
fail to find a matching route for a non-ASCII string.

Instead of relaying on gsm0480_parse_facility_ie(), let's check the
Data Coding Scheme value and decode the request string ourselves.
Expect the Coding Group 0, but be more tolerant to the indicated
language: print a warning and treat it as '1111'B (unspecified).

Change-Id: Ib7bac660b1a7942adcfbe7b14f162c95061a25db
Related: OS#6075
---
M src/hlr_ussd.c
1 file changed, 66 insertions(+), 2 deletions(-)

Approvals:
  laforge: Looks good to me, approved
  neels: Looks good to me, but someone else must approve
  osmith: Looks good to me, but someone else must approve
  Jenkins Builder: Verified




diff --git a/src/hlr_ussd.c b/src/hlr_ussd.c
index 8d5237f..1c0107b 100644
--- a/src/hlr_ussd.c
+++ b/src/hlr_ussd.c
@@ -122,9 +122,40 @@
        talloc_free(rt);
 }

-static struct hlr_ussd_route *ussd_route_lookup_7bit(struct hlr *hlr, const 
char *ussd_code)
+static struct hlr_ussd_route *ussd_route_lookup_for_req(struct hlr *hlr, const 
struct ss_request *req)
 {
+       const uint8_t cgroup = req->ussd_data_dcs >> 4;
+       const uint8_t lang = req->ussd_data_dcs & 0x0f;
+       char ussd_code[GSM0480_USSD_7BIT_STRING_LEN];
        struct hlr_ussd_route *rt;
+
+       ussd_code[0] = '\0';
+
+       /* We support only the Coding Group 0 (GSM 7-bit default alphabeet).  
In fact,
+        * the USSD request is usually limited to [*#0-9], so we don't really 
need to
+        * support other coding groups and languages. */
+       switch (cgroup) {
+       case 0:
+               /* The Language is usually set to '1111'B (unspecified), but 
some UEs
+                * are known to indicate '0000'B (German). */
+               if (lang != 0x0f) {
+                       LOGP(DSS, LOGL_NOTICE, "USSD DataCodingScheme (0x%02x): 
"
+                            "the Language is usually set to 15 (unspecified), "
+                            "but the request indicates %u - ignoring this\n",
+                            req->ussd_data_dcs, lang);
+                       /* do not abort, attempt to decode as if it was '1111'B 
*/
+               }
+
+               gsm_7bit_decode_n_ussd(&ussd_code[0], sizeof(ussd_code),
+                                      req->ussd_data, (req->ussd_data_len * 8) 
/ 7);
+               break;
+       default:
+               LOGP(DSS, LOGL_ERROR, "USSD DataCodingScheme (0x%02x): "
+                    "Coding Group %u is not supported, expecting Coding Group 
0\n",
+                    req->ussd_data_dcs, cgroup);
+               return NULL;
+       }
+
        llist_for_each_entry(rt, &hlr->ussd_routes, list) {
                if (!strncmp(ussd_code, rt->prefix, strlen(rt->prefix))) {
                        LOGP(DSS, LOGL_DEBUG, "Found %s '%s' (prefix '%s') for 
USSD "
@@ -603,7 +634,7 @@
                        } else {
                                /* VLR->EUSE: MO USSD. VLR is known ('conn'), 
EUSE is to be resolved */
                                struct hlr_ussd_route *rt;
-                               rt = ussd_route_lookup_7bit(hlr, (const char *) 
req.ussd_text);
+                               rt = ussd_route_lookup_for_req(hlr, &req);
                                if (rt) {
                                        if (rt->is_external) {
                                                ss->is_external = true;

--
To view, visit https://gerrit.osmocom.org/c/osmo-hlr/+/33528
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-hlr
Gerrit-Branch: master
Gerrit-Change-Id: Ib7bac660b1a7942adcfbe7b14f162c95061a25db
Gerrit-Change-Number: 33528
Gerrit-PatchSet: 3
Gerrit-Owner: fixeria <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: neels <[email protected]>
Gerrit-Reviewer: osmith <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>
Gerrit-MessageType: merged

Reply via email to