Added bridgin support for GSM and SIP
[lcr.git] / interface.c
index a312e4e..60e058f 100644 (file)
@@ -325,11 +325,9 @@ static int inter_portname(struct interface *interface, char *filename, int line,
                        ifport = ifport->next;
        }
 
-       /* check for port already assigned, but not for shared gsm interface */
+       /* check for port already assigned, but not for shared loop interface */
        searchif = interface_newlist;
-#if defined WITH_GSM_BS || defined WITH_GSM_MS
-       if (!strcmp(value, gsm->conf.interface_lcr))
-#endif
+       if (!!strcmp(value, options.loopback_lcr))
        {
                while(searchif) {
                        ifport = searchif->ifport;
@@ -896,36 +894,19 @@ static int inter_gsm_bs(struct interface *interface, char *filename, int line, c
        SPRINT(interface_error, "Error in %s (line %d): GSM BS side not compiled in.\n", filename, line);
        return(-1);
 #else
-       struct interface_port *ifport;
        struct interface *searchif;
 
-       /* check gsm */
-       if (!gsm) {
-               SPRINT(interface_error, "Error in %s (line %d): GSM is not activated.\n", filename, line);
-               return(-1);
-       }
        searchif = interface_newlist;
        while(searchif) {
-               ifport = searchif->ifport;
-               while(ifport) {
-                       if (ifport->gsm_bs) {
-                               SPRINT(interface_error, "Error in %s (line %d): port '%s' already uses gsm BS side.\n", filename, line, ifport->portname);
-                               return(-1);
-                       }
-                       ifport = ifport->next;
+               if (searchif->gsm_bs) {
+                       SPRINT(interface_error, "Error in %s (line %d): interface '%s' already uses gsm BS side.\n", filename, line, searchif->name);
+                       return(-1);
                }
                searchif = searchif->next;
        }
 
-       /* set portname */
-       if (inter_portname(interface, filename, line, (char *)"portname", gsm->conf.interface_lcr))
-               return(-1);
-
        /* goto end of chain again to set gsmflag */
-       ifport = interface->ifport;
-       while(ifport->next)
-               ifport = ifport->next;
-       ifport->gsm_bs = 1;
+       interface->gsm_bs = 1;
 
        return(0);
 #endif
@@ -936,51 +917,23 @@ static int inter_gsm_ms(struct interface *interface, char *filename, int line, c
        SPRINT(interface_error, "Error in %s (line %d): GSM MS side not compiled in.\n", filename, line);
        return(-1);
 #else
-       struct interface_port *ifport, *searchifport;
        struct interface *searchif;
-       char *element;
-
-       /* check gsm */
-       if (!gsm) {
-               SPRINT(interface_error, "Error in %s (line %d): GSM is not activated.\n", filename, line);
-               return(-1);
-       }
-
-       /* set portname */
-       if (inter_portname(interface, filename, line, (char *)"portname", gsm->conf.interface_lcr))
-               return(-1);
 
-       /* goto end of chain again to set gsmflag and socket */
-       ifport = interface->ifport;
-       while(ifport->next)
-               ifport = ifport->next;
-       ifport->gsm_ms = 1;
+       interface->gsm_ms = 1;
 
        /* copy values */
-       element = strsep(&value, " ");
-       if (!element || !element[0]) {
+       if (!value || !value[0]) {
                SPRINT(interface_error, "Error in %s (line %d): Missing MS name and socket name.\n", filename, line);
                return(-1);
        }
-       SCPY(ifport->gsm_ms_name, element);
-       element = strsep(&value, " ");
-       if (!element || !element[0]) {
-               SPRINT(interface_error, "Error in %s (line %d): Missing socket name after MS name.\n", filename, line);
-               return(-1);
-       }
-       SCPY(ifport->gsm_ms_socket, element);
+       SCPY(interface->gsm_ms_name, value);
 
-       /* check if socket is used multiple times */
+       /* check if name is used multiple times */
        searchif = interface_newlist;
        while(searchif) {
-               searchifport = searchif->ifport;
-               while(searchifport) {
-                       if (searchifport != ifport 
-                        && !strcmp(searchifport->gsm_ms_socket, ifport->gsm_ms_socket)) {
-                               SPRINT(interface_error, "Error in %s (line %d): mobile '%s' already uses the given socket '%s', choose a different one.\n", filename, line, ifport->gsm_ms_name, searchifport->gsm_ms_socket);
-                               return(-1);
-                       }
-                       searchifport = searchifport->next;
+               if (!strcmp(searchif->gsm_ms_name, interface->gsm_ms_name)) {
+                       SPRINT(interface_error, "Error in %s (line %d): mobile '%s' already uses the given MS name '%s', choose a different one.\n", filename, line, interface->gsm_ms_name, searchif->gsm_ms_name);
+                       return(-1);
                }
                searchif = searchif->next;
        }
@@ -988,6 +941,38 @@ static int inter_gsm_ms(struct interface *interface, char *filename, int line, c
        return(0);
 #endif
 }
+static int inter_sip(struct interface *interface, char *filename, int line, char *parameter, char *value)
+{
+#ifndef WITH_SIP
+       SPRINT(interface_error, "Error in %s (line %d): SIP not compiled in.\n", filename, line);
+       return(-1);
+#else
+       char *p;
+
+       interface->sip = 1;
+
+       /* copy values */
+       if (!value || !value[0]) {
+               SPRINT(interface_error, "Error in %s (line %d): Missing SIP local IP.\n", filename, line);
+               return(-1);
+       }
+       p = get_seperated(value);
+       if (!p[0]) {
+               SPRINT(interface_error, "Error in %s (line %d): Missing SIP remote IP.\n", filename, line);
+               return(-1);
+       }
+       SCPY(interface->sip_local_ip, value);
+       SCPY(interface->sip_remote_ip, p);
+
+       return(0);
+#endif
+}
+static int inter_rtp_bridge(struct interface *interface, char *filename, int line, char *parameter, char *value)
+{
+       interface->rtp_bridge = 1;
+
+       return(0);
+}
 static int inter_nonotify(struct interface *interface, char *filename, int line, char *parameter, char *value)
 {
        struct interface_port *ifport;
@@ -1054,6 +1039,49 @@ static int inter_ss5(struct interface *interface, char *filename, int line, char
        return(0);
 }
 #endif
+static int inter_remote(struct interface *interface, char *filename, int line, char *parameter, char *value)
+{
+       struct interface_port *ifport;
+       struct interface *searchif;
+
+       if (!value[0]) {
+               SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects application name as value.\n", filename, line, parameter);
+               return(-1);
+       }
+       searchif = interface_newlist;
+       while(searchif) {
+               ifport = searchif->ifport;
+               while(ifport) {
+                       if (ifport->remote && !strcmp(ifport->remote_app, value)) {
+                               SPRINT(interface_error, "Error in %s (line %d): port '%s' already uses remote application '%s'.\n", filename, line, ifport->portname, value);
+                               return(-1);
+                       }
+                       ifport = ifport->next;
+               }
+               searchif = searchif->next;
+       }
+
+       /* set portname */
+       if (inter_portname(interface, filename, line, (char *)"portname", options.loopback_lcr))
+               return(-1);
+
+       /* goto end of chain again to set application name */
+       ifport = interface->ifport;
+       while(ifport->next)
+               ifport = ifport->next;
+       ifport->remote = 1;
+       SCPY(ifport->remote_app, value);
+
+
+       return(0);
+}
+
+static int inter_shutdown(struct interface *interface, char *filename, int line, char *parameter, char *value)
+{
+       interface->shutdown = 1;
+
+       return(0);
+}
 
 
 /*
@@ -1186,14 +1214,18 @@ struct interface_param interface_param[] = {
        {"gsm", &inter_gsm, "",
        ""},
        {"gsm-bs", &inter_gsm_bs, "",
-       "Sets up GSM base station interface for using OpenBSC.\n"
-       "See the default/gsm.conf for configuration for this version."},
-       {"gsm-ms", &inter_gsm_ms, "[<socket>]",
+       "Sets up GSM base station interface for using OpenBSC."},
+       {"gsm-ms", &inter_gsm_ms, "<socket>",
        "Sets up GSM mobile station interface for using Osmocom-BB.\n"
-       "See the default/gsm.conf for configuration for this version.\n"
        "The name of the MS folows the interface name.\n"
        "The socket is /tmp/osmocom_l2 by default and need to be changed when multiple\n"
        "MS interfaces are used."},
+       {"sip", &inter_sip, "<local IP> <remote IP>",
+       "Sets up SIP interface that represents one SIP endpoint.\n"
+       "Give SIP configuration file."},
+       {"rtp-bridge", &inter_rtp_bridge, "",
+       "Sets up SIP interface that represents one SIP endpoint.\n"
+       "Give SIP configuration file."},
        {"nonotify", &inter_nonotify, "",
        "Prevents sending notify messages to this interface. A call placed on hold will\n"
        "Not affect the remote end (phone or telcom switch).\n"
@@ -1215,6 +1247,13 @@ struct interface_param interface_param[] = {
        " suppress - Suppress received tones, as they will be recognized."},
 #endif
 
+       {"remote", &inter_remote, "<application>",
+       "Sets up an interface that communicates with the remote application.\n"
+       "Use \"asterisk\" to use chan_lcr as remote application."},
+
+       {"shutdown", &inter_shutdown, "",
+       "Interface will not be loaded when processing interface.conf"},
+
        {NULL, NULL, NULL, NULL}
 };
 
@@ -1464,8 +1503,61 @@ static void set_defaults(struct interface_port *ifport)
 void relink_interfaces(void)
 {
        struct mISDNport *mISDNport;
-       struct interface *interface;
+       struct interface *interface, *temp;
        struct interface_port *ifport;
+       int found;
+
+       interface = interface_first;
+       while(interface) {
+               found = 0;
+               temp = interface_newlist;
+               while(temp) {
+                       if (!strcmp(temp->name, interface->name))
+                               found = 1;
+                       temp = temp->next;
+               }
+               if (!found) {
+#ifdef WITH_GSM_MS
+                       if (interface->gsm_ms)
+                               gsm_ms_delete(interface->gsm_ms_name);
+#endif
+#ifdef WITH_GSM_BS
+                       if (interface->gsm_bs)
+                               gsm_bs_exit(0);
+#endif
+#ifdef WITH_SIP
+                       if (interface->sip)
+                               sip_exit_inst(interface);
+#endif
+               }
+               interface = interface->next;
+       }
+
+       interface = interface_newlist;
+       while(interface) {
+               found = 0;
+               temp = interface_first;
+               while(temp) {
+                       if (!strcmp(temp->name, interface->name))
+                               found = 1;
+                       temp = temp->next;
+               }
+               if (!found) {
+#ifdef WITH_GSM_MS
+                       if (interface->gsm_ms)
+                               gsm_ms_new(interface);
+#endif
+#ifdef WITH_GSM_BS
+                       if (interface->gsm_bs)
+                               gsm_bs_init(interface);
+#endif
+#ifdef WITH_SIP
+                       if (interface->sip)
+                               sip_init_inst(interface);
+#endif
+               }
+               interface = interface->next;
+       }
 
        /* unlink all mISDNports */
        mISDNport = mISDNport_first;
@@ -1502,11 +1594,7 @@ void relink_interfaces(void)
        while(mISDNport) {
                if (mISDNport->ifport == NULL) {
                        PDEBUG(DEBUG_ISDN, "Port %d is not used anymore and will be closed\n", mISDNport->portnum);
-                       /* remove all port objects and destroy port */
-#ifdef WITH_GSM_MS
-                       if (ifport->gsm_ms)
-                               gsm_ms_delete(ifport->gsm_ms_name);
-#endif
+                       /* destroy port */
                        mISDNport_close(mISDNport);
                        goto closeagain;
                }
@@ -1519,7 +1607,11 @@ void relink_interfaces(void)
                ifport = interface->ifport;
                while(ifport) {
                        if (!ifport->mISDNport) {
-                               load_port(ifport);
+                               if (!interface->shutdown) {
+                                       load_port(ifport);
+                               } else {
+                                       ifport->block = 2;
+                               }
                        }
                        ifport = ifport->next;
                }
@@ -1549,10 +1641,6 @@ void load_port(struct interface_port *ifport)
                set_defaults(ifport);
                /* load static port instances */
                mISDNport_static(mISDNport);
-#ifdef WITH_GSM_MS
-               if (ifport->gsm_ms)
-                       gsm_ms_new(ifport->gsm_ms_name, ifport->gsm_ms_socket);
-#endif
        } else {
                ifport->block = 2; /* not available */
        }
@@ -1590,12 +1678,21 @@ void doc_interface(void)
 /* screen caller id
  * out==0: incoming caller id, out==1: outgoing caller id
  */
-void do_screen(int out, char *id, int idsize, int *type, int *present, struct interface *interface)
+void do_screen(int out, char *id, int idsize, int *type, int *present, const char *interface_name)
 {
        char                    *msn1;
        struct interface_msn    *ifmsn;
        struct interface_screen *ifscreen;
        char suffix[64];
+       struct interface *interface = interface_first;
+
+       while (interface) {
+               if (!strcmp(interface->name, interface_name))
+                       break;
+               interface = interface->next;
+       }
+       if (!interface)
+               return;
 
        /* screen incoming caller id */
        if (!out) {