aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2009-10-22 11:47:45 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2009-10-27 04:52:29 +0100
commite81a6109f9e94ec5dcceb44a7ef1ea8cc52e7cb1 (patch)
tree3c7ad640e5837f2d6aae78d72b73ddf748eff02f
parent55aac6e868d4f3b565bba310598104c53c53da0a (diff)
[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.
-rw-r--r--openbsc/include/openbsc/gsm_04_08.h10
-rw-r--r--openbsc/src/abis_rsl.c1
-rw-r--r--openbsc/src/gsm_04_08_utils.c32
3 files changed, 43 insertions, 0 deletions
diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h
index 8c944e6ac..ae13581f2 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 6b328bb28..a4764f5fb 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 ef9e59c77..358212f17 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);
+}