This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Vadim Yanitskiy gerrit-no-reply at lists.osmocom.orgVadim Yanitskiy has uploaded this change for review. ( https://gerrit.osmocom.org/9528 Change subject: gsm/gsm0480.c: introduce gsm0480_extract_ie_by_tag() ...................................................................... gsm/gsm0480.c: introduce gsm0480_extract_ie_by_tag() In some cases, there is no need to parse the whole message, e.g. during the conversation from DTAP to GSUP/MAP. This function can be used to extract given IE from a message. Change-Id: I3989d061903352473305f80712f1a1560d05df3d --- M include/osmocom/gsm/gsm0480.h M src/gsm/gsm0480.c M src/gsm/libosmogsm.map M tests/ussd/ussd_test.c M tests/ussd/ussd_test.ok 5 files changed, 135 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/28/9528/1 diff --git a/include/osmocom/gsm/gsm0480.h b/include/osmocom/gsm/gsm0480.h index b0b6aa2..b31f8a7 100644 --- a/include/osmocom/gsm/gsm0480.h +++ b/include/osmocom/gsm/gsm0480.h @@ -91,6 +91,8 @@ uint8_t invoke_id; }; +int gsm0480_extract_ie_by_tag(const struct gsm48_hdr *hdr, uint16_t msg_len, + uint8_t **ie, uint16_t *ie_len, uint8_t ie_tag); int gsm0480_decode_ss_request(const struct gsm48_hdr *hdr, uint16_t len, struct ss_request *request); diff --git a/src/gsm/gsm0480.c b/src/gsm/gsm0480.c index 5c73e5b..80e59df 100644 --- a/src/gsm/gsm0480.c +++ b/src/gsm/gsm0480.c @@ -33,6 +33,7 @@ #include <osmocom/gsm/protocol/gsm_04_80.h> #include <string.h> +#include <errno.h> static inline unsigned char *msgb_wrap_with_TL(struct msgb *msgb, uint8_t tag) { @@ -214,6 +215,77 @@ uint16_t length, struct ss_request *req); +int gsm0480_extract_ie_by_tag(const struct gsm48_hdr *hdr, uint16_t msg_len, + uint8_t **ie, uint16_t *ie_len, uint8_t ie_tag) +{ + uint8_t pdisc, msg_type; + uint8_t *tlv, len; + + /* Init external variables */ + *ie_len = 0; + *ie = NULL; + + /* Drop incomplete / corrupted messages */ + if (msg_len < sizeof(*hdr)) + return -EINVAL; + + pdisc = gsm48_hdr_pdisc(hdr); + msg_type = gsm48_hdr_msg_type(hdr); + + /* Drop non-SS related messages */ + if (pdisc != GSM48_PDISC_NC_SS) + return -EINVAL; + + len = msg_len - sizeof(*hdr); + tlv = (uint8_t *) hdr->data; + + /* Parse a message depending on its type */ + switch (msg_type) { + /* See table 2.5: RELEASE COMPLETE message content */ + case GSM0480_MTYPE_RELEASE_COMPLETE: + /* See tables 2.3 and 2.4: REGISTER message content */ + case GSM0480_MTYPE_REGISTER: + /* Iterate over TLV-based IEs */ + while (len > 2) { + if (tlv[0] == ie_tag) { + *ie_len = tlv[1]; + *ie = tlv + 2; + return 0; + } + + len -= tlv[1] + 2; + tlv += tlv[1] + 2; + continue; + } + + /* The Facility IE is mandatory for REGISTER */ + if (msg_type == GSM0480_MTYPE_REGISTER) + if (ie_tag == GSM0480_IE_FACILITY) + return -EINVAL; + break; + + /* See table 2.2: FACILITY message content */ + case GSM0480_MTYPE_FACILITY: + /* There is no other IEs */ + if (ie_tag != GSM0480_IE_FACILITY) + break; + + /* Mandatory LV-based Facility IE */ + if (len < 2) + return -EINVAL; + + *ie_len = tlv[0]; + *ie = tlv + 1; + return 0; + + default: + /* Wrong message type, out of specs */ + return -EINVAL; + } + + return 0; +} + /* Decode a mobile-originated USSD-request message */ int gsm0480_decode_ussd_request(const struct gsm48_hdr *hdr, uint16_t len, struct ussd_request *req) diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 117cecf..4aaed46 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -89,6 +89,7 @@ gsm0480_create_ussd_resp; gsm0480_create_ussd_notify; gsm0480_create_ussd_release_complete; +gsm0480_extract_ie_by_tag; gsm0480_decode_ussd_request; gsm0480_decode_ss_request; gsm0480_wrap_facility; diff --git a/tests/ussd/ussd_test.c b/tests/ussd/ussd_test.c index 1f79063..47365c9 100644 --- a/tests/ussd/ussd_test.c +++ b/tests/ussd/ussd_test.c @@ -34,6 +34,11 @@ 0x01, 0x7f, 0x01, 0x00 }; +static const uint8_t ussd_release[] = { + 0x8b, 0x2a, 0x1c, 0x08, 0xa3, 0x06, 0x02, 0x01, + 0x05, 0x02, 0x01, 0x24 +}; + static const uint8_t interrogate_ss[] = { 0x0b, 0x7b, 0x1c, 0x0d, 0xa1, 0x0b, 0x02, 0x01, 0x03, 0x02, 0x01, 0x0e, 0x30, 0x03, 0x04, 0x01, @@ -116,6 +121,53 @@ } } +static void test_extract_ie_by_tag(void) +{ + uint16_t ie_len; + uint8_t *ie; + int rc; + + printf("[i] Testing gsm0480_extract_ie_by_tag()\n"); + + /* REGISTER message with Facility IE */ + rc = gsm0480_extract_ie_by_tag((struct gsm48_hdr *) ussd_request, + sizeof(ussd_request), &ie, &ie_len, GSM0480_IE_FACILITY); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(ie != NULL && ie_len > 0); + printf("[?] REGISTER message with Facility IE " + "(len=%u): %s\n", ie_len, osmo_hexdump(ie, ie_len)); + + /* REGISTER message with SS version IE */ + rc = gsm0480_extract_ie_by_tag((struct gsm48_hdr *) ussd_request, + sizeof(ussd_request), &ie, &ie_len, GSM0480_IE_SS_VERSION); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(ie != NULL && ie_len > 0); + printf("[?] REGISTER message with SS version IE " + "(len=%u): %s\n", ie_len, osmo_hexdump(ie, ie_len)); + + /* REGISTER message with unknown IE */ + rc = gsm0480_extract_ie_by_tag((struct gsm48_hdr *) ussd_request, + sizeof(ussd_request), &ie, &ie_len, 0xff); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(ie == NULL && ie_len == 0); + + /* RELEASE COMPLETE message with Facility IE */ + rc = gsm0480_extract_ie_by_tag((struct gsm48_hdr *) ussd_release, + sizeof(ussd_release), &ie, &ie_len, GSM0480_IE_FACILITY); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(ie != NULL && ie_len > 0); + printf("[?] RELEASE COMPLETE message with Facility IE " + "(len=%u): %s\n", ie_len, osmo_hexdump(ie, ie_len)); + + /* RELEASE COMPLETE message without Facility IE */ + rc = gsm0480_extract_ie_by_tag((struct gsm48_hdr *) ussd_release, + sizeof(struct gsm48_hdr), &ie, &ie_len, GSM0480_IE_FACILITY); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(ie == NULL && ie_len == 0); + + printf("\n"); +} + int main(int argc, char **argv) { struct ss_request req; @@ -126,6 +178,9 @@ osmo_init_logging2(ctx, &info); + /* Test gsm0480_extract_ie_by_tag() */ + test_extract_ie_by_tag(); + memset(&req, 0, sizeof(req)); gsm0480_decode_ss_request((struct gsm48_hdr *) ussd_request, sizeof(ussd_request), &req); diff --git a/tests/ussd/ussd_test.ok b/tests/ussd/ussd_test.ok index aff383e..75cabd4 100644 --- a/tests/ussd/ussd_test.ok +++ b/tests/ussd/ussd_test.ok @@ -1,3 +1,8 @@ +[i] Testing gsm0480_extract_ie_by_tag() +[?] REGISTER message with Facility IE (len=21): a1 13 02 01 03 02 01 3b 30 0b 04 01 0f 04 06 2a d5 4c 16 1b 01 +[?] REGISTER message with SS version IE (len=1): 00 +[?] RELEASE COMPLETE message with Facility IE (len=8): a3 06 02 01 05 02 01 24 + Tested if it still works. Text was: **321# interrogateSS CFU text..'' code 33 Testing parsing a USSD request and truncated versions -- To view, visit https://gerrit.osmocom.org/9528 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-MessageType: newchange Gerrit-Change-Id: I3989d061903352473305f80712f1a1560d05df3d Gerrit-Change-Number: 9528 Gerrit-PatchSet: 1 Gerrit-Owner: Vadim Yanitskiy <axilirator at gmail.com> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20180610/bb16aa19/attachment.htm>