* add more GSM 04.08 IEIs
* implement function for CHANNEL MODE MODIFY * don't use hard-coded SETUP message but construct it with tlv functions
This commit is contained in:
parent
45f83a10d8
commit
7584aeac42
|
@ -34,6 +34,12 @@ struct gsm48_req_ref {
|
|||
t3_low:3;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 9.1.5 */
|
||||
struct gsm48_chan_mode_modify {
|
||||
struct gsm48_chan_desc chan_desc;
|
||||
u_int8_t mode;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 9.1.18 */
|
||||
struct gsm48_imm_ass {
|
||||
u_int8_t l2_plen;
|
||||
|
@ -360,9 +366,50 @@ struct gsm48_system_information_type_6 {
|
|||
#define GSM48_IE_NET_TIME_TZ 0x47 /* 10.5.3.9 */
|
||||
#define GSM48_IE_LSA_IDENT 0x48 /* 10.5.3.11 */
|
||||
|
||||
#define GSM48_IE_BEARER_CAP 0x04 /* 10.5.4.5 */
|
||||
#define GSM48_IE_CAUSE 0x08 /* 10.5.4.11 */
|
||||
#define GSM48_IE_CC_CAP 0x15 /* 10.5.4.5a */
|
||||
#define GSM48_IE_ALERT 0x19 /* 10.5.4.26 */
|
||||
#define GSM48_IE_FACILITY 0x1c /* 10.5.4.15 */
|
||||
#define GSM48_IE_PROGR_IND 0x1e /* 10.5.4.21 */
|
||||
#define GSM48_IE_AUX_STATUS 0x24 /* 10.5.4.4 */
|
||||
#define GSM48_IE_KPD_FACILITY 0x2c /* 10.5.4.17 */
|
||||
#define GSM48_IE_SIGNAL 0x34 /* 10.5.4.23 */
|
||||
#define GSM48_IE_CONN_NUM 0x4c /* 10.5.4.13 */
|
||||
#define GSM48_IE_CONN_SUBADDR 0x4d /* 10.5.4.14 */
|
||||
#define GSM48_IE_CALLING_BCD 0x5c /* 10.5.4.9 */
|
||||
#define GSM48_IE_CALLING_SUB 0x5d /* 10.5.4.10 */
|
||||
#define GSM48_IE_CALLED_BCD 0x5e /* 10.5.4.7 */
|
||||
#define GSM48_IE_CALLED_SUB 0x6d /* 10.5.4.8 */
|
||||
#define GSM48_IE_REDIR_BCD 0x74 /* 10.5.4.21a */
|
||||
#define GSM48_IE_REDIR_SUB 0x75 /* 10.5.4.21b */
|
||||
#define GSM48_IE_LOWL_COMPAT 0x7c /* 10.5.4.18 */
|
||||
#define GSM48_IE_HIGHL_COMPAT 0x7d /* 10.5.4.16 */
|
||||
#define GSM48_IE_USER_USER 0x7e /* 10.5.4.25 */
|
||||
#define GSM48_IE_SS_VERS 0x7f /* 10.5.4.24 */
|
||||
#define GSM48_IE_MORE_DATA 0xa0 /* 10.5.4.19 */
|
||||
#define GSM48_IE_CLIR_SUPP 0xa1 /* 10.5.4.11a */
|
||||
#define GSM48_IE_CLIR_INVOC 0xa2 /* 10.5.4.11b */
|
||||
#define GSM48_IE_REV_C_SETUP 0xa3 /* 10.5.4.22a */
|
||||
|
||||
/* Section 10.5.4.11 / Table 10.5.122 */
|
||||
#define GSM48_CAUSE_CS_GSM 0x60
|
||||
|
||||
/* Section 10.5.4.23 / Table 10.5.130 */
|
||||
enum gsm48_signal_val {
|
||||
GSM48_SIGNAL_DIALTONE = 0x00,
|
||||
GSM48_SIGNAL_RINGBACK = 0x01,
|
||||
GSM48_SIGNAL_INTERCEPT = 0x02,
|
||||
GSM48_SIGNAL_NET_CONG = 0x03,
|
||||
GSM48_SIGNAL_BUSY = 0x04,
|
||||
GSM48_SIGNAL_CONFIRM = 0x05,
|
||||
GSM48_SIGNAL_ANSWER = 0x06,
|
||||
GSM48_SIGNAL_CALL_WAIT = 0x07,
|
||||
GSM48_SIGNAL_OFF_HOOK = 0x08,
|
||||
GSM48_SIGNAL_OFF = 0x3f,
|
||||
GSM48_SIGNAL_ALERT_OFF = 0x4f,
|
||||
};
|
||||
|
||||
enum gsm48_cause_loc {
|
||||
GSM48_CAUSE_LOC_USER = 0x00,
|
||||
GSM48_CAUSE_LOC_PRN_S_LU = 0x01,
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include <openbsc/db.h>
|
||||
#include <openbsc/msgb.h>
|
||||
#include <openbsc/tlv.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
|
@ -453,6 +454,30 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
|
|||
return gsm0408_loc_upd_acc(lchan, tmsi);
|
||||
}
|
||||
|
||||
/* 9.1.5 Channel mode modify */
|
||||
int gsm48_tx_chan_mode_modify(struct gsm_lchan *lchan, u_int8_t mode)
|
||||
{
|
||||
struct msgb *msg = gsm48_msgb_alloc();
|
||||
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
|
||||
struct gsm48_chan_mode_modify *cmm =
|
||||
(struct gsm48_chan_mode_modify *) msgb_put(msg, sizeof(*cmm));
|
||||
u_int16_t arfcn = lchan->ts->trx->arfcn;
|
||||
|
||||
msg->lchan = lchan;
|
||||
gh->proto_discr = GSM48_PDISC_RR;
|
||||
gh->msg_type = GSM48_MT_RR_CHAN_MODE_MODIF;
|
||||
|
||||
/* fill the channel information element, this code
|
||||
* should probably be shared with rsl_rx_chan_rqd() */
|
||||
cmm->chan_desc.chan_nr = lchan2chan_nr(lchan);
|
||||
cmm->chan_desc.h0.h = 0;
|
||||
cmm->chan_desc.h0.arfcn_high = arfcn >> 8;
|
||||
cmm->chan_desc.h0.arfcn_low = arfcn & 0xff;
|
||||
cmm->mode = mode;
|
||||
|
||||
return gsm48_sendmsg(msg);
|
||||
}
|
||||
|
||||
/* Section 9.2.15a */
|
||||
int gsm48_tx_mm_info(struct gsm_lchan *lchan)
|
||||
{
|
||||
|
@ -682,6 +707,9 @@ static int gsm48_rr_rx_pag_resp(struct msgb *msg)
|
|||
subscr_put(subscr);
|
||||
}
|
||||
|
||||
/* FIXME: somehow signal the completion of the PAGING to
|
||||
* the entity that requested the paging */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -733,6 +761,11 @@ int gsm48_send_rr_release(struct gsm_lchan *lchan)
|
|||
|
||||
/* Call Control */
|
||||
|
||||
/* The entire call control code is written in accordance with Figure 7.10c
|
||||
* for 'very early assignment', i.e. we allocate a TCH/F during IMMEDIATE
|
||||
* ASSIGN, then first use that TCH/F for signalling and later MODE MODIFY
|
||||
* it for voice */
|
||||
|
||||
static int gsm48_cc_tx_status(struct gsm_lchan *lchan)
|
||||
{
|
||||
struct msgb *msg = gsm48_msgb_alloc();
|
||||
|
@ -775,13 +808,45 @@ static int gsm48_cc_rx_status_enq(struct msgb *msg)
|
|||
return gsm48_cc_tx_status(msg->lchan);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int gsm48_cc_rx_setup(struct msgb *msg)
|
||||
{
|
||||
return gsm48_tx_simple(msg->lchan, GSM48_PDISC_CC,
|
||||
GSM48_MT_CC_CALL_CONF);
|
||||
struct gsm_call *call = &msg->lchan->call;
|
||||
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||
struct gsm_subscriber *called_subscr;
|
||||
int ret;
|
||||
|
||||
if (call->state == GSM_CSTATE_NULL ||
|
||||
call->state == GSM_CSTATE_RELEASE_REQ)
|
||||
use_lchan(msg->lchan);
|
||||
|
||||
call->type = GSM_CT_MO;
|
||||
call->state = GSM_CSTATE_INITIATED;
|
||||
call->transaction_id = gh->proto_discr & 0xf0;
|
||||
|
||||
DEBUGP(DCC, "SETUP(tid=0x%02x)\n", call->transaction_id);
|
||||
|
||||
/* Parse the number that was dialed and lookup subscriber */
|
||||
called_subscr = NULL;
|
||||
|
||||
if (!called_subscr) {
|
||||
DEBUGP(DCC, "could not find subscriber, RELEASE\n");
|
||||
put_lchan(msg->lchan);
|
||||
return gsm48_tx_simple(msg->lchan, GSM48_PDISC_CC,
|
||||
GSM48_MT_CC_RELEASE_COMPL);
|
||||
}
|
||||
|
||||
/* start paging of the receiving end of the call */
|
||||
paging_request(msg->trx->bts, called_subscr, RSL_CHANNEED_TCH_F);
|
||||
|
||||
/* send a CALL PROCEEDING message to the MO */
|
||||
ret = gsm48_tx_simple(msg->lchan, GSM48_PDISC_CC,
|
||||
GSM48_MT_CC_CALL_PROC);
|
||||
|
||||
/* change TCH/F mode to voice */
|
||||
return gsm48_tx_chan_mode_modify(msg->lchan, 0x01);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const u_int8_t calling_bcd[] = { 0xb9, 0x83, 0x32, 0x24 };
|
||||
|
||||
int gsm48_cc_tx_setup(struct gsm_lchan *lchan)
|
||||
{
|
||||
|
@ -789,7 +854,8 @@ int gsm48_cc_tx_setup(struct gsm_lchan *lchan)
|
|||
struct gsm48_hdr *gh;
|
||||
struct gsm_call *call = &lchan->call;
|
||||
|
||||
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 8);
|
||||
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 4 +
|
||||
sizeof(calling_bcd));
|
||||
|
||||
call->type = GSM_CT_MT;
|
||||
msg->lchan = lchan;
|
||||
|
@ -797,14 +863,9 @@ int gsm48_cc_tx_setup(struct gsm_lchan *lchan)
|
|||
|
||||
gh->proto_discr = GSM48_PDISC_CC;
|
||||
gh->msg_type = GSM48_MT_CC_SETUP;
|
||||
gh->data[0] = 0x34;
|
||||
gh->data[1] = 0x00;
|
||||
gh->data[2] = 0x5c;
|
||||
gh->data[3] = 0x04;
|
||||
gh->data[4] = 0xb9;
|
||||
gh->data[5] = 0x83;
|
||||
gh->data[6] = 0x32;
|
||||
gh->data[7] = 0x24;
|
||||
msgb_tv_put(msg, GSM48_IE_SIGNAL, GSM48_SIGNAL_DIALTONE);
|
||||
msgb_tlv_put(msg, GSM48_IE_CALLING_BCD,
|
||||
sizeof(calling_bcd), calling_bcd);
|
||||
|
||||
DEBUGP(DCC, "Sending SETUP\n");
|
||||
|
||||
|
@ -860,15 +921,7 @@ static int gsm0408_rcv_cc(struct msgb *msg)
|
|||
GSM48_MT_CC_RELEASE);
|
||||
break;
|
||||
case GSM48_MT_CC_SETUP:
|
||||
if (call->state == GSM_CSTATE_NULL || call->state == GSM_CSTATE_RELEASE_REQ)
|
||||
use_lchan(msg->lchan);
|
||||
call->type = GSM_CT_MO;
|
||||
call->state = GSM_CSTATE_INITIATED;
|
||||
call->transaction_id = gh->proto_discr & 0xf0;
|
||||
DEBUGP(DCC, "SETUP(tid=0x%02x)\n", call->transaction_id);
|
||||
rc = gsm48_tx_simple(msg->lchan, GSM48_PDISC_CC,
|
||||
GSM48_MT_CC_CONNECT);
|
||||
/* FIXME: continue with CALL_PROCEEDING, ALERTING, CONNECT, RELEASE_COMPLETE */
|
||||
rc = gsm48_cc_rx_setup(msg);
|
||||
break;
|
||||
case GSM48_MT_CC_EMERG_SETUP:
|
||||
DEBUGP(DCC, "EMERGENCY SETUP\n");
|
||||
|
|
Loading…
Reference in New Issue