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/.
dexter gerrit-no-reply at lists.osmocom.org
Review at https://gerrit.osmocom.org/2178
gsm0808: Add AoIP specific elements to gsm0808_create_... functions
the classic A implementation in libosmocore lacks support for AoIP
message elements. This patch adds support for AoIP by adding a set
of new gsm0808_create_..., which support the missing AoIP message
elements
Change-Id: I77f866abec1822d19871052f3c647ad782785b34
---
M include/osmocom/gsm/gsm0808.h
M src/gsm/gsm0808.c
M src/gsm/libosmogsm.map
M tests/gsm0808/gsm0808_test.c
M tests/gsm0808/gsm0808_test.ok
5 files changed, 284 insertions(+), 18 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/78/2178/1
diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h
index a7e102c..7ef62b2 100644
--- a/include/osmocom/gsm/gsm0808.h
+++ b/include/osmocom/gsm/gsm0808.h
@@ -20,10 +20,16 @@
#pragma once
#include "tlv.h"
+#include <osmocom/gsm/protocol/gsm_08_08.h>
+#include <sys/socket.h>
struct msgb;
-struct msgb *gsm0808_create_layer3(struct msgb *msg, uint16_t netcode, uint16_t countrycode, int lac, uint16_t ci);
+struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc,
+ uint16_t cc, int lac, uint16_t _ci);
+struct msgb *gsm0808_create_layer3_aoip(struct msgb *msg_l3, uint16_t nc,
+ uint16_t cc, int lac, uint16_t _ci,
+ struct llist_head *scl);
struct msgb *gsm0808_create_reset(void);
struct msgb *gsm0808_create_reset_ack(void);
struct msgb *gsm0808_create_clear_command(uint8_t reason);
@@ -33,9 +39,22 @@
struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len,
const uint8_t *cm3, uint8_t cm3_len);
struct msgb *gsm0808_create_sapi_reject(uint8_t link_id);
+struct msgb *gsm0808_create_assignment_completed_aoip(uint8_t rr_cause,
+ uint8_t chosen_channel,
+ uint8_t encr_alg_id,
+ uint8_t speech_mode,
+ struct sockaddr_storage
+ *ss,
+ struct
+ gsm0808_speech_codec *sc,
+ struct llist_head *scl);
struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause,
- uint8_t chosen_channel, uint8_t encr_alg_id,
+ uint8_t chosen_channel,
+ uint8_t encr_alg_id,
uint8_t speech_mode);
+struct msgb *gsm0808_create_assignment_failure_aoip(uint8_t cause,
+ uint8_t *rr_cause,
+ struct llist_head *scl);
struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause);
struct msgb *gsm0808_create_clear_rqst(uint8_t cause);
diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c
index de80006..c37ce3e 100644
--- a/src/gsm/gsm0808.c
+++ b/src/gsm/gsm0808.c
@@ -19,6 +19,7 @@
*/
#include <osmocom/gsm/gsm0808.h>
+#include <osmocom/gsm/gsm0808_utils.h>
#include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/gsm48.h>
@@ -27,17 +28,20 @@
#define BSSMAP_MSG_SIZE 512
#define BSSMAP_MSG_HEADROOM 128
-struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, uint16_t cc, int lac, uint16_t _ci)
+struct msgb *gsm0808_create_layer3_aoip(struct msgb *msg_l3, uint16_t nc,
+ uint16_t cc, int lac, uint16_t _ci,
+ struct llist_head *scl)
{
- struct msgb* msg;
+ struct msgb *msg;
+ struct msgb *scl_encoded;
struct {
uint8_t ident;
struct gsm48_loc_area_id lai;
uint16_t ci;
} __attribute__ ((packed)) lai_ci;
- msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
- "bssmap cmpl l3");
+ msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
+ "bssmap cmpl l3");
if (!msg)
return NULL;
@@ -49,16 +53,35 @@
gsm48_generate_lai(&lai_ci.lai, cc, nc, lac);
lai_ci.ci = htons(_ci);
msgb_tlv_put(msg, GSM0808_IE_CELL_IDENTIFIER, sizeof(lai_ci),
- (uint8_t *) &lai_ci);
+ (uint8_t *) & lai_ci);
/* copy the layer3 data */
msgb_tlv_put(msg, GSM0808_IE_LAYER_3_INFORMATION,
msgb_l3len(msg_l3), msg_l3->l3h);
+ /* AoIP: add Codec List (BSS Supported) 3.2.2.103 */
+ if (scl) {
+ scl_encoded = gsm0808_enc_speech_codec_list(scl);
+ if (!scl_encoded) {
+ msgb_free(msg);
+ return NULL;
+ }
+ msgb_tlv_put(msg, GSM0808_IE_SPEECH_CODEC_LIST,
+ scl_encoded->len, scl_encoded->data);
+ msgb_free(scl_encoded);
+ }
+
/* push the bssmap header */
- msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
+ msg->l3h =
+ msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
return msg;
+}
+
+struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc,
+ uint16_t cc, int lac, uint16_t _ci)
+{
+ return gsm0808_create_layer3_aoip(msg_l3, nc, cc, lac, _ci, NULL);
}
struct msgb *gsm0808_create_reset(void)
@@ -191,12 +214,22 @@
return msg;
}
-struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause,
- uint8_t chosen_channel, uint8_t encr_alg_id,
- uint8_t speech_mode)
+struct msgb *gsm0808_create_assignment_completed_aoip(uint8_t rr_cause,
+ uint8_t chosen_channel,
+ uint8_t encr_alg_id,
+ uint8_t speech_mode,
+ struct sockaddr_storage
+ *ss,
+ struct
+ gsm0808_speech_codec *sc,
+ struct llist_head *scl)
{
- struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
- "bssmap: ass compl");
+ struct msgb *ss_encoded;
+ struct msgb *sc_encoded;
+ struct msgb *scl_encoded;
+ struct msgb *msg =
+ msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
+ "bssmap: ass compl");
if (!msg)
return NULL;
@@ -218,17 +251,70 @@
if (speech_mode != 0)
msgb_tv_put(msg, GSM0808_IE_SPEECH_VERSION, speech_mode);
+ /* AoIP: AoIP Transport Layer Address (BSS) 3.2.2.102 */
+ if (ss) {
+ ss_encoded = gsm0808_enc_aoip_trasp_addr(ss);
+ if (!ss_encoded) {
+ msgb_free(msg);
+ return NULL;
+ }
+ msgb_tlv_put(msg, GSM0808_IE_AOIP_TRASP_ADDR,
+ ss_encoded->len, ss_encoded->data);
+ msgb_free(ss_encoded);
+ }
+
+ /* AoIP: Speech Codec (Chosen) 3.2.2.104 */
+ if (sc) {
+ sc_encoded = gsm0808_enc_speech_codec(sc);
+ if (!sc_encoded) {
+ msgb_free(msg);
+ return NULL;
+ }
+ msgb_tlv_put(msg, GSM0808_IE_SPEECH_CODEC,
+ sc_encoded->len, sc_encoded->data);
+ msgb_free(sc_encoded);
+ }
+
+ /* AoIP: add Codec List (BSS Supported) 3.2.2.103 */
+ if (scl) {
+ scl_encoded = gsm0808_enc_speech_codec_list(scl);
+ if (!scl_encoded) {
+ msgb_free(msg);
+ return NULL;
+ }
+ msgb_tlv_put(msg, GSM0808_IE_SPEECH_CODEC_LIST,
+ scl_encoded->len, scl_encoded->data);
+ msgb_free(scl_encoded);
+ }
+
/* write LSA identifier 3.2.2.15 */
- msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
+ msg->l3h =
+ msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
return msg;
}
-struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause)
+struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause,
+ uint8_t chosen_channel,
+ uint8_t encr_alg_id,
+ uint8_t speech_mode)
{
- struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
- "bssmap: ass fail");
+ return gsm0808_create_assignment_completed_aoip(rr_cause,
+ chosen_channel,
+ encr_alg_id,
+ speech_mode,
+ NULL, NULL, NULL);
+}
+
+struct msgb *gsm0808_create_assignment_failure_aoip(uint8_t cause,
+ uint8_t *rr_cause,
+ struct llist_head *scl)
+{
+ struct msgb *scl_encoded;
+ struct msgb *msg =
+ msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
+ "bssmap: ass fail");
if (!msg)
return NULL;
@@ -242,12 +328,31 @@
/* Circuit pool 3.22.45 */
/* Circuit pool list 3.2.2.46 */
+ /* AoIP: add Codec List (BSS Supported) 3.2.2.103 */
+ if (scl) {
+ scl_encoded = gsm0808_enc_speech_codec_list(scl);
+ if (!scl_encoded) {
+ msgb_free(msg);
+ return NULL;
+ }
+ msgb_tlv_put(msg, GSM0808_IE_SPEECH_CODEC_LIST,
+ scl_encoded->len, scl_encoded->data);
+ msgb_free(scl_encoded);
+ }
+
/* update the size */
- msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
+ msg->l3h =
+ msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
return msg;
}
+struct msgb *gsm0808_create_assignment_failure(uint8_t cause,
+ uint8_t *rr_cause)
+{
+ return gsm0808_create_assignment_failure_aoip(cause, rr_cause, NULL);
+}
+
struct msgb *gsm0808_create_clear_rqst(uint8_t cause)
{
struct msgb *msg;
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index c89cbe4..3c23ed8 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -125,7 +125,9 @@
gsm0808_bssap_name;
gsm0808_bssmap_name;
gsm0808_create_assignment_completed;
+gsm0808_create_assignment_completed_aoip;
gsm0808_create_assignment_failure;
+gsm0808_create_assignment_failure_aoip;
gsm0808_create_cipher_complete;
gsm0808_create_cipher_reject;
gsm0808_create_classmark_update;
@@ -134,6 +136,7 @@
gsm0808_create_clear_rqst;
gsm0808_create_dtap;
gsm0808_create_layer3;
+gsm0808_create_layer3_aoip;
gsm0808_create_reset;
gsm0808_create_sapi_reject;
gsm0808_prepend_dtap_header;
diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c
index 7f2cff1..6cfcf34 100644
--- a/tests/gsm0808/gsm0808_test.c
+++ b/tests/gsm0808/gsm0808_test.c
@@ -41,6 +41,47 @@
abort(); \
}
+/* Setup a fake codec list for testing */
+static struct llist_head *setup_codec_list(const void *ctx)
+{
+ struct gsm0808_speech_codec *enc_sc1;
+ struct gsm0808_speech_codec *enc_sc2;
+ struct gsm0808_speech_codec *enc_sc3;
+
+ struct llist_head *sc_list;
+
+ sc_list = talloc_zero(ctx, struct llist_head);
+ enc_sc1 = talloc_zero(sc_list, struct gsm0808_speech_codec);
+ enc_sc2 = talloc_zero(sc_list, struct gsm0808_speech_codec);
+ enc_sc3 = talloc_zero(sc_list, struct gsm0808_speech_codec);
+
+ INIT_LLIST_HEAD(sc_list);
+
+ memset(enc_sc1, 0, sizeof(*enc_sc1));
+ enc_sc1->pi = true;
+ enc_sc1->tf = true;
+ enc_sc1->type = 0xab;
+ enc_sc1->type_extended = true;
+ enc_sc1->cfg_present = true;
+ enc_sc1->cfg = 0xcdef;
+
+ memset(enc_sc2, 0, sizeof(*enc_sc2));
+ enc_sc2->fi = true;
+ enc_sc2->pt = true;
+ enc_sc2->type = 0x05;
+
+ memset(enc_sc3, 0, sizeof(*enc_sc3));
+ enc_sc3->fi = true;
+ enc_sc3->tf = true;
+ enc_sc3->type = 0xf2;
+ enc_sc3->type_extended = true;
+
+ llist_add(&enc_sc3->list, sc_list);
+ llist_add(&enc_sc2->list, sc_list);
+ llist_add(&enc_sc1->list, sc_list);
+
+ return sc_list;
+}
static void test_create_layer3(void)
{
@@ -56,6 +97,34 @@
msg = gsm0808_create_layer3(in_msg, 0x1122, 0x2244, 0x3366, 0x4488);
VERIFY(msg, res, ARRAY_SIZE(res));
+ msgb_free(msg);
+ msgb_free(in_msg);
+}
+
+static void test_create_layer3_aoip(const void *ctx)
+{
+ static const uint8_t res[] = {
+ 0x00, 0x17, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62,
+ 0x83, 0x33, 0x66, 0x44, 0x88, 0x17, 0x01, 0x23,
+ GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, 0xef,
+ 0xa5, 0x9f, 0xf2
+ };
+
+ struct msgb *msg, *in_msg;
+ struct llist_head *sc_list;
+ printf("Testing creating Layer3 (AoIP)\n");
+
+ sc_list = setup_codec_list(ctx);
+
+ in_msg = msgb_alloc_headroom(512, 128, "foo");
+ in_msg->l3h = in_msg->data;
+ msgb_v_put(in_msg, 0x23);
+
+ msg =
+ gsm0808_create_layer3_aoip(in_msg, 0x1122, 0x2244, 0x3366, 0x4488,
+ sc_list);
+ VERIFY(msg, res, ARRAY_SIZE(res));
+ talloc_free(sc_list);
msgb_free(msg);
msgb_free(in_msg);
}
@@ -189,6 +258,44 @@
msgb_free(msg);
}
+static void test_create_ass_compl_aoip(const void *ctx)
+{
+ struct sockaddr_storage ss;
+ struct sockaddr_in sin;
+ struct gsm0808_speech_codec sc;
+ struct llist_head *sc_list;
+ static const uint8_t res[] =
+ { 0x00, 0x1d, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11, 0x40, 0x22,
+ GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17, 0x04,
+ 0xd2, GSM0808_IE_SPEECH_CODEC, 0x01, 0x9a,
+ GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, 0xef, 0xa5,
+ 0x9f, 0xf2 };
+ struct msgb *msg;
+
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(1234);
+ inet_aton("192.168.100.23", &sin.sin_addr);
+
+ memset(&ss, 0, sizeof(ss));
+ memcpy(&ss, &sin, sizeof(sin));
+
+ memset(&sc, 0, sizeof(sc));
+ sc.fi = true;
+ sc.tf = true;
+ sc.type = 0x0a;
+
+ sc_list = setup_codec_list(ctx);
+
+ printf("Testing creating Assignment Complete (AoIP)\n");
+ msg =
+ gsm0808_create_assignment_completed_aoip(0x23, 0x42, 0x11, 0x22,
+ &ss, &sc, sc_list);
+ VERIFY(msg, res, ARRAY_SIZE(res));
+ msgb_free(msg);
+ talloc_free(sc_list);
+}
+
static void test_create_ass_fail()
{
static const uint8_t res1[] = { 0x00, 0x04, 0x03, 0x04, 0x01, 0x23 };
@@ -205,6 +312,32 @@
msg = gsm0808_create_assignment_failure(0x23, &rr_res);
VERIFY(msg, res2, ARRAY_SIZE(res2));
msgb_free(msg);
+}
+
+static void test_create_ass_fail_aoip(const void *ctx)
+{
+ static const uint8_t res1[] =
+ { 0x00, 0x0d, 0x03, 0x04, 0x01, 0x23, GSM0808_IE_SPEECH_CODEC_LIST,
+ 0x07, 0x5f, 0xab, 0xcd, 0xef, 0xa5, 0x9f, 0xf2 };
+ static const uint8_t res2[] =
+ { 0x00, 0x0f, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02,
+ GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab,
+ 0xcd, 0xef, 0xa5, 0x9f, 0xf2 };
+ uint8_t rr_res = 2;
+ struct msgb *msg;
+ struct llist_head *sc_list;
+
+ sc_list = setup_codec_list(ctx);
+
+ printf("Testing creating Assignment Failure (AoIP)\n");
+ msg = gsm0808_create_assignment_failure_aoip(0x23, NULL, sc_list);
+ VERIFY(msg, res1, ARRAY_SIZE(res1));
+ msgb_free(msg);
+
+ msg = gsm0808_create_assignment_failure_aoip(0x23, &rr_res, sc_list);
+ VERIFY(msg, res2, ARRAY_SIZE(res2));
+ msgb_free(msg);
+ talloc_free(sc_list);
}
static void test_create_clear_rqst()
@@ -467,6 +600,7 @@
printf("Testing generation of GSM0808 messages\n");
test_create_layer3();
+ test_create_layer3_aoip(ctx);
test_create_reset();
test_create_clear_command();
test_create_clear_complete();
@@ -475,7 +609,9 @@
test_create_cm_u();
test_create_sapi_reject();
test_create_ass_compl();
+ test_create_ass_compl_aoip(ctx);
test_create_ass_fail();
+ test_create_ass_fail_aoip(ctx);
test_create_clear_rqst();
test_create_dtap();
test_prepend_dtap();
diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok
index eb43126..f406551 100644
--- a/tests/gsm0808/gsm0808_test.ok
+++ b/tests/gsm0808/gsm0808_test.ok
@@ -1,5 +1,6 @@
Testing generation of GSM0808 messages
Testing creating Layer3
+Testing creating Layer3 (AoIP)
Testing creating Reset
Testing creating Clear Command
Testing creating Clear Complete
@@ -8,7 +9,9 @@
Testing creating CM U
Testing creating SAPI Reject
Testing creating Assignment Complete
+Testing creating Assignment Complete (AoIP)
Testing creating Assignment Failure
+Testing creating Assignment Failure (AoIP)
Testing creating Clear Request
Testing creating DTAP
Testing prepend DTAP
--
To view, visit https://gerrit.osmocom.org/2178
To unsubscribe, visit https://gerrit.osmocom.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I77f866abec1822d19871052f3c647ad782785b34
Gerrit-PatchSet: 1
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Owner: dexter <pmaier at sysmocom.de>