* more extensive A-bis OML support

This commit is contained in:
Harald Welte 2009-02-13 02:41:40 +00:00
parent 7584aeac42
commit 34a9968baf
2 changed files with 132 additions and 17 deletions

View File

@ -208,8 +208,8 @@ enum abis_nm_obj_class {
NM_OC_SITE_MANAGER = 0x00,
NM_OC_BTS,
NM_OC_RADIO_CARRIER,
NM_OC_BASEB_TRANSC,
NM_OC_CHANNEL,
NM_OC_BASEB_TRANSC,
/* RFU: 05-FE */
NM_OC_BS11_A0 = 0xa0,
NM_OC_BS11_A3 = 0xa3,
@ -417,20 +417,9 @@ enum abis_bs11_phase {
BS11_STATE_LOAD_MBCCU = 0x92,
BS11_STATE_WAIT_MIN_CFG_2 = 0xA2,
BS11_STATE_NORMAL = 0x03,
BS11_STATE_ABIS_LOAD = 0x13,
};
/* FIXME: this is not correct, please parse this correctly */
struct abis_nm_bs11_state {
u_int8_t tag_f0;
u_int8_t len_f0;
u_int8_t phase;
u_int8_t mbccu;
u_int8_t ccu;
u_int8_t tag_f1;
u_int8_t len_f1;
u_int8_t abis_link;
} __attribute__((packed));
/* PUBLIC */
@ -449,6 +438,9 @@ extern int abis_nm_rcvmsg(struct msgb *msg);
//extern void abis_nm_fini(struct abis_nm_h *nmh);
int abis_nm_rx(struct msgb *msg);
int abis_nm_opstart(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0, u_int8_t i1, u_int8_t i2);
int abis_nm_chg_adm_state(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0,
u_int8_t i1, u_int8_t i2, u_int8_t adm_state);
int abis_nm_establish_tei(struct gsm_bts *bts, u_int8_t trx_nr,
u_int8_t e1_port, u_int8_t e1_timeslot, u_int8_t e1_subslot,
u_int8_t tei);
@ -458,6 +450,8 @@ int abis_nm_conn_terr_traf(struct gsm_bts_trx_ts *ts,
u_int8_t e1_port, u_int8_t e1_timeslot,
u_int8_t e1_subslot);
int abis_nm_set_channel_attr(struct gsm_bts_trx_ts *ts, u_int8_t chan_comb);
int abis_nm_sw_act_req_ack(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i1,
u_int8_t i2, u_int8_t i3, u_int8_t *attr, int att_len);
int abis_nm_raw_msg(struct gsm_bts *bts, int len, u_int8_t *msg);
int abis_nm_event_reports(struct gsm_bts *bts, int on);
int abis_nm_reset_resource(struct gsm_bts *bts);

View File

@ -68,7 +68,7 @@ static const enum abis_nm_msgtype sw_load_msgs[] = {
NM_MT_LOAD_ABORT,
NM_MT_LOAD_END_ACK,
NM_MT_LOAD_END_NACK,
NM_MT_SW_ACT_REQ,
//NM_MT_SW_ACT_REQ,
NM_MT_ACTIVATE_SW_ACK,
NM_MT_ACTIVATE_SW_NACK,
NM_MT_SW_ACTIVATED_REP,
@ -170,16 +170,47 @@ int abis_nm_sendmsg(struct gsm_bts *bts, struct msgb *msg)
static int abis_nm_rcvmsg_sw(struct msgb *mb);
const char *oc_names[] = {
[NM_OC_SITE_MANAGER] = "SITE MANAGER",
[NM_OC_BTS] = "BTS",
[NM_OC_RADIO_CARRIER] = "RADIO CARRIER",
[NM_OC_BASEB_TRANSC] = "BASEBAND TRANSCEIVER",
[NM_OC_CHANNEL] = "CHANNEL",
};
static const char *obj_class_name(u_int8_t oc)
{
if (oc >= ARRAY_SIZE(oc_names))
return "UNKNOWN";
return oc_names[oc];
}
static const char *opstate_name(u_int8_t os)
{
switch (os) {
case 1:
return "Disabled";
case 2:
return "Enabled";
case 0xff:
return "NULL";
default:
return "RFU";
}
}
static int abis_nm_rx_statechg_rep(struct msgb *mb)
{
struct abis_om_fom_hdr *foh = msgb_l3(mb);
u_int8_t *data = &foh->data[0];
DEBUGP(DNM, "STATE CHG: OC=%02x INST=(%02x,%02x,%02x) ",
foh->obj_class, foh->obj_inst.bts_nr, foh->obj_inst.trx_nr,
DEBUGP(DNM, "STATE CHG: OC=%s(%02x) INST=(%02x,%02x,%02x) ",
obj_class_name(foh->obj_class), foh->obj_class,
foh->obj_inst.bts_nr, foh->obj_inst.trx_nr,
foh->obj_inst.ts_nr);
if (*data++ == NM_ATT_OPER_STATE)
DEBUGPC(DNM, "OP_STATE=%02x ", *data++);
DEBUGPC(DNM, "OP_STATE=%s ", opstate_name(*data++));
if (*data++ == NM_ATT_AVAIL_STATUS) {
u_int8_t att_len = *data++;
while (att_len--)
@ -200,6 +231,9 @@ static int abis_nm_rcvmsg_report(struct msgb *mb)
case NM_MT_STATECHG_EVENT_REP:
return abis_nm_rx_statechg_rep(mb);
break;
case NM_MT_SW_ACTIVATED_REP:
DEBUGP(DNM, "Software Activated Report\n");
break;
};
DEBUGP(DNM, "reporting NM MT 0x%02x\n", mt);
@ -207,6 +241,46 @@ static int abis_nm_rcvmsg_report(struct msgb *mb)
return 0;
}
/* Activate the specified software into the BTS */
static int ipacc_sw_activate(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0, u_int8_t i1,
u_int8_t i2, u_int8_t *sw_desc, u_int8_t swdesc_len)
{
struct abis_om_hdr *oh;
struct msgb *msg = nm_msgb_alloc();
u_int8_t len = swdesc_len;
u_int8_t *trailer;
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
fill_om_fom_hdr(oh, len, NM_MT_ACTIVATE_SW, obj_class, i0, i1, i2);
trailer = msgb_put(msg, swdesc_len);
memcpy(trailer, sw_desc, swdesc_len);
return abis_nm_sendmsg(bts, msg);
}
static int abis_nm_rx_sw_act_req(struct msgb *mb)
{
struct abis_om_hdr *oh = msgb_l2(mb);
struct abis_om_fom_hdr *foh = msgb_l3(mb);
int ret;
DEBUGP(DNM, "Software Activate Request, ACKing and Activating\n");
ret = abis_nm_sw_act_req_ack(mb->trx->bts, foh->obj_class,
foh->obj_inst.bts_nr,
foh->obj_inst.trx_nr,
foh->obj_inst.ts_nr,
foh->data, oh->length-sizeof(*foh));
/* FIXME: properly parse attributes */
return ipacc_sw_activate(mb->trx->bts, foh->obj_class,
foh->obj_inst.bts_nr,
foh->obj_inst.trx_nr,
foh->obj_inst.ts_nr,
foh->data + oh->length-sizeof(*foh)-22, 22);
}
/* Receive a OML NM Message from BTS */
static int abis_nm_rcvmsg_fom(struct msgb *mb)
{
@ -240,6 +314,9 @@ static int abis_nm_rcvmsg_fom(struct msgb *mb)
#endif
switch (mt) {
case NM_MT_SW_ACT_REQ:
return abis_nm_rx_sw_act_req(mb);
break;
case NM_MT_BS11_LMT_SESSION:
DEBUGP(DNM, "LMT Event: \n");
break;
@ -871,6 +948,23 @@ int abis_nm_set_channel_attr(struct gsm_bts_trx_ts *ts, u_int8_t chan_comb)
return abis_nm_sendmsg(bts, msg);
}
int abis_nm_sw_act_req_ack(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i1,
u_int8_t i2, u_int8_t i3, u_int8_t *attr, int att_len)
{
struct abis_om_hdr *oh;
struct msgb *msg = nm_msgb_alloc();
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
fill_om_fom_hdr(oh, att_len, NM_MT_SW_ACT_REQ_ACK, obj_class, i1, i2, i3);
/* FIXME: don't send ARFCN list, hopping sequence, mAIO, ...*/
if (attr) {
u_int8_t *ptr = msgb_put(msg, att_len);
memcpy(ptr, attr, att_len);
}
return abis_nm_sendmsg(bts, msg);
}
int abis_nm_raw_msg(struct gsm_bts *bts, int len, u_int8_t *rawmsg)
{
struct msgb *msg = nm_msgb_alloc();
@ -898,6 +992,33 @@ static int __simple_cmd(struct gsm_bts *bts, u_int8_t msg_type)
return abis_nm_sendmsg(bts, msg);
}
/* Chapter 8.9.2 */
int abis_nm_opstart(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0, u_int8_t i1, u_int8_t i2)
{
struct abis_om_hdr *oh;
struct msgb *msg = nm_msgb_alloc();
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
fill_om_fom_hdr(oh, 0, NM_MT_OPSTART, obj_class, i0, i1, i2);
return abis_nm_sendmsg(bts, msg);
}
/* Chapter 8.8.5 */
int abis_nm_chg_adm_state(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0,
u_int8_t i1, u_int8_t i2, u_int8_t adm_state)
{
struct abis_om_hdr *oh;
struct msgb *msg = nm_msgb_alloc();
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
fill_om_fom_hdr(oh, 2, NM_MT_CHG_ADM_STATE, obj_class, i0, i1, i2);
msgb_tv_put(msg, NM_ATT_ADM_STATE, adm_state);
return abis_nm_sendmsg(bts, msg);
}
int abis_nm_event_reports(struct gsm_bts *bts, int on)
{
if (on == 0)