Fixes of layer23 processes during tests of MNCC interface.

-> Emergency calls will now trigger channel request.
-> Normal calls will be rejected due to limited/no service.
This commit is contained in:
root 2010-05-24 02:21:24 +02:00
parent 9359a91504
commit bfc0285c7c
5 changed files with 57 additions and 27 deletions

View File

@ -72,7 +72,7 @@ struct gsm_support {
uint8_t gps_conv;
/* IMEI */
char imei[15];
char imei[16];
char imeisv[17];
char imei_random;

View File

@ -55,7 +55,10 @@ int gsm48_cc_init(struct osmocom_ms *ms)
cc->ms = ms;
LOGP(DCC, LOGL_INFO, "init Call Control process\n");
if (!cc->mncc_upqueue.next == 0)
return 0;
LOGP(DCC, LOGL_INFO, "init Call Control\n");
INIT_LLIST_HEAD(&cc->mncc_upqueue);
@ -68,7 +71,7 @@ int gsm48_cc_exit(struct osmocom_ms *ms)
struct gsm_trans *trans, *trans2;
struct msgb *msg;
LOGP(DCC, LOGL_INFO, "exit Call Control process\n");
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)
@ -242,9 +245,9 @@ static void gsm48_cc_timeout(void *arg)
struct osmocom_ms *ms = trans->ms;
int disconnect = 0, release = 0, abort = 1;
int mo_cause = GSM48_CC_CAUSE_RECOVERY_TIMER;
int mo_location = GSM48_CAUSE_LOC_USER;
int mo_location = GSM48_CAUSE_LOC_PRN_S_LU;
int l4_cause = GSM48_CC_CAUSE_NORMAL_UNSPEC;
int l4_location = GSM48_CAUSE_LOC_USER;
int l4_location = GSM48_CAUSE_LOC_PRN_S_LU;
struct gsm_mncc mo_rel, l4_rel;
memset(&mo_rel, 0, sizeof(struct gsm_mncc));
@ -375,7 +378,7 @@ void _gsm48_cc_trans_free(struct gsm_trans *trans)
if (trans->callref) {
/* Ressource unavailable */
mncc_release_ind(trans->ms, trans, trans->callref,
GSM48_CAUSE_LOC_USER,
GSM48_CAUSE_LOC_PRN_S_LU,
GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
}
if (trans->cc.state != GSM_CSTATE_NULL)
@ -438,7 +441,7 @@ static int gsm48_cc_tx_status(struct gsm_trans *trans, int cause)
cause_ie = msgb_put(nmsg, 3);
cause_ie[0] = 2;
cause_ie[1] = GSM48_CAUSE_CS_GSM | GSM48_CAUSE_LOC_USER;
cause_ie[1] = GSM48_CAUSE_CS_GSM | GSM48_CAUSE_LOC_PRN_S_LU;
cause_ie[2] = 0x80 | cause;
call_state_ie = msgb_put(nmsg, 1);
@ -522,7 +525,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans)
"This is not allowed!\n");
/* Temporarily out of order */
rc = mncc_release_ind(trans->ms, trans, trans->callref,
GSM48_CAUSE_LOC_USER,
GSM48_CAUSE_LOC_PRN_S_LU,
GSM48_CC_CAUSE_NORMAL_UNSPEC);
trans->callref = 0;
trans_free(trans);
@ -534,7 +537,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans)
if (transaction_id < 0) {
/* no free transaction ID */
rc = mncc_release_ind(trans->ms, trans, trans->callref,
GSM48_CAUSE_LOC_USER,
GSM48_CAUSE_LOC_PRN_S_LU,
GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
trans->callref = 0;
trans_free(trans);
@ -1778,13 +1781,13 @@ int mncc_send(struct osmocom_ms *ms, int msg_type, void *arg)
if (msg_type != MNCC_SETUP_REQ) {
/* Invalid call reference */
return mncc_release_ind(ms, NULL, data->callref,
GSM48_CAUSE_LOC_USER,
GSM48_CAUSE_LOC_PRN_S_LU,
GSM48_CC_CAUSE_INVAL_TRANS_ID);
}
if (data->callref < 0x80000000) {
if (data->callref >= 0x40000000) {
LOGP(DCC, LOGL_FATAL, "MNCC ref wrong.\n");
return mncc_release_ind(ms, NULL, data->callref,
GSM48_CAUSE_LOC_USER,
GSM48_CAUSE_LOC_PRN_S_LU,
GSM48_CC_CAUSE_INVAL_TRANS_ID);
}
@ -1793,7 +1796,7 @@ int mncc_send(struct osmocom_ms *ms, int msg_type, void *arg)
if (!trans) {
/* No memory or whatever */
return mncc_release_ind(ms, NULL, data->callref,
GSM48_CAUSE_LOC_USER,
GSM48_CAUSE_LOC_PRN_S_LU,
GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
}
}
@ -1942,6 +1945,10 @@ int gsm48_rcv_cc(struct osmocom_ms *ms, struct msgb *msg)
return -ENOMEM;
}
LOGP(DCC, LOGL_INFO, "(ms %s) Received '%s' in CC state %s\n", ms->name,
get_mmxx_name(msg_type),
gsm48_cc_state_name(trans->cc.state));
switch (msg_type) {
case GSM48_MMCC_EST_IND:
/* data included */
@ -1959,7 +1966,7 @@ int gsm48_rcv_cc(struct osmocom_ms *ms, struct msgb *msg)
case GSM48_MMCC_REL_IND:
/* release L4, release transaction */
mncc_release_ind(trans->ms, trans, trans->callref,
GSM48_CAUSE_LOC_USER, GSM48_CC_CAUSE_NORMAL_UNSPEC);
GSM48_CAUSE_LOC_PRN_S_LU, mmh->cause);
trans->callref = 0;
trans_free(trans);
break;

View File

@ -1235,8 +1235,8 @@ uint32_t mm_conn_new_ref = 1;
/* new MM connection state */
static void new_conn_state(struct gsm48_mm_conn *conn, int state)
{
LOGP(DMM, LOGL_INFO, "(ref %d) new state %s -> %s", conn->ref,
gsm48_mmxx_state_names[conn->mm->state],
LOGP(DMM, LOGL_INFO, "(ref %d) new state %s -> %s\n", conn->ref,
gsm48_mmxx_state_names[conn->state],
gsm48_mmxx_state_names[state]);
conn->state = state;
}
@ -1348,8 +1348,7 @@ static int gsm48_mm_release_mm_conn(struct osmocom_ms *ms, int abort_any,
mm_conn_free(conn);
continue; /* skip if not of CC type */
}
nmmh = (struct gsm48_mmxx_hdr *)
msgb_put(nmsg, sizeof(*nmmh));
nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
nmmh->cause = cause;
gsm48_mmxx_upmsg(ms, nmsg);
@ -2883,15 +2882,15 @@ static int gsm48_mm_init_mm_reject(struct osmocom_ms *ms, struct msgb *msg)
nmsg = NULL;
switch(msg_type) {
case GSM48_MMCC_EST_REQ:
nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_REQ, mmh->ref,
nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_IND, mmh->ref,
mmh->transaction_id);
break;
case GSM48_MMSS_EST_REQ:
nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_REL_REQ, mmh->ref,
nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_REL_IND, mmh->ref,
mmh->transaction_id);
break;
case GSM48_MMSMS_EST_REQ:
nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_REL_REQ, mmh->ref,
nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_REL_IND, mmh->ref,
mmh->transaction_id);
break;
}
@ -3008,12 +3007,31 @@ static int gsm48_mm_sync_ind_active(struct osmocom_ms *ms, struct msgb *msg)
static int gsm48_mm_abort_mm_con(struct osmocom_ms *ms, struct msgb *msg)
{
struct gsm48_mmlayer *mm = &ms->mmlayer;
struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
int cause;
/* this conversion is not of any standard */
switch(rrh->cause) {
case RR_REL_CAUSE_NOT_AUTHORIZED:
case RR_REL_CAUSE_EMERGENCY_ONLY:
cause = 21;
break;
case RR_REL_CAUSE_TRY_LATER:
cause = 34;
break;
default:
cause = 47;
}
/* stop MM connection timer */
stop_mm_t3230(mm);
/* release all connections */
gsm48_mm_release_mm_conn(ms, 1, 16, 1);
gsm48_mm_release_mm_conn(ms, 1, cause, 1);
/* no RR connection, so we return to MM IDLE */
if (mm->state == GSM48_MM_ST_WAIT_RR_CONN_MM_CON)
return gsm48_mm_return_idle(ms, NULL);
/* CS process will trigger: return to MM IDLE */
return 0;
@ -3481,6 +3499,9 @@ static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg)
uint8_t skip_ind;
int i, rc;
LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' in MM state %s\n", ms->name,
get_mm_name(msg_type), gsm48_mm_state_names[mm->state]);
/* pull the RR header */
msgb_pull(msg, sizeof(struct gsm48_rr_hdr));
@ -3564,9 +3585,6 @@ static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg)
GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED);
}
LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' in MM state %s\n", ms->name,
get_mm_name(msg_type), gsm48_mm_state_names[mm->state]);
stop_mm_t3212(mm); /* 4.4.2 */
/* 11.2 re-start pending RR release timer */

View File

@ -34,9 +34,12 @@
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#define GSM_L2_LENGTH 256
extern int quit;
static int layer2_read(struct bsc_fd *fd)
{
struct msgb *msg;
@ -51,7 +54,8 @@ static int layer2_read(struct bsc_fd *fd)
rc = read(fd->fd, &len, sizeof(len));
if (rc < sizeof(len)) {
msgb_free(msg);
fprintf(stderr, "Layer2 socket failed\n");
quit = rc;
return rc;
}

View File

@ -54,6 +54,7 @@ static struct osmocom_ms *ms = NULL;
static uint32_t gsmtap_ip = 0;
int (*l23_app_work) (struct osmocom_ms *ms) = NULL;
int (*l23_app_exit) (struct osmocom_ms *ms) = NULL;
int quit = 0;
static void print_usage(const char *app)
{
@ -182,7 +183,7 @@ int main(int argc, char **argv)
signal(SIGTERM, sighandler);
signal(SIGPIPE, sighandler);
while (1) {
while (!quit) {
if (l23_app_work)
l23_app_work(ms);
bsc_select_main(0);