2 * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include <osmocore/msgb.h>
29 #include <osmocore/utils.h>
30 #include <osmocore/gsm48.h>
31 #include <osmocore/talloc.h>
33 #include <osmocom/bb/common/logging.h>
34 #include <osmocom/bb/common/osmocom_data.h>
35 #include <osmocom/bb/mobile/mncc.h>
36 #include <osmocom/bb/mobile/transaction.h>
37 #include <osmocom/bb/mobile/gsm48_cc.h>
41 static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg);
42 static int gsm48_rel_null_free(struct gsm_trans *trans);
43 int mncc_release_ind(struct osmocom_ms *ms, struct gsm_trans *trans,
44 u_int32_t callref, int location, int value);
45 static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg);
46 static int gsm48_cc_tx_connect_ack(struct gsm_trans *trans, void *arg);
52 int gsm48_cc_init(struct osmocom_ms *ms)
54 struct gsm48_cclayer *cc = &ms->cclayer;
58 if (!cc->mncc_upqueue.next == 0)
61 LOGP(DCC, LOGL_INFO, "init Call Control\n");
63 INIT_LLIST_HEAD(&cc->mncc_upqueue);
68 int gsm48_cc_exit(struct osmocom_ms *ms)
70 struct gsm48_cclayer *cc = &ms->cclayer;
71 struct gsm_trans *trans, *trans2;
74 LOGP(DCC, LOGL_INFO, "exit Call Control processes for %s\n", ms->name);
76 llist_for_each_entry_safe(trans, trans2, &ms->trans_list, entry) {
77 if (trans->protocol == GSM48_PDISC_CC)
78 LOGP(DCC, LOGL_NOTICE, "Free pendig CC-transaction.\n");
82 while ((msg = msgb_dequeue(&cc->mncc_upqueue)))
92 /* names of MNCC-SAP */
93 static const struct value_string gsm_mncc_names[] = {
94 { MNCC_SETUP_REQ, "MNCC_SETUP_REQ" },
95 { MNCC_SETUP_IND, "MNCC_SETUP_IND" },
96 { MNCC_SETUP_RSP, "MNCC_SETUP_RSP" },
97 { MNCC_SETUP_CNF, "MNCC_SETUP_CNF" },
98 { MNCC_SETUP_COMPL_REQ, "MNCC_SETUP_COMPL_REQ" },
99 { MNCC_SETUP_COMPL_IND, "MNCC_SETUP_COMPL_IND" },
100 { MNCC_CALL_CONF_IND, "MNCC_CALL_CONF_IND" },
101 { MNCC_CALL_PROC_REQ, "MNCC_CALL_PROC_REQ" },
102 { MNCC_PROGRESS_REQ, "MNCC_PROGRESS_REQ" },
103 { MNCC_ALERT_REQ, "MNCC_ALERT_REQ" },
104 { MNCC_ALERT_IND, "MNCC_ALERT_IND" },
105 { MNCC_NOTIFY_REQ, "MNCC_NOTIFY_REQ" },
106 { MNCC_NOTIFY_IND, "MNCC_NOTIFY_IND" },
107 { MNCC_DISC_REQ, "MNCC_DISC_REQ" },
108 { MNCC_DISC_IND, "MNCC_DISC_IND" },
109 { MNCC_REL_REQ, "MNCC_REL_REQ" },
110 { MNCC_REL_IND, "MNCC_REL_IND" },
111 { MNCC_REL_CNF, "MNCC_REL_CNF" },
112 { MNCC_FACILITY_REQ, "MNCC_FACILITY_REQ" },
113 { MNCC_FACILITY_IND, "MNCC_FACILITY_IND" },
114 { MNCC_START_DTMF_IND, "MNCC_START_DTMF_IND" },
115 { MNCC_START_DTMF_RSP, "MNCC_START_DTMF_RSP" },
116 { MNCC_START_DTMF_REJ, "MNCC_START_DTMF_REJ" },
117 { MNCC_STOP_DTMF_IND, "MNCC_STOP_DTMF_IND" },
118 { MNCC_STOP_DTMF_RSP, "MNCC_STOP_DTMF_RSP" },
119 { MNCC_MODIFY_REQ, "MNCC_MODIFY_REQ" },
120 { MNCC_MODIFY_IND, "MNCC_MODIFY_IND" },
121 { MNCC_MODIFY_RSP, "MNCC_MODIFY_RSP" },
122 { MNCC_MODIFY_CNF, "MNCC_MODIFY_CNF" },
123 { MNCC_MODIFY_REJ, "MNCC_MODIFY_REJ" },
124 { MNCC_HOLD_IND, "MNCC_HOLD_IND" },
125 { MNCC_HOLD_CNF, "MNCC_HOLD_CNF" },
126 { MNCC_HOLD_REJ, "MNCC_HOLD_REJ" },
127 { MNCC_RETRIEVE_IND, "MNCC_RETRIEVE_IND" },
128 { MNCC_RETRIEVE_CNF, "MNCC_RETRIEVE_CNF" },
129 { MNCC_RETRIEVE_REJ, "MNCC_RETRIEVE_REJ" },
130 { MNCC_USERINFO_REQ, "MNCC_USERINFO_REQ" },
131 { MNCC_USERINFO_IND, "MNCC_USERINFO_IND" },
132 { MNCC_REJ_REQ, "MNCC_REJ_REQ" },
133 { MNCC_REJ_IND, "MNCC_REJ_IND" },
134 { MNCC_PROGRESS_IND, "MNCC_PROGRESS_IND" },
135 { MNCC_CALL_PROC_IND, "MNCC_CALL_PROC_IND" },
136 { MNCC_CALL_CONF_REQ, "MNCC_CALL_CONF_REQ" },
137 { MNCC_START_DTMF_REQ, "MNCC_START_DTMF_REQ" },
138 { MNCC_STOP_DTMF_REQ, "MNCC_STOP_DTMF_REQ" },
139 { MNCC_HOLD_REQ, "MNCC_HOLD_REQ " },
140 { MNCC_RETRIEVE_REQ, "MNCC_RETRIEVE_REQ" },
144 const char *get_mncc_name(int value)
146 return get_value_string(gsm_mncc_names, value);
149 /* push MMCC header and send to MM */
150 static int gsm48_cc_to_mm(struct msgb *msg, struct gsm_trans *trans,
153 struct gsm48_hdr *gh = msgb_l3(msg);
154 struct gsm48_mmxx_hdr *mmh;
157 /* Add protocol type and transaction ID */
158 gh->proto_discr = trans->protocol | (trans->transaction_id << 4);
160 /* indicate emergency setup to MM layer */
161 if (gh->msg_type == GSM48_MT_CC_EMERG_SETUP)
165 msgb_push(msg, sizeof(struct gsm48_mmxx_hdr));
166 mmh = (struct gsm48_mmxx_hdr *)msg->data;
167 mmh->msg_type = msg_type;
168 mmh->ref = trans->callref;
169 mmh->transaction_id = trans->transaction_id;
170 mmh->emergency = emergency;
172 /* send message to MM */
173 LOGP(DCC, LOGL_INFO, "Sending '%s' using %s (callref=%x, "
174 "transaction_id=%d)\n", gsm48_cc_msg_name(gh->msg_type),
175 get_mmxx_name(msg_type), trans->callref, trans->transaction_id);
176 return gsm48_mmxx_downmsg(trans->ms, msg);
179 /* enqueue message to application (MNCC-SAP) */
180 static int mncc_recvmsg(struct osmocom_ms *ms, struct gsm_trans *trans,
181 int msg_type, struct gsm_mncc *mncc)
183 struct gsm48_cclayer *cc = &ms->cclayer;
187 LOGP(DCC, LOGL_INFO, "(ms %s ti %x) Sending '%s' to MNCC.\n",
188 ms->name, trans->transaction_id,
189 get_mncc_name(msg_type));
191 LOGP(DCC, LOGL_INFO, "(ms %s ti -) Sending '%s' to MNCC.\n",
192 ms->name, get_mncc_name(msg_type));
194 mncc->msg_type = msg_type;
196 msg = msgb_alloc(sizeof(struct gsm_mncc), "MNCC");
199 memcpy(msg->data, mncc, sizeof(struct gsm_mncc));
200 msgb_enqueue(&cc->mncc_upqueue, msg);
205 /* dequeue messages to layer 4 */
206 int mncc_dequeue(struct osmocom_ms *ms)
208 struct gsm48_cclayer *cc = &ms->cclayer;
209 struct gsm_mncc *mncc;
213 while ((msg = msgb_dequeue(&cc->mncc_upqueue))) {
214 mncc = (struct gsm_mncc *)msg->data;
216 cc->mncc_recv(ms, mncc->msg_type, mncc);
217 work = 1; /* work done */
229 static void new_cc_state(struct gsm_trans *trans, int state)
231 if (state > 31 || state < 0)
234 DEBUGP(DCC, "new state %s -> %s\n",
235 gsm48_cc_state_name(trans->cc.state),
236 gsm48_cc_state_name(state));
238 trans->cc.state = state;
245 /* timeout events of all timers */
246 static void gsm48_cc_timeout(void *arg)
248 struct gsm_trans *trans = arg;
249 int disconnect = 0, release = 0, abort = 1;
250 int mo_cause = GSM48_CC_CAUSE_RECOVERY_TIMER;
251 int mo_location = GSM48_CAUSE_LOC_PRN_S_LU;
252 int l4_cause = GSM48_CC_CAUSE_NORMAL_UNSPEC;
253 int l4_location = GSM48_CAUSE_LOC_PRN_S_LU;
254 struct gsm_mncc mo_rel, l4_rel;
256 memset(&mo_rel, 0, sizeof(struct gsm_mncc));
257 mo_rel.callref = trans->callref;
258 memset(&l4_rel, 0, sizeof(struct gsm_mncc));
259 l4_rel.callref = trans->callref;
261 LOGP(DCC, LOGL_INFO, "Timer T%x has fired.\n", trans->cc.Tcurrent);
263 switch(trans->cc.Tcurrent) {
265 /* abort if connection is not already esablished */
266 if (trans->cc.state == GSM_CSTATE_MM_CONNECTION_PEND)
270 l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
274 mo_cause = trans->cc.msg.cause.value;
275 mo_location = trans->cc.msg.cause.location;
278 if (!trans->cc.T308_second) {
279 /* restart T308 a second time */
280 gsm48_cc_tx_release(trans, &trans->cc.msg);
281 trans->cc.T308_second = 1;
282 break; /* stay in release state */
284 /* release MM conn, got NULL state, free trans */
285 gsm48_rel_null_free(trans);
290 l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
294 /* unknown, did not find it in the specs */
300 if ((release || abort) && trans->callref) {
301 /* process release towards layer 4 */
302 mncc_release_ind(trans->ms, trans, trans->callref,
303 l4_location, l4_cause);
306 if (disconnect && trans->callref) {
307 /* process disconnect towards layer 4 */
308 mncc_set_cause(&l4_rel, l4_location, l4_cause);
309 mncc_recvmsg(trans->ms, trans, MNCC_DISC_IND, &l4_rel);
312 /* process disconnect towards mobile station */
313 if (disconnect || release || abort) {
314 mncc_set_cause(&mo_rel, mo_location, mo_cause);
315 mo_rel.cause.diag[0] =
316 ((trans->cc.Tcurrent & 0xf00) >> 8) + '0';
317 mo_rel.cause.diag[1] =
318 ((trans->cc.Tcurrent & 0x0f0) >> 4) + '0';
319 mo_rel.cause.diag[2] = (trans->cc.Tcurrent & 0x00f) + '0';
320 mo_rel.cause.diag_len = 3;
323 gsm48_cc_tx_disconnect(trans, &mo_rel);
325 gsm48_cc_tx_release(trans, &mo_rel);
327 /* release MM conn, got NULL state, free trans */
328 gsm48_rel_null_free(trans);
333 /* start various timers */
334 static void gsm48_start_cc_timer(struct gsm_trans *trans, int current,
337 LOGP(DCC, LOGL_INFO, "starting timer T%x with %d seconds\n", current,
339 trans->cc.timer.cb = gsm48_cc_timeout;
340 trans->cc.timer.data = trans;
341 bsc_schedule_timer(&trans->cc.timer, sec, micro);
342 trans->cc.Tcurrent = current;
345 /* stop various timers */
346 static void gsm48_stop_cc_timer(struct gsm_trans *trans)
348 if (bsc_timer_pending(&trans->cc.timer)) {
349 LOGP(DCC, LOGL_INFO, "stopping pending timer T%x\n",
351 bsc_del_timer(&trans->cc.timer);
352 trans->cc.Tcurrent = 0;
357 * process handlers (misc)
360 /* Call Control Specific transaction release.
361 * gets called by trans_free, DO NOT CALL YOURSELF!
363 void _gsm48_cc_trans_free(struct gsm_trans *trans)
365 gsm48_stop_cc_timer(trans);
367 /* send release to L4, if callref still exists */
368 if (trans->callref) {
369 /* Ressource unavailable */
370 mncc_release_ind(trans->ms, trans, trans->callref,
371 GSM48_CAUSE_LOC_PRN_S_LU,
372 GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
374 if (trans->cc.state != GSM_CSTATE_NULL)
375 new_cc_state(trans, GSM_CSTATE_NULL);
378 /* release MM connection, go NULL state, free transaction */
379 static int gsm48_rel_null_free(struct gsm_trans *trans)
383 /* release MM connection */
384 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_REQ, trans->callref,
385 trans->transaction_id);
388 LOGP(DCC, LOGL_INFO, "Sending MMCC_REL_REQ\n");
389 gsm48_mmxx_downmsg(trans->ms, nmsg);
391 new_cc_state(trans, GSM_CSTATE_NULL);
399 void mncc_set_cause(struct gsm_mncc *data, int loc, int val)
401 data->fields |= MNCC_F_CAUSE;
402 data->cause.coding = 0x3;
403 data->cause.location = loc;
404 data->cause.value = val;
407 /* send release indication to upper layer */
408 int mncc_release_ind(struct osmocom_ms *ms, struct gsm_trans *trans,
409 u_int32_t callref, int location, int value)
413 memset(&rel, 0, sizeof(rel));
414 rel.callref = callref;
415 mncc_set_cause(&rel, location, value);
416 return mncc_recvmsg(ms, trans, MNCC_REL_IND, &rel);
419 /* sending status message in response to unknown message */
420 static int gsm48_cc_tx_status(struct gsm_trans *trans, int cause)
423 struct gsm48_hdr *gh;
424 uint8_t *cause_ie, *call_state_ie;
426 LOGP(DCC, LOGL_INFO, "sending STATUS (cause %d)\n", cause);
428 nmsg = gsm48_l3_msgb_alloc();
431 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
433 gh->msg_type = GSM48_MT_CC_STATUS;
435 cause_ie = msgb_put(nmsg, 3);
437 cause_ie[1] = GSM48_CAUSE_CS_GSM | GSM48_CAUSE_LOC_PRN_S_LU;
438 cause_ie[2] = 0x80 | cause;
440 call_state_ie = msgb_put(nmsg, 1);
441 call_state_ie[0] = 0xc0 | trans->cc.state;
443 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
446 /* reply status enquiry */
447 static int gsm48_cc_rx_status_enq(struct gsm_trans *trans, struct msgb *msg)
449 LOGP(DCC, LOGL_INFO, "received STATUS ENQUIREY\n");
451 return gsm48_cc_tx_status(trans, GSM48_CC_CAUSE_RESP_STATUS_INQ);
454 static int gsm48_cc_rx_status(struct gsm_trans *trans, struct msgb *msg)
456 struct gsm48_hdr *gh = msgb_l3(msg);
457 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
458 struct gsm_mncc_cause cause;
460 if (payload_len < 1 || payload_len < gh->data[0] + 1) {
461 LOGP(DCC, LOGL_NOTICE, "Short read of status message "
465 gsm48_decode_cause(&cause, gh->data);
467 LOGP(DCC, LOGL_INFO, "received STATUS (cause %d)\n", cause.value);
473 * process handlers (mobile originating call establish)
476 /* on SETUP request from L4, init MM connection */
477 static int gsm48_cc_init_mm(struct gsm_trans *trans, void *arg)
480 struct gsm_mncc *data = arg;
481 struct gsm48_mmxx_hdr *nmmh;
483 /* store setup message */
484 memcpy(&trans->cc.msg, data, sizeof(struct gsm_mncc));
486 new_cc_state(trans, GSM_CSTATE_MM_CONNECTION_PEND);
488 /* establish MM connection */
489 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_EST_REQ, trans->callref,
490 trans->transaction_id);
493 nmmh = (struct gsm48_mmxx_hdr *) nmsg->data;
496 LOGP(DCC, LOGL_INFO, "Sending MMCC_EST_REQ\n");
497 return gsm48_mmxx_downmsg(trans->ms, nmsg);
500 /* abort connection prior SETUP */
501 static int gsm48_cc_abort_mm(struct gsm_trans *trans, void *arg)
505 /* abort MM connection */
506 nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_REQ, trans->callref,
507 trans->transaction_id);
510 LOGP(DCC, LOGL_INFO, "Sending MMCC_REL_REQ\n");
511 gsm48_mmxx_downmsg(trans->ms, nmsg);
513 new_cc_state(trans, GSM_CSTATE_NULL);
521 /* setup message from upper layer */
522 static int gsm48_cc_tx_setup(struct gsm_trans *trans)
525 struct gsm48_hdr *gh;
526 struct gsm_mncc *setup = &trans->cc.msg;
527 int rc, transaction_id;
530 LOGP(DCC, LOGL_INFO, "sending SETUP\n");
532 nmsg = gsm48_l3_msgb_alloc();
535 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
537 /* transaction id must not be assigned */
538 if (trans->transaction_id != 0xff) { /* unasssigned */
539 LOGP(DCC, LOGL_NOTICE, "TX Setup with assigned transaction. "
540 "This is not allowed!\n");
541 /* Temporarily out of order */
542 rc = mncc_release_ind(trans->ms, trans, trans->callref,
543 GSM48_CAUSE_LOC_PRN_S_LU,
544 GSM48_CC_CAUSE_NORMAL_UNSPEC);
550 /* Get free transaction_id */
551 transaction_id = trans_assign_trans_id(trans->ms, GSM48_PDISC_CC, 0);
552 if (transaction_id < 0) {
553 /* no free transaction ID */
554 rc = mncc_release_ind(trans->ms, trans, trans->callref,
555 GSM48_CAUSE_LOC_PRN_S_LU,
556 GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
561 trans->transaction_id = transaction_id;
563 gh->msg_type = (setup->emergency) ? GSM48_MT_CC_EMERG_SETUP :
566 /* actually we have to start it when CM SERVICE REQUEST has been sent,
567 * but there is no primitive for that defined. i think it is ok to
568 * do it here rather than inventing MMCC-NOTIFY-IND.
570 gsm48_start_cc_timer(trans, 0x303, GSM48_T303_MS);
572 /* bearer capability (optional for emergency calls only) */
573 if (setup->fields & MNCC_F_BEARER_CAP)
574 gsm48_encode_bearer_cap(nmsg, 0, &setup->bearer_cap);
575 if (!setup->emergency) {
577 if (setup->fields & MNCC_F_FACILITY)
578 gsm48_encode_facility(nmsg, 0, &setup->facility);
579 /* called party BCD number */
580 if (setup->fields & MNCC_F_CALLED)
581 gsm48_encode_called(nmsg, &setup->called);
583 if (setup->fields & MNCC_F_USERUSER)
584 gsm48_encode_useruser(nmsg, 0, &setup->useruser);
586 if (setup->fields & MNCC_F_SSVERSION)
587 gsm48_encode_ssversion(nmsg, &setup->ssversion);
588 /* CLIR suppression */
589 if (setup->clir.sup) {
590 ie = msgb_put(nmsg, 1);
591 ie[0] = GSM48_IE_CLIR_SUPP;
593 /* CLIR invocation */
594 if (setup->clir.inv) {
595 ie = msgb_put(nmsg, 1);
596 ie[0] = GSM48_IE_CLIR_INVOC;
599 if (setup->fields & MNCC_F_CCCAP)
600 gsm48_encode_cccap(nmsg, &setup->cccap);
603 /* actually MM CONNECTION PENDING */
604 new_cc_state(trans, GSM_CSTATE_INITIATED);
606 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
609 /* progress is received from lower layer */
610 static int gsm48_cc_rx_progress(struct gsm_trans *trans, struct msgb *msg)
612 struct gsm48_hdr *gh = msgb_l3(msg);
613 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
614 struct tlv_parsed tp;
615 struct gsm_mncc progress;
617 LOGP(DCC, LOGL_INFO, "received PROGRESS\n");
619 memset(&progress, 0, sizeof(struct gsm_mncc));
620 progress.callref = trans->callref;
621 tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len,
622 GSM48_IE_PROGR_IND, 0);
624 if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
625 progress.fields |= MNCC_F_PROGRESS;
626 gsm48_decode_progress(&progress.progress,
627 TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
628 /* store last progress indicator */
629 trans->cc.prog_ind = progress.progress.descr;
632 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
633 progress.fields |= MNCC_F_USERUSER;
634 gsm48_decode_useruser(&progress.useruser,
635 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
638 return mncc_recvmsg(trans->ms, trans, MNCC_PROGRESS_IND, &progress);
641 /* call proceeding is received from lower layer */
642 static int gsm48_cc_rx_call_proceeding(struct gsm_trans *trans,
645 struct gsm48_hdr *gh = msgb_l3(msg);
646 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
647 struct tlv_parsed tp;
648 struct gsm_mncc call_proc;
650 LOGP(DCC, LOGL_INFO, "sending CALL PROCEEDING\n");
652 gsm48_stop_cc_timer(trans);
654 memset(&call_proc, 0, sizeof(struct gsm_mncc));
655 call_proc.callref = trans->callref;
656 tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
659 if (TLVP_PRESENT(&tp, GSM48_IE_REPEAT_CIR))
660 call_conf.repeat = 1;
661 if (TLVP_PRESENT(&tp, GSM48_IE_REPEAT_SEQ))
662 call_conf.repeat = 2;
664 /* bearer capability */
665 if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
666 call_proc.fields |= MNCC_F_BEARER_CAP;
667 gsm48_decode_bearer_cap(&call_proc.bearer_cap,
668 TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
671 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
672 call_proc.fields |= MNCC_F_FACILITY;
673 gsm48_decode_facility(&call_proc.facility,
674 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
678 if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
679 call_proc.fields |= MNCC_F_PROGRESS;
680 gsm48_decode_progress(&call_proc.progress,
681 TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
682 /* store last progress indicator */
683 trans->cc.prog_ind = call_proc.progress.descr;
686 /* start T310, if last progress indicator was 1 or 2 or 64 */
687 if (trans->cc.prog_ind == 1
688 || trans->cc.prog_ind == 2
689 || trans->cc.prog_ind == 64)
690 gsm48_start_cc_timer(trans, 0x310, GSM48_T310_MS);
692 new_cc_state(trans, GSM_CSTATE_MO_CALL_PROC);
694 return mncc_recvmsg(trans->ms, trans, MNCC_CALL_PROC_IND,
698 /* alerting is received by the lower layer */
699 static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg)
701 struct gsm48_hdr *gh = msgb_l3(msg);
702 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
703 struct tlv_parsed tp;
704 struct gsm_mncc alerting;
706 LOGP(DCC, LOGL_INFO, "received ALERTING\n");
708 gsm48_stop_cc_timer(trans);
709 /* no T301 in MS call control */
711 memset(&alerting, 0, sizeof(struct gsm_mncc));
712 alerting.callref = trans->callref;
713 tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
715 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
716 alerting.fields |= MNCC_F_FACILITY;
717 gsm48_decode_facility(&alerting.facility,
718 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
721 if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
722 alerting.fields |= MNCC_F_PROGRESS;
723 gsm48_decode_progress(&alerting.progress,
724 TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
727 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
728 alerting.fields |= MNCC_F_USERUSER;
729 gsm48_decode_useruser(&alerting.useruser,
730 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
733 new_cc_state(trans, GSM_CSTATE_CALL_DELIVERED);
735 return mncc_recvmsg(trans->ms, trans, MNCC_ALERT_IND,
739 /* connect is received from lower layer */
740 static int gsm48_cc_rx_connect(struct gsm_trans *trans, struct msgb *msg)
742 struct gsm48_hdr *gh = msgb_l3(msg);
743 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
744 struct tlv_parsed tp;
745 struct gsm_mncc connect;
747 LOGP(DCC, LOGL_INFO, "received CONNECT\n");
749 gsm48_stop_cc_timer(trans);
751 memset(&connect, 0, sizeof(struct gsm_mncc));
752 connect.callref = trans->callref;
753 tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
755 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
756 connect.fields |= MNCC_F_FACILITY;
757 gsm48_decode_facility(&connect.facility,
758 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
761 if (TLVP_PRESENT(&tp, GSM48_IE_CONN_BCD)) {
762 connect.fields |= MNCC_F_CONNECTED;
763 gsm48_decode_connected(&connect.connected,
764 TLVP_VAL(&tp, GSM48_IE_CONN_BCD)-1);
767 if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
768 connect.fields |= MNCC_F_PROGRESS;
769 gsm48_decode_progress(&connect.progress,
770 TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
773 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
774 connect.fields |= MNCC_F_USERUSER;
775 gsm48_decode_useruser(&connect.useruser,
776 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
779 /* ACTIVE state is set during this: */
780 gsm48_cc_tx_connect_ack(trans, NULL);
782 return mncc_recvmsg(trans->ms, trans, MNCC_SETUP_CNF, &connect);
785 /* connect ack message from upper layer */
786 static int gsm48_cc_tx_connect_ack(struct gsm_trans *trans, void *arg)
789 struct gsm48_hdr *gh;
791 LOGP(DCC, LOGL_INFO, "sending CONNECT ACKNOWLEDGE\n");
793 nmsg = gsm48_l3_msgb_alloc();
796 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
798 gh->msg_type = GSM48_MT_CC_CONNECT_ACK;
800 new_cc_state(trans, GSM_CSTATE_ACTIVE);
802 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
806 * process handlers (mobile terminating call establish)
809 /* setup is received from lower layer */
810 static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
812 struct gsm48_hdr *gh = msgb_l3(msg);
813 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
814 struct tlv_parsed tp;
815 struct gsm_mncc setup;
817 LOGP(DCC, LOGL_INFO, "received SETUP\n");
819 memset(&setup, 0, sizeof(struct gsm_mncc));
820 setup.callref = trans->callref;
821 tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
823 /* bearer capability */
824 if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
825 setup.fields |= MNCC_F_BEARER_CAP;
826 gsm48_decode_bearer_cap(&setup.bearer_cap,
827 TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
830 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
831 setup.fields |= MNCC_F_FACILITY;
832 gsm48_decode_facility(&setup.facility,
833 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
836 if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
837 setup.fields |= MNCC_F_PROGRESS;
838 gsm48_decode_progress(&setup.progress,
839 TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
842 if (TLVP_PRESENT(&tp, GSM48_IE_SIGNAL)) {
843 setup.fields |= MNCC_F_SIGNAL;
844 gsm48_decode_signal(&setup.signal,
845 TLVP_VAL(&tp, GSM48_IE_SIGNAL)-1);
847 /* calling party bcd number */
848 if (TLVP_PRESENT(&tp, GSM48_IE_CALLING_BCD)) {
849 setup.fields |= MNCC_F_CALLING;
850 gsm48_decode_calling(&setup.calling,
851 TLVP_VAL(&tp, GSM48_IE_CALLING_BCD)-1);
853 /* called party bcd number */
854 if (TLVP_PRESENT(&tp, GSM48_IE_CALLED_BCD)) {
855 setup.fields |= MNCC_F_CALLED;
856 gsm48_decode_called(&setup.called,
857 TLVP_VAL(&tp, GSM48_IE_CALLED_BCD)-1);
859 /* redirecting party bcd number */
860 if (TLVP_PRESENT(&tp, GSM48_IE_REDIR_BCD)) {
861 setup.fields |= MNCC_F_REDIRECTING;
862 gsm48_decode_redirecting(&setup.redirecting,
863 TLVP_VAL(&tp, GSM48_IE_REDIR_BCD)-1);
866 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
867 setup.fields |= MNCC_F_USERUSER;
868 gsm48_decode_useruser(&setup.useruser,
869 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
872 new_cc_state(trans, GSM_CSTATE_CALL_PRESENT);
874 /* indicate setup to MNCC */
875 mncc_recvmsg(trans->ms, trans, MNCC_SETUP_IND, &setup);
880 /* call conf message from upper layer */
881 static int gsm48_cc_tx_call_conf(struct gsm_trans *trans, void *arg)
883 struct gsm_mncc *confirm = arg;
885 struct gsm48_hdr *gh;
887 LOGP(DCC, LOGL_INFO, "sending CALL CONFIRMED (proceeding)\n");
889 nmsg = gsm48_l3_msgb_alloc();
892 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
894 gh->msg_type = GSM48_MT_CC_CALL_CONF;
896 new_cc_state(trans, GSM_CSTATE_MO_TERM_CALL_CONF);
898 /* bearer capability */
899 if (confirm->fields & MNCC_F_BEARER_CAP)
900 gsm48_encode_bearer_cap(nmsg, 0, &confirm->bearer_cap);
902 if (confirm->fields & MNCC_F_CAUSE)
903 gsm48_encode_cause(nmsg, 0, &confirm->cause);
905 if (confirm->fields & MNCC_F_CCCAP)
906 gsm48_encode_cccap(nmsg, &confirm->cccap);
908 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
911 /* alerting message from upper layer */
912 static int gsm48_cc_tx_alerting(struct gsm_trans *trans, void *arg)
914 struct gsm_mncc *alerting = arg;
916 struct gsm48_hdr *gh;
918 LOGP(DCC, LOGL_INFO, "sending ALERTING\n");
920 nmsg = gsm48_l3_msgb_alloc();
923 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
925 gh->msg_type = GSM48_MT_CC_ALERTING;
928 if (alerting->fields & MNCC_F_FACILITY)
929 gsm48_encode_facility(nmsg, 0, &alerting->facility);
931 if (alerting->fields & MNCC_F_USERUSER)
932 gsm48_encode_useruser(nmsg, 0, &alerting->useruser);
934 if (alerting->fields & MNCC_F_SSVERSION)
935 gsm48_encode_ssversion(nmsg, &alerting->ssversion);
937 new_cc_state(trans, GSM_CSTATE_CALL_RECEIVED);
939 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
942 /* connect message from upper layer */
943 static int gsm48_cc_tx_connect(struct gsm_trans *trans, void *arg)
945 struct gsm_mncc *connect = arg;
947 struct gsm48_hdr *gh;
949 LOGP(DCC, LOGL_INFO, "sending CONNECT\n");
951 nmsg = gsm48_l3_msgb_alloc();
954 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
956 gh->msg_type = GSM48_MT_CC_CONNECT;
958 gsm48_stop_cc_timer(trans);
959 gsm48_start_cc_timer(trans, 0x313, GSM48_T313_MS);
962 if (connect->fields & MNCC_F_FACILITY)
963 gsm48_encode_facility(nmsg, 0, &connect->facility);
965 if (connect->fields & MNCC_F_USERUSER)
966 gsm48_encode_useruser(nmsg, 0, &connect->useruser);
968 if (connect->fields & MNCC_F_SSVERSION)
969 gsm48_encode_ssversion(nmsg, &connect->ssversion);
971 new_cc_state(trans, GSM_CSTATE_CONNECT_REQUEST);
973 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
976 /* connect ack is received from lower layer */
977 static int gsm48_cc_rx_connect_ack(struct gsm_trans *trans, struct msgb *msg)
979 struct gsm_mncc connect_ack;
981 LOGP(DCC, LOGL_INFO, "received CONNECT ACKNOWLEDGE\n");
983 gsm48_stop_cc_timer(trans);
985 new_cc_state(trans, GSM_CSTATE_ACTIVE);
987 memset(&connect_ack, 0, sizeof(struct gsm_mncc));
988 connect_ack.callref = trans->callref;
989 return mncc_recvmsg(trans->ms, trans, MNCC_SETUP_COMPL_IND,
994 * process handlers (during active state)
997 /* notify message from upper layer */
998 static int gsm48_cc_tx_notify(struct gsm_trans *trans, void *arg)
1000 struct gsm_mncc *notify = arg;
1002 struct gsm48_hdr *gh;
1004 LOGP(DCC, LOGL_INFO, "sending NOTIFY\n");
1006 nmsg = gsm48_l3_msgb_alloc();
1009 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
1011 gh->msg_type = GSM48_MT_CC_NOTIFY;
1014 gsm48_encode_notify(nmsg, notify->notify);
1016 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
1019 /* notify is received from lower layer */
1020 static int gsm48_cc_rx_notify(struct gsm_trans *trans, struct msgb *msg)
1022 struct gsm48_hdr *gh = msgb_l3(msg);
1023 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1024 struct gsm_mncc notify;
1026 LOGP(DCC, LOGL_INFO, "received NOTIFY\n");
1028 memset(¬ify, 0, sizeof(struct gsm_mncc));
1029 notify.callref = trans->callref;
1031 if (payload_len < 1) {
1032 LOGP(DCC, LOGL_NOTICE, "Short read of notify message error.\n");
1035 gsm48_decode_notify(¬ify.notify, gh->data);
1037 return mncc_recvmsg(trans->ms, trans, MNCC_NOTIFY_IND, ¬ify);
1040 /* start dtmf message from upper layer */
1041 static int gsm48_cc_tx_start_dtmf(struct gsm_trans *trans, void *arg)
1043 struct gsm_mncc *dtmf = arg;
1045 struct gsm48_hdr *gh;
1047 LOGP(DCC, LOGL_INFO, "sending START DTMF\n");
1049 nmsg = gsm48_l3_msgb_alloc();
1052 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
1054 gh->msg_type = GSM48_MT_CC_START_DTMF;
1057 gsm48_encode_keypad(nmsg, dtmf->keypad);
1059 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
1062 /* start dtmf ack is received from lower layer */
1063 static int gsm48_cc_rx_start_dtmf_ack(struct gsm_trans *trans, struct msgb *msg)
1065 struct gsm48_hdr *gh = msgb_l3(msg);
1066 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1067 struct tlv_parsed tp;
1068 struct gsm_mncc dtmf;
1070 LOGP(DCC, LOGL_INFO, "received START DTMF ACKNOWLEDGE\n");
1072 memset(&dtmf, 0, sizeof(struct gsm_mncc));
1073 dtmf.callref = trans->callref;
1074 tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
1075 /* keypad facility */
1076 if (TLVP_PRESENT(&tp, GSM48_IE_KPD_FACILITY)) {
1077 dtmf.fields |= MNCC_F_KEYPAD;
1078 gsm48_decode_keypad(&dtmf.keypad,
1079 TLVP_VAL(&tp, GSM48_IE_KPD_FACILITY)-1);
1082 return mncc_recvmsg(trans->ms, trans, MNCC_START_DTMF_RSP, &dtmf);
1085 /* start dtmf rej is received from lower layer */
1086 static int gsm48_cc_rx_start_dtmf_rej(struct gsm_trans *trans, struct msgb *msg)
1088 struct gsm48_hdr *gh = msgb_l3(msg);
1089 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1090 struct gsm_mncc dtmf;
1092 LOGP(DCC, LOGL_INFO, "received START DTMF REJECT\n");
1094 memset(&dtmf, 0, sizeof(struct gsm_mncc));
1095 dtmf.callref = trans->callref;
1097 if (payload_len < 1) {
1098 LOGP(DCC, LOGL_NOTICE, "Short read of dtmf reject message "
1102 gsm48_decode_cause(&dtmf.cause, gh->data);
1104 return mncc_recvmsg(trans->ms, trans, MNCC_START_DTMF_REJ, &dtmf);
1107 /* stop dtmf message from upper layer */
1108 static int gsm48_cc_tx_stop_dtmf(struct gsm_trans *trans, void *arg)
1111 struct gsm48_hdr *gh;
1113 LOGP(DCC, LOGL_INFO, "sending STOP DTMF\n");
1115 nmsg = gsm48_l3_msgb_alloc();
1118 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
1120 gh->msg_type = GSM48_MT_CC_STOP_DTMF;
1122 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
1125 /* stop dtmf ack is received from lower layer */
1126 static int gsm48_cc_rx_stop_dtmf_ack(struct gsm_trans *trans, struct msgb *msg)
1128 struct gsm48_hdr *gh = msgb_l3(msg);
1129 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1130 struct tlv_parsed tp;
1131 struct gsm_mncc dtmf;
1133 LOGP(DCC, LOGL_INFO, "received STOP DTMF ACKNOWLEDGE\n");
1135 memset(&dtmf, 0, sizeof(struct gsm_mncc));
1136 dtmf.callref = trans->callref;
1137 tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
1139 return mncc_recvmsg(trans->ms, trans, MNCC_STOP_DTMF_RSP, &dtmf);
1142 /* hold message from upper layer */
1143 static int gsm48_cc_tx_hold(struct gsm_trans *trans, void *arg)
1146 struct gsm48_hdr *gh;
1148 LOGP(DCC, LOGL_INFO, "sending HOLD\n");
1150 nmsg = gsm48_l3_msgb_alloc();
1153 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
1155 gh->msg_type = GSM48_MT_CC_HOLD;
1157 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
1160 /* hold ack is received from lower layer */
1161 static int gsm48_cc_rx_hold_ack(struct gsm_trans *trans, struct msgb *msg)
1163 struct gsm_mncc hold;
1165 LOGP(DCC, LOGL_INFO, "received HOLD ACKNOWLEDGE\n");
1167 memset(&hold, 0, sizeof(struct gsm_mncc));
1168 hold.callref = trans->callref;
1170 return mncc_recvmsg(trans->ms, trans, MNCC_HOLD_CNF, &hold);
1173 /* hold rej is received from lower layer */
1174 static int gsm48_cc_rx_hold_rej(struct gsm_trans *trans, struct msgb *msg)
1176 struct gsm48_hdr *gh = msgb_l3(msg);
1177 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1178 struct gsm_mncc hold;
1180 LOGP(DCC, LOGL_INFO, "received HOLD REJECT\n");
1182 memset(&hold, 0, sizeof(struct gsm_mncc));
1183 hold.callref = trans->callref;
1185 if (payload_len < 1) {
1186 LOGP(DCC, LOGL_NOTICE, "Short read of hold reject message "
1190 gsm48_decode_cause(&hold.cause, gh->data);
1192 return mncc_recvmsg(trans->ms, trans, MNCC_HOLD_REJ, &hold);
1195 /* retrieve message from upper layer */
1196 static int gsm48_cc_tx_retrieve(struct gsm_trans *trans, void *arg)
1199 struct gsm48_hdr *gh;
1201 LOGP(DCC, LOGL_INFO, "sending RETRIEVE\n");
1203 nmsg = gsm48_l3_msgb_alloc();
1206 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
1208 gh->msg_type = GSM48_MT_CC_RETR;
1210 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
1213 /* retrieve ack is received from lower layer */
1214 static int gsm48_cc_rx_retrieve_ack(struct gsm_trans *trans, struct msgb *msg)
1216 struct gsm_mncc retrieve;
1218 LOGP(DCC, LOGL_INFO, "received RETRIEVE ACKNOWLEDGE\n");
1220 memset(&retrieve, 0, sizeof(struct gsm_mncc));
1221 retrieve.callref = trans->callref;
1223 return mncc_recvmsg(trans->ms, trans, MNCC_RETRIEVE_CNF, &retrieve);
1226 /* retrieve rej is received from lower layer */
1227 static int gsm48_cc_rx_retrieve_rej(struct gsm_trans *trans, struct msgb *msg)
1229 struct gsm48_hdr *gh = msgb_l3(msg);
1230 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1231 struct gsm_mncc retrieve;
1233 LOGP(DCC, LOGL_INFO, "received RETRIEVE REJECT\n");
1235 memset(&retrieve, 0, sizeof(struct gsm_mncc));
1236 retrieve.callref = trans->callref;
1238 if (payload_len < 1) {
1239 LOGP(DCC, LOGL_NOTICE, "Short read of retrieve reject message "
1243 gsm48_decode_cause(&retrieve.cause, gh->data);
1245 return mncc_recvmsg(trans->ms, trans, MNCC_RETRIEVE_REJ, &retrieve);
1248 /* facility message from upper layer or from timer event */
1249 static int gsm48_cc_tx_facility(struct gsm_trans *trans, void *arg)
1251 struct gsm_mncc *fac = arg;
1253 struct gsm48_hdr *gh;
1255 LOGP(DCC, LOGL_INFO, "sending FACILITY\n");
1257 nmsg = gsm48_l3_msgb_alloc();
1260 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
1262 gh->msg_type = GSM48_MT_CC_FACILITY;
1265 gsm48_encode_facility(nmsg, 1, &fac->facility);
1267 if (fac->fields & MNCC_F_SSVERSION)
1268 gsm48_encode_ssversion(nmsg, &fac->ssversion);
1270 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
1273 /* facility is received from lower layer */
1274 static int gsm48_cc_rx_facility(struct gsm_trans *trans, struct msgb *msg)
1276 struct gsm48_hdr *gh = msgb_l3(msg);
1277 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1278 struct gsm_mncc fac;
1280 LOGP(DCC, LOGL_INFO, "received FACILITY\n");
1282 memset(&fac, 0, sizeof(struct gsm_mncc));
1283 fac.callref = trans->callref;
1284 if (payload_len < 1) {
1285 LOGP(DCC, LOGL_NOTICE, "Short read of facility message "
1290 gsm48_decode_facility(&fac.facility, gh->data);
1292 return mncc_recvmsg(trans->ms, trans, MNCC_FACILITY_IND, &fac);
1295 /* user info message from upper layer or from timer event */
1296 static int gsm48_cc_tx_userinfo(struct gsm_trans *trans, void *arg)
1298 struct gsm_mncc *user = arg;
1300 struct gsm48_hdr *gh;
1302 LOGP(DCC, LOGL_INFO, "sending USERINFO\n");
1304 nmsg = gsm48_l3_msgb_alloc();
1307 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
1309 gh->msg_type = GSM48_MT_CC_USER_INFO;
1312 if (user->fields & MNCC_F_USERUSER)
1313 gsm48_encode_useruser(nmsg, 1, &user->useruser);
1316 gsm48_encode_more(nmsg);
1318 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
1321 /* user info is received from lower layer */
1322 static int gsm48_cc_rx_userinfo(struct gsm_trans *trans, struct msgb *msg)
1324 struct gsm48_hdr *gh = msgb_l3(msg);
1325 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1326 struct tlv_parsed tp;
1327 struct gsm_mncc user;
1329 LOGP(DCC, LOGL_INFO, "received USERINFO\n");
1331 memset(&user, 0, sizeof(struct gsm_mncc));
1332 user.callref = trans->callref;
1333 if (payload_len < 1) {
1334 LOGP(DCC, LOGL_NOTICE, "Short read of userinfo message "
1338 tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len,
1339 GSM48_IE_USER_USER, 0);
1341 gsm48_decode_useruser(&user.useruser,
1342 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
1344 if (TLVP_PRESENT(&tp, GSM48_IE_MORE_DATA))
1347 return mncc_recvmsg(trans->ms, trans, MNCC_USERINFO_IND, &user);
1350 /* modify message from upper layer or from timer event */
1351 static int gsm48_cc_tx_modify(struct gsm_trans *trans, void *arg)
1353 struct gsm_mncc *modify = arg;
1355 struct gsm48_hdr *gh;
1357 LOGP(DCC, LOGL_INFO, "sending MODIFY\n");
1359 nmsg = gsm48_l3_msgb_alloc();
1362 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
1364 gh->msg_type = GSM48_MT_CC_MODIFY;
1366 gsm48_start_cc_timer(trans, 0x323, GSM48_T323_MS);
1368 /* bearer capability */
1369 gsm48_encode_bearer_cap(nmsg, 1, &modify->bearer_cap);
1371 new_cc_state(trans, GSM_CSTATE_MO_TERM_MODIFY);
1373 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
1376 /* modify complete is received from lower layer */
1377 static int gsm48_cc_rx_modify_complete(struct gsm_trans *trans,
1380 struct gsm48_hdr *gh = msgb_l3(msg);
1381 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1382 struct gsm_mncc modify;
1384 LOGP(DCC, LOGL_INFO, "received MODIFY COMPLETE\n");
1386 gsm48_stop_cc_timer(trans);
1388 memset(&modify, 0, sizeof(struct gsm_mncc));
1389 modify.callref = trans->callref;
1390 if (payload_len < 1) {
1391 LOGP(DCC, LOGL_NOTICE, "Short read of modify complete message "
1395 /* bearer capability */
1396 gsm48_decode_bearer_cap(&modify.bearer_cap, gh->data);
1398 new_cc_state(trans, GSM_CSTATE_ACTIVE);
1400 return mncc_recvmsg(trans->ms, trans, MNCC_MODIFY_CNF, &modify);
1403 /* modify reject is received from lower layer */
1404 static int gsm48_cc_rx_modify_reject(struct gsm_trans *trans, struct msgb *msg)
1406 struct gsm48_hdr *gh = msgb_l3(msg);
1407 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1408 struct tlv_parsed tp;
1409 struct gsm_mncc modify;
1411 LOGP(DCC, LOGL_INFO, "received MODIFY REJECT\n");
1413 gsm48_stop_cc_timer(trans);
1415 memset(&modify, 0, sizeof(struct gsm_mncc));
1416 modify.callref = trans->callref;
1417 if (payload_len < 1) {
1418 LOGP(DCC, LOGL_NOTICE, "Short read of modify reject message "
1422 tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len,
1423 GSM48_IE_BEARER_CAP, GSM48_IE_CAUSE);
1424 /* bearer capability */
1425 if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
1426 modify.fields |= MNCC_F_BEARER_CAP;
1427 gsm48_decode_bearer_cap(&modify.bearer_cap,
1428 TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
1431 if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
1432 modify.fields |= MNCC_F_CAUSE;
1433 gsm48_decode_cause(&modify.cause,
1434 TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
1437 new_cc_state(trans, GSM_CSTATE_ACTIVE);
1439 return mncc_recvmsg(trans->ms, trans, MNCC_MODIFY_REJ, &modify);
1442 /* modify is received from lower layer */
1443 static int gsm48_cc_rx_modify(struct gsm_trans *trans, struct msgb *msg)
1445 struct gsm48_hdr *gh = msgb_l3(msg);
1446 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1447 struct gsm_mncc modify;
1449 LOGP(DCC, LOGL_INFO, "received MODIFY\n");
1451 memset(&modify, 0, sizeof(struct gsm_mncc));
1452 modify.callref = trans->callref;
1453 if (payload_len < 1) {
1454 LOGP(DCC, LOGL_NOTICE, "Short read of modify message error.\n");
1457 /* bearer capability */
1458 gsm48_decode_bearer_cap(&modify.bearer_cap, gh->data);
1460 new_cc_state(trans, GSM_CSTATE_MO_ORIG_MODIFY);
1462 return mncc_recvmsg(trans->ms, trans, MNCC_MODIFY_IND, &modify);
1465 /* modify complete message from upper layer or from timer event */
1466 static int gsm48_cc_tx_modify_complete(struct gsm_trans *trans, void *arg)
1468 struct gsm_mncc *modify = arg;
1470 struct gsm48_hdr *gh;
1472 LOGP(DCC, LOGL_INFO, "sending MODIFY COMPLETE\n");
1474 nmsg = gsm48_l3_msgb_alloc();
1477 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
1479 gh->msg_type = GSM48_MT_CC_MODIFY_COMPL;
1481 /* bearer capability */
1482 gsm48_encode_bearer_cap(nmsg, 1, &modify->bearer_cap);
1484 new_cc_state(trans, GSM_CSTATE_ACTIVE);
1486 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
1489 /* modify reject message from upper layer or from timer event */
1490 static int gsm48_cc_tx_modify_reject(struct gsm_trans *trans, void *arg)
1492 struct gsm_mncc *modify = arg;
1494 struct gsm48_hdr *gh;
1496 LOGP(DCC, LOGL_INFO, "sending MODIFY REJECT\n");
1498 nmsg = gsm48_l3_msgb_alloc();
1501 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
1503 gh->msg_type = GSM48_MT_CC_MODIFY_REJECT;
1505 /* bearer capability */
1506 gsm48_encode_bearer_cap(nmsg, 1, &modify->bearer_cap);
1508 gsm48_encode_cause(nmsg, 1, &modify->cause);
1510 new_cc_state(trans, GSM_CSTATE_ACTIVE);
1512 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
1516 * process handlers (call clearing)
1519 static struct gsm_mncc_cause default_cause = {
1520 .location = GSM48_CAUSE_LOC_PRN_S_LU,
1524 .value = GSM48_CC_CAUSE_NORMAL_UNSPEC,
1529 /* disconnect message from upper layer or from timer event */
1530 static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg)
1532 struct gsm_mncc *disc = arg;
1534 struct gsm48_hdr *gh;
1536 LOGP(DCC, LOGL_INFO, "sending DISCONNECT\n");
1538 nmsg = gsm48_l3_msgb_alloc();
1541 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
1543 gh->msg_type = GSM48_MT_CC_DISCONNECT;
1545 gsm48_stop_cc_timer(trans);
1546 gsm48_start_cc_timer(trans, 0x305, GSM48_T305_MS);
1549 if (disc->fields & MNCC_F_CAUSE)
1550 gsm48_encode_cause(nmsg, 1, &disc->cause);
1552 gsm48_encode_cause(nmsg, 1, &default_cause);
1555 if (disc->fields & MNCC_F_FACILITY)
1556 gsm48_encode_facility(nmsg, 0, &disc->facility);
1558 if (disc->fields & MNCC_F_PROGRESS)
1559 gsm48_encode_progress(nmsg, 0, &disc->progress);
1561 if (disc->fields & MNCC_F_USERUSER)
1562 gsm48_encode_useruser(nmsg, 0, &disc->useruser);
1564 if (disc->fields & MNCC_F_SSVERSION)
1565 gsm48_encode_ssversion(nmsg, &disc->ssversion);
1567 new_cc_state(trans, GSM_CSTATE_DISCONNECT_REQ);
1569 return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
1572 /* release message from upper layer or from timer event */
1573 static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg)
1575 struct gsm_mncc *rel = arg;
1577 struct gsm48_hdr *gh;
1579 LOGP(DCC, LOGL_INFO, "sending RELEASE\n");
1581 nmsg = gsm48_l3_msgb_alloc();
1584 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
1586 gh->msg_type = GSM48_MT_CC_RELEASE;
1588 gsm48_stop_cc_timer(trans);
1589 gsm48_start_cc_timer(trans, 0x308, GSM48_T308_MS);
1592 if (rel->fields & MNCC_F_CAUSE)
1593 gsm48_encode_cause(nmsg, 0, &rel->cause);
1595 if (rel->fields & MNCC_F_FACILITY)
1596 gsm48_encode_facility(nmsg, 0, &rel->facility);
1598 if (rel->fields & MNCC_F_USERUSER)
1599 gsm48_encode_useruser(nmsg, 0, &rel->useruser);
1601 if (rel->fields & MNCC_F_SSVERSION)
1602 gsm48_encode_ssversion(nmsg, &rel->ssversion);
1604 trans->cc.T308_second = 0;
1605 memcpy(&trans->cc.msg, rel, sizeof(struct gsm_mncc));
1607 if (trans->cc.state != GSM_CSTATE_RELEASE_REQ)
1608 new_cc_state(trans, GSM_CSTATE_RELEASE_REQ);
1610 gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
1613 /* release without sending MMCC_REL_REQ */
1614 new_cc_state(trans, GSM_CSTATE_NULL);
1622 /* reject message from upper layer */
1623 static int gsm48_cc_tx_release_compl(struct gsm_trans *trans, void *arg)
1625 struct gsm_mncc *rel = arg;
1627 struct gsm48_hdr *gh;
1629 LOGP(DCC, LOGL_INFO, "sending RELEASE COMPLETE\n");
1631 nmsg = gsm48_l3_msgb_alloc();
1634 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
1636 gh->msg_type = GSM48_MT_CC_RELEASE_COMPL;
1638 gsm48_stop_cc_timer(trans);
1641 if (rel->fields & MNCC_F_CAUSE)
1642 gsm48_encode_cause(nmsg, 0, &rel->cause);
1644 if (rel->fields & MNCC_F_FACILITY)
1645 gsm48_encode_facility(nmsg, 0, &rel->facility);
1647 if (rel->fields & MNCC_F_USERUSER)
1648 gsm48_encode_useruser(nmsg, 0, &rel->useruser);
1650 if (rel->fields & MNCC_F_SSVERSION)
1651 gsm48_encode_ssversion(nmsg, &rel->ssversion);
1653 /* release without sending MMCC_REL_REQ */
1654 new_cc_state(trans, GSM_CSTATE_NULL);
1661 /* disconnect is received from lower layer */
1662 static int gsm48_cc_rx_disconnect(struct gsm_trans *trans, struct msgb *msg)
1664 struct gsm48_hdr *gh = msgb_l3(msg);
1665 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1666 struct tlv_parsed tp;
1667 struct gsm_mncc disc;
1669 LOGP(DCC, LOGL_INFO, "received DISCONNECT\n");
1671 gsm48_stop_cc_timer(trans);
1673 new_cc_state(trans, GSM_CSTATE_DISCONNECT_IND);
1675 memset(&disc, 0, sizeof(struct gsm_mncc));
1676 disc.callref = trans->callref;
1677 tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len,
1680 if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
1681 disc.fields |= MNCC_F_CAUSE;
1682 gsm48_decode_cause(&disc.cause,
1683 TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
1686 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
1687 disc.fields |= MNCC_F_FACILITY;
1688 gsm48_decode_facility(&disc.facility,
1689 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
1692 if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
1693 disc.fields |= MNCC_F_PROGRESS;
1694 gsm48_decode_progress(&disc.progress,
1695 TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
1698 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
1699 disc.fields |= MNCC_F_USERUSER;
1700 gsm48_decode_useruser(&disc.useruser,
1701 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
1704 /* store disconnect cause for T305 expiry */
1705 memcpy(&trans->cc.msg, &disc, sizeof(struct gsm_mncc));
1707 return mncc_recvmsg(trans->ms, trans, MNCC_DISC_IND, &disc);
1710 /* release is received from lower layer */
1711 static int gsm48_cc_rx_release(struct gsm_trans *trans, struct msgb *msg)
1713 struct gsm48_hdr *gh = msgb_l3(msg);
1714 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1715 struct tlv_parsed tp;
1716 struct gsm_mncc rel;
1718 LOGP(DCC, LOGL_INFO, "received RELEASE\n");
1720 gsm48_stop_cc_timer(trans);
1722 memset(&rel, 0, sizeof(struct gsm_mncc));
1723 rel.callref = trans->callref;
1724 tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
1726 if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
1727 rel.fields |= MNCC_F_CAUSE;
1728 gsm48_decode_cause(&rel.cause,
1729 TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
1732 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
1733 rel.fields |= MNCC_F_FACILITY;
1734 gsm48_decode_facility(&rel.facility,
1735 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
1738 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
1739 rel.fields |= MNCC_F_USERUSER;
1740 gsm48_decode_useruser(&rel.useruser,
1741 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
1744 /* in case we receive a relase, when we are already in NULL state */
1745 if (trans->cc.state == GSM_CSTATE_NULL) {
1746 LOGP(DCC, LOGL_INFO, "ignoring RELEASE in NULL state\n");
1747 /* release MM conn, free trans */
1748 return gsm48_rel_null_free(trans);
1750 if (trans->cc.state == GSM_CSTATE_RELEASE_REQ) {
1751 /* release collision 5.4.5 */
1752 mncc_recvmsg(trans->ms, trans, MNCC_REL_CNF, &rel);
1756 /* forward cause only */
1757 LOGP(DCC, LOGL_INFO, "sending RELEASE COMPLETE\n");
1759 nmsg = gsm48_l3_msgb_alloc();
1762 gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
1764 gh->msg_type = GSM48_MT_CC_RELEASE_COMPL;
1766 if (rel.fields & MNCC_F_CAUSE)
1767 gsm48_encode_cause(nmsg, 0, &rel.cause);
1769 gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
1771 /* release indication */
1772 mncc_recvmsg(trans->ms, trans, MNCC_REL_IND, &rel);
1775 /* release MM conn, got NULL state, free trans */
1776 return gsm48_rel_null_free(trans);
1779 /* release complete is received from lower layer */
1780 static int gsm48_cc_rx_release_compl(struct gsm_trans *trans, struct msgb *msg)
1782 struct gsm48_hdr *gh = msgb_l3(msg);
1783 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1784 struct tlv_parsed tp;
1785 struct gsm_mncc rel;
1787 LOGP(DCC, LOGL_INFO, "received RELEASE COMPLETE\n");
1789 gsm48_stop_cc_timer(trans);
1791 memset(&rel, 0, sizeof(struct gsm_mncc));
1792 rel.callref = trans->callref;
1793 tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
1795 if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
1796 rel.fields |= MNCC_F_CAUSE;
1797 gsm48_decode_cause(&rel.cause,
1798 TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
1801 if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
1802 rel.fields |= MNCC_F_FACILITY;
1803 gsm48_decode_facility(&rel.facility,
1804 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
1807 if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
1808 rel.fields |= MNCC_F_USERUSER;
1809 gsm48_decode_useruser(&rel.useruser,
1810 TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
1813 if (trans->callref) {
1814 switch (trans->cc.state) {
1815 case GSM_CSTATE_CALL_PRESENT:
1816 mncc_recvmsg(trans->ms, trans,
1817 MNCC_REJ_IND, &rel);
1819 case GSM_CSTATE_RELEASE_REQ:
1820 mncc_recvmsg(trans->ms, trans,
1821 MNCC_REL_CNF, &rel);
1824 mncc_recvmsg(trans->ms, trans,
1825 MNCC_REL_IND, &rel);
1829 /* release MM conn, got NULL state, free trans */
1830 return gsm48_rel_null_free(trans);
1837 /* state trasitions for MNCC messages (upper layer) */
1838 static struct downstate {
1841 int (*rout) (struct gsm_trans *trans, void *arg);
1842 } downstatelist[] = {
1843 /* mobile originating call establishment */
1844 {SBIT(GSM_CSTATE_NULL), /* 5.2.1 */
1845 MNCC_SETUP_REQ, gsm48_cc_init_mm},
1847 {SBIT(GSM_CSTATE_MM_CONNECTION_PEND), /* 5.2.1 */
1848 MNCC_REL_REQ, gsm48_cc_abort_mm},
1850 /* mobile terminating call establishment */
1851 {SBIT(GSM_CSTATE_CALL_PRESENT), /* 5.2.2.3.1 */
1852 MNCC_CALL_CONF_REQ, gsm48_cc_tx_call_conf},
1854 {SBIT(GSM_CSTATE_MO_TERM_CALL_CONF), /* 5.2.2.3.2 */
1855 MNCC_ALERT_REQ, gsm48_cc_tx_alerting},
1857 {SBIT(GSM_CSTATE_MO_TERM_CALL_CONF) |
1858 SBIT(GSM_CSTATE_CALL_RECEIVED), /* 5.2.2.5 */
1859 MNCC_SETUP_RSP, gsm48_cc_tx_connect},
1861 /* signalling during call */
1862 {SBIT(GSM_CSTATE_ACTIVE), /* 5.3.1 */
1863 MNCC_NOTIFY_REQ, gsm48_cc_tx_notify},
1865 {ALL_STATES, /* 5.5.7.1 */
1866 MNCC_START_DTMF_REQ, gsm48_cc_tx_start_dtmf},
1868 {ALL_STATES, /* 5.5.7.3 */
1869 MNCC_STOP_DTMF_REQ, gsm48_cc_tx_stop_dtmf},
1871 {SBIT(GSM_CSTATE_ACTIVE),
1872 MNCC_HOLD_REQ, gsm48_cc_tx_hold},
1874 {SBIT(GSM_CSTATE_ACTIVE),
1875 MNCC_RETRIEVE_REQ, gsm48_cc_tx_retrieve},
1877 {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ),
1878 MNCC_FACILITY_REQ, gsm48_cc_tx_facility},
1880 {SBIT(GSM_CSTATE_ACTIVE),
1881 MNCC_USERINFO_REQ, gsm48_cc_tx_userinfo},
1884 {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_DISCONNECT_IND) -
1885 SBIT(GSM_CSTATE_RELEASE_REQ) -
1886 SBIT(GSM_CSTATE_DISCONNECT_REQ), /* 5.4.3.1 */
1887 MNCC_DISC_REQ, gsm48_cc_tx_disconnect},
1889 {SBIT(GSM_CSTATE_INITIATED),
1890 MNCC_REJ_REQ, gsm48_cc_tx_release_compl},
1892 {ALL_STATES - SBIT(GSM_CSTATE_NULL) -
1893 SBIT(GSM_CSTATE_RELEASE_REQ), /* ??? */
1894 MNCC_REL_REQ, gsm48_cc_tx_release},
1897 {SBIT(GSM_CSTATE_ACTIVE),
1898 MNCC_MODIFY_REQ, gsm48_cc_tx_modify},
1900 {SBIT(GSM_CSTATE_MO_ORIG_MODIFY),
1901 MNCC_MODIFY_RSP, gsm48_cc_tx_modify_complete},
1903 {SBIT(GSM_CSTATE_MO_ORIG_MODIFY),
1904 MNCC_MODIFY_REJ, gsm48_cc_tx_modify_reject},
1908 (sizeof(downstatelist) / sizeof(struct downstate))
1910 int mncc_send(struct osmocom_ms *ms, int msg_type, void *arg)
1912 struct gsm_mncc *data = arg;
1913 struct gsm_trans *trans;
1917 trans = trans_find_by_callref(ms, data->callref);
1920 /* check for SETUP message */
1921 if (msg_type != MNCC_SETUP_REQ) {
1922 /* Invalid call reference */
1923 LOGP(DCC, LOGL_NOTICE, "transaction not found\n");
1924 return mncc_release_ind(ms, NULL, data->callref,
1925 GSM48_CAUSE_LOC_PRN_S_LU,
1926 GSM48_CC_CAUSE_INVAL_TRANS_ID);
1928 if (data->callref >= 0x40000000) {
1929 LOGP(DCC, LOGL_FATAL, "MNCC ref wrong.\n");
1930 return mncc_release_ind(ms, NULL, data->callref,
1931 GSM48_CAUSE_LOC_PRN_S_LU,
1932 GSM48_CC_CAUSE_INVAL_TRANS_ID);
1935 /* Create transaction */
1936 trans = trans_alloc(ms, GSM48_PDISC_CC, 0xff, data->callref);
1938 /* No memory or whatever */
1939 return mncc_release_ind(ms, NULL, data->callref,
1940 GSM48_CAUSE_LOC_PRN_S_LU,
1941 GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
1946 case GSM_TCHF_FRAME:
1947 printf("TCH/F frame ignored!\n");
1951 /* Find function for current state and message */
1952 for (i = 0; i < DOWNSLLEN; i++)
1953 if ((msg_type == downstatelist[i].type)
1954 && ((1 << trans->cc.state) & downstatelist[i].states))
1956 if (i == DOWNSLLEN) {
1957 LOGP(DCC, LOGL_NOTICE, "Message unhandled at this "
1962 rc = downstatelist[i].rout(trans, arg);
1967 /* state trasitions for call control messages (lower layer) */
1968 static struct datastate {
1971 int (*rout) (struct gsm_trans *trans, struct msgb *msg);
1972 } datastatelist[] = {
1973 /* mobile originating call establishment */
1974 {SBIT(GSM_CSTATE_INITIATED), /* 5.2.1.3 */
1975 GSM48_MT_CC_CALL_PROC, gsm48_cc_rx_call_proceeding},
1977 {SBIT(GSM_CSTATE_INITIATED) | SBIT(GSM_CSTATE_MO_CALL_PROC) |
1978 SBIT(GSM_CSTATE_CALL_DELIVERED), /* 5.2.1.4.1 */
1979 GSM48_MT_CC_PROGRESS, gsm48_cc_rx_progress},
1981 {SBIT(GSM_CSTATE_INITIATED) |
1982 SBIT(GSM_CSTATE_MO_CALL_PROC), /* 5.2.1.5 */
1983 GSM48_MT_CC_ALERTING, gsm48_cc_rx_alerting},
1985 {SBIT(GSM_CSTATE_INITIATED) | SBIT(GSM_CSTATE_MO_CALL_PROC) |
1986 SBIT(GSM_CSTATE_CALL_DELIVERED), /* 5.2.1.6 */
1987 GSM48_MT_CC_CONNECT, gsm48_cc_rx_connect},
1989 /* mobile terminating call establishment */
1990 {SBIT(GSM_CSTATE_NULL), /* 5.2.2.1 */
1991 GSM48_MT_CC_SETUP, gsm48_cc_rx_setup},
1993 {SBIT(GSM_CSTATE_CONNECT_REQUEST), /* 5.2.2.6 */
1994 GSM48_MT_CC_CONNECT_ACK, gsm48_cc_rx_connect_ack},
1996 /* signalling during call */
1997 {SBIT(GSM_CSTATE_ACTIVE), /* 5.3.1 */
1998 GSM48_MT_CC_NOTIFY, gsm48_cc_rx_notify},
2000 {ALL_STATES, /* 8.4 */
2001 GSM48_MT_CC_STATUS_ENQ, gsm48_cc_rx_status_enq},
2004 GSM48_MT_CC_STATUS, gsm48_cc_rx_status},
2006 {ALL_STATES, /* 5.5.7.2 */
2007 GSM48_MT_CC_START_DTMF_ACK, gsm48_cc_rx_start_dtmf_ack},
2009 {ALL_STATES, /* 5.5.7.2 */
2010 GSM48_MT_CC_START_DTMF_REJ, gsm48_cc_rx_start_dtmf_rej},
2012 {ALL_STATES, /* 5.5.7.4 */
2013 GSM48_MT_CC_STOP_DTMF_ACK, gsm48_cc_rx_stop_dtmf_ack},
2015 {SBIT(GSM_CSTATE_ACTIVE),
2016 GSM48_MT_CC_HOLD_ACK, gsm48_cc_rx_hold_ack},
2018 {SBIT(GSM_CSTATE_ACTIVE),
2019 GSM48_MT_CC_HOLD_REJ, gsm48_cc_rx_hold_rej},
2021 {SBIT(GSM_CSTATE_ACTIVE),
2022 GSM48_MT_CC_RETR_ACK, gsm48_cc_rx_retrieve_ack},
2024 {SBIT(GSM_CSTATE_ACTIVE),
2025 GSM48_MT_CC_RETR_REJ, gsm48_cc_rx_retrieve_rej},
2027 {ALL_STATES - SBIT(GSM_CSTATE_NULL),
2028 GSM48_MT_CC_FACILITY, gsm48_cc_rx_facility},
2030 {SBIT(GSM_CSTATE_ACTIVE),
2031 GSM48_MT_CC_USER_INFO, gsm48_cc_rx_userinfo},
2034 {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ) -
2035 SBIT(GSM_CSTATE_DISCONNECT_IND), /* 5.4.4.1.1 */
2036 GSM48_MT_CC_DISCONNECT, gsm48_cc_rx_disconnect},
2038 {ALL_STATES, /* 5.4.3.3 & 5.4.5!!!*/
2039 GSM48_MT_CC_RELEASE, gsm48_cc_rx_release},
2041 {ALL_STATES, /* 5.4.4.1.3 */
2042 GSM48_MT_CC_RELEASE_COMPL, gsm48_cc_rx_release_compl},
2045 {SBIT(GSM_CSTATE_ACTIVE),
2046 GSM48_MT_CC_MODIFY, gsm48_cc_rx_modify},
2048 {SBIT(GSM_CSTATE_MO_TERM_MODIFY),
2049 GSM48_MT_CC_MODIFY_COMPL, gsm48_cc_rx_modify_complete},
2051 {SBIT(GSM_CSTATE_MO_TERM_MODIFY),
2052 GSM48_MT_CC_MODIFY_REJECT, gsm48_cc_rx_modify_reject},
2056 (sizeof(datastatelist) / sizeof(struct datastate))
2058 static int gsm48_cc_data_ind(struct gsm_trans *trans, struct msgb *msg)
2060 struct osmocom_ms *ms = trans->ms;
2061 struct gsm48_hdr *gh = msgb_l3(msg);
2062 int msg_type = gh->msg_type & 0xbf;
2063 uint8_t transaction_id = ((gh->proto_discr & 0xf0) ^ 0x80) >> 4;
2065 int msg_supported = 0; /* determine, if message is supported at all */
2068 /* set transaction ID, if not already */
2069 trans->transaction_id = transaction_id;
2071 /* pull the MMCC header */
2072 msgb_pull(msg, sizeof(struct gsm48_mmxx_hdr));
2074 LOGP(DCC, LOGL_INFO, "(ms %s) Received '%s' in CC state %s\n", ms->name,
2075 gsm48_cc_msg_name(msg_type),
2076 gsm48_cc_state_name(trans->cc.state));
2078 /* find function for current state and message */
2079 for (i = 0; i < DATASLLEN; i++) {
2080 if (msg_type == datastatelist[i].type)
2082 if ((msg_type == datastatelist[i].type)
2083 && ((1 << trans->cc.state) & datastatelist[i].states))
2086 if (i == DATASLLEN) {
2087 if (msg_supported) {
2088 LOGP(DCC, LOGL_NOTICE, "Message unhandled at this "
2090 return gsm48_cc_tx_status(trans,
2091 GSM48_REJECT_MSG_TYPE_NOT_COMPATIBLE);
2093 LOGP(DCC, LOGL_NOTICE, "Message not supported.\n");
2094 return gsm48_cc_tx_status(trans,
2095 GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED);
2099 rc = datastatelist[i].rout(trans, msg);
2104 /* receive message from MM layer */
2105 int gsm48_rcv_cc(struct osmocom_ms *ms, struct msgb *msg)
2107 struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
2108 int msg_type = mmh->msg_type;
2109 struct gsm_trans *trans;
2112 trans = trans_find_by_callref(ms, mmh->ref);
2114 trans = trans_alloc(ms, GSM48_PDISC_CC, mmh->transaction_id,
2120 LOGP(DCC, LOGL_INFO, "(ms %s) Received '%s' in CC state %s\n", ms->name,
2121 get_mmxx_name(msg_type),
2122 gsm48_cc_state_name(trans->cc.state));
2125 case GSM48_MMCC_EST_IND:
2127 rc = gsm48_cc_data_ind(trans, msg);
2129 case GSM48_MMCC_EST_CNF:
2130 /* send setup after confirm */
2131 if (trans->cc.state == GSM_CSTATE_MM_CONNECTION_PEND)
2132 rc = gsm48_cc_tx_setup(trans);
2134 LOGP(DCC, LOGL_ERROR, "Oops, MMCC-EST-CONF in state "
2135 "%d?\n", trans->cc.state);
2137 case GSM48_MMCC_ERR_IND: /* no supporting re-establishment */
2138 case GSM48_MMCC_REL_IND:
2139 /* release L4, release transaction */
2140 mncc_release_ind(trans->ms, trans, trans->callref,
2141 GSM48_CAUSE_LOC_PRN_S_LU, mmh->cause);
2142 /* release without sending MMCC_REL_REQ */
2143 new_cc_state(trans, GSM_CSTATE_NULL);
2147 case GSM48_MMCC_DATA_IND:
2148 rc = gsm48_cc_data_ind(trans, msg);
2150 case GSM48_MMCC_UNIT_DATA_IND:
2152 case GSM48_MMCC_SYNC_IND:
2155 LOGP(DCC, LOGL_NOTICE, "Message unhandled.\n");