diff options
author | Harald Welte <laforge@gnumonks.org> | 2011-02-12 18:11:16 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2011-02-13 15:49:26 +0100 |
commit | 563d316106392787c2685c8bdb4b6dc3eddd5706 (patch) | |
tree | f60fadf933549f2741c27a03eb24ff14d7df9956 /openbsc/src | |
parent | 8024d8ff58feb1666845a057e24f7752b87d8f75 (diff) |
OM2000: Implement proper parsing and response for Negotiation
Diffstat (limited to 'openbsc/src')
-rw-r--r-- | openbsc/src/abis_om2000.c | 62 |
1 files changed, 59 insertions, 3 deletions
diff --git a/openbsc/src/abis_om2000.c b/openbsc/src/abis_om2000.c index 7c58a6f8d..fc0fbd87b 100644 --- a/openbsc/src/abis_om2000.c +++ b/openbsc/src/abis_om2000.c @@ -602,13 +602,69 @@ static int abis_om2k_tx_negot_req_ack(struct gsm_bts *bts, const struct abis_om2 return abis_om2k_sendmsg(bts, msg); } +struct iwd_version { + uint8_t gen_char[3+1]; + uint8_t rev_char[3+1]; +}; + +struct iwd_type { + uint8_t num_vers; + struct iwd_version v[8]; +}; + static int om2k_rx_negot_req(struct msgb *msg) { struct abis_om2k_hdr *o2h = msgb_l2(msg); - uint8_t *negot_data = o2h->data+2; - uint8_t negot_len = o2h->data[1]; + struct iwd_type iwd_types[16]; + uint8_t num_iwd_types = o2h->data[2]; + uint8_t *cur = o2h->data+3; + unsigned int i, v; + + uint8_t out_buf[1024]; + uint8_t *out_cur = out_buf+1; + uint8_t out_num_types = 0; + + memset(iwd_types, 0, sizeof(iwd_types)); + + /* Parse the RBS-supported IWD versions into iwd_types array */ + for (i = 0; i < num_iwd_types; i++) { + uint8_t num_versions = *cur++; + uint8_t iwd_type = *cur++; + + iwd_types[iwd_type].num_vers = num_versions; + + for (v = 0; v < num_versions; v++) { + struct iwd_version *iwd_v = &iwd_types[iwd_type].v[v]; + + memcpy(iwd_v->gen_char, cur, 3); + memcpy(iwd_v->rev_char, cur+3, 3); + DEBUGP(DNM, "\tIWD Type %u Gen %s Rev %s\n", iwd_type, + iwd_v->gen_char, iwd_v->rev_char); + } + } + + /* Select the last version for each IWD type */ + for (i = 0; i < ARRAY_SIZE(iwd_types); i++) { + struct iwd_type *type = &iwd_types[i]; + struct iwd_version *last_v; + + if (type->num_vers == 0) + continue; + + out_num_types++; + + last_v = &type->v[type->num_vers-1]; + + *out_cur++ = i; + memcpy(out_cur, last_v->gen_char, 3); + out_cur += 3; + memcpy(out_cur, last_v->rev_char, 3); + out_cur += 3; + } + + out_buf[0] = out_num_types; - return abis_om2k_tx_negot_req_ack(msg->trx->bts, &o2h->mo, negot_data, negot_len); + return abis_om2k_tx_negot_req_ack(msg->trx->bts, &o2h->mo, out_buf, out_cur - out_buf); } static int om2k_rx_start_res(struct msgb *msg) |