- add_trace("cause", "value", "%d", resp->cause.value);
-#endif
- end_trace();
- send_and_free_mncc((struct gsm_network *)gsm->network, resp->msg_type, resp);
-
- /* sending release to endpoint */
- while(p_epointlist) {
- message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
- message->param.disconnectinfo.cause = cause;
- message->param.disconnectinfo.location = location;
- message_put(message);
- /* remove epoint */
- free_epointlist(p_epointlist);
- }
- new_state(PORT_STATE_RELEASE);
- trigger_work(&p_m_g_delete);
-}
-
-/* CC_RELEASE INDICATION */
-void Pgsm::rel_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
-{
- int location = 0, cause = 16;
- struct lcr_msg *message;
-
- gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
- if (mncc->fields & MNCC_F_CAUSE) {
- location = mncc->cause.location;
- cause = mncc->cause.value;
- add_trace("cause", "coding", "%d", mncc->cause.coding);
- add_trace("cause", "location", "%d", mncc->cause.location);
- add_trace("cause", "value", "%d", mncc->cause.value);
- }
- end_trace();
-
- /* sending release to endpoint */
- while(p_epointlist) {
- message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
- message->param.disconnectinfo.cause = cause;
- message->param.disconnectinfo.location = location;
- message_put(message);
- /* remove epoint */
- free_epointlist(p_epointlist);
- }
- new_state(PORT_STATE_RELEASE);
- trigger_work(&p_m_g_delete);
-}
-
-/* NOTIFY INDICATION */
-void Pgsm::notify_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
-{
- struct lcr_msg *message;
-
- gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
- add_trace("notify", NULL, "%d", mncc->notify);
- end_trace();
-
- message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
- message->param.notifyinfo.notify = mncc->notify;
- message_put(message);
-}
-
-
-/* HOLD INDICATION */
-void Pgsm::hold_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
-{
- struct lcr_msg *message;
- struct gsm_mncc *resp, *frame;
-
- gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
- end_trace();
-
- /* notify the hold of call */
- message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
- message->param.notifyinfo.notify = INFO_NOTIFY_REMOTE_HOLD;
- message->param.notifyinfo.local = 1; /* call is held by supplementary service */
- message_put(message);
-
- /* acknowledge hold */
- gsm_trace_header(p_m_mISDNport, this, MNCC_HOLD_CNF, DIRECTION_OUT);
- end_trace();
- resp = create_mncc(MNCC_HOLD_CNF, p_m_g_callref);
- send_and_free_mncc((struct gsm_network *)gsm->network, resp->msg_type, resp);
-
- /* disable audio */
- if (p_m_g_tch_connected) { /* it should be true */
- gsm_trace_header(p_m_mISDNport, this, MNCC_FRAME_DROP, DIRECTION_OUT);
- end_trace();
- frame = create_mncc(MNCC_FRAME_DROP, p_m_g_callref);
- send_and_free_mncc((struct gsm_network *)gsm->network, frame->msg_type, frame);
- p_m_g_tch_connected = 0;
- }
-}
-
-
-/* RETRIEVE INDICATION */
-void Pgsm::retr_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
-{
- struct lcr_msg *message;
- struct gsm_mncc *resp, *frame;
-
- gsm_trace_header(p_m_mISDNport, this, msg_type, DIRECTION_IN);
- end_trace();
-
- /* notify the retrieve of call */
- message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
- message->param.notifyinfo.notify = INFO_NOTIFY_REMOTE_RETRIEVAL;
- message->param.notifyinfo.local = 1; /* call is retrieved by supplementary service */
- message_put(message);
-
- /* acknowledge retr */
- gsm_trace_header(p_m_mISDNport, this, MNCC_RETRIEVE_CNF, DIRECTION_OUT);
- end_trace();
- resp = create_mncc(MNCC_RETRIEVE_CNF, p_m_g_callref);
- send_and_free_mncc((struct gsm_network *)gsm->network, resp->msg_type, resp);
-
- /* enable audio */
- if (!p_m_g_tch_connected) { /* it should be true */
- gsm_trace_header(p_m_mISDNport, this, MNCC_FRAME_RECV, DIRECTION_OUT);
- end_trace();
- frame = create_mncc(MNCC_FRAME_RECV, p_m_g_callref);
- send_and_free_mncc((struct gsm_network *)gsm->network, frame->msg_type, frame);
- p_m_g_tch_connected = 1;
- }
-}
-
-/*
- * BSC sends message to port
- */
-static int message_bsc(struct gsm_network *net, int msg_type, void *arg)
-{
- struct gsm_mncc *mncc = (struct gsm_mncc *)arg;
- unsigned int callref = mncc->callref;
- class Port *port;
- class Pgsm *pgsm = NULL;
- char name[64];
- struct mISDNport *mISDNport;
-
- /* Special messages */
- switch(msg_type) {
- }
-
- /* find callref */
- callref = mncc->callref;
- port = port_first;
- while(port) {
- if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_mISDN_GSM) {
- pgsm = (class Pgsm *)port;
- if (pgsm->p_m_g_callref == callref) {
- break;
- }
- }
- port = port->next;
- }
-
- if (msg_type == GSM_TCHF_FRAME) {
- if (port)
- pgsm->frame_receive((struct gsm_trau_frame *)arg);
- return 0;
- }
-
- if (!port) {
- if (msg_type != MNCC_SETUP_IND)
- return(0);
- /* find gsm port */
- mISDNport = mISDNport_first;
- while(mISDNport) {
- if (mISDNport->gsm)
- break;
- mISDNport = mISDNport->next;
- }
- if (!mISDNport) {
- struct gsm_mncc *rej;
-
- rej = create_mncc(MNCC_REJ_REQ, callref);
- rej->fields |= MNCC_F_CAUSE;
- rej->cause.coding = 3;
- rej->cause.location = 1;
- rej->cause.value = 27;
- gsm_trace_header(NULL, NULL, MNCC_REJ_REQ, DIRECTION_OUT);
- add_trace("cause", "coding", "%d", rej->cause.coding);
- add_trace("cause", "location", "%d", rej->cause.location);
- add_trace("cause", "value", "%d", rej->cause.value);
- end_trace();
- send_and_free_mncc((struct gsm_network *)gsm->network, rej->msg_type, rej);
- return 0;
- }
- /* creating port object, transparent until setup with hdlc */
- SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum);
- if (!(pgsm = new Pgsm(PORT_TYPE_GSM_IN, mISDNport, name, NULL, 0, 0, B_MODE_TRANSPARENT)))
-
- FATAL("Cannot create Port instance.\n");
- }
-
- switch(msg_type) {
- case MNCC_SETUP_IND:
- pgsm->setup_ind(msg_type, callref, mncc);
- break;
-
- case MNCC_START_DTMF_IND:
- pgsm->start_dtmf_ind(msg_type, callref, mncc);
- break;
-
- case MNCC_STOP_DTMF_IND:
- pgsm->stop_dtmf_ind(msg_type, callref, mncc);
- break;
-
- case MNCC_CALL_CONF_IND:
- pgsm->call_conf_ind(msg_type, callref, mncc);
- break;
-
- case MNCC_ALERT_IND:
- pgsm->alert_ind(msg_type, callref, mncc);
- break;
-
- case MNCC_SETUP_CNF:
- pgsm->setup_cnf(msg_type, callref, mncc);
- break;
-
- case MNCC_SETUP_COMPL_IND:
- pgsm->setup_compl_ind(msg_type, callref, mncc);
- break;
-
- case MNCC_DISC_IND:
- pgsm->disc_ind(msg_type, callref, mncc);
- break;
-
- case MNCC_REL_IND:
- case MNCC_REL_CNF:
- case MNCC_REJ_IND:
- pgsm->rel_ind(msg_type, callref, mncc);
- break;
-
- case MNCC_NOTIFY_IND:
- pgsm->notify_ind(msg_type, callref, mncc);
- break;
-
- case MNCC_HOLD_IND:
- pgsm->hold_ind(msg_type, callref, mncc);
- break;
-
- case MNCC_RETRIEVE_IND:
- pgsm->retr_ind(msg_type, callref, mncc);
- break;