X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=blobdiff_plain;f=gsm_ms.cpp;h=481a4ac0b0d387796341cbbe3b4337ba85cbc812;hp=551fcad6b47a3f90542c21a9661b863ee1ae2351;hb=34598a346419f0e661526e6208dade4aff570008;hpb=d4097e35584a9490c778d93b7667930a834481e7 diff --git a/gsm_ms.cpp b/gsm_ms.cpp index 551fcad..481a4ac 100644 --- a/gsm_ms.cpp +++ b/gsm_ms.cpp @@ -16,24 +16,24 @@ #endif extern "C" { #include +#include #include #include +#include #include #include #include -#include +#include } -const char *openbsc_copyright = ""; +static const char *config_file = "/etc/osmocom/osmocom.cfg"; short vty_port = 4247; struct llist_head ms_list; struct log_target *stderr_target; void *l23_ctx = NULL; -int (*l23_app_work) (struct osmocom_ms *ms) = NULL; -int (*l23_app_exit) (struct osmocom_ms *ms) = NULL; static int dtmf_timeout(struct lcr_timer *timer, void *instance, int index); @@ -54,9 +54,6 @@ Pgsm_ms::Pgsm_ms(int type, struct mISDNport *mISDNport, char *portname, struct p } } - if (!p_m_g_instance) - FATAL("MS name %s does not exists. Please fix!"); - p_m_g_dtmf_state = DTMF_ST_IDLE; p_m_g_dtmf_index = 0; p_m_g_dtmf[0] = '\0'; @@ -391,7 +388,31 @@ static int message_ms(struct osmocom_ms *ms, int msg_type, void *arg) struct mISDNport *mISDNport; /* Special messages */ - if (msg_type) { + switch (msg_type) { + case MS_NEW: + PDEBUG(DEBUG_GSM, "MS %s comes available\n", ms->name); + return 0; + case MS_DELETE: + PDEBUG(DEBUG_GSM, "MS %s is removed\n", ms->name); + 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_m_g_instance == ms) { + struct lcr_msg *message; + + pgsm_ms->p_m_g_instance = 0; + message = message_create(pgsm_ms->p_serial, ACTIVE_EPOINT(pgsm_ms->p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE); + message->param.disconnectinfo.cause = 27; + message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL; + message_put(message); + pgsm_ms->new_state(PORT_STATE_RELEASE); + trigger_work(&pgsm_ms->p_m_g_delete); + } + } + port = port->next; + } + return 0; } /* find callref */ @@ -508,6 +529,20 @@ void Pgsm_ms::message_setup(unsigned int epoint_id, int message_id, union parame memcpy(&p_capainfo, ¶m->setup.capainfo, sizeof(p_capainfo)); memcpy(&p_redirinfo, ¶m->setup.redirinfo, sizeof(p_redirinfo)); + /* no instance */ + if (!p_m_g_instance) { + gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_REQ, DIRECTION_OUT); + add_trace("failure", NULL, "MS %s instance is unavailable", p_m_mISDNport->ifport->gsm_ms_name); + end_trace(); + message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE); + message->param.disconnectinfo.cause = 27; + message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL; + message_put(message); + new_state(PORT_STATE_RELEASE); + trigger_work(&p_m_g_delete); + return; + } + /* no number */ if (!p_dialinginfo.id[0]) { gsm_trace_header(p_m_mISDNport, this, MNCC_SETUP_REQ, DIRECTION_OUT); @@ -782,6 +817,7 @@ int Pgsm_ms::message_epoint(unsigned int epoint_id, int message_id, union parame int gsm_ms_exit(int rc) { + l23_app_exit(); return(rc); } @@ -796,50 +832,40 @@ int gsm_ms_init(void) l23_ctx = talloc_named_const(NULL, 1, "layer2 context"); - return 0; -} - -/* add a new GSM mobile instance */ -int gsm_ms_new(const char *name, const char *socket_path) -{ - struct osmocom_ms *ms = NULL; - int rc; - - PDEBUG(DEBUG_GSM, "GSM: creating new instance '%s' on '%s'\n", name, socket_path); + log_parse_category_mask(stderr_target, "DCS:DPLMN:DRR:DMM:DSIM:DCC:DMNCC:DPAG:DSUM"); + log_set_log_level(stderr_target, LOGL_INFO); - ms = talloc_zero(l23_ctx, struct osmocom_ms); - if (!ms) { - FATAL("Failed to allocate MS\n"); +#if 0 + if (gsmtap_ip) { + rc = gsmtap_init(gsmtap_ip); + if (rc < 0) { + fprintf(stderr, "Failed during gsmtap_init()\n"); + exit(1); + } } - /* must add here, because other init processes may search in the list */ - llist_add_tail(&ms->entity, &ms_list); - - - SPRINT(ms->name, name); +#endif - rc = layer2_open(ms, socket_path); - if (rc < 0) { - FATAL("Failed during layer2_open()\n"); - } + l23_app_init(message_ms, config_file, vty_port); - lapdm_init(&ms->l2_entity.lapdm_dcch, ms); - lapdm_init(&ms->l2_entity.lapdm_acch, ms); + return 0; +} - rc = l23_app_init(ms); - if (rc < 0) { - FATAL("Failed to init layer23\n"); - } - ms->mncc_entity.mncc_recv = message_ms; +/* add a new GSM mobile instance */ +int gsm_ms_new(const char *name) +{ + PDEBUG(DEBUG_GSM, "GSM: interface for MS '%s' is up\n", name); return 0; } int gsm_ms_delete(const char *name) { - struct osmocom_ms *ms = NULL; + struct osmocom_ms *ms; int found = 0; + class Port *port; + class Pgsm_ms *pgsm_ms = NULL; - PDEBUG(DEBUG_GSM, "GSM: destroying instance '%s'\n", name); + PDEBUG(DEBUG_GSM, "GSM: interface for MS '%s' is down\n", name); llist_for_each_entry(ms, &ms_list, entity) { if (!strcmp(ms->name, name)) { @@ -848,15 +874,29 @@ int gsm_ms_delete(const char *name) } } - if (!found) { - FATAL("Failed delete layer23, instance '%s' not found\n", name); - } - - l23_app_exit(ms); - lapdm_exit(&ms->l2_entity.lapdm_dcch); - lapdm_exit(&ms->l2_entity.lapdm_acch); + if (!found) + return 0; - llist_del(&ms->entity); + 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_m_g_instance == ms && pgsm_ms->p_m_g_callref) { + struct gsm_mncc *rej; + + rej = create_mncc(MNCC_REL_REQ, pgsm_ms->p_m_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(); + } + } + } return 0; } @@ -864,18 +904,17 @@ int gsm_ms_delete(const char *name) /* * handles bsc select function within LCR's main loop */ -int handle_gsm_ms(void) +int handle_gsm_ms(int *_quit) { - struct osmocom_ms *ms = NULL; - int work = 0; - - llist_for_each_entry(ms, &ms_list, entity) { - if (l23_app_work(ms)) - work = 1; -// debug_reset_context(); - if (bsc_select_main(1)) /* polling */ - work = 1; - } + int work = 0, quit = 0; + + if (l23_app_work(&quit)) + work = 1; + if (quit && llist_empty(&ms_list)) + *_quit = 1; +// debug_reset_context(); + if (bsc_select_main(1)) /* polling */ + work = 1; return work; }