2018-05-19 08:56:43 +00:00
/* JollyCom main
2017-11-12 14:59:48 +00:00
*
* ( C ) 2017 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/>.
*/
# include <stdio.h>
# include <stdint.h>
# include <stdlib.h>
# include <string.h>
# include <fcntl.h>
# include <unistd.h>
2018-05-19 08:56:43 +00:00
# include <errno.h>
2017-11-12 14:59:48 +00:00
# include <math.h>
# include <sys/types.h>
# include <sys/stat.h>
# include "../libsample/sample.h"
# include "../libmobile/main_mobile.h"
# include "../libdebug/debug.h"
# include "../libtimer/timer.h"
# include "../anetz/freiton.h"
# include "../anetz/besetztton.h"
2018-05-19 08:56:43 +00:00
# include "../liboptions/options.h"
2017-11-12 14:59:48 +00:00
# include "jolly.h"
# include "dsp.h"
# include "voice.h"
/* settings */
int num_freq = 0 ;
double dl_freq = 438.600 ;
double ul_freq = 431.000 ;
double step = 25.0 ;
static double squelch_db = - INFINITY ;
int nbfm = 0 ;
int repeater = 0 ;
2021-09-24 14:09:19 +00:00
const char * aaimage [ ] = { NULL } ;
2019-06-30 06:10:33 +00:00
2017-11-12 14:59:48 +00:00
void print_help ( const char * arg0 )
{
main_mobile_print_help ( arg0 , " [-F <downlink MHz>,<uplink MHz>] " ) ;
/* - - */
printf ( " -F --frequency <downlink MHz>,<uplink MHz>,<step KHz> \n " ) ;
printf ( " Downlink and uplink frequency to use for channel 0. \n " ) ;
printf ( " Give step for channel spacing. (default = %.3f,%.3f,%.4f) \n " , dl_freq , ul_freq , step ) ;
printf ( " -S --squelch <dB> | auto \n " ) ;
printf ( " Use given RF level to detect loss of signal. When the signal gets lost \n " ) ;
printf ( " and stays below this level, the connection is released. \n " ) ;
printf ( " Use 'auto' to do automatic noise floor calibration to detect loss. \n " ) ;
printf ( " Only works with SDR! (disabled by default) \n " ) ;
printf ( " -N --nbfm \n " ) ;
printf ( " Use Narrow band FM with deviation of 2.5 KHz instead of 5.0 KHz. \n " ) ;
printf ( " -R --relay \n " ) ;
printf ( " Use transceiver as repeater, so multiple radios can communicate with \n " ) ;
printf ( " each other. It is still possible to make and receive calls. Multiple \n " ) ;
printf ( " radios can talk then to the calling/called party. \n " ) ;
2021-10-07 17:35:56 +00:00
main_mobile_print_station_id ( ) ;
2017-11-12 14:59:48 +00:00
main_mobile_print_hotkeys ( ) ;
}
2018-05-19 08:56:43 +00:00
static void add_options ( void )
2017-11-12 14:59:48 +00:00
{
2018-05-19 08:56:43 +00:00
main_mobile_add_options ( ) ;
option_add ( ' F ' , " frequency " , 1 ) ;
option_add ( ' S ' , " squelch " , 1 ) ;
option_add ( ' N ' , " nbfm " , 0 ) ;
option_add ( ' R ' , " repeater " , 0 ) ;
}
static int handle_options ( int short_option , int argi , char * * argv )
{
char * string , * string_dl , * string_ul , * string_step ;
switch ( short_option ) {
case ' F ' :
2021-01-25 14:16:29 +00:00
string = options_strdup ( argv [ argi ] ) ;
2018-05-19 08:56:43 +00:00
string_dl = strsep ( & string , " , " ) ;
string_ul = strsep ( & string , " , " ) ;
string_step = strsep ( & string , " , " ) ;
if ( ! string_dl | | ! string_ul | | ! string_step ) {
2019-07-15 19:14:52 +00:00
fprintf ( stderr , " Please give 3 values for --frequency, separated by comma and no space! \n " ) ;
2018-05-19 08:56:43 +00:00
exit ( 0 ) ;
2017-11-12 14:59:48 +00:00
}
2018-05-19 08:56:43 +00:00
dl_freq = atof ( string_dl ) ;
ul_freq = atof ( string_ul ) ;
step = atof ( string_step ) ;
break ;
case ' S ' :
if ( ! strcasecmp ( argv [ argi ] , " auto " ) )
squelch_db = 0.0 ;
else
squelch_db = atof ( argv [ argi ] ) ;
break ;
case ' N ' :
nbfm = 1 ;
break ;
case ' R ' :
repeater = 1 ;
break ;
default :
return main_mobile_handle_options ( short_option , argi , argv ) ;
2017-11-12 14:59:48 +00:00
}
2018-05-19 08:56:43 +00:00
return 1 ;
2017-11-12 14:59:48 +00:00
}
2021-10-07 17:35:56 +00:00
static const struct number_lengths number_lengths [ ] = {
{ 4 , " number " } ,
{ 0 , NULL }
} ;
2017-11-12 14:59:48 +00:00
int main ( int argc , char * argv [ ] )
{
2018-05-19 08:56:43 +00:00
int rc , argi ;
2017-11-12 14:59:48 +00:00
const char * station_id = " " ;
int mandatory = 0 ;
int i ;
/* init tones */
init_freiton ( ) ;
init_besetzton ( ) ;
// init_ansage();
2021-10-07 17:35:56 +00:00
/* init mobile interface */
main_mobile_init ( " 0123456789 " , number_lengths , NULL , NULL ) ;
2017-11-12 14:59:48 +00:00
2018-05-19 08:56:43 +00:00
/* handle options / config file */
add_options ( ) ;
2021-03-11 06:38:00 +00:00
rc = options_config_file ( argc , argv , " ~/.osmocom/analog/jollycom.conf " , handle_options ) ;
2018-05-19 08:56:43 +00:00
if ( rc < 0 )
return 0 ;
argi = options_command_line ( argc , argv , handle_options ) ;
if ( argi < = 0 )
return argi ;
2017-11-12 14:59:48 +00:00
2018-05-19 08:56:43 +00:00
if ( argi < argc ) {
station_id = argv [ argi ] ;
2021-10-07 17:35:56 +00:00
rc = main_mobile_number_ask ( station_id , " station ID " ) ;
if ( rc )
return rc ;
2017-11-12 14:59:48 +00:00
}
if ( ! num_kanal ) {
printf ( " No channel ( \" Kanal \" ) is specified, Please use channel 0. \n \n " ) ;
mandatory = 1 ;
}
if ( use_sdr ) {
2021-09-18 09:43:01 +00:00
/* set device */
2017-11-12 14:59:48 +00:00
for ( i = 0 ; i < num_kanal ; i + + )
2021-09-18 09:43:01 +00:00
dsp_device [ i ] = " sdr " ;
num_device = num_kanal ;
2017-11-12 14:59:48 +00:00
}
2021-09-18 09:43:01 +00:00
if ( num_kanal = = 1 & & num_device = = 0 )
num_device = 1 ; /* use default */
if ( num_kanal ! = num_device ) {
2017-11-12 14:59:48 +00:00
fprintf ( stderr , " You need to specify as many sound devices as you have channels. \n " ) ;
exit ( 0 ) ;
}
if ( mandatory ) {
2018-05-19 08:56:43 +00:00
print_help ( argv [ 0 ] ) ;
2017-11-12 14:59:48 +00:00
return 0 ;
}
/* SDR always requires emphasis */
if ( use_sdr ) {
do_pre_emphasis = 1 ;
do_de_emphasis = 1 ;
}
/* no SDR, no squelch */
if ( ! use_sdr & & ! isinf ( squelch_db ) ) {
fprintf ( stderr , " Cannot use squelch without SDR! Analog receivers don't give use RSSI. \n " ) ;
goto fail ;
}
2018-11-10 14:16:20 +00:00
/* inits */
fm_init ( fast_math ) ;
2021-09-18 09:43:01 +00:00
init_voice ( dsp_samplerate ) ;
2017-11-12 14:59:48 +00:00
dsp_init ( ) ;
/* create transceiver instance */
for ( i = 0 ; i < num_kanal ; i + + ) {
2021-09-18 09:43:01 +00:00
rc = jolly_create ( kanal [ i ] , dl_freq , ul_freq , step , dsp_device [ i ] , use_sdr , dsp_samplerate , rx_gain , tx_gain , do_pre_emphasis , do_de_emphasis , write_rx_wave , write_tx_wave , read_rx_wave , read_tx_wave , loopback , squelch_db , nbfm , repeater ) ;
2017-11-12 14:59:48 +00:00
if ( rc < 0 ) {
fprintf ( stderr , " Failed to create transceiver instance. Quitting! \n " ) ;
goto fail ;
}
2019-07-20 16:11:17 +00:00
printf ( " base station on channel %s ready, please tune transmitter to %.4f MHz and receiver to %.4f MHz. (%.4f MHz offset) \n " , kanal [ i ] , dl_freq + step / 1e3 * ( double ) atoi ( kanal [ i ] ) , ul_freq + step / 1e3 * ( double ) atoi ( kanal [ i ] ) , ul_freq - dl_freq ) ;
2017-11-12 14:59:48 +00:00
}
2021-10-07 17:35:56 +00:00
main_mobile_loop ( " jollycom " , & quit , NULL , station_id ) ;
2017-11-12 14:59:48 +00:00
fail :
/* destroy transceiver instance */
while ( sender_head )
jolly_destroy ( sender_head ) ;
2018-11-10 14:16:20 +00:00
/* exits */
fm_exit ( ) ;
2021-01-25 14:16:29 +00:00
options_free ( ) ;
2017-11-12 14:59:48 +00:00
return 0 ;
}