diff options
-rw-r--r-- | include/openbsc/abis_rsl.h | 39 | ||||
-rw-r--r-- | include/openbsc/debug.h | 2 | ||||
-rw-r--r-- | include/openbsc/tlv.h | 18 | ||||
-rw-r--r-- | src/abis_nm.c | 21 | ||||
-rw-r--r-- | src/abis_rsl.c | 56 | ||||
-rw-r--r-- | src/bsc_hack.c | 19 | ||||
-rw-r--r-- | src/gsm_04_08.c | 2 | ||||
-rw-r--r-- | src/gsm_data.c | 2 | ||||
-rw-r--r-- | src/misdn.c | 6 | ||||
-rw-r--r-- | src/msgb.c | 1 |
10 files changed, 137 insertions, 29 deletions
diff --git a/include/openbsc/abis_rsl.h b/include/openbsc/abis_rsl.h index cbbb797fb..219fdd3db 100644 --- a/include/openbsc/abis_rsl.h +++ b/include/openbsc/abis_rsl.h @@ -244,6 +244,45 @@ struct rsl_ie_chan_ident { #endif } __attribute__ ((packed)); +/* Chapter 9.3.26 */ +#define RSL_ERRCLS_NORMAL 0x00 +#define RSL_ERRCLS_RESOURCE_UNAVAIL 0x20 +#define RSL_ERRCLS_SERVICE_UNAVAIL 0x30 +#define RSL_ERRCLS_SERVICE_UNIMPL 0x40 +#define RSL_ERRCLS_INVAL_MSG 0x50 +#define RSL_ERRCLS_PROTO_ERROR 0x60 +#define RSL_ERRCLS_INTERWORKING 0x70 + +#define RSL_ERR_RADIO_IF_FAIL 0x00 +#define RSL_ERR_RADIO_LINK_FAIL 0x01 +#define RSL_ERR_HANDOVER_ACC_FAIL 0x02 +#define RSL_ERR_TALKER_ACC_FAIL 0x03 +#define RSL_ERR_OM_INTERVENTION 0x07 +#define RSL_ERR_EQUIPMENT_FAIL 0x20 +#define RSL_ERR_RR_UNAVAIL 0x21 +#define RSL_ERR_TERR_CH_FAIL 0x22 +#define RSL_ERR_CCCH_OVERLOAD 0x23 +#define RSL_ERR_ACCH_OVERLOAD 0x24 +#define RSL_ERR_PROCESSOR_OVERLOAD 0x25 +#define RSL_ERR_RES_UNAVAIL 0x2f +#define RSL_ERR_TRANSC_UNAVAIL 0x30 +#define RSL_ERR_SERV_OPT_UNAVAIL 0x3f +#define RSL_ERR_ENCR_UNIMPL 0x40 +#define RSL_ERR_SEV_OPT_UNIMPL 0x4f +#define RSL_ERR_RCH_ALR_ACTV_ALLOC 0x50 +#define RSL_ERR_INVALID_MESSAGE 0x5f +#define RSL_ERR_MSG_DISCR 0x60 +#define RSL_ERR_MSG_TYPE 0x61 +#define RSL_ERR_MSG_SEQA 0x62 +#define RSL_ERR_IE_ERROR 0x63 +#define RSL_ERR_MAND_IE_ERROR 0x64 +#define RSL_ERR_OPT_IE_ERROR 0x65 +#define RSL_ERR_IE_NONEXIST 0x66 +#define RSL_ERR_IE_LENGTH 0x67 +#define RSL_ERR_IE_CONTENT 0x68 +#define RSL_ERR_PROTO 0x6f +#define RSL_ERR_INTERWORKING 0x7f + /* Chapter 9.3.30 */ #define RSL_SYSTEM_INFO_8 0x00 #define RSL_SYSTEM_INFO_1 0x01 diff --git a/include/openbsc/debug.h b/include/openbsc/debug.h index 02ae699c4..b95b1a7d4 100644 --- a/include/openbsc/debug.h +++ b/include/openbsc/debug.h @@ -17,6 +17,6 @@ #define DEBUGP(xss, fmt, args...) #endif -void debugp(int subsys, char *file, int line, const char *format, ...); +void debugp(unsigned int subsys, char *file, int line, const char *format, ...); #endif /* _DEBUG_H */ diff --git a/include/openbsc/tlv.h b/include/openbsc/tlv.h index 4c007725d..38ca81150 100644 --- a/include/openbsc/tlv.h +++ b/include/openbsc/tlv.h @@ -6,6 +6,7 @@ #define TLV_GROSS_LEN(x) (x+2) #define TLV16_GROSS_LEN(x) ((2*x)+2) +#define TL16V_GROSS_LEN(x) (x+3) static inline u_int8_t *tlv_put(u_int8_t *buf, u_int8_t tag, u_int8_t len, const u_int8_t *val) @@ -25,12 +26,29 @@ static inline u_int8_t *tlv16_put(u_int8_t *buf, u_int8_t tag, u_int8_t len, return buf + len*2; } +static inline u_int8_t *tl16v_put(u_int8_t *buf, u_int8_t tag, u_int16_t len, + const u_int8_t *val) +{ + *buf++ = tag; + *buf++ = len >> 8; + *buf++ = len & 0xff; + memcpy(buf, val, len); + return buf + len*2; +} + static inline u_int8_t *msgb_tlv16_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int16_t *val) { u_int8_t *buf = msgb_put(msg, TLV16_GROSS_LEN(len)); return tlv16_put(buf, tag, len, val); } +static inline u_int8_t *msgb_tl16v_put(struct msgb *msg, u_int8_t tag, u_int16_t len, + const u_int8_t *val) +{ + u_int8_t *buf = msgb_put(msg, TL16V_GROSS_LEN(len)); + return tl16v_put(buf, tag, len, val); +} + static inline u_int8_t *tv_put(u_int8_t *buf, u_int8_t tag, u_int8_t val) { diff --git a/src/abis_nm.c b/src/abis_nm.c index e1a641b53..52a5a52e6 100644 --- a/src/abis_nm.c +++ b/src/abis_nm.c @@ -122,7 +122,7 @@ static void fill_om_fom_hdr(struct abis_om_hdr *oh, u_int8_t len, struct abis_om_fom_hdr *foh = (struct abis_om_fom_hdr *) oh->data; - fill_om_hdr(oh, len); + fill_om_hdr(oh, len+sizeof(*foh)); foh->msg_type = msg_type; foh->obj_class = obj_class; foh->obj_inst.bts_nr = bts_nr; @@ -183,6 +183,7 @@ int abis_nm_rcvmsg(struct msgb *msg) int rc; struct abis_om_hdr *oh = msgb_l2(msg); unsigned int l2_len = msg->tail - (u_int8_t *)msgb_l2(msg); + unsigned int hlen = sizeof(*oh) + sizeof(struct abis_om_fom_hdr); /* Various consistency checks */ if (oh->placement != ABIS_OM_PLACEMENT_ONLY) { @@ -195,14 +196,15 @@ int abis_nm_rcvmsg(struct msgb *msg) oh->sequence); return -EINVAL; } - if (oh->length + sizeof(*oh) > l2_len) { +#if 0 + if (oh->length + hlen > l2_len) { fprintf(stderr, "ABIS OML truncated message (%u > %u)\n", oh->length + sizeof(*oh), l2_len); return -EINVAL; } - if (oh->length + sizeof(*oh) < l2_len) - fprintf(stderr, "ABIS OML message with extra trailer?!?\n"); - + if (oh->length + hlen < l2_len) + fprintf(stderr, "ABIS OML message with extra trailer?!? (oh->len=%d, sizeof_oh=%d l2_len=%d\n", oh->length, sizeof(*oh), l2_len); +#endif msg->l3h = (unsigned char *)oh + sizeof(*oh); switch (oh->mdisc) { @@ -295,7 +297,7 @@ int abis_nm_establish_tei(struct gsm_bts *bts, u_int8_t trx_nr, struct abis_om_hdr *oh; struct abis_nm_channel *ch; u_int8_t *tei_attr; - u_int8_t len = 2 + sizeof(*ch); + u_int8_t len = sizeof(*ch) + 2; struct msgb *msg = nm_msgb_alloc(); oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE); @@ -320,7 +322,7 @@ int abis_nm_conn_terr_sign(struct gsm_bts_trx *trx, struct msgb *msg = nm_msgb_alloc(); oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE); - fill_om_fom_hdr(oh, sizeof(*ch), NM_MT_CONN_TERR_SIGN, + fill_om_fom_hdr(oh, sizeof(*oh), NM_MT_CONN_TERR_SIGN, NM_OC_RADIO_CARRIER, bts->bts_nr, trx->nr, 0xff); ch = (struct abis_nm_channel *) msgb_put(msg, sizeof(*ch)); @@ -370,9 +372,10 @@ int abis_nm_set_channel_attr(struct gsm_bts_trx_ts *ts, u_int8_t chan_comb) u_int16_t arfcn = htons(ts->trx->arfcn); u_int8_t zero = 0x00; struct msgb *msg = nm_msgb_alloc(); + u_int8_t len = 4 + 2 + 2 + 2 + 2 +3; oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE); - fill_om_fom_hdr(oh, sizeof(*oh), NM_MT_SET_CHAN_ATTR, + fill_om_fom_hdr(oh, len, NM_MT_SET_CHAN_ATTR, NM_OC_BASEB_TRANSC, bts->bts_nr, ts->trx->nr, ts->nr); /* FIXME: don't send ARFCN list, hopping sequence, mAIO, ...*/ @@ -407,7 +410,7 @@ static int __simple_cmd(struct gsm_bts *bts, u_int8_t msg_type) struct msgb *msg = nm_msgb_alloc(); oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE); - fill_om_fom_hdr(oh, sizeof(*oh), msg_type, NM_OC_SITE_MANAGER, + fill_om_fom_hdr(oh, 0, msg_type, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff); return abis_nm_sendmsg(bts, msg); diff --git a/src/abis_rsl.c b/src/abis_rsl.c index 257b118b2..df34929ac 100644 --- a/src/abis_rsl.c +++ b/src/abis_rsl.c @@ -247,7 +247,7 @@ int rsl_sacch_filling(struct gsm_bts *bts, u_int8_t type, ch->msg_type = RSL_MT_SACCH_FILL; msgb_tv_put(msg, RSL_IE_SYSINFO_TYPE, type); - msgb_tlv_put(msg, RSL_IE_L3_INFO, len, data); + msgb_tl16v_put(msg, RSL_IE_L3_INFO, len, data); msg->trx = bts->c0; @@ -275,11 +275,13 @@ int rsl_chan_activate(struct gsm_bts *bts, u_int8_t chan_nr, msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(*chan_mode), (u_int8_t *) chan_mode); msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4, - (u_int8_t *) &chan_ident); + (u_int8_t *) chan_ident); /* FIXME: this shoould be optional */ +#if 0 msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1, (u_int8_t *) &encr_info); msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power); +#endif msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power); msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta); @@ -313,9 +315,9 @@ int rsl_chan_activate_tch_f(struct gsm_bts_trx_ts *ts) return rsl_chan_activate(ts->trx->bts, chan_nr, 0x01, &cm, &ci, 0x01, 0x0f, 0x00); } -int rsl_chan_activate_sdcch(struct gsm_bts_trx_ts *ts) +int rsl_chan_activate_sdcch4(struct gsm_bts_trx_ts *ts, int subslot) { - u_int8_t chan_nr = rsl_enc_chan_nr(RSL_CHAN_SDCCH4_ACCH, 0, ts->nr); + u_int8_t chan_nr = rsl_enc_chan_nr(RSL_CHAN_SDCCH4_ACCH, subslot, ts->nr); u_int16_t arfcn = ts->trx->arfcn; struct rsl_ie_chan_mode cm; struct rsl_ie_chan_ident ci; @@ -393,6 +395,7 @@ int rsl_paging_cmd_imsi(struct gsm_bts *bts, u_int8_t chan_needed, const char *i } #endif +/* Chapter 8.5.6 */ int rsl_imm_assign_cmd(struct gsm_bts *bts, u_int8_t len, u_int8_t *val) { struct msgb *msg = rsl_msgb_alloc(); @@ -437,6 +440,17 @@ int rsl_data_request(struct msgb *msg, u_int8_t link_id) return abis_rsl_sendmsg(msg); } +/* Chapter 8.4.2: Channel Activate Acknowledge */ +static int rsl_rx_chan_act_ack(struct msgb *msg) +{ + struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg); + + /* BTS has confirmed channel activation, we now need + * to assign the activated channel to the MS */ + + +} + static int abis_rsl_rx_dchan(struct msgb *msg) { struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg); @@ -447,6 +461,7 @@ static int abis_rsl_rx_dchan(struct msgb *msg) switch (rslh->c.msg_type) { case RSL_MT_CHAN_ACTIV_ACK: DEBUGP(DRSL, "rsl_rx_dchan: Channel Activate ACK\n"); + rc = rsl_rx_chan_act_ack(msg); break; case RSL_MT_CHAN_ACTIV_NACK: DEBUGP(DRSL, "rsl_rx_dchan: Channel Activate NACK\n"); @@ -479,17 +494,34 @@ static int abis_rsl_rx_dchan(struct msgb *msg) return rc; } +static int rsl_rx_error_rep(struct msgb *msg) +{ + struct abis_rsl_common_hdr *rslh = msgb_l2(msg); + u_int8_t cause_len; + + if (rslh->data[0] != RSL_IE_CAUSE) + return -EINVAL; + + cause_len = rslh->data[1]; + printf(stdout, "RSL ERROR REPORT, Cause "); + hexdump(&rslh->data[2], cause_len); + + return 0; +} + static int abis_rsl_rx_trx(struct msgb *msg) { - struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ; + struct abis_rsl_common_hdr *rslh = msgb_l2(msg); int rc = 0; switch (rslh->msg_type) { + case RSL_MT_ERROR_REPORT: + rc = rsl_rx_error_rep(msg); + break; case RSL_MT_RF_RES_IND: /* interference on idle channels of TRX */ case RSL_MT_OVERLOAD: /* indicate CCCH / ACCH / processor overload */ - case RSL_MT_ERROR_REPORT: fprintf(stderr, "Unimplemented Abis RSL TRX message type 0x%02x\n", rslh->msg_type); break; @@ -504,7 +536,7 @@ static int abis_rsl_rx_trx(struct msgb *msg) /* MS has requested a channel on the RACH */ static int rsl_rx_chan_rqd(struct msgb *msg) { - struct gsm_bts *bts = msg->bts_link->bts; + struct gsm_bts *bts = msg->trx->bts; struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg); struct gsm48_req_ref *rqd_ref; struct gsm48_imm_ass ia; @@ -546,8 +578,8 @@ static int rsl_rx_chan_rqd(struct msgb *msg) arfcn, ts_number, subch, lchan->type); /* send CHANNEL ACTIVATION on RSL to BTS */ - if (lchan->ts->pchan == GSM_PCHAN_SDCCH8_SACCH8C) - rsl_chan_activate_sdcch(lchan->ts); + if (lchan->ts->pchan == GSM_PCHAN_CCCH_SDCCH4) + rsl_chan_activate_sdcch4(lchan->ts, subch); else rsl_chan_activate_tch_f(lchan->ts); @@ -557,7 +589,7 @@ static int rsl_rx_chan_rqd(struct msgb *msg) ia.proto_discr = GSM48_PDISC_RR; ia.msg_type = GSM48_MT_RR_IMM_ASS; ia.page_mode = GSM48_PM_NORMAL; - ia.chan_desc.chan_nr = rsl_enc_chan_nr(lchan->ts->pchan, subch, ts_number); + ia.chan_desc.chan_nr = rsl_enc_chan_nr(RSL_CHAN_SDCCH4_ACCH, subch, ts_number); ia.chan_desc.h0.h = 0; ia.chan_desc.h0.arfcn_high = arfcn >> 8; ia.chan_desc.h0.arfcn_low = arfcn & 0xff; @@ -618,13 +650,13 @@ static int abis_rsl_rx_rll(struct msgb *msg) case RSL_MT_DATA_IND: DEBUGP(DRLL, "DATA INDICATION\n"); /* FIXME: Verify L3 info element */ - msg->l3h = &rllh->data[2]; + msg->l3h = &rllh->data[3]; rc = gsm0408_rcvmsg(msg); break; case RSL_MT_EST_IND: DEBUGP(DRLL, "ESTABLISH INDICATION\n"); /* FIXME: Verify L3 info element */ - msg->l3h = &rllh->data[2]; + msg->l3h = &rllh->data[3]; rc = gsm0408_rcvmsg(msg); break; case RSL_MT_ERROR_IND: diff --git a/src/bsc_hack.c b/src/bsc_hack.c index b0d726573..384f25d4d 100644 --- a/src/bsc_hack.c +++ b/src/bsc_hack.c @@ -31,6 +31,7 @@ #include <openbsc/select.h> #include <openbsc/abis_rsl.h> #include <openbsc/abis_nm.h> +#include <openbsc/debug.h> /* global pointer to the gsm network data structure */ static struct gsm_network *gsmnet; @@ -252,6 +253,15 @@ static void bootstrap_om(struct gsm_bts *bts) /* begin DB transmission */ abis_nm_db_transmission(bts, 1); + /* end DB transmission */ + abis_nm_db_transmission(bts, 0); + + /* Reset BTS Site manager resource */ + abis_nm_reset_resource(bts); + + /* begin DB transmission */ + abis_nm_db_transmission(bts, 1); + abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/ abis_nm_raw_msg(bts, sizeof(msg_2), msg_2); /* set BTS attr */ abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */ @@ -533,7 +543,7 @@ static void bootstrap_rsl(struct gsm_bts *bts) set_system_infos(bts); /* FIXME: defer this until the channels are used */ - activate_traffic_channels(&bts->trx[0]); + //activate_traffic_channels(&bts->trx[0]); } static void mi_cb(int event, struct gsm_bts *bts) @@ -570,13 +580,18 @@ static int bootstrap_network(void) return 0; } -void debugp(int subsys, char *file, int line, const char *format, ...) +static unsigned int debug_mask = 0xffffffff & ~DMI; + +void debugp(unsigned int subsys, char *file, int line, const char *format, ...) { char *timestr; va_list ap; time_t tm; FILE *outfd = stderr; + if (!(debug_mask & subsys)) + return; + va_start(ap, format); tm = time(NULL); diff --git a/src/gsm_04_08.c b/src/gsm_04_08.c index 397f13118..212b4ad6b 100644 --- a/src/gsm_04_08.c +++ b/src/gsm_04_08.c @@ -200,7 +200,7 @@ int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int8_t *tmsi) static int mm_loc_upd_req(struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); - struct gsm_bts *bts = msg->bts_link->bts; + struct gsm_bts *bts = msg->trx->bts; struct gsm48_loc_upd_req *lu; struct gsm_subscriber *subscr; u_int8_t mi_type; diff --git a/src/gsm_data.c b/src/gsm_data.c index e5ba906b0..61f868214 100644 --- a/src/gsm_data.c +++ b/src/gsm_data.c @@ -76,6 +76,8 @@ struct gsm_network *gsm_network_init(unsigned int num_bts, u_int8_t country_code } bts->num_trx = 1; /* FIXME */ + bts->c0 = &bts->trx[0]; + bts->c0->ts[0].pchan = GSM_PCHAN_CCCH_SDCCH4; } return net; } diff --git a/src/misdn.c b/src/misdn.c index 366580c22..dfc3a6541 100644 --- a/src/misdn.c +++ b/src/misdn.c @@ -72,7 +72,7 @@ static struct mi_e1_handle *global_e1h; #define TEI_OML 25 #define TEI_RSL 1 -static void hexdump(unsigned char *buf, int len) +void hexdump(unsigned char *buf, int len) { int i; for (i = 0; i < len; i++) { @@ -169,9 +169,6 @@ static int handle_ts1_read(struct bsc_fd *bfd) case DL_DATA_IND: DEBUGP(DMI, "got DL_DATA_IND\n"); - /* FIXME: this stinks */ - msg->trx = e1h->bts->c0; - msg->l2h = msg->data + MISDN_HEADER_LEN; fprintf(stdout, "RX: "); @@ -243,6 +240,7 @@ static int handle_ts1_write(struct bsc_fd *bfd) sizeof(e1h->l2addr)); msgb_free(msg); usleep(100000); + //sleep(1); } return ret; diff --git a/src/msgb.c b/src/msgb.c index 249fed9b6..f039be003 100644 --- a/src/msgb.c +++ b/src/msgb.c @@ -30,6 +30,7 @@ struct msgb *msgb_alloc(u_int16_t size) if (!msg) return NULL; + memset(msg, 0, sizeof(*msg)+size); msg->data_len = size; msg->len = 0; |