Added support of mISDN to direct bridge feature
[lcr.git] / appbridge.cpp
index 50808ca..b52e125 100644 (file)
@@ -78,55 +78,6 @@ void EndpointAppBridge::trace_header(const char *name, int direction)
                    msgtext);
 }
 
                    msgtext);
 }
 
-/* hunts for the given interface
- * it does not need to have an mISDNport instance */
-struct interface *EndpointAppBridge::hunt_interface(char *ifname)
-{
-       struct interface *interface;
-       int there_is_an_external = 0;
-
-       interface = interface_first;
-
-       /* first find the given interface or, if not given, one with no extension */
-       checknext:
-       if (!interface) {
-               if (!there_is_an_external && !(ifname && ifname[0])) {
-                       trace_header("CHANNEL SELECTION (no external interface specified)", DIRECTION_NONE);
-                       add_trace("info", NULL, "Add 'extern' parameter to interface.conf.");
-                       end_trace();
-               }
-               return(NULL);
-       }
-
-       /* check for given interface */
-       if (ifname && ifname[0]) {
-               if (!strcasecmp(interface->name, ifname)) {
-                       /* found explicit interface */
-                       trace_header("CHANNEL SELECTION (found given interface)", DIRECTION_NONE);
-                       add_trace("interface", NULL, "%s", ifname);
-                       end_trace();
-                       goto foundif;
-               }
-
-       } else {
-               if (interface->external) {
-                       there_is_an_external = 1;
-                       /* found non extension */
-                       trace_header("CHANNEL SELECTION (found external interface)", DIRECTION_NONE);
-                       add_trace("interface", NULL, "%s", interface->name);
-                       end_trace();
-                       goto foundif;
-               }
-       }
-
-       interface = interface->next;
-       goto checknext;
-foundif:
-
-       return interface;
-}
-
-
 /* port MESSAGE_SETUP */
 void EndpointAppBridge::port_setup(struct port_list *portlist, int message_type, union parameter *param)
 {
 /* port MESSAGE_SETUP */
 void EndpointAppBridge::port_setup(struct port_list *portlist, int message_type, union parameter *param)
 {
@@ -138,6 +89,7 @@ void EndpointAppBridge::port_setup(struct port_list *portlist, int message_type,
        unsigned int bridge_id;
        unsigned int source_port_id = portlist->port_id;
        char portname[64];
        unsigned int bridge_id;
        unsigned int source_port_id = portlist->port_id;
        char portname[64];
+       int cause = 47;
 
        PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint received setup from='%s' to='%s'\n", ea_endpoint->ep_serial, param->setup.callerinfo.id, param->setup.dialinginfo.id);
 
 
        PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint received setup from='%s' to='%s'\n", ea_endpoint->ep_serial, param->setup.callerinfo.id, param->setup.dialinginfo.id);
 
@@ -156,10 +108,10 @@ void EndpointAppBridge::port_setup(struct port_list *portlist, int message_type,
                interface_in = interface_in->next;
        }
        if (!interface_in) {
                interface_in = interface_in->next;
        }
        if (!interface_in) {
-fail:
                PERROR("Cannot find source interface %s.\n", param->setup.callerinfo.interface);
                PERROR("Cannot find source interface %s.\n", param->setup.callerinfo.interface);
+fail:
                message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_RELEASE);
                message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_RELEASE);
-               message->param.disconnectinfo.cause = 47;
+               message->param.disconnectinfo.cause = cause;
                message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
                message_put(message);
 
                message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
                message_put(message);
 
@@ -186,18 +138,69 @@ fail:
 #ifdef WITH_SIP
        if (interface_out->sip) {
                port = new Psip(PORT_TYPE_SIP_OUT, portname, &port_settings, interface_out);
 #ifdef WITH_SIP
        if (interface_out->sip) {
                port = new Psip(PORT_TYPE_SIP_OUT, portname, &port_settings, interface_out);
-       }
+       } else
 #endif
 #ifdef WITH_GSM_BS
        if (interface_out->gsm_bs) {
                port = new Pgsm_bs(PORT_TYPE_GSM_BS_OUT, portname, &port_settings, interface_out);
 #endif
 #ifdef WITH_GSM_BS
        if (interface_out->gsm_bs) {
                port = new Pgsm_bs(PORT_TYPE_GSM_BS_OUT, portname, &port_settings, interface_out);
-       }
+       } else
 #endif
 #ifdef WITH_GSM_MS
        if (interface_out->gsm_ms) {
                port = new Pgsm_bs(PORT_TYPE_GSM_MS_OUT, portname, &port_settings, interface_out);
 #endif
 #ifdef WITH_GSM_MS
        if (interface_out->gsm_ms) {
                port = new Pgsm_bs(PORT_TYPE_GSM_MS_OUT, portname, &port_settings, interface_out);
-       }
+       } else
 #endif
 #endif
+       {
+#ifdef WITH_MISDN
+               struct mISDNport *mISDNport;
+               char *ifname = interface_out->name;
+               int channel = 0;
+               struct admin_list *admin;
+               int earlyb;
+               int mode = B_MODE_TRANSPARENT;
+
+               /* hunt for mISDNport and create Port */
+               mISDNport = hunt_port(ifname, &channel);
+               if (!mISDNport) {
+                       trace_header("INTERFACE (busy)", DIRECTION_NONE);
+                       add_trace("interface", NULL, "%s", ifname);
+                       end_trace();
+                       cause = 33;
+                       goto fail;
+               }
+
+               SPRINT(portname, "%s-%d-out", mISDNport->ifport->interface->name, mISDNport->portnum);
+#ifdef WITH_SS5
+               if (mISDNport->ss5)
+                       port = ss5_hunt_line(mISDNport);
+               else
+#endif
+               if (mISDNport->ifport->remote) {
+                       admin = admin_first;
+                       while(admin) {
+                               if (admin->remote_name[0] && !strcmp(admin->remote_name, mISDNport->ifport->remote_app))
+                                       break;
+                               admin = admin->next;
+                       }
+                       if (!admin) {
+                               trace_header("INTERFACE (remote not connected)", DIRECTION_NONE);
+                               add_trace("application", NULL, "%s", mISDNport->ifport->remote_app);
+                               end_trace();
+                               cause = 27;
+                               goto fail;
+                       }
+                       port = new Premote(PORT_TYPE_REMOTE_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode, admin->sock);
+               } else
+                       port = new Pdss1((mISDNport->ntmode)?PORT_TYPE_DSS1_NT_OUT:PORT_TYPE_DSS1_TE_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode);
+               earlyb = mISDNport->earlyb;
+#else
+               trace_header("INTERFACE (has no function)", DIRECTION_NONE);
+               add_trace("interface", NULL, "%s", ifname);
+               end_trace();
+               cause = 31;
+               goto fail
+#endif
+       }
        if (!port)
                FATAL("Remote interface, but not supported???\n");
        portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type, interface_out->is_earlyb == IS_YES);
        if (!port)
                FATAL("Remote interface, but not supported???\n");
        portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type, interface_out->is_earlyb == IS_YES);