add minimal MO call state transitions
This commit is contained in:
parent
7eda3ab3c8
commit
4bc90a160a
207
src/gsm_04_08.c
207
src/gsm_04_08.c
|
@ -124,80 +124,6 @@ static int gsm0408_sendmsg(struct msgb *msg)
|
||||||
return rsl_data_request(msg, 0);
|
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 (msg_type) {
|
|
||||||
case GSM48_MT_CC_CALL_CONF:
|
|
||||||
/* Response to SETUP */
|
|
||||||
DEBUGP(DCC, "CALL CONFIRM\n");
|
|
||||||
break;
|
|
||||||
case GSM48_MT_CC_RELEASE_COMPL:
|
|
||||||
DEBUGP(DCC, "RELEASE COMPLETE\n");
|
|
||||||
break;
|
|
||||||
case GSM48_MT_CC_ALERTING:
|
|
||||||
DEBUGP(DCC, "ALERTING\n");
|
|
||||||
break;
|
|
||||||
case GSM48_MT_CC_CONNECT:
|
|
||||||
DEBUGP(DCC, "CONNECT\n");
|
|
||||||
/* need to respond with CONNECT_ACK */
|
|
||||||
break;
|
|
||||||
case GSM48_MT_CC_RELEASE:
|
|
||||||
DEBUGP(DCC, "RELEASE\n");
|
|
||||||
/* need to respond with RELEASE_COMPLETE */
|
|
||||||
break;
|
|
||||||
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");
|
|
||||||
/* 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",
|
|
||||||
msg_type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Chapter 9.2.14 : Send LOCATION UPDATE REJECT */
|
/* Chapter 9.2.14 : Send LOCATION UPDATE REJECT */
|
||||||
int gsm0408_loc_upd_rej(struct gsm_lchan *lchan, u_int8_t cause)
|
int gsm0408_loc_upd_rej(struct gsm_lchan *lchan, u_int8_t cause)
|
||||||
|
@ -462,6 +388,139 @@ static int gsm0408_rcv_rr(struct msgb *msg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Call Control */
|
||||||
|
|
||||||
|
/* Send a 04.08 call control message, add transaction ID and TI flag */
|
||||||
|
static int gsm48_cc_sendmsg(struct msgb *msg)
|
||||||
|
{
|
||||||
|
struct gsm48_hdr *gh = msg->data;
|
||||||
|
struct gsm_call *call = &msg->lchan->call;
|
||||||
|
|
||||||
|
gh->proto_discr |= msg->lchan->call.transaction_id;
|
||||||
|
|
||||||
|
/* GSM 04.07 Section 11.2.3.1.3 */
|
||||||
|
switch (call->type) {
|
||||||
|
case GSM_CT_MO:
|
||||||
|
gh->proto_discr |= 0x80;
|
||||||
|
break;
|
||||||
|
case GSM_CT_MT:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gsm0408_sendmsg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 gsm48_cc_sendmsg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gsm48_cc_tx_simple(struct gsm_lchan *lchan, u_int8_t msg_type)
|
||||||
|
{
|
||||||
|
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_CC;
|
||||||
|
gh->msg_type = msg_type;
|
||||||
|
|
||||||
|
return gsm48_cc_sendmsg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gsm48_cc_rx_status_enq(struct msgb *msg)
|
||||||
|
{
|
||||||
|
return gsm48_cc_tx_status(msg->lchan);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gsm48_cc_rx_setup(struct msgb *msg)
|
||||||
|
{
|
||||||
|
return gsm48_cc_tx_simple(msg->lchan, GSM48_MT_CC_CALL_CONF);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gsm0408_rcv_cc(struct msgb *msg)
|
||||||
|
{
|
||||||
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||||
|
u_int8_t msg_type = gh->msg_type & 0xbf;
|
||||||
|
struct gsm_call *call = &msg->lchan->call;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
switch (msg_type) {
|
||||||
|
case GSM48_MT_CC_CALL_CONF:
|
||||||
|
/* Response to SETUP */
|
||||||
|
DEBUGP(DCC, "CALL CONFIRM\n");
|
||||||
|
break;
|
||||||
|
case GSM48_MT_CC_RELEASE_COMPL:
|
||||||
|
/* Answer from MS to RELEASE */
|
||||||
|
DEBUGP(DCC, "RELEASE COMPLETE (state->NULL)\n");
|
||||||
|
call->state = GSM_CSTATE_NULL;
|
||||||
|
break;
|
||||||
|
case GSM48_MT_CC_ALERTING:
|
||||||
|
DEBUGP(DCC, "ALERTING\n");
|
||||||
|
break;
|
||||||
|
case GSM48_MT_CC_CONNECT:
|
||||||
|
DEBUGP(DCC, "CONNECT\n");
|
||||||
|
/* MT: need to respond with CONNECT_ACK */
|
||||||
|
rc = gsm48_cc_tx_simple(msg->lchan, GSM48_MT_CC_CONNECT_ACK);
|
||||||
|
break;
|
||||||
|
case GSM48_MT_CC_CONNECT_ACK:
|
||||||
|
/* MO: Answer to CONNECT */
|
||||||
|
call->state = GSM_CSTATE_ACTIVE;
|
||||||
|
DEBUGP(DCC, "CONNECT_ACK (state->ACTIVE)\n");
|
||||||
|
break;
|
||||||
|
case GSM48_MT_CC_RELEASE:
|
||||||
|
DEBUGP(DCC, "RELEASE\n");
|
||||||
|
/* need to respond with RELEASE_COMPLETE */
|
||||||
|
break;
|
||||||
|
case GSM48_MT_CC_STATUS_ENQ:
|
||||||
|
rc = gsm48_cc_rx_status_enq(msg);
|
||||||
|
break;
|
||||||
|
case GSM48_MT_CC_DISCONNECT:
|
||||||
|
/* Section 5.4.3.2 */
|
||||||
|
DEBUGP(DCC, "DISCONNECT (state->RELEASE_REQ)\n");
|
||||||
|
call->state = GSM_CSTATE_RELEASE_REQ;
|
||||||
|
/* FIXME: clear the network connection */
|
||||||
|
rc = gsm48_cc_tx_simple(msg->lchan, GSM48_MT_CC_RELEASE);
|
||||||
|
break;
|
||||||
|
case GSM48_MT_CC_SETUP:
|
||||||
|
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_cc_tx_simple(msg->lchan, GSM48_MT_CC_CONNECT);
|
||||||
|
/* 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",
|
||||||
|
msg_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/* here we pass in a msgb from the RSL->RLL. We expect the l3 pointer to be set */
|
/* here we pass in a msgb from the RSL->RLL. We expect the l3 pointer to be set */
|
||||||
int gsm0408_rcvmsg(struct msgb *msg)
|
int gsm0408_rcvmsg(struct msgb *msg)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue