2016-05-01 17:51:56 +00:00
/* AMPS frame transcoding
*
* ( C ) 2016 by Andreas Eversberg < jolly @ eversberg . eu >
* All Rights Reserved
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2016-12-09 15:34:33 +00:00
# define CHAN amps->sender.kanal
2016-05-01 17:51:56 +00:00
# include <stdio.h>
# include <stdint.h>
# include <stdlib.h>
# include <string.h>
# include <errno.h>
# include <math.h>
# include <inttypes.h>
2017-11-18 07:06:06 +00:00
# include "../libsample/sample.h"
2017-11-18 07:58:57 +00:00
# include "../libdebug/debug.h"
2016-05-01 17:51:56 +00:00
# include "amps.h"
# include "dsp.h"
# include "frame.h"
2017-05-30 10:49:40 +00:00
# include "main.h"
2016-05-01 17:51:56 +00:00
/* uncomment this to debug bits */
//#define BIT_DEBUGGING
2017-05-15 15:59:09 +00:00
/* uncomment this to debug all messages (control filler / global action messages) */
//#define DEBUG_ALL_MESSAGES
2016-05-01 17:51:56 +00:00
/*
* parity
*/
2016-10-07 06:55:18 +00:00
static uint64_t cut_bits [ 37 ] = {
2016-05-01 17:51:56 +00:00
0x0 ,
0x1 , 0x3 , 0x7 , 0xf , 0x1f , 0x3f , 0x7f , 0xff ,
0x1ff , 0x3ff , 0x7ff , 0xfff , 0x1fff , 0x3fff , 0x7fff , 0xffff ,
0x1ffff , 0x3ffff , 0x7ffff , 0xfffff , 0x1fffff , 0x3fffff , 0x7fffff , 0xffffff ,
0x1ffffff , 0x3ffffff , 0x7ffffff , 0xfffffff , 0x1fffffff , 0x3fffffff , 0x7fffffff , 0xffffffff ,
0x1ffffffff , 0x3ffffffff , 0x7ffffffff , 0xfffffffff ,
} ;
static char gp [ 12 ] = { 0 , 1 , 0 , 1 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 1 } ;
/* do BCH(length+12,length,5) encoding:
* given data and length , return 12 bits redundancy
* all arrays are MSB first .
*/
2016-10-07 06:55:18 +00:00
static const char * encode_bch ( const char * data , int length )
2016-05-01 17:51:56 +00:00
{
static char redun [ 13 ] ;
int i , j , feedback ;
for ( i = 0 ; i < 12 ; i + + )
redun [ i ] = 0 ;
for ( i = 0 ; i < length ; i + + ) {
feedback = ( data [ i ] & 1 ) ^ redun [ 0 ] ;
if ( feedback ) {
for ( j = 11 ; j > 0 ; j - - ) {
if ( gp [ 11 - j ] )
redun [ 11 - j ] = redun [ 12 - j ] ^ feedback ;
else
redun [ 11 - j ] = redun [ 12 - j ] ;
}
redun [ 11 ] = gp [ 11 ] ;
} else {
for ( j = 11 ; j > 0 ; j - - )
redun [ 11 - j ] = redun [ 12 - j ] ;
redun [ 11 ] = 0 ;
}
}
for ( i = 0 ; i < 12 ; i + + )
redun [ i ] + = ' 0 ' ;
redun [ 12 ] = ' \0 ' ;
return redun ;
}
/* same as above, but with binary data (without parity space holder) */
2016-10-07 06:55:18 +00:00
static uint16_t encode_bch_binary ( uint64_t value , int length )
2016-05-01 17:51:56 +00:00
{
char data [ length + 1 ] ;
const char * redun ;
uint16_t p = 0 ;
int i ;
for ( i = 0 ; i < length ; i + + )
data [ i ] = ' 0 ' + ( ( value > > ( length - 1 - i ) ) & 1 ) ;
data [ i ] = ' \0 ' ;
redun = encode_bch ( data , length ) ;
for ( i = 0 ; i < 12 ; i + + )
p = ( p < < 1 ) | ( ( * redun + + ) & 1 ) ;
return p ;
}
/*
* helper
*/
/* convert amps digits to number digits */
static char digit2number [ 16 ] = {
' \0 ' ,
' 1 ' ,
' 2 ' ,
' 3 ' ,
' 4 ' ,
' 5 ' ,
' 6 ' ,
' 7 ' ,
' 8 ' ,
' 9 ' ,
' 0 ' ,
' * ' ,
' # ' ,
' + ' ,
' ? ' ,
' ? ' ,
} ;
/*
* Word definitions
*/
struct def_ie {
const char * name ;
int bits ;
enum amps_ie ie ;
} ;
struct def_word {
const char * name ;
struct def_ie ie [ ] ;
} ;
struct def_message_set {
const char * name ;
int num_bits ;
struct def_word * word [ ] ;
} ;
/* FOCC - Mobile Station Control Message */
static struct def_word word1_abbreviated_address_word = {
" Word 1 - Abbreviated Address Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " MIN1 " , 24 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word2_extended_address_word_a = {
" Word 2 - Extended Address Word (SCC == 11) " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " SCC " , 2 , 0 } ,
{ " MIN2 " , 10 , 0 } ,
{ " EF " , 1 , 0 } ,
{ " LOCAL/MSG TYPE " , 5 , 0 } ,
{ " ORDQ " , 3 , 0 } ,
{ " ORDER " , 5 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word2_extended_address_word_b = {
" Word 2 - Extended Address Word (SCC != 11) " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " SCC " , 2 , 0 } ,
{ " MIN2 " , 10 , 0 } ,
{ " VMAC " , 3 , 0 } ,
{ " CHAN " , 11 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word3_first_analog_channel_assignment_word = {
" Word 3 - First Analog Channel Assignment Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " PVI " , 1 , 0 } ,
{ " MEM " , 1 , 0 } ,
{ " DTX Support " , 2 , 0 } ,
{ " RSVD " , 6 , 0 } ,
{ " SCC " , 2 , 0 } ,
{ " VMAC " , 3 , 0 } ,
{ " CHAN " , 11 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word3_first_digital_channel_assignment_word = {
" Word 3 - First Digital Channel Assignment Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " PVI " , 1 , 0 } ,
{ " MEM " , 1 , 0 } ,
{ " DVCC " , 8 , 0 } ,
{ " PM " , 1 , 0 } ,
{ " DMAC " , 4 , 0 } ,
{ " CHAN " , 11 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word3_first_directed_retry_word = {
" Word 3 - First Directed-Retry Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " SCC " , 2 , 0 } ,
{ " CHANPOS " , 7 , 0 } ,
{ " CHANPOS " , 7 , 0 } ,
{ " CHANPOS " , 7 , 0 } ,
{ " RSVD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word3_base_station_challenge_order_confirmation_word = {
" Word 3 - Base Station Challenge Order Confirmation Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " SCC " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " AUTHBS " , 18 , 0 } ,
{ " RSVD " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word3_unique_challenge_order_word = {
" Word 3 - Unique Challenge Order Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " SCC " , 2 , 0 } ,
{ " RANDU " , 24 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word3_first_ssd_update_order_word = {
" Word 3 - First SSD Update Order Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " SCC " , 2 , 0 } ,
{ " RANDSSD_1 " , 24 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word4_second_directed_retry_word = {
" Word 4 - Second Directed-Retry Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " SCC " , 2 , 0 } ,
{ " CHANPOS " , 7 , 0 } ,
{ " CHANPOS " , 7 , 0 } ,
{ " CHANPOS " , 7 , 0 } ,
{ " RSVD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word4_second_ssd_update_order_word = {
" Word 4 - Second SSD Update Order Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " SCC " , 2 , 0 } ,
{ " RANDSSD_2 " , 24 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word5_third_ssd_update_order_word = {
" Word 5 - Third SSD Update Order Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " SCC " , 2 , 0 } ,
{ " RSVD " , 12 , 0 } ,
{ " RANDSSD_3 " , 8 , 0 } ,
{ " RSVD " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
/* FOCC - System Parameter Overhead Message */
2017-05-30 10:49:40 +00:00
static struct def_word amps_word1_system_parameter_overhead = {
2016-05-01 17:51:56 +00:00
" Word 1 - System Parameter Overhead " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " SID1 " , 14 , 0 } ,
{ " EP " , 1 , 0 } ,
{ " AUTH " , 1 , 0 } ,
{ " PCI " , 1 , 0 } ,
{ " NAWC " , 4 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
2017-05-30 10:49:40 +00:00
static struct def_word tacs_word1_system_parameter_overhead = {
" Word 1 - System Parameter Overhead " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " AID1 " , 14 , 0 } ,
{ " EP " , 1 , 0 } ,
{ " AUTH " , 1 , 0 } ,
{ " PCI " , 1 , 0 } ,
{ " NAWC " , 4 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
2016-05-01 17:51:56 +00:00
static struct def_word word2_system_parameter_overhead = {
" Word 2 - System Parameter Overhead " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " S " , 1 , 0 } ,
{ " E " , 1 , 0 } ,
{ " REGH " , 1 , 0 } ,
{ " REGR " , 1 , 0 } ,
{ " DTX Support " , 2 , 0 } ,
{ " N-1 " , 5 , 0 } ,
{ " RCF " , 1 , 0 } ,
{ " CPA " , 1 , 0 } ,
{ " CMAX-1 " , 7 , 0 } ,
{ " END " , 1 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
/* FOCC - Global action Overhead Message */
static struct def_word rescan_global_action = {
" Rescan Global Action Message " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " ACT " , 4 , 0 } ,
{ " RSVD " , 16 , 0 } ,
{ " END " , 1 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word registration_increment_global_action = {
" Registration Increment Global Action Message " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " ACT " , 4 , 0 } ,
{ " REGINCR " , 12 , 0 } ,
{ " RSVD " , 4 , 0 } ,
{ " END " , 1 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word location_area_global_action = {
" Location Area Global Action Message " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " ACT " , 4 , 0 } ,
{ " PUREG " , 1 , 0 } ,
{ " PDREG " , 1 , 0 } ,
{ " LREG " , 1 , 0 } ,
{ " RSVD " , 1 , 0 } ,
{ " LOCAID " , 12 , 0 } ,
{ " END " , 1 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word new_access_channel_set_global_action = {
" New Access Channel Set Global Action Message " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " ACT " , 4 , 0 } ,
{ " NEWACC " , 11 , 0 } ,
{ " RSVD " , 5 , 0 } ,
{ " END " , 1 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word overload_control_global_action = {
" Overload Control Global Action Message " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " ACT " , 4 , 0 } ,
{ " OLC 0 " , 1 , 0 } ,
{ " OLC 1 " , 1 , 0 } ,
{ " OLC 2 " , 1 , 0 } ,
{ " OLC 3 " , 1 , 0 } ,
{ " OLC 4 " , 1 , 0 } ,
{ " OLC 5 " , 1 , 0 } ,
{ " OLC 6 " , 1 , 0 } ,
{ " OLC 7 " , 1 , 0 } ,
{ " OLC 8 " , 1 , 0 } ,
{ " OLC 9 " , 1 , 0 } ,
{ " OLC 10 " , 1 , 0 } ,
{ " OLC 11 " , 1 , 0 } ,
{ " OLC 12 " , 1 , 0 } ,
{ " OLC 13 " , 1 , 0 } ,
{ " OLC 14 " , 1 , 0 } ,
{ " OLC 15 " , 1 , 0 } ,
{ " END " , 1 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word access_type_parameters_global_action = {
" Access Type Parameters Global Action Message " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " ACT " , 4 , 0 } ,
{ " BIS " , 1 , 0 } ,
{ " PCI_HOME " , 1 , 0 } ,
{ " PCI_ROAM " , 1 , 0 } ,
{ " BSPC " , 4 , 0 } ,
{ " BSCAP " , 3 , 0 } ,
{ " RSVD " , 6 , 0 } ,
{ " END " , 1 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word access_attempt_parameters_global_action = {
" Access Attempt Parameters Global Action Message " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " ACT " , 4 , 0 } ,
{ " MAXBUSY-PGR " , 4 , 0 } ,
{ " MAXSZTR-PGR " , 4 , 0 } ,
{ " MAXBUSY-OTHER " , 4 , 0 } ,
{ " MAXSZTR-OTHER " , 4 , 0 } ,
{ " END " , 1 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word random_challenge_a_global_action = {
" Random Challenge A Global Action Message " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " ACT " , 4 , 0 } ,
{ " RAND1_A " , 16 , 0 } ,
{ " END " , 1 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word random_challenge_b_global_action = {
" Random Challenge B Global Action Message " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " ACT " , 4 , 0 } ,
{ " RAND1_B " , 16 , 0 } ,
{ " END " , 1 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word local_control_1 = {
" Local Control 1 Message " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " ACT " , 4 , 0 } ,
{ " LOCAL CONTROL " , 16 , 0 } ,
{ " END " , 1 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word local_control_2 = {
" Local Control 2 Message " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " ACT " , 4 , 0 } ,
{ " LOCAL CONTROL " , 16 , 0 } ,
{ " END " , 1 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
/* FOCC - Registration ID Message */
static struct def_word registration_id = {
" Registration ID Message " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " REGID " , 20 , 0 } ,
{ " END " , 1 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
/* FOCC - Control Filler Message */
static struct def_word control_filler = {
" Control-Filler Message " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " 010111 " , 6 , 0 } ,
{ " CMAC " , 3 , 0 } ,
{ " SDCC1 " , 2 , 0 } ,
{ " 11 " , 2 , 0 } ,
{ " SDCC2 " , 2 , 0 } ,
{ " 1 " , 1 , 0 } ,
{ " WFOM " , 1 , 0 } ,
{ " 1111 " , 4 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
/* FOCC - Control Channel Information Message */
static struct def_word control_channel_information = {
" Control Channel Information Message " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " DCC " , 2 , 0 } ,
{ " CHAN " , 11 , 0 } ,
{ " Async Data " , 1 , 0 } ,
{ " G3 Fax " , 1 , 0 } ,
{ " Data Privacy " , 1 , 0 } ,
{ " HDVCC " , 4 , 0 } ,
{ " Hyperband " , 2 , 0 } ,
{ " END " , 1 , 0 } ,
{ " OHD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_message_set focc_words = {
" FOCC Messages " , 40 ,
{
& word1_abbreviated_address_word ,
& word2_extended_address_word_a ,
& word2_extended_address_word_b ,
& word3_first_analog_channel_assignment_word ,
& word3_first_digital_channel_assignment_word ,
& word3_first_directed_retry_word ,
& word3_base_station_challenge_order_confirmation_word ,
& word3_unique_challenge_order_word ,
& word3_first_ssd_update_order_word ,
& word4_second_directed_retry_word ,
& word4_second_ssd_update_order_word ,
& word5_third_ssd_update_order_word ,
2017-05-30 10:49:40 +00:00
& amps_word1_system_parameter_overhead ,
& tacs_word1_system_parameter_overhead ,
2016-05-01 17:51:56 +00:00
& word2_system_parameter_overhead ,
& rescan_global_action ,
& registration_increment_global_action ,
& location_area_global_action ,
& new_access_channel_set_global_action ,
& overload_control_global_action ,
& access_type_parameters_global_action ,
& access_attempt_parameters_global_action ,
& random_challenge_a_global_action ,
& random_challenge_b_global_action ,
& local_control_1 ,
& local_control_2 ,
& registration_id ,
& control_filler ,
& control_channel_information ,
NULL
}
} ;
/* RECC - Words */
static struct def_word abbreviated_address_word = {
" Word A - Abbreviated Address Word " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 3 , 0 } ,
{ " T " , 1 , 0 } ,
{ " S " , 1 , 0 } ,
{ " E " , 1 , 0 } ,
{ " ER " , 1 , 0 } ,
{ " SCM " , 4 , 0 } ,
{ " MIN1 " , 24 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word extended_address_word = {
" Word B - Extended Address Word " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 3 , 0 } ,
{ " LOCAL/MSG TYPE " , 5 , 0 } ,
{ " ORDQ " , 3 , 0 } ,
{ " ORDER " , 5 , 0 } ,
{ " LT " , 1 , 0 } ,
{ " EP " , 1 , 0 } ,
{ " SCM " , 1 , 0 } ,
{ " MPCI " , 2 , 0 } ,
{ " SDCC1 " , 2 , 0 } ,
{ " SDCC2 " , 2 , 0 } ,
{ " MIN2 " , 10 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word serial_number_word = {
" Word C - Serial Number Word " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 3 , 0 } ,
{ " ESN " , 32 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word authentication_word = {
" Word C - Authentication Word " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 3 , 0 } ,
{ " COUNT " , 6 , 0 } ,
{ " RANDC " , 8 , 0 } ,
{ " AUTHR " , 18 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word unique_challenge_order_confirmation_word = {
" Word C - Unique Challenge Order Confirmation Word " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 3 , 0 } ,
{ " RSVD " , 14 , 0 } ,
{ " AUTHU " , 18 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word base_station_challenge_word = {
" Word C - Base Station Challenge Word " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 3 , 0 } ,
{ " RANDBS " , 32 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word pci_report_registration_word = {
" Word C - PCI Report/Registration Word " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 3 , 0 } ,
{ " MSPC " , 4 , 0 } ,
{ " MSCAP " , 3 , 0 } ,
{ " RSVD " , 25 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word first_word_of_the_called_address = {
" Word D - First Word of the Called-Address (Origination - Voice Service) " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 3 , 0 } ,
{ " DIGIT 1 " , 4 , 0 } ,
{ " DIGIT 2 " , 4 , 0 } ,
{ " DIGIT 3 " , 4 , 0 } ,
{ " DIGIT 4 " , 4 , 0 } ,
{ " DIGIT 5 " , 4 , 0 } ,
{ " DIGIT 6 " , 4 , 0 } ,
{ " DIGIT 7 " , 4 , 0 } ,
{ " DIGIT 8 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word service_code_word = {
" Word D - Service Code Word (Origination with Service and Page Response with 2 Service) " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 3 , 0 } ,
{ " Service Code " , 4 , 0 } ,
{ " PM_D " , 3 , 0 } ,
{ " SAP " , 1 , 0 } ,
{ " Acked Data " , 1 , 0 } ,
{ " CRC " , 2 , 0 } ,
{ " Data Part " , 3 , 0 } ,
{ " RLP " , 2 , 0 } ,
{ " RSVD " , 16 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word second_word_of_the_called_address = {
" Word E - Second Word of the Called-Address (Origination - Voice Service) " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 3 , 0 } ,
{ " DIGIT 9 " , 4 , 0 } ,
{ " DIGIT 10 " , 4 , 0 } ,
{ " DIGIT 11 " , 4 , 0 } ,
{ " DIGIT 12 " , 4 , 0 } ,
{ " DIGIT 13 " , 4 , 0 } ,
{ " DIGIT 14 " , 4 , 0 } ,
{ " DIGIT 15 " , 4 , 0 } ,
{ " DIGIT 16 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word third_word_of_the_called_address = {
" Word F - Third Word of the Called-Address (Origination - Voice Service) " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 3 , 0 } ,
{ " DIGIT 17 " , 4 , 0 } ,
{ " DIGIT 18 " , 4 , 0 } ,
{ " DIGIT 19 " , 4 , 0 } ,
{ " DIGIT 20 " , 4 , 0 } ,
{ " DIGIT 21 " , 4 , 0 } ,
{ " DIGIT 22 " , 4 , 0 } ,
{ " DIGIT 23 " , 4 , 0 } ,
{ " DIGIT 24 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word fourth_word_of_the_called_address = {
" Word G - Fourth Word of the Called-Address (Origination - Voice Service) " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 3 , 0 } ,
{ " DIGIT 25 " , 4 , 0 } ,
{ " DIGIT 26 " , 4 , 0 } ,
{ " DIGIT 27 " , 4 , 0 } ,
{ " DIGIT 28 " , 4 , 0 } ,
{ " DIGIT 29 " , 4 , 0 } ,
{ " DIGIT 30 " , 4 , 0 } ,
{ " DIGIT 31 " , 4 , 0 } ,
{ " DIGIT 32 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_message_set recc_words = {
" RECC Words " , 48 ,
{
& abbreviated_address_word ,
& extended_address_word ,
& serial_number_word ,
& authentication_word ,
& unique_challenge_order_confirmation_word ,
& base_station_challenge_word ,
& pci_report_registration_word ,
& first_word_of_the_called_address ,
& service_code_word ,
& second_word_of_the_called_address ,
& third_word_of_the_called_address ,
& fourth_word_of_the_called_address ,
NULL
}
} ;
/* FVC - Mobile Station Control Message */
static struct def_word mobile_station_control_message_word1_a = {
" Mobile Station Control Message Word 1 (SCC == 11) " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " SCC " , 2 , 0 } ,
{ " PSCC " , 2 , 0 } ,
{ " EF " , 1 , 0 } ,
{ " DVCC " , 8 , 0 } ,
{ " LOCAL/MSG TYPE " , 5 , 0 } ,
{ " ORDQ " , 3 , 0 } ,
{ " ORDER " , 5 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word mobile_station_control_message_word1_b = {
" Mobile Station Control Message Word 1 (SCC != 11) " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " SCC " , 2 , 0 } ,
{ " PSCC " , 2 , 0 } ,
{ " EF " , 1 , 0 } ,
{ " RSVD " , 4 , 0 } ,
{ " DTX " , 1 , 0 } ,
{ " PVI " , 1 , 0 } ,
{ " MEM " , 1 , 0 } ,
{ " VMAC " , 3 , 0 } ,
{ " CHAN " , 11 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word2_digital_channel_assignment = {
" Word 2 - Digital Channel Assignment " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " MEM " , 1 , 0 } ,
{ " PM " , 1 , 0 } ,
{ " PSCC " , 2 , 0 } ,
{ " SBI " , 2 , 0 } ,
{ " TA " , 5 , 0 } ,
{ " DMAC " , 4 , 0 } ,
{ " CHAN " , 11 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word2_digital_control_channel_information_word = {
" Word 2 - Digital Control Channel Information Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 5 , 0 } ,
{ " Hyperband " , 2 , 0 } ,
{ " DVCC " , 8 , 0 } ,
{ " CHAN " , 11 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word2_base_station_challenge_order_confirmation = {
" Word 2 - Base Station Challenge Order Confirmation " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 4 , 0 } ,
{ " AUTHBS " , 18 , 0 } ,
{ " RSVD " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word2_unique_challenge_order_word = {
" Word 2 - Unique Challenge Order Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " RANDU " , 24 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word2_first_ssd_update_order_word = {
" Word 2 - First SSD Update Order Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RANDSSD_1 " , 24 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word2_first_alert_with_info_word = {
" Word 2 - First Alert With Info Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RL_W " , 5 , 0 } ,
{ " SIGNAL " , 8 , 0 } ,
{ " CPN_RL " , 6 , 0 } ,
{ " PI " , 2 , 0 } ,
{ " SI " , 2 , 0 } ,
{ " RSVD " , 3 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word2_first_flash_with_info_word = {
" Word 2 - First Flash With Info Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RL_W " , 5 , 0 } ,
{ " CPN_RL " , 6 , 0 } ,
{ " PI " , 2 , 0 } ,
{ " SI " , 2 , 0 } ,
{ " RSVD " , 11 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word3_second_ssd_update_oder_word = {
" Word 3 - Second SSD Update Order Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RANDSSD_2 " , 24 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word3_second_alert_with_info_word = {
" Word 3 - Second Alert With Info Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CHARACTER 1 " , 8 , 0 } ,
{ " CHARACTER 2 " , 8 , 0 } ,
{ " CHARACTER 3 " , 8 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word3_second_alert_with_info_cri_message_word = {
" Word 3 - Second Alert With Info CRI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CRI E14 " , 4 , 0 } ,
{ " CRI E13 " , 4 , 0 } ,
{ " CRI E12 " , 4 , 0 } ,
{ " CRI E11 " , 4 , 0 } ,
{ " CRI E24 " , 4 , 0 } ,
{ " CRI E23 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word3_second_alert_with_info_tci_message_word = {
" Word 3 - Second Alert With Info TCI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " TCI1 " , 7 , 0 } ,
{ " TCI5 " , 1 , 0 } ,
{ " TCI24 " , 4 , 0 } ,
{ " TCI23 " , 4 , 0 } ,
{ " TCI22 " , 4 , 0 } ,
{ " TCI21 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word3_second_flash_with_info_word = {
" Word 3 - Second Flash With Info Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CHARACTER 1 " , 8 , 0 } ,
{ " CHARACTER 2 " , 8 , 0 } ,
{ " CHARACTER 3 " , 8 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word3_second_flash_with_info_cri_message_word = {
" Word 3 - Second Flash With Info CRI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CRI E14 " , 4 , 0 } ,
{ " CRI E13 " , 4 , 0 } ,
{ " CRI E12 " , 4 , 0 } ,
{ " CRI E11 " , 4 , 0 } ,
{ " CRI E24 " , 4 , 0 } ,
{ " CRI E23 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word3_second_flash_with_info_tci_message_word = {
" Word 3 - Second Flash With Info TCI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " TCI1 " , 7 , 0 } ,
{ " TCI5 " , 1 , 0 } ,
{ " TCI24 " , 4 , 0 } ,
{ " TCI23 " , 4 , 0 } ,
{ " TCI22 " , 4 , 0 } ,
{ " TCI21 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word4_third_ssd_update_order_word = {
" Word 4 - Third SSD Update Order Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RANDSSD_3 " , 8 , 0 } ,
{ " RSVD " , 18 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word4_third_alert_with_info_word = {
" Word 4 - Third Alert With Info Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CHARACTER 1 " , 8 , 0 } ,
{ " CHARACTER 2 " , 8 , 0 } ,
{ " CHARACTER 3 " , 8 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word4_third_alert_with_info_cri_message_word = {
" Word 4 - Third Alert With Info CRI Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CRI E22 " , 4 , 0 } ,
{ " CRI E21 " , 4 , 0 } ,
{ " CRI E34 " , 4 , 0 } ,
{ " CRI E33 " , 4 , 0 } ,
{ " CRI E32 " , 4 , 0 } ,
{ " CRI E31 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word4_third_alert_with_info_tci_message_word = {
" Word 4 - Third Alert With Info TCI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " TCI34 " , 7 , 0 } ,
{ " TCI33 " , 1 , 0 } ,
{ " TCI32 " , 4 , 0 } ,
{ " TCI31 " , 4 , 0 } ,
{ " TCI44 " , 4 , 0 } ,
{ " TCI43 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word4_third_flash_with_info_word = {
" Word 4 - Third Flash With Info Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CHARACTER 1 " , 8 , 0 } ,
{ " CHARACTER 2 " , 8 , 0 } ,
{ " CHARACTER 3 " , 8 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word4_third_flash_with_info_cri_message_word = {
" Word 4 - Third Flash With Info CRI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CRI E22 " , 4 , 0 } ,
{ " CRI E21 " , 4 , 0 } ,
{ " CRI E34 " , 4 , 0 } ,
{ " CRI E33 " , 4 , 0 } ,
{ " CRI E32 " , 4 , 0 } ,
{ " CRI E31 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word4_third_flash_with_info_tci_message_word = {
" Word 4 - Third Flash With Info TCI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " TCI34 " , 4 , 0 } ,
{ " TCI33 " , 4 , 0 } ,
{ " TCI32 " , 4 , 0 } ,
{ " TCI31 " , 4 , 0 } ,
{ " TCI44 " , 4 , 0 } ,
{ " TCI43 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word5_alert_with_info_word = {
" Word 5 - Fourth Alert With Info Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CHARACTER 1 " , 8 , 0 } ,
{ " CHARACTER 2 " , 8 , 0 } ,
{ " CHARACTER 3 " , 8 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word5_alert_with_info_cri_message_word = {
" Word 5 - Fourth Alert With Info CRI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CRI E44 " , 4 , 0 } ,
{ " CRI E43 " , 4 , 0 } ,
{ " CRI E42 " , 4 , 0 } ,
{ " CRI E41 " , 4 , 0 } ,
{ " CRI E54 " , 4 , 0 } ,
{ " CRI E53 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word5_alert_with_info_tci_message_word = {
" Word 5 - Fourth Alert With Info TCI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " TCI42 " , 4 , 0 } ,
{ " TCI41 " , 4 , 0 } ,
{ " NULL " , 8 , 0 } ,
{ " NULL " , 8 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word5_flash_with_info_word = {
" Word 5 - Fourth Flash With Info Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CHARACTER 1 " , 8 , 0 } ,
{ " CHARACTER 2 " , 8 , 0 } ,
{ " CHARACTER 3 " , 8 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word5_flash_with_info_cri_message_word = {
" Word 5 - Fourth Flash With Info CRI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CRI E44 " , 4 , 0 } ,
{ " CRI E43 " , 4 , 0 } ,
{ " CRI E42 " , 4 , 0 } ,
{ " CRI E41 " , 4 , 0 } ,
{ " CRI E54 " , 4 , 0 } ,
{ " CRI E53 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word5_flash_with_info_tci_message_word = {
" Word 5 - Fourth Flash With Info TCI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " TCI42 " , 4 , 0 } ,
{ " TCI41 " , 4 , 0 } ,
{ " NULL " , 8 , 0 } ,
{ " NULL " , 8 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word wordn_n_minus_1th_alert_with_info_word = {
" Word N - (N-1)th Alert With Info Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CHARACTER 1 " , 8 , 0 } ,
{ " CHARACTER 2 " , 8 , 0 } ,
{ " CHARACTER 3 " , 8 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word6_fifth_alert_with_info_cri_mesage_word = {
" Word 6 - Fifth Alert With Info CRI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CRI E52 " , 4 , 0 } ,
{ " CRI E51 " , 4 , 0 } ,
{ " CRI E64 " , 4 , 0 } ,
{ " CRI E63 " , 4 , 0 } ,
{ " CRI E62 " , 4 , 0 } ,
{ " CRI E61 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word7_sixth_alert_with_info_cri_mesage_word = {
" Word 7 - Sixth Alert With Info CRI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CRI E74 " , 4 , 0 } ,
{ " CRI E73 " , 4 , 0 } ,
{ " CRI E72 " , 4 , 0 } ,
{ " CRI E71 " , 4 , 0 } ,
{ " CRI E84 " , 4 , 0 } ,
{ " CRI E83 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word8_seventh_alert_with_info_cri_mesage_word = {
" Word 8 - Seventh Alert With Info CRI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CRI E82 " , 4 , 0 } ,
{ " CRI E81 " , 4 , 0 } ,
{ " NULL " , 8 , 0 } ,
{ " NULL " , 8 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word wordn_n_minus_1th_flash_with_info_word = {
" Word N - (N-1)th Flash With Info Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CHARACTER 1 " , 8 , 0 } ,
{ " CHARACTER 2 " , 8 , 0 } ,
{ " CHARACTER 3 " , 8 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word6_fith_flash_with_info_cri_message_word = {
" Word 6 - Fifth Flash With Info CRI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CRI E52 " , 4 , 0 } ,
{ " CRI E51 " , 4 , 0 } ,
{ " CRI E64 " , 4 , 0 } ,
{ " CRI E63 " , 4 , 0 } ,
{ " CRI E62 " , 4 , 0 } ,
{ " CRI E61 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word7_sixth_flash_with_info_cri_message_word = {
" Word 7 - Sixth Flash With Info CRI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CRI E74 " , 4 , 0 } ,
{ " CRI E73 " , 4 , 0 } ,
{ " CRI E72 " , 4 , 0 } ,
{ " CRI E71 " , 4 , 0 } ,
{ " CRI E84 " , 4 , 0 } ,
{ " CRI E83 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word8_seventh_flash_with_info_cri_message_word = {
" Word 8 - Seventh Flash With Info CRI Message Word " ,
{
{ " T1T2 " , 2 , 0 } ,
{ " RSVD " , 2 , 0 } ,
{ " CRI E82 " , 4 , 0 } ,
{ " CRI E81 " , 4 , 0 } ,
{ " NULL " , 8 , 0 } ,
{ " NULL " , 8 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_message_set fvc_words = {
" FVC Words " , 40 ,
{
& mobile_station_control_message_word1_a ,
& mobile_station_control_message_word1_b ,
& word2_digital_channel_assignment ,
& word2_digital_control_channel_information_word ,
& word2_base_station_challenge_order_confirmation ,
& word2_unique_challenge_order_word ,
& word2_first_ssd_update_order_word ,
& word2_first_alert_with_info_word ,
& word2_first_flash_with_info_word ,
& word3_second_ssd_update_oder_word ,
& word3_second_alert_with_info_word ,
& word3_second_alert_with_info_cri_message_word ,
& word3_second_alert_with_info_tci_message_word ,
& word3_second_flash_with_info_word ,
& word3_second_flash_with_info_cri_message_word ,
& word3_second_flash_with_info_tci_message_word ,
& word4_third_ssd_update_order_word ,
& word4_third_alert_with_info_word ,
& word4_third_alert_with_info_cri_message_word ,
& word4_third_alert_with_info_tci_message_word ,
& word4_third_flash_with_info_word ,
& word4_third_flash_with_info_cri_message_word ,
& word4_third_flash_with_info_tci_message_word ,
& word5_alert_with_info_word ,
& word5_alert_with_info_cri_message_word ,
& word5_alert_with_info_tci_message_word ,
& word5_flash_with_info_word ,
& word5_flash_with_info_cri_message_word ,
& word5_flash_with_info_tci_message_word ,
& wordn_n_minus_1th_alert_with_info_word ,
& word6_fifth_alert_with_info_cri_mesage_word ,
& word7_sixth_alert_with_info_cri_mesage_word ,
& word8_seventh_alert_with_info_cri_mesage_word ,
& wordn_n_minus_1th_flash_with_info_word ,
& word6_fith_flash_with_info_cri_message_word ,
& word7_sixth_flash_with_info_cri_message_word ,
& word8_seventh_flash_with_info_cri_message_word ,
NULL
}
} ;
/* RVC - Order Confirmation Message */
static struct def_word order_confirmation_message = {
" Order/Order Confirmation Message " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 2 , 0 } ,
{ " T " , 1 , 0 } ,
{ " LOCAL/MSG TYPE " , 5 , 0 } ,
{ " ORDQ " , 3 , 0 } ,
{ " ORDER " , 5 , 0 } ,
{ " RSVD " , 19 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
/* RVC - Called-Address Message */
static struct def_word word1_called_address = {
" Word 1 - First Word of the Called-Address " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 2 , 0 } ,
{ " T " , 1 , 0 } ,
{ " DIGIT 1 " , 4 , 0 } ,
{ " DIGIT 2 " , 4 , 0 } ,
{ " DIGIT 3 " , 4 , 0 } ,
{ " DIGIT 4 " , 4 , 0 } ,
{ " DIGIT 5 " , 4 , 0 } ,
{ " DIGIT 6 " , 4 , 0 } ,
{ " DIGIT 7 " , 4 , 0 } ,
{ " DIGIT 8 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word2_called_address = {
" Word 2 - Second Word of the Called-Address " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 2 , 0 } ,
{ " T " , 1 , 0 } ,
{ " DIGIT 9 " , 4 , 0 } ,
{ " DIGIT 10 " , 4 , 0 } ,
{ " DIGIT 11 " , 4 , 0 } ,
{ " DIGIT 12 " , 4 , 0 } ,
{ " DIGIT 13 " , 4 , 0 } ,
{ " DIGIT 14 " , 4 , 0 } ,
{ " DIGIT 15 " , 4 , 0 } ,
{ " DIGIT 16 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word3_called_address = {
" Word 3 - Third Word of the Called-Address " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 2 , 0 } ,
{ " T " , 1 , 0 } ,
{ " DIGIT 17 " , 4 , 0 } ,
{ " DIGIT 18 " , 4 , 0 } ,
{ " DIGIT 19 " , 4 , 0 } ,
{ " DIGIT 20 " , 4 , 0 } ,
{ " DIGIT 21 " , 4 , 0 } ,
{ " DIGIT 22 " , 4 , 0 } ,
{ " DIGIT 23 " , 4 , 0 } ,
{ " DIGIT 24 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word4_called_address = {
" Word 4 - Fourth Word of the Called-Address " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 2 , 0 } ,
{ " T " , 1 , 0 } ,
{ " DIGIT 25 " , 4 , 0 } ,
{ " DIGIT 26 " , 4 , 0 } ,
{ " DIGIT 27 " , 4 , 0 } ,
{ " DIGIT 28 " , 4 , 0 } ,
{ " DIGIT 29 " , 4 , 0 } ,
{ " DIGIT 30 " , 4 , 0 } ,
{ " DIGIT 31 " , 4 , 0 } ,
{ " DIGIT 32 " , 4 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
/* RVC - Serial Number Response Message */
static struct def_word word1_serial_number_response_message = {
" Word 1 of Serial Number Response Message " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 2 , 0 } ,
{ " T " , 1 , 0 } ,
{ " LOCAL/MSG TYPE " , 5 , 0 } ,
{ " ORDQ " , 3 , 0 } ,
{ " ORDER " , 5 , 0 } ,
{ " RSVD " , 19 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word2_serial_number_response_message = {
" Word 2 of Serial Number response message " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 2 , 0 } ,
{ " T " , 1 , 0 } ,
{ " ESN " , 32 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word page_response = {
" Page Response " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 2 , 0 } ,
{ " T " , 1 , 0 } ,
{ " LOCAL/MSG TYPE " , 5 , 0 } ,
{ " ORDQ " , 3 , 0 } ,
{ " ORDER " , 5 , 0 } ,
{ " RSVD " , 19 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word challenge_order_confirmation_message = {
" Unique Challenge Order Confirmation Message " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 2 , 0 } ,
{ " T " , 1 , 0 } ,
{ " LOCAL/MSG TYPE " , 5 , 0 } ,
{ " ORDQ " , 3 , 0 } ,
{ " ORDER " , 5 , 0 } ,
{ " AUTHU " , 18 , 0 } ,
{ " RSVD " , 1 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
/* RVC - Base Station Challenge Order Message */
static struct def_word word1_base_station_challenge_order_message = {
" Word 1 of Base Station Challenge Order Message " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 2 , 0 } ,
{ " T " , 1 , 0 } ,
{ " LOCAL/MSG TYPE " , 5 , 0 } ,
{ " ORDQ " , 3 , 0 } ,
{ " ORDER " , 5 , 0 } ,
{ " RSVD " , 19 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_word word2_base_station_challenge_order_message = {
" Word 2 of Base Station Challenge Order Message " ,
{
{ " F " , 1 , 0 } ,
{ " NAWC " , 2 , 0 } ,
{ " T " , 1 , 0 } ,
{ " RANDBS " , 32 , 0 } ,
{ " P " , 12 , 0 } ,
{ NULL , 0 , 0 }
}
} ;
static struct def_message_set rvc_words = {
" RVC Words " , 48 ,
{
& order_confirmation_message ,
& word1_called_address ,
& word2_called_address ,
& word3_called_address ,
& word4_called_address ,
& word1_serial_number_response_message ,
& word2_serial_number_response_message ,
& page_response ,
& challenge_order_confirmation_message ,
& word1_base_station_challenge_order_message ,
& word2_base_station_challenge_order_message ,
NULL
}
} ;
static struct def_message_set * amps_message_sets [ ] = {
& focc_words ,
& recc_words ,
& fvc_words ,
& rvc_words ,
NULL
} ;
static const char * amps_act [ 16 ] = {
" Reserved " ,
" Rescan paging channels " ,
" Registration increment " ,
" Location Area " ,
" Reserved " ,
" Reserved " ,
" New access channel set " ,
" Random Challenge A " ,
" Overload control " ,
" Access type parameters " ,
" Access attempt parameters " ,
" Random Challenge B " ,
" Reserved " ,
" Reserved " ,
" Local Control 1 " ,
" Local Control 2 " ,
} ;
static const char * ie_hex ( uint64_t value )
{
static char string [ 64 ] ;
sprintf ( string , " 0x% " PRIx64 , value ) ;
return string ;
}
static const char * ie_act ( uint64_t value )
{
return amps_act [ value & 0xf ] ;
}
static const char * ie_yes ( uint64_t value )
{
if ( value )
return " Yes " ;
return " No " ;
}
static const char * ie_bis ( uint64_t value )
{
if ( value )
return " Wait for Idle-Busy transition " ;
return " Ignore Idle-Busy after access " ;
}
static const char * ie_bscap ( uint64_t value )
{
switch ( value ) {
case 0 :
return " Reserved for backward compatibility " ;
case 1 :
return " ANSI TIA/EIA-553-A " ;
}
return " Reserved " ;
}
static const char * ie_bspc ( uint64_t value )
{
switch ( value ) {
case 0 :
return " Reserved for backward compatibility " ;
case 2 :
return " IS-91A or TIA/EIA-691 " ;
case 3 :
return " TIA/EIA-136-B " ;
case 4 :
return " IS-95B or TIA/EIA-95 " ;
}
return " Reserved " ;
}
static const char * ie_chan ( uint64_t value )
{
static char string [ 32 ] ;
if ( value = = 0 )
return " No channel " ;
2017-01-04 13:14:02 +00:00
sprintf ( string , " % " PRIu64 " = %.3f MHz " , value , amps_channel2freq ( value , 0 ) / 1e6 ) ;
2016-05-01 17:51:56 +00:00
return string ;
}
static const char * ie_cmac ( uint64_t value )
{
2017-08-27 18:50:37 +00:00
switch ( value ) {
case 0 :
if ( ! tacs )
2017-05-30 10:49:40 +00:00
return " 6 dbW (4 Watts) " ;
2017-08-27 18:50:37 +00:00
else
return " 10 dbW (10 Watts) " ;
case 1 :
return " 2 dbW (1.6 Watts) " ;
case 2 :
return " -2 dbW (630 Milliwatts) " ;
case 3 :
return " -6 dbW (250 Milliwatts) " ;
case 4 :
return " -10 dbW (100 Milliwatts) " ;
case 5 :
return " -14 dbW (40 Milliwatts) " ;
case 6 :
return " -18 dbW (16 Milliwatts) " ;
2016-05-01 17:51:56 +00:00
}
2017-08-27 18:50:37 +00:00
return " -22 dbW (6.3 Milliwatts) " ;
2016-05-01 17:51:56 +00:00
}
static const char * ie_cmax ( uint64_t value )
{
static char string [ 32 ] ;
sprintf ( string , " % " PRIu64 , value + 1 ) ;
return string ;
}
static const char * ie_n ( uint64_t value )
{
static char string [ 32 ] ;
sprintf ( string , " % " PRIu64 , value + 1 ) ;
return string ;
}
static const char * ie_dtx_support ( uint64_t value )
{
switch ( value ) {
case 0 :
return " DTX Not Supported " ;
case 2 :
return " DTX Supported up to 8 dB attenuation " ;
case 3 :
return " DTX Supported with no limit on attenuation " ;
}
return " Reserved " ;
}
static const char * ie_hyperband ( uint64_t value )
{
switch ( value ) {
case 0 :
return " 800 MHz " ;
case 1 :
return " 1900 MHz " ;
}
return " Reserved " ;
}
static const char * ie_enabled ( uint64_t value )
{
if ( value )
return " Enabled " ;
return " Disabled " ;
}
static const char * amps_ohd [ 8 ] = {
" Registration ID " ,
" Control-Filler " ,
" Control Channel Information " ,
" Reserved " ,
" Global action " ,
" Reserved " ,
" Word 1 of system parameter message " ,
" Word 2 of system parameter message " ,
} ;
static const char * ie_ohd ( uint64_t value )
{
return amps_ohd [ value & 0x7 ] ;
}
static const char * amps_t1t2 [ 4 ] = {
" Only Word 1 " ,
2017-06-17 10:11:07 +00:00
" First Word (FOCC) Next Word (FVC) " ,
" Next Word (FOCC) First Word (FVC) " ,
2016-05-01 17:51:56 +00:00
" Overhead Message " ,
} ;
static const char * ie_t1t2 ( uint64_t value )
{
return amps_t1t2 [ value & 0x3 ] ;
}
static const char * ie_digit ( uint64_t value )
{
static char string [ 32 ] ;
switch ( value ) {
case 0 :
return " NULL " ;
case 10 :
return " 0 " ;
case 11 :
return " * " ;
case 12 :
return " # " ;
case 13 :
return " + " ;
case 14 :
return " reserved 15 " ;
case 15 :
return " reserved 16 " ;
}
sprintf ( string , " % " PRIu64 , value ) ;
return string ;
}
static const char * ie_mscap ( uint64_t value )
{
switch ( value ) {
case 0 :
return " Reserved for backward compatibility " ;
case 1 :
return " TIA/EIA-553-A " ;
}
return " Reserved " ;
}
static const char * ie_mspc ( uint64_t value )
{
switch ( value ) {
case 0 :
return " Reserved for backward compatibility " ;
case 1 :
return " TIA/EIA-553-A " ;
case 2 :
return " IS-91A " ;
case 3 :
return " TIA/EIA-136-B " ;
case 4 :
return " IS-95B " ;
}
return " Reserved " ;
}
static const char * ie_service_code ( uint64_t value )
{
switch ( value ) {
case 4 :
return " Async Data " ;
case 5 :
return " G3 Fax " ;
case 6 :
return " Service Rejected " ;
case 8 :
return " Direct Async Data Service " ;
}
return " Reserved " ;
}
static const char * amps_scc [ 4 ] = {
" 5970 Hz " ,
" 6000 Hz " ,
" 6030 Hz " ,
2017-06-17 10:11:07 +00:00
" This word includes message " ,
2016-05-01 17:51:56 +00:00
} ;
static const char * ie_scc ( uint64_t value )
{
return amps_scc [ value & 0x3 ] ;
}
static const char * amps_acked_data [ 2 ] = {
" Acknowledged data, unacknowledged data, or both " ,
" Unacknowledged data only " ,
} ;
static const char * ie_acked_data ( uint64_t value )
{
return amps_acked_data [ value & 0x1 ] ;
}
static const char * ie_ascii ( uint64_t value )
{
static char string [ 32 ] ;
if ( value > = 32 & & value < = 126 )
sprintf ( string , " '%c' " , ( char ) value ) ;
else
sprintf ( string , " 0x%02x " , ( unsigned char ) value ) ;
return string ;
}
static const char * amps_crc [ 4 ] = {
" 16-bit CRC " ,
" 24-bit CRC " ,
" No CRC " ,
" Reserved " ,
} ;
static const char * ie_crc ( uint64_t value )
{
return amps_crc [ value & 0x3 ] ;
}
static const char * ie_data_part ( uint64_t value )
{
switch ( value ) {
case 0 :
return " See TIA/EIA-136-350 " ;
case 1 :
return " STU-II (Standard FSVS211) " ;
}
return " Reserved " ;
}
static const char * amps_mpci [ 4 ] = {
" indicates TIA/EIA-553 or IS-54A mobile station " ,
" indicates TIA/EIA-627 dual-mode mobile station " ,
" reserved (see TIA/EIA IS-95) " ,
" indicates EIATIA/EIA-136 dual-mode mobile station " ,
} ;
static const char * ie_mpci ( uint64_t value )
{
return amps_mpci [ value & 0x3 ] ;
}
static const char * amps_pi [ 4 ] = {
" Presentation Allowed " ,
" Presentation Restricted " ,
" Number Not Available " ,
" Reserved " ,
} ;
static const char * ie_pi ( uint64_t value )
{
return amps_pi [ value & 0x3 ] ;
}
static const char * ie_pm_d ( uint64_t value )
{
switch ( value ) {
case 0 :
return " No Data Privacy " ;
case 1 :
return " Data Privacy Algorithm A (ORYX) " ;
case 2 :
return " Data Privacy Algorithm B (SCEMA) " ;
}
return " Reserved " ;
}
static const char * amps_pvi [ 2 ] = {
" TIA/EIA 627 " ,
" TIA/EIA-136 " ,
} ;
static const char * ie_pvi ( uint64_t value )
{
return amps_pvi [ value & 0x1 ] ;
}
static const char * ie_rlp ( uint64_t value )
{
switch ( value ) {
case 0 :
return " RLP1 " ;
case 1 :
return " RLP2 " ;
}
return " Reserved " ;
}
static const char * amps_sap [ 2 ] = {
" SAP 0 only " ,
" SAP 0 and SAP 1 " ,
} ;
static const char * ie_sap ( uint64_t value )
{
return amps_sap [ value & 0x1 ] ;
}
static const char * ie_sbi ( uint64_t value )
{
switch ( value ) {
case 0 :
return " Transmit normal burst after cell to cell handoff " ;
case 1 :
return " Transmit normal burst after handoff within cell " ;
case 2 :
return " Transmit shortened burst after cell to cell handoff " ;
}
return " Reserved " ;
}
static const char * amps_ie_si [ 4 ] = {
" User-provided, not screened " ,
" User-provided, verified and passed " ,
" User-provided, verified and failed " ,
" Network-provided " ,
} ;
static const char * ie_si ( uint64_t value )
{
return amps_ie_si [ value & 0x3 ] ;
}
static const char * ie_signal ( uint64_t value )
{
static char string [ 256 ] ;
const char * pitch , * cadence ;
switch ( ( value > > 6 ) & 0x3 ) {
case 0 :
pitch = " Medium pitch " ;
break ;
case 1 :
pitch = " High pitch " ;
break ;
case 2 :
pitch = " Low pitch " ;
break ;
default :
pitch = " Reserved " ;
}
switch ( value & 0x3f ) {
case 0 :
cadence = " No Tone " ;
break ;
case 1 :
cadence = " Long " ;
break ;
case 2 :
cadence = " Short-Short " ;
break ;
case 3 :
cadence = " Short-Short-Long " ;
break ;
case 4 :
cadence = " Short-Short-2 " ;
break ;
case 5 :
cadence = " Short-Long-Short " ;
break ;
case 6 :
cadence = " Short-Short-Short-Short " ;
break ;
case 7 :
cadence = " PBX Long " ;
break ;
case 8 :
cadence = " PBX Short-Short " ;
break ;
case 9 :
cadence = " PBX Short-Short-Long " ;
break ;
case 10 :
cadence = " PBX Short-Long-Short " ;
break ;
case 11 :
cadence = " PBX Short-Short-Short-Short " ;
break ;
default :
cadence = " Reserved " ;
}
sprintf ( string , " Pitch=%s, Cadence=%s " , pitch , cadence ) ;
return string ;
}
static const char * ie_min1 ( uint64_t value )
{
return amps_min12number ( value ) ;
}
static const char * ie_min2 ( uint64_t value )
{
return amps_min22number ( value ) ;
}
static const char * ie_scm ( uint64_t value )
{
return amps_scm ( value ) ;
}
struct amps_ie_desc {
enum amps_ie ie ;
const char * name ;
const char * desc ;
const char * ( * decoder ) ( uint64_t value ) ;
} ;
struct amps_ie_desc amps_ie_desc [ ] = {
{ AMPS_IE_010111 , " 010111 " , " bit combination 23 " , NULL } ,
{ AMPS_IE_1 , " 1 " , " bit combination 1 " , NULL } ,
{ AMPS_IE_11 , " 11 " , " bit combination 3 " , NULL } ,
{ AMPS_IE_1111 , " 1111 " , " bit combination 15 " , NULL } ,
{ AMPS_IE_ACT , " ACT " , " Global action field " , ie_act } ,
2017-05-30 10:49:40 +00:00
{ AMPS_IE_AID1 , " AID1 " , " First part of the area identification field " , NULL } ,
2016-05-01 17:51:56 +00:00
{ AMPS_IE_AUTH , " AUTH " , " Support of authentication procedures described in TIA/EIA-136-510 " , ie_yes } ,
{ AMPS_IE_AUTHBS , " AUTHBS " , " Output response of the authentication algorithm initiated by the Base Station Challenge Order " , ie_hex } ,
{ AMPS_IE_AUTHR , " AUTHR " , " Output response of the authentication algorithm " , ie_hex } ,
{ AMPS_IE_AUTHU , " AUTHU " , " Output of the authentication algorithm when responsing to a Unique Challenge Order " , ie_hex } ,
{ AMPS_IE_Acked_Data , " Acked Data " , " Used to identidy the selected privacy mode for a data/fax call " , ie_acked_data } ,
{ AMPS_IE_Async_Data , " Async Data " , " Async Data is supported on the current Analog Control Channel " , ie_yes } ,
{ AMPS_IE_BIS , " BIS " , " Busy-Idle status field " , ie_bis } ,
{ AMPS_IE_BSCAP , " BSCAP " , " Base Station Core Analog Protocol field " , ie_bscap } ,
{ AMPS_IE_BSPC , " BSPC " , " Base Station Protocol Capability field " , ie_bspc } ,
{ AMPS_IE_CHAN , " CHAN " , " Channel number field " , ie_chan } ,
{ AMPS_IE_CHANPOS , " CHANPOS " , " Channel position field (relative to FIRSTCHA) " , NULL } ,
{ AMPS_IE_CHARACTER_1 , " CHARACTER 1 " , " ASCII Character " , ie_ascii } ,
{ AMPS_IE_CHARACTER_2 , " CHARACTER 2 " , " ASCII Character " , ie_ascii } ,
{ AMPS_IE_CHARACTER_3 , " CHARACTER 3 " , " ASCII Character " , ie_ascii } ,
{ AMPS_IE_CMAC , " CMAC " , " Control mobile attenuation field " , ie_cmac } ,
{ AMPS_IE_CMAX_1 , " CMAX-1 " , " CMAX is the number of access channels in the system " , ie_cmax } ,
{ AMPS_IE_COUNT , " COUNT " , " A modulo-64 count for authenticaiton " , NULL } ,
{ AMPS_IE_CPA , " CPA " , " Combined paging/access field " , ie_yes } ,
{ AMPS_IE_CPN_RL , " CPN_RL " , " Number of Characters in Calling Party Number " , NULL } ,
{ AMPS_IE_CRC , " CRC " , " Identifies used CRC " , ie_crc } ,
{ AMPS_IE_CRI_E11 , " CRI E11 " , " Charing Rate Indication Element 1 Digit 1 " , NULL } ,
{ AMPS_IE_CRI_E12 , " CRI E12 " , " Charing Rate Indication Element 1 Digit 2 " , NULL } ,
{ AMPS_IE_CRI_E13 , " CRI E13 " , " Charing Rate Indication Element 1 Digit 3 " , NULL } ,
{ AMPS_IE_CRI_E14 , " CRI E14 " , " Charing Rate Indication Element 1 Digit 4 " , NULL } ,
{ AMPS_IE_CRI_E21 , " CRI E21 " , " Charing Rate Indication Element 2 Digit 1 " , NULL } ,
{ AMPS_IE_CRI_E22 , " CRI E22 " , " Charing Rate Indication Element 2 Digit 2 " , NULL } ,
{ AMPS_IE_CRI_E23 , " CRI E23 " , " Charing Rate Indication Element 2 Digit 3 " , NULL } ,
{ AMPS_IE_CRI_E24 , " CRI E24 " , " Charing Rate Indication Element 2 Digit 4 " , NULL } ,
{ AMPS_IE_CRI_E31 , " CRI E31 " , " Charing Rate Indication Element 3 Digit 1 " , NULL } ,
{ AMPS_IE_CRI_E32 , " CRI E32 " , " Charing Rate Indication Element 3 Digit 2 " , NULL } ,
{ AMPS_IE_CRI_E33 , " CRI E33 " , " Charing Rate Indication Element 3 Digit 3 " , NULL } ,
{ AMPS_IE_CRI_E34 , " CRI E34 " , " Charing Rate Indication Element 3 Digit 4 " , NULL } ,
{ AMPS_IE_CRI_E41 , " CRI E41 " , " Charing Rate Indication Element 4 Digit 1 " , NULL } ,
{ AMPS_IE_CRI_E42 , " CRI E42 " , " Charing Rate Indication Element 4 Digit 2 " , NULL } ,
{ AMPS_IE_CRI_E43 , " CRI E43 " , " Charing Rate Indication Element 4 Digit 3 " , NULL } ,
{ AMPS_IE_CRI_E44 , " CRI E44 " , " Charing Rate Indication Element 4 Digit 4 " , NULL } ,
{ AMPS_IE_CRI_E51 , " CRI E51 " , " Charing Rate Indication Element 5 Digit 1 " , NULL } ,
{ AMPS_IE_CRI_E52 , " CRI E52 " , " Charing Rate Indication Element 5 Digit 2 " , NULL } ,
{ AMPS_IE_CRI_E53 , " CRI E53 " , " Charing Rate Indication Element 5 Digit 3 " , NULL } ,
{ AMPS_IE_CRI_E54 , " CRI E54 " , " Charing Rate Indication Element 5 Digit 4 " , NULL } ,
{ AMPS_IE_CRI_E61 , " CRI E61 " , " Charing Rate Indication Element 6 Digit 1 " , NULL } ,
{ AMPS_IE_CRI_E62 , " CRI E62 " , " Charing Rate Indication Element 6 Digit 2 " , NULL } ,
{ AMPS_IE_CRI_E63 , " CRI E63 " , " Charing Rate Indication Element 6 Digit 3 " , NULL } ,
{ AMPS_IE_CRI_E64 , " CRI E64 " , " Charing Rate Indication Element 6 Digit 4 " , NULL } ,
{ AMPS_IE_CRI_E71 , " CRI E71 " , " Charing Rate Indication Element 7 Digit 1 " , NULL } ,
{ AMPS_IE_CRI_E72 , " CRI E72 " , " Charing Rate Indication Element 7 Digit 2 " , NULL } ,
{ AMPS_IE_CRI_E73 , " CRI E73 " , " Charing Rate Indication Element 7 Digit 3 " , NULL } ,
{ AMPS_IE_CRI_E74 , " CRI E74 " , " Charing Rate Indication Element 7 Digit 4 " , NULL } ,
{ AMPS_IE_CRI_E81 , " CRI E81 " , " Charing Rate Indication Element 8 Digit 1 " , NULL } ,
{ AMPS_IE_CRI_E82 , " CRI E82 " , " Charing Rate Indication Element 8 Digit 2 " , NULL } ,
{ AMPS_IE_CRI_E83 , " CRI E83 " , " Charing Rate Indication Element 8 Digit 3 " , NULL } ,
{ AMPS_IE_CRI_E84 , " CRI E84 " , " Charing Rate Indication Element 8 Digit 4 " , NULL } ,
{ AMPS_IE_DCC , " DCC " , " Digital color code field " , NULL } ,
{ AMPS_IE_DIGIT_1 , " DIGIT 1 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_10 , " DIGIT 10 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_11 , " DIGIT 11 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_12 , " DIGIT 12 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_13 , " DIGIT 13 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_14 , " DIGIT 14 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_15 , " DIGIT 15 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_16 , " DIGIT 16 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_17 , " DIGIT 17 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_18 , " DIGIT 18 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_19 , " DIGIT 19 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_2 , " DIGIT 2 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_20 , " DIGIT 20 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_21 , " DIGIT 21 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_22 , " DIGIT 22 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_23 , " DIGIT 23 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_24 , " DIGIT 24 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_25 , " DIGIT 25 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_26 , " DIGIT 26 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_27 , " DIGIT 27 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_28 , " DIGIT 28 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_29 , " DIGIT 29 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_3 , " DIGIT 3 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_30 , " DIGIT 30 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_31 , " DIGIT 31 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_32 , " DIGIT 32 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_4 , " DIGIT 4 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_5 , " DIGIT 5 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_6 , " DIGIT 6 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_7 , " DIGIT 7 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_8 , " DIGIT 8 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DIGIT_9 , " DIGIT 9 " , " Digit field " , ie_digit } ,
{ AMPS_IE_DMAC , " DMAC " , " Digital mobile attenuation code field " , ie_cmac } ,
{ AMPS_IE_DTX , " DTX " , " Discontinuous-Transmission field " , ie_yes } ,
{ AMPS_IE_DTX_Support , " DTX Support " , " Indicates the nature of DTX supported on an analog voice " , ie_dtx_support } ,
2019-07-15 19:14:52 +00:00
{ AMPS_IE_DVCC , " DVCC " , " Digital Verification Color Code " , NULL } ,
2016-05-01 17:51:56 +00:00
{ AMPS_IE_Data_Part , " Data Part " , " Identifies the Data Port associated with a data/fax call " , ie_data_part } ,
{ AMPS_IE_Data_Privacy , " Data Privacy " , " This field indicates whether or not Data Privacy is supported " , ie_yes } ,
{ AMPS_IE_E , " E " , " Extended address field " , ie_yes } ,
{ AMPS_IE_EC , " EC " , " Extended Protocol Reverse Channel " , ie_yes } ,
{ AMPS_IE_EF , " EF " , " Extended Protocol Forward Channel Indicator " , ie_yes } ,
{ AMPS_IE_END , " END " , " End indication field " , ie_yes } ,
{ AMPS_IE_EP , " EP " , " Extended Protocol Capability Indicator " , ie_yes } ,
{ AMPS_IE_ER , " ER " , " Extended Protocol Reverse Channel " , ie_yes } ,
2017-06-17 10:11:07 +00:00
{ AMPS_IE_ESN , " ESN " , " Electronic Serial Number field " , ie_hex } ,
2016-05-01 17:51:56 +00:00
{ AMPS_IE_F , " F " , " First word indication Field " , ie_yes } ,
{ AMPS_IE_G3_Fax , " G3 Fax " , " This field indicates whether or not G3 Fax is supported " , ie_yes } ,
{ AMPS_IE_HDVCC , " HDVCC " , " Half Digital Verification Color Code " , NULL } ,
{ AMPS_IE_Hyperband , " Hyperband " , " Designates Hyperband associated with the Digital Control Channel specified by the CHAN field " , ie_hyperband } ,
{ AMPS_IE_LOCAID , " LOCAID " , " Location area identity field " , NULL } ,
{ AMPS_IE_LOCAL_CONTROL , " LOCAL CONTROL " , " May be set to any bit pattern " , NULL } ,
{ AMPS_IE_LOCAL_MSG_TYPE , " LOCAL/MSG TYPE " , " Message Type field " , NULL } ,
{ AMPS_IE_LREG , " LREG " , " Location area ID registration status field " , ie_enabled } ,
{ AMPS_IE_LT , " LT " , " Last-try code field " , ie_yes } ,
{ AMPS_IE_MAXBUSY_OTHER , " MAXBUSY-OTHER " , " Maximum busy occurrences field (other accesses) " , NULL } ,
{ AMPS_IE_MAXBUSY_PGR , " MAXBUSY-PGR " , " Maximum busy occurrences field (page response) " , NULL } ,
{ AMPS_IE_MAXSZTR_OTHER , " MAXSZTR-OTHER " , " Maximum seizure tries field (other accesses) " , NULL } ,
{ AMPS_IE_MAXSZTR_PGR , " MAXSZTR-PGR " , " Maximum seizure tries field (page response) " , NULL } ,
{ AMPS_IE_MEM , " MEM " , " Message Encryption Mode " , ie_yes } ,
{ AMPS_IE_MIN1 , " MIN1 " , " First part of the mobile identification number field " , ie_min1 } ,
{ AMPS_IE_MIN2 , " MIN2 " , " Second part of the mobile identification number field " , ie_min2 } ,
{ AMPS_IE_MPCI , " MPCI " , " Mobile station Protocol Indicator " , ie_mpci } ,
{ AMPS_IE_MSCAP , " MSCAP " , " Mobile Station Core Analog Protocol field " , ie_mscap } ,
{ AMPS_IE_MSPC , " MSPC " , " Mobile Station Protocol Capability field " , ie_mspc } ,
{ AMPS_IE_N_1 , " N-1 " , " N is the number of paging channels in the system " , ie_n } ,
{ AMPS_IE_NAWC , " NAWC " , " Number of additional words coming field " , NULL } ,
{ AMPS_IE_NEWACC , " NEWACC " , " New access channel starting point field " , ie_chan } ,
{ AMPS_IE_NULL , " NULL " , " Null character " , NULL } ,
{ AMPS_IE_OHD , " OHD " , " Overhead Message Type field " , ie_ohd } ,
{ AMPS_IE_OLC_0 , " OLC 0 " , " Overload class field 0 " , NULL } ,
{ AMPS_IE_OLC_1 , " OLC 1 " , " Overload class field 1 " , NULL } ,
{ AMPS_IE_OLC_10 , " OLC 10 " , " Overload class field 10 " , NULL } ,
{ AMPS_IE_OLC_11 , " OLC 11 " , " Overload class field 11 " , NULL } ,
{ AMPS_IE_OLC_12 , " OLC 12 " , " Overload class field 12 " , NULL } ,
{ AMPS_IE_OLC_13 , " OLC 13 " , " Overload class field 13 " , NULL } ,
{ AMPS_IE_OLC_14 , " OLC 14 " , " Overload class field 14 " , NULL } ,
{ AMPS_IE_OLC_15 , " OLC 15 " , " Overload class field 15 " , NULL } ,
{ AMPS_IE_OLC_2 , " OLC 2 " , " Overload class field 2 " , NULL } ,
{ AMPS_IE_OLC_3 , " OLC 3 " , " Overload class field 3 " , NULL } ,
{ AMPS_IE_OLC_4 , " OLC 4 " , " Overload class field 4 " , NULL } ,
{ AMPS_IE_OLC_5 , " OLC 5 " , " Overload class field 5 " , NULL } ,
{ AMPS_IE_OLC_6 , " OLC 6 " , " Overload class field 6 " , NULL } ,
{ AMPS_IE_OLC_7 , " OLC 7 " , " Overload class field 7 " , NULL } ,
{ AMPS_IE_OLC_8 , " OLC 8 " , " Overload class field 8 " , NULL } ,
{ AMPS_IE_OLC_9 , " OLC 9 " , " Overload class field 9 " , NULL } ,
{ AMPS_IE_ORDER , " ORDER " , " Order field " , NULL } ,
{ AMPS_IE_ORDQ , " ORDQ " , " Order qualifier field " , NULL } ,
{ AMPS_IE_P , " P " , " Parity field " , NULL } ,
{ AMPS_IE_PCI , " PCI " , " Set to 1 if Control Channel can assign digital traffic channels " , ie_yes } ,
{ AMPS_IE_PCI_HOME , " PCI_HOME " , " Home Protocol Capability Indicator " , ie_yes } ,
{ AMPS_IE_PCI_ROAM , " PCI_ROAM " , " Roam Protocol Capability Indicator " , ie_yes } ,
2016-06-19 09:03:59 +00:00
{ AMPS_IE_PDREG , " PDREG " , " Power Down Registration status field " , ie_enabled } ,
2016-05-01 17:51:56 +00:00
{ AMPS_IE_PI , " PI " , " Presentation Indicator " , ie_pi } ,
{ AMPS_IE_PM , " PM " , " Privacy Mode indicator " , ie_yes } ,
{ AMPS_IE_PM_D , " PM_D " , " Privacy Mode indicator for Fax/Data " , ie_pm_d } ,
{ AMPS_IE_PSCC , " PSCC " , " Present SAT color code " , ie_scc } ,
2016-06-19 09:03:59 +00:00
{ AMPS_IE_PUREG , " PUREG " , " Power Up Registration status field " , ie_enabled } ,
2016-05-01 17:51:56 +00:00
{ AMPS_IE_PVI , " PVI " , " Protocol Version Indicator " , ie_pvi } ,
{ AMPS_IE_RAND1_A , " RAND1_A " , " The 16 most significant bits of the 32-bit RAND variable stored by a mobile station for use in the authentication process " , ie_hex } ,
{ AMPS_IE_RAND1_B , " RAND1_B " , " The 16 least significant bits of the 32-bit RAND variable stored by a mobile station for use in the authentication process " , ie_hex } ,
{ AMPS_IE_RANDBS , " RANDBS " , " Random number used in the SSD Update procedure " , ie_hex } ,
{ AMPS_IE_RANDC , " RANDC " , " Confirm the last RAND received by the mobile station " , ie_hex } ,
{ AMPS_IE_RANDSSD_1 , " RANDSSD_1 " , " The most significant 24 bits of the random number issued by the base station in the SSD Update Order " , ie_hex } ,
{ AMPS_IE_RANDSSD_2 , " RANDSSD_2 " , " The subsequent 24 bits (following RANDSSD_1) of the random number issued by the base station in the SSD Update Order " , ie_hex } ,
{ AMPS_IE_RANDSSD_3 , " RANDSSD_3 " , " The least significant 8 bits of the random number issued by the base station in the SSD Update Order " , ie_hex } ,
{ AMPS_IE_RANDU , " RANDU " , " The 24-bit random number issued by the base station in the Unique Challenge Order " , ie_hex } ,
{ AMPS_IE_RCF , " RCF " , " Read-control-filler field " , ie_yes } ,
{ AMPS_IE_REGH , " REGH " , " Registration field for home stations " , ie_yes } ,
{ AMPS_IE_REGID , " REGID " , " Registration ID field " , NULL } ,
{ AMPS_IE_REGINCR , " REGINCR " , " Registration increment field " , NULL } ,
{ AMPS_IE_REGR , " REGR " , " Registration field for roaming stations " , ie_yes } ,
{ AMPS_IE_RLP , " RLP " , " Identifies the layer 2 radio link protocol used for a data/fax call " , ie_rlp } ,
{ AMPS_IE_RL_W , " RL_W " , " The remaining length, in `Words' of the Alert With Info or Flash With Info order " , NULL } ,
{ AMPS_IE_RSVD , " RSVD " , " Reserved for future use " , NULL } ,
{ AMPS_IE_S , " S " , " Serial number field " , ie_yes } ,
{ AMPS_IE_SAP , " SAP " , " Service Access Point(s) used for data/fax call " , ie_sap } ,
{ AMPS_IE_SBI , " SBI " , " Short Burst Indication " , ie_sbi } ,
{ AMPS_IE_SCC , " SCC " , " SAT color code " , ie_scc } ,
{ AMPS_IE_SCM , " SCM " , " The station class mark field " , ie_scm } ,
{ AMPS_IE_SDCC1 , " SDCC1 " , " Supplementary Digital Color Codes " , NULL } ,
{ AMPS_IE_SDCC2 , " SDCC2 " , " Supplementary Digital Color Codes " , NULL } ,
{ AMPS_IE_SI , " SI " , " Screening Indicator " , ie_si } ,
{ AMPS_IE_SID1 , " SID1 " , " First part of the system identification field " , NULL } ,
{ AMPS_IE_SIGNAL , " SIGNAL " , " An 8-bit IE to cause MS to generate tones " , ie_signal } ,
{ AMPS_IE_Service_Code , " Service Code " , " Service Indicator " , ie_service_code } ,
{ AMPS_IE_T , " T " , " T field. 1 = Orig/Order 0 = (paging) response " , NULL } ,
{ AMPS_IE_T1T2 , " T1T2 " , " Type field " , ie_t1t2 } ,
{ AMPS_IE_TA , " TA " , " Time Alignment Offset " , NULL } ,
{ AMPS_IE_TCI1 , " TCI1 " , " Total Charing component " , NULL } ,
{ AMPS_IE_TCI21 , " TCI21 " , " Total Charing component " , NULL } ,
{ AMPS_IE_TCI22 , " TCI22 " , " Total Charing component " , NULL } ,
{ AMPS_IE_TCI23 , " TCI23 " , " Total Charing component " , NULL } ,
{ AMPS_IE_TCI24 , " TCI24 " , " Total Charing component " , NULL } ,
{ AMPS_IE_TCI31 , " TCI31 " , " Total Charing component " , NULL } ,
{ AMPS_IE_TCI32 , " TCI32 " , " Total Charing component " , NULL } ,
{ AMPS_IE_TCI33 , " TCI33 " , " Total Charing component " , NULL } ,
{ AMPS_IE_TCI34 , " TCI34 " , " Total Charing component " , NULL } ,
{ AMPS_IE_TCI41 , " TCI41 " , " Total Charing component " , NULL } ,
{ AMPS_IE_TCI42 , " TCI42 " , " Total Charing component " , NULL } ,
{ AMPS_IE_TCI43 , " TCI43 " , " Total Charing component " , NULL } ,
{ AMPS_IE_TCI44 , " TCI44 " , " Total Charing component " , NULL } ,
{ AMPS_IE_TCI5 , " TCI5 " , " Total Charing component " , NULL } ,
{ AMPS_IE_VMAC , " VMAC " , " Voice mobile attenuation code field " , ie_cmac } ,
{ AMPS_IE_WFOM , " WFOM " , " Wait-for-overhead-message field " , ie_yes } ,
2016-10-07 06:55:18 +00:00
{ AMPS_IE_NUM , NULL , NULL , NULL }
2016-05-01 17:51:56 +00:00
} ;
static int ie_desc_max_len ;
/* decode 7 bit sequence to DCC code
* return - 1 if failed */
2016-06-19 09:03:59 +00:00
static int8_t dcc_decode [ 128 ] ;
2016-05-01 17:51:56 +00:00
/* encode DCC code to 7 bit sequence */
static uint8_t dcc_encode [ 4 ] = {
0x00 , 0x1f , 0x63 , 0x7c
} ;
struct amps_table4_def {
const char * order ;
const char * ordq ;
const char * msg_type ;
const char * function ;
} amps_table4_def [ ] = {
{ " 00001 " , " 000 " , " 00000 " , " Alert " } ,
{ " 00001 " , " 001 " , " 00000 " , " Abbreviated Alert " } ,
{ " 10001 " , " 000 " , " 00000 " , " Alert With Info " } ,
{ " 10001 " , " 001 " , " 00000 " , " Alert with Info CRI Message " } ,
{ " 10001 " , " 010 " , " 00000 " , " Alert with Info TCI Message " } ,
{ " 10010 " , " 000 " , " 00000 " , " Flash With Info " } ,
{ " 10010 " , " 001 " , " 00000 " , " Flash with Info CRI Message " } ,
{ " 10010 " , " 010 " , " 00000 " , " Flash with Info TCI Message " } ,
{ " 00011 " , " 000 " , " 00000 " , " Release " } ,
{ " 00011 " , " 010 " , " 00000 " , " Release with Digital Control Channel Information " } ,
{ " 00011 " , " 011 " , " 00000 " , " Release Complete " } ,
{ " 00100 " , " 000 " , " 00000 " , " Reorder " } ,
{ " 00101 " , " 000 " , " XXXXX " , " Voice Message Waiting (Message Type field indicates number of messages, 11111 = unknown number of messages waiting) " } ,
{ " 00101 " , " 001 " , " XXXXX " , " SMS Message Waiting (Message Type field indicates number of messages, 11111 = unknown number of messages waiting) " } ,
{ " 00101 " , " 010 " , " XXXXX " , " G3-Fax Message Waiting (Message Type field indicates number of messages, 11111 = unknown number of messages waiting) " } ,
{ " 00110 " , " 000 " , " 00000 " , " Stop Alert " } ,
{ " 00111 " , " 000 " , " 00000 " , " Audit " } ,
{ " 01000 " , " 000 " , " 00000 " , " Send Called-address " } ,
{ " 01001 " , " 000 " , " 00000 " , " Intercept " } ,
{ " 01010 " , " 000 " , " 00000 " , " Maintenance " } ,
{ " 01011 " , " 000 " , " 00000 " , " Change Power to Power Level 0 (see TIA/EIA-136-270) " } ,
{ " 01011 " , " 001 " , " 00000 " , " Change Power to Power Level 1 " } ,
{ " 01011 " , " 010 " , " 00000 " , " Change Power to Power Level 2 " } ,
{ " 01011 " , " 011 " , " 00000 " , " Change Power to Power Level 3 " } ,
{ " 01011 " , " 100 " , " 00000 " , " Change Power to Power Level 4 " } ,
{ " 01011 " , " 101 " , " 00000 " , " Change Power to Power Level 5 " } ,
{ " 01011 " , " 110 " , " 00000 " , " Change Power to Power Level 6 " } ,
{ " 01011 " , " 111 " , " 00000 " , " Change Power to Power Level 7 " } ,
{ " 01100 " , " 000 " , " 00000 " , " Directed Retry - not last try " } ,
{ " 01100 " , " 000 " , " 00001 " , " Directed Retry to Primary Dedicated Control Channels - analog channels only, Authentication disabled, not last try " } ,
{ " 01100 " , " 000 " , " 00010 " , " Directed Retry to Primary Dedicated Control Channels - analog channels only, Authentication enabled, not last try " } ,
{ " 01100 " , " 001 " , " 00000 " , " Directed Retry - last try " } ,
{ " 01100 " , " 001 " , " 00001 " , " Directed Retry to Primary Dedicated Control Channels - analog channels only, Authentication disabled, last try " } ,
{ " 01111 " , " 001 " , " 00000 " , " Serial Number Request / Response " } ,
{ " 01100 " , " 001 " , " 00010 " , " Directed Retry to Primary Dedicated Control Channels - analog channels only, Authentication enabled, last try " } ,
{ " 01101 " , " 010 " , " 00000 " , " Autonomous Registration - Do not make whereabouts known, Authentication Word C not included " } ,
{ " 01101 " , " 011 " , " 00000 " , " Autonomous Registration - Make whereabouts known, Authentication Word C not included " } ,
{ " 01101 " , " 011 " , " 00001 " , " Autonomous Registration - Power Down, Authentication Word C not included " } ,
{ " 11000 " , " 010 " , " 00000 " , " Autonomous Registration - Do not make whereabouts known, Authentication Word C included " } ,
{ " 11000 " , " 011 " , " 00000 " , " Autonomous Registration - Make whereabouts known, Authentication Word C included " } ,
{ " 11000 " , " 011 " , " 00001 " , " Autonomous Registration - Power Down, Authentication Word C included " } ,
{ " 11010 " , " 100 " , " 00000 " , " PCI Query (report) Order/Order Confirmation - Authentication Word C not included " } ,
{ " 11010 " , " 100 " , " 00001 " , " PCI Query (report) Order/Order Confirmation - Authentication Word C included " } ,
{ " 11110 " , " 000 " , " XXXXX " , " local control " } ,
/* (Base station initiated messages only - Page and Call Mode Ack messages) */
{ " 00000 " , " 000 " , " 00000 " , " Page Message (Voice Service) " } ,
{ " 00000 " , " 000 " , " 00001 " , " Page Message (Async Data) " } ,
{ " 00000 " , " 000 " , " 00010 " , " Page Message (Group 3 Fax) " } ,
{ " 10000 " , " 000 " , " XXXX0 " , " Call Mode Ack: Analog Voice channel permissible " } ,
{ " 10000 " , " 000 " , " XXXX1 " , " Call Mode Ack: Analog Voice channel not permissible " } ,
{ " 10000 " , " 000 " , " XXX0X " , " Call Mode Ack: Full-rate digital traffic channel not permissible (VSELP) " } ,
{ " 10000 " , " 000 " , " XXX1X " , " Call Mode Ack: Full -rate digital traffic channel permissible, voice privacy off (VSELP) " } ,
{ " 10000 " , " 100 " , " XXX1X " , " Call Mode Ack: Full -rate digital traffic channel permissible, voice privacy on (VSELP) " } ,
{ " 10000 " , " 000 " , " XX0XX " , " Call Mode Ack: Half-rate digital traffic channel not permissible " } ,
{ " 10000 " , " 000 " , " XX1XX " , " Call Mode Ack: Half-rate digital traffic channel permissible, voice privacy off " } ,
{ " 10000 " , " 100 " , " XX1XX " , " Call Mode Ack: Half-rate digital traffic channel permissible, voice privacy on " } ,
{ " 10000 " , " 000 " , " X0XXX " , " Call Mode Ack: Other DQPSK channel not permissible " } ,
{ " 10000 " , " 000 " , " X1XXX " , " Call Mode Ack: Other DQPSK channel permissible " } ,
{ " 10000 " , " 000 " , " 0XXXX " , " Call Mode Ack: Other voice coding not permissible (see TIA/EIA-136-410) " } ,
{ " 10000 " , " 000 " , " 1XXXX " , " Call Mode Ack: Other voice coding permissible (see TIA/EIA-136-410), voice privacy off " } ,
{ " 10000 " , " 100 " , " 1XXXX " , " Call Mode Ack: Other voice coding permissible (see TIA/EIA-136-410), voice privacy on " } ,
{ " 10000 " , " 001 " , " XXXXX " , " Call Mode Ack: Extended modulation and framing permissible " } ,
/* (Mobile station initiated messages only - Origination and Page Response messages) */
{ " 00000 " , " 000 " , " XXXX0 " , " Analog Voice channel acceptable, Authentication Word C not included " } ,
{ " 00000 " , " 000 " , " XXXX1 " , " Analog Voice channel not acceptable, Authentication Word C not included " } ,
{ " 00000 " , " 000 " , " XXX0X " , " Full-rate digital traffic channel (VSELP) not acceptable, Authentication Word C not included " } ,
{ " 00000 " , " 000 " , " XXX1X " , " Full-rate digital traffic channel (VSELP) acceptable (voice privacy off), Authentication Word C not included " } ,
{ " 00000 " , " 100 " , " XXX1X " , " Full-rate digital traffic channel (VSELP) acceptable (voice privacy on), Authentication Word C not included " } ,
{ " 00000 " , " 000 " , " XX0XX " , " Half-rate digital traffic channel not acceptable, Authentication Word C not included " } ,
{ " 00000 " , " 000 " , " XX1XX " , " Half-rate digital traffic channel acceptable (voice privacy off), Authentication Word C not included " } ,
{ " 00000 " , " 100 " , " XX1XX " , " Half-rate digital traffic channel acceptable (voice privacy on), Authentication Word C not included " } ,
{ " 00000 " , " 000 " , " X0XXX " , " Other DQPSK channel not acceptable, Authentication Word C not included " } ,
{ " 00000 " , " 000 " , " X1XXX " , " Other DQPSK channel acceptable, Authentication Word C not included " } ,
{ " 00000 " , " 000 " , " 0XXXX " , " Other voice coding not acceptable, (see TIA/EIA-136-410), Authentication Word C not included " } ,
{ " 00000 " , " 000 " , " 1XXXX " , " Other voice coding acceptable (see TIA/EIA-136-410), (voice privacy off), Authentication Word C not included " } ,
{ " 00000 " , " 100 " , " 1XXXX " , " Other voice coding acceptable (see TIA/EIA-136-410), (voice privacy on), Authentication Word C not included " } ,
{ " 00000 " , " 001 " , " XXXXX " , " Extended Modulation and Framing, Authentication Word C not included " } ,
{ " 00010 " , " 000 " , " XXXX0 " , " Analog Voice Channel (AVC) acceptable, Authentication Word C included " } ,
{ " 00010 " , " 000 " , " XXXX1 " , " AVC not acceptable, Auth. Word C included " } ,
{ " 00010 " , " 000 " , " XXX0X " , " Full-rate digital traffic channel (VSELP) not acceptable, Authentication Word C included " } ,
{ " 00010 " , " 000 " , " XXX1X " , " Full-rate digital traffic channel (VSELP) acceptable (voice privacy off), Authentication Word C included " } ,
{ " 00010 " , " 100 " , " XXX1X " , " Full-rate digital traffic channel (VSELP) acceptable (voice privacy on), Authentication Word C included " } ,
{ " 00010 " , " 000 " , " XX0XX " , " Half-rate digital traffic channel not acceptable, Authentication Word C included " } ,
{ " 00010 " , " 000 " , " XX1XX " , " Half-rate digital traffic channel acceptable (voice privacy off), Authentication Word C included " } ,
{ " 00010 " , " 100 " , " XX1XX " , " Half-rate digital traffic channel acceptable (voice privacy on), Authentication Word C included " } ,
/* (Mobile station initiated messages only - Origination and Page Response messages) */
{ " 00010 " , " 000 " , " X0XXX " , " Other DQPSK channel not acceptable, Authentication Word C included " } ,
{ " 00010 " , " 000 " , " X1XXX " , " Other DQPSK channel acceptable, Authentication Word C included " } ,
{ " 00010 " , " 000 " , " 0XXXX " , " Other voice coding not acceptable, (see TIA/EIA-136-410), Authentication Word C included " } ,
{ " 00010 " , " 000 " , " 1XXXX " , " Other voice coding acceptable (see TIA/EIA-136-410), (voice privacy off), Authentication Word C included " } ,
{ " 00010 " , " 100 " , " 1XXXX " , " Other voice coding acceptable (see TIA/EIA-136-410), (voice privacy on), Authentication Word C included " } ,
{ " 00010 " , " 001 " , " XXXXX " , " Extended Modulation and Framing, Authentication Word C included " } ,
/* (Mobile station initiated messages only - Origination with Service and Page Response with Service messages) */
{ " 11101 " , " 000 " , " XXX0X " , " Full-rate DTC not acceptable, Authentication Word C not included " } ,
{ " 11101 " , " 000 " , " XXX1X " , " Full-rate DTC acceptable, Authentication Word C not included " } ,
{ " 11101 " , " 000 " , " XX0XX " , " Half-rate DTC not acceptable, Authentication Word C not included " } ,
{ " 11101 " , " 000 " , " XX1XX " , " Half-rate DTC acceptable, Authentication Word C not included " } ,
{ " 11101 " , " 000 " , " X0XXX " , " Other DQPSK channel not acceptable, Authentication Word C not included " } ,
{ " 11101 " , " 000 " , " X1XXX " , " Other DQPSK channel acceptable, Authentication Word C not included " } ,
{ " 11101 " , " 000 " , " 0XXXX " , " Other voice coding not acceptable, Authentication Word C not included " } ,
{ " 11101 " , " 000 " , " 1XXXX " , " Other voice coding acceptable, Authentication Word C not included " } ,
{ " 11101 " , " 001 " , " XXXXX " , " Extended Modulation and Framing, Authentication Word C not included " } ,
{ " 11101 " , " 010 " , " XXX0X " , " Double Full-Rate or Full-Rate Digital Traffic Channel not acceptable, Authentication Word C not included " } ,
{ " 11101 " , " 010 " , " XXX1X " , " Double Full-Rate or Full-Rate Digital Traffic Channel acceptable - Double-Rate Preferred, Authentication Word C not included " } ,
{ " 11101 " , " 010 " , " XX0XX " , " Triple Full-Rate, Double Full-Rate, or Full-Rate Digital Traffic Channel not acceptable, Authentication Word C not included " } ,
{ " 11101 " , " 010 " , " XX1XX " , " Triple Full-Rate, Double Full-Rate, or Full-Rate Digital Traffic Channel acceptable - Triple Rate Preferred, Authentication Word C not included " } ,
{ " 11101 " , " 010 " , " X0XXX " , " Double Full-Rate Digital Traffic Channel not acceptable, Authentication Word C not included " } ,
{ " 11101 " , " 010 " , " X1XXX " , " Double Full-Rate Digital Traffic Channel acceptable, Authentication Word C not included " } ,
{ " 11101 " , " 010 " , " 0XXXX " , " Triple Full-Rate Digital Traffic Channel not acceptable, Authentication Word C not included " } ,
{ " 11101 " , " 010 " , " 1XXXX " , " Triple Full-Rate Digital Traffic Channel acceptable, Authentication Word C not included " } ,
{ " 11111 " , " 000 " , " XXX0X " , " Full-rate DTC not acceptable, Authentication Word C included " } ,
/* (Mobile station initiated messages only - Origination with Service and Page Response with Service messages) */
{ " 11111 " , " 000 " , " XXX1X " , " Full-rate DTC acceptable, Authentication Word C included " } ,
{ " 11111 " , " 000 " , " XX0XX " , " Half-rate DTC not acceptable, Authentication Word C included " } ,
{ " 11111 " , " 000 " , " XX1XX " , " Half-rate DTC acceptable, Authentication Word C included " } ,
{ " 11111 " , " 000 " , " X0XXX " , " Other DQPSK channel not acceptable, Authentication Word C included " } ,
{ " 11111 " , " 000 " , " X1XXX " , " Other DQPSK channel acceptable, Authentication Word C included " } ,
{ " 11111 " , " 000 " , " 0XXXX " , " Other voice coding not acceptable, Authentication Word C included " } ,
{ " 11111 " , " 000 " , " 1XXXX " , " Other voice coding acceptable, Authentication Word C included " } ,
{ " 11111 " , " 001 " , " XXXXX " , " Extended Modulation and Framing, Authentication Word C included " } ,
{ " 11111 " , " 010 " , " XXX0X " , " Double Full-Rate or Full-Rate Digital Traffic Channel not acceptable, Authentication Word C included " } ,
{ " 11111 " , " 010 " , " XXX1X " , " Double Full-Rate Digital Traffic Channel acceptable - Double-Rate Preferred, Authentication Word C included " } ,
{ " 11111 " , " 010 " , " XX0XX " , " Triple Full-Rate, Double Full-Rate, or Full-Rate Digital Traffic Channel not acceptable, Authentication Word C included " } ,
{ " 11111 " , " 010 " , " XX1XX " , " Triple Full-Rate, Double Full-Rate, or Full-Rate Digital Traffic Channel acceptable - Triple Rate Preferred, Authentication Word C included " } ,
{ " 11111 " , " 010 " , " X0XXX " , " Double Full-Rate Digital Traffic Channel not acceptable, Authentication Word C included " } ,
{ " 11111 " , " 010 " , " X1XXX " , " Double Full-Rate Digital Traffic Channel acceptable, Authentication Word C included " } ,
{ " 11111 " , " 010 " , " 0XXXX " , " Triple Full-Rate Digital Traffic Channel not acceptable, Authentication Word C included " } ,
{ " 11111 " , " 010 " , " 1XXXX " , " Triple Full-Rate Digital Traffic Channel acceptable, Authentication Word C included " } ,
/* (Base station initiated messages only - Initial Traffic Channel Designation message) */
{ " 01110 " , " 000 " , " 00001 " , " DTC Assignment for TIA/EIA 627 Minimum Dual-Mode: Assigned to timeslot 1, full-rate (VSELP) " } ,
{ " 01110 " , " 000 " , " 01001 " , " DTC Assignment for TIA/EIA 627 Minimum Dual-Mode: Assigned to timeslot 1, half-rate " } ,
{ " 01110 " , " 000 " , " 00010 " , " DTC Assignment for TIA/EIA 627 Minimum Dual-Mode: Assigned to timeslot 2, full-rate (VSELP) " } ,
{ " 01110 " , " 000 " , " 01010 " , " DTC Assignment for TIA/EIA 627 Minimum Dual-Mode: Assigned to timeslot 2 , half-rate " } ,
{ " 01110 " , " 000 " , " 00011 " , " DTC Assignment for TIA/EIA 627 Minimum Dual-Mode: Assigned to timeslot 3, full-rate (VSELP) " } ,
{ " 01110 " , " 000 " , " 01011 " , " DTC Assignment for TIA/EIA 627 Minimum Dual-Mode: Assigned to timeslot 3, half-rate " } ,
{ " 01110 " , " 000 " , " 01100 " , " DTC Assignment for TIA/EIA 627 Minimum Dual-Mode: Assigned to timeslot 4, half-rate " } ,
{ " 01110 " , " 000 " , " 01101 " , " DTC Assignment for TIA/EIA 627 Minimum Dual-Mode: Assigned to timeslot 5, half-rate " } ,
{ " 01110 " , " 000 " , " 01110 " , " DTC Assignment for TIA/EIA 627 Minimum Dual-Mode: Assigned to timeslot 6, half-rate " } ,
{ " 01110 " , " 010 " , " 00001 " , " DTC Assignment for IS-136: Assigned to timeslot 1, full-rate (VSELP) " } ,
{ " 01110 " , " 010 " , " 01001 " , " DTC Assignment for IS-136: Assigned to timeslot 1, half-rate " } ,
{ " 01110 " , " 010 " , " 00010 " , " DTC Assignment for IS-136: Assigned to timeslot 2, full-rate (VSELP) " } ,
{ " 01110 " , " 010 " , " 01010 " , " DTC Assignment for IS-136: Assigned to timeslot 2 , half-rate " } ,
{ " 01110 " , " 010 " , " 00011 " , " DTC Assignment for IS-136: Assigned to timeslot 3, full-rate (VSELP) " } ,
{ " 01110 " , " 010 " , " 01011 " , " DTC Assignment for IS-136: Assigned to timeslot 3, half-rate " } ,
{ " 01110 " , " 010 " , " 01100 " , " DTC Assignment for IS-136: Assigned to timeslot 4, half-rate " } ,
{ " 01110 " , " 010 " , " 01101 " , " DTC Assignment for IS-136: Assigned to timeslot 5, half-rate " } ,
{ " 01110 " , " 010 " , " 01110 " , " DTC Assignment for IS-136: Assigned to timeslot 6, half-rate " } ,
/* (Base station initiated messages only - Initial Traffic Channel Designation message) */
{ " 01110 " , " 010 " , " 10001 " , " DTC Assignment for TIA/EIA-136: Assigned to timeslot 1, full-rate (see TIA/EIA-136-410) " } ,
{ " 01110 " , " 010 " , " 10010 " , " DTC Assignment for TIA/EIA-136: Assigned to timeslot 2, full-rate (see TIA/EIA-136-410) " } ,
{ " 01110 " , " 010 " , " 10011 " , " DTC Assignment for TIA/EIA-136: Assigned to timeslot 3, full-rate (see TIA/EIA-136-410) " } ,
{ " 01110 " , " 100 " , " 00001 " , " DTC Assignment for TIA/EIA-136: Assigned to timeslot 1, full-rate (Fax/Data) " } ,
{ " 01110 " , " 100 " , " 00010 " , " DTC Assignment for TIA/EIA-136: Assigned to timeslot 2, full-rate (Fax/Data) " } ,
{ " 01110 " , " 100 " , " 00011 " , " DTC Assignment for TIA/EIA-136: Assigned to timeslot 3, full-rate (Fax/Data) " } ,
{ " 01110 " , " 100 " , " 00100 " , " DTC Assignment for TIA/EIA-136: Assigned to timeslots 1 & 2, double rate (Fax/Data) " } ,
{ " 01110 " , " 100 " , " 00101 " , " DTC Assignment for TIA/EIA-136: Assigned to timeslots 1 & 3, double rate (Fax/Data) " } ,
{ " 01110 " , " 100 " , " 00110 " , " DTC Assignment for TIA/EIA-136: Assigned to timeslots 2 & 3, double rate (Fax/Data) " } ,
{ " 01110 " , " 100 " , " 00111 " , " DTC Assignment for TIA/EIA-136: Assigned to timeslots 1, 2 & 3, triple rate (Fax/Data) " } ,
{ " 01110 " , " 001 " , " XXXXX " , " Digital Traffic Channel Assignment with Extended Modulation and Framing " } ,
{ " 11010 " , " 000 " , " 00000 " , " Analog Voice Channel Assignment " } ,
/* (Base station initiated messages only - Mobile Station Authentication and Privacy) */
{ " 01111 " , " 000 " , " 00000 " , " Parameter Update Order " } ,
{ " 10011 " , " 000 " , " 00000 " , " Base Station Challenge Order Confirmation " } ,
{ " 10100 " , " 000 " , " 00000 " , " Unique Challenge Order " } ,
{ " 10101 " , " 000 " , " 00000 " , " SSD Update Order " } ,
{ " 10110 " , " 000 " , " 00000 " , " Disable DTMF Order " } ,
{ " 10111 " , " 000 " , " 00000 " , " Message Encryption Mode Order with disable indication " } ,
{ " 10111 " , " 001 " , " 00000 " , " Message Encryption Mode Order with enable indication " } ,
/* (Mobile station initiated messages only - Mobile Station Authentication and Privacy) */
{ " 01111 " , " 000 " , " 00000 " , " Parameter Update Order/Confirmation " } ,
{ " 10011 " , " 000 " , " 00000 " , " Base Station Challenge Order " } ,
{ " 10100 " , " 000 " , " 00000 " , " Unique Challenge Order Confirmation " } ,
{ " 10101 " , " 000 " , " 00000 " , " SSD Update Order Confirmation with failure indication " } ,
{ " 10101 " , " 001 " , " 00000 " , " SSD Update Order Confirmation with success indication " } ,
{ " 10111 " , " 000 " , " 00000 " , " Message Encryption Mode Order Confirmation with disable indication " } ,
{ " 10111 " , " 001 " , " 00000 " , " Message Encryption Mode Order Confirmation with enable indication " } ,
{ NULL , NULL , NULL , NULL }
} ;
struct amps_table4 {
uint8_t order ;
uint8_t ordq ;
uint8_t msg_type ;
uint8_t msg_type_mask ;
const char * function ;
} * amps_table4 ;
static void gen_table4 ( void )
{
uint8_t value , mask ;
int i , j ;
/* count entries including last one */
for ( i = 0 ; amps_table4_def [ i ] . function ; i + + )
;
amps_table4 = calloc ( i + 1 , sizeof ( struct amps_table4 ) ) ;
if ( ! amps_table4 ) {
fprintf ( stderr , " No mem! \n " ) ;
abort ( ) ;
}
for ( i = 0 ; amps_table4_def [ i ] . function ; i + + ) {
if ( strlen ( amps_table4_def [ i ] . order ) ! = 5
| | strlen ( amps_table4_def [ i ] . ordq ) ! = 3
| | strlen ( amps_table4_def [ i ] . msg_type ) ! = 5 ) {
fprintf ( stderr , " Error in table definition entry %d: Wrong length! \n " , i ) ;
abort ( ) ;
}
value = 0 ;
for ( j = 0 ; j < 5 ; j + + ) {
if ( amps_table4_def [ i ] . order [ j ] = = ' 1 ' )
value = ( value < < 1 ) | 1 ;
else if ( amps_table4_def [ i ] . order [ j ] ! = ' 0 ' ) {
fprintf ( stderr , " Error in table definition entry %d: Wrong digit! \n " , i ) ;
abort ( ) ;
} else
value = ( value < < 1 ) ;
}
amps_table4 [ i ] . order = value ;
value = 0 ;
for ( j = 0 ; j < 3 ; j + + ) {
if ( amps_table4_def [ i ] . ordq [ j ] = = ' 1 ' )
value = ( value < < 1 ) | 1 ;
else if ( amps_table4_def [ i ] . ordq [ j ] ! = ' 0 ' ) {
fprintf ( stderr , " Error in table definition entry %d: Wrong digit! \n " , i ) ;
abort ( ) ;
} else
value = ( value < < 1 ) ;
}
amps_table4 [ i ] . ordq = value ;
value = 0 ;
mask = 0 ;
for ( j = 0 ; j < 5 ; j + + ) {
if ( amps_table4_def [ i ] . msg_type [ j ] = = ' 1 ' ) {
value = ( value < < 1 ) | 1 ;
mask = ( mask < < 1 ) | 1 ;
} else if ( amps_table4_def [ i ] . msg_type [ j ] = = ' 0 ' ) {
value = ( value < < 1 ) ;
mask = ( mask < < 1 ) | 1 ;
} else if ( amps_table4_def [ i ] . msg_type [ j ] = = ' X ' ) {
value = ( value < < 1 ) ;
mask = ( mask < < 1 ) ;
} else {
fprintf ( stderr , " Error in table definition entry %d: Wrong digit! \n " , i ) ;
abort ( ) ;
}
}
amps_table4 [ i ] . msg_type = value ;
amps_table4 [ i ] . msg_type_mask = mask ;
amps_table4 [ i ] . function = amps_table4_def [ i ] . function ;
}
}
static const char * amps_table4_name ( uint8_t msg_type , uint8_t ordq , uint8_t order )
{
int i ;
for ( i = 0 ; amps_table4 [ i ] . function ; i + + ) {
//printf("c %d %d %d with %d %d %d\n", msg_type, ordq, order, amps_table4[i].msg_type, amps_table4[i].ordq, amps_table4[i].order);
if ( amps_table4 [ i ] . order = = order
& & amps_table4 [ i ] . ordq = = ordq
& & amps_table4 [ i ] . msg_type = = ( msg_type & amps_table4 [ i ] . msg_type_mask ) )
return amps_table4 [ i ] . function ;
}
return ( " Unknown message type " ) ;
}
void init_frame ( void )
{
struct def_message_set * * ms ;
struct def_word * * w ;
struct def_ie * ie ;
struct amps_ie_desc * ied ;
int num_bits , bits ;
int i , j ;
uint8_t dcc ;
ie_desc_max_len = 0 ;
for ( i = 0 ; amps_ie_desc [ i ] . name ; i + + ) {
2016-10-07 06:55:18 +00:00
if ( ( int ) strlen ( amps_ie_desc [ i ] . name ) > ie_desc_max_len )
2016-05-01 17:51:56 +00:00
ie_desc_max_len = strlen ( amps_ie_desc [ i ] . name ) ;
2016-10-07 06:55:18 +00:00
if ( i ! = ( int ) amps_ie_desc [ i ] . ie ) {
2016-05-01 17:51:56 +00:00
fprintf ( stderr , " IEs #%d in amps_ie_desc is different from definitions AMPS_IE_xxx (%d), please fix! \n " , i , amps_ie_desc [ i ] . ie ) ;
abort ( ) ;
}
if ( amps_ie_desc [ i + 1 ] . name ) {
if ( strcmp ( amps_ie_desc [ i + 1 ] . name , amps_ie_desc [ i ] . name ) < = 0 ) {
fprintf ( stderr , " IE '%s' in amps_ie_desc list is not greater (unsorted) or is equal to '%s', please fix! \n " , amps_ie_desc [ i + 1 ] . name , amps_ie_desc [ i ] . name ) ;
abort ( ) ;
}
}
}
if ( i ! = AMPS_IE_NUM ) {
fprintf ( stderr , " number of IEs in amps_ie_desc (%d) is different from number of definitions AMPS_IE_xxx (%d), please fix! \n " , i , AMPS_IE_NUM ) ;
abort ( ) ;
}
/* check message words */
for ( ms = amps_message_sets ; * ms ; ms + + ) {
// printf("Checking message set '%s'\n", (*ms)->name);
num_bits = ( * ms ) - > num_bits ;
for ( w = ( * ms ) - > word ; * w ; w + + ) {
// printf(" Checking message word '%s'\n", (*w)->name);
bits = 0 ;
for ( ie = ( * w ) - > ie ; ie - > name ; ie + + ) {
// printf(" Checking ie '%s'\n", ie->name);
bits + = ie - > bits ;
if ( strchr ( ie - > name , ' = ' ) ) {
fprintf ( stderr , " IE name '%s' in '%s' has '=' character, please fix! \n " , ie - > name , ( * w ) - > name ) ;
abort ( ) ;
}
for ( i = 0 , ied = amps_ie_desc ; ied - > name ; i + + , ied + + ) {
if ( ! strcmp ( ied - > name , ie - > name ) )
break ;
}
if ( ! ied - > name ) {
fprintf ( stderr , " IE name '%s' not found in amps_ie_desc list, please fix! \n " , ie - > name ) ;
abort ( ) ;
}
ie - > ie = i ;
}
if ( bits ! = num_bits ) {
fprintf ( stderr , " Bits in '%s' is not %d, please fix! \n " , ( * w ) - > name , num_bits ) ;
abort ( ) ;
}
}
}
/* generate DCC decoding table */
for ( i = 0 ; i < 128 ; i + + )
dcc_decode [ i ] = - 1 ;
for ( i = 0 ; i < 4 ; i + + ) {
dcc = dcc_encode [ i ] ;
dcc_decode [ dcc ] = i ;
/* one bit errors */
for ( j = 0 ; j < 7 ; j + + )
dcc_decode [ dcc ^ ( 1 < < j ) ] = i ;
}
/* generate table 4 */
gen_table4 ( ) ;
}
/*
* encode and decode words
*/
2016-10-07 06:55:18 +00:00
static uint64_t amps_encode_word ( frame_t * frame , struct def_word * w , int debug )
2016-05-01 17:51:56 +00:00
{
uint64_t word , value ;
char spaces [ ie_desc_max_len + 1 ] ;
int sum_bits , bits ;
int i , t4 = 0 ;
2017-05-15 15:59:09 +00:00
# ifdef DEBUG_ALL_MESSAGES
debug = 1 ;
# endif
2016-05-01 17:51:56 +00:00
memset ( spaces , ' ' , ie_desc_max_len ) ;
spaces [ ie_desc_max_len ] = ' \0 ' ;
/* sum of bits */
sum_bits = 0 ;
for ( i = 0 ; w - > ie [ i ] . name ; i + + )
sum_bits + = w - > ie [ i ] . bits ;
PDEBUG ( DFRAME , ( debug > = 0 ) ? DEBUG_INFO : DEBUG_DEBUG , " Transmit: %s \n " , w - > name ) ;
word = 0 ;
for ( i = 0 ; w - > ie [ i ] . name ; i + + ) {
bits = w - > ie [ i ] . bits ;
if ( w - > ie [ i ] . name [ 0 ] = = ' P ' & & w - > ie [ i ] . name [ 1 ] = = ' \0 ' )
value = encode_bch_binary ( word , sum_bits - bits ) ;
else
value = frame - > ie [ w - > ie [ i ] . ie ] ;
word = ( word < < bits ) | ( value & cut_bits [ bits ] ) ;
if ( debug > = 0 ) {
if ( amps_ie_desc [ w - > ie [ i ] . ie ] . decoder )
PDEBUG ( DFRAME , DEBUG_DEBUG , " %s%s: % " PRIu64 " = %s (%s) \n " , spaces + strlen ( w - > ie [ i ] . name ) , w - > ie [ i ] . name , value , amps_ie_desc [ w - > ie [ i ] . ie ] . decoder ( value ) , amps_ie_desc [ w - > ie [ i ] . ie ] . desc ) ;
else
PDEBUG ( DFRAME , DEBUG_DEBUG , " %s%s: % " PRIu64 " (%s) \n " , spaces + strlen ( w - > ie [ i ] . name ) , w - > ie [ i ] . name , value , amps_ie_desc [ w - > ie [ i ] . ie ] . desc ) ;
}
/* show result for 3 IEs of table 4 */
if ( w - > ie [ i ] . ie = = AMPS_IE_LOCAL_MSG_TYPE | | w - > ie [ i ] . ie = = AMPS_IE_ORDQ | | w - > ie [ i ] . ie = = AMPS_IE_ORDER )
t4 + + ;
if ( t4 = = 3 ) {
t4 = 0 ;
if ( debug > = 0 )
PDEBUG ( DFRAME , DEBUG_DEBUG , " %s--> %s \n " , spaces , amps_table4_name ( frame - > ie [ AMPS_IE_LOCAL_MSG_TYPE ] , frame - > ie [ AMPS_IE_ORDQ ] , frame - > ie [ AMPS_IE_ORDER ] ) ) ;
}
}
return word ;
}
2016-06-20 15:15:42 +00:00
static uint64_t amps_encode_control_filler ( amps_t * amps , uint8_t dcc , uint8_t cmac , uint8_t sdcc1 , uint8_t sdcc2 , uint8_t wfom )
2016-05-01 17:51:56 +00:00
{
2016-06-19 09:03:59 +00:00
frame_t frame ;
2016-05-01 17:51:56 +00:00
memset ( & frame , 0 , sizeof ( frame ) ) ;
frame . ie [ AMPS_IE_T1T2 ] = 3 ;
frame . ie [ AMPS_IE_DCC ] = dcc ;
frame . ie [ AMPS_IE_010111 ] = 23 ;
frame . ie [ AMPS_IE_CMAC ] = cmac ;
frame . ie [ AMPS_IE_SDCC1 ] = sdcc1 ;
frame . ie [ AMPS_IE_11 ] = 3 ;
frame . ie [ AMPS_IE_SDCC2 ] = sdcc2 ;
frame . ie [ AMPS_IE_1 ] = 1 ;
frame . ie [ AMPS_IE_WFOM ] = wfom ;
2016-06-20 15:15:42 +00:00
if ( amps - > sender . loopback ) {
frame . ie [ AMPS_IE_1111 ] = amps - > when_count ;
amps - > when_transmitted [ amps - > when_count ] = get_time ( ) ;
amps - > when_count = ( amps - > when_count + 1 ) & 0xf ;
} else
frame . ie [ AMPS_IE_1111 ] = 15 ;
2016-05-01 17:51:56 +00:00
frame . ie [ AMPS_IE_OHD ] = 1 ;
return amps_encode_word ( & frame , & control_filler , - 1 ) ;
}
uint64_t amps_encode_word1_system ( uint8_t dcc , uint16_t sid1 , uint8_t ep , uint8_t auth , uint8_t pci , uint8_t nawc )
{
2016-06-19 09:03:59 +00:00
frame_t frame ;
2016-05-01 17:51:56 +00:00
memset ( & frame , 0 , sizeof ( frame ) ) ;
frame . ie [ AMPS_IE_T1T2 ] = 3 ;
frame . ie [ AMPS_IE_DCC ] = dcc ;
frame . ie [ AMPS_IE_SID1 ] = sid1 ;
frame . ie [ AMPS_IE_EP ] = ep ;
frame . ie [ AMPS_IE_AUTH ] = auth ;
frame . ie [ AMPS_IE_PCI ] = pci ;
frame . ie [ AMPS_IE_NAWC ] = nawc ;
frame . ie [ AMPS_IE_OHD ] = 6 ;
2017-05-30 10:49:40 +00:00
return amps_encode_word ( & frame , & amps_word1_system_parameter_overhead , - 1 ) ;
}
uint64_t tacs_encode_word1_system ( uint8_t dcc , uint16_t aid1 , uint8_t ep , uint8_t auth , uint8_t pci , uint8_t nawc )
{
frame_t frame ;
memset ( & frame , 0 , sizeof ( frame ) ) ;
frame . ie [ AMPS_IE_T1T2 ] = 3 ;
frame . ie [ AMPS_IE_DCC ] = dcc ;
frame . ie [ AMPS_IE_AID1 ] = aid1 ;
frame . ie [ AMPS_IE_EP ] = ep ;
frame . ie [ AMPS_IE_AUTH ] = auth ;
frame . ie [ AMPS_IE_PCI ] = pci ;
frame . ie [ AMPS_IE_NAWC ] = nawc ;
frame . ie [ AMPS_IE_OHD ] = 6 ;
return amps_encode_word ( & frame , & tacs_word1_system_parameter_overhead , - 1 ) ;
2016-05-01 17:51:56 +00:00
}
uint64_t amps_encode_word2_system ( uint8_t dcc , uint8_t s , uint8_t e , uint8_t regh , uint8_t regr , uint8_t dtx , uint8_t n_1 , uint8_t rcf , uint8_t cpa , uint8_t cmax_1 , uint8_t end )
{
2016-06-19 09:03:59 +00:00
frame_t frame ;
2016-05-01 17:51:56 +00:00
memset ( & frame , 0 , sizeof ( frame ) ) ;
frame . ie [ AMPS_IE_T1T2 ] = 3 ;
frame . ie [ AMPS_IE_DCC ] = dcc ;
frame . ie [ AMPS_IE_S ] = s ;
frame . ie [ AMPS_IE_E ] = e ;
frame . ie [ AMPS_IE_REGH ] = regh ;
frame . ie [ AMPS_IE_REGR ] = regr ;
2017-05-21 14:40:10 +00:00
frame . ie [ AMPS_IE_DTX_Support ] = dtx ;
2016-05-01 17:51:56 +00:00
frame . ie [ AMPS_IE_N_1 ] = n_1 ;
frame . ie [ AMPS_IE_RCF ] = rcf ;
frame . ie [ AMPS_IE_CPA ] = cpa ;
frame . ie [ AMPS_IE_CMAX_1 ] = cmax_1 ;
frame . ie [ AMPS_IE_END ] = end ;
frame . ie [ AMPS_IE_OHD ] = 7 ;
return amps_encode_word ( & frame , & word2_system_parameter_overhead , - 1 ) ;
}
uint64_t amps_encode_registration_id ( uint8_t dcc , uint32_t regid , uint8_t end )
{
2016-06-19 09:03:59 +00:00
frame_t frame ;
2016-05-01 17:51:56 +00:00
memset ( & frame , 0 , sizeof ( frame ) ) ;
frame . ie [ AMPS_IE_T1T2 ] = 3 ;
frame . ie [ AMPS_IE_DCC ] = dcc ;
frame . ie [ AMPS_IE_REGID ] = regid ;
frame . ie [ AMPS_IE_END ] = end ;
frame . ie [ AMPS_IE_OHD ] = 0 ;
return amps_encode_word ( & frame , & registration_id , - 1 ) ;
}
uint64_t amps_encode_registration_increment ( uint8_t dcc , uint16_t regincr , uint8_t end )
{
2016-06-19 09:03:59 +00:00
frame_t frame ;
2016-05-01 17:51:56 +00:00
memset ( & frame , 0 , sizeof ( frame ) ) ;
frame . ie [ AMPS_IE_T1T2 ] = 3 ;
frame . ie [ AMPS_IE_DCC ] = dcc ;
frame . ie [ AMPS_IE_ACT ] = 2 ;
frame . ie [ AMPS_IE_REGINCR ] = regincr ;
frame . ie [ AMPS_IE_END ] = end ;
frame . ie [ AMPS_IE_OHD ] = 4 ;
return amps_encode_word ( & frame , & registration_increment_global_action , - 1 ) ;
}
uint64_t amps_encode_location_area ( uint8_t dcc , uint8_t pureg , uint8_t pdreg , uint8_t lreg , uint16_t locaid , uint8_t end )
{
2016-06-19 09:03:59 +00:00
frame_t frame ;
2016-05-01 17:51:56 +00:00
memset ( & frame , 0 , sizeof ( frame ) ) ;
frame . ie [ AMPS_IE_T1T2 ] = 3 ;
frame . ie [ AMPS_IE_DCC ] = dcc ;
frame . ie [ AMPS_IE_ACT ] = 3 ;
frame . ie [ AMPS_IE_PUREG ] = pureg ;
frame . ie [ AMPS_IE_PDREG ] = pdreg ;
frame . ie [ AMPS_IE_LREG ] = lreg ;
frame . ie [ AMPS_IE_LOCAID ] = locaid ;
frame . ie [ AMPS_IE_END ] = end ;
frame . ie [ AMPS_IE_OHD ] = 4 ;
return amps_encode_word ( & frame , & location_area_global_action , - 1 ) ;
}
uint64_t amps_encode_new_access_channel_set ( uint8_t dcc , uint16_t newacc , uint8_t end )
{
2016-06-19 09:03:59 +00:00
frame_t frame ;
2016-05-01 17:51:56 +00:00
memset ( & frame , 0 , sizeof ( frame ) ) ;
frame . ie [ AMPS_IE_T1T2 ] = 3 ;
frame . ie [ AMPS_IE_DCC ] = dcc ;
frame . ie [ AMPS_IE_ACT ] = 6 ;
frame . ie [ AMPS_IE_NEWACC ] = newacc ;
frame . ie [ AMPS_IE_END ] = end ;
frame . ie [ AMPS_IE_OHD ] = 4 ;
return amps_encode_word ( & frame , & new_access_channel_set_global_action , - 1 ) ;
}
uint64_t amps_encode_overload_control ( uint8_t dcc , uint8_t * olc , uint8_t end )
{
2016-06-19 09:03:59 +00:00
frame_t frame ;
2016-05-01 17:51:56 +00:00
memset ( & frame , 0 , sizeof ( frame ) ) ;
frame . ie [ AMPS_IE_T1T2 ] = 3 ;
frame . ie [ AMPS_IE_DCC ] = dcc ;
frame . ie [ AMPS_IE_ACT ] = 8 ;
frame . ie [ AMPS_IE_OLC_0 ] = olc [ 0 ] ;
frame . ie [ AMPS_IE_OLC_1 ] = olc [ 1 ] ;
frame . ie [ AMPS_IE_OLC_2 ] = olc [ 2 ] ;
frame . ie [ AMPS_IE_OLC_3 ] = olc [ 3 ] ;
frame . ie [ AMPS_IE_OLC_4 ] = olc [ 4 ] ;
frame . ie [ AMPS_IE_OLC_5 ] = olc [ 5 ] ;
frame . ie [ AMPS_IE_OLC_6 ] = olc [ 6 ] ;
frame . ie [ AMPS_IE_OLC_7 ] = olc [ 7 ] ;
frame . ie [ AMPS_IE_OLC_8 ] = olc [ 8 ] ;
frame . ie [ AMPS_IE_OLC_9 ] = olc [ 9 ] ;
frame . ie [ AMPS_IE_OLC_10 ] = olc [ 10 ] ;
frame . ie [ AMPS_IE_OLC_11 ] = olc [ 11 ] ;
frame . ie [ AMPS_IE_OLC_12 ] = olc [ 12 ] ;
frame . ie [ AMPS_IE_OLC_13 ] = olc [ 13 ] ;
frame . ie [ AMPS_IE_OLC_14 ] = olc [ 14 ] ;
frame . ie [ AMPS_IE_OLC_15 ] = olc [ 15 ] ;
frame . ie [ AMPS_IE_END ] = end ;
frame . ie [ AMPS_IE_OHD ] = 4 ;
return amps_encode_word ( & frame , & overload_control_global_action , - 1 ) ;
}
uint64_t amps_encode_access_type ( uint8_t dcc , uint8_t bis , uint8_t pci_home , uint8_t pci_roam , uint8_t bspc , uint8_t bscap , uint8_t end )
{
2016-06-19 09:03:59 +00:00
frame_t frame ;
2016-05-01 17:51:56 +00:00
memset ( & frame , 0 , sizeof ( frame ) ) ;
frame . ie [ AMPS_IE_T1T2 ] = 3 ;
frame . ie [ AMPS_IE_DCC ] = dcc ;
frame . ie [ AMPS_IE_ACT ] = 9 ;
frame . ie [ AMPS_IE_BIS ] = bis ;
frame . ie [ AMPS_IE_PCI_HOME ] = pci_home ;
frame . ie [ AMPS_IE_PCI_ROAM ] = pci_roam ;
frame . ie [ AMPS_IE_BSPC ] = bspc ;
frame . ie [ AMPS_IE_BSCAP ] = bscap ;
frame . ie [ AMPS_IE_END ] = end ;
frame . ie [ AMPS_IE_OHD ] = 4 ;
return amps_encode_word ( & frame , & access_type_parameters_global_action , - 1 ) ;
}
uint64_t amps_encode_access_attempt ( uint8_t dcc , uint8_t maxbusy_pgr , uint8_t maxsztr_pgr , uint8_t maxbusy_other , uint8_t maxsztr_other , uint8_t end )
{
2016-06-19 09:03:59 +00:00
frame_t frame ;
2016-05-01 17:51:56 +00:00
memset ( & frame , 0 , sizeof ( frame ) ) ;
frame . ie [ AMPS_IE_T1T2 ] = 3 ;
frame . ie [ AMPS_IE_DCC ] = dcc ;
frame . ie [ AMPS_IE_ACT ] = 10 ;
frame . ie [ AMPS_IE_MAXBUSY_PGR ] = maxbusy_pgr ;
frame . ie [ AMPS_IE_MAXSZTR_PGR ] = maxsztr_pgr ;
frame . ie [ AMPS_IE_MAXBUSY_OTHER ] = maxbusy_other ;
frame . ie [ AMPS_IE_MAXSZTR_OTHER ] = maxsztr_other ;
frame . ie [ AMPS_IE_END ] = end ;
frame . ie [ AMPS_IE_OHD ] = 4 ;
return amps_encode_word ( & frame , & access_attempt_parameters_global_action , - 1 ) ;
}
2016-10-07 06:55:18 +00:00
static uint64_t amps_encode_word1_abbreviated_address_word ( uint8_t dcc , uint32_t min1 , int multiple )
2016-05-01 17:51:56 +00:00
{
2016-06-19 09:03:59 +00:00
frame_t frame ;
2016-05-01 17:51:56 +00:00
memset ( & frame , 0 , sizeof ( frame ) ) ;
if ( multiple )
frame . ie [ AMPS_IE_T1T2 ] = 1 ;
else
frame . ie [ AMPS_IE_T1T2 ] = 0 ;
frame . ie [ AMPS_IE_DCC ] = dcc ;
frame . ie [ AMPS_IE_MIN1 ] = min1 ;
return amps_encode_word ( & frame , & word1_abbreviated_address_word , DEBUG_INFO ) ;
}
2017-06-17 10:11:07 +00:00
static uint64_t amps_encode_word2_extended_address_word_a ( uint16_t min2 , uint8_t msg_type , uint8_t ordq , uint8_t order )
2016-05-01 17:51:56 +00:00
{
2016-06-19 09:03:59 +00:00
frame_t frame ;
2016-05-01 17:51:56 +00:00
memset ( & frame , 0 , sizeof ( frame ) ) ;
frame . ie [ AMPS_IE_T1T2 ] = 2 ;
2016-10-30 08:25:45 +00:00
frame . ie [ AMPS_IE_SCC ] = 3 ;
2016-05-01 17:51:56 +00:00
frame . ie [ AMPS_IE_MIN2 ] = min2 ;
frame . ie [ AMPS_IE_EF ] = 0 ;
frame . ie [ AMPS_IE_LOCAL_MSG_TYPE ] = msg_type ;
frame . ie [ AMPS_IE_ORDQ ] = ordq ;
frame . ie [ AMPS_IE_ORDER ] = order ;
return amps_encode_word ( & frame , & word2_extended_address_word_a , DEBUG_INFO ) ;
}
2017-06-17 10:11:07 +00:00
static uint64_t amps_encode_word2_extended_address_word_b ( uint8_t scc , uint16_t min2 , uint8_t vmac , uint16_t chan )
2016-05-01 17:51:56 +00:00
{
2016-06-19 09:03:59 +00:00
frame_t frame ;
2016-05-01 17:51:56 +00:00
memset ( & frame , 0 , sizeof ( frame ) ) ;
frame . ie [ AMPS_IE_T1T2 ] = 2 ;
frame . ie [ AMPS_IE_SCC ] = scc ;
frame . ie [ AMPS_IE_MIN2 ] = min2 ;
frame . ie [ AMPS_IE_VMAC ] = vmac ;
frame . ie [ AMPS_IE_CHAN ] = chan ;
return amps_encode_word ( & frame , & word2_extended_address_word_b , DEBUG_INFO ) ;
}
2016-10-07 06:55:18 +00:00
static uint64_t amps_encode_mobile_station_control_message_word1_a ( uint8_t pscc , uint8_t msg_type , uint8_t ordq , uint8_t order )
2016-05-01 17:51:56 +00:00
{
2016-06-19 09:03:59 +00:00
frame_t frame ;
2016-05-01 17:51:56 +00:00
memset ( & frame , 0 , sizeof ( frame ) ) ;
frame . ie [ AMPS_IE_T1T2 ] = 2 ;
2016-10-30 08:25:45 +00:00
frame . ie [ AMPS_IE_SCC ] = 3 ;
2016-05-01 17:51:56 +00:00
frame . ie [ AMPS_IE_PSCC ] = pscc ;
frame . ie [ AMPS_IE_EF ] = 0 ;
frame . ie [ AMPS_IE_LOCAL_MSG_TYPE ] = msg_type ;
frame . ie [ AMPS_IE_ORDQ ] = ordq ;
frame . ie [ AMPS_IE_ORDER ] = order ;
return amps_encode_word ( & frame , & mobile_station_control_message_word1_a , DEBUG_INFO ) ;
}
2016-10-07 06:55:18 +00:00
static uint64_t amps_encode_mobile_station_control_message_word1_b ( uint8_t scc , uint8_t pscc , uint8_t dtx , uint8_t pvi , uint8_t mem , uint8_t vmac , uint16_t chan )
2016-05-01 17:51:56 +00:00
{
2016-06-19 09:03:59 +00:00
frame_t frame ;
2016-05-01 17:51:56 +00:00
memset ( & frame , 0 , sizeof ( frame ) ) ;
frame . ie [ AMPS_IE_T1T2 ] = 2 ;
frame . ie [ AMPS_IE_SCC ] = scc ;
frame . ie [ AMPS_IE_PSCC ] = pscc ;
frame . ie [ AMPS_IE_EF ] = 0 ;
frame . ie [ AMPS_IE_DTX ] = dtx ;
frame . ie [ AMPS_IE_PVI ] = pvi ;
frame . ie [ AMPS_IE_MEM ] = mem ;
frame . ie [ AMPS_IE_VMAC ] = vmac ;
frame . ie [ AMPS_IE_CHAN ] = chan ;
return amps_encode_word ( & frame , & mobile_station_control_message_word1_b , DEBUG_INFO ) ;
}
/* decoder function of a word */
static frame_t * amps_decode_word ( uint64_t word , struct def_word * w )
{
static frame_t frame ;
char spaces [ ie_desc_max_len + 1 ] ;
int bits_left , bits ;
uint64_t value ;
int i , t4 = 0 ;
memset ( & frame , 0 , sizeof ( frame ) ) ;
memset ( spaces , ' ' , ie_desc_max_len ) ;
spaces [ ie_desc_max_len ] = ' \0 ' ;
/* sum of bits */
bits_left = 0 ;
for ( i = 0 ; w - > ie [ i ] . name ; i + + )
bits_left + = w - > ie [ i ] . bits ;
PDEBUG ( DFRAME , DEBUG_INFO , " Received: %s \n " , w - > name ) ;
for ( i = 0 ; w - > ie [ i ] . name ; i + + ) {
bits = w - > ie [ i ] . bits ;
bits_left - = bits ;
value = ( word > > bits_left ) & cut_bits [ bits ] ;
frame . ie [ w - > ie [ i ] . ie ] = value ;
if ( amps_ie_desc [ w - > ie [ i ] . ie ] . decoder )
PDEBUG ( DFRAME , DEBUG_DEBUG , " %s%s: % " PRIu64 " = %s (%s) \n " , spaces + strlen ( w - > ie [ i ] . name ) , w - > ie [ i ] . name , value , amps_ie_desc [ w - > ie [ i ] . ie ] . decoder ( value ) , amps_ie_desc [ w - > ie [ i ] . ie ] . desc ) ;
else
PDEBUG ( DFRAME , DEBUG_DEBUG , " %s%s: % " PRIu64 " (%s) \n " , spaces + strlen ( w - > ie [ i ] . name ) , w - > ie [ i ] . name , value , amps_ie_desc [ w - > ie [ i ] . ie ] . desc ) ;
/* show result for 3 IEs of table 4 */
if ( w - > ie [ i ] . ie = = AMPS_IE_LOCAL_MSG_TYPE | | w - > ie [ i ] . ie = = AMPS_IE_ORDQ | | w - > ie [ i ] . ie = = AMPS_IE_ORDER )
t4 + + ;
if ( t4 = = 3 ) {
t4 = 0 ;
PDEBUG ( DFRAME , DEBUG_DEBUG , " %s--> %s \n " , spaces , amps_table4_name ( frame . ie [ AMPS_IE_LOCAL_MSG_TYPE ] , frame . ie [ AMPS_IE_ORDQ ] , frame . ie [ AMPS_IE_ORDER ] ) ) ;
}
}
return & frame ;
}
/* get word from data bits and call decoder function */
static void amps_decode_word_focc ( amps_t * amps , uint64_t word )
{
struct def_word * w = NULL ;
2016-06-20 15:15:42 +00:00
int t1t2 , ohd = - 1 , act , scc ;
static frame_t * frame ;
2016-05-01 17:51:56 +00:00
t1t2 = ( word > > 38 ) & 3 ;
/* control message */
if ( t1t2 ! = 3 ) {
2016-12-09 15:34:33 +00:00
PDEBUG_CHAN ( DFRAME , DEBUG_INFO , " Received Mobile Station Control Message (T1T2 = %d) \n " , t1t2 ) ;
2016-05-01 17:51:56 +00:00
if ( t1t2 = = 1 )
amps - > rx_focc_word_count = 1 ;
if ( t1t2 = = 0 | | t1t2 = = 1 ) {
w = & word1_abbreviated_address_word ;
goto decode ;
}
if ( t1t2 = = 2 ) {
amps - > rx_focc_word_count + + ;
if ( amps - > rx_focc_word_count = = 2 ) {
scc = ( word > > 36 ) & 3 ;
if ( scc = = 3 )
w = & word2_extended_address_word_a ;
else
w = & word2_extended_address_word_b ;
goto decode ;
}
2016-12-09 15:34:33 +00:00
PDEBUG_CHAN ( DFRAME , DEBUG_INFO , " Decoding of more than 2 Control messages not supported \n " ) ;
2016-05-01 17:51:56 +00:00
}
return ;
}
/* overhead message */
ohd = ( word > > 12 ) & 7 ;
switch ( ohd ) {
case 6 :
2017-05-30 10:49:40 +00:00
if ( ! tacs )
w = & amps_word1_system_parameter_overhead ;
else
w = & tacs_word1_system_parameter_overhead ;
2016-05-01 17:51:56 +00:00
break ;
case 7 :
w = & word2_system_parameter_overhead ;
break ;
case 4 :
act = ( word > > 32 ) & 15 ;
switch ( act ) {
case 1 :
w = & rescan_global_action ;
break ;
case 2 :
w = & registration_increment_global_action ;
break ;
case 3 :
w = & location_area_global_action ;
break ;
case 6 :
w = & new_access_channel_set_global_action ;
break ;
case 8 :
w = & overload_control_global_action ;
break ;
case 9 :
w = & access_type_parameters_global_action ;
break ;
case 10 :
w = & access_attempt_parameters_global_action ;
break ;
case 7 :
w = & random_challenge_a_global_action ;
break ;
case 11 :
w = & random_challenge_b_global_action ;
break ;
case 14 :
w = & local_control_1 ;
break ;
case 15 :
w = & local_control_2 ;
break ;
}
break ;
case 0 :
w = & registration_id ;
break ;
case 1 :
w = & control_filler ;
break ;
case 2 :
w = & control_channel_information ;
break ;
}
decode :
if ( ! w ) {
2016-12-09 15:34:33 +00:00
PDEBUG_CHAN ( DFRAME , DEBUG_INFO , " Received Illegal Overhead Message \n " ) ;
2016-05-01 17:51:56 +00:00
return ;
}
2016-06-20 15:15:42 +00:00
frame = amps_decode_word ( word , w ) ;
/* show control filler delay */
if ( amps - > sender . loopback & & ohd = = 1 )
2016-12-09 15:34:33 +00:00
PDEBUG_CHAN ( DDSP , DEBUG_NOTICE , " Round trip delay is %.3f seconds \n " , amps - > when_received - amps - > when_transmitted [ frame - > ie [ AMPS_IE_1111 ] ] ) ;
2016-05-01 17:51:56 +00:00
}
/* get word from data bits and call decoder function
* return 1 if we expect more frames */
static int amps_decode_word_recc ( amps_t * amps , uint64_t word , int first )
{
struct def_word * w = NULL ;
int msg_count , f , nawc ;
static frame_t * frame ;
f = ( word > > 47 ) & 0x1 ;
nawc = ( word > > 44 ) & 0x7 ;
if ( first ) {
memset ( amps - > rx_recc_dialing , 0 , sizeof ( amps - > rx_recc_dialing ) ) ;
amps - > rx_recc_word_count = 0 ;
2017-05-21 14:40:10 +00:00
amps - > rx_recc_nawc = nawc ;
2016-05-01 17:51:56 +00:00
if ( f = = 0 ) {
2016-12-09 15:34:33 +00:00
PDEBUG_CHAN ( DFRAME , DEBUG_NOTICE , " Received first word, but F bit is not set. \n " ) ;
2016-05-01 17:51:56 +00:00
return 0 ;
}
} else {
if ( f = = 1 ) {
2016-12-09 15:34:33 +00:00
PDEBUG_CHAN ( DFRAME , DEBUG_NOTICE , " Received additional word, but F bit is set. \n " ) ;
2016-05-01 17:51:56 +00:00
return 0 ;
}
2017-05-21 14:40:10 +00:00
amps - > rx_recc_nawc - - ;
if ( amps - > rx_recc_nawc ! = nawc ) {
PDEBUG_CHAN ( DFRAME , DEBUG_NOTICE , " Received additional word with NAWC missmatch! \n " ) ;
}
2016-05-01 17:51:56 +00:00
}
msg_count = amps - > rx_recc_word_count ;
if ( msg_count = = 8 ) {
2016-12-09 15:34:33 +00:00
PDEBUG_CHAN ( DFRAME , DEBUG_NOTICE , " Received too many words. \n " ) ;
2016-05-01 17:51:56 +00:00
return 0 ;
}
if ( msg_count = = 0 )
w = & abbreviated_address_word ;
if ( msg_count = = 1 )
w = & extended_address_word ;
if ( amps - > si . word2 . s ) {
if ( msg_count = = 2 )
w = & serial_number_word ;
} else
msg_count + + ;
if ( amps - > si . word1 . auth ) {
if ( msg_count = = 3 )
w = & authentication_word ;
} else
msg_count + + ;
// FIXME: other messages Word D
if ( msg_count = = 4 )
w = & first_word_of_the_called_address ;
if ( msg_count = = 5 )
w = & second_word_of_the_called_address ;
if ( msg_count = = 6 )
w = & third_word_of_the_called_address ;
if ( msg_count = = 7 )
w = & fourth_word_of_the_called_address ;
if ( ! w ) {
2016-12-09 15:34:33 +00:00
PDEBUG_CHAN ( DFRAME , DEBUG_INFO , " Received Illegal RECC Message \n " ) ;
2016-05-01 17:51:56 +00:00
goto done ;
}
frame = amps_decode_word ( word , w ) ;
if ( amps - > rx_recc_word_count = = 0 & & frame ) {
amps - > rx_recc_min1 = frame - > ie [ AMPS_IE_MIN1 ] ;
amps - > rx_recc_scm = frame - > ie [ AMPS_IE_SCM ] ;
}
if ( amps - > rx_recc_word_count = = 1 & & frame ) {
amps - > rx_recc_min2 = frame - > ie [ AMPS_IE_MIN2 ] ;
amps - > rx_recc_msg_type = frame - > ie [ AMPS_IE_LOCAL_MSG_TYPE ] ;
amps - > rx_recc_ordq = frame - > ie [ AMPS_IE_ORDQ ] ;
amps - > rx_recc_order = frame - > ie [ AMPS_IE_ORDER ] ;
amps - > rx_recc_scm | = frame - > ie [ AMPS_IE_SCM ] < < 4 ;
2017-05-21 14:40:10 +00:00
amps - > rx_recc_mpci = frame - > ie [ AMPS_IE_MPCI ] ;
2016-05-01 17:51:56 +00:00
}
if ( amps - > rx_recc_word_count = = 2 & & frame ) {
if ( amps - > si . word2 . s )
amps - > rx_recc_esn = frame - > ie [ AMPS_IE_ESN ] ;
else
amps - > rx_recc_esn = 0 ;
}
if ( msg_count = = 4 & & frame ) {
amps - > rx_recc_dialing [ 0 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_1 ] ] ;
amps - > rx_recc_dialing [ 1 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_2 ] ] ;
amps - > rx_recc_dialing [ 2 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_3 ] ] ;
amps - > rx_recc_dialing [ 3 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_4 ] ] ;
amps - > rx_recc_dialing [ 4 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_5 ] ] ;
amps - > rx_recc_dialing [ 5 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_6 ] ] ;
amps - > rx_recc_dialing [ 6 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_7 ] ] ;
amps - > rx_recc_dialing [ 7 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_8 ] ] ;
}
if ( msg_count = = 5 & & frame ) {
amps - > rx_recc_dialing [ 8 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_9 ] ] ;
amps - > rx_recc_dialing [ 9 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_10 ] ] ;
amps - > rx_recc_dialing [ 10 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_11 ] ] ;
amps - > rx_recc_dialing [ 11 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_12 ] ] ;
amps - > rx_recc_dialing [ 12 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_13 ] ] ;
amps - > rx_recc_dialing [ 13 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_14 ] ] ;
amps - > rx_recc_dialing [ 14 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_15 ] ] ;
amps - > rx_recc_dialing [ 15 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_16 ] ] ;
}
if ( msg_count = = 6 & & frame ) {
amps - > rx_recc_dialing [ 16 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_17 ] ] ;
amps - > rx_recc_dialing [ 17 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_18 ] ] ;
amps - > rx_recc_dialing [ 18 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_19 ] ] ;
amps - > rx_recc_dialing [ 19 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_20 ] ] ;
amps - > rx_recc_dialing [ 20 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_21 ] ] ;
amps - > rx_recc_dialing [ 21 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_22 ] ] ;
amps - > rx_recc_dialing [ 22 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_23 ] ] ;
amps - > rx_recc_dialing [ 23 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_24 ] ] ;
}
if ( msg_count = = 7 & & frame ) {
amps - > rx_recc_dialing [ 24 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_25 ] ] ;
amps - > rx_recc_dialing [ 25 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_26 ] ] ;
amps - > rx_recc_dialing [ 26 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_27 ] ] ;
amps - > rx_recc_dialing [ 27 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_28 ] ] ;
amps - > rx_recc_dialing [ 28 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_29 ] ] ;
amps - > rx_recc_dialing [ 29 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_30 ] ] ;
amps - > rx_recc_dialing [ 30 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_31 ] ] ;
amps - > rx_recc_dialing [ 31 ] = digit2number [ frame - > ie [ AMPS_IE_DIGIT_32 ] ] ;
}
2017-05-21 14:40:10 +00:00
PDEBUG_CHAN ( DFRAME , DEBUG_INFO , " expecting %d more word(s) to come \n " , amps - > rx_recc_nawc ) ;
if ( msg_count > = 3 & & amps - > rx_recc_nawc = = 0 ) {
2016-06-19 15:41:42 +00:00
/* if no digit messages are present, send NULL as dial string (paging reply) */
2017-05-21 14:40:10 +00:00
amps_rx_recc ( amps , amps - > rx_recc_scm , amps - > rx_recc_mpci , amps - > rx_recc_esn , amps - > rx_recc_min1 , amps - > rx_recc_min2 , amps - > rx_recc_msg_type , amps - > rx_recc_ordq , amps - > rx_recc_order , ( msg_count > 3 ) ? amps - > rx_recc_dialing : NULL ) ;
2016-05-01 17:51:56 +00:00
}
amps - > rx_recc_word_count + + ;
done :
2017-05-21 14:40:10 +00:00
if ( amps - > rx_recc_nawc > 0 )
2016-05-01 17:51:56 +00:00
return 1 ;
return 0 ;
}
/*
* encode and decode bits
*/
static const char * dotting = " 10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101 " ;
static const char * sync_word = " 11100010010 " ;
char * test1 = " 101011101000111001101110100111011111111110100000 " ;
char * test2 = " 000100000011011010000000000110101101001110101011 " ;
#if 0
static uint64_t string2bin ( const char * string )
{
uint64_t bin = 0 ;
while ( * string )
bin = ( bin < < 1 ) | ( ( * string + + ) & 1 ) ;
return bin ;
}
# endif
2016-10-07 06:55:18 +00:00
static void amps_encode_focc_bits ( uint64_t word_a , uint64_t word_b , char * bits )
2016-05-01 17:51:56 +00:00
{
int i , j , k ;
2018-05-20 09:35:06 +00:00
memcpy ( bits + 0 , dotting , 10 ) ;
2016-06-20 15:16:46 +00:00
bits [ 10 ] = ' i ' ;
2016-05-01 17:51:56 +00:00
strcpy ( bits + 11 , sync_word ) ;
2016-06-20 15:16:46 +00:00
bits [ 22 ] = ' i ' ;
2016-05-01 17:51:56 +00:00
k = 23 ;
for ( i = 0 ; i < 5 ; i + + ) {
2017-05-15 15:59:09 +00:00
/* WORD A (msb first) */
2016-05-01 17:51:56 +00:00
for ( j = 39 ; j > = 0 ; j - - ) {
bits [ k + + ] = ( ( word_a > > j ) & 1 ) + ' 0 ' ;
if ( ( j % 10 ) = = 0 )
2016-06-20 15:16:46 +00:00
bits [ k + + ] = ' i ' ;
2016-05-01 17:51:56 +00:00
}
2017-05-15 15:59:09 +00:00
/* WORD B (msb first) */
2016-05-01 17:51:56 +00:00
for ( j = 39 ; j > = 0 ; j - - ) {
bits [ k + + ] = ( ( word_b > > j ) & 1 ) + ' 0 ' ;
if ( ( j % 10 ) = = 0 )
2016-06-20 15:16:46 +00:00
bits [ k + + ] = ' i ' ;
2016-05-01 17:51:56 +00:00
}
}
if ( k ! = 463 )
abort ( ) ;
bits [ 463 ] = ' \0 ' ;
if ( debuglevel = = DEBUG_DEBUG ) {
char text [ 64 ] ;
strncpy ( text , bits , 23 ) ;
text [ 23 ] = ' \0 ' ;
# ifdef BIT_DEBUGGING
PDEBUG ( DFRAME , DEBUG_INFO , " TX FOCC: %s \n " , text ) ;
2017-05-15 15:59:09 +00:00
for ( i = 0 ; i < 10 ; i + + ) {
2016-05-01 17:51:56 +00:00
strncpy ( text , bits + 23 + i * 44 , 44 ) ;
text [ 44 ] = ' \0 ' ;
2017-05-15 15:59:09 +00:00
PDEBUG ( DFRAME , DEBUG_DEBUG , " word %c - %s \n " , ( i & 1 ) ? ' b ' : ' a ' , text ) ;
2016-05-01 17:51:56 +00:00
}
# endif
}
}
2016-10-07 06:55:18 +00:00
static void amps_encode_fvc_bits ( uint64_t word_a , char * bits )
2016-05-01 17:51:56 +00:00
{
int i , j , k ;
k = 0 ;
for ( i = 0 ; i < 11 ; i + + ) {
if ( i = = 0 ) {
2018-05-20 09:35:06 +00:00
memcpy ( bits + k , dotting , 101 ) ;
2016-05-01 17:51:56 +00:00
k + = 101 ;
} else {
2018-05-20 09:35:06 +00:00
memcpy ( bits + k , dotting , 37 ) ;
2016-05-01 17:51:56 +00:00
k + = 37 ;
}
strcpy ( bits + k , sync_word ) ;
k + = 11 ;
for ( j = 39 ; j > = 0 ; j - - )
bits [ k + + ] = ( ( word_a > > j ) & 1 ) + ' 0 ' ;
}
if ( k ! = 1032 )
abort ( ) ;
bits [ 1032 ] = ' \0 ' ;
# ifdef BIT_DEBUGGING
if ( debuglevel = = DEBUG_DEBUG ) {
PDEBUG ( DFRAME , DEBUG_INFO , " TX FVC: %s \n " , bits ) ;
}
# endif
}
2016-06-20 15:16:46 +00:00
int amps_encode_frame_focc ( amps_t * amps , char * bits )
2016-05-01 17:51:56 +00:00
{
uint64_t word ;
/* init overhead train */
if ( amps - > tx_focc_frame_count = = 0 )
prepare_sysinfo ( & amps - > si ) ;
/* send overhead train */
if ( amps - > si . num ) {
word = get_sysinfo ( & amps - > si ) ;
2017-05-30 10:49:40 +00:00
if ( + + amps - > tx_focc_frame_count > = amps - > si . overhead_repeat )
2016-05-01 17:51:56 +00:00
amps - > tx_focc_frame_count = 0 ;
goto send ;
}
/* see if we can schedule a mobile control message */
if ( ! amps - > tx_focc_send ) {
transaction_t * trans ;
trans = amps_tx_frame_focc ( amps ) ;
if ( trans ) {
amps - > tx_focc_min1 = trans - > min1 ;
amps - > tx_focc_min2 = trans - > min2 ;
amps - > tx_focc_msg_type = trans - > msg_type ;
amps - > tx_focc_ordq = trans - > ordq ;
amps - > tx_focc_order = trans - > order ;
amps - > tx_focc_chan = trans - > chan ;
amps - > tx_focc_send = 1 ;
amps - > tx_focc_word_count = 0 ;
amps - > tx_focc_word_repeat = 0 ;
}
/* on change of dsp mode */
if ( amps - > dsp_mode ! = DSP_MODE_FRAME_RX_FRAME_TX )
2016-06-20 15:16:46 +00:00
return 1 ;
2016-05-01 17:51:56 +00:00
}
/* send scheduled mobile control message */
if ( amps - > tx_focc_send ) {
if ( amps - > tx_focc_word_count = = 0 )
word = amps_encode_word1_abbreviated_address_word ( amps - > si . dcc , amps - > tx_focc_min1 , 1 ) ;
else {
if ( amps - > tx_focc_chan )
2017-06-17 10:11:07 +00:00
word = amps_encode_word2_extended_address_word_b ( amps - > sat , amps - > tx_focc_min2 , amps - > si . vmac , amps - > tx_focc_chan ) ;
2016-05-01 17:51:56 +00:00
else
2017-06-17 10:11:07 +00:00
word = amps_encode_word2_extended_address_word_a ( amps - > tx_focc_min2 , amps - > tx_focc_msg_type , amps - > tx_focc_ordq , amps - > tx_focc_order ) ;
2016-05-01 17:51:56 +00:00
}
/* dont wrap frame count until we are done */
+ + amps - > tx_focc_frame_count ;
if ( + + amps - > tx_focc_word_count = = 2 ) {
amps - > tx_focc_word_count = 0 ;
if ( + + amps - > tx_focc_word_repeat = = 3 ) {
amps - > tx_focc_word_repeat = 0 ;
amps - > tx_focc_send = 0 ;
/* now we may wrap */
2017-05-30 10:49:40 +00:00
if ( amps - > tx_focc_frame_count > = amps - > si . overhead_repeat )
2016-05-01 17:51:56 +00:00
amps - > tx_focc_frame_count = 0 ;
}
}
goto send ;
}
/* send filler */
2016-06-20 15:15:42 +00:00
word = amps_encode_control_filler ( amps , amps - > si . dcc , amps - > si . filler . cmac , amps - > si . filler . sdcc1 , amps - > si . filler . sdcc2 , amps - > si . filler . wfom ) ;
2017-05-30 10:49:40 +00:00
if ( + + amps - > tx_focc_frame_count > = amps - > si . overhead_repeat )
2016-05-01 17:51:56 +00:00
amps - > tx_focc_frame_count = 0 ;
send :
2016-10-07 06:55:18 +00:00
amps_encode_focc_bits ( word , word , bits ) ;
2016-05-01 17:51:56 +00:00
2016-06-20 15:16:46 +00:00
return 0 ;
2016-05-01 17:51:56 +00:00
}
2016-06-20 15:16:46 +00:00
int amps_encode_frame_fvc ( amps_t * amps , char * bits )
2016-05-01 17:51:56 +00:00
{
uint64_t word ;
/* see if we can schedule a mobile control message */
if ( ! amps - > tx_fvc_send ) {
transaction_t * trans ;
trans = amps_tx_frame_fvc ( amps ) ;
if ( trans ) {
amps - > tx_fvc_msg_type = trans - > msg_type ;
amps - > tx_fvc_ordq = trans - > ordq ;
amps - > tx_fvc_order = trans - > order ;
amps - > tx_fvc_chan = trans - > chan ;
amps - > tx_fvc_send = 1 ;
}
/* on change of dsp mode */
if ( amps - > dsp_mode ! = DSP_MODE_AUDIO_RX_FRAME_TX )
2016-06-20 15:16:46 +00:00
return 1 ;
2016-05-01 17:51:56 +00:00
}
/* send scheduled mobile control message */
if ( amps - > tx_fvc_send ) {
amps - > tx_fvc_send = 0 ;
if ( amps - > tx_fvc_chan )
2017-05-21 14:40:10 +00:00
word = amps_encode_mobile_station_control_message_word1_b ( amps - > sat , amps - > sat , ( amps - > si . word2 . dtx ) ? 1 : 0 , 0 , 0 , amps - > si . vmac , amps - > tx_fvc_chan ) ;
2016-05-01 17:51:56 +00:00
else
word = amps_encode_mobile_station_control_message_word1_a ( amps - > sat , amps - > tx_fvc_msg_type , amps - > tx_fvc_ordq , amps - > tx_fvc_order ) ;
} else
2016-06-20 15:16:46 +00:00
return 1 ;
2016-05-01 17:51:56 +00:00
2016-10-07 06:55:18 +00:00
amps_encode_fvc_bits ( word , bits ) ;
2016-05-01 17:51:56 +00:00
2016-06-20 15:16:46 +00:00
return 0 ;
2016-05-01 17:51:56 +00:00
}
/* assemble FOCC bits */
2016-10-07 06:55:18 +00:00
static void amps_decode_bits_focc ( amps_t * amps , const char * bits )
2016-05-01 17:51:56 +00:00
{
char word_string [ 41 ] ;
uint64_t word_a [ 5 ] , word_b [ 5 ] , word ;
int crc_a_ok [ 5 ] , crc_b_ok [ 5 ] , crc_ok ;
int idle ;
int i , j , k , crc_i , crc_j ;
bits + + ; /* skip B/I after sync */
idle = 0 ;
for ( i = 0 ; i < 10 ; i + + ) {
word = 0 ;
for ( j = 0 , k = 0 ; j < 44 ; j + + ) {
if ( j % 11 = = 10 ) {
idle + = ( * bits + + ) & 1 ;
continue ;
}
word_string [ k + + ] = * bits ;
word = ( word < < 1 ) | ( ( * bits + + ) & 1 ) ;
}
word_string [ k ] = ' \0 ' ;
if ( ! strncmp ( encode_bch ( word_string , 28 ) , word_string + 28 , 12 ) )
crc_ok = 1 ;
else
crc_ok = 0 ;
2017-06-04 14:11:13 +00:00
if ( ( i & 1 ) = = 0 ) {
word_a [ i > > 1 ] = word ;
crc_a_ok [ i > > 1 ] = crc_ok ;
2016-05-01 17:51:56 +00:00
} else {
2017-06-04 14:11:13 +00:00
word_b [ i > > 1 ] = word ;
crc_b_ok [ i > > 1 ] = crc_ok ;
2016-05-01 17:51:56 +00:00
}
}
bits - = 440 ;
if ( idle > 20 )
idle = 1 ;
else
idle = 0 ;
2016-12-09 15:34:33 +00:00
PDEBUG_CHAN ( DFRAME , DEBUG_INFO , " RX FOCC: B/I = %s \n " , ( idle ) ? " idle " : " busy " ) ;
2016-05-01 17:51:56 +00:00
if ( debuglevel = = DEBUG_DEBUG ) {
char text [ 64 ] ;
2017-05-15 15:59:09 +00:00
for ( i = 0 ; i < 10 ; i + + ) {
2016-05-01 17:51:56 +00:00
strncpy ( text , bits + i * 44 , 44 ) ;
text [ 44 ] = ' \0 ' ;
2017-06-04 14:11:13 +00:00
if ( ( i & 1 ) = = 0 )
PDEBUG_CHAN ( DFRAME , DEBUG_DEBUG , " word a - %s%s \n " , text , ( crc_a_ok [ i > > 1 ] ) ? " ok " : " BAD CRC! " ) ;
else
PDEBUG_CHAN ( DFRAME , DEBUG_DEBUG , " word b - %s%s \n " , text , ( crc_b_ok [ i > > 1 ] ) ? " ok " : " BAD CRC! " ) ;
2016-05-01 17:51:56 +00:00
}
}
for ( crc_i = 0 ; crc_i < 5 ; crc_i + + ) {
if ( crc_a_ok [ crc_i ] )
break ;
}
if ( crc_i < 5 ) {
amps_decode_word_focc ( amps , word_a [ crc_i ] ) ;
}
for ( crc_j = 0 ; crc_j < 5 ; crc_j + + ) {
if ( crc_b_ok [ crc_j ] )
break ;
}
if ( crc_j < 5 & & word_b [ crc_j ] ! = word_a [ crc_i ] ) {
amps_decode_word_focc ( amps , word_b [ crc_j ] ) ;
}
}
/* assemble RECC bits, return true, if more bits are expected */
2016-10-07 06:55:18 +00:00
static int amps_decode_bits_recc ( amps_t * amps , const char * bits , int first )
2016-05-01 17:51:56 +00:00
{
char word_string [ 49 ] ;
int8_t dcc = - 1 ;
uint64_t word_a [ 5 ] , word ;
2016-10-28 15:07:38 +00:00
int crc_a_ok [ 5 ] , crc_ok , crc_ok_count = 0 ;
2016-05-01 17:51:56 +00:00
int i , j , k , crc_i ;
const char * bits_ = bits ; /* for extra check */
/* decode color code */
if ( first ) {
dcc = 0 ;
for ( j = 0 ; j < 7 ; j + + ) {
dcc = ( dcc < < 1 ) | ( ( * bits + + ) & 1 ) ;
}
dcc = dcc_decode [ dcc ] ;
}
/* assemble word */
for ( i = 0 ; i < 5 ; i + + ) {
word = 0 ;
for ( j = 0 , k = 0 ; j < 48 ; j + + ) {
word_string [ k + + ] = * bits ;
word = ( word < < 1 ) | ( ( * bits + + ) & 1 ) ;
}
word_string [ k ] = ' \0 ' ;
2016-10-28 15:07:38 +00:00
if ( ! strncmp ( encode_bch ( word_string , 36 ) , word_string + 36 , 12 ) ) {
2016-05-01 17:51:56 +00:00
crc_ok = 1 ;
2016-10-28 15:07:38 +00:00
crc_ok_count + + ;
} else
2016-05-01 17:51:56 +00:00
crc_ok = 0 ;
2017-06-04 14:11:13 +00:00
word_a [ i ] = word ;
crc_a_ok [ i ] = crc_ok ;
2016-05-01 17:51:56 +00:00
}
bits - = 240 ;
2016-10-28 15:07:38 +00:00
if ( crc_ok_count = = 0 ) {
2016-05-01 17:51:56 +00:00
/* check if we receive frame in a loop */
crc_ok = 0 ;
bits_ + + ; /* skip B/I after sync */
for ( i = 0 ; i < 5 ; i + + ) {
word = 0 ;
for ( j = 0 , k = 0 ; j < 44 ; j + + ) {
if ( j % 11 = = 10 ) {
bits_ + + ;
continue ;
}
word_string [ k + + ] = * bits_ ;
word = ( word < < 1 ) | ( ( * bits_ + + ) & 1 ) ;
}
word_string [ k ] = ' \0 ' ;
if ( ! strncmp ( encode_bch ( word_string , 28 ) , word_string + 28 , 12 ) )
crc_ok + + ;
}
2016-06-19 15:41:42 +00:00
if ( crc_ok ) {
2016-12-09 15:34:33 +00:00
PDEBUG_CHAN ( DFRAME , DEBUG_NOTICE , " Seems we RX FOCC frame due to loopback, ignoring! \n " ) ;
2016-05-01 17:51:56 +00:00
return 0 ;
}
bits_ - = 221 ;
}
2016-10-28 15:07:38 +00:00
for ( crc_i = 0 ; crc_i < 5 ; crc_i + + ) {
if ( crc_a_ok [ crc_i ] )
break ;
}
2016-05-01 17:51:56 +00:00
if ( first ) {
2016-10-28 15:07:38 +00:00
if ( debuglevel = = DEBUG_DEBUG | | crc_ok_count > 0 ) {
2016-12-09 15:34:33 +00:00
PDEBUG_CHAN ( DFRAME , DEBUG_INFO , " RX RECC: DCC=%d (%d of 5 CRCs are ok) \n " , dcc , crc_ok_count ) ;
2016-05-01 17:51:56 +00:00
if ( dcc ! = amps - > si . dcc ) {
PDEBUG ( DFRAME , DEBUG_INFO , " received DCC=%d missmatches the base station's DCC=%d \n " , dcc , amps - > si . dcc ) ;
return 0 ;
}
}
2016-10-28 15:07:38 +00:00
} else {
if ( debuglevel = = DEBUG_DEBUG | | crc_ok_count > 0 )
2016-12-09 15:34:33 +00:00
PDEBUG_CHAN ( DFRAME , DEBUG_INFO , " RX RECC: (%d of 5 CRCs are ok) \n " , crc_ok_count ) ;
2016-05-01 17:51:56 +00:00
}
if ( debuglevel = = DEBUG_DEBUG ) {
char text [ 64 ] ;
for ( i = 0 ; i < 5 ; i + + ) {
strncpy ( text , bits + i * 48 , 48 ) ;
text [ 48 ] = ' \0 ' ;
2017-06-04 14:11:13 +00:00
PDEBUG_CHAN ( DFRAME , DEBUG_DEBUG , " word - %s%s \n " , text , ( crc_a_ok [ i ] ) ? " ok " : " BAD CRC! " ) ;
2016-05-01 17:51:56 +00:00
}
}
2016-10-28 15:07:38 +00:00
if ( crc_ok_count > 0 )
2016-05-01 17:51:56 +00:00
return amps_decode_word_recc ( amps , word_a [ crc_i ] , first ) ;
return 0 ;
}
int amps_decode_frame ( amps_t * amps , const char * bits , int count , double level , double quality , int negative )
{
int more = 0 ;
/* not if additional words are received without sync */
2016-06-20 15:15:42 +00:00
if ( count ! = 240 ) {
2016-12-09 15:34:33 +00:00
PDEBUG_CHAN ( DDSP , DEBUG_INFO , " RX Level: %.0f%% Quality: %.0f%% Polarity: %s \n " , level * 100.0 , quality * 100.0 , ( negative ) ? " NEGATIVE " : " POSITIVE " ) ;
2016-06-20 15:15:42 +00:00
}
2016-05-01 17:51:56 +00:00
if ( count = = 441 ) {
amps_decode_bits_focc ( amps , bits ) ;
} else if ( count = = 247 ) {
more = amps_decode_bits_recc ( amps , bits , 1 ) ;
} else if ( count = = 240 ) {
more = amps_decode_bits_recc ( amps , bits , 0 ) ;
} else {
2019-07-15 19:14:52 +00:00
PDEBUG_CHAN ( DFRAME , DEBUG_ERROR , " Frame with unknown length = %d, please fix! \n " , count ) ;
2016-05-01 17:51:56 +00:00
}
return more ;
}