working state up to location update and classmark inquiry

This commit is contained in:
Harald Welte 2008-12-26 20:25:35 +00:00
parent 5d2f8eca60
commit 702d8707a9
10 changed files with 137 additions and 29 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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)
{

View File

@ -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);

View File

@ -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:

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;