diff options
Diffstat (limited to 'openbsc/src/libbsc/abis_om2000.c')
-rw-r--r-- | openbsc/src/libbsc/abis_om2000.c | 71 |
1 files changed, 60 insertions, 11 deletions
diff --git a/openbsc/src/libbsc/abis_om2000.c b/openbsc/src/libbsc/abis_om2000.c index 8c4bfb3b5..2733a90fd 100644 --- a/openbsc/src/libbsc/abis_om2000.c +++ b/openbsc/src/libbsc/abis_om2000.c @@ -1132,20 +1132,48 @@ int abis_om2k_tx_is_conf_req(struct gsm_bts *bts) return abis_om2k_sendmsg(bts, msg); } -int abis_om2k_tx_con_conf_req(struct gsm_bts *bts, uint8_t *data, - unsigned int len) +int abis_om2k_tx_con_conf_req(struct gsm_bts *bts) { struct msgb *msg = om2k_msgb_alloc(); struct abis_om2k_hdr *o2k; + struct con_group *grp; + unsigned int num_grps = 0; - o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k)); - fill_om2k_hdr(o2k, &bts->rbs2000.con.om2k_mo.addr, - OM2K_MSGT_CON_CONF_REQ); + /* count number of groups in linked list */ + llist_for_each_entry(grp, &bts->rbs2000.con.conn_groups, list) + num_grps++; - msgb_tv_put(msg, OM2K_DEI_LIST_NR, 1); - msgb_tv_put(msg, OM2K_DEI_END_LIST_NR, 1); + if (!num_grps) + return -EINVAL; + + /* first build the value part of the OM2K_DEI_CON_CONN_LIST DEI */ + msgb_put_u8(msg, num_grps); + llist_for_each_entry(grp, &bts->rbs2000.con.conn_groups, list) { + struct con_path *cp; + unsigned int num_paths = 0; + llist_for_each_entry(cp, &grp->paths, list) + num_paths++; + msgb_put_u8(msg, num_paths); + llist_for_each_entry(cp, &grp->paths, list) { + struct om2k_con_path *om2k_cp; + om2k_cp = (struct om2k_con_path *) msgb_put(msg, sizeof(*om2k_cp)); + om2k_cp->ccp = htons(cp->ccp); + om2k_cp->ci = cp->ci; + om2k_cp->tag = cp->tag; + om2k_cp->tei = cp->tei; + } + } + msgb_push_u8(msg, msgb_length(msg)); + msgb_push_u8(msg, OM2K_DEI_CON_CONN_LIST); + + /* pre-pend the list number DEIs */ + msgb_tv_push(msg, OM2K_DEI_END_LIST_NR, 1); + msgb_tv_push(msg, OM2K_DEI_LIST_NR, 1); - msgb_tlv_put(msg, OM2K_DEI_CON_CONN_LIST, len, data); + /* pre-pend the OM2K header */ + o2k = (struct abis_om2k_hdr *) msgb_push(msg, sizeof(*o2k)); + fill_om2k_hdr(o2k, &bts->rbs2000.con.om2k_mo.addr, + OM2K_MSGT_CON_CONF_REQ); DEBUGP(DNM, "Tx MO=%s %s\n", om2k_mo_name(&bts->rbs2000.con.om2k_mo.addr), @@ -1566,8 +1594,7 @@ static void om2k_mo_st_wait_start_res(struct osmo_fsm_inst *fi, uint32_t event, abis_om2k_tx_is_conf_req(omfp->trx->bts); break; case OM2K_MO_CLS_CON: - /* TODO */ - //abis_om2k_tx_con_conf_req(omfp->trx->bts, data, len); + abis_om2k_tx_con_conf_req(omfp->trx->bts); break; case OM2K_MO_CLS_TX: abis_om2k_tx_tx_conf_req(omfp->trx); @@ -2061,6 +2088,7 @@ enum om2k_bts_event { OM2K_BTS_EVT_START, OM2K_BTS_EVT_CF_DONE, OM2K_BTS_EVT_IS_DONE, + OM2K_BTS_EVT_CON_DONE, OM2K_BTS_EVT_TF_DONE, OM2K_BTS_EVT_TRX_DONE, OM2K_BTS_EVT_STOP, @@ -2070,6 +2098,7 @@ static const struct value_string om2k_bts_events[] = { { OM2K_BTS_EVT_START, "START" }, { OM2K_BTS_EVT_CF_DONE, "CF-DONE" }, { OM2K_BTS_EVT_IS_DONE, "IS-DONE" }, + { OM2K_BTS_EVT_CON_DONE, "CON-DONE" }, { OM2K_BTS_EVT_TF_DONE, "TF-DONE" }, { OM2K_BTS_EVT_TRX_DONE, "TRX-DONE" }, { OM2K_BTS_EVT_STOP, "STOP" }, @@ -2080,6 +2109,7 @@ enum om2k_bts_state { OM2K_BTS_S_INIT, OM2K_BTS_S_WAIT_CF, OM2K_BTS_S_WAIT_IS, + OM2K_BTS_S_WAIT_CON, OM2K_BTS_S_WAIT_TF, OM2K_BTS_S_WAIT_TRX, OM2K_BTS_S_DONE, @@ -2121,6 +2151,18 @@ static void om2k_bts_s_wait_is(struct osmo_fsm_inst *fi, uint32_t event, void *d struct gsm_bts *bts = obfp->bts; OSMO_ASSERT(event == OM2K_BTS_EVT_IS_DONE); + osmo_fsm_inst_state_chg(fi, OM2K_BTS_S_WAIT_CON, + BTS_FSM_TIMEOUT, 0); + om2k_mo_fsm_start(fi, OM2K_BTS_EVT_CON_DONE, bts->c0, + &bts->rbs2000.con.om2k_mo); +} + +static void om2k_bts_s_wait_con(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct om2k_bts_fsm_priv *obfp = fi->priv; + struct gsm_bts *bts = obfp->bts; + + OSMO_ASSERT(event == OM2K_BTS_EVT_CON_DONE); /* TF can take a long time to initialize, wait for 10min */ osmo_fsm_inst_state_chg(fi, OM2K_BTS_S_WAIT_TF, 600, 0); om2k_mo_fsm_start(fi, OM2K_BTS_EVT_TF_DONE, bts->c0, @@ -2178,10 +2220,17 @@ static const struct osmo_fsm_state om2k_bts_states[] = { [OM2K_BTS_S_WAIT_IS] = { .in_event_mask = S(OM2K_BTS_EVT_IS_DONE), .out_state_mask = S(OM2K_BTS_S_ERROR) | - S(OM2K_BTS_S_WAIT_TF), + S(OM2K_BTS_S_WAIT_CON), .name = "WAIT-IS", .action = om2k_bts_s_wait_is, }, + [OM2K_BTS_S_WAIT_CON] = { + .in_event_mask = S(OM2K_BTS_EVT_CON_DONE), + .out_state_mask = S(OM2K_BTS_S_ERROR) | + S(OM2K_BTS_S_WAIT_TF), + .name = "WAIT-CON", + .action = om2k_bts_s_wait_con, + }, [OM2K_BTS_S_WAIT_TF] = { .in_event_mask = S(OM2K_BTS_EVT_TF_DONE), .out_state_mask = S(OM2K_BTS_S_ERROR) | |