Merge branch 'master' into sms
This commit is contained in:
commit
e34e117ff1
|
@ -266,16 +266,23 @@ struct rsl_ie_chan_mode {
|
|||
} __attribute__ ((packed));
|
||||
#define RSL_CMOD_DTXu 0x01 /* uplink */
|
||||
#define RSL_CMOD_DTXd 0x02 /* downlink */
|
||||
#define RSL_CMOD_SPD_SPEECH 0x01
|
||||
#define RSL_CMOD_SPD_DATA 0x02
|
||||
#define RSL_CMOD_SPD_SIGN 0x03
|
||||
enum rsl_cmod_spd {
|
||||
RSL_CMOD_SPD_SPEECH = 0x01,
|
||||
RSL_CMOD_SPD_DATA = 0x02,
|
||||
RSL_CMOD_SPD_SIGN = 0x03,
|
||||
};
|
||||
#define RSL_CMOD_CRT_SDCCH 0x01
|
||||
#define RSL_CMOD_CRT_TCH_Bm 0x08 /* full-rate */
|
||||
#define RSL_CMOD_CRT_TCH_Lm 0x09 /* half-rate */
|
||||
/* FIXME: More CRT types */
|
||||
/* Speech */
|
||||
#define RSL_CMOD_SP_GSM1 0x01
|
||||
#define RSL_CMOD_SP_GSM2 0x11
|
||||
#define RSL_CMOD_SP_GSM3 0x21
|
||||
/* Data */
|
||||
#define RSL_CMOD_SP_NT_14k5 0x58
|
||||
#define RSL_CMOD_SP_NT_12k0 0x50
|
||||
#define RSL_CMOD_SP_NT_6k0 0x51
|
||||
|
||||
/* Chapter 9.3.5 */
|
||||
struct rsl_ie_chan_ident {
|
||||
|
@ -459,7 +466,7 @@ int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
|
|||
u_int8_t bs_power, u_int8_t ms_power,
|
||||
u_int8_t ta);
|
||||
int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
|
||||
u_int8_t ta, u_int8_t mode);
|
||||
u_int8_t ta);
|
||||
int rsl_chan_mode_modify_req(struct gsm_lchan *ts);
|
||||
int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
|
||||
u_int8_t *ms_ident, u_int8_t chan_needed);
|
||||
|
|
|
@ -48,14 +48,16 @@ struct gsm48_chan_mode_modify {
|
|||
u_int8_t mode;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define GSM48_CMODE_SIGN 0x00
|
||||
#define GSM48_CMODE_SPEECH_V1 0x01
|
||||
#define GSM48_CMODE_SPEECH_EFR 0x21
|
||||
#define GSM48_CMODE_SPEECH_AMR 0x41
|
||||
#define GSM48_CMODE_DATA_14k5 0x0f
|
||||
#define GSM48_CMODE_DATA_12k0 0x03
|
||||
#define GSM48_CMODE_DATA_6k0 0x0b
|
||||
#define GSM48_CMODE_DATA_3k6 0x23
|
||||
enum gsm48_chan_mode {
|
||||
GSM48_CMODE_SIGN = 0x00,
|
||||
GSM48_CMODE_SPEECH_V1 = 0x01,
|
||||
GSM48_CMODE_SPEECH_EFR = 0x21,
|
||||
GSM48_CMODE_SPEECH_AMR = 0x41,
|
||||
GSM48_CMODE_DATA_14k5 = 0x0f,
|
||||
GSM48_CMODE_DATA_12k0 = 0x03,
|
||||
GSM48_CMODE_DATA_6k0 = 0x0b,
|
||||
GSM48_CMODE_DATA_3k6 = 0x23,
|
||||
};
|
||||
|
||||
/* Chapter 9.1.18 */
|
||||
struct gsm48_imm_ass {
|
||||
|
@ -642,6 +644,34 @@ enum chreq_type {
|
|||
#define SBIT(a) (1 << a)
|
||||
#define ALL_STATES 0xffffffff
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Information Transfer Capability */
|
||||
enum gsm48_bcap_itcap {
|
||||
GSM48_BCAP_ITCAP_SPEECH = 0,
|
||||
GSM48_BCAP_ITCAP_UNR_DIG_INF = 1,
|
||||
GSM48_BCAP_ITCAP_3k1_AUDIO = 2,
|
||||
GSM48_BCAP_ITCAP_FAX_G3 = 3,
|
||||
GSM48_BCAP_ITCAP_OTHER = 5,
|
||||
GSM48_BCAP_ITCAP_RESERVED = 7,
|
||||
};
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Transfer Mode */
|
||||
enum gsm48_bcap_tmod {
|
||||
GSM48_BCAP_TMOD_CIRCUIT = 0,
|
||||
GSM48_BCAP_TMOD_PACKET = 1,
|
||||
};
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Coding Standard */
|
||||
enum gsm48_bcap_coding {
|
||||
GSM48_BCAP_CODING_GSM_STD = 0,
|
||||
};
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Radio Channel Requirements */
|
||||
enum gsm48_bcap_rrq {
|
||||
GSM48_BCAP_RRQ_FR_ONLY = 1,
|
||||
GSM48_BCAP_RRQ_DUAL_HR = 2,
|
||||
GSM48_BCAP_RRQ_DUAL_FR = 3,
|
||||
};
|
||||
|
||||
struct msgb;
|
||||
struct gsm_bts;
|
||||
struct gsm_subscriber;
|
||||
|
|
|
@ -41,6 +41,7 @@ enum gsm_chreq_reason_t {
|
|||
|
||||
#include <openbsc/timer.h>
|
||||
#include <openbsc/gsm_04_08.h>
|
||||
#include <openbsc/abis_rsl.h>
|
||||
#include <openbsc/mncc.h>
|
||||
#include <openbsc/tlv.h>
|
||||
|
||||
|
@ -127,8 +128,10 @@ struct gsm_lchan {
|
|||
u_int8_t nr;
|
||||
/* The logical channel type */
|
||||
enum gsm_chan_t type;
|
||||
/* RSL channel mode */
|
||||
enum rsl_cmod_spd rsl_cmode;
|
||||
/* If TCH, traffic channel mode */
|
||||
enum gsm_chan_t tch_mode;
|
||||
enum gsm48_chan_mode tch_mode;
|
||||
/* Power levels for MS and BTS */
|
||||
u_int8_t bs_power;
|
||||
u_int8_t ms_power;
|
||||
|
|
|
@ -108,13 +108,14 @@ struct gsm_call {
|
|||
#define MNCC_F_KEYPAD 0x1000
|
||||
#define MNCC_F_SIGNAL 0x2000
|
||||
|
||||
/* Expanded fields from GSM TS 04.08, Table 10.5.102 */
|
||||
struct gsm_mncc_bearer_cap {
|
||||
int transfer;
|
||||
int mode;
|
||||
int coding;
|
||||
int radio;
|
||||
int speech_ctm;
|
||||
int speech_ver[8];
|
||||
int transfer; /* Information Transfer Capability */
|
||||
int mode; /* Transfer Mode */
|
||||
int coding; /* Coding Standard */
|
||||
int radio; /* Radio Channel Requirement */
|
||||
int speech_ctm; /* CTM text telephony indication */
|
||||
int speech_ver[8]; /* Speech version indication */
|
||||
};
|
||||
|
||||
struct gsm_mncc_number {
|
||||
|
|
|
@ -530,6 +530,62 @@ int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
|
|||
return abis_rsl_sendmsg(msg);
|
||||
}
|
||||
|
||||
static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
|
||||
struct gsm_lchan *lchan)
|
||||
{
|
||||
memset(cm, 0, sizeof(cm));
|
||||
|
||||
/* FIXME: what to do with data calls ? */
|
||||
cm->dtx_dtu = 0x00;
|
||||
|
||||
/* set TCH Speech/Data */
|
||||
cm->spd_ind = lchan->rsl_cmode;
|
||||
|
||||
switch (lchan->type) {
|
||||
case GSM_LCHAN_SDCCH:
|
||||
cm->chan_rt = RSL_CMOD_CRT_SDCCH;
|
||||
break;
|
||||
case GSM_LCHAN_TCH_F:
|
||||
cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
|
||||
break;
|
||||
case GSM_LCHAN_TCH_H:
|
||||
cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
|
||||
break;
|
||||
case GSM_LCHAN_NONE:
|
||||
case GSM_LCHAN_UNKNOWN:
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (lchan->tch_mode) {
|
||||
case GSM48_CMODE_SIGN:
|
||||
cm->chan_rate = 0;
|
||||
break;
|
||||
case GSM48_CMODE_SPEECH_V1:
|
||||
cm->chan_rate = RSL_CMOD_SP_GSM1;
|
||||
break;
|
||||
case GSM48_CMODE_SPEECH_EFR:
|
||||
cm->chan_rate = RSL_CMOD_SP_GSM2;
|
||||
break;
|
||||
case GSM48_CMODE_SPEECH_AMR:
|
||||
cm->chan_rate = RSL_CMOD_SP_GSM3;
|
||||
break;
|
||||
case GSM48_CMODE_DATA_14k5:
|
||||
cm->chan_rate = RSL_CMOD_SP_NT_14k5;
|
||||
break;
|
||||
case GSM48_CMODE_DATA_12k0:
|
||||
cm->chan_rate = RSL_CMOD_SP_NT_12k0;
|
||||
break;
|
||||
case GSM48_CMODE_DATA_6k0:
|
||||
cm->chan_rate = RSL_CMOD_SP_NT_6k0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Chapter 8.4.1 */
|
||||
#if 0
|
||||
int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
|
||||
|
@ -567,45 +623,20 @@ int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
|
|||
#endif
|
||||
|
||||
int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
|
||||
u_int8_t ta, u_int8_t mode)
|
||||
u_int8_t ta)
|
||||
{
|
||||
struct abis_rsl_dchan_hdr *dh;
|
||||
struct msgb *msg;
|
||||
int rc;
|
||||
|
||||
u_int8_t chan_nr = lchan2chan_nr(lchan);
|
||||
u_int16_t arfcn = lchan->ts->trx->arfcn;
|
||||
struct rsl_ie_chan_mode cm;
|
||||
struct rsl_ie_chan_ident ci;
|
||||
|
||||
memset(&cm, 0, sizeof(cm));
|
||||
/* FIXME: what to do with data calls ? */
|
||||
cm.dtx_dtu = 0x00;
|
||||
switch (lchan->type) {
|
||||
case GSM_LCHAN_SDCCH:
|
||||
cm.spd_ind = RSL_CMOD_SPD_SIGN;
|
||||
cm.chan_rt = RSL_CMOD_CRT_SDCCH;
|
||||
cm.chan_rate = 0x00;
|
||||
break;
|
||||
case GSM_LCHAN_TCH_F:
|
||||
cm.chan_rt = RSL_CMOD_CRT_TCH_Bm;
|
||||
switch (mode) {
|
||||
case RSL_CMOD_SPD_SIGN:
|
||||
cm.spd_ind = RSL_CMOD_SPD_SIGN;
|
||||
cm.chan_rate = 0x00;
|
||||
break;
|
||||
case RSL_CMOD_SPD_SPEECH:
|
||||
cm.spd_ind = RSL_CMOD_SPD_SPEECH;
|
||||
cm.chan_rate = RSL_CMOD_SP_GSM2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GSM_LCHAN_TCH_H:
|
||||
DEBUGP(DRSL, "Unimplemented TCH_H activation\n");
|
||||
return -1;
|
||||
case GSM_LCHAN_UNKNOWN:
|
||||
case GSM_LCHAN_NONE:
|
||||
return -1;
|
||||
}
|
||||
rc = channel_mode_from_lchan(&cm, lchan);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
memset(&ci, 0, sizeof(ci));
|
||||
ci.chan_desc.iei = 0x64;
|
||||
|
@ -637,40 +668,19 @@ int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
|
|||
return abis_rsl_sendmsg(msg);
|
||||
}
|
||||
|
||||
/* Chapter 8.4.9 */
|
||||
/* Chapter 8.4.9: Modify channel mode on BTS side */
|
||||
int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
|
||||
{
|
||||
struct abis_rsl_dchan_hdr *dh;
|
||||
struct msgb *msg;
|
||||
int rc;
|
||||
|
||||
u_int8_t chan_nr = lchan2chan_nr(lchan);
|
||||
struct rsl_ie_chan_mode cm;
|
||||
|
||||
memset(&cm, 0, sizeof(cm));
|
||||
|
||||
/* FIXME: what to do with data calls ? */
|
||||
cm.dtx_dtu = 0x00;
|
||||
switch (lchan->type) {
|
||||
/* todo more modes */
|
||||
case GSM_LCHAN_TCH_F:
|
||||
cm.spd_ind = RSL_CMOD_SPD_SPEECH;
|
||||
cm.chan_rt = RSL_CMOD_CRT_TCH_Bm;
|
||||
switch(lchan->tch_mode) {
|
||||
case GSM48_CMODE_SPEECH_V1:
|
||||
cm.chan_rate = RSL_CMOD_SP_GSM1;
|
||||
break;
|
||||
case GSM48_CMODE_SPEECH_EFR:
|
||||
cm.chan_rate = RSL_CMOD_SP_GSM2;
|
||||
break;
|
||||
default:
|
||||
DEBUGP(DRSL, "Unimplemented channel modification\n");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEBUGP(DRSL, "Unimplemented channel modification\n");
|
||||
return -1;
|
||||
}
|
||||
rc = channel_mode_from_lchan(&cm, lchan);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
msg = rsl_msgb_alloc();
|
||||
dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
|
||||
|
@ -1080,7 +1090,8 @@ static int rsl_rx_chan_rqd(struct msgb *msg)
|
|||
subch = lchan->nr;
|
||||
|
||||
lchan->ms_power = lchan->bs_power = 0x0f; /* 30dB reduction */
|
||||
rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, RSL_CMOD_SPD_SIGN);
|
||||
lchan->rsl_cmode = RSL_CMOD_SPD_SIGN;
|
||||
rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
|
||||
|
||||
/* create IMMEDIATE ASSIGN 04.08 messge */
|
||||
memset(&ia, 0, sizeof(ia));
|
||||
|
@ -1244,7 +1255,6 @@ static int abis_rsl_rx_rll(struct msgb *msg)
|
|||
|
||||
static u_int8_t ipa_smod_s_for_tch_mode(u_int8_t tch_mode)
|
||||
{
|
||||
#if 0
|
||||
switch (tch_mode) {
|
||||
case GSM48_CMODE_SPEECH_V1:
|
||||
return 0x00;
|
||||
|
@ -1254,12 +1264,9 @@ static u_int8_t ipa_smod_s_for_tch_mode(u_int8_t tch_mode)
|
|||
return 0x02;
|
||||
/* FIXME: Type1 half-rate and type3 half-rate */
|
||||
}
|
||||
DEBUGPC(DRSL, "Cannot determine ip.access speech mode for "
|
||||
"tch_mode == 0x%02x\n", tch_mode);
|
||||
return 0;
|
||||
#else
|
||||
/* hard-code EFR for now, since tch_mode is not correct at this
|
||||
* point in time */
|
||||
return 0x01;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ip.access specific RSL extensions */
|
||||
|
@ -1267,19 +1274,20 @@ int rsl_ipacc_bind(struct gsm_lchan *lchan)
|
|||
{
|
||||
struct msgb *msg = rsl_msgb_alloc();
|
||||
struct abis_rsl_dchan_hdr *dh;
|
||||
u_int8_t speech_mode_s;
|
||||
u_int8_t speech_mode;
|
||||
|
||||
dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
|
||||
init_dchan_hdr(dh, RSL_MT_IPAC_BIND);
|
||||
dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
|
||||
dh->chan_nr = lchan2chan_nr(lchan);
|
||||
|
||||
speech_mode_s = ipa_smod_s_for_tch_mode(lchan->tch_mode);
|
||||
/* 0x1- == receive-only, 0x-1 == EFR codec */
|
||||
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, 0x10 | speech_mode_s);
|
||||
speech_mode = 0x10 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
|
||||
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
|
||||
|
||||
DEBUGPC(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND\n",
|
||||
gsm_ts_name(lchan->ts), dh->chan_nr);
|
||||
DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND "
|
||||
"speech_mode=0x%02x\n", gsm_ts_name(lchan->ts),
|
||||
dh->chan_nr, speech_mode);
|
||||
|
||||
msg->trx = lchan->ts->trx;
|
||||
|
||||
|
@ -1292,7 +1300,7 @@ int rsl_ipacc_connect(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
|
|||
struct msgb *msg = rsl_msgb_alloc();
|
||||
struct abis_rsl_dchan_hdr *dh;
|
||||
u_int8_t *att_f8, *att_ip, *att_port;
|
||||
u_int8_t speech_mode_s;
|
||||
u_int8_t speech_mode;
|
||||
struct in_addr ia;
|
||||
|
||||
dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
|
||||
|
@ -1300,11 +1308,14 @@ int rsl_ipacc_connect(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
|
|||
dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
|
||||
dh->chan_nr = lchan2chan_nr(lchan);
|
||||
|
||||
/* 0x0- == both directions, 0x-1 == EFR codec */
|
||||
speech_mode = 0x00 | ipa_smod_s_for_tch_mode(lchan->tch_mode);
|
||||
|
||||
ia.s_addr = htonl(ip);
|
||||
DEBUGP(DRSL, "IPAC_CONNECT channel=%s chan_nr=0x%02x "
|
||||
"IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d\n",
|
||||
DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_CONNECT "
|
||||
"IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d speech_mode=0x%02x\n",
|
||||
gsm_ts_name(lchan->ts), dh->chan_nr,
|
||||
inet_ntoa(ia), port, rtp_payload2, conn_id);
|
||||
inet_ntoa(ia), port, rtp_payload2, conn_id, speech_mode);
|
||||
|
||||
att_f8 = msgb_put(msg, sizeof(conn_id)+1);
|
||||
att_f8[0] = RSL_IE_IPAC_CONN_ID;
|
||||
|
@ -1324,9 +1335,7 @@ int rsl_ipacc_connect(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
|
|||
att_port[1] = port >> 8;
|
||||
att_port[2] = port & 0xff;
|
||||
|
||||
speech_mode_s = ipa_smod_s_for_tch_mode(lchan->tch_mode);
|
||||
/* 0x0- == both directions, 0x-1 == EFR codec */
|
||||
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, 0x00 | speech_mode_s);
|
||||
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, speech_mode);
|
||||
if (rtp_payload2)
|
||||
msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2);
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ static int BSIC = HARDCODED_BSIC;
|
|||
static int ARFCN = HARDCODED_ARFCN;
|
||||
static int cardnr = 0;
|
||||
static int release_l2 = 0;
|
||||
static int bs11_has_trx1 = 0;
|
||||
static enum gsm_bts_type BTS_TYPE = GSM_BTS_TYPE_BS11;
|
||||
static enum gsm_band BAND = GSM_BAND_900;
|
||||
static const char *database_name = "hlr.sqlite3";
|
||||
|
@ -531,13 +532,6 @@ static void bootstrap_om_bs11(struct gsm_bts *bts)
|
|||
abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x01);
|
||||
abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
|
||||
|
||||
#ifdef HAVE_TRX1
|
||||
/* TRX 1 */
|
||||
abis_nm_conn_terr_sign(&bts->trx[1], 0, 1, 0xff);
|
||||
/* FIXME: TRX ATTRIBUTE */
|
||||
abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x02);
|
||||
#endif
|
||||
|
||||
/* SET CHANNEL ATTRIBUTE TS1 */
|
||||
abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
|
||||
/* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
|
||||
|
@ -573,6 +567,69 @@ static void bootstrap_om_bs11(struct gsm_bts *bts)
|
|||
/* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
|
||||
abis_nm_conn_terr_traf(&trx->ts[7], 0, 3, 3);
|
||||
|
||||
trx = gsm_bts_trx_num(bts, 1);
|
||||
if (trx) {
|
||||
u_int8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
|
||||
u_int8_t arfcn_low = trx->arfcn & 0xff;
|
||||
u_int8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
|
||||
memcpy(trx1_attr_radio, bs11_attr_radio,
|
||||
sizeof(trx1_attr_radio));
|
||||
|
||||
/* patch ARFCN into TRX Attributes */
|
||||
trx1_attr_radio[2] &= 0xf0;
|
||||
trx1_attr_radio[2] |= arfcn_high;
|
||||
trx1_attr_radio[3] = arfcn_low;
|
||||
|
||||
/* Connect signalling of TRX1 to e1_0/ts1/64kbps */
|
||||
abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
|
||||
/* FIXME: TRX ATTRIBUTE */
|
||||
abis_nm_set_radio_attr(trx, trx1_attr_radio,
|
||||
sizeof(trx1_attr_radio));
|
||||
|
||||
/* Use TEI 2 for signalling */
|
||||
abis_nm_establish_tei(bts, 1, 0, 1, 0xff, 0x02);
|
||||
|
||||
/* SET CHANNEL ATTRIBUTE TS1 */
|
||||
abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
|
||||
/* Connect traffic of bts0/trx0/ts1 to e1_0/ts4/a */
|
||||
abis_nm_conn_terr_traf(&trx->ts[1], 0, 4, 0);
|
||||
|
||||
/* SET CHANNEL ATTRIBUTE TS1 */
|
||||
abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
|
||||
/* Connect traffic of bts0/trx0/ts1 to e1_0/ts4/b */
|
||||
abis_nm_conn_terr_traf(&trx->ts[1], 0, 4, 1);
|
||||
|
||||
/* SET CHANNEL ATTRIBUTE TS2 */
|
||||
abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
|
||||
/* Connect traffic of bts0/trx0/ts2 to e1_0/ts4/c */
|
||||
abis_nm_conn_terr_traf(&trx->ts[2], 0, 4, 2);
|
||||
|
||||
/* SET CHANNEL ATTRIBUTE TS3 */
|
||||
abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
|
||||
/* Connect traffic of bts0/trx0/ts3 to e1_0/ts4/d */
|
||||
abis_nm_conn_terr_traf(&trx->ts[3], 0, 4, 3);
|
||||
|
||||
/* SET CHANNEL ATTRIBUTE TS4 */
|
||||
abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
|
||||
/* Connect traffic of bts0/trx0/ts4 to e1_0/ts5/a */
|
||||
abis_nm_conn_terr_traf(&trx->ts[4], 0, 5, 0);
|
||||
|
||||
/* SET CHANNEL ATTRIBUTE TS5 */
|
||||
abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
|
||||
/* Connect traffic of bts0/trx0/ts5 to e1_0/ts5/b */
|
||||
abis_nm_conn_terr_traf(&trx->ts[5], 0, 5, 1);
|
||||
|
||||
/* SET CHANNEL ATTRIBUTE TS6 */
|
||||
abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
|
||||
/* Connect traffic of bts0/trx0/ts6 to e1_0/ts5/c */
|
||||
abis_nm_conn_terr_traf(&trx->ts[6], 0, 5, 2);
|
||||
|
||||
/* SET CHANNEL ATTRIBUTE TS7 */
|
||||
abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
|
||||
/* Connect traffic of bts0/trx0/ts7 to e1_0/ts5/d */
|
||||
abis_nm_conn_terr_traf(&trx->ts[7], 0, 5, 3);
|
||||
}
|
||||
|
||||
/* end DB transmission */
|
||||
abis_nm_bs11_db_transmission(bts, 0);
|
||||
|
||||
|
@ -962,18 +1019,20 @@ static int bootstrap_bts(struct gsm_bts *bts)
|
|||
set_ts_e1link(&trx->ts[5], 0, 3, 1);
|
||||
set_ts_e1link(&trx->ts[6], 0, 3, 2);
|
||||
set_ts_e1link(&trx->ts[7], 0, 3, 3);
|
||||
#ifdef HAVE_TRX1
|
||||
|
||||
/* TRX 1 */
|
||||
trx = &bts->trx[1];
|
||||
set_ts_e1link(&trx->ts[0], 0, 1, 0xff);
|
||||
set_ts_e1link(&trx->ts[1], 0, 2, 1);
|
||||
set_ts_e1link(&trx->ts[2], 0, 2, 2);
|
||||
set_ts_e1link(&trx->ts[3], 0, 2, 3);
|
||||
set_ts_e1link(&trx->ts[4], 0, 3, 0);
|
||||
set_ts_e1link(&trx->ts[5], 0, 3, 1);
|
||||
set_ts_e1link(&trx->ts[6], 0, 3, 2);
|
||||
set_ts_e1link(&trx->ts[7], 0, 3, 3);
|
||||
#endif
|
||||
trx = gsm_bts_trx_num(bts, 1);
|
||||
if (trx) {
|
||||
trx = gsm_bts_trx_num(bts, 1);
|
||||
set_ts_e1link(&trx->ts[0], 0, 4, 0);
|
||||
set_ts_e1link(&trx->ts[1], 0, 4, 1);
|
||||
set_ts_e1link(&trx->ts[2], 0, 4, 2);
|
||||
set_ts_e1link(&trx->ts[3], 0, 4, 3);
|
||||
set_ts_e1link(&trx->ts[4], 0, 5, 0);
|
||||
set_ts_e1link(&trx->ts[5], 0, 5, 1);
|
||||
set_ts_e1link(&trx->ts[6], 0, 5, 2);
|
||||
set_ts_e1link(&trx->ts[7], 0, 5, 3);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1028,6 +1087,13 @@ static int bootstrap_network(void)
|
|||
/* E1 mISDN input setup */
|
||||
if (BTS_TYPE == GSM_BTS_TYPE_BS11) {
|
||||
struct gsm_bts *bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC);
|
||||
|
||||
if (bs11_has_trx1) {
|
||||
struct gsm_bts_trx *trx1;
|
||||
trx1 = gsm_bts_trx_alloc(bts);
|
||||
trx1->arfcn = ARFCN + 2;
|
||||
}
|
||||
|
||||
bootstrap_bts(bts);
|
||||
|
||||
gsmnet->num_bts = 1;
|
||||
|
@ -1115,10 +1181,11 @@ static void handle_options(int argc, char** argv)
|
|||
{"tsc", 1, 0, 'S'},
|
||||
{"bsic", 1, 0, 'B'},
|
||||
{"rtp-proxy", 0, 0, 'P'},
|
||||
{"trx1", 0, 0, '1'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:l:Tb:i:S:B:P",
|
||||
c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:l:Tb:i:S:B:P1",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
@ -1192,6 +1259,9 @@ static void handle_options(int argc, char** argv)
|
|||
case 'P':
|
||||
ipacc_rtp_direct = 0;
|
||||
break;
|
||||
case '1':
|
||||
bs11_has_trx1 = 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* ignore */
|
||||
|
|
|
@ -73,20 +73,34 @@ struct gsm_bts_trx_ts *ts_alloc(struct gsm_bts *bts,
|
|||
|
||||
/* the following constraints are pure policy,
|
||||
* no requirement to put this restriction in place */
|
||||
switch (pchan) {
|
||||
case GSM_PCHAN_CCCH:
|
||||
case GSM_PCHAN_CCCH_SDCCH4:
|
||||
from = 0; to = 0;
|
||||
break;
|
||||
case GSM_PCHAN_SDCCH8_SACCH8C:
|
||||
from = 1; to = 1;
|
||||
break;
|
||||
case GSM_PCHAN_TCH_F:
|
||||
case GSM_PCHAN_TCH_H:
|
||||
from = 2; to = 7;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
if (trx == bts->c0) {
|
||||
/* On the first TRX we run one CCCH and one SDCCH8 */
|
||||
switch (pchan) {
|
||||
case GSM_PCHAN_CCCH:
|
||||
case GSM_PCHAN_CCCH_SDCCH4:
|
||||
from = 0; to = 0;
|
||||
break;
|
||||
case GSM_PCHAN_SDCCH8_SACCH8C:
|
||||
from = 1; to = 1;
|
||||
break;
|
||||
case GSM_PCHAN_TCH_F:
|
||||
case GSM_PCHAN_TCH_H:
|
||||
from = 2; to = 7;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
/* Every secondary TRX is configured for TCH/F
|
||||
* and TCH/H only */
|
||||
switch (pchan) {
|
||||
case GSM_PCHAN_TCH_F:
|
||||
case GSM_PCHAN_TCH_H:
|
||||
from = 0; to = 7;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = from; j <= to; j++) {
|
||||
|
|
|
@ -24,6 +24,7 @@ int e1_config(struct gsm_bts *bts, int cardnr, int release_l2)
|
|||
struct e1inp_line *line;
|
||||
struct e1inp_ts *sign_ts;
|
||||
struct e1inp_sign_link *oml_link, *rsl_link;
|
||||
struct gsm_bts_trx *trx = bts->c0;
|
||||
|
||||
line = talloc_zero(tall_bsc_ctx, struct e1inp_line);
|
||||
if (!line)
|
||||
|
@ -37,13 +38,13 @@ int e1_config(struct gsm_bts *bts, int cardnr, int release_l2)
|
|||
/* create signalling links for TS1 */
|
||||
sign_ts = &line->ts[1-1];
|
||||
oml_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_OML,
|
||||
bts->c0, TEI_OML, SAPI_OML);
|
||||
trx, TEI_OML, SAPI_OML);
|
||||
rsl_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
|
||||
bts->c0, TEI_RSL, SAPI_RSL);
|
||||
trx, TEI_RSL, SAPI_RSL);
|
||||
|
||||
/* create back-links from bts/trx */
|
||||
bts->oml_link = oml_link;
|
||||
bts->c0->rsl_link = rsl_link;
|
||||
trx->rsl_link = rsl_link;
|
||||
|
||||
/* enable subchannel demuxer on TS2 */
|
||||
subch_demux_activate(&line->ts[2-1].trau.demux, 1);
|
||||
|
@ -56,18 +57,31 @@ int e1_config(struct gsm_bts *bts, int cardnr, int release_l2)
|
|||
subch_demux_activate(&line->ts[3-1].trau.demux, 2);
|
||||
subch_demux_activate(&line->ts[3-1].trau.demux, 3);
|
||||
|
||||
#ifdef HAVE_TRX1
|
||||
/* create E1 timeslots for TRAU frames of TRX1 */
|
||||
e1inp_ts_config(&line->ts[4-1], line, E1INP_TS_TYPE_TRAU);
|
||||
e1inp_ts_config(&line->ts[5-1], line, E1INP_TS_TYPE_TRAU);
|
||||
trx = gsm_bts_trx_num(bts, 1);
|
||||
if (trx) {
|
||||
/* create E1 timeslots for TRAU frames of TRX1 */
|
||||
e1inp_ts_config(&line->ts[4-1], line, E1INP_TS_TYPE_TRAU);
|
||||
e1inp_ts_config(&line->ts[5-1], line, E1INP_TS_TYPE_TRAU);
|
||||
|
||||
/* create RSL signalling link for TRX1 */
|
||||
sign_ts = &line->ts[1-1];
|
||||
rsl_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
|
||||
&bts->trx[1], TEI_RSL+1, SAPI_RSL);
|
||||
/* create back-links from trx */
|
||||
bts->trx[1].rsl_link = rsl_link;
|
||||
#endif
|
||||
/* create RSL signalling link for TRX1 */
|
||||
sign_ts = &line->ts[1-1];
|
||||
rsl_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
|
||||
trx, TEI_RSL+1, SAPI_RSL);
|
||||
/* create back-links from trx */
|
||||
trx->rsl_link = rsl_link;
|
||||
|
||||
/* enable subchannel demuxer on TS2 */
|
||||
subch_demux_activate(&line->ts[4-1].trau.demux, 0);
|
||||
subch_demux_activate(&line->ts[4-1].trau.demux, 1);
|
||||
subch_demux_activate(&line->ts[4-1].trau.demux, 2);
|
||||
subch_demux_activate(&line->ts[4-1].trau.demux, 3);
|
||||
|
||||
/* enable subchannel demuxer on TS3 */
|
||||
subch_demux_activate(&line->ts[5-1].trau.demux, 0);
|
||||
subch_demux_activate(&line->ts[5-1].trau.demux, 1);
|
||||
subch_demux_activate(&line->ts[5-1].trau.demux, 2);
|
||||
subch_demux_activate(&line->ts[5-1].trau.demux, 3);
|
||||
}
|
||||
|
||||
return mi_setup(cardnr, line, release_l2);
|
||||
}
|
||||
|
|
|
@ -1278,7 +1278,7 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
|
|||
return gsm0408_authorize(lchan, msg);
|
||||
}
|
||||
|
||||
/* 9.1.5 Channel mode modify */
|
||||
/* 9.1.5 Channel mode modify: Modify the mode on the MS side */
|
||||
int gsm48_tx_chan_mode_modify(struct gsm_lchan *lchan, u_int8_t mode)
|
||||
{
|
||||
struct msgb *msg = gsm48_msgb_alloc();
|
||||
|
@ -1744,6 +1744,9 @@ static int gsm0408_rcv_rr(struct msgb *msg)
|
|||
break;
|
||||
case GSM48_MT_RR_CHAN_MODE_MODIF_ACK:
|
||||
DEBUGP(DRR, "CHANNEL MODE MODIFY ACK\n");
|
||||
/* We've successfully modified the MS side of the channel,
|
||||
* now go on to modify the BTS side of the channel */
|
||||
msg->lchan->rsl_cmode = RSL_CMOD_SPD_SPEECH;
|
||||
rc = rsl_chan_mode_modify_req(msg->lchan);
|
||||
break;
|
||||
case GSM48_MT_RR_STATUS:
|
||||
|
@ -1948,8 +1951,6 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
|
|||
}
|
||||
/* send SETUP request to called party */
|
||||
gsm48_cc_tx_setup(transt, &transt->cc.msg);
|
||||
if (is_ipaccess_bts(lchan->ts->trx->bts))
|
||||
rsl_ipacc_bind(lchan);
|
||||
break;
|
||||
case GSM_PAGING_EXPIRED:
|
||||
DEBUGP(DCC, "Paging subscr %s expired!\n",
|
||||
|
@ -2317,14 +2318,14 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
|
|||
TLVP_VAL(&tp, GSM48_IE_CC_CAP)-1);
|
||||
}
|
||||
|
||||
if (is_ipaccess_bts(msg->trx->bts))
|
||||
rsl_ipacc_bind(msg->lchan);
|
||||
|
||||
new_cc_state(trans, GSM_CSTATE_INITIATED);
|
||||
|
||||
/* indicate setup to MNCC */
|
||||
mncc_recvmsg(trans->subscr->net, trans, MNCC_SETUP_IND, &setup);
|
||||
|
||||
/* MNCC code will modify the channel asynchronously, we should
|
||||
* ipaccess-bind only after the modification has been made to the
|
||||
* lchan->tch_mode */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3294,8 +3295,19 @@ static int gsm48_cc_rx_userinfo(struct gsm_trans *trans, struct msgb *msg)
|
|||
static int gsm48_lchan_modify(struct gsm_trans *trans, void *arg)
|
||||
{
|
||||
struct gsm_mncc *mode = arg;
|
||||
int rc;
|
||||
|
||||
return gsm48_tx_chan_mode_modify(trans->lchan, mode->lchan_mode);
|
||||
rc = gsm48_tx_chan_mode_modify(trans->lchan, mode->lchan_mode);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* FIXME: we not only need to do this after mode modify, but
|
||||
* also after channel activation */
|
||||
if (is_ipaccess_bts(trans->lchan->ts->trx->bts) &&
|
||||
mode->lchan_mode != GSM48_CMODE_SIGN)
|
||||
rc = rsl_ipacc_bind(trans->lchan);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct downstate {
|
||||
|
|
|
@ -57,7 +57,7 @@ struct rtcp_hdr {
|
|||
|
||||
#define RTCP_IE_CNAME 1
|
||||
|
||||
/* iterate over all chunks in one RTCP message, kook for CNAME IEs and
|
||||
/* iterate over all chunks in one RTCP message, look for CNAME IEs and
|
||||
* replace all of those with 'new_cname' */
|
||||
static int rtcp_sdes_cname_mangle(struct msgb *msg, struct rtcp_hdr *rh,
|
||||
u_int16_t *rtcp_len, const char *new_cname)
|
||||
|
|
|
@ -45,6 +45,7 @@ Boston, MA 02111-1307, USA. */
|
|||
//#include "workqueue.h"
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
|
||||
/* Command vector which includes some level of command lists. Normally
|
||||
each daemon maintains each own cmdvec. */
|
||||
|
|
|
@ -66,32 +66,32 @@ int main() {
|
|||
struct gsm_subscriber *alice_db;
|
||||
|
||||
char *alice_imsi = "3243245432345";
|
||||
alice = db_create_subscriber(alice_imsi);
|
||||
alice = db_create_subscriber(NULL, alice_imsi);
|
||||
db_sync_subscriber(alice);
|
||||
alice_db = db_get_subscriber(GSM_SUBSCRIBER_IMSI, alice->imsi);
|
||||
alice_db = db_get_subscriber(NULL, GSM_SUBSCRIBER_IMSI, alice->imsi);
|
||||
COMPARE(alice, alice_db);
|
||||
subscr_put(alice_db);
|
||||
subscr_put(alice);
|
||||
|
||||
alice_imsi = "3693245423445";
|
||||
alice = db_create_subscriber(alice_imsi);
|
||||
alice = db_create_subscriber(NULL, alice_imsi);
|
||||
db_subscriber_assoc_imei(alice, "1234567890");
|
||||
db_subscriber_alloc_tmsi(alice);
|
||||
alice->lac=42;
|
||||
db_sync_subscriber(alice);
|
||||
alice_db = db_get_subscriber(GSM_SUBSCRIBER_IMSI, alice_imsi);
|
||||
alice_db = db_get_subscriber(NULL, GSM_SUBSCRIBER_IMSI, alice_imsi);
|
||||
COMPARE(alice, alice_db);
|
||||
subscr_put(alice);
|
||||
subscr_put(alice_db);
|
||||
|
||||
alice_imsi = "9993245423445";
|
||||
alice = db_create_subscriber(alice_imsi);
|
||||
alice = db_create_subscriber(NULL, alice_imsi);
|
||||
db_subscriber_alloc_tmsi(alice);
|
||||
alice->lac=42;
|
||||
db_sync_subscriber(alice);
|
||||
db_subscriber_assoc_imei(alice, "1234567890");
|
||||
db_subscriber_assoc_imei(alice, "6543560920");
|
||||
alice_db = db_get_subscriber(GSM_SUBSCRIBER_IMSI, alice_imsi);
|
||||
alice_db = db_get_subscriber(NULL, GSM_SUBSCRIBER_IMSI, alice_imsi);
|
||||
COMPARE(alice, alice_db);
|
||||
subscr_put(alice);
|
||||
subscr_put(alice_db);
|
||||
|
|
Loading…
Reference in New Issue