# HG changeset patch # User Mychaela Falconia # Date 1727157568 0 # Node ID 40f781efdbe1c5894a217a26146598e409459e60 # Parent 3cc26391d24dabee5d5a70331b9e9bdaf202a478 ater: beginning of D144 mode diff -r 3cc26391d24d -r 40f781efdbe1 ater/activate.c --- a/ater/activate.c Fri Sep 13 01:03:43 2024 +0000 +++ b/ater/activate.c Tue Sep 24 05:59:28 2024 +0000 @@ -66,6 +66,7 @@ /* good to proceed now */ at->is_active = true; at->is_data = false; + at->is_data_144 = false; at->is_efr = is_efr; init_trau_ul_frame(nr); at->ul_frame.c_bits[16] = dtxd; @@ -76,21 +77,26 @@ void cmd_activate_csd(int argc, char **argv) { int nr; - bool ir_16k, is_hr; + bool ir_16k, is_144, is_hr; struct ater_subslot *at; if (argc < 3 || argc > 4) { -usage: fprintf(stderr, "usage: %s 0|1|2|3 8|16 [hr]\n", argv[0]); +usage: fprintf(stderr, "usage: %s 0|1|2|3 8|16|14.4 [hr]\n", argv[0]); return; } if (argv[1][0] < '0' || argv[1][0] > '3' || argv[1][1]) goto usage; nr = argv[1][0] - '0'; - if (!strcmp(argv[2], "8")) + if (!strcmp(argv[2], "8")) { + is_144 = false; ir_16k = false; - else if (!strcmp(argv[2], "16")) + } else if (!strcmp(argv[2], "16")) { + is_144 = false; ir_16k = true; - else + } else if (!strcmp(argv[2], "14.4")) { + is_144 = true; + ir_16k = true; + } else goto usage; if (argv[3]) { if (strcmp(argv[3], "hr")) @@ -98,6 +104,10 @@ is_hr = true; } else is_hr = false; + if (is_hr && (is_144 || ir_16k)) { + fprintf(stderr, "error: HR above 8 kbit/s is impossible\n"); + return; + } at = &subslots[nr]; if (at->is_active) { @@ -108,7 +118,9 @@ /* good to proceed now */ at->is_active = true; at->is_data = true; + at->is_data_144 = is_144; at->is_hr_data = is_hr; + at->d144_edata = false; init_trau_ul_frame_csd(nr, ir_16k); } diff -r 3cc26391d24d -r 40f781efdbe1 ater/dbits.c --- a/ater/dbits.c Fri Sep 13 01:03:43 2024 +0000 +++ b/ater/dbits.c Tue Sep 24 05:59:28 2024 +0000 @@ -41,6 +41,10 @@ fprintf(stderr, "error: subslot %d is not in data mode\n", nr); return; } + if (at->is_data_144) { + fprintf(stderr, "error: subslot %d is in D144 mode\n", nr); + return; + } fr = &at->ul_frame; d_offset = atoi(argv[2]); if (d_offset >= 252) { diff -r 3cc26391d24d -r 40f781efdbe1 ater/submux.h --- a/ater/submux.h Fri Sep 13 01:03:43 2024 +0000 +++ b/ater/submux.h Tue Sep 24 05:59:28 2024 +0000 @@ -22,6 +22,8 @@ bool is_data; bool is_hr_data; bool is_efr; + bool is_data_144; + bool d144_edata; struct osmo_trau_frame ul_frame; unsigned mfrm_count; uint8_t *play_buffer; diff -r 3cc26391d24d -r 40f781efdbe1 ater/tx_func.c --- a/ater/tx_func.c Fri Sep 13 01:03:43 2024 +0000 +++ b/ater/tx_func.c Tue Sep 24 05:59:28 2024 +0000 @@ -18,6 +18,100 @@ #include "submux.h" #include "out_frame.h" +/* + * The following hard-coded frame is based on TS 48.060 section 5.3.1. + * 0-based octet numbers in the comments are as in the spec. + */ +static const ubit_t d144_sync_frame[320] = { + 0, 0, 0, 0, 0, 0, 0, 0, /* octet 0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* octet 1 */ + 1, 1, 0, 1, 0, 0, 1, 1, /* octet 2 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 3 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 4 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 5 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 6 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 7 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 8 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 9 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 10 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 11 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 12 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 13 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 14 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 15 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 16 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 17 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 18 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 19 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 20 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 21 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 22 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 23 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 24 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 25 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 26 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 27 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 28 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 29 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 30 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 31 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 32 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 33 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 34 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 35 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 36 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 37 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 38 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 39 */ +}; + +/* + * The following hard-coded frame is based on TS 48.060 section 5.3.2. + * 0-based octet numbers in the comments are as in the spec. + */ +static const ubit_t d144_idle_edata[320] = { + 0, 0, 0, 0, 0, 0, 0, 0, /* octet 0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* octet 1 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 2 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 3 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 4 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 5 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 6 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 7 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 8 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 9 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 10 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 11 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 12 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 13 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 14 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 15 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 16 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 17 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 18 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 19 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 20 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 21 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 22 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 23 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 24 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 25 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 26 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 27 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 28 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 29 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 30 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 31 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 32 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 33 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 34 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 35 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 36 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 37 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 38 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* octet 39 */ +}; + void init_trau_ul_frame(int nr) { struct ater_subslot *at = &subslots[nr]; @@ -42,6 +136,20 @@ memset(fr->d_bits, 1, 63 * 4); } +static void handle_d144(int nr) +{ + struct ater_subslot *at = &subslots[nr]; + struct msgb *msg; + + msg = msgb_alloc_c(g_ctx, 320, "TRAU-UL-frame"); + if (!msg) + return; + memcpy(msg->tail, at->d144_edata ? d144_idle_edata : d144_sync_frame, + 320); + msgb_put(msg, 320); + osmo_i460_mux_enqueue(at->schan, msg); +} + static void handle_play(struct ater_subslot *at) { if (at->play_wait_align) { @@ -68,6 +176,10 @@ if (!at->is_active) return; + if (at->is_data_144) { + handle_d144(nr); + return; + } if (at->play_buffer) handle_play(at); if (!at->is_data) {