diff options
author | Harald Welte <laforge@gnumonks.org> | 2011-03-05 19:21:26 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2011-03-05 19:21:26 +0100 |
commit | 1164dce679e186b2b0d9d67c2a010814e51cbeea (patch) | |
tree | 18831bfc715588b7dcc7364044e1c02604d1c682 /openbsc/src/libbsc/abis_om2000.c | |
parent | 3ede723cb416c2e57cb5a265b2327de5fa4a5e4b (diff) |
OM2000: Add channel combination specific DIEs for TS config request
... and in order to do this reasonably well, we have to get rid of
the pre-computed message length field in the OML header. Instead,
we now simply compute it at abis_om2k_sendmsg() time based on the
msgb_l2len().
Diffstat (limited to 'openbsc/src/libbsc/abis_om2000.c')
-rw-r--r-- | openbsc/src/libbsc/abis_om2000.c | 94 |
1 files changed, 78 insertions, 16 deletions
diff --git a/openbsc/src/libbsc/abis_om2000.c b/openbsc/src/libbsc/abis_om2000.c index b86503829..08f95e840 100644 --- a/openbsc/src/libbsc/abis_om2000.c +++ b/openbsc/src/libbsc/abis_om2000.c @@ -166,10 +166,15 @@ enum abis_om2k_msgtype { enum abis_om2k_dei { OM2K_DEI_BCC = 0x06, + OM2K_DEI_BS_AG_BKS_RES = 0x07, OM2K_DEI_BSIC = 0x09, + OM2K_DEI_BA_PA_MFRMS = 0x0a, + OM2K_DEI_CBCH_INDICATOR = 0x0b, + OM2K_DEI_CCCH_OPTIONS = 0x0c, OM2K_DEI_CAL_TIME = 0x0d, OM2K_DEI_COMBINATION = 0x0f, OM2K_DEI_CON_CONN_LIST = 0x10, + OM2K_DEI_DRX_DEV_MAX = 0x12, OM2K_DEI_END_LIST_NR = 0x13, OM2K_DEI_FILLING_MARKER = 0x1c, OM2K_DEI_FN_OFFSET = 0x1d, @@ -177,29 +182,44 @@ enum abis_om2k_dei { OM2K_DEI_FREQ_SPEC_RX = 0x1f, OM2K_DEI_FREQ_SPEC_TX = 0x20, OM2K_DEI_HSN = 0x21, + OM2K_DEI_ICM_INDICATOR = 0x22, OM2K_DEI_IS_CONN_LIST = 0x27, OM2K_DEI_LIST_NR = 0x28, OM2K_DEI_MAIO = 0x2b, + OM2K_DEI_NY1 = 0x2d, OM2K_DEI_OP_INFO = 0x2e, OM2K_DEI_POWER = 0x2f, OM2K_DEI_REASON_CODE = 0x32, OM2K_DEI_RX_DIVERSITY = 0x33, OM2K_DEI_RESULT_CODE = 0x35, + OM2K_DEI_T3105 = 0x38, OM2K_DEI_TF_MODE = 0x3a, OM2K_DEI_TS_NR = 0x3c, + OM2K_DEI_TSC = 0x3d, OM2K_DEI_EXT_RANGE = 0x47, + OM2K_DEI_LSC = 0x79, + OM2K_DEI_LSC_FILT_TIME = 0x7a, + OM2K_DEI_CALL_SUPV_TIME = 0x7b, + OM2K_DEI_TTA = 0x87, OM2K_DEI_NEGOT_REC1 = 0x90, OM2K_DEI_NEGOT_REC2 = 0x91, + OM2K_DEI_ENCR_ALG = 0x92, + OM2K_DEI_INTERF_REJ_COMB = 0x94, OM2K_DEI_FS_OFFSET = 0x98, }; const struct tlv_definition om2k_att_tlvdef = { .def = { [OM2K_DEI_BCC] = { TLV_TYPE_TV }, + [OM2K_DEI_BS_AG_BKS_RES] = { TLV_TYPE_TV }, [OM2K_DEI_BSIC] = { TLV_TYPE_TV }, + [OM2K_DEI_BA_PA_MFRMS] = { TLV_TYPE_TV }, + [OM2K_DEI_CBCH_INDICATOR] = { TLV_TYPE_TV }, + [OM2K_DEI_CCCH_OPTIONS] = { TLV_TYPE_TV }, [OM2K_DEI_CAL_TIME] = { TLV_TYPE_FIXED, 6 }, [OM2K_DEI_COMBINATION] = { TLV_TYPE_TV }, [OM2K_DEI_CON_CONN_LIST] = { TLV_TYPE_TLV }, + [OM2K_DEI_DRX_DEV_MAX] = { TLV_TYPE_TV }, [OM2K_DEI_END_LIST_NR] = { TLV_TYPE_TV }, [OM2K_DEI_FILLING_MARKER] = { TLV_TYPE_TV }, [OM2K_DEI_FN_OFFSET] = { TLV_TYPE_FIXED, 2 }, @@ -207,19 +227,29 @@ const struct tlv_definition om2k_att_tlvdef = { [OM2K_DEI_FREQ_SPEC_RX] = { TLV_TYPE_FIXED, 2 }, [OM2K_DEI_FREQ_SPEC_TX] = { TLV_TYPE_FIXED, 2 }, [OM2K_DEI_HSN] = { TLV_TYPE_TV }, + [OM2K_DEI_ICM_INDICATOR] = { TLV_TYPE_TV }, [OM2K_DEI_IS_CONN_LIST] = { TLV_TYPE_TLV }, [OM2K_DEI_LIST_NR] = { TLV_TYPE_TV }, [OM2K_DEI_MAIO] = { TLV_TYPE_TV }, + [OM2K_DEI_NY1] = { TLV_TYPE_TV }, [OM2K_DEI_OP_INFO] = { TLV_TYPE_TV }, [OM2K_DEI_POWER] = { TLV_TYPE_TV }, [OM2K_DEI_REASON_CODE] = { TLV_TYPE_TV }, [OM2K_DEI_RX_DIVERSITY] = { TLV_TYPE_TV }, [OM2K_DEI_RESULT_CODE] = { TLV_TYPE_TV }, + [OM2K_DEI_T3105] = { TLV_TYPE_TV }, [OM2K_DEI_TF_MODE] = { TLV_TYPE_TV }, [OM2K_DEI_TS_NR] = { TLV_TYPE_TV }, + [OM2K_DEI_TSC] = { TLV_TYPE_TV }, [OM2K_DEI_EXT_RANGE] = { TLV_TYPE_TV }, + [OM2K_DEI_LSC] = { TLV_TYPE_TV }, + [OM2K_DEI_LSC_FILT_TIME] = { TLV_TYPE_TV }, + [OM2K_DEI_CALL_SUPV_TIME] = { TLV_TYPE_TV }, + [OM2K_DEI_TTA] = { TLV_TYPE_TV }, [OM2K_DEI_NEGOT_REC1] = { TLV_TYPE_TLV }, [OM2K_DEI_NEGOT_REC2] = { TLV_TYPE_TLV }, + [OM2K_DEI_ENCR_ALG] = { TLV_TYPE_TV }, + [OM2K_DEI_INTERF_REJ_COMB] = { TLV_TYPE_TV }, [OM2K_DEI_FS_OFFSET] = { TLV_TYPE_FIXED, 5 }, }, }; @@ -577,6 +607,9 @@ static int abis_om2k_sendmsg(struct gsm_bts *bts, struct msgb *msg) msg->l2h = msg->data; o2h = (struct abis_om2k_hdr *) msg->l2h; + /* Compute the length in the OML header */ + o2h->om.length = 6 + msgb_l2len(msg)-sizeof(*o2h); + switch (o2h->mo.class) { case OM2K_MO_CLS_TRXC: case OM2K_MO_CLS_TX: @@ -602,12 +635,12 @@ static int abis_om2k_sendmsg(struct gsm_bts *bts, struct msgb *msg) } static void fill_om2k_hdr(struct abis_om2k_hdr *o2h, const struct abis_om2k_mo *mo, - uint16_t msg_type, uint8_t attr_len) + uint16_t msg_type) { o2h->om.mdisc = ABIS_OM_MDISC_FOM; o2h->om.placement = ABIS_OM_PLACEMENT_ONLY; o2h->om.sequence = 0; - o2h->om.length = 6 + attr_len; + /* We fill o2h->om.length later during om2k_sendmsg() */ o2h->msg_type = htons(msg_type); memcpy(&o2h->mo, mo, sizeof(o2h->mo)); } @@ -625,7 +658,7 @@ static int abis_om2k_cal_time_resp(struct gsm_bts *bts) struct tm *tm; o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k)); - fill_om2k_hdr(o2k, &om2k_mo_cf, OM2K_MSGT_CAL_TIME_RESP, 7); + fill_om2k_hdr(o2k, &om2k_mo_cf, OM2K_MSGT_CAL_TIME_RESP); tm_t = time(NULL); tm = localtime(&tm_t); @@ -648,7 +681,7 @@ static int abis_om2k_tx_simple(struct gsm_bts *bts, const struct abis_om2k_mo *m struct abis_om2k_hdr *o2k; o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k)); - fill_om2k_hdr(o2k, mo, msg_type, 0); + fill_om2k_hdr(o2k, mo, msg_type); DEBUGP(DNM, "Tx MO=%s %s\n", om2k_mo_name(mo), get_value_string(om2k_msgcode_vals, msg_type)); @@ -703,7 +736,7 @@ int abis_om2k_tx_op_info(struct gsm_bts *bts, const struct abis_om2k_mo *mo, struct abis_om2k_hdr *o2k; o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k)); - fill_om2k_hdr(o2k, mo, OM2K_MSGT_OP_INFO, 2); + fill_om2k_hdr(o2k, mo, OM2K_MSGT_OP_INFO); msgb_tv_put(msg, OM2K_DEI_OP_INFO, operational); @@ -720,8 +753,7 @@ int abis_om2k_tx_is_conf_req(struct gsm_bts *bts, struct om2k_is_conn_grp *cg, struct abis_om2k_hdr *o2k; o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k)); - fill_om2k_hdr(o2k, &om2k_mo_is, OM2K_MSGT_IS_CONF_REQ, - 2 + 2 + TLV_GROSS_LEN(num_cg * sizeof(*cg))); + fill_om2k_hdr(o2k, &om2k_mo_is, OM2K_MSGT_IS_CONF_REQ); msgb_tv_put(msg, OM2K_DEI_LIST_NR, 1); msgb_tv_put(msg, OM2K_DEI_END_LIST_NR, 1); @@ -739,8 +771,7 @@ int abis_om2k_tx_con_conf_req(struct gsm_bts *bts, uint8_t *data, struct abis_om2k_hdr *o2k; o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k)); - fill_om2k_hdr(o2k, &om2k_mo_con, OM2K_MSGT_CON_CONF_REQ, - 2 + 2 + TLV_GROSS_LEN(len)); + fill_om2k_hdr(o2k, &om2k_mo_con, OM2K_MSGT_CON_CONF_REQ); msgb_tv_put(msg, OM2K_DEI_LIST_NR, 1); msgb_tv_put(msg, OM2K_DEI_END_LIST_NR, 1); @@ -779,7 +810,7 @@ int abis_om2k_tx_rx_conf_req(struct gsm_bts_trx *trx) om2k_trx_to_mo(&mo, trx, OM2K_MO_CLS_RX); o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k)); - fill_om2k_hdr(o2k, &mo, OM2K_MSGT_RX_CONF_REQ, 3+2); + fill_om2k_hdr(o2k, &mo, OM2K_MSGT_RX_CONF_REQ); msgb_tv16_put(msg, OM2K_DEI_FREQ_SPEC_RX, trx->arfcn); msgb_tv_put(msg, OM2K_DEI_RX_DIVERSITY, 0x03); /* A+B */ @@ -797,7 +828,7 @@ int abis_om2k_tx_tx_conf_req(struct gsm_bts_trx *trx) om2k_trx_to_mo(&mo, trx, OM2K_MO_CLS_TX); o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k)); - fill_om2k_hdr(o2k, &mo, OM2K_MSGT_TX_CONF_REQ, 3+2+2+2); + fill_om2k_hdr(o2k, &mo, OM2K_MSGT_TX_CONF_REQ); msgb_tv16_put(msg, OM2K_DEI_FREQ_SPEC_TX, trx->arfcn); msgb_tv_put(msg, OM2K_DEI_POWER, trx->nominal_power-trx->max_power_red); @@ -823,8 +854,7 @@ int abis_om2k_tx_tf_conf_req(struct gsm_bts *bts) struct abis_om2k_hdr *o2k; o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k)); - fill_om2k_hdr(o2k, &om2k_mo_tf, OM2K_MSGT_TF_CONF_REQ, - 2+1+sizeof(fs_offset_undef)); + fill_om2k_hdr(o2k, &om2k_mo_tf, OM2K_MSGT_TF_CONF_REQ); msgb_tv_put(msg, OM2K_DEI_TF_MODE, OM2K_TF_MODE_STANDALONE); msgb_tv_fixed_put(msg, OM2K_DEI_FS_OFFSET, @@ -897,8 +927,7 @@ int abis_om2k_tx_ts_conf_req(struct gsm_bts_trx_ts *ts) return freq_list_len; o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k)); - fill_om2k_hdr(o2k, &mo, OM2K_MSGT_TS_CONF_REQ, - 2+2+TLV_GROSS_LEN(freq_list_len)+2+2+2+2+3+2); + fill_om2k_hdr(o2k, &mo, OM2K_MSGT_TS_CONF_REQ); msgb_tv_put(msg, OM2K_DEI_COMBINATION, pchan2comb(ts->pchan)); msgb_tv_put(msg, OM2K_DEI_TS_NR, ts->nr); @@ -910,6 +939,39 @@ int abis_om2k_tx_ts_conf_req(struct gsm_bts_trx_ts *ts) msgb_tv16_put(msg, OM2K_DEI_FN_OFFSET, 0); msgb_tv_put(msg, OM2K_DEI_EXT_RANGE, 0); /* Off */ /* Optional: Interference Rejection Combining */ + msgb_tv_put(msg, OM2K_DEI_INTERF_REJ_COMB, 0x00); + switch (ts->pchan) { + case GSM_PCHAN_CCCH: + case GSM_PCHAN_CCCH_SDCCH4: + msgb_tv_put(msg, OM2K_DEI_BA_PA_MFRMS, 0x06); + msgb_tv_put(msg, OM2K_DEI_BS_AG_BKS_RES, 0x01); + msgb_tv_put(msg, OM2K_DEI_DRX_DEV_MAX, 0x05); + /* Repeat Paging/IMM.ASS: True, Allow Paging Type 3: Yes, Page for 5 seconds (default) */ + msgb_tv_put(msg, OM2K_DEI_CCCH_OPTIONS, 0x01); + break; + case GSM_PCHAN_SDCCH8_SACCH8C: + msgb_tv_put(msg, OM2K_DEI_T3105, 0x04); + msgb_tv_put(msg, OM2K_DEI_NY1, 35); + msgb_tv_put(msg, OM2K_DEI_CBCH_INDICATOR, 0); + msgb_tv_put(msg, OM2K_DEI_TSC, ts->trx->bts->tsc); + /* Disable RF RESOURCE INDICATION on idle channels */ + msgb_tv_put(msg, OM2K_DEI_ICM_INDICATOR, 0); + break; + default: + msgb_tv_put(msg, OM2K_DEI_T3105, 0x04); + msgb_tv_put(msg, OM2K_DEI_NY1, 35); + msgb_tv_put(msg, OM2K_DEI_CBCH_INDICATOR, 0); + msgb_tv_put(msg, OM2K_DEI_TSC, ts->trx->bts->tsc); + /* Disable RF RESOURCE INDICATION on idle channels */ + msgb_tv_put(msg, OM2K_DEI_ICM_INDICATOR, 0); + msgb_tv_put(msg, OM2K_DEI_TTA, 10); /* Timer for Time Alignment */ + msgb_tv_put(msg, OM2K_DEI_LSC, 1); /* enabled */ + msgb_tv_put(msg, OM2K_DEI_LSC_FILT_TIME, 160); /* units of 100ms */ + msgb_tv_put(msg, OM2K_DEI_CALL_SUPV_TIME, 8); + msgb_tv_put(msg, OM2K_DEI_ENCR_ALG, 0x00); + /* FIXME: do we need 9e/9f/a0? */ + break; + } return abis_om2k_sendmsg(ts->trx->bts, msg); } @@ -921,7 +983,7 @@ static int abis_om2k_tx_negot_req_ack(struct gsm_bts *bts, const struct abis_om2 struct abis_om2k_hdr *o2k; o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k)); - fill_om2k_hdr(o2k, mo, OM2K_MSGT_NEGOT_REQ_ACK, 2+len); + fill_om2k_hdr(o2k, mo, OM2K_MSGT_NEGOT_REQ_ACK); msgb_tlv_put(msg, OM2K_DEI_NEGOT_REC2, len, data); |