diff options
Diffstat (limited to 'openbsc/src/gsm_04_08.c')
-rw-r--r-- | openbsc/src/gsm_04_08.c | 282 |
1 files changed, 4 insertions, 278 deletions
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index 46b447900..94f9ef4d4 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -49,18 +49,13 @@ #include <openbsc/talloc.h> #include <openbsc/transaction.h> -#define GSM48_ALLOC_SIZE 1024 -#define GSM48_ALLOC_HEADROOM 128 - #define GSM_MAX_FACILITY 128 #define GSM_MAX_SSVERSION 128 #define GSM_MAX_USERUSER 128 void *tall_locop_ctx; -/* 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; +extern int ipacc_rtp_direct; static const struct tlv_definition rsl_att_tlvdef = { .def = { @@ -158,73 +153,6 @@ static const char *cc_state_names[] = { "illegal state 31", }; -static const char *cc_msg_names[] = { - "unknown 0x00", - "ALERTING", - "CALL_PROC", - "PROGRESS", - "ESTAB", - "SETUP", - "ESTAB_CONF", - "CONNECT", - "CALL_CONF", - "START_CC", - "unknown 0x0a", - "RECALL", - "unknown 0x0c", - "unknown 0x0d", - "EMERG_SETUP", - "CONNECT_ACK", - "USER_INFO", - "unknown 0x11", - "unknown 0x12", - "MODIFY_REJECT", - "unknown 0x14", - "unknown 0x15", - "unknown 0x16", - "MODIFY", - "HOLD", - "HOLD_ACK", - "HOLD_REJ", - "unknown 0x1b", - "RETR", - "RETR_ACK", - "RETR_REJ", - "MODIFY_COMPL", - "unknown 0x20", - "unknown 0x21", - "unknown 0x22", - "unknown 0x23", - "unknown 0x24", - "DISCONNECT", - "unknown 0x26", - "unknown 0x27", - "unknown 0x28", - "unknown 0x29", - "RELEASE_COMPL", - "unknown 0x2b", - "unknown 0x2c", - "RELEASE", - "unknown 0x2e", - "unknown 0x2f", - "unknown 0x30", - "STOP_DTMF", - "STOP_DTMF_ACK", - "unknown 0x33", - "STATUS_ENQ", - "START_DTMF", - "START_DTMF_ACK", - "START_DTMF_REJ", - "unknown 0x38", - "CONG_CTRL", - "FACILITY", - "unknown 0x3b", - "STATUS", - "unknown 0x3c", - "NOTIFY", - "unknown 0x3f", -}; - static char strbuf[64]; static const char *rr_cause_name(u_int8_t cause) @@ -413,53 +341,6 @@ static int gsm0408_handle_lchan_signal(unsigned int subsys, unsigned int signal, return 0; } -static void to_bcd(u_int8_t *bcd, u_int16_t val) -{ - bcd[2] = val % 10; - val = val / 10; - bcd[1] = val % 10; - val = val / 10; - bcd[0] = val % 10; - val = val / 10; -} - -void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc, - u_int16_t mnc, u_int16_t lac) -{ - u_int8_t bcd[3]; - - to_bcd(bcd, mcc); - lai48->digits[0] = bcd[0] | (bcd[1] << 4); - lai48->digits[1] = bcd[2]; - - to_bcd(bcd, mnc); - /* FIXME: do we need three-digit MNC? See Table 10.5.3 */ -#if 0 - lai48->digits[1] |= bcd[2] << 4; - lai48->digits[2] = bcd[0] | (bcd[1] << 4); -#else - lai48->digits[1] |= 0xf << 4; - lai48->digits[2] = bcd[1] | (bcd[2] << 4); -#endif - - lai48->lac = htons(lac); -} - -#define TMSI_LEN 5 -#define MID_TMSI_LEN (TMSI_LEN + 2) - -int generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi) -{ - u_int32_t *tptr = (u_int32_t *) &buf[3]; - - buf[0] = GSM48_IE_MOBILE_ID; - buf[1] = TMSI_LEN; - buf[2] = 0xf0 | GSM_MI_TYPE_TMSI; - *tptr = htonl(tmsi); - - return 7; -} - static const char bcd_num_digits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '#', 'a', 'b', 'c', '\0' @@ -979,44 +860,6 @@ static int encode_more(struct msgb *msg) return 0; } -struct msgb *gsm48_msgb_alloc(void) -{ - return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM, - "GSM 04.08"); -} - -int gsm48_sendmsg(struct msgb *msg, struct gsm_trans *trans) -{ - struct gsm48_hdr *gh = (struct gsm48_hdr *) msg->data; - - /* if we get passed a transaction reference, do some common - * work that the caller no longer has to do */ - if (trans) { - gh->proto_discr = trans->protocol | (trans->transaction_id << 4); - msg->lchan = trans->lchan; - } - - if (msg->lchan) { - msg->trx = msg->lchan->ts->trx; - - if ((gh->proto_discr & GSM48_PDISC_MASK) == GSM48_PDISC_CC) - DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x) " - "Sending '%s' to MS.\n", msg->trx->bts->nr, - msg->trx->nr, msg->lchan->ts->nr, - gh->proto_discr & 0xf0, - cc_msg_names[gh->msg_type & 0x3f]); - else - DEBUGP(DCC, "(bts %d trx %d ts %d pd %02x) " - "Sending 0x%02x to MS.\n", msg->trx->bts->nr, - msg->trx->nr, msg->lchan->ts->nr, - gh->proto_discr, gh->msg_type); - } - - msg->l3h = msg->data; - - return rsl_data_request(msg, 0); -} - /* Chapter 9.2.14 : Send LOCATION UPDATING REJECT */ int gsm0408_loc_upd_rej(struct gsm_lchan *lchan, u_int8_t cause) { @@ -1055,7 +898,7 @@ int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int32_t tmsi) gsm0408_generate_lai(lai, bts->network->country_code, bts->network->network_code, bts->location_area_code); - mid = msgb_put(msg, MID_TMSI_LEN); + mid = msgb_put(msg, GSM48_MID_TMSI_LEN); generate_mid_from_tmsi(mid, tmsi); DEBUGP(DMM, "-> LOCATION UPDATE ACCEPT\n"); @@ -1091,7 +934,7 @@ static int mi_to_string(char *string, int str_len, u_int8_t *mi, int mi_len) break; case GSM_MI_TYPE_TMSI: /* Table 10.5.4.3, reverse generate_mid_from_tmsi */ - if (mi_len == TMSI_LEN && mi[0] == (0xf0 | GSM_MI_TYPE_TMSI)) { + if (mi_len == GSM48_TMSI_LEN && mi[0] == (0xf0 | GSM_MI_TYPE_TMSI)) { memcpy(&tmsi, &mi[1], 4); tmsi = ntohl(tmsi); return snprintf(string, str_len, "%u", tmsi); @@ -1891,30 +1734,6 @@ static int gsm0408_rcv_rr(struct msgb *msg) return rc; } -/* 7.1.7 and 9.1.7: RR CHANnel RELease */ -int gsm48_send_rr_release(struct gsm_lchan *lchan) -{ - struct msgb *msg = gsm48_msgb_alloc(); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - u_int8_t *cause; - - msg->lchan = lchan; - gh->proto_discr = GSM48_PDISC_RR; - gh->msg_type = GSM48_MT_RR_CHAN_REL; - - cause = msgb_put(msg, 1); - cause[0] = GSM48_RR_CAUSE_NORMAL; - - DEBUGP(DRR, "Sending Channel Release: Chan: Number: %d Type: %d\n", - lchan->nr, lchan->type); - - /* Send actual release request to MS */ - gsm48_sendmsg(msg, NULL); - /* FIXME: Start Timer T3109 */ - - /* Deactivate the SACCH on the BTS side */ - return rsl_deact_sacch(lchan); -} int gsm48_send_rr_app_info(struct gsm_lchan *lchan, u_int8_t apdu_id, u_int8_t apdu_len, u_int8_t *apdu) @@ -3756,7 +3575,7 @@ static int gsm0408_rcv_cc(struct msgb *msg) "Received '%s' from MS in state %d (%s)\n", lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, transaction_id, (lchan->subscr)?(lchan->subscr->extension):"-", - cc_msg_names[msg_type], trans?(trans->cc.state):0, + gsm0408_cc_msg_names[msg_type], trans?(trans->cc.state):0, cc_state_names[trans?(trans->cc.state):0]); /* Create transaction */ @@ -3827,99 +3646,6 @@ int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id) return rc; } -/* Section 9.1.8 / Table 9.9 */ -struct chreq { - u_int8_t val; - u_int8_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_SDCCH }, - { 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 }, - { 0x20, 0xf0, CHREQ_T_PAG_R_TCH_F }, - { 0x30, 0xf0, CHREQ_T_PAG_R_TCH_FH }, -}; - -/* 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 }, - { 0x20, 0xf0, CHREQ_T_PAG_R_TCH_F }, - { 0x30, 0xf0, CHREQ_T_PAG_R_TCH_FH }, -}; - -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] = GSM_LCHAN_SDCCH, - [CHREQ_T_PAG_R_TCH_F] = GSM_LCHAN_TCH_F, - [CHREQ_T_PAG_R_TCH_FH] = GSM_LCHAN_TCH_F, -}; - -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_OTHER, - [CHREQ_T_DATA_CALL_TCH_H] = GSM_CHREQ_REASON_OTHER, - [CHREQ_T_LOCATION_UPD] = GSM_CHREQ_REASON_LOCATION_UPD, - [CHREQ_T_PAG_R_ANY] = GSM_CHREQ_REASON_PAG, - [CHREQ_T_PAG_R_TCH_F] = GSM_CHREQ_REASON_PAG, - [CHREQ_T_PAG_R_TCH_FH] = GSM_CHREQ_REASON_PAG, -}; - -enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra) -{ - int i; - /* FIXME: determine if we set NECI = 0 in the BTS SI4 */ - - for (i = 0; i < ARRAY_SIZE(chreq_type_neci0); i++) { - const struct chreq *chr = &chreq_type_neci0[i]; - if ((ra & chr->mask) == chr->val) - return ctype_by_chreq[chr->type]; - } - fprintf(stderr, "Unknown CHANNEL REQUEST RQD 0x%02x\n", ra); - return GSM_LCHAN_SDCCH; -} - -enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra) -{ - int i; - /* FIXME: determine if we set NECI = 0 in the BTS SI4 */ - - for (i = 0; i < ARRAY_SIZE(chreq_type_neci0); i++) { - const struct chreq *chr = &chreq_type_neci0[i]; - if ((ra & chr->mask) == chr->val) - return reason_by_chreq[chr->type]; - } - fprintf(stderr, "Unknown CHANNEL REQUEST REASON 0x%02x\n", ra); - return GSM_CHREQ_REASON_OTHER; -} - /* dequeue messages to layer 4 */ int bsc_upqueue(struct gsm_network *net) { |