Merge branch 'on-waves/mgcp'
diff --git a/openbsc/include/openbsc/abis_rsl.h b/openbsc/include/openbsc/abis_rsl.h
index e6973ee..8e6774d 100644
--- a/openbsc/include/openbsc/abis_rsl.h
+++ b/openbsc/include/openbsc/abis_rsl.h
@@ -70,10 +70,11 @@
u_int8_t lchan2chan_nr(const struct gsm_lchan *lchan);
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id);
+int rsl_lchan_set_state(struct gsm_lchan *lchan, int);
+
/* to be provided by external code */
int abis_rsl_sendmsg(struct msgb *msg);
int rsl_deact_sacch(struct gsm_lchan *lchan);
-int rsl_chan_release(struct gsm_lchan *lchan);
/* BCCH related code */
int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf);
diff --git a/openbsc/include/openbsc/chan_alloc.h b/openbsc/include/openbsc/chan_alloc.h
index f564e9e..d4f5858 100644
--- a/openbsc/include/openbsc/chan_alloc.h
+++ b/openbsc/include/openbsc/chan_alloc.h
@@ -45,6 +45,7 @@
/* Free a logical channel (SDCCH, TCH, ...) */
void lchan_free(struct gsm_lchan *lchan);
+void lchan_reset(struct gsm_lchan *lchan);
/* Consider releasing the channel */
int lchan_auto_release(struct gsm_lchan *lchan);
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 8dfa588..52b82c0 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -73,6 +73,12 @@
GSM_PAGING_OOM,
};
+enum bts_gprs_mode {
+ BTS_GPRS_NONE = 0,
+ BTS_GPRS_GPRS = 1,
+ BTS_GPRS_EGPRS = 2,
+};
+
struct msgb;
typedef int gsm_cbfn(unsigned int hooknum,
unsigned int event,
@@ -250,6 +256,7 @@
u_int16_t bound_port;
u_int16_t connect_port;
u_int16_t conn_id;
+ u_int8_t rtp_payload;
u_int8_t rtp_payload2;
u_int8_t speech_mode;
struct rtp_socket *rtp_socket;
@@ -368,7 +375,6 @@
struct gsm_bts_paging_state {
/* pending requests */
struct llist_head pending_requests;
- struct gsm_paging_request *last_request;
struct gsm_bts *bts;
struct timer_list work_timer;
@@ -476,7 +482,7 @@
/* Not entirely sure how ip.access specific this is */
struct {
- int enabled;
+ enum bts_gprs_mode mode;
struct {
struct gsm_nm_state nm_state;
u_int16_t nsei;
@@ -535,6 +541,14 @@
struct counter *alerted; /* we alerted the other end */
struct counter *connected;/* how many calls were accepted */
} call;
+ struct {
+ struct counter *rf_fail;
+ struct counter *rll_err;
+ } chan;
+ struct {
+ struct counter *oml_fail;
+ struct counter *rsl_fail;
+ } bts;
};
enum gsm_auth_policy {
@@ -697,6 +711,9 @@
enum rrlp_mode rrlp_mode_parse(const char *arg);
const char *rrlp_mode_name(enum rrlp_mode mode);
+enum bts_gprs_mode bts_gprs_mode_parse(const char *arg);
+const char *bts_gprs_mode_name(enum bts_gprs_mode mode);
+
void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
/* A parsed GPRS routing area */
diff --git a/openbsc/include/openbsc/ipaccess.h b/openbsc/include/openbsc/ipaccess.h
index 86248aa..f8ddfd4 100644
--- a/openbsc/include/openbsc/ipaccess.h
+++ b/openbsc/include/openbsc/ipaccess.h
@@ -53,6 +53,8 @@
int ipaccess_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len);
+int ipaccess_drop_oml(struct gsm_bts *bts);
+int ipaccess_drop_rsl(struct gsm_bts_trx *trx);
/*
* Firmware specific header
diff --git a/openbsc/include/openbsc/rest_octets.h b/openbsc/include/openbsc/rest_octets.h
index 4e72c0f..6d90119 100644
--- a/openbsc/include/openbsc/rest_octets.h
+++ b/openbsc/include/openbsc/rest_octets.h
@@ -71,6 +71,7 @@
GPRS_NMO_III = 2, /* no paging coordination */
};
+/* TS 04.60 12.24 */
struct gprs_cell_options {
enum gprs_nmo nmo;
/* T3168: wait for packet uplink assignment message */
@@ -79,6 +80,16 @@
u_int32_t t3192; /* in milliseconds */
u_int32_t drx_timer_max;/* in seconds */
u_int32_t bs_cv_max;
+
+ u_int8_t ext_info_present;
+ struct {
+ u_int8_t egprs_supported;
+ u_int8_t use_egprs_p_ch_req;
+ u_int8_t bep_period;
+ u_int8_t pfc_supported;
+ u_int8_t dtm_supported;
+ u_int8_t bss_paging_coordination;
+ } ext_info;
};
/* TS 04.60 Table 12.9.2 */
diff --git a/openbsc/include/openbsc/rtp_proxy.h b/openbsc/include/openbsc/rtp_proxy.h
index f82711a..65b1a5f 100644
--- a/openbsc/include/openbsc/rtp_proxy.h
+++ b/openbsc/include/openbsc/rtp_proxy.h
@@ -28,6 +28,12 @@
#include <osmocore/linuxlist.h>
#include <osmocore/select.h>
+#define RTP_PT_GSM_FULL 3
+#define RTP_PT_GSM_HALF 96
+#define RTP_PT_GSM_EFR 97
+#define RTP_PT_AMR_FULL 98
+#define RTP_PT_AMR_HALF 99
+
enum rtp_rx_action {
RTP_NONE,
RTP_PROXY,
diff --git a/openbsc/include/openbsc/vty.h b/openbsc/include/openbsc/vty.h
index 40e2191..f1b1148 100644
--- a/openbsc/include/openbsc/vty.h
+++ b/openbsc/include/openbsc/vty.h
@@ -1,6 +1,10 @@
#ifndef OPENBSC_VTY_H
#define OPENBSC_VTY_H
+struct gsm_network;
+struct vty;
+
void openbsc_vty_add_cmds(void);
+void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *);
#endif
diff --git a/openbsc/src/abis_nm.c b/openbsc/src/abis_nm.c
index 5e6e819..c78ee56 100644
--- a/openbsc/src/abis_nm.c
+++ b/openbsc/src/abis_nm.c
@@ -822,15 +822,56 @@
return abis_nm_sendmsg(bts, msg);
}
+static int abis_nm_parse_sw_descr(const u_int8_t *sw_descr, int sw_descr_len)
+{
+ static const struct tlv_definition sw_descr_def = {
+ .def = {
+ [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V, },
+ [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V, },
+ },
+ };
+
+ u_int8_t tag;
+ u_int16_t tag_len;
+ const u_int8_t *val;
+ int ofs = 0, len;
+
+ /* Classic TLV parsing doesn't work well with SW_DESCR because of it's
+ * nested nature and the fact you have to assume it contains only two sub
+ * tags NM_ATT_FILE_VERSION & NM_ATT_FILE_ID to parse it */
+
+ if (sw_descr[0] != NM_ATT_SW_DESCR) {
+ DEBUGP(DNM, "SW_DESCR attribute identifier not found!\n");
+ return -1;
+ }
+ ofs += 1;
+
+ len = tlv_parse_one(&tag, &tag_len, &val,
+ &sw_descr_def, &sw_descr[ofs], sw_descr_len-ofs);
+ if (len < 0 || (tag != NM_ATT_FILE_ID)) {
+ DEBUGP(DNM, "FILE_ID attribute identifier not found!\n");
+ return -2;
+ }
+ ofs += len;
+
+ len = tlv_parse_one(&tag, &tag_len, &val,
+ &sw_descr_def, &sw_descr[ofs], sw_descr_len-ofs);
+ if (len < 0 || (tag != NM_ATT_FILE_VERSION)) {
+ DEBUGP(DNM, "FILE_VERSION attribute identifier not found!\n");
+ return -3;
+ }
+ ofs += len;
+
+ return ofs;
+}
+
static int abis_nm_rx_sw_act_req(struct msgb *mb)
{
struct abis_om_hdr *oh = msgb_l2(mb);
struct abis_om_fom_hdr *foh = msgb_l3(mb);
struct tlv_parsed tp;
const u_int8_t *sw_config;
- int sw_config_len;
- int file_id_len;
- int ret;
+ int ret, sw_config_len, sw_descr_len;
debugp_foh(foh);
@@ -854,20 +895,16 @@
DEBUGP(DNM, "Found SW config: %s\n", hexdump(sw_config, sw_config_len));
}
- if (sw_config[0] != NM_ATT_SW_DESCR)
- DEBUGP(DNM, "SW_DESCR attribute identifier not found!\n");
- if (sw_config[1] != NM_ATT_FILE_ID)
- DEBUGP(DNM, "FILE_ID attribute identifier not found!\n");
- file_id_len = sw_config[2] * 256 + sw_config[3];
+ /* Use the first SW_DESCR present in SW config */
+ sw_descr_len = abis_nm_parse_sw_descr(sw_config, sw_config_len);
+ if (sw_descr_len < 0)
+ return -EINVAL;
- /* Assumes first SW file in list is the one to be activated */
- /* sw_config + 4 to skip over 2 attribute ID bytes and 16-bit length field */
return ipacc_sw_activate(mb->trx->bts, foh->obj_class,
foh->obj_inst.bts_nr,
foh->obj_inst.trx_nr,
foh->obj_inst.ts_nr,
- sw_config + 4,
- file_id_len);
+ sw_config, sw_descr_len);
}
/* Receive a CHANGE_ADM_STATE_ACK, parse the TLV and update local state */
diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c
index 0e572cc..53b2982 100644
--- a/openbsc/src/abis_rsl.c
+++ b/openbsc/src/abis_rsl.c
@@ -727,7 +727,6 @@
link_id, 0);
msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */
- lchan->state = LCHAN_S_REL_REQ;
/* FIXME: start some timer in case we don't receive a REL ACK ? */
msg->trx = lchan->ts->trx;
@@ -735,6 +734,12 @@
return abis_rsl_sendmsg(msg);
}
+int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
+{
+ lchan->state = state;
+ return 0;
+}
+
/* Chapter 8.4.2: Channel Activate Acknowledge */
static int rsl_rx_chan_act_ack(struct msgb *msg)
{
@@ -749,7 +754,7 @@
LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
gsm_lchan_name(msg->lchan),
gsm_lchans_name(msg->lchan->state));
- msg->lchan->state = LCHAN_S_ACTIVE;
+ rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_ACK, msg->lchan);
@@ -775,9 +780,9 @@
print_rsl_cause(LOGL_ERROR, cause,
TLVP_LEN(&tp, RSL_IE_CAUSE));
if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
- msg->lchan->state = LCHAN_S_NONE;
+ rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
} else
- msg->lchan->state = LCHAN_S_NONE;
+ rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
LOGPC(DRSL, LOGL_ERROR, "\n");
@@ -805,6 +810,7 @@
LOGPC(DRSL, LOGL_NOTICE, "\n");
/* FIXME: only free it after channel release ACK */
+ counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
return rsl_rf_chan_release(msg->lchan);
}
@@ -981,7 +987,7 @@
LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
gsm_lchan_name(msg->lchan),
gsm_lchans_name(msg->lchan->state));
- msg->lchan->state = LCHAN_S_NONE;
+ rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
lchan_free(msg->lchan);
break;
case RSL_MT_MODE_MODIFY_ACK:
@@ -1124,7 +1130,7 @@
LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
"in state %s\n", gsm_lchan_name(lchan),
gsm_lchans_name(lchan->state));
- lchan->state = LCHAN_S_ACT_REQ;
+ rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
ts_number = lchan->ts->nr;
arfcn = lchan->ts->trx->arfcn;
@@ -1181,6 +1187,10 @@
switch (rslh->data[0]) {
case RSL_IE_PAGING_LOAD:
pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
+ if (is_ipaccess_bts(msg->trx->bts) && pg_buf_space == 0xffff) {
+ /* paging load below configured threshold, use 50 as default */
+ pg_buf_space = 50;
+ }
paging_update_buffer_space(msg->trx->bts, pg_buf_space);
break;
case RSL_IE_RACH_LOAD:
@@ -1240,8 +1250,10 @@
rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
- if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
+ if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED) {
+ counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
return rsl_rf_chan_release(msg->lchan);
+ }
return 0;
}
@@ -1363,6 +1375,44 @@
return 0;
}
+static u_int8_t ipa_rtp_pt_for_lchan(struct gsm_lchan *lchan)
+{
+ switch (lchan->tch_mode) {
+ case GSM48_CMODE_SPEECH_V1:
+ switch (lchan->type) {
+ case GSM_LCHAN_TCH_F:
+ return RTP_PT_GSM_FULL;
+ case GSM_LCHAN_TCH_H:
+ return RTP_PT_GSM_HALF;
+ default:
+ break;
+ }
+ case GSM48_CMODE_SPEECH_EFR:
+ switch (lchan->type) {
+ case GSM_LCHAN_TCH_F:
+ return RTP_PT_GSM_EFR;
+ /* there's no half-rate EFR */
+ default:
+ break;
+ }
+ case GSM48_CMODE_SPEECH_AMR:
+ switch (lchan->type) {
+ case GSM_LCHAN_TCH_F:
+ return RTP_PT_AMR_FULL;
+ case GSM_LCHAN_TCH_H:
+ return RTP_PT_AMR_HALF;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+ LOGP(DRSL, LOGL_ERROR, "Cannot determine ip.access rtp payload type for "
+ "tch_mode == 0x%02x\n & lchan_type == %d",
+ lchan->tch_mode, lchan->type);
+ return 0;
+}
+
/* ip.access specific RSL extensions */
static void ipac_parse_rtp(struct gsm_lchan *lchan, struct tlv_parsed *tv)
{
@@ -1429,10 +1479,13 @@
/* 0x1- == receive-only, 0x-1 == EFR codec */
lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
+ lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
+ msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
- DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x\n",
- gsm_lchan_name(lchan), lchan->abis_ip.speech_mode);
+ DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x RTP_PAYLOAD=%d\n",
+ gsm_lchan_name(lchan), lchan->abis_ip.speech_mode,
+ lchan->abis_ip.rtp_payload);
msg->trx = lchan->ts->trx;
@@ -1459,11 +1512,13 @@
/* 0x0- == both directions, 0x-1 == EFR codec */
lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
+ lchan->abis_ip.rtp_payload = ipa_rtp_pt_for_lchan(lchan);
ia.s_addr = htonl(ip);
- DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d "
- "speech_mode=0x%02x\n", gsm_lchan_name(lchan), inet_ntoa(ia), port,
- rtp_payload2, lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
+ DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD=%d RTP_PAYLOAD2=%d "
+ "CONN_ID=%d speech_mode=0x%02x\n", gsm_lchan_name(lchan),
+ inet_ntoa(ia), port, lchan->abis_ip.rtp_payload, rtp_payload2,
+ lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
msgb_v_put(msg, RSL_IE_IPAC_REMOTE_IP);
@@ -1471,6 +1526,7 @@
*att_ip = ia.s_addr;
msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, port);
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
+ msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
if (rtp_payload2)
msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
@@ -1652,9 +1708,21 @@
/* Entry-point where L2 RSL from BTS enters */
int abis_rsl_rcvmsg(struct msgb *msg)
{
- struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
+ struct abis_rsl_common_hdr *rslh;
int rc = 0;
+ if (!msg) {
+ DEBUGP(DRSL, "Empty RSL msg?..\n");
+ return -1;
+ }
+
+ if (msgb_l2len(msg) < sizeof(*rslh)) {
+ DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
+ return -1;
+ }
+
+ rslh = msgb_l2(msg);
+
switch (rslh->msg_discr & 0xfe) {
case ABIS_RSL_MDISC_RLL:
rc = abis_rsl_rx_rll(msg);
diff --git a/openbsc/src/bsc_init.c b/openbsc/src/bsc_init.c
index f343662..a39bc19 100644
--- a/openbsc/src/bsc_init.c
+++ b/openbsc/src/bsc_init.c
@@ -31,6 +31,7 @@
#include <openbsc/system_information.h>
#include <openbsc/paging.h>
#include <openbsc/signal.h>
+#include <openbsc/chan_alloc.h>
#include <osmocore/talloc.h>
/* global pointer to the gsm network data structure */
@@ -377,11 +378,11 @@
4, /* N3103 */
8, /* N3105 */
15, /* RLC CV countdown */
- NM_ATT_IPACC_CODING_SCHEMES, 0, 2, 0x0f, 0x00,
+ NM_ATT_IPACC_CODING_SCHEMES, 0, 2, 0x0f, 0x00, /* CS1..CS4 */
NM_ATT_IPACC_RLC_CFG_2, 0, 5,
- 0x00, 250,
- 0x00, 250,
- 2, /* MCS2 */
+ 0x00, 250, /* T downlink TBF extension (0..500) */
+ 0x00, 250, /* T uplink TBF extension (0..500) */
+ 2, /* CS2 */
#if 0
/* EDGE model only, breaks older models.
* Should inquire the BTS capabilities */
@@ -461,7 +462,7 @@
break;
case NM_OC_GPRS_NSE:
bts = container_of(obj, struct gsm_bts, gprs.nse);
- if (!bts->gprs.enabled)
+ if (bts->gprs.mode == BTS_GPRS_NONE)
break;
if (new_state->availability == 5) {
abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
@@ -475,7 +476,7 @@
break;
case NM_OC_GPRS_CELL:
bts = container_of(obj, struct gsm_bts, gprs.cell);
- if (!bts->gprs.enabled)
+ if (bts->gprs.mode == BTS_GPRS_NONE)
break;
if (new_state->availability == 5) {
abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
@@ -490,7 +491,7 @@
case NM_OC_GPRS_NSVC:
nsvc = obj;
bts = nsvc->bts;
- if (!bts->gprs.enabled)
+ if (bts->gprs.mode == BTS_GPRS_NONE)
break;
/* We skip NSVC1 since we only use NSVC0 */
if (nsvc->id == 1)
@@ -798,7 +799,7 @@
DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
rsl_bcch_info(trx, i, si_tmp, sizeof(si_tmp));
}
- if (bts->gprs.enabled) {
+ if (bts->gprs.mode != BTS_GPRS_NONE) {
i = 13;
rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_13);
if (rc < 0)
@@ -885,6 +886,11 @@
/* patch RAC */
nanobts_attr_cell[3] = bts->gprs.rac;
+ if (bts->gprs.mode == BTS_GPRS_EGPRS) {
+ /* patch EGPRS coding schemes MCS 1..9 */
+ nanobts_attr_cell[29] = 0x8f;
+ nanobts_attr_cell[30] = 0xff;
+ }
}
static void bootstrap_rsl(struct gsm_bts_trx *trx)
@@ -899,6 +905,8 @@
void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
{
+ int ts_no, lchan_no;
+
switch (event) {
case EVT_E1_TEI_UP:
switch (type) {
@@ -913,8 +921,35 @@
}
break;
case EVT_E1_TEI_DN:
- LOGP(DMI, LOGL_NOTICE, "Lost some E1 TEI link\n");
- /* FIXME: deal with TEI or L1 link loss */
+ LOGP(DMI, LOGL_ERROR, "Lost some E1 TEI link: %d %p\n", type, trx);
+
+ if (type == E1INP_SIGN_OML)
+ counter_inc(trx->bts->network->stats.bts.oml_fail);
+ else if (type == E1INP_SIGN_RSL)
+ counter_inc(trx->bts->network->stats.bts.rsl_fail);
+
+ /*
+ * free all allocated channels. change the nm_state so the
+ * trx and trx_ts becomes unusable and chan_alloc.c can not
+ * allocate from it.
+ */
+ for (ts_no = 0; ts_no < ARRAY_SIZE(trx->ts); ++ts_no) {
+ struct gsm_bts_trx_ts *ts = &trx->ts[ts_no];
+
+ for (lchan_no = 0; lchan_no < ARRAY_SIZE(ts->lchan); ++lchan_no) {
+ if (ts->lchan[lchan_no].state != GSM_LCHAN_NONE)
+ lchan_free(&ts->lchan[lchan_no]);
+ lchan_reset(&ts->lchan[lchan_no]);
+ }
+
+ ts->nm_state.operational = 0;
+ ts->nm_state.availability = 0;
+ }
+
+ trx->nm_state.operational = 0;
+ trx->nm_state.availability = 0;
+ trx->bb_transc.nm_state.operational = 0;
+ trx->bb_transc.nm_state.availability = 0;
break;
default:
break;
diff --git a/openbsc/src/chan_alloc.c b/openbsc/src/chan_alloc.c
index cd48e43..107abdc 100644
--- a/openbsc/src/chan_alloc.c
+++ b/openbsc/src/chan_alloc.c
@@ -330,6 +330,20 @@
* channel using it */
}
+/*
+ * There was an error with the TRX and we need to forget
+ * any state so that a lchan can be allocated again after
+ * the trx is fully usable.
+ */
+void lchan_reset(struct gsm_lchan *lchan)
+{
+ bsc_del_timer(&lchan->T3101);
+
+ lchan->type = GSM_LCHAN_NONE;
+ lchan->state = LCHAN_S_NONE;
+}
+
+
/* Consider releasing the channel now */
int lchan_auto_release(struct gsm_lchan *lchan)
{
@@ -348,6 +362,7 @@
lchan->conn.use_count);
DEBUGP(DRLL, "%s Recycling Channel\n", gsm_lchan_name(lchan));
+ rsl_lchan_set_state(lchan, LCHAN_S_REL_REQ);
rsl_release_request(lchan, 0);
return 1;
}
diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c
index 176367d..4d8fa17 100644
--- a/openbsc/src/gsm_data.c
+++ b/openbsc/src/gsm_data.c
@@ -280,6 +280,10 @@
net->stats.call.dialled = counter_alloc("net.call.dialled");
net->stats.call.alerted = counter_alloc("net.call.alerted");
net->stats.call.connected = counter_alloc("net.call.connected");
+ net->stats.chan.rf_fail = counter_alloc("net.chan.rf_fail");
+ net->stats.chan.rll_err = counter_alloc("net.chan.rll_err");
+ net->stats.bts.oml_fail = counter_alloc("net.bts.oml_fail");
+ net->stats.bts.rsl_fail = counter_alloc("net.bts.rsl_fail");
net->mncc_recv = mncc_recv;
@@ -498,6 +502,23 @@
return get_value_string(rrlp_mode_names, mode);
}
+static const struct value_string bts_gprs_mode_names[] = {
+ { BTS_GPRS_NONE, "none" },
+ { BTS_GPRS_GPRS, "gprs" },
+ { BTS_GPRS_EGPRS, "egprs" },
+ { 0, NULL }
+};
+
+enum bts_gprs_mode bts_gprs_mode_parse(const char *arg)
+{
+ return get_string_value(bts_gprs_mode_names, arg);
+}
+
+const char *bts_gprs_mode_name(enum bts_gprs_mode mode)
+{
+ return get_value_string(bts_gprs_mode_names, mode);
+}
+
struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan)
{
struct gsm_meas_rep *meas_rep;
diff --git a/openbsc/src/handover_logic.c b/openbsc/src/handover_logic.c
index 7fb0b13..b2ffe46 100644
--- a/openbsc/src/handover_logic.c
+++ b/openbsc/src/handover_logic.c
@@ -134,6 +134,7 @@
return rc;
}
+ rsl_lchan_set_state(new_lchan, LCHAN_S_ACT_REQ);
llist_add(&ho->list, &bsc_handovers);
/* we continue in the SS_LCHAN handler / ho_chan_activ_ack */
@@ -229,7 +230,7 @@
/* update lchan pointer of transaction */
trans_lchan_change(&ho->old_lchan->conn, &new_lchan->conn);
- ho->old_lchan->state = LCHAN_S_INACTIVE;
+ rsl_lchan_set_state(ho->old_lchan, LCHAN_S_INACTIVE);
lchan_auto_release(ho->old_lchan);
/* do something to re-route the actual speech frames ! */
diff --git a/openbsc/src/input/ipaccess.c b/openbsc/src/input/ipaccess.c
index 323540f..8a8a198 100644
--- a/openbsc/src/input/ipaccess.c
+++ b/openbsc/src/input/ipaccess.c
@@ -1,6 +1,8 @@
/* OpenBSC Abis input driver for ip.access */
/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2010 by Holger Hans Peter Freyther
+ * (C) 2010 by On-Waves
*
* All Rights Reserved
*
@@ -57,7 +59,7 @@
static struct ia_e1_handle *e1h;
-#define TS1_ALLOC_SIZE 300
+#define TS1_ALLOC_SIZE 900
static const u_int8_t pong[] = { 0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_PONG };
static const u_int8_t id_ack[] = { 0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_ACK };
@@ -234,6 +236,8 @@
}
DEBUGP(DINP, "Identified BTS %u/%u/%u\n", site_id, bts_id, trx_id);
if (bfd->priv_nr == PRIV_OML) {
+ /* drop any old oml connection */
+ ipaccess_drop_oml(bts);
bts->oml_link = e1inp_sign_link_create(&line->ts[PRIV_OML - 1],
E1INP_SIGN_OML, bts->c0,
bts->oml_tei, 0);
@@ -241,7 +245,18 @@
struct e1inp_ts *e1i_ts;
struct bsc_fd *newbfd;
struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_id);
-
+
+ /* drop any old rsl connection */
+ ipaccess_drop_rsl(trx);
+
+ if (!bts->oml_link) {
+ bsc_unregister_fd(bfd);
+ close(bfd->fd);
+ bfd->fd = -1;
+ talloc_free(bfd);
+ return 0;
+ }
+
bfd->data = line = bts->oml_link->ts->line;
e1i_ts = &line->ts[PRIV_RSL + trx_id - 1];
newbfd = &e1i_ts->driver.ipaccess.fd;
@@ -251,19 +266,13 @@
E1INP_SIGN_RSL, trx,
trx->rsl_tei, 0);
- if (newbfd->fd >= 0) {
- LOGP(DINP, LOGL_ERROR, "BTS is still registered. Closing old connection.\n");
- bsc_unregister_fd(newbfd);
- close(newbfd->fd);
- newbfd->fd = -1;
- }
-
/* get rid of our old temporary bfd */
memcpy(newbfd, bfd, sizeof(*newbfd));
newbfd->priv_nr = PRIV_RSL + trx_id;
bsc_unregister_fd(bfd);
- bsc_register_fd(newbfd);
+ bfd->fd = -1;
talloc_free(bfd);
+ bsc_register_fd(newbfd);
}
break;
}
@@ -328,6 +337,103 @@
return msg;
}
+int ipaccess_drop_oml(struct gsm_bts *bts)
+{
+ struct gsm_bts_trx *trx;
+ struct e1inp_ts *ts;
+ struct e1inp_line *line;
+ struct bsc_fd *bfd;
+
+ if (!bts || !bts->oml_link)
+ return -1;
+
+ /* send OML down */
+ ts = bts->oml_link->ts;
+ line = ts->line;
+ e1inp_event(ts, EVT_E1_TEI_DN, bts->oml_link->tei, bts->oml_link->sapi);
+
+ bfd = &ts->driver.ipaccess.fd;
+ bsc_unregister_fd(bfd);
+ close(bfd->fd);
+ bfd->fd = -1;
+
+ /* clean up OML and RSL */
+ e1inp_sign_link_destroy(bts->oml_link);
+ bts->oml_link = NULL;
+ bts->ip_access.flags = 0;
+
+ /* drop all RSL connections too */
+ llist_for_each_entry(trx, &bts->trx_list, list)
+ ipaccess_drop_rsl(trx);
+
+ /* kill the E1 line now... as we have no one left to use it */
+ talloc_free(line);
+
+ return -1;
+}
+
+static int ipaccess_drop(struct e1inp_ts *ts, struct bsc_fd *bfd)
+{
+ struct e1inp_sign_link *link;
+ int bts_nr;
+
+ if (!ts) {
+ /*
+ * If we don't have a TS this means that this is a RSL
+ * connection but we are not past the authentication
+ * handling yet. So we can safely delete this bfd and
+ * wait for a reconnect.
+ */
+ bsc_unregister_fd(bfd);
+ close(bfd->fd);
+ bfd->fd = -1;
+ talloc_free(bfd);
+ return -1;
+ }
+
+ /* attempt to find a signalling link */
+ if (ts->type == E1INP_TS_TYPE_SIGN) {
+ llist_for_each_entry(link, &ts->sign.sign_links, list) {
+ bts_nr = link->trx->bts->bts_nr;
+ /* we have issues just reconnecting RLS so we drop OML */
+ ipaccess_drop_oml(link->trx->bts);
+ return bts_nr;
+ }
+ }
+
+ /* error case */
+ LOGP(DINP, LOGL_ERROR, "Failed to find a signalling link for ts: %p\n", ts);
+ bsc_unregister_fd(bfd);
+ close(bfd->fd);
+ bfd->fd = -1;
+ return -1;
+}
+
+int ipaccess_drop_rsl(struct gsm_bts_trx *trx)
+{
+ struct bsc_fd *bfd;
+ struct e1inp_ts *ts;
+
+ if (!trx || !trx->rsl_link)
+ return -1;
+
+ /* send RSL down */
+ ts = trx->rsl_link->ts;
+ e1inp_event(ts, EVT_E1_TEI_DN, trx->rsl_link->tei, trx->rsl_link->sapi);
+
+ /* close the socket */
+ bfd = &ts->driver.ipaccess.fd;
+ bsc_unregister_fd(bfd);
+ close(bfd->fd);
+ bfd->fd = -1;
+
+ /* destroy */
+ e1inp_sign_link_destroy(trx->rsl_link);
+ trx->rsl_link = NULL;
+
+ return -1;
+}
+
static int handle_ts1_read(struct bsc_fd *bfd)
{
struct e1inp_line *line = bfd->data;
@@ -341,18 +447,12 @@
msg = ipaccess_read_msg(bfd, &error);
if (!msg) {
if (error == 0) {
- link = e1inp_lookup_sign_link(e1i_ts, IPAC_PROTO_OML, 0);
- if (link) {
- link->trx->bts->ip_access.flags = 0;
+ int ret = ipaccess_drop(e1i_ts, bfd);
+ if (ret >= 0)
LOGP(DINP, LOGL_NOTICE, "BTS %u disappeared, dead socket\n",
- link->trx->bts->nr);
- } else
+ ret);
+ else
LOGP(DINP, LOGL_NOTICE, "unknown BTS disappeared, dead socket\n");
- e1inp_event(e1i_ts, EVT_E1_TEI_DN, 0, IPAC_PROTO_RSL);
- e1inp_event(e1i_ts, EVT_E1_TEI_DN, 0, IPAC_PROTO_OML);
- bsc_unregister_fd(bfd);
- close(bfd->fd);
- bfd->fd = -1;
}
return error;
}
@@ -362,13 +462,8 @@
hh = (struct ipaccess_head *) msg->data;
if (hh->proto == IPAC_PROTO_IPACCESS) {
ret = ipaccess_rcvmsg(line, msg, bfd);
- if (ret < 0) {
- e1inp_event(e1i_ts, EVT_E1_TEI_DN, 0, IPAC_PROTO_RSL);
- e1inp_event(e1i_ts, EVT_E1_TEI_DN, 0, IPAC_PROTO_OML);
- bsc_unregister_fd(bfd);
- close(bfd->fd);
- bfd->fd = -1;
- }
+ if (ret < 0)
+ ipaccess_drop(e1i_ts, bfd);
msgb_free(msg);
return ret;
}
@@ -475,7 +570,9 @@
/* set tx delay timer for next event */
e1i_ts->sign.tx_timer.cb = timeout_ts1_write;
e1i_ts->sign.tx_timer.data = e1i_ts;
- bsc_schedule_timer(&e1i_ts->sign.tx_timer, 0, 100);
+
+ /* Reducing this might break the nanoBTS 900 init. */
+ bsc_schedule_timer(&e1i_ts->sign.tx_timer, 0, 100000);
return ret;
}
diff --git a/openbsc/src/openbsc.cfg.nanobts b/openbsc/src/openbsc.cfg.nanobts
index a1ceaec..da0ba74 100644
--- a/openbsc/src/openbsc.cfg.nanobts
+++ b/openbsc/src/openbsc.cfg.nanobts
@@ -1,6 +1,6 @@
!
! OpenBSC configuration saved from vty
-!
+! !
password foo
!
line vty
@@ -11,17 +11,52 @@
mobile network code 1
short name OpenBSC
long name OpenBSC
+ auth policy closed
+ location updating reject cause 13
+ encryption a5 0
+ neci 0
+ rrlp mode none
+ mm info 1
+ handover 0
+ handover window rxlev averaging 10
+ handover window rxqual averaging 1
+ handover window rxlev neighbor averaging 10
+ handover power budget interval 6
+ handover power budget hysteresis 3
+ handover maximum distance 9999
timer t3101 10
+ timer t3103 0
+ timer t3105 0
+ timer t3107 0
+ timer t3109 0
+ timer t3111 0
timer t3113 60
+ timer t3115 0
+ timer t3117 0
+ timer t3119 0
+ timer t3141 0
bts 0
type nanobts
- ip.access unit_id 1801 0
- band GSM1800
+ band DCS1800
+ cell_identity 0
location_area_code 1
training_sequence_code 7
base_station_id_code 63
+ ms max power 15
+ cell reselection hysteresis 4
+ rxlev access min 0
+ channel allocator ascending
+ rach tx integer 9
+ rach max transmission 7
+ ip.access unit_id 1801 0
+ oml ip.access stream_id 255
+ gprs mode none
trx 0
+ rf_locked 0
arfcn 514
+ nominal power 23
+ max_power_red 20
+ rsl e1 tei 0
timeslot 0
phys_chan_config CCCH+SDCCH4
timeslot 1
diff --git a/openbsc/src/openbsc.cfg.nanobts.multitrx b/openbsc/src/openbsc.cfg.nanobts.multitrx
new file mode 100644
index 0000000..d9fb54b
--- /dev/null
+++ b/openbsc/src/openbsc.cfg.nanobts.multitrx
@@ -0,0 +1,97 @@
+!
+! OpenBSC configuration saved from vty
+! !
+password foo
+!
+line vty
+ no login
+!
+network
+ network country code 1
+ mobile network code 1
+ short name OpenBSC
+ long name OpenBSC
+ auth policy closed
+ location updating reject cause 13
+ encryption a5 0
+ neci 0
+ rrlp mode none
+ mm info 0
+ handover 0
+ handover window rxlev averaging 10
+ handover window rxqual averaging 1
+ handover window rxlev neighbor averaging 10
+ handover power budget interval 6
+ handover power budget hysteresis 3
+ handover maximum distance 9999
+ timer t3101 10
+ timer t3103 0
+ timer t3105 0
+ timer t3107 0
+ timer t3109 0
+ timer t3111 0
+ timer t3113 60
+ timer t3115 0
+ timer t3117 0
+ timer t3119 0
+ timer t3141 0
+ bts 0
+ type nanobts
+ band DCS1800
+ cell_identity 0
+ location_area_code 1
+ training_sequence_code 7
+ base_station_id_code 63
+ ms max power 15
+ cell reselection hysteresis 4
+ rxlev access min 0
+ channel allocator ascending
+ rach tx integer 9
+ rach max transmission 7
+ ip.access unit_id 1800 0
+ oml ip.access stream_id 255
+ gprs mode none
+ trx 0
+ rf_locked 0
+ arfcn 871
+ nominal power 23
+ max_power_red 0
+ rsl e1 tei 0
+ timeslot 0
+ phys_chan_config CCCH+SDCCH4
+ timeslot 1
+ phys_chan_config SDCCH8
+ timeslot 2
+ phys_chan_config TCH/F
+ timeslot 3
+ phys_chan_config TCH/F
+ timeslot 4
+ phys_chan_config TCH/F
+ timeslot 5
+ phys_chan_config TCH/F
+ timeslot 6
+ phys_chan_config TCH/F
+ timeslot 7
+ phys_chan_config TCH/F
+ trx 1
+ rf_locked 0
+ arfcn 873
+ nominal power 23
+ max_power_red 0
+ rsl e1 tei 0
+ timeslot 0
+ phys_chan_config CCCH+SDCCH4
+ timeslot 1
+ phys_chan_config SDCCH8
+ timeslot 2
+ phys_chan_config TCH/F
+ timeslot 3
+ phys_chan_config TCH/F
+ timeslot 4
+ phys_chan_config TCH/F
+ timeslot 5
+ phys_chan_config TCH/F
+ timeslot 6
+ phys_chan_config TCH/F
+ timeslot 7
+ phys_chan_config TCH/F
diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c
index 7c3750d..314d3d1 100644
--- a/openbsc/src/paging.c
+++ b/openbsc/src/paging.c
@@ -45,6 +45,7 @@
#include <openbsc/signal.h>
#include <openbsc/abis_rsl.h>
#include <openbsc/gsm_data.h>
+#include <openbsc/chan_alloc.h>
void *tall_paging_ctx;
@@ -70,14 +71,6 @@
static void paging_remove_request(struct gsm_bts_paging_state *paging_bts,
struct gsm_paging_request *to_be_deleted)
{
- /* Update the last_request if that is necessary */
- if (to_be_deleted == paging_bts->last_request) {
- paging_bts->last_request =
- (struct gsm_paging_request *)paging_bts->last_request->entry.next;
- if (&to_be_deleted->entry == &paging_bts->pending_requests)
- paging_bts->last_request = NULL;
- }
-
bsc_del_timer(&to_be_deleted->T3113);
llist_del(&to_be_deleted->entry);
subscr_put(to_be_deleted->subscr);
@@ -90,7 +83,7 @@
unsigned int mi_len;
unsigned int page_group;
- DEBUGP(DPAG, "Going to send paging commands: imsi: '%s' tmsi: '0x%x'\n",
+ LOGP(DPAG, LOGL_INFO, "Going to send paging commands: imsi: '%s' tmsi: '0x%x'\n",
request->subscr->imsi, request->subscr->tmsi);
if (request->subscr->tmsi == GSM_RESERVED_TMSI)
@@ -103,14 +96,6 @@
request->chan_type);
}
-static void paging_move_to_next(struct gsm_bts_paging_state *paging_bts)
-{
- paging_bts->last_request =
- (struct gsm_paging_request *)paging_bts->last_request->entry.next;
- if (&paging_bts->last_request->entry == &paging_bts->pending_requests)
- paging_bts->last_request = NULL;
-}
-
/*
* This is kicked by the periodic PAGING LOAD Indicator
* coming from abis_rsl.c
@@ -128,17 +113,26 @@
* return then.
*/
if (llist_empty(&paging_bts->pending_requests)) {
- paging_bts->last_request = NULL;
/* since the list is empty, no need to reschedule the timer */
return;
}
- if (!paging_bts->last_request)
- paging_bts->last_request =
- (struct gsm_paging_request *)paging_bts->pending_requests.next;
+ /*
+ * In case the BTS does not provide us with load indication just fill
+ * up our slots for this round. We should be able to page 20 subscribers
+ * every two seconds. So we will just give the BTS some extra credit.
+ * We will have to see how often we run out of this credit, so we might
+ * need a low watermark and then add credit or give 20 every run when
+ * the bts sets an option for that.
+ */
+ if (paging_bts->available_slots == 0) {
+ LOGP(DPAG, LOGL_NOTICE, "No slots available on bts nr %d\n",
+ paging_bts->bts->nr);
+ paging_bts->available_slots = 20;
+ }
- assert(paging_bts->last_request);
- initial_request = paging_bts->last_request;
+ initial_request = llist_entry(paging_bts->pending_requests.next,
+ struct gsm_paging_request, entry);
current_request = initial_request;
do {
@@ -146,21 +140,17 @@
page_ms(current_request);
paging_bts->available_slots--;
- /*
- * move to the next item. We might wrap around
- * this means last_request will be NULL and we just
- * call paging_page_to_next again. It it guranteed
- * that the list is not empty.
- */
- paging_move_to_next(paging_bts);
- if (!paging_bts->last_request)
- paging_bts->last_request =
- (struct gsm_paging_request *)paging_bts->pending_requests.next;
- current_request = paging_bts->last_request;
+ /* take the current and add it to the back */
+ llist_del(¤t_request->entry);
+ llist_add_tail(¤t_request->entry, &paging_bts->pending_requests);
+
+ /* take the next request */
+ current_request = llist_entry(paging_bts->pending_requests.next,
+ struct gsm_paging_request, entry);
} while (paging_bts->available_slots > 0
&& initial_request != current_request);
- bsc_schedule_timer(&paging_bts->work_timer, 1, 0);
+ bsc_schedule_timer(&paging_bts->work_timer, 2, 0);
}
static void paging_worker(void *data)
@@ -178,7 +168,7 @@
bts->paging.work_timer.data = &bts->paging;
/* Large number, until we get a proper message */
- bts->paging.available_slots = 100;
+ bts->paging.available_slots = 20;
}
static int paging_pending_request(struct gsm_bts_paging_state *bts,
@@ -200,7 +190,7 @@
void *cbfn_param;
gsm_cbfn *cbfn;
- DEBUGP(DPAG, "T3113 expired for request %p (%s)\n",
+ LOGP(DPAG, LOGL_INFO, "T3113 expired for request %p (%s)\n",
req, req->subscr->imsi);
sig_data.subscr = req->subscr;
@@ -208,11 +198,11 @@
sig_data.lchan = NULL;
/* must be destroyed before calling cbfn, to prevent double free */
+ counter_inc(req->bts->network->stats.paging.expired);
cbfn_param = req->cbfn_param;
cbfn = req->cbfn;
paging_remove_request(&req->bts->paging, req);
- counter_inc(req->bts->network->stats.paging.expired);
dispatch_signal(SS_PAGING, S_PAGING_EXPIRED, &sig_data);
if (cbfn)
@@ -227,11 +217,11 @@
struct gsm_paging_request *req;
if (paging_pending_request(bts_entry, subscr)) {
- DEBUGP(DPAG, "Paging request already pending\n");
+ LOGP(DPAG, LOGL_INFO, "Paging request already pending for %s\n", subscr->imsi);
return -EEXIST;
}
- DEBUGP(DPAG, "Start paging of subscriber %llu on bts %d.\n",
+ LOGP(DPAG, LOGL_DEBUG, "Start paging of subscriber %llu on bts %d.\n",
subscr->id, bts->nr);
req = talloc_zero(tall_paging_ctx, struct gsm_paging_request);
req->subscr = subscr_get(subscr);
@@ -245,7 +235,7 @@
llist_add_tail(&req->entry, &bts_entry->pending_requests);
if (!bsc_timer_pending(&bts_entry->work_timer))
- bsc_schedule_timer(&bts_entry->work_timer, 1, 0);
+ bsc_schedule_timer(&bts_entry->work_timer, 2, 0);
return 0;
}
@@ -296,11 +286,11 @@
entry) {
if (req->subscr == subscr) {
if (lchan && req->cbfn) {
- DEBUGP(DPAG, "Stop paging on bts %d, calling cbfn.\n", bts->nr);
+ LOGP(DPAG, LOGL_DEBUG, "Stop paging on bts %d, calling cbfn.\n", bts->nr);
req->cbfn(GSM_HOOK_RR_PAGING, GSM_PAGING_SUCCEEDED,
NULL, lchan, req->cbfn_param);
} else
- DEBUGP(DPAG, "Stop paging on bts %d silently.\n", bts->nr);
+ LOGP(DPAG, LOGL_DEBUG, "Stop paging on bts %d silently.\n", bts->nr);
paging_remove_request(&bts->paging, req);
break;
}
diff --git a/openbsc/src/rest_octets.c b/openbsc/src/rest_octets.c
index 16996ce..039d2c8 100644
--- a/openbsc/src/rest_octets.c
+++ b/openbsc/src/rest_octets.c
@@ -133,6 +133,7 @@
const struct gsm48_lsa_params *lsa_params)
{
/* FIXME */
+ return -1;
}
/* Generate SI4 Rest Octets (Chapter 10.5.2.35) */
@@ -318,8 +319,31 @@
/* hard-code no PAN_{DEC,INC,MAX} */
bitvec_set_bit(bv, 0);
- /* no extension information (EDGE) */
- bitvec_set_bit(bv, 0);
+ if (!gco->ext_info_present) {
+ /* no extension information */
+ bitvec_set_bit(bv, 0);
+ } else {
+ /* extension information */
+ bitvec_set_bit(bv, 1);
+ if (!gco->ext_info.egprs_supported) {
+ /* 6bit length of extension */
+ bitvec_set_uint(bv, (1 + 3)-1, 6);
+ /* EGPRS supported in the cell */
+ bitvec_set_bit(bv, 0);
+ } else {
+ /* 6bit length of extension */
+ bitvec_set_uint(bv, (1 + 5 + 3)-1, 6);
+ /* EGPRS supported in the cell */
+ bitvec_set_bit(bv, 1);
+ /* 1bit EGPRS PACKET CHANNEL REQUEST */
+ bitvec_set_bit(bv, gco->ext_info.use_egprs_p_ch_req);
+ /* 4bit BEP PERIOD */
+ bitvec_set_uint(bv, gco->ext_info.bep_period, 4);
+ }
+ bitvec_set_bit(bv, gco->ext_info.pfc_supported);
+ bitvec_set_bit(bv, gco->ext_info.dtm_supported);
+ bitvec_set_bit(bv, gco->ext_info.bss_paging_coordination);
+ }
return 0;
}
@@ -334,7 +358,7 @@
bitvec_set_uint(bv, pcp->n_avg_i, 4);
}
-/* Generate SI13 Rest Octests (Chapter 10.5.2.37b) */
+/* Generate SI13 Rest Octests (04.08 Chapter 10.5.2.37b) */
int rest_octets_si13(u_int8_t *data, const struct gsm48_si13_info *si13)
{
struct bitvec bv;
@@ -390,6 +414,11 @@
break;
}
}
+ /* 3GPP TS 44.018 Release 6 / 10.5.2.37b */
+ bitvec_set_bit(&bv, H); /* added Release 99 */
+ /* claim our SGSN is compatible with Release 99, as EDGE and EGPRS
+ * was only added in this Release */
+ bitvec_set_bit(&bv, 1);
}
bitvec_spare_padding(&bv, (bv.data_len*8)-1);
return bv.data_len;
diff --git a/openbsc/src/rtp_proxy.c b/openbsc/src/rtp_proxy.c
index 375204e..924173d 100644
--- a/openbsc/src/rtp_proxy.c
+++ b/openbsc/src/rtp_proxy.c
@@ -91,9 +91,6 @@
#define RTP_VERSION 2
-#define RTP_PT_GSM_FULL 3
-#define RTP_PT_GSM_EFR 97
-
/* decode an rtp frame and create a new buffer with payload */
static int rtp_decode(struct msgb *msg, u_int32_t callref, struct msgb **data)
{
diff --git a/openbsc/src/system_information.c b/openbsc/src/system_information.c
index 3f9d609..3bd833a 100644
--- a/openbsc/src/system_information.c
+++ b/openbsc/src/system_information.c
@@ -402,6 +402,16 @@
.t3192 = 500,
.drx_timer_max = 3,
.bs_cv_max = 15,
+ .ext_info_present = 0,
+ .ext_info = {
+ /* The values below are just guesses ! */
+ .egprs_supported = 0,
+ .use_egprs_p_ch_req = 1,
+ .bep_period = 4,
+ .pfc_supported = 0,
+ .dtm_supported = 0,
+ .bss_paging_coordination = 0,
+ },
},
.pwr_ctrl_pars = {
.alpha = 10, /* a = 1.0 */
@@ -448,7 +458,18 @@
int gsm_generate_si(u_int8_t *output, struct gsm_bts *bts, int type)
{
- si_info.gprs_ind.present = bts->gprs.enabled;
+ switch (bts->gprs.mode) {
+ case BTS_GPRS_EGPRS:
+ si13_default.cell_opts.ext_info_present = 1;
+ si13_default.cell_opts.ext_info.egprs_supported = 1;
+ /* fallthrough */
+ case BTS_GPRS_GPRS:
+ si_info.gprs_ind.present = 1;
+ break;
+ case BTS_GPRS_NONE:
+ si_info.gprs_ind.present = 0;
+ break;
+ }
switch (type) {
case RSL_SYSTEM_INFO_1:
diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c
index b5bdbc8..dd35372 100644
--- a/openbsc/src/vty_interface.c
+++ b/openbsc/src/vty_interface.c
@@ -266,6 +266,9 @@
int i;
vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE);
+ vty_out(vty, " rf_locked %u%s",
+ trx->nm_state.administrative == NM_STATE_LOCKED ? 1 : 0,
+ VTY_NEWLINE);
vty_out(vty, " arfcn %u%s", trx->arfcn, VTY_NEWLINE);
vty_out(vty, " nominal power %u%s", trx->nominal_power, VTY_NEWLINE);
vty_out(vty, " max_power_red %u%s", trx->max_power_red, VTY_NEWLINE);
@@ -315,8 +318,9 @@
config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
}
- vty_out(vty, " gprs enabled %u%s", bts->gprs.enabled, VTY_NEWLINE);
- if (bts->gprs.enabled) {
+ vty_out(vty, " gprs mode %s%s", bts_gprs_mode_name(bts->gprs.mode),
+ VTY_NEWLINE);
+ if (bts->gprs.mode != BTS_GPRS_NONE) {
vty_out(vty, " gprs routing area %u%s", bts->gprs.rac,
VTY_NEWLINE);
vty_out(vty, " gprs cell bvci %u%s", bts->gprs.cell.bvci,
@@ -540,10 +544,6 @@
static void subscr_dump_vty(struct vty *vty, struct gsm_subscriber *subscr)
{
- int rc;
- struct gsm_auth_info ainfo;
- struct gsm_auth_tuple atuple;
-
vty_out(vty, " ID: %llu, Authorized: %d%s", subscr->id,
subscr->authorized, VTY_NEWLINE);
if (subscr->name)
@@ -879,46 +879,6 @@
return CMD_SUCCESS;
}
-DEFUN(show_stats,
- show_stats_cmd,
- "show statistics",
- SHOW_STR "Display network statistics\n")
-{
- struct gsm_network *net = gsmnet;
-
- vty_out(vty, "Channel Requests : %lu total, %lu no channel%s",
- counter_get(net->stats.chreq.total),
- counter_get(net->stats.chreq.no_channel), VTY_NEWLINE);
- vty_out(vty, "Location Update : %lu attach, %lu normal, %lu periodic%s",
- counter_get(net->stats.loc_upd_type.attach),
- counter_get(net->stats.loc_upd_type.normal),
- counter_get(net->stats.loc_upd_type.periodic), VTY_NEWLINE);
- vty_out(vty, "IMSI Detach Indications : %lu%s",
- counter_get(net->stats.loc_upd_type.detach), VTY_NEWLINE);
- vty_out(vty, "Location Update Response: %lu accept, %lu reject%s",
- counter_get(net->stats.loc_upd_resp.accept),
- counter_get(net->stats.loc_upd_resp.reject), VTY_NEWLINE);
- vty_out(vty, "Paging : %lu attempted, %lu complete, %lu expired%s",
- counter_get(net->stats.paging.attempted),
- counter_get(net->stats.paging.completed),
- counter_get(net->stats.paging.expired), VTY_NEWLINE);
- vty_out(vty, "Handover : %lu attempted, %lu no_channel, %lu timeout, "
- "%lu completed, %lu failed%s",
- counter_get(net->stats.handover.attempted),
- counter_get(net->stats.handover.no_channel),
- counter_get(net->stats.handover.timeout),
- counter_get(net->stats.handover.completed),
- counter_get(net->stats.handover.failed), VTY_NEWLINE);
- vty_out(vty, "SMS MO : %lu submitted, %lu no receiver%s",
- counter_get(net->stats.sms.submitted),
- counter_get(net->stats.sms.no_receiver), VTY_NEWLINE);
- vty_out(vty, "SMS MT : %lu delivered, %lu no memory, %lu other error%s",
- counter_get(net->stats.sms.delivered),
- counter_get(net->stats.sms.rp_err_mem),
- counter_get(net->stats.sms.rp_err_other), VTY_NEWLINE);
- return CMD_SUCCESS;
-}
-
DEFUN(cfg_net,
cfg_net_cmd,
"network",
@@ -1433,12 +1393,12 @@
}
DEFUN(cfg_bts_prs_bvci, cfg_bts_gprs_bvci_cmd,
- "gprs cell bvci <0-65535>",
+ "gprs cell bvci <2-65535>",
"GPRS BSSGP VC Identifier")
{
struct gsm_bts *bts = vty->index;
- if (!bts->gprs.enabled) {
+ if (bts->gprs.mode == BTS_GPRS_NONE) {
vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1454,7 +1414,7 @@
{
struct gsm_bts *bts = vty->index;
- if (!bts->gprs.enabled) {
+ if (bts->gprs.mode == BTS_GPRS_NONE) {
vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1472,7 +1432,7 @@
struct gsm_bts *bts = vty->index;
int idx = atoi(argv[0]);
- if (!bts->gprs.enabled) {
+ if (bts->gprs.mode == BTS_GPRS_NONE) {
vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1489,7 +1449,7 @@
struct gsm_bts *bts = vty->index;
int idx = atoi(argv[0]);
- if (!bts->gprs.enabled) {
+ if (bts->gprs.mode == BTS_GPRS_NONE) {
vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1506,7 +1466,7 @@
struct gsm_bts *bts = vty->index;
int idx = atoi(argv[0]);
- if (!bts->gprs.enabled) {
+ if (bts->gprs.mode == BTS_GPRS_NONE) {
vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1524,7 +1484,7 @@
int idx = atoi(argv[0]);
struct in_addr ia;
- if (!bts->gprs.enabled) {
+ if (bts->gprs.mode == BTS_GPRS_NONE) {
vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1541,7 +1501,7 @@
{
struct gsm_bts *bts = vty->index;
- if (!bts->gprs.enabled) {
+ if (bts->gprs.mode == BTS_GPRS_NONE) {
vty_out(vty, "%% GPRS not enabled on this BTS%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1551,13 +1511,13 @@
return CMD_SUCCESS;
}
-DEFUN(cfg_bts_gprs_enabled, cfg_bts_gprs_enabled_cmd,
- "gprs enabled <0-1>",
- "GPRS Enabled on this BTS")
+DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
+ "gprs mode (none|gprs|egprs)",
+ "GPRS Mode for this BTS")
{
struct gsm_bts *bts = vty->index;
- bts->gprs.enabled = atoi(argv[0]);
+ bts->gprs.mode = bts_gprs_mode_parse(argv[0]);
return CMD_SUCCESS;
}
@@ -1740,6 +1700,8 @@
return CMD_SUCCESS;
}
+extern int bsc_vty_init_extra(struct gsm_network *net);
+
int bsc_vty_init(struct gsm_network *net)
{
gsmnet = net;
@@ -1758,7 +1720,6 @@
install_element(VIEW_NODE, &show_e1ts_cmd);
install_element(VIEW_NODE, &show_paging_cmd);
- install_element(VIEW_NODE, &show_stats_cmd);
openbsc_vty_add_cmds();
@@ -1815,7 +1776,7 @@
install_element(BTS_NODE, &cfg_bts_per_loc_upd_cmd);
install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
- install_element(BTS_NODE, &cfg_bts_gprs_enabled_cmd);
+ install_element(BTS_NODE, &cfg_bts_gprs_mode_cmd);
install_element(BTS_NODE, &cfg_bts_gprs_rac_cmd);
install_element(BTS_NODE, &cfg_bts_gprs_bvci_cmd);
install_element(BTS_NODE, &cfg_bts_gprs_nsei_cmd);
diff --git a/openbsc/src/vty_interface_cmds.c b/openbsc/src/vty_interface_cmds.c
index d494584..671351e 100644
--- a/openbsc/src/vty_interface_cmds.c
+++ b/openbsc/src/vty_interface_cmds.c
@@ -228,6 +228,23 @@
return CMD_SUCCESS;
}
+void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *net)
+{
+ vty_out(vty, "Channel Requests : %lu total, %lu no channel%s",
+ counter_get(net->stats.chreq.total),
+ counter_get(net->stats.chreq.no_channel), VTY_NEWLINE);
+ vty_out(vty, "Channel Failures : %lu rf_failures, %lu rll failures%s",
+ counter_get(net->stats.chan.rf_fail),
+ counter_get(net->stats.chan.rll_err), VTY_NEWLINE);
+ vty_out(vty, "Paging : %lu attempted, %lu complete, %lu expired%s",
+ counter_get(net->stats.paging.attempted),
+ counter_get(net->stats.paging.completed),
+ counter_get(net->stats.paging.expired), VTY_NEWLINE);
+ vty_out(vty, "BTS failures : %lu OML, %lu RSL%s",
+ counter_get(net->stats.bts.oml_fail),
+ counter_get(net->stats.bts.rsl_fail), VTY_NEWLINE);
+}
+
void openbsc_vty_add_cmds()
{
install_element(VIEW_NODE, &enable_logging_cmd);
diff --git a/openbsc/src/vty_interface_layer3.c b/openbsc/src/vty_interface_layer3.c
index b824c3d..5e30982 100644
--- a/openbsc/src/vty_interface_layer3.c
+++ b/openbsc/src/vty_interface_layer3.c
@@ -41,6 +41,7 @@
#include <osmocore/talloc.h>
#include <openbsc/signal.h>
#include <openbsc/debug.h>
+#include <openbsc/vty.h>
static struct gsm_network *gsmnet;
@@ -502,6 +503,41 @@
return 0;
}
+DEFUN(show_stats,
+ show_stats_cmd,
+ "show statistics",
+ SHOW_STR "Display network statistics\n")
+{
+ struct gsm_network *net = gsmnet;
+
+ openbsc_vty_print_statistics(vty, net);
+ vty_out(vty, "Location Update : %lu attach, %lu normal, %lu periodic%s",
+ counter_get(net->stats.loc_upd_type.attach),
+ counter_get(net->stats.loc_upd_type.normal),
+ counter_get(net->stats.loc_upd_type.periodic), VTY_NEWLINE);
+ vty_out(vty, "IMSI Detach Indications : %lu%s",
+ counter_get(net->stats.loc_upd_type.detach), VTY_NEWLINE);
+ vty_out(vty, "Location Update Response: %lu accept, %lu reject%s",
+ counter_get(net->stats.loc_upd_resp.accept),
+ counter_get(net->stats.loc_upd_resp.reject), VTY_NEWLINE);
+ vty_out(vty, "Handover : %lu attempted, %lu no_channel, %lu timeout, "
+ "%lu completed, %lu failed%s",
+ counter_get(net->stats.handover.attempted),
+ counter_get(net->stats.handover.no_channel),
+ counter_get(net->stats.handover.timeout),
+ counter_get(net->stats.handover.completed),
+ counter_get(net->stats.handover.failed), VTY_NEWLINE);
+ vty_out(vty, "SMS MO : %lu submitted, %lu no receiver%s",
+ counter_get(net->stats.sms.submitted),
+ counter_get(net->stats.sms.no_receiver), VTY_NEWLINE);
+ vty_out(vty, "SMS MT : %lu delivered, %lu no memory, %lu other error%s",
+ counter_get(net->stats.sms.delivered),
+ counter_get(net->stats.sms.rp_err_mem),
+ counter_get(net->stats.sms.rp_err_other), VTY_NEWLINE);
+ return CMD_SUCCESS;
+}
+
+
int bsc_vty_init_extra(struct gsm_network *net)
{
gsmnet = net;
@@ -517,6 +553,7 @@
install_element(VIEW_NODE, &subscriber_silent_sms_cmd);
install_element(VIEW_NODE, &subscriber_silent_call_start_cmd);
install_element(VIEW_NODE, &subscriber_silent_call_stop_cmd);
+ install_element(VIEW_NODE, &show_stats_cmd);
install_element(CONFIG_NODE, &cfg_subscr_cmd);
install_node(&subscr_node, dummy_config_write);
diff --git a/wireshark/abis_oml.patch b/wireshark/abis_oml.patch
index 9f06b4d..4013211 100644
--- a/wireshark/abis_oml.patch
+++ b/wireshark/abis_oml.patch
@@ -1,8 +1,21 @@
-Index: wireshark/epan/dissectors/Makefile.common
-===================================================================
---- wireshark.orig/epan/dissectors/Makefile.common
-+++ wireshark/epan/dissectors/Makefile.common
-@@ -474,6 +474,7 @@
+From 5857518be87641fdab45e593bc9fd5ef5595e619 Mon Sep 17 00:00:00 2001
+From: Holger Hans Peter Freyther <zecke@selfish.org>
+Date: Mon, 19 Apr 2010 13:23:51 +0800
+Subject: [PATCH 1/2] Add the Abis OML patch.
+
+---
+ epan/dissectors/Makefile.common | 1 +
+ epan/dissectors/packet-gsm_abis_oml.c | 1382 +++++++++++++++++++++++++++++++++
+ epan/dissectors/packet-gsm_abis_oml.h | 787 +++++++++++++++++++
+ 3 files changed, 2170 insertions(+), 0 deletions(-)
+ create mode 100644 epan/dissectors/packet-gsm_abis_oml.c
+ create mode 100644 epan/dissectors/packet-gsm_abis_oml.h
+
+diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common
+index dbc3726..98dcdc3 100644
+--- a/epan/dissectors/Makefile.common
++++ b/epan/dissectors/Makefile.common
+@@ -481,6 +481,7 @@ DISSECTOR_SRC = \
packet-gsm_a_gm.c \
packet-gsm_a_rp.c \
packet-gsm_a_rr.c \
@@ -12,7 +25,7 @@
packet-gsm_bssmap_le.c \
diff --git a/epan/dissectors/packet-gsm_abis_oml.c b/epan/dissectors/packet-gsm_abis_oml.c
new file mode 100644
-index 0000000..2de9dca
+index 0000000..fa46ab5
--- /dev/null
+++ b/epan/dissectors/packet-gsm_abis_oml.c
@@ -0,0 +1,1382 @@
@@ -1398,11 +1411,12 @@
+ abis_oml_handle = create_dissector_handle(dissect_abis_oml, proto_abis_oml);
+ dissector_add("lapd.gsm.sapi", LAPD_GSM_SAPI_OM_PROC, abis_oml_handle);
+}
-Index: wireshark/epan/dissectors/packet-gsm_abis_oml.h
-===================================================================
+diff --git a/epan/dissectors/packet-gsm_abis_oml.h b/epan/dissectors/packet-gsm_abis_oml.h
+new file mode 100644
+index 0000000..d523e96
--- /dev/null
-+++ wireshark/epan/dissectors/packet-gsm_abis_oml.h
-@@ -0,0 +1,786 @@
++++ b/epan/dissectors/packet-gsm_abis_oml.h
+@@ -0,0 +1,787 @@
+/* GSM Network Management messages on the A-bis interface
+ * 3GPP TS 12.21 version 8.0.0 Release 1999 / ETSI TS 100 623 V8.0.0 */
+
@@ -2190,3 +2204,6 @@
+};
+
+#endif /* _NM_H */
+--
+1.7.0.1
+
diff --git a/wireshark/rsl-ipaccess.patch b/wireshark/rsl-ipaccess.patch
index 36c09c5..29220b8 100644
--- a/wireshark/rsl-ipaccess.patch
+++ b/wireshark/rsl-ipaccess.patch
@@ -1,16 +1,25 @@
-Index: wireshark/epan/dissectors/packet-rsl.c
-===================================================================
---- wireshark.orig/epan/dissectors/packet-rsl.c 2009-10-21 23:03:41.000000000 +0200
-+++ wireshark/epan/dissectors/packet-rsl.c 2009-10-22 10:02:51.000000000 +0200
+From 8f35d623641dbba90e6186604c11e892bf515ecc Mon Sep 17 00:00:00 2001
+From: Holger Hans Peter Freyther <zecke@selfish.org>
+Date: Mon, 19 Apr 2010 13:32:58 +0800
+Subject: [PATCH 2/2] RSL patch
+
+---
+ epan/dissectors/packet-rsl.c | 522 +++++++++++++++++++++++++++++++++++++++++-
+ 1 files changed, 515 insertions(+), 7 deletions(-)
+
+diff --git a/epan/dissectors/packet-rsl.c b/epan/dissectors/packet-rsl.c
+index b10a671..a455cf3 100644
+--- a/epan/dissectors/packet-rsl.c
++++ b/epan/dissectors/packet-rsl.c
@@ -2,6 +2,7 @@
* Routines for Radio Signalling Link (RSL) dissection.
*
* Copyright 2007, Anders Broman <anders.broman@ericsson.com>
+ * Copyright 2009, Harald Welte <laforge@gnumonks.org>
*
- * $Id: packet-rsl.c 29944 2009-09-16 13:39:37Z morriss $
+ * $Id$
*
-@@ -44,6 +45,8 @@
+@@ -42,6 +43,8 @@
#include <epan/lapd_sapi.h>
#include "packet-gsm_a_common.h"
@@ -19,7 +28,7 @@
/* Initialize the protocol and registered fields */
static int proto_rsl = -1;
-@@ -117,6 +120,24 @@
+@@ -115,6 +118,24 @@ static int hf_rsl_emlpp_prio = -1;
static int hf_rsl_rtd = -1;
static int hf_rsl_delay_ind = -1;
static int hf_rsl_tfo = -1;
@@ -44,7 +53,7 @@
/* Initialize the subtree pointers */
static int ett_rsl = -1;
-@@ -174,6 +195,15 @@
+@@ -172,6 +193,15 @@ static int ett_ie_cause = -1;
static int ett_ie_meas_res_no = -1;
static int ett_ie_message_id = -1;
static int ett_ie_sys_info_type = -1;
@@ -60,7 +69,7 @@
proto_tree *top_tree;
dissector_handle_t gsm_a_ccch_handle;
-@@ -209,8 +239,11 @@
+@@ -207,8 +237,11 @@ static const value_string rsl_msg_disc_vals[] = {
{ 0x06, "Common Channel Management messages" },
{ 0x08, "TRX Management messages" },
{ 0x16, "Location Services messages" },
@@ -72,7 +81,7 @@
/*
* 9.2 MESSAGE TYPE
*/
-@@ -277,6 +310,49 @@
+@@ -275,6 +308,49 @@ static const value_string rsl_msg_disc_vals[] = {
/* 0 1 - - - - - - Location Services messages: */
#define RSL_MSG_LOC_INF 65 /* 8.7.1 */
@@ -90,16 +99,16 @@
+#define RSL_MSG_TYPE_IPAC_PDCH_DEACT_ACK 0x4c
+#define RSL_MSG_TYPE_IPAC_PDCH_DEACT_NACK 0x4d
+
-+#define RSL_MSG_TYPE_IPAC_BIND 0x70
-+#define RSL_MSG_TYPE_IPAC_BIND_ACK 0x71
-+#define RSL_MSG_TYPE_IPAC_BIND_NACK 0x72
-+#define RSL_MSG_TYPE_IPAC_CONNECT 0x73
-+#define RSL_MSG_TYPE_IPAC_CONNECT_ACK 0x74
-+#define RSL_MSG_TYPE_IPAC_CONNECT_NACK 0x75
-+#define RSL_MSG_TYPE_IPAC_DISC_IND 0x76
-+#define RSL_MSG_TYPE_IPAC_DISC 0x77
-+#define RSL_MSG_TYPE_IPAC_DISC_ACK 0x78
-+#define RSL_MSG_TYPE_IPAC_DISC_NACK 0x79
++#define RSL_MSG_TYPE_IPAC_CRCX 0x70
++#define RSL_MSG_TYPE_IPAC_CRCX_ACK 0x71
++#define RSL_MSG_TYPE_IPAC_CRCX_NACK 0x72
++#define RSL_MSG_TYPE_IPAC_MDCX 0x73
++#define RSL_MSG_TYPE_IPAC_MDCX_ACK 0x74
++#define RSL_MSG_TYPE_IPAC_MDCX_NACK 0x75
++#define RSL_MSG_TYPE_IPAC_DLCX_IND 0x76
++#define RSL_MSG_TYPE_IPAC_DLCX 0x77
++#define RSL_MSG_TYPE_IPAC_DLCX_ACK 0x78
++#define RSL_MSG_TYPE_IPAC_DLCX_NACK 0x79
+
+#define RSL_IE_IPAC_SRTP_CONFIG 0xe0
+#define RSL_IE_IPAC_PROXY_UDP 0xe1
@@ -122,7 +131,7 @@
static const value_string rsl_msg_type_vals[] = {
/* 0 0 0 0 - - - - Radio Link Layer Management messages: */
-@@ -339,6 +415,26 @@
+@@ -337,6 +413,26 @@ static const value_string rsl_msg_type_vals[] = {
{ 0x3f, "TFO MODification REQuest" }, /* 8.4.31 */
/* 0 1 - - - - - - Location Services messages: */
{ 0x41, "Location Information" }, /* 8.7.1 */
@@ -149,7 +158,7 @@
{ 0, NULL }
};
-@@ -372,10 +468,10 @@ static const value_string rsl_msg_type_vals[] = {
+@@ -370,10 +466,10 @@ static const value_string rsl_msg_type_vals[] = {
#define RSL_IE_MESSAGE_ID 28
#define RSL_IE_SYS_INFO_TYPE 30
@@ -164,7 +173,7 @@
#define RSL_IE_FULL_IMM_ASS_INF 35
#define RSL_IE_SMSCB_INF 36
#define RSL_IE_FULL_MS_TIMING_OFFSET 37
-@@ -478,6 +574,24 @@
+@@ -476,6 +572,24 @@ static const value_string rsl_ie_type_vals[] = {
Not used
*/
@@ -189,7 +198,7 @@
{ 0, NULL }
};
-@@ -514,6 +628,96 @@
+@@ -512,6 +626,96 @@ static const value_string rsl_ch_no_Cbits_vals[] = {
{ 0, NULL }
};
@@ -286,7 +295,7 @@
/* 9.3.1 Channel number 9.3.1 M TV 2 */
static int
dissect_rsl_ie_ch_no(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, gboolean is_mandatory)
-@@ -2044,7 +2248,6 @@
+@@ -2042,7 +2246,6 @@ dissect_rsl_ie_err_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int
proto_item_set_len(ti, length+2);
proto_tree_add_item(ie_tree, hf_rsl_ie_length, tvb, offset, 1, FALSE);
@@ -294,7 +303,7 @@
/* Received Message */
offset = dissct_rsl_msg(tvb, pinfo, ie_tree, offset);
-@@ -2909,12 +3112,183 @@
+@@ -2907,12 +3110,184 @@ dissect_rsl_ie_tfo_transp_cont(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
}
static int
@@ -310,16 +319,16 @@
+
+#if 0
+ switch (msg_type) {
-+ case RSL_MSG_TYPE_IPAC_BIND:
-+ case RSL_MSG_TYPE_IPAC_BIND_ACK:
-+ case RSL_MSG_TYPE_IPAC_BIND_NACK:
-+ case RSL_MSG_TYPE_IPAC_CONNECT:
-+ case RSL_MSG_TYPE_IPAC_CONNECT_ACK:
-+ case RSL_MSG_TYPE_IPAC_CONNECT_NACK:
-+ case RSL_MSG_TYPE_IPAC_DISC_IND:
-+ case RSL_MSG_TYPE_IPAC_DISC:
-+ case RSL_MSG_TYPE_IPAC_DISC_ACK:
-+ case RSL_MSG_TYPE_IPAC_DISC_NACK:
++ case RSL_MSG_TYPE_IPAC_CRCX:
++ case RSL_MSG_TYPE_IPAC_CRCX_ACK:
++ case RSL_MSG_TYPE_IPAC_CRCX_NACK:
++ case RSL_MSG_TYPE_IPAC_MDCX:
++ case RSL_MSG_TYPE_IPAC_MDCX_ACK:
++ case RSL_MSG_TYPE_IPAC_MDCX_NACK:
++ case RSL_MSG_TYPE_IPAC_DLCX_IND:
++ case RSL_MSG_TYPE_IPAC_DLCX:
++ case RSL_MSG_TYPE_IPAC_DLCX_ACK:
++ case RSL_MSG_TYPE_IPAC_DLCX_NACK:
+ case RSL_MSG_TYPE_IPAC_PDCH_ACT:
+ case RSL_MSG_TYPE_IPAC_PDCH_ACT_ACK:
+ case RSL_MSG_TYPE_IPAC_PDCH_ACT_NACK:
@@ -449,7 +458,7 @@
+ }
+
+ switch (msg_type) {
-+ case RSL_MSG_TYPE_IPAC_BIND_ACK:
++ case RSL_MSG_TYPE_IPAC_CRCX_ACK:
+ /* Notify the RTP and RTCP dissectors about a new RTP stream */
+ src_addr.type = AT_IPv4;
+ src_addr.len = 4;
@@ -480,7 +489,7 @@
offset++;
switch (msg_type){
-@@ -3482,6 +3856,18 @@
+@@ -3480,6 +3855,18 @@ dissct_rsl_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
/* LLP APDU 9.3.58 M LV 2-N */
offset = dissect_rsl_ie_llp_apdu(tvb, pinfo, tree, offset, TRUE);
break;
@@ -499,7 +508,7 @@
default:
break;
}
-@@ -3489,6 +3875,40 @@
+@@ -3487,6 +3874,40 @@ dissct_rsl_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
return offset;
}
@@ -540,7 +549,7 @@
static void
dissect_rsl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
-@@ -3516,7 +3936,6 @@
+@@ -3514,7 +3935,6 @@ dissect_rsl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* 9.1 Message discriminator */
proto_tree_add_item(rsl_tree, hf_rsl_msg_dsc, tvb, offset, 1, FALSE);
proto_tree_add_item(rsl_tree, hf_rsl_T_bit, tvb, offset, 1, FALSE);
@@ -548,7 +557,7 @@
offset = dissct_rsl_msg(tvb, pinfo, rsl_tree, offset);
-@@ -3886,6 +4305,86 @@
+@@ -3884,6 +4304,86 @@ void proto_register_rsl(void)
FT_UINT8, BASE_DEC, VALS(rsl_emlpp_prio_vals), 0x03,
NULL, HFILL }
},
@@ -635,7 +644,7 @@
};
static gint *ett[] = {
&ett_rsl,
-@@ -3943,6 +4442,14 @@
+@@ -3941,6 +4441,14 @@ void proto_register_rsl(void)
&ett_ie_meas_res_no,
&ett_ie_message_id,
&ett_ie_sys_info_type,
@@ -650,3 +659,6 @@
};
/* Register the protocol name and description */
+--
+1.7.0.1
+