-
- /* 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_bcs(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_TRAU_FRAME) {
- if (port)
- pgsm->trau_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->cause = 1;
- 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;
-
- default:
- PDEBUG(DEBUG_GSM, "Pgsm(%s) gsm port with (caller id %s) received unhandled nessage: 0x%x\n", pgsm->p_name, pgsm->p_callerinfo.id, msg_type);
- }
- return(0);
-}
-
-/* MESSAGE_SETUP */
-void Pgsm::message_setup(unsigned int epoint_id, int message_id, union parameter *param)
-{
- struct lcr_msg *message;
- int ret;
- struct epoint_list *epointlist;
- struct gsm_mncc *mncc;
- int channel;
-
- /* copy setup infos to port */
- memcpy(&p_callerinfo, ¶m->setup.callerinfo, sizeof(p_callerinfo));
- memcpy(&p_dialinginfo, ¶m->setup.dialinginfo, sizeof(p_dialinginfo));
- memcpy(&p_capainfo, ¶m->setup.capainfo, sizeof(p_capainfo));
- memcpy(&p_redirinfo, ¶m->setup.redirinfo, sizeof(p_redirinfo));
-
- /* no number */
- if (!p_dialinginfo.id[0]) {
- gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_REQ, DIRECTION_OUT);
- add_trace("failure", NULL, "No dialed subscriber given.");
- end_trace();
- message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
- message->param.disconnectinfo.cause = 28;
- message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
- message_put(message);
- new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
- return;
- }
-
- /* release if port is blocked */
- if (p_m_mISDNport->ifport->block) {
- gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_REQ, DIRECTION_OUT);
- add_trace("failure", NULL, "Port blocked.");
- end_trace();
- message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
- message->param.disconnectinfo.cause = 27; // temp. unavail.
- message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
- message_put(message);
- new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
- return;
- }
-
- /* hunt channel */
- ret = channel = hunt_bchannel();
- if (ret < 0)
- goto no_channel;
- /* open channel */
- ret = seize_bchannel(channel, 1);
- if (ret < 0) {
- no_channel:
- gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_REQ, DIRECTION_OUT);
- add_trace("failure", NULL, "No internal audio channel available.");
- end_trace();
- message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
- message->param.disconnectinfo.cause = 34;
- message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
- message_put(message);
- new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
- return;
- }
- bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
- if (bchannel_open(p_m_b_index))
- goto no_channel;
-
-// SCPY(&p_m_tones_dir, param->setup.ext.tones_dir);
- /* screen outgoing caller id */
- do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_m_mISDNport->ifport->interface);
-
- /* attach only if not already */
- epointlist = p_epointlist;
- while(epointlist) {
- if (epointlist->epoint_id == epoint_id)
- break;
- epointlist = epointlist->next;
- }
- if (!epointlist)
- epointlist_new(epoint_id);
-
- /* creating l3id */
- l1l2l3_trace_header(p_m_mISDNport, this, L3_NEW_L3ID_REQ, DIRECTION_OUT);
- p_m_g_callref = new_callref++;
- add_trace("callref", "new", "0x%x", p_m_g_callref);
- end_trace();
-
- gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_REQ, DIRECTION_OUT);
- mncc = create_mncc(MNCC_SETUP_REQ, p_m_g_callref);
- /* caller information */
- mncc->calling = 1;
- mncc->calling_plan = 1;
- switch (p_callerinfo.ntype) {
- case INFO_NTYPE_UNKNOWN:
- mncc->calling_type = 0x0;
- break;
- case INFO_NTYPE_INTERNATIONAL:
- mncc->calling_type = 0x1;
- break;
- case INFO_NTYPE_NATIONAL:
- mncc->calling_type = 0x2;
- break;
- case INFO_NTYPE_SUBSCRIBER:
- mncc->calling_type = 0x4;
- break;
- default: /* INFO_NTYPE_NOTPRESENT */
- mncc->calling = 0;
- break;
- }
- switch (p_callerinfo.screen) {
- case INFO_SCREEN_USER:
- mncc->calling_screen = 0;
- break;
- default: /* INFO_SCREEN_NETWORK */
- mncc->calling_screen = 3;
- break;
- }
- switch (p_callerinfo.present) {
- case INFO_PRESENT_ALLOWED:
- mncc->calling_present = 0;
- break;
- case INFO_PRESENT_RESTRICTED:
- mncc->calling_present = 1;
- break;
- default: /* INFO_PRESENT_NOTAVAIL */
- mncc->calling_present = 2;
- break;
- }
- if (mncc->calling) {
- SCPY(mncc->calling_number, p_callerinfo.id);
- add_trace("calling", "type", "%d", mncc->calling_type);
- add_trace("calling", "plan", "%d", mncc->calling_plan);
- add_trace("calling", "present", "%d", mncc->calling_present);
- add_trace("calling", "screen", "%d", mncc->calling_screen);
- add_trace("calling", "number", "%s", mncc->calling_number);
- }
- /* dialing information */
- mncc->called = 1;
- if (!strncmp(p_dialinginfo.id, "imsi-", 5)) {
- SCPY(mncc->imsi, p_dialinginfo.id+5);
- add_trace("dialing", "imsi", "%s", mncc->imsi);
- } else {
- SCPY(mncc->called_number, p_dialinginfo.id);
- add_trace("dialing", "number", "%s", mncc->called_number);
- }
-
- /* sending user-user */
-
- /* redirecting number */
- mncc->redirecting = 1;
- mncc->redirecting_plan = 1;
- switch (p_redirinfo.ntype) {
- case INFO_NTYPE_UNKNOWN:
- mncc->redirecting_type = 0x0;
- break;
- case INFO_NTYPE_INTERNATIONAL:
- mncc->redirecting_type = 0x1;
- break;
- case INFO_NTYPE_NATIONAL:
- mncc->redirecting_type = 0x2;
- break;
- case INFO_NTYPE_SUBSCRIBER:
- mncc->redirecting_type = 0x4;
- break;
- default: /* INFO_NTYPE_NOTPRESENT */
- mncc->redirecting = 0;
- break;
- }
- switch (p_redirinfo.screen) {
- case INFO_SCREEN_USER:
- mncc->redirecting_screen = 0;
- break;
- default: /* INFO_SCREE_NETWORK */
- mncc->redirecting_screen = 3;
- break;
- }
- switch (p_redirinfo.present) {
- case INFO_PRESENT_ALLOWED:
- mncc->redirecting_present = 0;
- break;
- case INFO_PRESENT_RESTRICTED:
- mncc->redirecting_present = 1;
- break;
- default: /* INFO_PRESENT_NOTAVAIL */
- mncc->redirecting_present = 2;
- break;
- }
- /* sending redirecting number only in ntmode */
- if (mncc->redirecting) {
- SCPY(mncc->redirecting_number, p_redirinfo.id);
- add_trace("redir", "type", "%d", mncc->redirecting_type);
- add_trace("redir", "plan", "%d", mncc->redirecting_plan);
- add_trace("redir", "present", "%d", mncc->redirecting_present);
- add_trace("redir", "screen", "%d", mncc->redirecting_screen);
- add_trace("redir", "number", "%s", mncc->redirecting_number);
- }
- /* bearer capability */
- //todo
-
- end_trace();
- send_and_free_mncc((struct gsm_network *)gsm->network, mncc->msg_type, mncc);
-
- new_state(PORT_STATE_OUT_SETUP);
-
- message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROCEEDING);
- message_put(message);
-
- new_state(PORT_STATE_OUT_PROCEEDING);