NMT: Assign traffic channel for outgoing and incoming calls
This way the control channel stays available for other (idle) phones. No more loss of coverage for other phones, when a call to a mobile is made. It is still possible to define a combined control+traffic channel. (e.g. for single channel setup)
This commit is contained in:
parent
5c33b8824b
commit
87a21a285a
|
@ -314,10 +314,11 @@ int main(int argc, char *argv[])
|
|||
for (i = 0; i < num_kanal; i++)
|
||||
audiodev[i] = "sdr";
|
||||
num_audiodev = num_kanal;
|
||||
/* set chan_type */
|
||||
if (num_chan_type == 0) {
|
||||
for (i = 0; i < num_kanal; i++)
|
||||
chan_type[i] = CHAN_TYPE_CC_TC;
|
||||
/* set channel types for more than 1 channel */
|
||||
if (num_kanal > 1 && num_chan_type == 0) {
|
||||
chan_type[0] = CHAN_TYPE_CC;
|
||||
for (i = 1; i < num_kanal; i++)
|
||||
chan_type[i] = CHAN_TYPE_TC;
|
||||
num_chan_type = num_kanal;
|
||||
}
|
||||
if (num_supervisory == 0) {
|
||||
|
|
|
@ -241,6 +241,26 @@ static int dialstring2number(const char *dialstring, char *ms_country, char *ms_
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int is_chan_class_cc(enum nmt_chan_type chan_type)
|
||||
{
|
||||
if (chan_type == CHAN_TYPE_CC
|
||||
|| chan_type == CHAN_TYPE_CCA
|
||||
|| chan_type == CHAN_TYPE_CCB)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int is_chan_class_tc(enum nmt_chan_type chan_type)
|
||||
{
|
||||
if (chan_type == CHAN_TYPE_TC
|
||||
|| chan_type == CHAN_TYPE_AC_TC
|
||||
|| chan_type == CHAN_TYPE_CC_TC)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nmt_timeout(struct timer *timer);
|
||||
|
||||
/* Create transceiver instance and link to a list. */
|
||||
|
@ -372,8 +392,8 @@ void nmt_check_channels(int __attribute__((unused)) nmt_system)
|
|||
if (note)
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** Selected channel(s) can be used for calling only.\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** No call from the mobile phone is possible on this channel.\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** Use combined 'CC/TC' instead!\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** No call is possible on this channel.\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** Use at least one 'TC'!\n");
|
||||
note = 1;
|
||||
}
|
||||
if (tc && !(cca || ccb)) {
|
||||
|
@ -381,23 +401,23 @@ void nmt_check_channels(int __attribute__((unused)) nmt_system)
|
|||
PDEBUG(DNMT, DEBUG_NOTICE, "\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** Selected channel(s) can be used for traffic only.\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** No call to the mobile phone is possible on this channel.\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** Use combined 'CC/TC' instead!\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** Use one 'CC'!\n");
|
||||
note = 1;
|
||||
}
|
||||
if (cca && !ccb) {
|
||||
if (note)
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** Selected channel(s) can be used for calling of MS type A only.\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** No call from the MS type B phone is possible on this channel.\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** Use combined 'CC' or 'CC/TC' instead!\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** No call to the MS type B phone is possible on this channel.\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** Use one 'CC' instead!\n");
|
||||
note = 1;
|
||||
}
|
||||
if (!cca && ccb) {
|
||||
if (note)
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** Selected channel(s) can be used for calling of MS type B only.\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** No call from the MS type A phone is possible on this channel.\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** Use combined 'CC' or 'CC/TC' instead!\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** No call to the MS type A phone is possible on this channel.\n");
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "*** Use one 'CC' instead!\n");
|
||||
note = 1;
|
||||
}
|
||||
}
|
||||
|
@ -468,8 +488,7 @@ static void nmt_page(transaction_t *trans, int try)
|
|||
/* page on all CC (CC/TC) */
|
||||
for (sender = sender_head; sender; sender = sender->next) {
|
||||
nmt = (nmt_t *)sender;
|
||||
if (nmt->sysinfo.chan_type != CHAN_TYPE_CC
|
||||
&& nmt->sysinfo.chan_type != CHAN_TYPE_CC_TC)
|
||||
if (!is_chan_class_cc(nmt->sysinfo.chan_type))
|
||||
continue;
|
||||
/* page on all idle channels and on channels we previously paged */
|
||||
if (nmt->state != STATE_IDLE && nmt->trans != trans)
|
||||
|
@ -482,6 +501,26 @@ static void nmt_page(transaction_t *trans, int try)
|
|||
}
|
||||
}
|
||||
|
||||
static nmt_t *search_free_tc(void)
|
||||
{
|
||||
sender_t *sender;
|
||||
nmt_t *nmt, *cc_tc = NULL;
|
||||
|
||||
for (sender = sender_head; sender; sender = sender->next) {
|
||||
nmt = (nmt_t *) sender;
|
||||
if (nmt->state != STATE_IDLE)
|
||||
continue;
|
||||
/* remember combined voice/control/paging channel as second alternative */
|
||||
if (nmt->sysinfo.chan_type == CHAN_TYPE_CC_TC)
|
||||
cc_tc = nmt;
|
||||
else if (is_chan_class_tc(nmt->sysinfo.chan_type))
|
||||
return nmt;
|
||||
}
|
||||
|
||||
return cc_tc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* frame matching functions to check if channels is accessed correctly
|
||||
*/
|
||||
|
@ -1015,15 +1054,36 @@ static void rx_mt_paging(nmt_t *nmt, frame_t *frame)
|
|||
static void tx_mt_channel(nmt_t *nmt, frame_t *frame)
|
||||
{
|
||||
transaction_t *trans = nmt->trans;
|
||||
nmt_t *tc;
|
||||
|
||||
/* get free channel (after releasing all channels) */
|
||||
tc = search_free_tc();
|
||||
if (!tc) {
|
||||
PDEBUG_CHAN(DNMT, DEBUG_NOTICE, "TC is not free anymore.\n");
|
||||
PDEBUG(DNMT, DEBUG_INFO, "Release call towards network.\n");
|
||||
call_up_release(trans->callref, CAUSE_NOCHANNEL);
|
||||
trans->callref = 0;
|
||||
nmt_release(nmt);
|
||||
/* send idle for now, then continue with release */
|
||||
tx_idle(nmt, frame);
|
||||
return;
|
||||
}
|
||||
|
||||
/* link trans and tc together, so we can continue with channel assignment */
|
||||
PDEBUG_CHAN(DNMT, DEBUG_NOTICE, "Switching to TC channel #%d.\n", tc->sender.kanal);
|
||||
nmt_new_state(nmt, STATE_IDLE);
|
||||
tc->trans = trans;
|
||||
trans->nmt = tc;
|
||||
nmt_new_state(tc, STATE_MT_IDENT);
|
||||
|
||||
/* assign channel on 'nmt' to 'tc' */
|
||||
frame->mt = NMT_MESSAGE_2b;
|
||||
frame->channel_no = nmt_encode_channel(nmt->sysinfo.system, nmt->sender.kanal, nmt->sysinfo.ms_power);
|
||||
frame->traffic_area = nmt_encode_traffic_area(nmt->sysinfo.system, nmt->sender.kanal, nmt->sysinfo.traffic_area);
|
||||
frame->ms_country = nmt_digits2value(&trans->subscriber.country, 1);
|
||||
frame->ms_number = nmt_digits2value(trans->subscriber.number, 6);
|
||||
frame->tc_no = nmt_encode_tc(nmt->sysinfo.system, nmt->sender.kanal, nmt->sysinfo.ms_power);
|
||||
frame->tc_no = nmt_encode_tc(tc->sysinfo.system, tc->sender.kanal, tc->sysinfo.ms_power);
|
||||
PDEBUG_CHAN(DNMT, DEBUG_INFO, "Send channel activation to mobile.\n");
|
||||
nmt_new_state(nmt, STATE_MT_IDENT);
|
||||
}
|
||||
|
||||
static void tx_mt_ident(nmt_t *nmt, frame_t *frame)
|
||||
|
@ -1686,9 +1746,8 @@ inval:
|
|||
/* 3. check if all paging (calling) channels are busy, return NOCHANNEL */
|
||||
for (sender = sender_head; sender; sender = sender->next) {
|
||||
nmt = (nmt_t *) sender;
|
||||
if (nmt->sysinfo.chan_type != CHAN_TYPE_CC
|
||||
&& nmt->sysinfo.chan_type != CHAN_TYPE_CC_TC)
|
||||
continue;
|
||||
if (!is_chan_class_cc(nmt->sysinfo.chan_type))
|
||||
continue;
|
||||
if (nmt->state == STATE_IDLE)
|
||||
break;
|
||||
}
|
||||
|
@ -1696,6 +1755,10 @@ inval:
|
|||
PDEBUG(DNMT, DEBUG_NOTICE, "Outgoing call, but no free calling channel, rejecting!\n");
|
||||
return -CAUSE_NOCHANNEL;
|
||||
}
|
||||
if (!search_free_tc()) {
|
||||
PDEBUG(DNMT, DEBUG_NOTICE, "Outgoing call, but no free traffic channel, rejecting!\n");
|
||||
return -CAUSE_NOCHANNEL;
|
||||
}
|
||||
|
||||
PDEBUG(DNMT, DEBUG_INFO, "Call to mobile station, paging station id '%c%s'\n", subscr.country, subscr.number);
|
||||
|
||||
|
|
Loading…
Reference in New Issue