GSM: Fixes to GSM interface (multiple networks)
authorAndreas Eversberg <jolly@eversberg.eu>
Sun, 4 Jun 2017 09:22:51 +0000 (11:22 +0200)
committerAndreas Eversberg <jolly@eversberg.eu>
Wed, 26 Jul 2017 06:39:44 +0000 (08:39 +0200)
* Multiple network instances are now possible to attach multiple networks
* Early audio handling fixed
* Number type can be given from base station (setup / setup confirm)
* Equal callref for different GSM-MS instances are handled correctly

default/interface.conf
gsm.cpp
gsm.h
gsm_bs.cpp
gsm_bs.h
gsm_ms.cpp
gsm_ms.h
interface.c
interface.h
main.c

index 19c7a34..1450ae3 100644 (file)
 
 
 # A special case for GSM Network interface.
 
 
 # A special case for GSM Network interface.
+# optionally give "gsm-bs <name of network instance>".
 # You may add 'extension' and 'msn' keywords to turn all your subscribers
 # in you GSM network to internal 'extensions'.
 # The MSN numbers will equal the subscriber number.
 # You may add 'extension' and 'msn' keywords to turn all your subscribers
 # in you GSM network to internal 'extensions'.
 # The MSN numbers will equal the subscriber number.
diff --git a/gsm.cpp b/gsm.cpp
index b9b88ee..8f9005b 100644 (file)
--- a/gsm.cpp
+++ b/gsm.cpp
@@ -667,7 +667,20 @@ void Pgsm::setup_cnf(unsigned int msg_type, unsigned int callref, struct gsm_mnc
        SCPY(p_connectinfo.imsi, mncc->imsi);
        p_connectinfo.present = INFO_PRESENT_ALLOWED;
        p_connectinfo.screen = INFO_SCREEN_NETWORK;
        SCPY(p_connectinfo.imsi, mncc->imsi);
        p_connectinfo.present = INFO_PRESENT_ALLOWED;
        p_connectinfo.screen = INFO_SCREEN_NETWORK;
-       p_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
+       switch (mncc->connected.type) {
+               case 0x1:
+               p_connectinfo.ntype = INFO_NTYPE_INTERNATIONAL;
+               break;
+               case 0x2:
+               p_connectinfo.ntype = INFO_NTYPE_NATIONAL;
+               break;
+               case 0x4:
+               p_connectinfo.ntype = INFO_NTYPE_SUBSCRIBER;
+               break;
+               default:
+               p_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
+               break;
+       }
        SCPY(p_connectinfo.interface, p_interface_name);
 
        gsm_trace_header(p_interface_name, this, msg_type, DIRECTION_IN);
        SCPY(p_connectinfo.interface, p_interface_name);
 
        gsm_trace_header(p_interface_name, this, msg_type, DIRECTION_IN);
@@ -1355,6 +1368,9 @@ static int mncc_fd_read(struct lcr_fd *lfd, void *inst, int idx)
        static char buf[sizeof(struct gsm_mncc)+1024];
        struct gsm_mncc *mncc_prim = (struct gsm_mncc *) buf;
        struct gsm_mncc_hello *hello = (struct gsm_mncc_hello *) buf;
        static char buf[sizeof(struct gsm_mncc)+1024];
        struct gsm_mncc *mncc_prim = (struct gsm_mncc *) buf;
        struct gsm_mncc_hello *hello = (struct gsm_mncc_hello *) buf;
+       class Port *port;
+       class Pgsm *pgsm = NULL;
+       unsigned int callref;
 
        memset(buf, 0, sizeof(buf));
        rc = recv(lfd->fd, buf, sizeof(buf), 0);
 
        memset(buf, 0, sizeof(buf));
        rc = recv(lfd->fd, buf, sizeof(buf), 0);
@@ -1402,15 +1418,31 @@ static int mncc_fd_read(struct lcr_fd *lfd, void *inst, int idx)
                break;
        }
 
                break;
        }
 
+       /* Find port object */
+       callref = mncc_prim->callref;
+       port = port_first;
+       while(port) {
+               if ((port->p_type & PORT_CLASS_MASK) == PORT_CLASS_GSM) {
+                       pgsm = (class Pgsm *)port;
+                       if (pgsm->p_g_lcr_gsm == lcr_gsm && pgsm->p_g_callref == callref)
+                               break;
+               }
+               port = port->next;
+       }
+
        /* Hand the MNCC message into LCR */
        switch (lcr_gsm->type) {
 #ifdef WITH_GSM_BS
        case LCR_GSM_TYPE_NETWORK:
        /* Hand the MNCC message into LCR */
        switch (lcr_gsm->type) {
 #ifdef WITH_GSM_BS
        case LCR_GSM_TYPE_NETWORK:
-               return message_bsc(lcr_gsm, mncc_prim->msg_type, mncc_prim);
+               if (port && (port->p_type & PORT_CLASS_GSM_MASK) != PORT_CLASS_GSM_BS)
+                       FATAL("Port is set and bound to network socket, but is not of network type, please fix");
+               return message_bsc((class Pgsm_bs *)port, lcr_gsm, mncc_prim->msg_type, mncc_prim);
 #endif
 #ifdef WITH_GSM_MS
        case LCR_GSM_TYPE_MS:
 #endif
 #ifdef WITH_GSM_MS
        case LCR_GSM_TYPE_MS:
-               return message_ms(lcr_gsm, mncc_prim->msg_type, mncc_prim);
+               if (port && (port->p_type & PORT_CLASS_GSM_MASK) != PORT_CLASS_GSM_MS)
+                       FATAL("Port is set and bound to mobile socket, but is not of mobile type, please fix");
+               return message_ms((class Pgsm_ms *)port, lcr_gsm, mncc_prim->msg_type, mncc_prim);
 #endif
        default:
                return 0;
 #endif
        default:
                return 0;
diff --git a/gsm.h b/gsm.h
index b0b9b89..f14794f 100644 (file)
--- a/gsm.h
+++ b/gsm.h
@@ -16,8 +16,8 @@ enum {
 
 struct lcr_gsm {
        char interface_name[64]; /* name of interface this instance is associated to */
 
 struct lcr_gsm {
        char interface_name[64]; /* name of interface this instance is associated to */
-       struct lcr_gsm  *gsm_ms_next;   /* list of MS instances, in case of MS */
-       char            name[16];       /* name of MS instance, in case of MS */
+       struct lcr_gsm  *gsm_next;      /* list of MS/BS instances */
+       char            name[16];       /* name of MS/BS instance */
        int             type;           /* LCR_GSM_TYPE_*/
 
        struct lcr_fd   mncc_lfd;       /* Unix domain socket to OpenBSC MNCC */
        int             type;           /* LCR_GSM_TYPE_*/
 
        struct lcr_fd   mncc_lfd;       /* Unix domain socket to OpenBSC MNCC */
index 6d1a122..81a0672 100644 (file)
@@ -12,7 +12,7 @@
 #include "main.h"
 #include "mncc.h"
 
 #include "main.h"
 #include "mncc.h"
 
-struct lcr_gsm *gsm_bs = NULL;
+struct lcr_gsm *gsm_bs_first = NULL;
 
 #define PAYLOAD_TYPE_GSM 3
 
 
 #define PAYLOAD_TYPE_GSM 3
 
@@ -49,11 +49,23 @@ void generate_dtmf(void)
  */
 Pgsm_bs::Pgsm_bs(int type, char *portname, struct port_settings *settings, struct interface *interface) : Pgsm(type, portname, settings, interface)
 {
  */
 Pgsm_bs::Pgsm_bs(int type, char *portname, struct port_settings *settings, struct interface *interface) : Pgsm(type, portname, settings, interface)
 {
-       p_g_lcr_gsm = gsm_bs;
+       struct lcr_gsm *gsm_bs = gsm_bs_first;
+
+       p_g_lcr_gsm = NULL;
+       SCPY(p_g_bs_name, interface->gsm_bs_name);
+
+       while (gsm_bs) {
+               if (gsm_bs->type == LCR_GSM_TYPE_NETWORK && !strcmp(gsm_bs->name, p_g_bs_name)) {
+                       p_g_lcr_gsm = gsm_bs;
+                       break;
+               }
+               gsm_bs = gsm_bs->gsm_next;
+       }
+
        p_g_dtmf = NULL;
        p_g_dtmf_index = 0;
 
        p_g_dtmf = NULL;
        p_g_dtmf_index = 0;
 
-       PDEBUG(DEBUG_GSM, "Created new GSMBSPort(%s).\n", portname);
+       PDEBUG(DEBUG_GSM, "Created new GSMBSPort(%s %s).\n", portname, p_g_bs_name);
 }
 
 /*
 }
 
 /*
@@ -181,6 +193,15 @@ void Pgsm_bs::call_conf_ind(unsigned int msg_type, unsigned int callref, struct
                modify_lchan(media_types[0]);
                p_g_payload_type = payload_types[0];
        }
                modify_lchan(media_types[0]);
                p_g_payload_type = payload_types[0];
        }
+
+       if (p_g_earlyb && !p_g_tch_connected) { /* only if ... */
+               struct gsm_mncc *frame;
+               gsm_trace_header(p_interface_name, this, MNCC_FRAME_RECV, DIRECTION_OUT);
+               end_trace();
+               frame = create_mncc(MNCC_FRAME_RECV, p_g_callref);
+               send_and_free_mncc(p_g_lcr_gsm, frame->msg_type, frame);
+               p_g_tch_connected = 1;
+       }
 }
 
 /* DTMF INDICATION */
 }
 
 /* DTMF INDICATION */
@@ -507,7 +528,20 @@ reject:
                p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
        SCPY(p_callerinfo.imsi, mncc->imsi);
        p_callerinfo.screen = INFO_SCREEN_NETWORK;
                p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
        SCPY(p_callerinfo.imsi, mncc->imsi);
        p_callerinfo.screen = INFO_SCREEN_NETWORK;
-       p_callerinfo.ntype = INFO_NTYPE_UNKNOWN;
+       switch (mncc->calling.type) {
+               case 0x1:
+               p_callerinfo.ntype = INFO_NTYPE_INTERNATIONAL;
+               break;
+               case 0x2:
+               p_callerinfo.ntype = INFO_NTYPE_NATIONAL;
+               break;
+               case 0x4:
+               p_callerinfo.ntype = INFO_NTYPE_SUBSCRIBER;
+               break;
+               default:
+               p_callerinfo.ntype = INFO_NTYPE_UNKNOWN;
+               break;
+       }
        SCPY(p_callerinfo.interface, p_interface_name);
 
        /* dialing information */
        SCPY(p_callerinfo.interface, p_interface_name);
 
        /* dialing information */
@@ -660,39 +694,23 @@ reject:
 /*
  * BSC sends message to port
  */
 /*
  * BSC sends message to port
  */
-int message_bsc(struct lcr_gsm *lcr_gsm, int msg_type, void *arg)
+int message_bsc(class Pgsm_bs *pgsm_bs, struct lcr_gsm *lcr_gsm, int msg_type, void *arg)
 {
        struct gsm_mncc *mncc = (struct gsm_mncc *)arg;
        unsigned int callref = mncc->callref;
 {
        struct gsm_mncc *mncc = (struct gsm_mncc *)arg;
        unsigned int callref = mncc->callref;
-       class Port *port;
-       class Pgsm_bs *pgsm_bs = NULL;
        char name[64];
        char name[64];
-//     struct mISDNport *mISDNport;
 
        /* Special messages */
        switch(msg_type) {
        }
 
 
        /* Special messages */
        switch(msg_type) {
        }
 
-       /* find callref */
-       callref = mncc->callref;
-       port = port_first;
-       while(port) {
-               if ((port->p_type & PORT_CLASS_GSM_MASK) == PORT_CLASS_GSM_BS) {
-                       pgsm_bs = (class Pgsm_bs *)port;
-                       if (pgsm_bs->p_g_callref == callref) {
-                               break;
-                       }
-               }
-               port = port->next;
-       }
-
        if (msg_type == GSM_TCHF_FRAME
         || msg_type == GSM_TCHF_FRAME_EFR
         || msg_type == GSM_TCHH_FRAME
         || msg_type == GSM_TCH_FRAME_AMR
         || msg_type == ANALOG_8000HZ
         || msg_type == GSM_BAD_FRAME) {
        if (msg_type == GSM_TCHF_FRAME
         || msg_type == GSM_TCHF_FRAME_EFR
         || msg_type == GSM_TCHH_FRAME
         || msg_type == GSM_TCH_FRAME_AMR
         || msg_type == ANALOG_8000HZ
         || msg_type == GSM_BAD_FRAME) {
-               if (port) {
+               if (pgsm_bs) {
                        /* inject DTMF, if enabled */
                        if (pgsm_bs->p_g_dtmf) {
                                unsigned char data[160];
                        /* inject DTMF, if enabled */
                        if (pgsm_bs->p_g_dtmf) {
                                unsigned char data[160];
@@ -720,7 +738,7 @@ int message_bsc(struct lcr_gsm *lcr_gsm, int msg_type, void *arg)
                return 0;
        }
 
                return 0;
        }
 
-       if (!port) {
+       if (!pgsm_bs) {
                struct interface *interface;
 
                if (msg_type != MNCC_SETUP_IND)
                struct interface *interface;
 
                if (msg_type != MNCC_SETUP_IND)
@@ -1080,31 +1098,41 @@ int Pgsm_bs::message_epoint(unsigned int epoint_id, int message_id, union parame
 
 int gsm_bs_exit(int rc)
 {
 
 int gsm_bs_exit(int rc)
 {
-       /* free gsm instance */
-       if (gsm_bs) {
-               if (gsm_bs->mncc_lfd.fd > -1) {
-                       close(gsm_bs->mncc_lfd.fd);
-                       unregister_fd(&gsm_bs->mncc_lfd);
-               }
-
-               del_timer(&gsm_bs->socket_retry);
-               free(gsm_bs);
-               gsm_bs = NULL;
-       }
+       /* destroy all instances */
+       while (gsm_bs_first)
+               gsm_bs_delete(gsm_bs_first->name);
 
 
+       return rc;
+}
 
 
-       return(rc);
+int gsm_bs_init(void)
+{
+       return 0;
 }
 
 }
 
-int gsm_bs_init(struct interface *interface)
+/* add a new GSM base station instance */
+int gsm_bs_new(struct interface *interface)
 {
 {
+       struct lcr_gsm *gsm_bs = gsm_bs_first, **gsm_bs_p = &gsm_bs_first;
+
+       while (gsm_bs) {
+               gsm_bs_p = &gsm_bs->gsm_next;
+               gsm_bs = gsm_bs->gsm_next;
+       }
+
+       PDEBUG(DEBUG_GSM, "GSM: interface for BS '%s' is created\n", interface->gsm_bs_name);
+
        /* create gsm instance */
        gsm_bs = (struct lcr_gsm *)MALLOC(sizeof(struct lcr_gsm));
 
        SCPY(gsm_bs->interface_name, interface->name);
        gsm_bs->type = LCR_GSM_TYPE_NETWORK;
        /* create gsm instance */
        gsm_bs = (struct lcr_gsm *)MALLOC(sizeof(struct lcr_gsm));
 
        SCPY(gsm_bs->interface_name, interface->name);
        gsm_bs->type = LCR_GSM_TYPE_NETWORK;
+       SCPY(gsm_bs->name, interface->gsm_bs_name);
        gsm_bs->sun.sun_family = AF_UNIX;
        gsm_bs->sun.sun_family = AF_UNIX;
-       SCPY(gsm_bs->sun.sun_path, "/tmp/bsc_mncc");
+       if (gsm_bs->name[0])
+               SPRINT(gsm_bs->sun.sun_path, "/tmp/bsc_mncc_%s", gsm_bs->name);
+       else
+               SCPY(gsm_bs->sun.sun_path, "/tmp/bsc_mncc");
 
        memset(&gsm_bs->socket_retry, 0, sizeof(gsm_bs->socket_retry));
        add_timer(&gsm_bs->socket_retry, mncc_socket_retry_cb, gsm_bs, 0);
 
        memset(&gsm_bs->socket_retry, 0, sizeof(gsm_bs->socket_retry));
        add_timer(&gsm_bs->socket_retry, mncc_socket_retry_cb, gsm_bs, 0);
@@ -1114,5 +1142,37 @@ int gsm_bs_init(struct interface *interface)
 
        generate_dtmf();
 
 
        generate_dtmf();
 
+       *gsm_bs_p = gsm_bs;
+
        return 0;
 }
        return 0;
 }
+
+int gsm_bs_delete(const char *name)
+{
+       struct lcr_gsm *gsm_bs = gsm_bs_first, **gsm_bs_p = &gsm_bs_first;
+
+       PDEBUG(DEBUG_GSM, "GSM: interface for BS '%s' is deleted\n", name);
+       
+       while (gsm_bs) {
+               if (gsm_bs->type == LCR_GSM_TYPE_NETWORK && !strcmp(gsm_bs->name, name))
+                       break;
+               gsm_bs_p = &gsm_bs->gsm_next;
+               gsm_bs = gsm_bs->gsm_next;
+       }
+
+       if (!gsm_bs)
+               return 0;
+       
+       if (gsm_bs->mncc_lfd.fd > -1) {
+               close(gsm_bs->mncc_lfd.fd);
+               unregister_fd(&gsm_bs->mncc_lfd);
+       }
+       del_timer(&gsm_bs->socket_retry);
+
+       /* remove instance from list */
+       *gsm_bs_p = gsm_bs->gsm_next;
+       FREE(gsm_bs, sizeof(struct lcr_gsm));
+
+       return 0;
+}
+
index 5575daa..afb0415 100644 (file)
--- a/gsm_bs.h
+++ b/gsm_bs.h
@@ -6,6 +6,7 @@ class Pgsm_bs : public Pgsm
        Pgsm_bs(int type, char *portname, struct port_settings *settings, struct interface *interface);
        ~Pgsm_bs();
 
        Pgsm_bs(int type, char *portname, struct port_settings *settings, struct interface *interface);
        ~Pgsm_bs();
 
+       char p_g_bs_name[32];
        unsigned char *p_g_dtmf; /* DTMF tone generation (MS only) */
        int p_g_dtmf_index; /* DTMF tone generation index */
 
        unsigned char *p_g_dtmf; /* DTMF tone generation (MS only) */
        int p_g_dtmf_index; /* DTMF tone generation index */
 
@@ -22,6 +23,8 @@ class Pgsm_bs : public Pgsm
 
 int gsm_bs_conf(struct gsm_conf *gsm_conf, char *conf_error);
 int gsm_bs_exit(int rc);
 
 int gsm_bs_conf(struct gsm_conf *gsm_conf, char *conf_error);
 int gsm_bs_exit(int rc);
-int gsm_bs_init(struct interface *interface);
+int gsm_bs_init(void);
+int gsm_bs_new(struct interface *interface);
+int gsm_bs_delete(const char *name);
 
 
-int message_bsc(struct lcr_gsm *lcr_gsm, int msg_type, void *arg);
+int message_bsc(class Pgsm_bs *pgsm_bs, struct lcr_gsm *lcr_gsm, int msg_type, void *arg);
index 6ef0a82..4d42ee7 100644 (file)
@@ -40,7 +40,7 @@ Pgsm_ms::Pgsm_ms(int type, char *portname, struct port_settings *settings, struc
                        p_g_lcr_gsm = gsm_ms;
                        break;
                }
                        p_g_lcr_gsm = gsm_ms;
                        break;
                }
-               gsm_ms = gsm_ms->gsm_ms_next;
+               gsm_ms = gsm_ms->gsm_next;
        }
 
        p_g_dtmf_state = DTMF_ST_IDLE;
        }
 
        p_g_dtmf_state = DTMF_ST_IDLE;
@@ -332,40 +332,24 @@ reject:
 /*
  * MS sends message to port
  */
 /*
  * MS sends message to port
  */
-int message_ms(struct lcr_gsm *gsm_ms, int msg_type, void *arg)
+int message_ms(class Pgsm_ms *pgsm_ms, struct lcr_gsm *gsm_ms, int msg_type, void *arg)
 {
        struct gsm_mncc *mncc = (struct gsm_mncc *)arg;
        unsigned int callref = mncc->callref;
 {
        struct gsm_mncc *mncc = (struct gsm_mncc *)arg;
        unsigned int callref = mncc->callref;
-       class Port *port;
-       class Pgsm_ms *pgsm_ms = NULL;
        char name[64];
        char name[64];
-//     struct mISDNport *mISDNport;
 
        /* Special messages */
        switch (msg_type) {
        }
 
 
        /* Special messages */
        switch (msg_type) {
        }
 
-       /* find callref */
-       callref = mncc->callref;
-       port = port_first;
-       while(port) {
-               if ((port->p_type & PORT_CLASS_GSM_MASK) == PORT_CLASS_GSM_MS) {
-                       pgsm_ms = (class Pgsm_ms *)port;
-                       if (pgsm_ms->p_g_callref == callref) {
-                               break;
-                       }
-               }
-               port = port->next;
-       }
-
        if (msg_type == GSM_TCHF_FRAME
         || msg_type == GSM_BAD_FRAME) {
        if (msg_type == GSM_TCHF_FRAME
         || msg_type == GSM_BAD_FRAME) {
-               if (port)
+               if (pgsm_ms)
                        pgsm_ms->frame_receive(arg);
                return 0;
        }
 
                        pgsm_ms->frame_receive(arg);
                return 0;
        }
 
-       if (!port) {
+       if (!pgsm_ms) {
                struct interface *interface;
 
                if (msg_type != MNCC_SETUP_IND)
                struct interface *interface;
 
                if (msg_type != MNCC_SETUP_IND)
@@ -726,8 +710,8 @@ int gsm_ms_new(struct interface *interface)
        struct lcr_gsm *gsm_ms = gsm_ms_first, **gsm_ms_p = &gsm_ms_first;
 
        while (gsm_ms) {
        struct lcr_gsm *gsm_ms = gsm_ms_first, **gsm_ms_p = &gsm_ms_first;
 
        while (gsm_ms) {
-               gsm_ms_p = &gsm_ms->gsm_ms_next;
-               gsm_ms = gsm_ms->gsm_ms_next;
+               gsm_ms_p = &gsm_ms->gsm_next;
+               gsm_ms = gsm_ms->gsm_next;
        }
 
        PDEBUG(DEBUG_GSM, "GSM: interface for MS '%s' is created\n", interface->gsm_ms_name);
        }
 
        PDEBUG(DEBUG_GSM, "GSM: interface for MS '%s' is created\n", interface->gsm_ms_name);
@@ -755,51 +739,19 @@ int gsm_ms_new(struct interface *interface)
 int gsm_ms_delete(const char *name)
 {
        struct lcr_gsm *gsm_ms = gsm_ms_first, **gsm_ms_p = &gsm_ms_first;
 int gsm_ms_delete(const char *name)
 {
        struct lcr_gsm *gsm_ms = gsm_ms_first, **gsm_ms_p = &gsm_ms_first;
-//     class Port *port;
-//     class Pgsm_ms *pgsm_ms = NULL;
 
        PDEBUG(DEBUG_GSM, "GSM: interface for MS '%s' is deleted\n", name);
 
        while (gsm_ms) {
                if (gsm_ms->type == LCR_GSM_TYPE_MS && !strcmp(gsm_ms->name, name))
                        break;
 
        PDEBUG(DEBUG_GSM, "GSM: interface for MS '%s' is deleted\n", name);
 
        while (gsm_ms) {
                if (gsm_ms->type == LCR_GSM_TYPE_MS && !strcmp(gsm_ms->name, name))
                        break;
-               gsm_ms_p = &gsm_ms->gsm_ms_next;
-               gsm_ms = gsm_ms->gsm_ms_next;
+               gsm_ms_p = &gsm_ms->gsm_next;
+               gsm_ms = gsm_ms->gsm_next;
        }
 
        if (!gsm_ms)
                return 0;
 
        }
 
        if (!gsm_ms)
                return 0;
 
-/* not needed, because:
- * - shutdown of interface will destry port instances locally
- * - closing of socket will make remote socket destroy calls locally
- */
-#if 0
-       port = port_first;
-       while(port) {
-               if ((port->p_type & PORT_CLASS_GSM_MASK) == PORT_CLASS_GSM_MS) {
-                       pgsm_ms = (class Pgsm_ms *)port;
-                       if (pgsm_ms->p_g_lcr_gsm == gsm_ms && pgsm_ms->p_g_callref) {
-                               struct gsm_mncc *rej;
-
-                               rej = create_mncc(MNCC_REL_REQ, pgsm_ms->p_g_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(gsm_ms, rej->msg_type, rej);
-                               pgsm_ms->new_state(PORT_STATE_RELEASE);
-                               trigger_work(&pgsm_ms->p_g_delete);
-                       }
-               }
-       }
-#endif
-
        if (gsm_ms->mncc_lfd.fd > -1) {
                close(gsm_ms->mncc_lfd.fd);
                unregister_fd(&gsm_ms->mncc_lfd);
        if (gsm_ms->mncc_lfd.fd > -1) {
                close(gsm_ms->mncc_lfd.fd);
                unregister_fd(&gsm_ms->mncc_lfd);
@@ -807,7 +759,7 @@ int gsm_ms_delete(const char *name)
        del_timer(&gsm_ms->socket_retry);
 
        /* remove instance from list */
        del_timer(&gsm_ms->socket_retry);
 
        /* remove instance from list */
-       *gsm_ms_p = gsm_ms->gsm_ms_next;
+       *gsm_ms_p = gsm_ms->gsm_next;
        FREE(gsm_ms, sizeof(struct lcr_gsm));
 
        return 0;
        FREE(gsm_ms, sizeof(struct lcr_gsm));
 
        return 0;
index 82202f5..aeff505 100644 (file)
--- a/gsm_ms.h
+++ b/gsm_ms.h
@@ -25,5 +25,5 @@ int gsm_ms_exit(int rc);
 int gsm_ms_init(void);
 int gsm_ms_new(struct interface *interface);
 int gsm_ms_delete(const char *name);
 int gsm_ms_init(void);
 int gsm_ms_new(struct interface *interface);
 int gsm_ms_delete(const char *name);
-int message_ms(struct lcr_gsm *lcr_gsm, int msg_type, void *arg);
+int message_ms(class Pgsm_ms *pgsm_ms, struct lcr_gsm *lcr_gsm, int msg_type, void *arg);
 
 
index 292c9aa..7619294 100644 (file)
@@ -907,18 +907,23 @@ static int inter_gsm_bs(struct interface *interface, char *filename, int line, c
 #else
        struct interface *searchif;
 
 #else
        struct interface *searchif;
 
+       interface->gsm_bs = 1;
+
+       if (!value)
+               interface->gsm_bs_name[0] = '\0';
+       else
+               SCPY(interface->gsm_bs_name, value);
+
+       /* check if name is used multiple times */
        searchif = interface_newlist;
        while(searchif) {
        searchif = interface_newlist;
        while(searchif) {
-               if (searchif->gsm_bs) {
-                       SPRINT(interface_error, "Error in %s (line %d): interface '%s' already uses gsm BS side.\n", filename, line, searchif->name);
+               if (searchif != interface && searchif->gsm_bs && !strcmp(searchif->gsm_bs_name, interface->gsm_bs_name)) {
+                       SPRINT(interface_error, "Error in %s (line %d): network '%s' already uses the given MS name '%s', choose a different one.\n", filename, line, interface->gsm_bs_name, searchif->gsm_bs_name);
                        return(-1);
                }
                searchif = searchif->next;
        }
 
                        return(-1);
                }
                searchif = searchif->next;
        }
 
-       /* goto end of chain again to set gsmflag */
-       interface->gsm_bs = 1;
-
        return(0);
 #endif
 }
        return(0);
 #endif
 }
@@ -953,7 +958,7 @@ static int inter_gsm_ms(struct interface *interface, char *filename, int line, c
        /* check if name is used multiple times */
        searchif = interface_newlist;
        while(searchif) {
        /* check if name is used multiple times */
        searchif = interface_newlist;
        while(searchif) {
-               if (searchif != interface && !strcmp(searchif->gsm_ms_name, interface->gsm_ms_name)) {
+               if (searchif != interface && searchif->gsm_bs && !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);
                }
                        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);
                }
@@ -1352,15 +1357,15 @@ struct interface_param interface_param[] = {
 
        {"gsm", &inter_gsm, "",
        ""},
 
        {"gsm", &inter_gsm, "",
        ""},
-       {"gsm-bs", &inter_gsm_bs, "",
-       "Sets up GSM base station interface for using OpenBSC."},
+       {"gsm-bs", &inter_gsm_bs, "[<socket name>]",
+       "Sets up GSM base station interface for using OpenBSC.\n"
+       "The socket is /tmp/bsc_mncc by default. If socket name is given, the socket will be\n"
+       "extended to /tmp/bsc_mncc_<socket name>."},
        {"hr", &inter_gsm_bs_hr, "",
        "Enable and prefer half rate for mobile terminating calls."},
        {"hr", &inter_gsm_bs_hr, "",
        "Enable and prefer half rate for mobile terminating calls."},
-       {"gsm-ms", &inter_gsm_ms, "<socket>",
+       {"gsm-ms", &inter_gsm_ms, "<socket name>",
        "Sets up GSM mobile station interface for using Osmocom-BB.\n"
        "Sets up GSM mobile station interface for using Osmocom-BB.\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."},
+       "The socket will be /tmp/ms_mncc_<socket name>."},
        {"sip", &inter_sip, "<local IP> <remote IP>",
        "Sets up SIP interface that represents one SIP endpoint.\n"
        "Give SIP configuration file."},
        {"sip", &inter_sip, "<local IP> <remote IP>",
        "Sets up SIP interface that represents one SIP endpoint.\n"
        "Give SIP configuration file."},
@@ -1697,7 +1702,7 @@ void relink_interfaces(void)
 #endif
 #ifdef WITH_GSM_BS
                        if (interface->gsm_bs)
 #endif
 #ifdef WITH_GSM_BS
                        if (interface->gsm_bs)
-                               gsm_bs_exit(0);
+                               gsm_bs_delete(interface->gsm_bs_name);
 #endif
 #ifdef WITH_SIP
                        if (interface->sip)
 #endif
 #ifdef WITH_SIP
                        if (interface->sip)
@@ -1732,7 +1737,7 @@ void relink_interfaces(void)
 #endif
 #ifdef WITH_GSM_BS
                        if (interface->gsm_bs)
 #endif
 #ifdef WITH_GSM_BS
                        if (interface->gsm_bs)
-                               gsm_bs_init(interface);
+                               gsm_bs_new(interface);
 #endif
 #ifdef WITH_SIP
                        if (interface->sip)
 #endif
 #ifdef WITH_SIP
                        if (interface->sip)
index a4b4baa..4b624f3 100644 (file)
@@ -113,6 +113,7 @@ struct interface {
        char                    remote_context[128]; /* context feld to use for remote application */
 #ifdef WITH_GSM_BS
        int                     gsm_bs; /* interface is an GSM BS interface */
        char                    remote_context[128]; /* context feld to use for remote application */
 #ifdef WITH_GSM_BS
        int                     gsm_bs; /* interface is an GSM BS interface */
+       char                    gsm_bs_name[32]; /* name of bs */
        int                     gsm_bs_hr; /* prefer half rate for MOT calls */
 #if 0
        int                     gsm_bs_payloads;
        int                     gsm_bs_hr; /* prefer half rate for MOT calls */
 #if 0
        int                     gsm_bs_payloads;
diff --git a/main.c b/main.c
index 1e85e39..b1f3ee7 100644 (file)
--- a/main.c
+++ b/main.c
@@ -397,15 +397,12 @@ int main(int argc, char *argv[])
                goto free;
        }
 #endif
                goto free;
        }
 #endif
-#if 0
-init is done when interface is up
 #ifdef WITH_GSM_BS
        if (gsm_bs_init()) {
                fprintf(stderr, "GSM BS initialization failed.\n");
                goto free;
        }
 #endif
 #ifdef WITH_GSM_BS
        if (gsm_bs_init()) {
                fprintf(stderr, "GSM BS initialization failed.\n");
                goto free;
        }
 #endif
-#endif
 #ifdef WITH_GSM_MS
        if (gsm_ms_init()) {
                fprintf(stderr, "GSM MS initialization failed.\n");
 #ifdef WITH_GSM_MS
        if (gsm_ms_init()) {
                fprintf(stderr, "GSM MS initialization failed.\n");
@@ -618,12 +615,9 @@ free:
 #endif
 
        /* free gsm */
 #endif
 
        /* free gsm */
-#if 0
-exit is done when interface is down
 #ifdef WITH_GSM_BS
        gsm_bs_exit(0);
 #endif
 #ifdef WITH_GSM_BS
        gsm_bs_exit(0);
 #endif
-#endif
 #ifdef WITH_GSM_MS
        gsm_ms_exit(0);
 #endif
 #ifdef WITH_GSM_MS
        gsm_ms_exit(0);
 #endif