[mobile] Using socket application interface with mobile application
Use "-m" with mobile app, to use it in conjunction with LCR or other applications.
This commit is contained in:
parent
5c8b76e74e
commit
c9927c72ea
|
@ -18,6 +18,7 @@ struct osmocom_ms;
|
|||
#include <osmocom/bb/mobile/gsm322.h>
|
||||
#include <osmocom/bb/mobile/gsm48_mm.h>
|
||||
#include <osmocom/bb/mobile/gsm48_cc.h>
|
||||
#include <osmocom/bb/mobile/mncc_sock.h>
|
||||
#include <osmocom/bb/common/sim.h>
|
||||
#include <osmocom/bb/common/l1ctl.h>
|
||||
|
||||
|
@ -31,6 +32,7 @@ struct osmol1_entity {
|
|||
|
||||
struct osmomncc_entity {
|
||||
int (*mncc_recv)(struct osmocom_ms *ms, int msg_type, void *arg);
|
||||
struct mncc_sock_state *sock_state;
|
||||
uint32_t ref;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
noinst_HEADERS = gsm322.h gsm48_cc.h gsm48_mm.h gsm48_rr.h mncc.h settings.h \
|
||||
subscriber.h support.h transaction.h vty.h
|
||||
subscriber.h support.h transaction.h vty.h mncc_sock.h
|
||||
|
|
|
@ -11,7 +11,8 @@ int gsm48_cc_init(struct osmocom_ms *ms);
|
|||
int gsm48_cc_exit(struct osmocom_ms *ms);
|
||||
int gsm48_rcv_cc(struct osmocom_ms *ms, struct msgb *msg);
|
||||
int mncc_dequeue(struct osmocom_ms *ms);
|
||||
int mncc_send(struct osmocom_ms *ms, int msg_type, void *arg);
|
||||
int mncc_tx_to_cc(void *inst, int msg_type, void *arg);
|
||||
int mncc_clear_trans(void *inst, uint8_t protocol);
|
||||
|
||||
#endif /* _GSM48_CC_H */
|
||||
|
||||
|
|
|
@ -109,9 +109,6 @@ struct gsm_call {
|
|||
#define GSM_TCHF_FRAME 0x0300
|
||||
#define GSM_TCHF_FRAME_EFR 0x0301
|
||||
|
||||
#define MS_NEW 0x0400
|
||||
#define MS_DELETE 0x0401
|
||||
|
||||
#define GSM_MAX_FACILITY 128
|
||||
#define GSM_MAX_SSVERSION 128
|
||||
#define GSM_MAX_USERUSER 128
|
||||
|
|
|
@ -5,7 +5,7 @@ LDADD = ../common/liblayer23.a $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOG
|
|||
noinst_LIBRARIES = libmobile.a
|
||||
libmobile_a_SOURCES = gsm322.c gsm48_cc.c gsm48_mm.c gsm48_rr.c \
|
||||
mnccms.c settings.c subscriber.c support.c \
|
||||
transaction.c vty_interface.c voice.c
|
||||
transaction.c vty_interface.c voice.c mncc_sock.c
|
||||
|
||||
bin_PROGRAMS = mobile
|
||||
|
||||
|
|
|
@ -233,16 +233,13 @@ struct osmocom_ms *mobile_new(char *name)
|
|||
ms->shutdown = 2; /* being down */
|
||||
|
||||
if (mncc_recv_app) {
|
||||
struct msgb *msg;
|
||||
char name[32];
|
||||
|
||||
msg = msgb_alloc(sizeof(struct gsm_mncc), "MNCC");
|
||||
if (msg) {
|
||||
struct gsm_mncc *mncc = (struct gsm_mncc *)msg->data;
|
||||
sprintf(name, "/tmp/ms_mncc_%s", ms->name);
|
||||
|
||||
mncc->msg_type = MS_NEW;
|
||||
mncc_recv_app(ms, mncc->msg_type, mncc);
|
||||
}
|
||||
ms->mncc_entity.mncc_recv = mncc_recv_app;
|
||||
ms->mncc_entity.sock_state = mncc_sock_init(ms, name, l23_ctx);
|
||||
|
||||
} else if (ms->settings.ch_cap == GSM_CAP_SDCCH)
|
||||
ms->mncc_entity.mncc_recv = mncc_recv_dummy;
|
||||
else
|
||||
|
@ -266,15 +263,8 @@ int mobile_delete(struct osmocom_ms *ms, int force)
|
|||
}
|
||||
|
||||
if (mncc_recv_app) {
|
||||
struct msgb *msg;
|
||||
|
||||
msg = msgb_alloc(sizeof(struct gsm_mncc), "MNCC");
|
||||
if (msg) {
|
||||
struct gsm_mncc *mncc = (struct gsm_mncc *)msg->data;
|
||||
|
||||
mncc->msg_type = MS_DELETE;
|
||||
mncc_recv_app(ms, mncc->msg_type, mncc);
|
||||
}
|
||||
mncc_sock_exit(ms->mncc_entity.sock_state);
|
||||
ms->mncc_entity.sock_state = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -76,9 +76,10 @@ int gsm48_cc_exit(struct osmocom_ms *ms)
|
|||
LOGP(DCC, LOGL_INFO, "exit Call Control processes for %s\n", ms->name);
|
||||
|
||||
llist_for_each_entry_safe(trans, trans2, &ms->trans_list, entry) {
|
||||
if (trans->protocol == GSM48_PDISC_CC)
|
||||
if (trans->protocol == GSM48_PDISC_CC) {
|
||||
LOGP(DCC, LOGL_NOTICE, "Free pendig CC-transaction.\n");
|
||||
trans_free(trans);
|
||||
}
|
||||
}
|
||||
|
||||
while ((msg = msgb_dequeue(&cc->mncc_upqueue)))
|
||||
|
@ -1916,12 +1917,29 @@ static struct downstate {
|
|||
#define DOWNSLLEN \
|
||||
(sizeof(downstatelist) / sizeof(struct downstate))
|
||||
|
||||
int mncc_send(struct osmocom_ms *ms, int msg_type, void *arg)
|
||||
int mncc_tx_to_cc(void *inst, int msg_type, void *arg)
|
||||
{
|
||||
struct osmocom_ms *ms = (struct osmocom_ms *) inst;
|
||||
struct gsm_mncc *data = arg;
|
||||
struct gsm_trans *trans;
|
||||
int i, rc;
|
||||
|
||||
if (!ms->started || ms->shutdown) {
|
||||
LOGP(DCC, LOGL_NOTICE, "Phone is down!\n");
|
||||
if (ms->mncc_entity.mncc_recv && msg_type != MNCC_REL_REQ) {
|
||||
struct gsm_mncc rel;
|
||||
|
||||
memset(&rel, 0, sizeof(rel));
|
||||
rel.callref = data->callref;
|
||||
mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU,
|
||||
GSM48_CC_CAUSE_DEST_OOO);
|
||||
ms->mncc_entity.mncc_recv(ms, MNCC_REL_IND, &rel);
|
||||
}
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
data->msg_type = msg_type;
|
||||
|
||||
/* Find callref */
|
||||
trans = trans_find_by_callref(ms, data->callref);
|
||||
|
||||
|
@ -2179,3 +2197,26 @@ int gsm48_rcv_cc(struct osmocom_ms *ms, struct msgb *msg)
|
|||
return rc;
|
||||
}
|
||||
|
||||
int mncc_clear_trans(void *inst, uint8_t protocol)
|
||||
{
|
||||
struct osmocom_ms *ms = (struct osmocom_ms *) inst;
|
||||
struct gsm_mncc rel;
|
||||
struct gsm_trans *trans, *trans2;
|
||||
|
||||
memset(&rel, 0, sizeof(struct gsm_mncc));
|
||||
|
||||
/* safe, in case the release process will destroy transaction node */
|
||||
llist_for_each_entry_safe(trans, trans2, &ms->trans_list, entry) {
|
||||
if (trans->protocol == protocol) {
|
||||
LOGP(DCC, LOGL_NOTICE, "Release CC-transaction.\n");
|
||||
rel.callref = trans->callref;
|
||||
mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU,
|
||||
GSM48_CC_CAUSE_TEMP_FAILURE);
|
||||
mncc_tx_to_cc(ms, MNCC_REL_REQ, &rel);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,9 @@ struct gsmtap_inst *gsmtap_inst = NULL;
|
|||
unsigned short vty_port = 4247;
|
||||
int debug_set = 0;
|
||||
char *config_dir = NULL;
|
||||
int use_mncc_sock = 0;
|
||||
|
||||
int mncc_recv_socket(struct osmocom_ms *ms, int msg_type, void *arg);
|
||||
|
||||
int mobile_delete(struct osmocom_ms *ms, int force);
|
||||
int mobile_signal_cb(unsigned int subsys, unsigned int signal,
|
||||
|
@ -83,6 +86,8 @@ static void print_help()
|
|||
printf(" -v --vty-port The VTY port number to telnet to. "
|
||||
"(default %u)\n", vty_port);
|
||||
printf(" -d --debug Change debug flags.\n");
|
||||
printf(" -m --mncc-sock Disable built-in MNCC handler and "
|
||||
"offer socket\n");
|
||||
}
|
||||
|
||||
static void handle_options(int argc, char **argv)
|
||||
|
@ -94,10 +99,11 @@ static void handle_options(int argc, char **argv)
|
|||
{"gsmtap-ip", 1, 0, 'i'},
|
||||
{"vty-port", 1, 0, 'v'},
|
||||
{"debug", 1, 0, 'd'},
|
||||
{"mncc-sock", 0, 0, 'm'},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "hi:v:d:",
|
||||
c = getopt_long(argc, argv, "hi:v:d:m",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
@ -118,6 +124,9 @@ static void handle_options(int argc, char **argv)
|
|||
log_parse_category_mask(stderr_target, optarg);
|
||||
debug_set = 1;
|
||||
break;
|
||||
case 'm':
|
||||
use_mncc_sock = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -187,7 +196,10 @@ int main(int argc, char **argv)
|
|||
config_dir = talloc_strdup(l23_ctx, config_file);
|
||||
config_dir = dirname(config_dir);
|
||||
|
||||
rc = l23_app_init(NULL, config_file, vty_port);
|
||||
if (use_mncc_sock)
|
||||
rc = l23_app_init(mncc_recv_socket, config_file, vty_port);
|
||||
else
|
||||
rc = l23_app_init(NULL, config_file, vty_port);
|
||||
if (rc)
|
||||
exit(rc);
|
||||
|
||||
|
|
|
@ -216,7 +216,43 @@ int mncc_recv_dummy(struct osmocom_ms *ms, int msg_type, void *arg)
|
|||
mncc_set_cause(&rel, GSM48_CAUSE_LOC_USER,
|
||||
GSM48_CC_CAUSE_INCOMPAT_DEST);
|
||||
|
||||
return mncc_send(ms, MNCC_REL_REQ, &rel);
|
||||
return mncc_tx_to_cc(ms, MNCC_REL_REQ, &rel);
|
||||
}
|
||||
|
||||
/*
|
||||
* MNCCms call application via socket
|
||||
*/
|
||||
int mncc_recv_socket(struct osmocom_ms *ms, int msg_type, void *arg)
|
||||
{
|
||||
struct mncc_sock_state *state = ms->mncc_entity.sock_state;
|
||||
struct gsm_mncc *mncc = arg;
|
||||
struct msgb *msg;
|
||||
unsigned char *data;
|
||||
|
||||
if (!state) {
|
||||
if (msg_type != MNCC_REL_IND && msg_type != MNCC_REL_CNF) {
|
||||
struct gsm_mncc rel;
|
||||
|
||||
/* reject */
|
||||
memset(&rel, 0, sizeof(struct gsm_mncc));
|
||||
rel.callref = mncc->callref;
|
||||
mncc_set_cause(&rel, GSM48_CAUSE_LOC_USER,
|
||||
GSM48_CC_CAUSE_TEMP_FAILURE);
|
||||
return mncc_tx_to_cc(ms, MNCC_REL_REQ, &rel);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
mncc->msg_type = msg_type;
|
||||
|
||||
msg = msgb_alloc(sizeof(struct gsm_mncc), "MNCC");
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
data = msgb_put(msg, sizeof(struct gsm_mncc));
|
||||
memcpy(data, mncc, sizeof(struct gsm_mncc));
|
||||
|
||||
return mncc_sock_from_cc(state, msg);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -244,7 +280,7 @@ int mncc_recv_mobile(struct osmocom_ms *ms, int msg_type, void *arg)
|
|||
memset(&mncc, 0, sizeof(struct gsm_mncc));
|
||||
mncc.callref = data->callref;
|
||||
mncc_set_cause(&mncc, GSM48_CAUSE_LOC_USER, cause);
|
||||
return mncc_send(ms, MNCC_REL_REQ, &mncc);
|
||||
return mncc_tx_to_cc(ms, MNCC_REL_REQ, &mncc);
|
||||
}
|
||||
|
||||
/* setup without call */
|
||||
|
@ -439,7 +475,7 @@ int mncc_recv_mobile(struct osmocom_ms *ms, int msg_type, void *arg)
|
|||
mncc.fields |= MNCC_F_CCCAP;
|
||||
mncc.cccap.dtmf = 1;
|
||||
}
|
||||
mncc_send(ms, MNCC_CALL_CONF_REQ, &mncc);
|
||||
mncc_tx_to_cc(ms, MNCC_CALL_CONF_REQ, &mncc);
|
||||
if (first_call)
|
||||
LOGP(DMNCC, LOGL_INFO, "Ring!\n");
|
||||
else {
|
||||
|
@ -449,7 +485,7 @@ int mncc_recv_mobile(struct osmocom_ms *ms, int msg_type, void *arg)
|
|||
call->ring = 1;
|
||||
memset(&mncc, 0, sizeof(struct gsm_mncc));
|
||||
mncc.callref = call->callref;
|
||||
mncc_send(ms, MNCC_ALERT_REQ, &mncc);
|
||||
mncc_tx_to_cc(ms, MNCC_ALERT_REQ, &mncc);
|
||||
if (ms->settings.auto_answer) {
|
||||
LOGP(DMNCC, LOGL_INFO, "Auto-answering call\n");
|
||||
mncc_answer(ms);
|
||||
|
@ -558,7 +594,7 @@ int mncc_call(struct osmocom_ms *ms, char *number)
|
|||
}
|
||||
}
|
||||
|
||||
return mncc_send(ms, MNCC_SETUP_REQ, &setup);
|
||||
return mncc_tx_to_cc(ms, MNCC_SETUP_REQ, &setup);
|
||||
}
|
||||
|
||||
int mncc_hangup(struct osmocom_ms *ms)
|
||||
|
@ -583,7 +619,7 @@ int mncc_hangup(struct osmocom_ms *ms)
|
|||
disc.callref = found->callref;
|
||||
mncc_set_cause(&disc, GSM48_CAUSE_LOC_USER,
|
||||
GSM48_CC_CAUSE_NORM_CALL_CLEAR);
|
||||
return mncc_send(ms, (call->init) ? MNCC_REL_REQ : MNCC_DISC_REQ,
|
||||
return mncc_tx_to_cc(ms, (call->init) ? MNCC_REL_REQ : MNCC_DISC_REQ,
|
||||
&disc);
|
||||
}
|
||||
|
||||
|
@ -616,7 +652,7 @@ int mncc_answer(struct osmocom_ms *ms)
|
|||
|
||||
memset(&rsp, 0, sizeof(struct gsm_mncc));
|
||||
rsp.callref = alerting->callref;
|
||||
return mncc_send(ms, MNCC_SETUP_RSP, &rsp);
|
||||
return mncc_tx_to_cc(ms, MNCC_SETUP_RSP, &rsp);
|
||||
}
|
||||
|
||||
int mncc_hold(struct osmocom_ms *ms)
|
||||
|
@ -639,7 +675,7 @@ int mncc_hold(struct osmocom_ms *ms)
|
|||
|
||||
memset(&hold, 0, sizeof(struct gsm_mncc));
|
||||
hold.callref = found->callref;
|
||||
return mncc_send(ms, MNCC_HOLD_REQ, &hold);
|
||||
return mncc_tx_to_cc(ms, MNCC_HOLD_REQ, &hold);
|
||||
}
|
||||
|
||||
int mncc_retrieve(struct osmocom_ms *ms, int number)
|
||||
|
@ -687,7 +723,7 @@ int mncc_retrieve(struct osmocom_ms *ms, int number)
|
|||
|
||||
memset(&retr, 0, sizeof(struct gsm_mncc));
|
||||
retr.callref = call->callref;
|
||||
return mncc_send(ms, MNCC_RETRIEVE_REQ, &retr);
|
||||
return mncc_tx_to_cc(ms, MNCC_RETRIEVE_REQ, &retr);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -714,7 +750,7 @@ static int dtmf_statemachine(struct gsm_call *call, struct gsm_mncc *mncc)
|
|||
call->dtmf_state = DTMF_ST_START;
|
||||
LOGP(DMNCC, LOGL_INFO, "start DTMF (keypad %c)\n",
|
||||
dtmf.keypad);
|
||||
return mncc_send(ms, MNCC_START_DTMF_REQ, &dtmf);
|
||||
return mncc_tx_to_cc(ms, MNCC_START_DTMF_REQ, &dtmf);
|
||||
case DTMF_ST_START:
|
||||
if (mncc->msg_type != MNCC_START_DTMF_RSP) {
|
||||
LOGP(DMNCC, LOGL_INFO, "DTMF was rejected\n");
|
||||
|
@ -729,7 +765,7 @@ static int dtmf_statemachine(struct gsm_call *call, struct gsm_mncc *mncc)
|
|||
dtmf.callref = call->callref;
|
||||
call->dtmf_state = DTMF_ST_STOP;
|
||||
LOGP(DMNCC, LOGL_INFO, "stop DTMF\n");
|
||||
return mncc_send(ms, MNCC_STOP_DTMF_REQ, &dtmf);
|
||||
return mncc_tx_to_cc(ms, MNCC_STOP_DTMF_REQ, &dtmf);
|
||||
case DTMF_ST_STOP:
|
||||
start_dtmf_timer(call, 120);
|
||||
call->dtmf_state = DTMF_ST_SPACE;
|
||||
|
|
Loading…
Reference in New Issue