diff options
Diffstat (limited to 'openbsc/src/libbsc')
-rw-r--r-- | openbsc/src/libbsc/gsm_04_08_utils.c | 225 |
1 files changed, 0 insertions, 225 deletions
diff --git a/openbsc/src/libbsc/gsm_04_08_utils.c b/openbsc/src/libbsc/gsm_04_08_utils.c index 4901912f5..76a3b4ca0 100644 --- a/openbsc/src/libbsc/gsm_04_08_utils.c +++ b/openbsc/src/libbsc/gsm_04_08_utils.c @@ -38,10 +38,6 @@ #include <openbsc/signal.h> #include <openbsc/bsc_api.h> -/* should ip.access BTS use direct RTP streams between each other (1), - * or should OpenBSC always act as RTP relay/proxy in between (0) ? */ -int ipacc_rtp_direct = 1; - static int gsm48_sendmsg(struct msgb *msg) { if (msg->lchan) @@ -50,170 +46,6 @@ static int gsm48_sendmsg(struct msgb *msg) msg->l3h = msg->data; return rsl_data_request(msg, 0); } - -/* Section 9.1.8 / Table 9.9 */ -struct chreq { - uint8_t val; - uint8_t mask; - enum chreq_type type; -}; - -/* If SYSTEM INFORMATION TYPE 4 NECI bit == 1 */ -static const struct chreq chreq_type_neci1[] = { - { 0xa0, 0xe0, CHREQ_T_EMERG_CALL }, - { 0xc0, 0xe0, CHREQ_T_CALL_REEST_TCH_F }, - { 0x68, 0xfc, CHREQ_T_CALL_REEST_TCH_H }, - { 0x6c, 0xfc, CHREQ_T_CALL_REEST_TCH_H_DBL }, - { 0xe0, 0xe0, CHREQ_T_TCH_F }, - { 0x40, 0xf0, CHREQ_T_VOICE_CALL_TCH_H }, - { 0x50, 0xf0, CHREQ_T_DATA_CALL_TCH_H }, - { 0x00, 0xf0, CHREQ_T_LOCATION_UPD }, - { 0x10, 0xf0, CHREQ_T_SDCCH }, - { 0x80, 0xe0, CHREQ_T_PAG_R_ANY_NECI1 }, - { 0x20, 0xf0, CHREQ_T_PAG_R_TCH_F }, - { 0x30, 0xf0, CHREQ_T_PAG_R_TCH_FH }, - { 0x67, 0xff, CHREQ_T_LMU }, - { 0x60, 0xf9, CHREQ_T_RESERVED_SDCCH }, - { 0x61, 0xfb, CHREQ_T_RESERVED_SDCCH }, - { 0x63, 0xff, CHREQ_T_RESERVED_SDCCH }, - { 0x7f, 0xff, CHREQ_T_RESERVED_IGNORE }, -}; - -/* If SYSTEM INFORMATION TYPE 4 NECI bit == 0 */ -static const struct chreq chreq_type_neci0[] = { - { 0xa0, 0xe0, CHREQ_T_EMERG_CALL }, - { 0xc0, 0xe0, CHREQ_T_CALL_REEST_TCH_H }, - { 0xe0, 0xe0, CHREQ_T_TCH_F }, - { 0x50, 0xf0, CHREQ_T_DATA_CALL_TCH_H }, - { 0x00, 0xe0, CHREQ_T_LOCATION_UPD }, - { 0x80, 0xe0, CHREQ_T_PAG_R_ANY_NECI0 }, - { 0x20, 0xf0, CHREQ_T_PAG_R_TCH_F }, - { 0x30, 0xf0, CHREQ_T_PAG_R_TCH_FH }, - { 0x67, 0xff, CHREQ_T_LMU }, - { 0x60, 0xf9, CHREQ_T_RESERVED_SDCCH }, - { 0x61, 0xfb, CHREQ_T_RESERVED_SDCCH }, - { 0x63, 0xff, CHREQ_T_RESERVED_SDCCH }, - { 0x7f, 0xff, CHREQ_T_RESERVED_IGNORE }, -}; - -static const enum gsm_chan_t ctype_by_chreq[] = { - [CHREQ_T_EMERG_CALL] = GSM_LCHAN_TCH_F, - [CHREQ_T_CALL_REEST_TCH_F] = GSM_LCHAN_TCH_F, - [CHREQ_T_CALL_REEST_TCH_H] = GSM_LCHAN_TCH_H, - [CHREQ_T_CALL_REEST_TCH_H_DBL] = GSM_LCHAN_TCH_H, - [CHREQ_T_SDCCH] = GSM_LCHAN_SDCCH, - [CHREQ_T_TCH_F] = GSM_LCHAN_TCH_F, - [CHREQ_T_VOICE_CALL_TCH_H] = GSM_LCHAN_TCH_H, - [CHREQ_T_DATA_CALL_TCH_H] = GSM_LCHAN_TCH_H, - [CHREQ_T_LOCATION_UPD] = GSM_LCHAN_SDCCH, - [CHREQ_T_PAG_R_ANY_NECI1] = GSM_LCHAN_SDCCH, - [CHREQ_T_PAG_R_ANY_NECI0] = GSM_LCHAN_SDCCH, - [CHREQ_T_PAG_R_TCH_F] = GSM_LCHAN_TCH_F, - [CHREQ_T_PAG_R_TCH_FH] = GSM_LCHAN_TCH_F, - [CHREQ_T_LMU] = GSM_LCHAN_SDCCH, - [CHREQ_T_RESERVED_SDCCH] = GSM_LCHAN_SDCCH, - [CHREQ_T_RESERVED_IGNORE] = GSM_LCHAN_UNKNOWN, -}; - -static const enum gsm_chreq_reason_t reason_by_chreq[] = { - [CHREQ_T_EMERG_CALL] = GSM_CHREQ_REASON_EMERG, - [CHREQ_T_CALL_REEST_TCH_F] = GSM_CHREQ_REASON_CALL, - [CHREQ_T_CALL_REEST_TCH_H] = GSM_CHREQ_REASON_CALL, - [CHREQ_T_CALL_REEST_TCH_H_DBL] = GSM_CHREQ_REASON_CALL, - [CHREQ_T_SDCCH] = GSM_CHREQ_REASON_OTHER, - [CHREQ_T_TCH_F] = GSM_CHREQ_REASON_OTHER, - [CHREQ_T_VOICE_CALL_TCH_H] = GSM_CHREQ_REASON_CALL, - [CHREQ_T_DATA_CALL_TCH_H] = GSM_CHREQ_REASON_OTHER, - [CHREQ_T_LOCATION_UPD] = GSM_CHREQ_REASON_LOCATION_UPD, - [CHREQ_T_PAG_R_ANY_NECI1] = GSM_CHREQ_REASON_PAG, - [CHREQ_T_PAG_R_ANY_NECI0] = GSM_CHREQ_REASON_PAG, - [CHREQ_T_PAG_R_TCH_F] = GSM_CHREQ_REASON_PAG, - [CHREQ_T_PAG_R_TCH_FH] = GSM_CHREQ_REASON_PAG, - [CHREQ_T_LMU] = GSM_CHREQ_REASON_OTHER, - [CHREQ_T_RESERVED_SDCCH] = GSM_CHREQ_REASON_OTHER, - [CHREQ_T_RESERVED_IGNORE] = GSM_CHREQ_REASON_OTHER, -}; - -/* verify that the two tables match */ -osmo_static_assert(sizeof(ctype_by_chreq) == - sizeof(((struct gsm_network *) NULL)->ctype_by_chreq), assert_size); - -/* - * Update channel types for request based on policy. E.g. in the - * case of a TCH/H network/bsc use TCH/H for the emergency calls, - * for early assignment assign a SDCCH and some other options. - */ -void gsm_net_update_ctype(struct gsm_network *network) -{ - /* copy over the data */ - memcpy(network->ctype_by_chreq, ctype_by_chreq, sizeof(ctype_by_chreq)); - - /* - * Use TCH/H for emergency calls when this cell allows TCH/H. Maybe it - * is better to iterate over the BTS/TRX and check if no TCH/F is available - * and then set it to TCH/H. - */ - if (network->neci) - network->ctype_by_chreq[CHREQ_T_EMERG_CALL] = GSM_LCHAN_TCH_H; - - if (network->pag_any_tch) { - if (network->neci) { - network->ctype_by_chreq[CHREQ_T_PAG_R_ANY_NECI0] = GSM_LCHAN_TCH_H; - network->ctype_by_chreq[CHREQ_T_PAG_R_ANY_NECI1] = GSM_LCHAN_TCH_H; - } else { - network->ctype_by_chreq[CHREQ_T_PAG_R_ANY_NECI0] = GSM_LCHAN_TCH_F; - network->ctype_by_chreq[CHREQ_T_PAG_R_ANY_NECI1] = GSM_LCHAN_TCH_F; - } - } -} - -enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *network, uint8_t ra) -{ - int i; - int length; - const struct chreq *chreq; - - if (network->neci) { - chreq = chreq_type_neci1; - length = ARRAY_SIZE(chreq_type_neci1); - } else { - chreq = chreq_type_neci0; - length = ARRAY_SIZE(chreq_type_neci0); - } - - - for (i = 0; i < length; i++) { - const struct chreq *chr = &chreq[i]; - if ((ra & chr->mask) == chr->val) - return network->ctype_by_chreq[chr->type]; - } - LOGP(DRR, LOGL_ERROR, "Unknown CHANNEL REQUEST RQD 0x%02x\n", ra); - return GSM_LCHAN_SDCCH; -} - -int get_reason_by_chreq(uint8_t ra, int neci) -{ - int i; - int length; - const struct chreq *chreq; - - if (neci) { - chreq = chreq_type_neci1; - length = ARRAY_SIZE(chreq_type_neci1); - } else { - chreq = chreq_type_neci0; - length = ARRAY_SIZE(chreq_type_neci0); - } - - for (i = 0; i < length; i++) { - const struct chreq *chr = &chreq[i]; - if ((ra & chr->mask) == chr->val) - return reason_by_chreq[chr->type]; - } - LOGP(DRR, LOGL_ERROR, "Unknown CHANNEL REQUEST REASON 0x%02x\n", ra); - return GSM_CHREQ_REASON_OTHER; -} - static void mr_config_for_ms(struct gsm_lchan *lchan, struct msgb *msg) { if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) @@ -258,30 +90,6 @@ int send_siemens_mrpci(struct gsm_lchan *lchan, return rsl_siemens_mrpci(lchan, &mrpci); } -int gsm48_extract_mi(uint8_t *classmark2_lv, int length, char *mi_string, uint8_t *mi_type) -{ - /* Check the size for the classmark */ - if (length < 1 + *classmark2_lv) - return -1; - - uint8_t *mi_lv = classmark2_lv + *classmark2_lv + 1; - if (length < 2 + *classmark2_lv + mi_lv[0]) - return -2; - - *mi_type = mi_lv[1] & GSM_MI_TYPE_MASK; - return gsm48_mi_to_string(mi_string, GSM48_MI_SIZE, mi_lv+1, *mi_lv); -} - -int gsm48_paging_extract_mi(struct gsm48_pag_resp *resp, int length, - char *mi_string, uint8_t *mi_type) -{ - static const uint32_t classmark_offset = - offsetof(struct gsm48_pag_resp, classmark2); - uint8_t *classmark2_lv = (uint8_t *) &resp->classmark2; - return gsm48_extract_mi(classmark2_lv, length - classmark_offset, - mi_string, mi_type); -} - int gsm48_handle_paging_resp(struct gsm_subscriber_connection *conn, struct msgb *msg, struct gsm_subscriber *subscr) { @@ -645,39 +453,6 @@ int gsm48_parse_meas_rep(struct gsm_meas_rep *rep, struct msgb *msg) return 0; } -struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value) -{ - struct msgb *msg; - struct gsm48_hdr *gh; - - msg = gsm48_msgb_alloc(); - if (!msg) - return NULL; - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); - gh->proto_discr = GSM48_PDISC_MM; - gh->msg_type = GSM48_MT_MM_CM_SERV_REJ; - gh->data[0] = value; - - return msg; -} - -struct msgb *gsm48_create_loc_upd_rej(uint8_t cause) -{ - struct gsm48_hdr *gh; - struct msgb *msg; - - msg = gsm48_msgb_alloc(); - if (!msg) - return NULL; - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); - gh->proto_discr = GSM48_PDISC_MM; - gh->msg_type = GSM48_MT_MM_LOC_UPD_REJECT; - gh->data[0] = cause; - return msg; -} - /* 9.2.5 CM service accept */ int gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn) { |