OM2000: Process MO STATE and ACCORDANCE INFO

This commit is contained in:
Harald Welte 2011-03-06 19:26:11 +01:00
parent 1edc2b4c85
commit e898ecc57b
1 changed files with 91 additions and 1 deletions

View File

@ -165,6 +165,7 @@ enum abis_om2k_msgtype {
};
enum abis_om2k_dei {
OM2K_DEI_ACCORDANCE_IND = 0x00,
OM2K_DEI_BCC = 0x06,
OM2K_DEI_BS_AG_BKS_RES = 0x07,
OM2K_DEI_BSIC = 0x09,
@ -233,6 +234,7 @@ enum abis_om2k_dei {
const struct tlv_definition om2k_att_tlvdef = {
.def = {
[OM2K_DEI_ACCORDANCE_IND] = { TLV_TYPE_TV },
[OM2K_DEI_BCC] = { TLV_TYPE_TV },
[OM2K_DEI_BS_AG_BKS_RES] = { TLV_TYPE_TV },
[OM2K_DEI_BSIC] = { TLV_TYPE_TV },
@ -634,6 +636,11 @@ static int abis_om2k_tlv_parse(struct tlv_parsed *tp, const u_int8_t *buf, int l
return tlv_parse(tp, &om2k_att_tlvdef, buf, len, 0, 0);
}
static int abis_om2k_msg_tlv_parse(struct tlv_parsed *tp, struct abis_om2k_hdr *oh)
{
return abis_om2k_tlv_parse(tp, oh->data, oh->om.length - 6);
}
static char *om2k_mo_name(const struct abis_om2k_mo *mo)
{
static char mo_buf[64];
@ -1171,6 +1178,22 @@ const struct value_string om2k_result_strings[] = {
{ 0, NULL }
};
const struct value_string om2k_accordance_strings[] = {
{ 0x00, "Data according to request" },
{ 0x01, "Data not according to request" },
{ 0x02, "Inconsistent MO data" },
{ 0x03, "Capability constraint violation" },
{ 0, NULL }
};
const struct value_string om2k_mostate_vals[] = {
{ 0x00, "RESET" },
{ 0x01, "STARTED" },
{ 0x02, "ENABLED" },
{ 0x03, "DISABLED" },
{ 0, NULL }
};
static int om2k_rx_nack(struct msgb *msg)
{
struct abis_om2k_hdr *o2h = msgb_l2(msg);
@ -1180,7 +1203,7 @@ static int om2k_rx_nack(struct msgb *msg)
LOGP(DNM, LOGL_ERROR, "Rx MO=%s %s", om2k_mo_name(&o2h->mo),
get_value_string(om2k_msgcode_vals, msg_type));
abis_om2k_tlv_parse(&tp, o2h->data, o2h->om.length - 6);
abis_om2k_msg_tlv_parse(&tp, o2h);
if (TLVP_PRESENT(&tp, OM2K_DEI_REASON_CODE))
LOGPC(DNM, LOGL_ERROR, ", Reason 0x%02x",
*TLVP_VAL(&tp, OM2K_DEI_REASON_CODE));
@ -1194,6 +1217,61 @@ static int om2k_rx_nack(struct msgb *msg)
return 0;
}
/* Process a Configuration Result message */
static int process_conf_res(struct gsm_bts *bts, struct msgb *msg)
{
struct abis_om2k_hdr *o2h = msgb_l2(msg);
uint16_t msg_type = ntohs(o2h->msg_type);
struct tlv_parsed tp;
uint8_t acc;
unsigned int log_level;
int ret;
abis_om2k_msg_tlv_parse(&tp, o2h);
if (!TLVP_PRESENT(&tp, OM2K_DEI_ACCORDANCE_IND))
return -EIO;
acc = *TLVP_VAL(&tp, OM2K_DEI_ACCORDANCE_IND);
switch (acc) {
case 0:
log_level = LOGL_DEBUG;
ret = 0;
break;
default:
log_level = LOGL_ERROR;
ret = -EINVAL;
break;
}
LOGP(DNM, log_level, "Rx MO=%s %s, Accordance: %s\n",
om2k_mo_name(&o2h->mo),
get_value_string(om2k_msgcode_vals, msg_type),
get_value_string(om2k_accordance_strings, acc));
return ret;
}
static int process_mo_state(struct gsm_bts *bts, struct msgb *msg)
{
struct abis_om2k_hdr *o2h = msgb_l2(msg);
uint16_t msg_type = ntohs(o2h->msg_type);
struct tlv_parsed tp;
uint8_t mo_state;
abis_om2k_msg_tlv_parse(&tp, o2h);
if (!TLVP_PRESENT(&tp, OM2K_DEI_MO_STATE))
return -EIO;
mo_state = *TLVP_VAL(&tp, OM2K_DEI_MO_STATE);
LOGP(DNM, LOGL_DEBUG, "Rx MO=%s %s, MO State: %s\n",
om2k_mo_name(&o2h->mo),
get_value_string(om2k_msgcode_vals, msg_type),
get_value_string(om2k_mostate_vals, mo_state));
return 0;
}
int abis_om2k_rcvmsg(struct msgb *msg)
{
struct gsm_bts *bts = msg->trx->bts;
@ -1232,33 +1310,41 @@ int abis_om2k_rcvmsg(struct msgb *msg)
rc = abis_om2k_cal_time_resp(bts);
break;
case OM2K_MSGT_FAULT_REP:
process_mo_state(bts, msg);
rc = abis_om2k_tx_simple(bts, &o2h->mo, OM2K_MSGT_FAULT_REP_ACK);
break;
case OM2K_MSGT_NEGOT_REQ:
rc = om2k_rx_negot_req(msg);
break;
case OM2K_MSGT_START_RES:
process_mo_state(bts, msg);
rc = om2k_rx_start_res(msg);
break;
case OM2K_MSGT_OP_INFO_ACK:
rc = om2k_rx_op_info_ack(msg);
break;
case OM2K_MSGT_IS_CONF_RES:
process_conf_res(bts, msg);
rc = abis_om2k_tx_simple(bts, &o2h->mo, OM2K_MSGT_IS_CONF_RES_ACK);
break;
case OM2K_MSGT_CON_CONF_RES:
process_conf_res(bts, msg);
rc = abis_om2k_tx_simple(bts, &o2h->mo, OM2K_MSGT_CON_CONF_RES_ACK);
break;
case OM2K_MSGT_TX_CONF_RES:
process_conf_res(bts, msg);
rc = abis_om2k_tx_simple(bts, &o2h->mo, OM2K_MSGT_TX_CONF_RES_ACK);
break;
case OM2K_MSGT_RX_CONF_RES:
process_conf_res(bts, msg);
rc = abis_om2k_tx_simple(bts, &o2h->mo, OM2K_MSGT_RX_CONF_RES_ACK);
break;
case OM2K_MSGT_TS_CONF_RES:
process_conf_res(bts, msg);
rc = abis_om2k_tx_simple(bts, &o2h->mo, OM2K_MSGT_TS_CONF_RES_ACK);
break;
case OM2K_MSGT_TF_CONF_RES:
process_conf_res(bts, msg);
rc = abis_om2k_tx_simple(bts, &o2h->mo, OM2K_MSGT_TF_CONF_RES_ACK);
break;
case OM2K_MSGT_CONNECT_COMPL:
@ -1268,15 +1354,19 @@ int abis_om2k_rcvmsg(struct msgb *msg)
rc = abis_om2k_tx_simple(bts, &o2h->mo, OM2K_MSGT_START_REQ);
break;
case OM2K_MSGT_ENABLE_RES:
process_mo_state(bts, msg);
rc = abis_om2k_tx_simple(bts, &o2h->mo, OM2K_MSGT_ENABLE_RES_ACK);
break;
case OM2K_MSGT_DISABLE_RES:
process_mo_state(bts, msg);
rc = abis_om2k_tx_simple(bts, &o2h->mo, OM2K_MSGT_DISABLE_RES_ACK);
break;
case OM2K_MSGT_TEST_RES:
process_mo_state(bts, msg);
rc = abis_om2k_tx_simple(bts, &o2h->mo, OM2K_MSGT_TEST_RES_ACK);
break;
case OM2K_MSGT_STATUS_RESP:
process_mo_state(bts, msg);
break;
case OM2K_MSGT_START_REQ_ACK:
case OM2K_MSGT_CON_CONF_REQ_ACK: