From 942ff1737a789fd24eb60b6cc426a953cd229511 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 22 Oct 2009 11:47:45 +0200 Subject: [PATCH] [gsm48] Add generation of ASSIGNMENT COMMAND to the 0408 utils Add code to generate an assignment command for a given lchan. It is expected that the lchan is modified already and the mode will be picked up from their. Currently only the mandantory items are supported. --- openbsc/include/openbsc/gsm_04_08.h | 10 +++++++++ openbsc/src/abis_rsl.c | 1 + openbsc/src/gsm_04_08_utils.c | 32 +++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h index 8c944e6a..ae13581f 100644 --- a/openbsc/include/openbsc/gsm_04_08.h +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -59,6 +59,15 @@ enum gsm48_chan_mode { GSM48_CMODE_DATA_3k6 = 0x23, }; +/* Chapter 9.1.2 */ +struct gsm48_ass_cmd { + /* Semantic is from 10.5.2.5a */ + struct gsm48_chan_desc chan_desc; + u_int8_t power_command; + u_int8_t data[0]; +} __attribute__((packed)); + + /* Chapter 9.1.18 */ struct gsm48_imm_ass { u_int8_t l2_plen; @@ -727,6 +736,7 @@ int gsm48_send_rr_release(struct gsm_lchan *lchan); int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv); int gsm48_send_rr_app_info(struct gsm_lchan *lchan, u_int8_t apdu_id, u_int8_t apdu_len, const u_int8_t *apdu); +int gsm48_send_rr_ass_cmd(struct gsm_lchan *lchan, u_int8_t power_class); int bsc_upqueue(struct gsm_network *net); diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index 6b328bb2..a4764f5f 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -239,6 +239,7 @@ struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, u_int8_t chan_nr) return lchan; } +/* See Table 10.5.25 of GSM04.08 */ u_int8_t lchan2chan_nr(struct gsm_lchan *lchan) { struct gsm_bts_trx_ts *ts = lchan->ts; diff --git a/openbsc/src/gsm_04_08_utils.c b/openbsc/src/gsm_04_08_utils.c index ef9e59c7..358212f1 100644 --- a/openbsc/src/gsm_04_08_utils.c +++ b/openbsc/src/gsm_04_08_utils.c @@ -482,3 +482,35 @@ int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv) return rsl_encryption_cmd(msg); } +/* Chapter 9.1.2: Assignment Command */ +int gsm48_send_rr_ass_cmd(struct gsm_lchan *lchan, u_int8_t power_command) +{ + struct msgb *msg = gsm48_msgb_alloc(); + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + struct gsm48_ass_cmd *ass = + (struct gsm48_ass_cmd *) msgb_put(msg, sizeof(*ass)); + u_int16_t arfcn = lchan->ts->trx->arfcn & 0x3ff; + + DEBUGP(DRR, "-> ASSIGNMENT COMMAND tch_mode=0x%02x\n", lchan->tch_mode); + + msg->lchan = lchan; + gh->proto_discr = GSM48_PDISC_RR; + gh->msg_type = GSM48_MT_RR_ASS_CMD; + + /* + * fill the channel information element, this code + * should probably be shared with rsl_rx_chan_rqd(), + * gsm48_tx_chan_mode_modify. But beware that 10.5.2.5 + * 10.5.2.5.a have slightly different semantic for + * the chan_desc. But as long as multi-slot configurations + * are not used we seem to be fine. + */ + ass->chan_desc.chan_nr = lchan2chan_nr(lchan); + ass->chan_desc.h0.tsc = lchan->ts->trx->bts->tsc; + ass->chan_desc.h0.h = 0; + ass->chan_desc.h0.arfcn_high = arfcn >> 8; + ass->chan_desc.h0.arfcn_low = arfcn & 0xff; + ass->power_command = power_command; + + return gsm48_sendmsg(msg, NULL); +}