/* * (C) 2012 by Holger Hans Peter Freyther * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #define VERIFY(msg, data, len) \ if (msgb_l3len(msg) != len) { \ printf("%s:%d Length don't match: %d vs. %d. %s\n", \ __func__, __LINE__, msgb_l3len(msg), len, \ osmo_hexdump(msg->l3h, msgb_l3len(msg))); \ abort(); \ } else if (memcmp(msg->l3h, data, len) != 0) { \ printf("%s:%d didn't match: got: %s\n", \ __func__, __LINE__, \ osmo_hexdump(msg->l3h, msgb_l3len(msg))); \ abort(); \ } static void test_create_layer3(void) { static const uint8_t res[] = { 0x00, 0x0e, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62, 0x83, 0x33, 0x66, 0x44, 0x88, 0x17, 0x01, 0x23 }; struct msgb *msg, *in_msg; printf("Testing creating Layer3\n"); in_msg = msgb_alloc_headroom(512, 128, "foo"); in_msg->l3h = in_msg->data; msgb_v_put(in_msg, 0x23); 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_reset() { static const uint8_t res[] = { 0x00, 0x04, 0x30, 0x04, 0x01, 0x20 }; struct msgb *msg; printf("Testing creating Reset\n"); msg = gsm0808_create_reset(); VERIFY(msg, res, ARRAY_SIZE(res)); msgb_free(msg); } static void test_create_clear_command() { static const uint8_t res[] = { 0x20, 0x04, 0x01, 0x23 }; struct msgb *msg; printf("Testing creating Clear Command\n"); msg = gsm0808_create_clear_command(0x23); VERIFY(msg, res, ARRAY_SIZE(res)); msgb_free(msg); } static void test_create_clear_complete() { static const uint8_t res[] = { 0x00, 0x01, 0x21 }; struct msgb *msg; printf("Testing creating Clear Complete\n"); msg = gsm0808_create_clear_complete(); VERIFY(msg, res, ARRAY_SIZE(res)); msgb_free(msg); } static void test_create_cipher_complete() { static const uint8_t res1[] = { 0x00, 0x08, 0x55, 0x20, 0x03, 0x23, 0x42, 0x21, 0x2c, 0x04 }; static const uint8_t res2[] = { 0x00, 0x03, 0x55, 0x2c, 0x04}; struct msgb *l3, *msg; printf("Testing creating Cipher Complete\n"); l3 = msgb_alloc_headroom(512, 128, "l3h"); l3->l3h = l3->data; msgb_v_put(l3, 0x23); msgb_v_put(l3, 0x42); msgb_v_put(l3, 0x21); /* with l3 data */ msg = gsm0808_create_cipher_complete(l3, 4); VERIFY(msg, res1, ARRAY_SIZE(res1)); msgb_free(msg); /* with l3 data but short */ l3->len -= 1; l3->tail -= 1; msg = gsm0808_create_cipher_complete(l3, 4); VERIFY(msg, res2, ARRAY_SIZE(res2)); msgb_free(msg); /* without l3 data */ msg = gsm0808_create_cipher_complete(NULL, 4); VERIFY(msg, res2, ARRAY_SIZE(res2)); msgb_free(msg); msgb_free(l3); } static void test_create_cipher_reject() { static const uint8_t res[] = { 0x00, 0x02, 0x59, 0x23 }; struct msgb *msg; printf("Testing creating Cipher Reject\n"); msg = gsm0808_create_cipher_reject(0x23); VERIFY(msg, res, ARRAY_SIZE(res)); msgb_free(msg); } static void test_create_cm_u() { static const uint8_t res[] = { 0x00, 0x07, 0x54, 0x12, 0x01, 0x23, 0x13, 0x01, 0x42 }; static const uint8_t res2o[] = { 0x00, 0x04, 0x54, 0x12, 0x01, 0x23 }; struct msgb *msg; const uint8_t cm2 = 0x23; const uint8_t cm3 = 0x42; printf("Testing creating CM U\n"); msg = gsm0808_create_classmark_update(&cm2, 1, &cm3, 1); VERIFY(msg, res, ARRAY_SIZE(res)); msg = gsm0808_create_classmark_update(&cm2, 1, NULL, 0); VERIFY(msg, res2o, ARRAY_SIZE(res2o)); msgb_free(msg); } static void test_create_sapi_reject() { static const uint8_t res[] = { 0x00, 0x03, 0x25, 0x03, 0x25 }; struct msgb *msg; printf("Testing creating SAPI Reject\n"); msg = gsm0808_create_sapi_reject(3); VERIFY(msg, res, ARRAY_SIZE(res)); msgb_free(msg); } static void test_create_ass_compl() { static const uint8_t res1[] = { 0x00, 0x09, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11, 0x40, 0x22 }; static const uint8_t res2[] = { 0x00, 0x07, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11}; struct msgb *msg; printf("Testing creating Assignment Complete\n"); msg = gsm0808_create_assignment_completed(0x23, 0x42, 0x11, 0x22); VERIFY(msg, res1, ARRAY_SIZE(res1)); msgb_free(msg); msg = gsm0808_create_assignment_completed(0x23, 0x42, 0x11, 0); VERIFY(msg, res2, ARRAY_SIZE(res2)); msgb_free(msg); } static void test_create_ass_fail() { static const uint8_t res1[] = { 0x00, 0x04, 0x03, 0x04, 0x01, 0x23 }; static const uint8_t res2[] = { 0x00, 0x06, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02}; uint8_t rr_res = 2; struct msgb *msg; printf("Testing creating Assignment Failure\n"); msg = gsm0808_create_assignment_failure(0x23, NULL); VERIFY(msg, res1, ARRAY_SIZE(res1)); msgb_free(msg); msg = gsm0808_create_assignment_failure(0x23, &rr_res); VERIFY(msg, res2, ARRAY_SIZE(res2)); msgb_free(msg); } static void test_create_clear_rqst() { static const uint8_t res[] = { 0x00, 0x04, 0x22, 0x04, 0x01, 0x23 }; struct msgb *msg; printf("Testing creating Clear Request\n"); msg = gsm0808_create_clear_rqst(0x23); VERIFY(msg, res, ARRAY_SIZE(res)); msgb_free(msg); } static void test_create_dtap() { static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 }; struct msgb *msg, *l3; printf("Testing creating DTAP\n"); l3 = msgb_alloc_headroom(512, 128, "test"); l3->l3h = l3->data; msgb_v_put(l3, 0x23); msgb_v_put(l3, 0x42); msg = gsm0808_create_dtap(l3, 0x3); VERIFY(msg, res, ARRAY_SIZE(res)); msgb_free(msg); msgb_free(l3); } static void test_prepend_dtap() { static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 }; struct msgb *in_msg; printf("Testing prepend DTAP\n"); in_msg = msgb_alloc_headroom(512, 128, "test"); msgb_v_put(in_msg, 0x23); msgb_v_put(in_msg, 0x42); gsm0808_prepend_dtap_header(in_msg, 0x3); in_msg->l3h = in_msg->data; VERIFY(in_msg, res, ARRAY_SIZE(res)); msgb_free(in_msg); } int main(int argc, char **argv) { printf("Testing generation of GSM0808 messages\n"); test_create_layer3(); test_create_reset(); test_create_clear_command(); test_create_clear_complete(); test_create_cipher_complete(); test_create_cipher_reject(); test_create_cm_u(); test_create_sapi_reject(); test_create_ass_compl(); test_create_ass_fail(); test_create_clear_rqst(); test_create_dtap(); test_prepend_dtap(); printf("Done\n"); return EXIT_SUCCESS; }