gsm0808: Add create functions for BSS_MAP_MSG_ASSIGMENT_RQST

gsm0808.h/c lacks functionality to generate BSS_MAP_MSG_ASSIGMENT_RQST messages.
These messages are required if the code is used in an MSC implementation.

This commit adds a gsm0808_create_assignment() function, that generates an
A/AoiP BSS_MAP_MSG_PAGING message.

Change-Id: I4d1d455a1e1cf95407e23ded7b7defbcf2dd6ff0
This commit is contained in:
Philipp Maier 2017-03-29 17:53:43 +02:00 committed by Harald Welte
parent 3d48ec06a9
commit c6144a2448
5 changed files with 113 additions and 0 deletions

View File

@ -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, struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len,
const uint8_t *cm3, uint8_t cm3_len); const uint8_t *cm3, uint8_t cm3_len);
struct msgb *gsm0808_create_sapi_reject(uint8_t link_id); 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, struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel,
uint8_t encr_alg_id, uint8_t speech_mode, uint8_t encr_alg_id, uint8_t speech_mode,
const struct sockaddr_storage *ss, const struct sockaddr_storage *ss,

View File

@ -238,6 +238,62 @@ struct msgb *gsm0808_create_sapi_reject(uint8_t link_id)
return msg; 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, struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel,
uint8_t encr_alg_id, uint8_t speech_mode, uint8_t encr_alg_id, uint8_t speech_mode,
const struct sockaddr_storage *ss, const struct sockaddr_storage *ss,

View File

@ -124,6 +124,7 @@ gsm0503_mcs9;
gsm0808_att_tlvdef; gsm0808_att_tlvdef;
gsm0808_bssap_name; gsm0808_bssap_name;
gsm0808_bssmap_name; gsm0808_bssmap_name;
gsm0808_create_ass;
gsm0808_create_assignment_completed; gsm0808_create_assignment_completed;
gsm0808_create_ass_compl; gsm0808_create_ass_compl;
gsm0808_create_assignment_failure; gsm0808_create_assignment_failure;

View File

@ -262,6 +262,55 @@ static void test_create_sapi_reject()
msgb_free(msg); 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 void test_create_ass_compl()
{ {
static const uint8_t res1[] = { static const uint8_t res1[] = {
@ -786,6 +835,7 @@ int main(int argc, char **argv)
test_create_cipher_reject(); test_create_cipher_reject();
test_create_cm_u(); test_create_cm_u();
test_create_sapi_reject(); test_create_sapi_reject();
test_create_ass();
test_create_ass_compl(); test_create_ass_compl();
test_create_ass_compl_aoip(); test_create_ass_compl_aoip();
test_create_ass_fail(); test_create_ass_fail();

View File

@ -9,6 +9,7 @@ Testing creating Cipher Complete
Testing creating Cipher Reject Testing creating Cipher Reject
Testing creating CM U Testing creating CM U
Testing creating SAPI Reject Testing creating SAPI Reject
Testing creating Assignment Request
Testing creating Assignment Complete Testing creating Assignment Complete
Testing creating Assignment Complete (AoIP) Testing creating Assignment Complete (AoIP)
Testing creating Assignment Failure Testing creating Assignment Failure