diff options
-rw-r--r-- | include/osmo-bts/amr.h | 2 | ||||
-rw-r--r-- | include/osmo-bts/l1sap.h | 3 | ||||
-rw-r--r-- | include/osmo-bts/msg_utils.h | 7 | ||||
-rw-r--r-- | src/common/Makefile.am | 1 | ||||
-rw-r--r-- | src/common/amr.c | 9 | ||||
-rw-r--r-- | src/common/l1sap.c | 20 | ||||
-rw-r--r-- | src/common/msg_utils.c | 43 | ||||
-rw-r--r-- | src/osmo-bts-litecell15/tch.c | 77 | ||||
-rw-r--r-- | src/osmo-bts-octphy/l1_tch.c | 28 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/tch.c | 69 |
10 files changed, 94 insertions, 165 deletions
diff --git a/include/osmo-bts/amr.h b/include/osmo-bts/amr.h index ba66e4df..6bdc41fc 100644 --- a/include/osmo-bts/amr.h +++ b/include/osmo-bts/amr.h @@ -11,7 +11,7 @@ void amr_log_mr_conf(int ss, int logl, const char *pfx, int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc, const uint8_t *mr_conf, unsigned int len); - +int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, uint8_t cmi); unsigned int amr_get_initial_mode(struct gsm_lchan *lchan); #endif /* _OSMO_BTS_AMR_H */ diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index 1f8b2a5b..dd25161d 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -66,6 +66,9 @@ extern struct gsmtap_inst *gsmtap; extern uint32_t gsmtap_sapi_mask; extern uint8_t gsmtap_sapi_acch; +int add_l1sap_header(struct gsm_bts_trx *trx, struct msgb *rmsg, + struct gsm_lchan *lchan, uint8_t chan_nr, uint32_t fn); + #define msgb_l1sap_prim(msg) ((struct osmo_phsap_prim *)(msg)->l1h) int bts_check_for_first_ciphrd(struct gsm_lchan *lchan, diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index f63c0964..73f8c964 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -4,6 +4,10 @@ #pragma once +#include <osmo-bts/gsm_data.h> + +#include <stdbool.h> + struct msgb; /** @@ -16,5 +20,8 @@ enum { OML_MSG_TYPE_OSMO, }; +void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, + uint32_t fn, bool update); +bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn); int msg_verify_ipa_structure(struct msgb *msg); int msg_verify_oml_structure(struct msgb *msg); diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 8df65138..fbb65729 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -6,7 +6,6 @@ noinst_LIBRARIES = libbts.a libl1sched.a libbts_a_SOURCES = gsm_data_shared.c sysinfo.c logging.c abis.c oml.c bts.c \ rsl.c vty.c paging.c measurement.c amr.c lchan.c \ load_indication.c pcu_sock.c handover.c msg_utils.c \ - load_indication.c pcu_sock.c handover.c msg_utils.c \ tx_power.c bts_ctrl_commands.c bts_ctrl_lookup.c \ l1sap.c cbch.c power_control.c main.c phy_link.c diff --git a/src/common/amr.c b/src/common/amr.c index 80c5fb62..56ed4302 100644 --- a/src/common/amr.c +++ b/src/common/amr.c @@ -22,6 +22,15 @@ void amr_log_mr_conf(int ss, int logl, const char *pfx, LOGPC(ss, logl, "\n"); } +int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, uint8_t cmi) +{ + unsigned int i; + for (i = 0; i < amr_mrc->num_modes; i++) { + if (amr_mrc->bts_mode[i].mode == cmi) + return i; + } + return -EINVAL; +} /* parse a GSM 04.08 MultiRate Config IE (10.5.2.21aa) in a more * comfortable internal data structure */ diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 0af73436..0a6bc49d 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -104,6 +104,26 @@ struct msgb *l1sap_msgb_alloc(unsigned int l2_len) return msg; } +int add_l1sap_header(struct gsm_bts_trx *trx, struct msgb *rmsg, + struct gsm_lchan *lchan, uint8_t chan_nr, uint32_t fn) +{ + struct osmo_phsap_prim *l1sap; + + LOGP(DL1C, LOGL_DEBUG, "%s Rx -> RTP: %s\n", + gsm_lchan_name(lchan), osmo_hexdump(rmsg->data, rmsg->len)); + + rmsg->l2h = rmsg->data; + msgb_push(rmsg, sizeof(*l1sap)); + rmsg->l1h = rmsg->data; + l1sap = msgb_l1sap_prim(rmsg); + osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_TCH, PRIM_OP_INDICATION, + rmsg); + l1sap->u.tch.chan_nr = chan_nr; + l1sap->u.tch.fn = fn; + + return l1sap_up(trx, l1sap); +} + static int l1sap_tx_ciph_req(struct gsm_bts_trx *trx, uint8_t chan_nr, uint8_t downlink, uint8_t uplink) { diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index 841ffe61..6f42f73b 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -86,6 +86,49 @@ static int check_manuf(struct msgb *msg, struct abis_om_hdr *omh, size_t msg_siz return type; } +/* store the last SID frame in lchan context */ +void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, + uint32_t fn, bool update) +{ + size_t copy_len = OSMO_MIN(length + 1, + ARRAY_SIZE(lchan->tch.last_sid.buf)); + + lchan->tch.last_sid.len = copy_len; + lchan->tch.last_sid.fn = fn; + lchan->tch.last_sid.is_update = update; + + memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); +} + +static inline bool fn_chk(uint8_t *t, uint32_t fn) +{ + uint8_t i; + for (i = 0; i < ARRAY_SIZE(t); i++) + if (fn % 104 == t[i]) + return false; + return true; +} + +/*! \brief Check if TX scheduling is optional for a given FN in case of DTX + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] fn Frame Number for which we check scheduling + * \returns true if transmission can be omitted, false otherwise + */ +bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn) +{ + /* According to 3GPP TS 45.008 § 8.3: */ + uint8_t f[] = { 52, 53, 54, 55, 56, 57, 58, 59 }, + h0[] = { 0, 2, 4, 6, 52, 54, 56, 58 }, + h1[] = { 14, 16, 18, 20, 66, 68, 70, 72 }; + if (lchan->tch_mode == GSM48_CMODE_SPEECH_V1) { + if (lchan->type == GSM_LCHAN_TCH_F) + return fn_chk(f, fn); + else + return fn_chk(lchan->nr ? h1 : h0, fn); + } + return false; +} + /** * Return 0 in case the IPA structure is okay and in this * case the l2h will be set to the beginning of the data. diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c index add79519..ec43c107 100644 --- a/src/osmo-bts-litecell15/tch.c +++ b/src/osmo-bts-litecell15/tch.c @@ -42,6 +42,7 @@ #include <osmo-bts/logging.h> #include <osmo-bts/bts.h> #include <osmo-bts/gsm_data.h> +#include <osmo-bts/msg_utils.h> #include <osmo-bts/measurement.h> #include <osmo-bts/amr.h> #include <osmo-bts/l1sap.h> @@ -93,14 +94,6 @@ void osmo_nibble_shift_left_unal(uint8_t *out, const uint8_t *in, out[i] = (in[i] & 0xF) << 4; } - -#define GSM_FR_BITS 260 -#define GSM_EFR_BITS 244 - -#define GSM_FR_BYTES 33 /* TS 101318 Chapter 5.1: 260 bits + 4bit sig */ -#define GSM_HR_BYTES 14 /* TS 101318 Chapter 5.2: 112 bits, no sig */ -#define GSM_EFR_BYTES 31 /* TS 101318 Chapter 5.3: 244 bits + 4bit sig */ - static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len, struct gsm_lchan *lchan) { @@ -252,16 +245,6 @@ static struct msgb *l1_to_rtppayload_amr(uint8_t *l1_payload, uint8_t payload_le return msg; } -int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, uint8_t cmi) -{ - unsigned int i; - for (i = 0; i < amr_mrc->num_modes; i++) { - if (amr_mrc->bts_mode[i].mode == cmi) - return i; - } - return -EINVAL; -} - /*! \brief convert AMR from RTP payload to L1 format * \param[out] l1_payload payload part of L1 buffer * \param[in] rtp_payload pointer to RTP payload data @@ -526,23 +509,9 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) break; } - if (rmsg) { - struct osmo_phsap_prim *l1sap; - - LOGP(DL1C, LOGL_DEBUG, "%s Rx -> RTP: %s\n", - gsm_lchan_name(lchan), osmo_hexdump(rmsg->data, rmsg->len)); - - /* add l1sap header */ - rmsg->l2h = rmsg->data; - msgb_push(rmsg, sizeof(*l1sap)); - rmsg->l1h = rmsg->data; - l1sap = msgb_l1sap_prim(rmsg); - osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_TCH, PRIM_OP_INDICATION, rmsg); - l1sap->u.tch.chan_nr = chan_nr; - l1sap->u.tch.fn = data_ind->u32Fn; - - return l1sap_up(trx, l1sap); - } + if (rmsg) + return add_l1sap_header(trx, rmsg, lchan, chan_nr, + data_ind->u32Fn); return 0; @@ -553,30 +522,6 @@ err_payload_match: return -EINVAL; } -static inline bool fn_chk(uint8_t *t, uint32_t fn) -{ - uint8_t i; - for (i = 0; i < ARRAY_SIZE(t); i++) - if (fn % 104 == t[i]) - return false; - return true; -} - -static bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn) -{ - /* 3GPP TS 45.008 § 8.3 */ - uint8_t f[] = { 52, 53, 54, 55, 56, 57, 58, 59 }, - h0[] = { 0, 2, 4, 6, 52, 54, 56, 58 }, - h1[] = { 14, 16, 18, 20, 66, 68, 70, 72 }; - if (lchan->tch_mode == GSM48_CMODE_SPEECH_V1) { - if (lchan->type == GSM_LCHAN_TCH_F) - return fn_chk(f, fn); - else - return fn_chk(lchan->nr ? h1 : h0, fn); - } - return false; -} - static bool repeat_last_sid(struct gsm_lchan *lchan, struct msgb *msg) { GsmL1_Prim_t *l1p; @@ -598,20 +543,6 @@ static bool repeat_last_sid(struct gsm_lchan *lchan, struct msgb *msg) return false; } -/* store the last SID frame in lchan context */ -void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, - uint32_t fn, bool update) -{ - size_t copy_len = OSMO_MIN(length + 1, - ARRAY_SIZE(lchan->tch.last_sid.buf)); - - lchan->tch.last_sid.len = copy_len; - lchan->tch.last_sid.fn = fn; - lchan->tch.last_sid.is_update = update; - - memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); -} - struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn) { struct msgb *msg; diff --git a/src/osmo-bts-octphy/l1_tch.c b/src/osmo-bts-octphy/l1_tch.c index a0001612..af789802 100644 --- a/src/osmo-bts-octphy/l1_tch.c +++ b/src/osmo-bts-octphy/l1_tch.c @@ -38,13 +38,6 @@ #include "l1_if.h" -#define GSM_FR_BITS 260 -#define GSM_EFR_BITS 244 - -#define GSM_FR_BYTES 33 /* TS 101318 Chapter 5.1: 260 bits + 4bit sig */ -#define GSM_HR_BYTES 14 /* TS 101318 Chapter 5.2: 112 bits, no sig */ -#define GSM_EFR_BYTES 31 /* TS 101318 Chapter 5.3: 244 bits + 4bit sig */ - /* input octet-aligned, output not octet-aligned */ void osmo_nibble_shift_right(uint8_t *out, const uint8_t *in, unsigned int num_nibbles) @@ -298,24 +291,9 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, break; } - if (rmsg) { - struct osmo_phsap_prim *l1sap; - - LOGP(DL1C, LOGL_DEBUG, "%s Rx -> RTP: %s\n", - gsm_lchan_name(lchan), osmo_hexdump(rmsg->data, - rmsg->len)); - - /* add l1sap header */ - rmsg->l2h = rmsg->data; - msgb_push(rmsg, sizeof(*l1sap)); - rmsg->l1h = rmsg->data; - l1sap = msgb_l1sap_prim(rmsg); - osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_TCH, - PRIM_OP_INDICATION, rmsg); - l1sap->u.tch.chan_nr = chan_nr; - - return l1sap_up(trx, l1sap); - } + if (rmsg) + return add_l1sap_header(trx, rmsg, lchan, chan_nr, + data_ind->u32Fn); return 0; diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index e027408c..17469f00 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -39,6 +39,7 @@ #include <osmo-bts/logging.h> #include <osmo-bts/bts.h> #include <osmo-bts/gsm_data.h> +#include <osmo-bts/msg_utils.h> #include <osmo-bts/measurement.h> #include <osmo-bts/amr.h> #include <osmo-bts/l1sap.h> @@ -328,16 +329,6 @@ static struct msgb *l1_to_rtppayload_amr(uint8_t *l1_payload, uint8_t payload_le return msg; } -int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, uint8_t cmi) -{ - unsigned int i; - for (i = 0; i < amr_mrc->num_modes; i++) { - if (amr_mrc->bts_mode[i].mode == cmi) - return i; - } - return -EINVAL; -} - /*! \brief convert AMR from RTP payload to L1 format * \param[out] l1_payload payload part of L1 buffer * \param[in] rtp_payload pointer to RTP payload data @@ -622,23 +613,9 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) break; } - if (rmsg) { - struct osmo_phsap_prim *l1sap; - - LOGP(DL1C, LOGL_DEBUG, "%s Rx -> RTP: %s\n", - gsm_lchan_name(lchan), osmo_hexdump(rmsg->data, rmsg->len)); - - /* add l1sap header */ - rmsg->l2h = rmsg->data; - msgb_push(rmsg, sizeof(*l1sap)); - rmsg->l1h = rmsg->data; - l1sap = msgb_l1sap_prim(rmsg); - osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_TCH, PRIM_OP_INDICATION, rmsg); - l1sap->u.tch.chan_nr = chan_nr; - l1sap->u.tch.fn = data_ind->u32Fn; - - return l1sap_up(trx, l1sap); - } + if (rmsg) + return add_l1sap_header(trx, rmsg, lchan, chan_nr, + data_ind->u32Fn); return 0; @@ -649,30 +626,6 @@ err_payload_match: return -EINVAL; } -static inline bool fn_chk(uint8_t *t, uint32_t fn) -{ - uint8_t i; - for (i = 0; i < ARRAY_SIZE(t); i++) - if (fn % 104 == t[i]) - return false; - return true; -} - -static bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn) -{ - /* 3GPP TS 45.008 § 8.3 */ - uint8_t f[] = { 52, 53, 54, 55, 56, 57, 58, 59 }, - h0[] = { 0, 2, 4, 6, 52, 54, 56, 58 }, - h1[] = { 14, 16, 18, 20, 66, 68, 70, 72 }; - if (lchan->tch_mode == GSM48_CMODE_SPEECH_V1) { - if (lchan->type == GSM_LCHAN_TCH_F) - return fn_chk(f, fn); - else - return fn_chk(lchan->nr ? h1 : h0, fn); - } - return false; -} - static bool repeat_last_sid(struct gsm_lchan *lchan, struct msgb *msg) { GsmL1_Prim_t *l1p; @@ -694,20 +647,6 @@ static bool repeat_last_sid(struct gsm_lchan *lchan, struct msgb *msg) return false; } -/* store the last SID frame in lchan context */ -void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length, - uint32_t fn, bool update) -{ - size_t copy_len = OSMO_MIN(length + 1, - ARRAY_SIZE(lchan->tch.last_sid.buf)); - - lchan->tch.last_sid.len = copy_len; - lchan->tch.last_sid.fn = fn; - lchan->tch.last_sid.is_update = update; - - memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len); -} - struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn) { struct msgb *msg; |