now we get up to the SETUP of MO calls
This commit is contained in:
parent
faaa49ca51
commit
4b634544e6
|
@ -244,6 +244,22 @@ struct rsl_ie_chan_ident {
|
|||
#endif
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 9.3.22 */
|
||||
#define RLL_CAUSE_T200_EXPIRED 0x01
|
||||
#define RLL_CAUSE_REEST_REQ 0x02
|
||||
#define RLL_CAUSE_UNSOL_UA_RESP 0x03
|
||||
#define RLL_CAUSE_UNSOL_DM_RESP 0x04
|
||||
#define RLL_CAUSE_UNSOL_DM_RESP_MF 0x05
|
||||
#define RLL_CAUSE_UNSOL_SPRV_RESP 0x06
|
||||
#define RLL_CAUSE_SEQ_ERR 0x07
|
||||
#define RLL_CAUSE_UFRM_INC_PARAM 0x08
|
||||
#define RLL_CAUSE_SFRM_INC_PARAM 0x09
|
||||
#define RLL_CAUSE_IFRM_INC_MBITS 0x0a
|
||||
#define RLL_CAUSE_IFRM_INC_LEN 0x0b
|
||||
#define RLL_CAUSE_FRM_UNIMPL 0x0c
|
||||
#define RLL_CAUSE_SABM_MF 0x0d
|
||||
#define RLL_CAUSE_SABM_INFO_NOTALL 0x0e
|
||||
|
||||
/* Chapter 9.3.26 */
|
||||
#define RSL_ERRCLS_NORMAL 0x00
|
||||
#define RSL_ERRCLS_RESOURCE_UNAVAIL 0x20
|
||||
|
|
|
@ -46,6 +46,7 @@ struct gsm48_imm_ass {
|
|||
u_int8_t mob_alloc[0];
|
||||
};
|
||||
|
||||
/* Chapter 10.5.1.3 */
|
||||
struct gsm48_loc_area_id {
|
||||
u_int8_t digits[3]; /* BCD! */
|
||||
u_int16_t lac;
|
||||
|
@ -57,7 +58,6 @@ struct gsm48_loc_upd_req {
|
|||
key_seq:4;
|
||||
struct gsm48_loc_area_id lai;
|
||||
u_int8_t classmark1;
|
||||
u_int8_t ie_mi;
|
||||
u_int8_t mi_len;
|
||||
u_int8_t mi[0];
|
||||
} __attribute__ ((packed));
|
||||
|
@ -70,7 +70,7 @@ struct gsm48_hdr {
|
|||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 10.2 */
|
||||
#define GSM48_PDISC_CC 0x02
|
||||
#define GSM48_PDISC_CC 0x03
|
||||
#define GSM48_PDISC_MM 0x05
|
||||
#define GSM48_PDISC_RR 0x06
|
||||
#define GSM48_PDISC_MM_GPRS 0x08
|
||||
|
@ -235,6 +235,23 @@ struct gsm48_hdr {
|
|||
#define GSM_MI_TYPE_TMSI 0x04
|
||||
#define GSM_MI_ODD 0x08
|
||||
|
||||
#define GSM48_IE_MOBILE_ID 0x17
|
||||
|
||||
/* Section 10.5.4.11 / Table 10.5.122 */
|
||||
#define GSM48_CAUSE_CS_GSM 0x60
|
||||
|
||||
enum gsm48_cause_loc {
|
||||
GSM48_CAUSE_LOC_USER = 0x00,
|
||||
GSM48_CAUSE_LOC_PRN_S_LU = 0x01,
|
||||
GSM48_CAUSE_LOC_PUN_S_LU = 0x02,
|
||||
GSM48_CAUSE_LOC_TRANS_NET = 0x03,
|
||||
GSM48_CAUSE_LOC_PUN_S_RU = 0x04,
|
||||
GSM48_CAUSE_LOC_PRN_S_RU = 0x05,
|
||||
/* not defined */
|
||||
GSM48_CAUSE_LOC_INN_NET = 0x07,
|
||||
GSM48_CAUSE_LOC_NET_BEYOND = 0x0a,
|
||||
};
|
||||
|
||||
struct msgb;
|
||||
struct gsm_bts;
|
||||
|
||||
|
|
|
@ -57,6 +57,15 @@ static inline u_int8_t *tv_put(u_int8_t *buf, u_int8_t tag,
|
|||
return buf;
|
||||
}
|
||||
|
||||
static inline u_int8_t *tv16_put(u_int8_t *buf, u_int8_t tag,
|
||||
u_int16_t val)
|
||||
{
|
||||
*buf++ = tag;
|
||||
*buf++ = val >> 8;
|
||||
*buf++ = val & 0xff;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tlv_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, TLV_GROSS_LEN(len));
|
||||
|
@ -69,6 +78,12 @@ static inline u_int8_t *msgb_tv_put(struct msgb *msg, u_int8_t tag, u_int8_t val
|
|||
return tv_put(buf, tag, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tv16_put(struct msgb *msg, u_int8_t tag, u_int16_t val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, 3);
|
||||
return tv16_put(buf, tag, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tlv_push(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val)
|
||||
{
|
||||
u_int8_t *buf = msgb_push(msg, TLV_GROSS_LEN(len));
|
||||
|
@ -81,4 +96,11 @@ static inline u_int8_t *msgb_tv_push(struct msgb *msg, u_int8_t tag, u_int8_t va
|
|||
return tv_put(buf, tag, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tv16_push(struct msgb *msg, u_int8_t tag, u_int16_t val)
|
||||
{
|
||||
u_int8_t *buf = msgb_push(msg, 3);
|
||||
return tv16_put(buf, tag, val);
|
||||
}
|
||||
|
||||
|
||||
#endif /* _TLV_H */
|
||||
|
|
111
src/abis_rsl.c
111
src/abis_rsl.c
|
@ -336,6 +336,62 @@ int rsl_chan_activate_sdcch4(struct gsm_bts_trx_ts *ts, int subslot)
|
|||
return rsl_chan_activate(ts->trx->bts, chan_nr, 0x00, &cm, &ci, 0x01, 0x0f, 0x00);
|
||||
}
|
||||
|
||||
int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type, u_int8_t ta)
|
||||
{
|
||||
struct abis_rsl_dchan_hdr *dh;
|
||||
struct msgb *msg = rsl_msgb_alloc();
|
||||
/* FXIME: don't hardcode these!! */
|
||||
u_int8_t encr_info = 0x01;
|
||||
u_int8_t ms_power = 0x0f;
|
||||
u_int8_t bs_power = 0x01;
|
||||
|
||||
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;
|
||||
|
||||
/* 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.spd_ind = RSL_CMOD_SPD_SPEECH;
|
||||
cm.chan_rt = RSL_CMOD_CRT_TCH_Bm;
|
||||
cm.chan_rate = 0x11; /* speech coding alg version 2*/
|
||||
break;
|
||||
}
|
||||
|
||||
ci.chan_desc.iei = 0x64;
|
||||
ci.chan_desc.chan_nr = chan_nr;
|
||||
ci.chan_desc.oct3 = (TSC << 5) | ((arfcn & 0x3ff) >> 8);
|
||||
ci.chan_desc.oct4 = arfcn & 0xff;
|
||||
|
||||
dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
|
||||
init_dchan_hdr(dh, RSL_MT_CHAN_ACTIV);
|
||||
dh->chan_nr = chan_nr;
|
||||
|
||||
msgb_tv_put(msg, RSL_IE_ACT_TYPE, act_type);
|
||||
/* For compatibility with Phase 1 */
|
||||
msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm),
|
||||
(u_int8_t *) &cm);
|
||||
msgb_tlv_put(msg, RSL_IE_CHAN_IDENT, 4,
|
||||
(u_int8_t *) &ci);
|
||||
/* FIXME: this shoould be optional */
|
||||
#if 0
|
||||
msgb_tlv_put(msg, RSL_IE_ENCR_INFO, 1,
|
||||
(u_int8_t *) &encr_info);
|
||||
msgb_tv_put(msg, RSL_IE_BS_POWER, bs_power);
|
||||
#endif
|
||||
msgb_tv_put(msg, RSL_IE_MS_POWER, ms_power);
|
||||
msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
|
||||
|
||||
return abis_rsl_sendmsg(msg);
|
||||
}
|
||||
|
||||
int rsl_chan_release(struct gsm_lchan *lchan)
|
||||
{
|
||||
struct abis_rsl_dchan_hdr *dh;
|
||||
|
@ -427,7 +483,7 @@ int rsl_data_request(struct msgb *msg, u_int8_t link_id)
|
|||
}
|
||||
|
||||
/* First push the L3 IE tag and length */
|
||||
msgb_tv_push(msg, RSL_IE_L3_INFO, l3_len);
|
||||
msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
|
||||
|
||||
/* Then push the RSL header */
|
||||
rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
|
||||
|
@ -447,8 +503,27 @@ static int rsl_rx_chan_act_ack(struct msgb *msg)
|
|||
|
||||
/* BTS has confirmed channel activation, we now need
|
||||
* to assign the activated channel to the MS */
|
||||
if (rslh->ie_chan != RSL_IE_CHAN_NR)
|
||||
return -EINVAL;
|
||||
|
||||
DEBUGP(DRSL, "Channel Activate ACK Channel 0x%02x\n", rslh->chan_nr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Chapter 8.4.3: Channel Activate NACK */
|
||||
static int rsl_rx_chan_act_nack(struct msgb *msg)
|
||||
{
|
||||
struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
|
||||
|
||||
/* BTS has confirmed channel activation, we now need
|
||||
* to assign the activated channel to the MS */
|
||||
if (rslh->ie_chan != RSL_IE_CHAN_NR)
|
||||
return -EINVAL;
|
||||
|
||||
DEBUGP(DRSL, "Channel Activate NACK Channel 0x%02x\n", rslh->chan_nr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int abis_rsl_rx_dchan(struct msgb *msg)
|
||||
|
@ -460,11 +535,11 @@ static int abis_rsl_rx_dchan(struct msgb *msg)
|
|||
|
||||
switch (rslh->c.msg_type) {
|
||||
case RSL_MT_CHAN_ACTIV_ACK:
|
||||
DEBUGP(DRSL, "rsl_rx_dchan: Channel Activate ACK\n");
|
||||
rc = rsl_rx_chan_act_ack(msg);
|
||||
rc = rsl_rx_chan_act_ack(msg);
|
||||
break;
|
||||
case RSL_MT_CHAN_ACTIV_NACK:
|
||||
DEBUGP(DRSL, "rsl_rx_dchan: Channel Activate NACK\n");
|
||||
rc = rsl_rx_chan_act_nack(msg);
|
||||
break;
|
||||
case RSL_MT_CONN_FAIL:
|
||||
DEBUGP(DRSL, "rsl_rx_dchan: Connection Fail\n");
|
||||
|
@ -503,7 +578,7 @@ static int rsl_rx_error_rep(struct msgb *msg)
|
|||
return -EINVAL;
|
||||
|
||||
cause_len = rslh->data[1];
|
||||
printf(stdout, "RSL ERROR REPORT, Cause ");
|
||||
fprintf(stdout, "RSL ERROR REPORT, Cause ");
|
||||
hexdump(&rslh->data[2], cause_len);
|
||||
|
||||
return 0;
|
||||
|
@ -577,11 +652,15 @@ static int rsl_rx_chan_rqd(struct msgb *msg)
|
|||
DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %u\n",
|
||||
arfcn, ts_number, subch, lchan->type);
|
||||
|
||||
#if 0
|
||||
/* send CHANNEL ACTIVATION on RSL to BTS */
|
||||
if (lchan->ts->pchan == GSM_PCHAN_CCCH_SDCCH4)
|
||||
rsl_chan_activate_sdcch4(lchan->ts, subch);
|
||||
else
|
||||
rsl_chan_activate_tch_f(lchan->ts);
|
||||
#else
|
||||
rsl_chan_activate_lchan(lchan, 0x00, rqd_ta);
|
||||
#endif
|
||||
|
||||
/* create IMMEDIATE ASSIGN 04.08 messge */
|
||||
memset(&ia, 0, sizeof(ia));
|
||||
|
@ -589,7 +668,7 @@ static int rsl_rx_chan_rqd(struct msgb *msg)
|
|||
ia.proto_discr = GSM48_PDISC_RR;
|
||||
ia.msg_type = GSM48_MT_RR_IMM_ASS;
|
||||
ia.page_mode = GSM48_PM_NORMAL;
|
||||
ia.chan_desc.chan_nr = rsl_enc_chan_nr(RSL_CHAN_SDCCH4_ACCH, subch, ts_number);
|
||||
ia.chan_desc.chan_nr = lchan2chan_nr(lchan);
|
||||
ia.chan_desc.h0.h = 0;
|
||||
ia.chan_desc.h0.arfcn_high = arfcn >> 8;
|
||||
ia.chan_desc.h0.arfcn_low = arfcn & 0xff;
|
||||
|
@ -633,6 +712,16 @@ static int abis_rsl_rx_cchan(struct msgb *msg)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int rsl_rx_rll_err_ind(struct msgb *msg)
|
||||
{
|
||||
struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
|
||||
u_int8_t *rlm_cause = rllh->data;
|
||||
|
||||
DEBUGP(DRLL, "RLL ERROR INDICATION: chan_nr=0x%02x cause=0x%02x\n",
|
||||
rllh->chan_nr, rlm_cause[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
|
||||
0x02, 0x06,
|
||||
0x01, 0x20,
|
||||
|
@ -648,19 +737,25 @@ static int abis_rsl_rx_rll(struct msgb *msg)
|
|||
|
||||
switch (rllh->c.msg_type) {
|
||||
case RSL_MT_DATA_IND:
|
||||
DEBUGP(DRLL, "DATA INDICATION\n");
|
||||
DEBUGP(DRLL, "DATA INDICATION chan_nr=0x%02x\n", rllh->chan_nr);
|
||||
/* FIXME: Verify L3 info element */
|
||||
msg->l3h = &rllh->data[3];
|
||||
rc = gsm0408_rcvmsg(msg);
|
||||
break;
|
||||
case RSL_MT_EST_IND:
|
||||
DEBUGP(DRLL, "ESTABLISH INDICATION\n");
|
||||
DEBUGP(DRLL, "ESTABLISH INDICATION chan_nr=0x%02x\n", rllh->chan_nr);
|
||||
/* FIXME: Verify L3 info element */
|
||||
msg->l3h = &rllh->data[3];
|
||||
rc = gsm0408_rcvmsg(msg);
|
||||
break;
|
||||
case RSL_MT_ERROR_IND:
|
||||
case RSL_MT_REL_IND:
|
||||
DEBUGP(DRLL, "RELEASE INDICATION chan_nr=0x%02x\n", rllh->chan_nr);
|
||||
lchan_free(msg->lchan);
|
||||
rc = 0;
|
||||
break;
|
||||
case RSL_MT_ERROR_IND:
|
||||
rc = rsl_rx_rll_err_ind(msg);
|
||||
break;
|
||||
case RSL_MT_UNIT_DATA_IND:
|
||||
fprintf(stderr, "unimplemented Abis RLL message type 0x%02x\n",
|
||||
rllh->c.msg_type);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/chan_alloc.h>
|
||||
#include <openbsc/abis_nm.h>
|
||||
|
||||
struct gsm_bts_trx_ts *ts_c0_alloc(struct gsm_bts *bts,
|
||||
enum gsm_phys_chan_config pchan)
|
||||
|
@ -46,6 +47,14 @@ struct gsm_bts_trx_ts *ts_c0_alloc(struct gsm_bts *bts,
|
|||
return ts;
|
||||
}
|
||||
|
||||
static const enum abis_nm_chan_comb chcomb4pchan[] = {
|
||||
[GSM_PCHAN_CCCH] = NM_CHANC_mainBCCH,
|
||||
[GSM_PCHAN_CCCH_SDCCH4] = NM_CHANC_BCCCHComb,
|
||||
[GSM_PCHAN_TCH_F] = NM_CHANC_TCHFull,
|
||||
[GSM_PCHAN_TCH_H] = NM_CHANC_TCHHalf,
|
||||
[GSM_PCHAN_SDCCH8_SACCH8C] = NM_CHANC_SDCCH,
|
||||
/* FIXME: bounds check */
|
||||
};
|
||||
|
||||
/* Allocate a logical channel (TS) */
|
||||
struct gsm_bts_trx_ts *ts_alloc(struct gsm_bts *bts,
|
||||
|
@ -58,6 +67,8 @@ struct gsm_bts_trx_ts *ts_alloc(struct gsm_bts *bts,
|
|||
struct gsm_bts_trx_ts *ts = &trx->ts[j];
|
||||
if (ts->pchan == GSM_PCHAN_NONE) {
|
||||
ts->pchan = pchan;
|
||||
/* set channel attribute on OML */
|
||||
abis_nm_set_channel_attr(ts, chcomb4pchan[pchan]);
|
||||
return ts;
|
||||
}
|
||||
}
|
||||
|
|
104
src/gsm_04_08.c
104
src/gsm_04_08.c
|
@ -26,6 +26,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <openbsc/msgb.h>
|
||||
#include <openbsc/debug.h>
|
||||
|
@ -64,11 +65,11 @@ static void parse_lai(struct gsm_lai *lai, const struct gsm48_loc_area_id *lai48
|
|||
|
||||
static void to_bcd(u_int8_t *bcd, u_int16_t val)
|
||||
{
|
||||
bcd[0] = val % 10;
|
||||
bcd[2] = val % 10;
|
||||
val = val / 10;
|
||||
bcd[1] = val % 10;
|
||||
val = val / 10;
|
||||
bcd[2] = val % 10;
|
||||
bcd[0] = val % 10;
|
||||
val = val / 10;
|
||||
}
|
||||
|
||||
|
@ -82,10 +83,16 @@ static void generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc,
|
|||
lai48->digits[1] = bcd[2];
|
||||
|
||||
to_bcd(bcd, mnc);
|
||||
/* FIXME: do we need three-digit MNC? See Table 10.5.3 */
|
||||
#if 0
|
||||
lai48->digits[1] |= bcd[2] << 4;
|
||||
lai48->digits[2] = bcd[0] | (bcd[1] << 4);
|
||||
#else
|
||||
lai48->digits[1] |= 0xf << 4;
|
||||
lai48->digits[2] = bcd[1] | (bcd[2] << 4);
|
||||
#endif
|
||||
|
||||
lai48->lac = lac;
|
||||
lai48->lac = htons(lac);
|
||||
}
|
||||
|
||||
#define TMSI_LEN 4
|
||||
|
@ -93,12 +100,13 @@ static void generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc,
|
|||
|
||||
static void generate_mid_from_tmsi(u_int8_t *buf, u_int8_t *tmsi_bcd)
|
||||
{
|
||||
buf[0] = MID_TMSI_LEN;
|
||||
buf[1] = 0xf0 | GSM_MI_TYPE_TMSI;
|
||||
buf[2] = tmsi_bcd[0];
|
||||
buf[3] = tmsi_bcd[1];
|
||||
buf[4] = tmsi_bcd[2];
|
||||
buf[5] = tmsi_bcd[3];
|
||||
buf[0] = GSM48_IE_MOBILE_ID;
|
||||
buf[1] = MID_TMSI_LEN;
|
||||
buf[2] = 0xf0 | GSM_MI_TYPE_TMSI;
|
||||
buf[3] = tmsi_bcd[0];
|
||||
buf[4] = tmsi_bcd[1];
|
||||
buf[5] = tmsi_bcd[2];
|
||||
buf[6] = tmsi_bcd[3];
|
||||
}
|
||||
|
||||
static struct msgb *gsm48_msgb_alloc(void)
|
||||
|
@ -111,14 +119,45 @@ static int gsm0408_sendmsg(struct msgb *msg)
|
|||
if (msg->lchan)
|
||||
msg->trx = msg->lchan->ts->trx;
|
||||
|
||||
msg->l3h = msg->data;
|
||||
|
||||
return rsl_data_request(msg, 0);
|
||||
}
|
||||
|
||||
static int gsm48_cc_tx_status(struct gsm_lchan *lchan)
|
||||
{
|
||||
struct msgb *msg = gsm48_msgb_alloc();
|
||||
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
|
||||
u_int8_t *cause, *call_state;
|
||||
|
||||
msg->lchan = lchan;
|
||||
|
||||
gh->proto_discr = GSM48_PDISC_CC;
|
||||
gh->msg_type = GSM48_MT_CC_STATUS;
|
||||
|
||||
cause = msgb_put(msg, 3);
|
||||
cause[0] = 2;
|
||||
cause[1] = GSM48_CAUSE_CS_GSM | GSM48_CAUSE_LOC_USER;
|
||||
cause[2] = 0x80 | 30; /* response to status inquiry */
|
||||
|
||||
call_state = msgb_put(msg, 1);
|
||||
call_state[0] = 0xc0 | 0x00;
|
||||
|
||||
return gsm0408_sendmsg(msg);
|
||||
}
|
||||
|
||||
static int gsm48_cc_rx_status_enq(struct msgb *msg)
|
||||
{
|
||||
return gsm48_cc_tx_status(msg->lchan);
|
||||
}
|
||||
|
||||
static int gsm0408_rcv_cc(struct msgb *msg)
|
||||
{
|
||||
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||
u_int8_t msg_type = gh->msg_type & 0xbf;
|
||||
int rc = 0;
|
||||
|
||||
switch (gh->msg_type & 0xbf) {
|
||||
switch (msg_type) {
|
||||
case GSM48_MT_CC_CALL_CONF:
|
||||
/* Response to SETUP */
|
||||
DEBUGP(DCC, "CALL CONFIRM\n");
|
||||
|
@ -137,18 +176,27 @@ static int gsm0408_rcv_cc(struct msgb *msg)
|
|||
DEBUGP(DCC, "RELEASE\n");
|
||||
/* need to respond with RELEASE_COMPLETE */
|
||||
break;
|
||||
case GSM48_MT_CC_EMERG_SETUP:
|
||||
//DEBUGP(DCC, "EMERGENCY SETUP\n");
|
||||
case GSM48_MT_CC_STATUS_ENQ:
|
||||
rc = gsm48_cc_rx_status_enq(msg);
|
||||
break;
|
||||
case GSM48_MT_CC_DISCONNECT:
|
||||
DEBUGP(DCC, "DISCONNECT\n");
|
||||
break;
|
||||
case GSM48_MT_CC_SETUP:
|
||||
//DEBUGP(DCC, "SETUP\n");
|
||||
DEBUGP(DCC, "SETUP\n");
|
||||
/* FIXME: continue with CALL_PROCEEDING, ALERTING, CONNECT, RELEASE_COMPLETE */
|
||||
break;
|
||||
case GSM48_MT_CC_EMERG_SETUP:
|
||||
DEBUGP(DCC, "EMERGENCY SETUP\n");
|
||||
/* FIXME: continue with CALL_PROCEEDING, ALERTING, CONNECT, RELEASE_COMPLETE */
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unimplemented GSM 04.08 msg type 0x%02x\n",
|
||||
gh->msg_type);
|
||||
msg_type);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Chapter 9.2.14 : Send LOCATION UPDATE REJECT */
|
||||
|
@ -209,6 +257,7 @@ static int mm_loc_upd_req(struct msgb *msg)
|
|||
|
||||
mi_type = lu->mi[0] & GSM_MI_TYPE_MASK;
|
||||
|
||||
DEBUGP(DMM, "LUPDREQ: mi_type = 0x%02x\n", mi_type);
|
||||
switch (mi_type) {
|
||||
case GSM_MI_TYPE_IMSI:
|
||||
/* look up subscriber based on IMSI */
|
||||
|
@ -244,6 +293,29 @@ static int mm_loc_upd_req(struct msgb *msg)
|
|||
return gsm0408_loc_upd_acc(msg->lchan, subscr->tmsi);
|
||||
}
|
||||
|
||||
static int gsm48_tx_mm_serv_ack(struct gsm_lchan *lchan)
|
||||
{
|
||||
struct msgb *msg = gsm48_msgb_alloc();
|
||||
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
|
||||
|
||||
msg->lchan = lchan;
|
||||
|
||||
gh->proto_discr = GSM48_PDISC_MM;
|
||||
gh->msg_type = GSM48_MT_MM_CM_SERV_ACC;
|
||||
|
||||
DEBUGP(DMM, "-> CM SERVICE ACK\n");
|
||||
|
||||
return gsm0408_sendmsg(msg);
|
||||
}
|
||||
|
||||
static int gsm48_rx_mm_serv_req(struct msgb *msg)
|
||||
{
|
||||
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||
|
||||
DEBUGP(DMM, "CM SERVICE REQUEST\n");
|
||||
return gsm48_tx_mm_serv_ack(msg->lchan);
|
||||
}
|
||||
|
||||
static int gsm0408_rcv_mm(struct msgb *msg)
|
||||
{
|
||||
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||
|
@ -259,6 +331,8 @@ static int gsm0408_rcv_mm(struct msgb *msg)
|
|||
case GSM48_MT_MM_AUTH_RESP:
|
||||
case GSM48_MT_MM_IMSI_DETACH_IND:
|
||||
case GSM48_MT_MM_CM_SERV_REQ:
|
||||
rc = gsm48_rx_mm_serv_req(msg);
|
||||
break;
|
||||
case GSM48_MT_MM_CM_REEST_REQ:
|
||||
fprintf(stderr, "Unimplemented GSM 04.08 MM msg type 0x%02x\n",
|
||||
gh->msg_type);
|
||||
|
|
Loading…
Reference in New Issue