summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-12-29 23:06:22 +0100
committerHarald Welte <laforge@gnumonks.org>2010-12-30 17:11:46 +0100
commitd2a28026c152985e571ee157ac8f3dafd18649f4 (patch)
tree11fc4e3c2195a0389c046084863a9b99b92434ad
parent2c1a26adb55d6c0f7e2203b186873ba73fb03425 (diff)
smscb: Prepare to fill in the info for CBCH in SI4laforge/27c3
Pass the number of bytes the rest octet for si4 should fill. We will need to include info for CBCH in our SI4. WIP: SMSCB... this should reuse the lchan2desc if it works... smscb: Add vty command for experimentation...
-rw-r--r--openbsc/include/openbsc/rest_octets.h2
-rw-r--r--openbsc/src/rest_octets.c4
-rw-r--r--openbsc/src/system_information.c17
-rw-r--r--openbsc/src/vty_interface_layer3.c28
4 files changed, 45 insertions, 6 deletions
diff --git a/openbsc/include/openbsc/rest_octets.h b/openbsc/include/openbsc/rest_octets.h
index 6d9011963..1f0724ab0 100644
--- a/openbsc/include/openbsc/rest_octets.h
+++ b/openbsc/include/openbsc/rest_octets.h
@@ -56,7 +56,7 @@ struct gsm48_si_ro_info {
int rest_octets_si3(u_int8_t *data, const struct gsm48_si_ro_info *si3);
/* Generate SI4 Rest Octets (Chapter 10.5.2.35) */
-int rest_octets_si4(u_int8_t *data, const struct gsm48_si_ro_info *si4);
+int rest_octets_si4(u_int8_t *data, const struct gsm48_si_ro_info *si4, int len);
enum pbcch_carrier_type {
PBCCH_BCCH,
diff --git a/openbsc/src/rest_octets.c b/openbsc/src/rest_octets.c
index d9f5da568..0d037b840 100644
--- a/openbsc/src/rest_octets.c
+++ b/openbsc/src/rest_octets.c
@@ -137,13 +137,13 @@ static int append_lsa_params(struct bitvec *bv,
}
/* Generate SI4 Rest Octets (Chapter 10.5.2.35) */
-int rest_octets_si4(u_int8_t *data, const struct gsm48_si_ro_info *si4)
+int rest_octets_si4(u_int8_t *data, const struct gsm48_si_ro_info *si4, int len)
{
struct bitvec bv;
memset(&bv, 0, sizeof(bv));
bv.data = data;
- bv.data_len = 10; /* FIXME: up to ? */
+ bv.data_len = len;
/* SI4 Rest Octets O */
append_selection_params(&bv, &si4->selection_params);
diff --git a/openbsc/src/system_information.c b/openbsc/src/system_information.c
index 8ee95f9f1..eb7eef56a 100644
--- a/openbsc/src/system_information.c
+++ b/openbsc/src/system_information.c
@@ -324,7 +324,8 @@ static int generate_si3(u_int8_t *output, struct gsm_bts *bts)
static int generate_si4(u_int8_t *output, struct gsm_bts *bts)
{
- int rc;
+ int rc, offset = 0;
+ struct gsm48_chan_desc *cd;
struct gsm48_system_information_type_4 *si4 =
(struct gsm48_system_information_type_4 *) output;
@@ -344,13 +345,23 @@ static int generate_si4(u_int8_t *output, struct gsm_bts *bts)
si4->rach_control = bts->si_common.rach_control;
/* Optional: CBCH Channel Description + CBCH Mobile Allocation */
+ if (!bts->c0->ts[0].hopping.enabled) {
+ cd = (struct gsm48_chan_desc *) si4->data;
+ cd->h0.tsc = bts->tsc;
+ cd->h0.h = 0;
+ cd->h0.arfcn_high = (bts->c0->arfcn & 0x3ff) >> 8;
+ cd->h0.arfcn_low = bts->c0->arfcn & 0xff;
+ offset = 4;
+ } else {
+ offset = 0;
+ }
- si4->header.l2_plen = (l2_plen << 2) | 1;
+ si4->header.l2_plen = ((l2_plen + offset)<< 2) | 1;
/* SI4 Rest Octets (10.5.2.35), containing
Optional Power offset, GPRS Indicator,
Cell Identity, LSA ID, Selection Parameter */
- rc = rest_octets_si4(si4->data, &si_info);
+ rc = rest_octets_si4(si4->data + offset, &si_info, 10 - offset);
return sizeof(*si4) + rc;
}
diff --git a/openbsc/src/vty_interface_layer3.c b/openbsc/src/vty_interface_layer3.c
index 218e3ce58..b6382ded8 100644
--- a/openbsc/src/vty_interface_layer3.c
+++ b/openbsc/src/vty_interface_layer3.c
@@ -798,7 +798,34 @@ DEFUN(ussd_dump,
return CMD_SUCCESS;
}
+DEFUN(smscb,
+ smscb_cmd,
+ "smscb-command <0-255> <0-255> HEX",
+ "Send SMSCB\n" "BTS Nr\n" "CB Cmd Type\n" "Message\n")
+{
+ uint8_t hex[86];
+ struct gsm_network *network;
+ struct gsm_bts *bts;
+ int rc;
+
+ network = gsmnet_from_vty(vty);
+ bts = gsm_bts_num(network, atoi(argv[0]));
+ if (!bts) {
+ vty_out(vty, "BTS %d was not found.%s", atoi(argv[0]), VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ rc = hexparse(argv[2], hex, sizeof(hex));
+ if (rc < 0) {
+ vty_out(vty, "Parsing the message failed.\n");
+ return CMD_WARNING;
+ }
+ /* check channel config */
+ rsl_sms_cb_command(bts, RSL_CHAN_SDCCH4_ACCH, atoi(argv[1]),
+ hex, rc);
+ return CMD_SUCCESS;
+}
int bsc_vty_init_extra(void)
{
@@ -834,6 +861,7 @@ int bsc_vty_init_extra(void)
install_element(ENABLE_NODE, &ussd_add_cmd);
install_element(ENABLE_NODE, &ussd_clear_cmd);
install_element(ENABLE_NODE, &ussd_dump_cmd);
+ install_element(ENABLE_NODE, &smscb_cmd);
return 0;
}