diff options
-rw-r--r-- | include/osmocom/gsm/gsm0808.h | 5 | ||||
-rw-r--r-- | src/gsm/gsm0808.c | 56 | ||||
-rw-r--r-- | src/gsm/libosmogsm.map | 1 | ||||
-rw-r--r-- | tests/gsm0808/gsm0808_test.c | 50 | ||||
-rw-r--r-- | tests/gsm0808/gsm0808_test.ok | 1 |
5 files changed, 113 insertions, 0 deletions
diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h index 990fd74d..a9f610a8 100644 --- a/include/osmocom/gsm/gsm0808.h +++ b/include/osmocom/gsm/gsm0808.h @@ -42,6 +42,11 @@ struct msgb *gsm0808_create_cipher_reject(uint8_t cause); 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_ass(const struct gsm0808_channel_type *ct, + const uint16_t *cic, + const struct sockaddr_storage *ss, + const struct gsm0808_speech_codec_list *scl, + const uint32_t *ci); struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel, uint8_t encr_alg_id, uint8_t speech_mode, const struct sockaddr_storage *ss, diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c index 2721a1b1..be58939d 100644 --- a/src/gsm/gsm0808.c +++ b/src/gsm/gsm0808.c @@ -238,6 +238,62 @@ struct msgb *gsm0808_create_sapi_reject(uint8_t link_id) return msg; } +struct msgb *gsm0808_create_ass(const struct gsm0808_channel_type *ct, + const uint16_t *cic, + const struct sockaddr_storage *ss, + const struct gsm0808_speech_codec_list *scl, + const uint32_t *ci) +{ + /* See also: 3GPP TS 48.008 3.2.1.1 ASSIGNMENT REQUEST */ + struct msgb *msg; + uint16_t cic_sw; + uint32_t ci_sw; + + /* Mandatory emelent! */ + OSMO_ASSERT(ct); + + msg = + msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, + "bssmap: ass req"); + if (!msg) + return NULL; + + /* Message Type 3.2.2.1 */ + msgb_v_put(msg, BSS_MAP_MSG_ASSIGMENT_RQST); + + /* Channel Type 3.2.2.11 */ + gsm0808_enc_channel_type(msg, ct); + + /* Circuit Identity Code 3.2.2.2 */ + if (cic) { + cic_sw = htons(*cic); + msgb_tv_fixed_put(msg, GSM0808_IE_CIRCUIT_IDENTITY_CODE, + sizeof(cic_sw), (uint8_t *) & cic_sw); + } + + /* AoIP: AoIP Transport Layer Address (MGW) 3.2.2.102 */ + if (ss) { + gsm0808_enc_aoip_trasp_addr(msg, ss); + } + + /* AoIP: Codec List (MSC Preferred) 3.2.2.103 */ + if (scl) + gsm0808_enc_speech_codec_list(msg, scl); + + /* AoIP: Call Identifier 3.2.2.105 */ + if (ci) { + ci_sw = htonl(*ci); + msgb_tv_fixed_put(msg, GSM0808_IE_CALL_ID, sizeof(ci_sw), + (uint8_t *) & ci_sw); + } + + /* push the bssmap header */ + msg->l3h = + msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg)); + + return msg; +} + struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel, uint8_t encr_alg_id, uint8_t speech_mode, const struct sockaddr_storage *ss, diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index ec234189..a4e6083b 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -124,6 +124,7 @@ gsm0503_mcs9; gsm0808_att_tlvdef; gsm0808_bssap_name; gsm0808_bssmap_name; +gsm0808_create_ass; gsm0808_create_assignment_completed; gsm0808_create_ass_compl; gsm0808_create_assignment_failure; diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c index b0dad7d8..a0ff6d52 100644 --- a/tests/gsm0808/gsm0808_test.c +++ b/tests/gsm0808/gsm0808_test.c @@ -262,6 +262,55 @@ static void test_create_sapi_reject() msgb_free(msg); } +static void test_create_ass() +{ + static const uint8_t res1[] = + { 0x00, 0x0a, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00, + 0x04 }; + static const uint8_t res2[] = + { 0x00, 0x20, 0x01, 0x0b, 0x04, 0x01, 0x0b, 0xa1, 0x25, 0x01, 0x00, + 0x04, GSM0808_IE_AOIP_TRASP_ADDR, 0x06, 0xc0, 0xa8, 0x64, 0x17, + 0x04, 0xd2, GSM0808_IE_SPEECH_CODEC_LIST, 0x07, 0x5f, 0xab, 0xcd, + 0xef, 0xa5, 0x9f, 0xf2, GSM0808_IE_CALL_ID, 0xaa, 0xbb, 0xcc, + 0xdd }; + + struct msgb *msg; + struct gsm0808_channel_type ct; + uint16_t cic = 0004; + struct sockaddr_storage ss; + struct sockaddr_in sin; + struct gsm0808_speech_codec_list sc_list; + uint32_t call_id = 0xAABBCCDD; + + memset(&ct, 0, sizeof(ct)); + ct.ch_indctr = GSM0808_CHAN_SPEECH; + ct.ch_rate_type = GSM0808_SPEECH_HALF_PREF; + ct.perm_spch[0] = GSM0808_PERM_FR3; + ct.perm_spch[1] = GSM0808_PERM_HR3; + ct.perm_spch_len = 2; + + 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)); + + setup_codec_list(&sc_list); + + printf("Testing creating Assignment Request\n"); + msg = gsm0808_create_ass(&ct, &cic, NULL, NULL, NULL); + OSMO_ASSERT(msg); + VERIFY(msg, res1, ARRAY_SIZE(res1)); + msgb_free(msg); + + msg = gsm0808_create_ass(&ct, &cic, &ss, &sc_list, &call_id); + OSMO_ASSERT(msg); + VERIFY(msg, res2, ARRAY_SIZE(res2)); + msgb_free(msg); +} + static void test_create_ass_compl() { static const uint8_t res1[] = { @@ -786,6 +835,7 @@ int main(int argc, char **argv) test_create_cipher_reject(); test_create_cm_u(); test_create_sapi_reject(); + test_create_ass(); test_create_ass_compl(); test_create_ass_compl_aoip(); test_create_ass_fail(); diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok index 6170a7ab..52af1342 100644 --- a/tests/gsm0808/gsm0808_test.ok +++ b/tests/gsm0808/gsm0808_test.ok @@ -9,6 +9,7 @@ Testing creating Cipher Complete Testing creating Cipher Reject Testing creating CM U Testing creating SAPI Reject +Testing creating Assignment Request Testing creating Assignment Complete Testing creating Assignment Complete (AoIP) Testing creating Assignment Failure |