From d63d625151d435017d0a7a155acc1631d9d7b999 Mon Sep 17 00:00:00 2001 From: John Melton G0ORX Date: Wed, 20 May 2020 08:42:14 +0100 Subject: [PATCH] Rewrite of rigctl (CAT commands) --- agc_menu.c | 12 +- band_menu.c | 12 +- client_server.c | 2502 ++++++++++++++++++++ client_server.h | 516 +++++ discovered.h | 5 +- discovery.c | 349 ++- exit_menu.c | 31 +- ext.c | 523 ++++- ext.h | 112 +- freqent_menu.c | 31 +- gpio.c | 34 +- main.c | 28 +- new_menu.c | 22 + new_menu.h | 3 + new_protocol.c | 5 - noise_menu.c | 14 +- noise_menu.h | 1 + pa_menu.h | 1 - radio.c | 726 +++--- radio.h | 22 +- radio_menu.c | 27 +- radio_menu.h | 1 + receiver.c | 692 +++--- receiver.h | 12 + rigctl.c | 5514 ++++++++++++++++++++------------------------- rigctl_menu.c | 38 +- rigctl_menu.h | 3 +- rx_panadapter.c | 50 +- server_menu.c | 121 + server_menu.h | 20 + sliders.c | 67 +- soapy_discovery.c | 4 +- soapy_protocol.c | 2 +- toolbar.c | 174 +- update.c | 2 +- vfo.c | 86 +- vfo.h | 8 +- vfo_menu.c | 16 +- waterfall.c | 14 +- zoompan.c | 73 +- zoompan.h | 3 + 41 files changed, 7640 insertions(+), 4236 deletions(-) create mode 100644 client_server.c create mode 100644 client_server.h create mode 100644 server_menu.c create mode 100644 server_menu.h diff --git a/agc_menu.c b/agc_menu.c index bf8ec11..5670218 100644 --- a/agc_menu.c +++ b/agc_menu.c @@ -59,8 +59,16 @@ static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_d static void agc_select_cb (GtkToggleButton *widget, gpointer data) { if(gtk_toggle_button_get_active(widget)) { active_receiver->agc=GPOINTER_TO_INT(data); - set_agc(active_receiver, active_receiver->agc); - g_idle_add(ext_vfo_update, NULL); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_agc(client_socket,active_receiver->id,active_receiver->agc); + } else { +#endif + set_agc(active_receiver, active_receiver->agc); + g_idle_add(ext_vfo_update, NULL); +#ifdef CLIENT_SERVER + } +#endif } } diff --git a/band_menu.c b/band_menu.c index bc79bed..30c70b7 100644 --- a/band_menu.c +++ b/band_menu.c @@ -32,6 +32,7 @@ #include "receiver.h" #include "vfo.h" #include "button_text.h" +#include "client_server.h" static GtkWidget *parent_window=NULL; @@ -62,7 +63,15 @@ gboolean band_select_cb (GtkWidget *widget, gpointer data) { set_button_text_color(last_band,"black"); last_band=widget; set_button_text_color(last_band,"orange"); - vfo_band_changed(b); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_band(client_socket,active_receiver->id,b); + } else { +#endif + vfo_band_changed(active_receiver->id,b); +#ifdef CLIENT_SERVER + } +#endif return FALSE; } @@ -103,6 +112,7 @@ void band_menu(GtkWidget *parent) { long long frequency_min=radio->frequency_min; long long frequency_max=radio->frequency_max; +g_print("band_menu: min=%lld max=%lld\n",frequency_min,frequency_max); j=0; for(i=0;i + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef __APPLE__ +#include +#endif +#include + +#include "discovered.h" +#include "adc.h" +#include "dac.h" +#include "receiver.h" +#include "transmitter.h" +#include "radio.h" +#include "main.h" +#include "vfo.h" +#ifdef CLIENT_SERVER +#include "client_server.h" +#endif +#include "ext.h" +#include "audio.h" + +#define DISCOVERY_PORT 4992 +#define LISTEN_PORT 50000 + +gint listen_port=LISTEN_PORT; + +REMOTE_CLIENT *clients=NULL; + +GMutex client_mutex; + +#define MAX_COMMAND 256 + +enum { + NO_ACTION, + SET, + MOVE, + MOVETO, + GET, + START, + STOP, +}; + +static char title[128]; + +gboolean hpsdr_server=FALSE; + +gint client_socket=-1; +GThread *client_thread_id; +gint start_spectrum(void *data); +gboolean remote_started=FALSE; + +static GThread *listen_thread_id; +static char status[1024]; +static int n_status=0; +static char reply[64]; +static gboolean running; +static gint listen_socket; + +static int audio_buffer_index=0; +AUDIO_DATA audio_data; + + +GMutex accumulated_mutex; +static int accumulated_steps=0; +static long long accumulated_hz=0LL; +static gboolean accumulated_round=FALSE; +gint check_vfo_timer_id=-1; + +REMOTE_CLIENT *add_client(REMOTE_CLIENT *client) { +g_print("add_client: %p\n",client); +// add to front of queue + g_mutex_lock(&client_mutex); + client->next=clients; + clients=client; + g_mutex_unlock(&client_mutex); +g_print("add_client: clients=%p\n",clients); + return client; +} + +void delete_client(REMOTE_CLIENT *client) { +g_print("delete_client: %p\n",client); + g_mutex_lock(&client_mutex); + if(clients==client) { + clients=client->next; + g_free(client); + } else { + REMOTE_CLIENT* c=clients; + REMOTE_CLIENT* last_c=NULL; + while(c!=NULL && c!=client) { + last_c=c; + c=c->next; + } + if(c!=NULL) { + last_c->next=c->next; + g_free(c); + } + } +g_print("delete_client: clients=%p\n",clients); + g_mutex_unlock(&client_mutex); +} + +static int recv_bytes(int s,char *buffer,int bytes) { + int bytes_read=0; + int rc; + while(bytes_read!=bytes) { + rc=recv(s,&buffer[bytes_read],bytes-bytes_read,0); + if(rc<0) { + bytes_read=rc; + perror("recv_bytes"); + break; + } else { + bytes_read+=rc; + } + } + return bytes_read; +} + +static int send_bytes(int s,char *buffer,int bytes) { + int bytes_sent=0; + int rc; + if(s<0) return -1; + while(bytes_sent!=bytes) { + rc=send(s,&buffer[bytes_sent],bytes-bytes_sent,0); + if(rc<0) { + bytes_sent=rc; + perror("send_bytes"); + break; + } else { + bytes_sent+=rc; + } + } + return bytes_sent; +} + +void remote_audio(RECEIVER *rx,short left_sample,short right_sample) { + int i=audio_buffer_index*2; + audio_data.sample[i]=htons(left_sample); + audio_data.sample[i+1]=htons(right_sample); + audio_buffer_index++; + if(audio_buffer_index>=AUDIO_DATA_SIZE) { + g_mutex_lock(&client_mutex); + REMOTE_CLIENT *c=clients; + while(c!=NULL && c->socket!=-1) { + audio_data.header.sync=REMOTE_SYNC; + audio_data.header.data_type=htons(INFO_AUDIO); + audio_data.header.version=htonll(CLIENT_SERVER_VERSION); + audio_data.rx=rx->id; + audio_data.samples=ntohs(audio_buffer_index); + int bytes_sent=send_bytes(c->socket,(char *)&audio_data,sizeof(audio_data)); + if(bytes_sent<0) { + perror("remote_audio"); + if(c->socket!=-1) { + close(c->socket); + } + } + c=c->next; + } + g_mutex_unlock(&client_mutex); + audio_buffer_index=0; + } +} + +static gint send_spectrum(void *arg) { + REMOTE_CLIENT *client=(REMOTE_CLIENT *)arg; + float *samples; + double sample; + short s; + SPECTRUM_DATA spectrum_data; + gint result; + + result=TRUE; + + if(!(client->receiver[0].send_spectrum || client->receiver[1].send_spectrum) || !client->running) { + client->spectrum_update_timer_id=-1; +g_print("send_spectrum: no more receivers\n"); + return FALSE; + } + + for(int r=0;rreceiver[r].send_spectrum) { + if(rx->displaying && (rx->pixels>0) && (rx->pixel_samples!=NULL)) { + g_mutex_lock(&rx->display_mutex); + spectrum_data.header.sync=REMOTE_SYNC; + spectrum_data.header.data_type=htons(INFO_SPECTRUM); + spectrum_data.header.version=htonll(CLIENT_SERVER_VERSION); + spectrum_data.rx=r; + spectrum_data.vfo_a_freq=htonll(vfo[VFO_A].frequency); + spectrum_data.vfo_b_freq=htonll(vfo[VFO_B].frequency); + spectrum_data.vfo_a_ctun_freq=htonll(vfo[VFO_A].ctun_frequency); + spectrum_data.vfo_b_ctun_freq=htonll(vfo[VFO_B].ctun_frequency); + spectrum_data.vfo_a_offset=htonll(vfo[VFO_A].offset); + spectrum_data.vfo_b_offset=htonll(vfo[VFO_B].offset); + s=(short)receiver[r]->meter; + spectrum_data.meter=htons(s); + spectrum_data.samples=htons(rx->width); + samples=rx->pixel_samples; + for(int i=0;iwidth;i++) { + s=(short)samples[i+rx->pan]; + spectrum_data.sample[i]=htons(s); + } + // send the buffer + int bytes_sent=send_bytes(client->socket,(char *)&spectrum_data,sizeof(spectrum_data)); + if(bytes_sent<0) { + result=FALSE; + } + g_mutex_unlock(&rx->display_mutex); + } + } + } + return result; +} + +void send_radio_data(REMOTE_CLIENT *client) { + RADIO_DATA radio_data; + radio_data.header.sync=REMOTE_SYNC; + radio_data.header.data_type=htons(INFO_RADIO); + radio_data.header.version=htonl(CLIENT_SERVER_VERSION); + strcpy(radio_data.name,radio->name); + radio_data.protocol=htons(radio->protocol); + radio_data.device=htons(radio->device); + uint64_t temp=(uint64_t)radio->frequency_min; + radio_data.frequency_min=htonll(temp); + temp=(uint64_t)radio->frequency_max; + radio_data.frequency_max=htonll(temp); + long long rate=(long long)radio_sample_rate; + radio_data.sample_rate=htonll(rate); + radio_data.display_filled=display_filled; + radio_data.locked=locked; + radio_data.supported_receivers=htons(radio->supported_receivers); + radio_data.receivers=htons(receivers); + radio_data.can_transmit=can_transmit; + radio_data.step=htonll(step); + radio_data.split=split; + radio_data.sat_mode=sat_mode; + radio_data.duplex=duplex; + radio_data.have_rx_gain=have_rx_gain; + radio_data.rx_gain_calibration=htons(rx_gain_calibration); + radio_data.filter_board=htons(filter_board); + + int bytes_sent=send_bytes(client->socket,(char *)&radio_data,sizeof(radio_data)); +g_print("send_radio_data: %d\n",bytes_sent); + if(bytes_sent<0) { + perror("send_radio_data"); + } else { + //g_print("send_radio_data: %d\n",bytes_sent); + } +} + +void send_adc_data(REMOTE_CLIENT *client,int i) { + ADC_DATA adc_data; + adc_data.header.sync=REMOTE_SYNC; + adc_data.header.data_type=htons(INFO_ADC); + adc_data.header.version=htonl(CLIENT_SERVER_VERSION); + adc_data.adc=i; + adc_data.filters=htons(adc[i].filters); + adc_data.hpf=htons(adc[i].hpf); + adc_data.lpf=htons(adc[i].lpf); + adc_data.antenna=htons(adc[i].antenna); + adc_data.dither=adc[i].dither; + adc_data.random=adc[i].random; + adc_data.preamp=adc[i].preamp; + adc_data.attenuation=htons(adc[i].attenuation); + adc_data.adc_attenuation=htons(adc_attenuation[i]); + int bytes_sent=send_bytes(client->socket,(char *)&adc_data,sizeof(adc_data)); + if(bytes_sent<0) { + perror("send_adc_data"); + } else { + //g_print("send_adc_data: %d\n",bytes_sent); + } +} + +void send_receiver_data(REMOTE_CLIENT *client,int rx) { + RECEIVER_DATA receiver_data; + receiver_data.header.sync=REMOTE_SYNC; + receiver_data.header.data_type=htons(INFO_RECEIVER); + receiver_data.header.version=htonl(CLIENT_SERVER_VERSION); + receiver_data.rx=rx; + receiver_data.adc=htons(receiver[rx]->adc); + long long rate=(long long)receiver[rx]->sample_rate; + receiver_data.sample_rate=htonll(rate); + receiver_data.displaying=receiver[rx]->displaying; + receiver_data.display_panadapter=receiver[rx]->display_panadapter; + receiver_data.display_waterfall=receiver[rx]->display_waterfall; + receiver_data.fps=htons(receiver[rx]->fps); + receiver_data.agc=receiver[rx]->agc; + short s=(short)receiver[rx]->agc_hang; + receiver_data.agc_hang=htons(s); + s=(short)receiver[rx]->agc_thresh; + receiver_data.agc_thresh=htons(s); + receiver_data.nb=receiver[rx]->nb; + receiver_data.nb2=receiver[rx]->nb2; + receiver_data.nr=receiver[rx]->nr; + receiver_data.nr2=receiver[rx]->nr2; + receiver_data.anf=receiver[rx]->anf; + receiver_data.snb=receiver[rx]->snb; + receiver_data.filter_low=htons(receiver[rx]->filter_low); + receiver_data.filter_high=htons(receiver[rx]->filter_high); + receiver_data.panadapter_low=htons(receiver[rx]->panadapter_low); + receiver_data.panadapter_high=htons(receiver[rx]->panadapter_high); + receiver_data.panadapter_step=htons(receiver[rx]->panadapter_step); + receiver_data.waterfall_low=htons(receiver[rx]->waterfall_low); + receiver_data.waterfall_high=htons(receiver[rx]->waterfall_high); + receiver_data.waterfall_automatic=receiver[rx]->waterfall_automatic; + receiver_data.pixels=htons(receiver[rx]->pixels); + receiver_data.zoom=htons(receiver[rx]->zoom); + receiver_data.pan=htons(receiver[rx]->pan); + receiver_data.width=htons(receiver[rx]->width); + receiver_data.height=htons(receiver[rx]->height); + receiver_data.x=htons(receiver[rx]->x); + receiver_data.y=htons(receiver[rx]->y); + s=(short)(receiver[rx]->volume*100.0); + receiver_data.volume=htons(s); + s=(short)receiver[rx]->rf_gain; + receiver_data.rf_gain=htons(s); + s=(short)receiver[rx]->agc_gain; + receiver_data.agc_gain=htons(s); + + int bytes_sent=send_bytes(client->socket,(char *)&receiver_data,sizeof(receiver_data)); + if(bytes_sent<0) { + perror("send_receiver_data"); + } else { + //g_print("send_receiver_data: bytes sent %d\n",bytes_sent); + } +} + +void send_vfo_data(REMOTE_CLIENT *client,int v) { + VFO_DATA vfo_data; + vfo_data.header.sync=REMOTE_SYNC; + vfo_data.header.data_type=htons(INFO_VFO); + vfo_data.header.version=htonl(CLIENT_SERVER_VERSION); + vfo_data.vfo=v; + vfo_data.band=htons(vfo[v].band); + vfo_data.bandstack=htons(vfo[v].bandstack); + vfo_data.frequency=htonll(vfo[v].frequency); + vfo_data.mode=htons(vfo[v].mode); + vfo_data.filter=htons(vfo[v].filter); + vfo_data.ctun=vfo[v].ctun; + vfo_data.ctun_frequency=htonll(vfo[v].ctun_frequency); + vfo_data.rit_enabled=vfo[v].rit_enabled; + vfo_data.rit=htonll(vfo[v].rit); + vfo_data.lo=htonll(vfo[v].lo); + vfo_data.offset=htonll(vfo[v].offset); + + int bytes_sent=send_bytes(client->socket,(char *)&vfo_data,sizeof(vfo_data)); + if(bytes_sent<0) { + perror("send_vfo_data"); + } else { + //g_print("send_vfo_data: bytes sent %d\n",bytes_sent); + } +} + +static void *server_client_thread(void *arg) { + REMOTE_CLIENT *client=(REMOTE_CLIENT *)arg; + int bytes_read; + HEADER header; + +g_print("Client connected on port %d\n",client->address.sin_port); + send_radio_data(client); + send_adc_data(client,0); + send_adc_data(client,1); + for(int i=0;irunning) { + bytes_read=recv_bytes(client->socket,(char *)&header.sync,sizeof(header.sync)); + if(bytes_read<=0) { + g_print("server_client_thread: read %d bytes for HEADER SYNC\n",bytes_read); + perror("server_client_thread"); + client->running=FALSE; + continue; + } + +g_print("header.sync is %x\n",header.sync); + + if(header.sync!=REMOTE_SYNC) { +g_print("header.sync is %x wanted %x\n",header.sync,REMOTE_SYNC); + int syncs=0; + char c; + while(syncs!=sizeof(header.sync) && client->running) { + // try to resync on 2 0xFA bytes + bytes_read=recv_bytes(client->socket,(char *)&c,1); + if(bytes_read<=0) { + g_print("server_client_thread: read %d bytes for HEADER RESYNC\n",bytes_read); + perror("server_client_thread"); + client->running=FALSE; + continue; + } + if(c==(char)0xFA) { + syncs++; + } else { + syncs=0; + } + } + } + + bytes_read=recv_bytes(client->socket,(char *)&header.data_type,sizeof(header)-sizeof(header.sync)); + if(bytes_read<=0) { + g_print("server_client_thread: read %d bytes for HEADER\n",bytes_read); + perror("server_client_thread"); + client->running=FALSE; + continue; + } +g_print("header remaining bytes %d\n",bytes_read); + +g_print("server_client_thread: received header: type=%d\n",ntohs(header.data_type)); + + switch(ntohs(header.data_type)) { + case CMD_RESP_SPECTRUM: + { + SPECTRUM_COMMAND spectrum_command; + bytes_read=recv_bytes(client->socket,(char *)&spectrum_command.id,sizeof(SPECTRUM_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for SPECTRUM_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + + int rx=spectrum_command.id; + int state=spectrum_command.start_stop; +g_print("server_client_thread: CMD_RESP_SPECTRUM rx=%d state=%d timer_id=%d\n",rx,state,client->spectrum_update_timer_id); + if(state) { + client->receiver[rx].receiver=rx; + client->receiver[rx].spectrum_fps=receiver[rx]->fps; + client->receiver[rx].spectrum_port=0; + client->receiver[rx].send_spectrum=TRUE; + if(client->spectrum_update_timer_id==-1) { +g_print("start send_spectrum thread: fps=%d\n",client->receiver[rx].spectrum_fps); + client->spectrum_update_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,1000/client->receiver[rx].spectrum_fps, send_spectrum, client, NULL); +g_print("spectrum_update_timer_id=%d\n",client->spectrum_update_timer_id); + } else { +g_print("send_spectrum thread already running\n"); + } + } else { + client->receiver[rx].send_spectrum=FALSE; + } + } + break; + case CMD_RESP_RX_FREQ: +g_print("server_client_thread: CMD_RESP_RX_FREQ\n"); + { + FREQ_COMMAND *freq_command=g_new(FREQ_COMMAND,1); + freq_command->header.data_type=header.data_type; + freq_command->header.version=header.version; + freq_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&freq_command->id,sizeof(FREQ_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for FREQ_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,freq_command); + } + break; + case CMD_RESP_RX_STEP: +g_print("server_client_thread: CMD_RESP_RX_STEP\n"); + { + STEP_COMMAND *step_command=g_new(STEP_COMMAND,1); + step_command->header.data_type=header.data_type; + step_command->header.version=header.version; + step_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&step_command->id,sizeof(STEP_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for STEP_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,step_command); + } + break; + case CMD_RESP_RX_MOVE: +g_print("server_client_thread: CMD_RESP_RX_MOVE\n"); + { + MOVE_COMMAND *move_command=g_new(MOVE_COMMAND,1); + move_command->header.data_type=header.data_type; + move_command->header.version=header.version; + move_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&move_command->id,sizeof(MOVE_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for MOVE_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,move_command); + } + break; + case CMD_RESP_RX_MOVETO: +g_print("server_client_thread: CMD_RESP_RX_MOVETO\n"); + { + MOVE_TO_COMMAND *move_to_command=g_new(MOVE_TO_COMMAND,1); + move_to_command->header.data_type=header.data_type; + move_to_command->header.version=header.version; + move_to_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&move_to_command->id,sizeof(MOVE_TO_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for MOVE_TO_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,move_to_command); + } + break; + case CMD_RESP_RX_ZOOM: +g_print("server_client_thread: CMD_RESP_RX_ZOOM\n"); + { + ZOOM_COMMAND *zoom_command=g_new(ZOOM_COMMAND,1); + zoom_command->header.data_type=header.data_type; + zoom_command->header.version=header.version; + zoom_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&zoom_command->id,sizeof(ZOOM_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for ZOOM_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,zoom_command); + } + break; + case CMD_RESP_RX_PAN: +g_print("server_client_thread: CMD_RESP_RX_PAN\n"); + { + PAN_COMMAND *pan_command=g_new(PAN_COMMAND,1); + pan_command->header.data_type=header.data_type; + pan_command->header.version=header.version; + pan_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&pan_command->id,sizeof(PAN_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for PAN_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,pan_command); + } + break; + case CMD_RESP_RX_VOLUME: +g_print("server_client_thread: CMD_RESP_RX_VOLUME\n"); + { + VOLUME_COMMAND *volume_command=g_new(VOLUME_COMMAND,1); + volume_command->header.data_type=header.data_type; + volume_command->header.version=header.version; + volume_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&volume_command->id,sizeof(VOLUME_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for VOLUME_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,volume_command); + } + break; + case CMD_RESP_RX_AGC: +g_print("server_client_thread: CMD_RESP_RX_AGC\n"); + { + AGC_COMMAND *agc_command=g_new(AGC_COMMAND,1); + agc_command->header.data_type=header.data_type; + agc_command->header.version=header.version; + agc_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&agc_command->id,sizeof(AGC_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for AGC_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } +g_print("CMD_RESP_RX_AGC: id=%d agc=%d\n",agc_command->id,ntohs(agc_command->agc)); + g_idle_add(ext_remote_command,agc_command); + } + break; + case CMD_RESP_RX_AGC_GAIN: +g_print("server_client_thread: CMD_RESP_RX_AGC_GAIN\n"); + { + AGC_GAIN_COMMAND *agc_gain_command=g_new(AGC_GAIN_COMMAND,1); + agc_gain_command->header.data_type=header.data_type; + agc_gain_command->header.version=header.version; + agc_gain_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&agc_gain_command->id,sizeof(AGC_GAIN_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for AGC_GAIN_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,agc_gain_command); + } + break; + case CMD_RESP_RX_ATTENUATION: +g_print("server_client_thread: CMD_RESP_RX_ATTENUATION\n"); + { + ATTENUATION_COMMAND *attenuation_command=g_new(ATTENUATION_COMMAND,1); + attenuation_command->header.data_type=header.data_type; + attenuation_command->header.version=header.version; + attenuation_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&attenuation_command->id,sizeof(ATTENUATION_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for ATTENUATION_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,attenuation_command); + } + break; + case CMD_RESP_RX_SQUELCH: +g_print("server_client_thread: CMD_RESP_RX_SQUELCH\n"); + { + SQUELCH_COMMAND *squelch_command=g_new(SQUELCH_COMMAND,1); + squelch_command->header.data_type=header.data_type; + squelch_command->header.version=header.version; + squelch_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&squelch_command->id,sizeof(SQUELCH_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for SQUELCH_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,squelch_command); + } + break; + case CMD_RESP_RX_NOISE: +g_print("server_client_thread: CMD_RESP_RX_NOISE\n"); + { + NOISE_COMMAND *noise_command=g_new(NOISE_COMMAND,1); + noise_command->header.data_type=header.data_type; + noise_command->header.version=header.version; + noise_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&noise_command->id,sizeof(NOISE_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for NOISE_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,noise_command); + } + break; + case CMD_RESP_RX_BAND: +g_print("server_client_thread: CMD_RESP_RX_BAND\n"); + { + BAND_COMMAND *band_command=g_new(BAND_COMMAND,1); + band_command->header.data_type=header.data_type; + band_command->header.version=header.version; + band_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&band_command->id,sizeof(BAND_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for BAND_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,band_command); + } + break; + case CMD_RESP_RX_MODE: +g_print("server_client_thread: CMD_RESP_RX_MODE\n"); + { + MODE_COMMAND *mode_command=g_new(MODE_COMMAND,1); + mode_command->header.data_type=header.data_type; + mode_command->header.version=header.version; + mode_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&mode_command->id,sizeof(MODE_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for MODE_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,mode_command); + } + break; + case CMD_RESP_RX_FILTER: +g_print("server_client_thread: CMD_RESP_RX_FILTER\n"); + { + FILTER_COMMAND *filter_command=g_new(FILTER_COMMAND,1); + filter_command->header.data_type=header.data_type; + filter_command->header.version=header.version; + filter_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&filter_command->id,sizeof(FILTER_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for FILTER_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,filter_command); + } + break; + case CMD_RESP_SPLIT: +g_print("server_client_thread: CMD_RESP_RX_SPLIT\n"); + { + SPLIT_COMMAND *split_command=g_new(SPLIT_COMMAND,1); + split_command->header.data_type=header.data_type; + split_command->header.version=header.version; + split_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&split_command->split,sizeof(SPLIT_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for SPLIT_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,split_command); + } + break; + case CMD_RESP_SAT: +g_print("server_client_thread: CMD_RESP_RX_SAT\n"); + { + SAT_COMMAND *sat_command=g_new(SAT_COMMAND,1); + sat_command->header.data_type=header.data_type; + sat_command->header.version=header.version; + sat_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&sat_command->sat,sizeof(SAT_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for SAT_COMMAND\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,sat_command); + } + break; + case CMD_RESP_DUP: +g_print("server_client_thread: CMD_RESP_DUP\n"); + { + DUP_COMMAND *dup_command=g_new(DUP_COMMAND,1); + dup_command->header.data_type=header.data_type; + dup_command->header.version=header.version; + dup_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&dup_command->dup,sizeof(DUP_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for DUP\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,dup_command); + } + break; + case CMD_RESP_LOCK: +g_print("server_client_thread: CMD_RESP_LOCK\n"); + { + LOCK_COMMAND *lock_command=g_new(LOCK_COMMAND,1); + lock_command->header.data_type=header.data_type; + lock_command->header.version=header.version; + lock_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&lock_command->lock,sizeof(LOCK_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for LOCK\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,lock_command); + } + break; + case CMD_RESP_CTUN: +g_print("server_client_thread: CMD_RESP_CTUN\n"); + { + CTUN_COMMAND *ctun_command=g_new(CTUN_COMMAND,1); + ctun_command->header.data_type=header.data_type; + ctun_command->header.version=header.version; + ctun_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&ctun_command->id,sizeof(CTUN_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for CTUN\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,ctun_command); + } + break; + case CMD_RESP_RX_FPS: +g_print("server_client_thread: CMD_RESP_RX_FPS\n"); + { + FPS_COMMAND *fps_command=g_new(FPS_COMMAND,1); + fps_command->header.data_type=header.data_type; + fps_command->header.version=header.version; + fps_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&fps_command->id,sizeof(FPS_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for FPS\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,fps_command); + } + break; + case CMD_RESP_RX_SELECT: +g_print("server_client_thread: CMD_RESP_RX_SELECT\n"); + { + RX_SELECT_COMMAND *rx_select_command=g_new(RX_SELECT_COMMAND,1); + rx_select_command->header.data_type=header.data_type; + rx_select_command->header.version=header.version; + rx_select_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&rx_select_command->id,sizeof(RX_SELECT_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for RX_SELECT\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,rx_select_command); + } + break; + case CMD_RESP_VFO: +g_print("server_client_thread: CMD_RESP_VFO\n"); + { + VFO_COMMAND *vfo_command=g_new(VFO_COMMAND,1); + vfo_command->header.data_type=header.data_type; + vfo_command->header.version=header.version; + vfo_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&vfo_command->id,sizeof(VFO_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for VFO\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,vfo_command); + } + break; + case CMD_RESP_RIT_UPDATE: +g_print("server_client_thread: CMD_RESP_RIT_UPDATE\n"); + { + RIT_UPDATE_COMMAND *rit_update_command=g_new(RIT_UPDATE_COMMAND,1); + rit_update_command->header.data_type=header.data_type; + rit_update_command->header.version=header.version; + rit_update_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&rit_update_command->id,sizeof(RIT_UPDATE_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for RIT_UPDATE\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,rit_update_command); + } + break; + case CMD_RESP_RIT_CLEAR: +g_print("server_client_thread: CMD_RESP_RIT_CLEAR\n"); + { + RIT_CLEAR_COMMAND *rit_clear_command=g_new(RIT_CLEAR_COMMAND,1); + rit_clear_command->header.data_type=header.data_type; + rit_clear_command->header.version=header.version; + rit_clear_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&rit_clear_command->id,sizeof(RIT_CLEAR_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for RIT_CLEAR\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,rit_clear_command); + } + break; + case CMD_RESP_RIT: +g_print("server_client_thread: CMD_RESP_RIT\n"); + { + RIT_COMMAND *rit_command=g_new(RIT_COMMAND,1); + rit_command->header.data_type=header.data_type; + rit_command->header.version=header.version; + rit_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&rit_command->id,sizeof(RIT_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for RIT\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,rit_command); + } + break; + case CMD_RESP_XIT_UPDATE: +g_print("server_client_thread: CMD_RESP_XIT_UPDATE\n"); + { + XIT_UPDATE_COMMAND *xit_update_command=g_new(XIT_UPDATE_COMMAND,1); + xit_update_command->header.data_type=header.data_type; + xit_update_command->header.version=header.version; + xit_update_command->header.context.client=client; + g_idle_add(ext_remote_command,xit_update_command); + } + break; + case CMD_RESP_XIT_CLEAR: +g_print("server_client_thread: CMD_RESP_XIT_CLEAR\n"); + { + XIT_CLEAR_COMMAND *xit_clear_command=g_new(XIT_CLEAR_COMMAND,1); + xit_clear_command->header.data_type=header.data_type; + xit_clear_command->header.version=header.version; + xit_clear_command->header.context.client=client; + g_idle_add(ext_remote_command,xit_clear_command); + } + break; + case CMD_RESP_XIT: +g_print("server_client_thread: CMD_RESP_XIT\n"); + { + XIT_COMMAND *xit_command=g_new(XIT_COMMAND,1); + xit_command->header.data_type=header.data_type; + xit_command->header.version=header.version; + xit_command->header.context.client=client; + g_idle_add(ext_remote_command,xit_command); + } + break; + case CMD_RESP_SAMPLE_RATE: +g_print("server_client_thread: CMD_RESP_SAMPLE_RATE\n"); + { + SAMPLE_RATE_COMMAND *sample_rate_command=g_new(SAMPLE_RATE_COMMAND,1); + sample_rate_command->header.data_type=header.data_type; + sample_rate_command->header.version=header.version; + sample_rate_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&sample_rate_command->id,sizeof(SAMPLE_RATE_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for SAMPLE_RATE\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,sample_rate_command); + } + break; + case CMD_RESP_RECEIVERS: +g_print("server_client_thread: CMD_RESP_RECEIVERS\n"); + { + RECEIVERS_COMMAND *receivers_command=g_new(RECEIVERS_COMMAND,1); + receivers_command->header.data_type=header.data_type; + receivers_command->header.version=header.version; + receivers_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&receivers_command->receivers,sizeof(RECEIVERS_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for RECEIVERS\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,receivers_command); + } + break; + case CMD_RESP_RIT_INCREMENT: +g_print("server_client_thread: CMD_RESP_RIT_INCREMENT\n"); + { + RIT_INCREMENT_COMMAND *rit_increment_command=g_new(RIT_INCREMENT_COMMAND,1); + rit_increment_command->header.data_type=header.data_type; + rit_increment_command->header.version=header.version; + rit_increment_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&rit_increment_command->increment,sizeof(RIT_INCREMENT_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for RIT_INCREMENT\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,rit_increment_command); + } + break; + case CMD_RESP_FILTER_BOARD: +g_print("server_client_thread: CMD_RESP_FILTER_BOARD\n"); + { + FILTER_BOARD_COMMAND *filter_board_command=g_new(FILTER_BOARD_COMMAND,1); + filter_board_command->header.data_type=header.data_type; + filter_board_command->header.version=header.version; + filter_board_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&filter_board_command->filter_board,sizeof(FILTER_BOARD_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for FILTER_BOARD\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,filter_board_command); + } + break; + case CMD_RESP_SWAP_IQ: +g_print("server_client_thread: CMD_RESP_SWAP_IQ\n"); + { + SWAP_IQ_COMMAND *swap_iq_command=g_new(SWAP_IQ_COMMAND,1); + swap_iq_command->header.data_type=header.data_type; + swap_iq_command->header.version=header.version; + swap_iq_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&swap_iq_command->iqswap,sizeof(SWAP_IQ_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for SWAP_IQ\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,swap_iq_command); + } + break; + case CMD_RESP_REGION: +g_print("server_client_thread: CMD_RESP_REGION\n"); + { + REGION_COMMAND *region_command=g_new(REGION_COMMAND,1); + region_command->header.data_type=header.data_type; + region_command->header.version=header.version; + region_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)®ion_command->region,sizeof(REGION_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for REGION\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,region_command); + } + break; + case CMD_RESP_MUTE_RX: +g_print("server_client_thread: CMD_RESP_MUTE_RX\n"); + { + MUTE_RX_COMMAND *mute_rx_command=g_new(MUTE_RX_COMMAND,1); + mute_rx_command->header.data_type=header.data_type; + mute_rx_command->header.version=header.version; + mute_rx_command->header.context.client=client; + bytes_read=recv_bytes(client->socket,(char *)&mute_rx_command->mute,sizeof(MUTE_RX_COMMAND)-sizeof(header)); + if(bytes_read<0) { + g_print("server_client_thread: read %d bytes for MUTE_RX\n",bytes_read); + perror("server_client_thread"); + // dialog box? + return NULL; + } + g_idle_add(ext_remote_command,mute_rx_command); + } + break; + + + + + + default: +g_print("server_client_thread: UNKNOWN command: %d\n",ntohs(header.data_type)); + break; + } + + } + + // close the socket to force listen to terminate +g_print("client disconnected\n"); + if(client->socket!=-1) { + close(client->socket); + client->socket=-1; + } + delete_client(client); + return NULL; +} + +void send_start_spectrum(int s,int rx) { + SPECTRUM_COMMAND command; + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_SPECTRUM); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.start_stop=1; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_vfo_frequency(int s,int rx,long long hz) { + FREQ_COMMAND command; + + g_print("send_vfo_frequency\n"); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_FREQ); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.hz=htonll(hz); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_vfo_move_to(int s,int rx,long long hz) { + MOVE_TO_COMMAND command; + g_print("send_vfo_move_to\n"); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_MOVETO); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.hz=htonll(hz); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_vfo_move(int s,int rx,long long hz,int round) { + MOVE_COMMAND command; + + g_print("send_vfo_move\n"); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_MOVE); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.hz=htonll(hz); + command.round=round; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void update_vfo_move(int rx,long long hz,int round) { + g_mutex_lock(&accumulated_mutex); + accumulated_hz+=hz; + accumulated_round=round; + g_mutex_unlock(&accumulated_mutex); +} + +void send_vfo_step(int s,int rx,int steps) { + STEP_COMMAND command; + + short stps=(short)steps; + g_print("send_vfo_step rx=%d steps=%d s=%d\n",rx,steps,stps); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_STEP); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.steps=htons(stps); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void update_vfo_step(int rx,int steps) { + g_mutex_lock(&accumulated_mutex); + accumulated_steps+=steps; + g_mutex_unlock(&accumulated_mutex); +} + +void send_zoom(int s,int rx,int zoom) { + ZOOM_COMMAND command; + short z=(short)zoom; +g_print("send_zoom rx=%d zoom=%d\n",rx,zoom); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_ZOOM); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.zoom=htons(z); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_pan(int s,int rx,int pan) { + PAN_COMMAND command; + short p=(short)pan; +g_print("send_pan rx=%d pan=%d\n",rx,pan); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_PAN); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.pan=htons(p); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_volume(int s,int rx,int volume) { + VOLUME_COMMAND command; + short v=(short)volume; +g_print("send_volume rx=%d volume=%d\n",rx,volume); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_VOLUME); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.volume=htons(v); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_agc(int s,int rx,int agc) { + AGC_COMMAND command; + short a=(short)agc; +g_print("send_agc rx=%d agc=%d\n",rx,agc); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_AGC); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.agc=htons(a); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_agc_gain(int s,int rx,int gain,int hang,int thresh) { + AGC_GAIN_COMMAND command; + short g=(short)gain; + short h=(short)hang; + short t=(short)thresh; +g_print("send_agc_gain rx=%d gain=%d\n",rx,gain); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_AGC_GAIN); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.gain=htons(g); + command.hang=htons(h); + command.thresh=htons(t); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_attenuation(int s,int rx,int attenuation) { + ATTENUATION_COMMAND command; + short a=(short)attenuation; +g_print("send_attenuation rx=%d attenuation=%d\n",rx,attenuation); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_ATTENUATION); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.attenuation=htons(a); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_squelch(int s,int rx,int enable,int squelch) { + SQUELCH_COMMAND command; + short sq=(short)squelch; +g_print("send_squelch rx=%d enable=%d squelch=%d\n",rx,enable,squelch); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_SQUELCH); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.enable=enable; + command.squelch=htons(sq); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_noise(int s,int rx,int nb,int nb2,int nr,int nr2,int anf,int snb) { + NOISE_COMMAND command; +g_print("send_noise rx=%d nb=%d nb2=%d nr=%d nr2=%d anf=%d snb=%d\n",rx,nb,nb2,nr,nr2,anf,snb); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_NOISE); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.nb=nb; + command.nb2=nb2; + command.nr=nr; + command.nr2=nr2; + command.anf=anf; + command.snb=snb; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_band(int s,int rx,int band) { + BAND_COMMAND command; +g_print("send_band rx=%d band=%d\n",rx,band); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_BAND); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.band=htons(band); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_mode(int s,int rx,int mode) { + MODE_COMMAND command; +g_print("send_mode rx=%d mode=%d\n",rx,mode); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_MODE); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.mode=htons(mode); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_filter(int s,int rx,int filter) { + FILTER_COMMAND command; +g_print("send_filter rx=%d filter=%d\n",rx,filter); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_FILTER); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.filter=htons(filter); + command.filter_low=htons(receiver[rx]->filter_low); + command.filter_high=htons(receiver[rx]->filter_high); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_split(int s,int split) { + SPLIT_COMMAND command; +g_print("send_split split=%d\n",split); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_SPLIT); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.split=split; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_sat(int s,int sat) { + SAT_COMMAND command; +g_print("send_sat sat=%d\n",sat); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_SAT); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.sat=sat; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_dup(int s,int dup) { + DUP_COMMAND command; +g_print("send_dup dup=%d\n",dup); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_DUP); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.dup=dup; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_fps(int s,int rx,int fps) { + FPS_COMMAND command; +g_print("send_fps rx=%d fps=%d\n",rx,fps); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_FPS); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.fps=htons(fps); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_lock(int s,int lock) { + LOCK_COMMAND command; +g_print("send_lock lock=%d\n",lock); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_LOCK); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.lock=lock; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_ctun(int s,int vfo,int ctun) { + CTUN_COMMAND command; +g_print("send_ctun vfo=%d ctun=%d\n",vfo,ctun); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_CTUN); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=vfo; + command.ctun=ctun; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_rx_select(int s,int rx) { + RX_SELECT_COMMAND command; +g_print("send_rx_select rx=%d\n",rx); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RX_SELECT); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_vfo(int s,int action) { + VFO_COMMAND command; +g_print("send_vfo action=%d\n",action); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_VFO); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=action; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_rit_update(int s,int rx) { + RIT_UPDATE_COMMAND command; +g_print("send_rit_enable rx=%d\n",rx); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RIT_UPDATE); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_rit_clear(int s,int rx) { + RIT_CLEAR_COMMAND command; +g_print("send_rit_clear rx=%d\n",rx); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RIT_CLEAR); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_rit(int s,int rx,int rit) { + RIT_COMMAND command; +g_print("send_rit rx=%d rit=%d\n",rx,rit); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RIT); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.rit=htons(rit); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_xit_update(int s) { + XIT_UPDATE_COMMAND command; +g_print("send_xit_update\n"); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RIT_UPDATE); + command.header.version=htonl(CLIENT_SERVER_VERSION); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_xit_clear(int s) { + XIT_CLEAR_COMMAND command; +g_print("send_xit_clear\n"); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_XIT_CLEAR); + command.header.version=htonl(CLIENT_SERVER_VERSION); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_xit(int s,int xit) { + XIT_COMMAND command; +g_print("send_xit xit=%d\n",xit); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_XIT); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.xit=htons(xit); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_sample_rate(int s,int rx,int sample_rate) { + SAMPLE_RATE_COMMAND command; + + long long rate=(long long)sample_rate; + g_print("send_sample_rate rx=%d rate=%lld\n",rx,rate); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_SAMPLE_RATE); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.id=rx; + command.sample_rate=htonll(rate); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_receivers(int s,int receivers) { + RECEIVERS_COMMAND command; + + g_print("send_receivers receivers=%d\n",receivers); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RECEIVERS); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.receivers=receivers; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } +} + +void send_rit_increment(int s,int increment) { + RIT_INCREMENT_COMMAND command; + +g_print("send_rit_increment increment=%d\n",increment); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_RIT_INCREMENT); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.increment=htons(increment); + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } + +} + +void send_filter_board(int s,int filter_board) { + FILTER_BOARD_COMMAND command; + +g_print("send_filter_board filter_board=%d\n",filter_board); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_FILTER_BOARD); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.filter_board=filter_board; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } + +} + +void send_swap_iq(int s,int iqswap) { + SWAP_IQ_COMMAND command; + +g_print("send_swap_iq iqswap=%d\n",iqswap); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_SWAP_IQ); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.iqswap=iqswap; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } + +} + +void send_region(int s,int region) { + REGION_COMMAND command; + +g_print("send_region region=%d\n",region); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_REGION); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.region=region; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } + +} + +void send_mute_rx(int s,int mute) { + MUTE_RX_COMMAND command; + +g_print("send_mute_rx mute=%d\n",mute); + command.header.sync=REMOTE_SYNC; + command.header.data_type=htons(CMD_RESP_MUTE_RX); + command.header.version=htonl(CLIENT_SERVER_VERSION); + command.mute=mute; + int bytes_sent=send_bytes(s,(char *)&command,sizeof(command)); + if(bytes_sent<0) { + perror("send_command"); + } else { + //g_print("send_command: %d\n",bytes_sent); + } + +} + + +static void *listen_thread(void *arg) { + int address_length; + struct sockaddr_in address; + REMOTE_CLIENT* client; + int rc; + int on=1; + +g_print("hpsdr_server: listening on port %d\n",listen_port); + while(running) { + // create TCP socket to listen on + listen_socket=socket(AF_INET,SOCK_STREAM,0); + if(listen_socket<0) { + g_print("listen_thread: socket failed\n"); + return NULL; + } + + setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + setsockopt(listen_socket, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)); + + // bind to listening port + memset(&address,0,sizeof(address)); + address.sin_family=AF_INET; + address.sin_addr.s_addr=INADDR_ANY; + address.sin_port=htons(listen_port); + if(bind(listen_socket,(struct sockaddr*)&address,sizeof(address))<0) { + g_print("listen_thread: bind failed\n"); + return NULL; + } + + // listen for connections + if(listen(listen_socket,5)<0) { + g_print("listen_thread: listen failed\n"); + break; + } + REMOTE_CLIENT* client=g_new(REMOTE_CLIENT,1); + client->spectrum_update_timer_id=-1; + client->address_length=sizeof(client->address); + client->running=TRUE; +g_print("hpsdr_server: accept\n"); + if((client->socket=accept(listen_socket,(struct sockaddr*)&client->address,&client->address_length))<0) { + g_print("listen_thread: accept failed\n"); + g_free(client); + continue; + } + char s[128]; + inet_ntop(AF_INET, &(((struct sockaddr_in *)&client->address)->sin_addr),s,128); +g_print("Client_connected from %s\n",s); + client->thread_id=g_thread_new("SSDR_client",server_client_thread,client); + add_client(client); + close(listen_socket); + gpointer thread_result=g_thread_join(client->thread_id); + } + return NULL; +} + +int create_hpsdr_server() { + g_print("create_hpsdr_server\n"); + + g_mutex_init(&client_mutex); + clients=NULL; + running=TRUE; + listen_thread_id = g_thread_new( "HPSDR_listen", listen_thread, NULL); + return 0; +} + +int destroy_hpsdr_server() { +g_print("destroy_hpsdr_server\n"); + running=FALSE; + return 0; +} + +// CLIENT Code + +static gint check_vfo(void *arg) { + if(!running) return FALSE; + + g_mutex_lock(&accumulated_mutex); + + if(accumulated_steps!=0) { + send_vfo_step(client_socket,active_receiver->id,accumulated_steps); + accumulated_steps=0; + } + + if(accumulated_hz!=0LL || accumulated_round) { + send_vfo_move(client_socket,active_receiver->id,accumulated_hz,accumulated_round); + accumulated_hz=0LL; + accumulated_round=FALSE; + } + + g_mutex_unlock(&accumulated_mutex); + + return TRUE; +} + +static char server_host[128]; +static int delay=0; + +gint start_spectrum(void *data) { + RECEIVER *rx=(RECEIVER *)data; + + if(delay!=3) { + delay++; +g_print("start_spectrum: delay %d\n",delay); + return TRUE; + } + send_start_spectrum(client_socket,rx->id); + return FALSE; +} + +void start_vfo_timer() { + g_mutex_init(&accumulated_mutex); + check_vfo_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,100,check_vfo, NULL, NULL); +g_print("check_vfo_timer_id %d\n",check_vfo_timer_id); +} + +static void *client_thread(void* arg) { + gint bytes_read; +#define MAX_BUFFER 2400 + char buffer[MAX_BUFFER]; + char *token; + HEADER header; + char *server=(char *)arg; + + running=TRUE; + + while(running) { + bytes_read=recv_bytes(client_socket,(char *)&header,sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for HEADER\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + + switch(ntohs(header.data_type)) { + case INFO_RADIO: + { + RADIO_DATA radio_data; + bytes_read=recv_bytes(client_socket,(char *)&radio_data.name,sizeof(radio_data)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for RADIO_DATA\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + +g_print("INFO_RADIO: %d\n",bytes_read); + // build a radio (discovered) structure + radio=g_new(DISCOVERED,1); + strcpy(radio->name,radio_data.name); + radio->protocol=ntohs(radio_data.protocol); + radio->device=ntohs(radio_data.device); + uint64_t temp=ntohll(radio_data.frequency_min); + radio->frequency_min=(double)temp; + temp=ntohll(radio_data.frequency_max); + radio->frequency_max=(double)temp; + radio->supported_receivers=ntohs(radio_data.supported_receivers); + temp=ntohll(radio_data.sample_rate); + radio_sample_rate=(int)temp; +#ifdef SOAPYSDR + if(protocol==SOAPYSDR_PROTOCOL) { + radio->info.soapy.sample_rate=(int)temp; + } +#endif + display_filled=radio_data.display_filled; + locked=radio_data.locked; + receivers=ntohs(radio_data.receivers); + can_transmit=radio_data.can_transmit; +//TEMP +can_transmit=0; + step=ntohll(radio_data.step); + split=radio_data.split; + sat_mode=radio_data.sat_mode; + duplex=radio_data.duplex; + protocol=radio->protocol; + have_rx_gain=radio_data.have_rx_gain; + short s=ntohs(radio_data.rx_gain_calibration); + rx_gain_calibration=(int)s; + filter_board=ntohs(radio_data.filter_board); +g_print("have_rx_gain=%d rx_gain_calibration=%d filter_board=%d\n",have_rx_gain,rx_gain_calibration,filter_board); +// +// A semaphore for safely writing to the props file +// + g_mutex_init(&property_mutex); + + sprintf(title,"piHPSDR: %s remote at %s",radio->name,server); + g_idle_add(ext_set_title,(void *)title); + + } + break; + case INFO_ADC: + { + ADC_DATA adc_data; + bytes_read=recv_bytes(client_socket,(char *)&adc_data.adc,sizeof(adc_data)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for ADC_DATA\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } +g_print("INFO_ADC: %d\n",bytes_read); + int i=adc_data.adc; + adc[i].filters=ntohs(adc_data.filters); + adc[i].hpf=ntohs(adc_data.hpf); + adc[i].lpf=ntohs(adc_data.lpf); + adc[i].antenna=ntohs(adc_data.antenna); + adc[i].dither=adc_data.dither; + adc[i].random=adc_data.random; + adc[i].preamp=adc_data.preamp; + adc[i].attenuation=ntohs(adc_data.attenuation); + adc_attenuation[i]=ntohs(adc_data.adc_attenuation); + } + break; + case INFO_RECEIVER: + { + RECEIVER_DATA receiver_data; + bytes_read=recv_bytes(client_socket,(char *)&receiver_data.rx,sizeof(receiver_data)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for RECEIVER_DATA\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + +g_print("INFO_RECEIVER: %d\n",bytes_read); + int rx=receiver_data.rx; + receiver[rx]=g_new(RECEIVER,1); + receiver[rx]->id=rx; + receiver[rx]->adc=ntohs(receiver_data.adc);; + long long rate=ntohll(receiver_data.sample_rate); + receiver[rx]->sample_rate=(int)rate; + receiver[rx]->displaying=receiver_data.displaying; + receiver[rx]->display_panadapter=receiver_data.display_panadapter; + receiver[rx]->display_waterfall=receiver_data.display_waterfall; + receiver[rx]->fps=ntohs(receiver_data.fps); + receiver[rx]->agc=receiver_data.agc; + short s=ntohs(receiver_data.agc_hang); + receiver[rx]->agc_hang=(double)s; + s=ntohs(receiver_data.agc_thresh); + receiver[rx]->agc_thresh=(double)s; + receiver[rx]->nb=receiver_data.nb; + receiver[rx]->nb2=receiver_data.nb2; + receiver[rx]->nr=receiver_data.nr; + receiver[rx]->nr2=receiver_data.nr2; + receiver[rx]->anf=receiver_data.anf; + receiver[rx]->snb=receiver_data.snb; + s=ntohs(receiver_data.filter_low); + receiver[rx]->filter_low=(int)s; + s=ntohs(receiver_data.filter_high); + receiver[rx]->filter_high=(int)s; + s=ntohs(receiver_data.panadapter_low); + receiver[rx]->panadapter_low=(int)s; + s=ntohs(receiver_data.panadapter_high); + receiver[rx]->panadapter_high=(int)s; + s=ntohs(receiver_data.panadapter_step); + receiver[rx]->panadapter_step=s; + s=ntohs(receiver_data.waterfall_low); + receiver[rx]->waterfall_low=(int)s; + s=ntohs(receiver_data.waterfall_high); + receiver[rx]->waterfall_high=s; + receiver[rx]->waterfall_automatic=receiver_data.waterfall_automatic; + receiver[rx]->pixels=ntohs(receiver_data.pixels); + receiver[rx]->zoom=ntohs(receiver_data.zoom); + receiver[rx]->pan=ntohs(receiver_data.pan); + receiver[rx]->width=ntohs(receiver_data.width); + receiver[rx]->height=ntohs(receiver_data.height); + receiver[rx]->x=ntohs(receiver_data.x); + receiver[rx]->y=ntohs(receiver_data.y); + s=ntohs(receiver_data.volume); + receiver[rx]->volume=(double)s/100.0; + s=ntohs(receiver_data.rf_gain); + receiver[rx]->rf_gain=(double)s; + s=ntohs(receiver_data.agc_gain); + receiver[rx]->agc_gain=(double)s; +// + receiver[rx]->pixel_samples=NULL; + g_mutex_init(&receiver[rx]->display_mutex); + receiver[rx]->hz_per_pixel=(double)receiver[rx]->sample_rate/(double)receiver[rx]->pixels; + + receiver[rx]->playback_handle=NULL; + receiver[rx]->local_audio_buffer=NULL; + receiver[rx]->local_audio_buffer_size=2048; + receiver[rx]->local_audio=0; + g_mutex_init(&receiver[rx]->local_audio_mutex); + receiver[rx]->audio_name=NULL; + receiver[rx]->mute_when_not_active=0; + receiver[rx]->audio_channel=STEREO; + receiver[rx]->audio_device=-1; + receiver[rx]->mute_radio=0; + +g_print("rx=%d width=%d sample_rate=%d hz_per_pixel=%f pan=%d zoom=%d\n",rx,receiver[rx]->width,receiver[rx]->sample_rate,receiver[rx]->hz_per_pixel,receiver[rx]->pan,receiver[rx]->zoom); + } + break; + case INFO_TRANSMITTER: + { +g_print("INFO_TRANSMITTER\n"); + } + break; + case INFO_VFO: + { + VFO_DATA vfo_data; + bytes_read=recv_bytes(client_socket,(char *)&vfo_data.vfo,sizeof(vfo_data)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for VFO_DATA\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + +g_print("INFO_VFO: %d\n",bytes_read); + + int v=vfo_data.vfo; + vfo[v].band=ntohs(vfo_data.band); + vfo[v].bandstack=ntohs(vfo_data.bandstack); + vfo[v].frequency=ntohll(vfo_data.frequency); + vfo[v].mode=ntohs(vfo_data.mode); + vfo[v].filter=ntohs(vfo_data.filter); + vfo[v].ctun=vfo_data.ctun; + vfo[v].ctun_frequency=ntohll(vfo_data.ctun_frequency); + vfo[v].rit_enabled=vfo_data.rit_enabled; + vfo[v].rit=ntohll(vfo_data.rit); + vfo[v].lo=ntohll(vfo_data.lo); + vfo[v].offset=ntohll(vfo_data.offset); + + // when VFO-B is initialized we can create the visual. start the MIDI interface and start the data flowing + if(v==VFO_B && !remote_started) { +g_print("g_idle_add: remote_start\n"); + g_idle_add(remote_start,(gpointer)server); + } else if(remote_started) { +g_print("g_idle_add: ext_vfo_update\n"); + g_idle_add(ext_vfo_update,(gpointer)NULL); + } + } + break; + case INFO_SPECTRUM: + { + SPECTRUM_DATA spectrum_data; + bytes_read=recv_bytes(client_socket,(char *)&spectrum_data.rx,sizeof(spectrum_data)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for SPECTRUM_DATA\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + int r=spectrum_data.rx; + long long frequency_a=ntohll(spectrum_data.vfo_a_freq); + long long frequency_b=ntohll(spectrum_data.vfo_b_freq); + long long ctun_frequency_a=ntohll(spectrum_data.vfo_a_ctun_freq); + long long ctun_frequency_b=ntohll(spectrum_data.vfo_b_ctun_freq); + long long offset_a=ntohll(spectrum_data.vfo_a_offset); + long long offset_b=ntohll(spectrum_data.vfo_b_offset); + short meter=ntohs(spectrum_data.meter); + receiver[r]->meter=(double)meter; + short samples=ntohs(spectrum_data.samples); + if(receiver[r]->pixel_samples==NULL) { + receiver[r]->pixel_samples=g_new(float,(int)samples); + } + + short sample; + for(int i=0;ipixel_samples[i]=(float)sample; + } + if(vfo[VFO_A].frequency!=frequency_a || vfo[VFO_B].frequency!=frequency_b || vfo[VFO_A].ctun_frequency!=ctun_frequency_a || vfo[VFO_B].ctun_frequency!=ctun_frequency_b || vfo[VFO_A].offset!=offset_a || vfo[VFO_B].offset!=offset_b) { + vfo[VFO_A].frequency=frequency_a; + vfo[VFO_B].frequency=frequency_b; + vfo[VFO_A].ctun_frequency=ctun_frequency_a; + vfo[VFO_B].ctun_frequency=ctun_frequency_b; + vfo[VFO_A].offset=offset_a; + vfo[VFO_B].offset=offset_b; + g_idle_add(ext_vfo_update,(gpointer)NULL); + } + g_idle_add(ext_receiver_remote_update_display,receiver[r]); + } + break; + case INFO_AUDIO: + { + AUDIO_DATA audio_data; + bytes_read=recv_bytes(client_socket,(char *)&audio_data.rx,sizeof(audio_data)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for AUDIO_DATA\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + RECEIVER *rx=receiver[audio_data.rx]; + short left_sample; + short right_sample; + int samples=ntohs(audio_data.samples); + if(rx->local_audio) { + for(int i=0;izoom=%d\n",zoom,rx,receiver[rx]->zoom); + if(receiver[rx]->zoom!=zoom) { + g_idle_add(ext_remote_set_zoom,GINT_TO_POINTER(zoom)); + } else { + receiver_change_zoom(receiver[rx],(double)zoom); + } + } + break; + case CMD_RESP_RX_PAN: + { + PAN_COMMAND pan_cmd; + bytes_read=recv_bytes(client_socket,(char *)&pan_cmd.id,sizeof(pan_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for PAN_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + int rx=pan_cmd.id; + short pan=ntohs(pan_cmd.pan); +g_print("CMD_RESP_RX_PAN: pan=%d rx[%d]->pan=%d\n",pan,rx,receiver[rx]->pan); + g_idle_add(ext_remote_set_pan,GINT_TO_POINTER(pan)); + } + break; + case CMD_RESP_RX_VOLUME: + { + VOLUME_COMMAND volume_cmd; + bytes_read=recv_bytes(client_socket,(char *)&volume_cmd.id,sizeof(volume_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for VOLUME_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + int rx=volume_cmd.id; + short volume=ntohs(volume_cmd.volume); +g_print("CMD_RESP_RX_VOLUME: volume=%d rx[%d]->volume=%f\n",volume,rx,receiver[rx]->volume); + receiver[rx]->volume=(double)volume/100.0; + } + break; + case CMD_RESP_RX_AGC: + { + AGC_COMMAND agc_cmd; + bytes_read=recv_bytes(client_socket,(char *)&agc_cmd.id,sizeof(agc_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for AGC_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + int rx=agc_cmd.id; + short a=ntohs(agc_cmd.agc); +g_print("AGC_COMMAND: rx=%d agc=%d\n",rx,a); + receiver[rx]->agc=(int)a; + g_idle_add(ext_vfo_update,(gpointer)NULL); + } + break; + case CMD_RESP_RX_AGC_GAIN: + { + AGC_GAIN_COMMAND agc_gain_cmd; + bytes_read=recv_bytes(client_socket,(char *)&agc_gain_cmd.id,sizeof(agc_gain_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for AGC_GAIN_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + int rx=agc_gain_cmd.id; + short gain=ntohs(agc_gain_cmd.gain); + short hang=ntohs(agc_gain_cmd.hang); + short thresh=ntohs(agc_gain_cmd.thresh); + receiver[rx]->agc_gain=(double)gain; + receiver[rx]->agc_hang=(double)hang; + receiver[rx]->agc_thresh=(double)thresh; + } + break; + case CMD_RESP_RX_ATTENUATION: + { + ATTENUATION_COMMAND attenuation_cmd; + bytes_read=recv_bytes(client_socket,(char *)&attenuation_cmd.id,sizeof(attenuation_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for ATTENUATION_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + int rx=attenuation_cmd.id; + short attenuation=ntohs(attenuation_cmd.attenuation); +g_print("CMD_RESP_RX_ATTENUATION: attenuation=%d adc_attenuation[rx[%d]->adc]=%d\n",attenuation,rx,adc_attenuation[receiver[rx]->adc]); + adc_attenuation[receiver[rx]->adc]=attenuation; + } + break; + case CMD_RESP_RX_NOISE: + { + NOISE_COMMAND noise_command; + bytes_read=recv_bytes(client_socket,(char *)&noise_command.id,sizeof(noise_command)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for NOISE_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + RECEIVER *rx=receiver[noise_command.id]; + rx->nb=noise_command.nb; + rx->nb2=noise_command.nb2; + mode_settings[vfo[rx->id].mode].nb=rx->nb; + mode_settings[vfo[rx->id].mode].nb2=rx->nb2; + rx->nr=noise_command.nr; + rx->nr2=noise_command.nr2; + mode_settings[vfo[rx->id].mode].nr=rx->nr; + mode_settings[vfo[rx->id].mode].nr2=rx->nr2; + rx->snb=noise_command.snb; + mode_settings[vfo[rx->id].mode].snb=rx->snb; + rx->anf=noise_command.anf; + mode_settings[vfo[rx->id].mode].anf=rx->anf; + g_idle_add(ext_vfo_update,(gpointer)NULL); + } + break; + case CMD_RESP_RX_MODE: + { + MODE_COMMAND mode_cmd; + bytes_read=recv_bytes(client_socket,(char *)&mode_cmd.id,sizeof(mode_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for MODE_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + int rx=mode_cmd.id; + short m=ntohs(mode_cmd.mode); + vfo[rx].mode=m; + g_idle_add(ext_vfo_update,(gpointer)NULL); + } + break; + case CMD_RESP_RX_FILTER: + { + FILTER_COMMAND filter_cmd; + bytes_read=recv_bytes(client_socket,(char *)&filter_cmd.id,sizeof(filter_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for FILTER_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + int rx=filter_cmd.id; + short low=ntohs(filter_cmd.filter_low); + short high=ntohs(filter_cmd.filter_high); + receiver[rx]->filter_low=(int)low; + receiver[rx]->filter_high=(int)high; + g_idle_add(ext_vfo_update,(gpointer)NULL); + } + break; + case CMD_RESP_SPLIT: + { + SPLIT_COMMAND split_cmd; + bytes_read=recv_bytes(client_socket,(char *)&split_cmd.split,sizeof(split_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for SPLIT_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + split=split_cmd.split; + } + g_idle_add(ext_vfo_update,(gpointer)NULL); + break; + case CMD_RESP_SAT: + { + SAT_COMMAND sat_cmd; + bytes_read=recv_bytes(client_socket,(char *)&sat_cmd.sat,sizeof(sat_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for SAT_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + sat_mode=sat_cmd.sat; + } + g_idle_add(ext_vfo_update,(gpointer)NULL); + break; + case CMD_RESP_DUP: + { + DUP_COMMAND dup_cmd; + bytes_read=recv_bytes(client_socket,(char *)&dup_cmd.dup,sizeof(dup_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for DUP_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + duplex=dup_cmd.dup; + } + g_idle_add(ext_vfo_update,(gpointer)NULL); + break; + case CMD_RESP_LOCK: + { + LOCK_COMMAND lock_cmd; + bytes_read=recv_bytes(client_socket,(char *)&lock_cmd.lock,sizeof(lock_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for LOCK_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + locked=lock_cmd.lock; + } + g_idle_add(ext_vfo_update,(gpointer)NULL); + break; + case CMD_RESP_RX_FPS: + { + FPS_COMMAND fps_cmd; + bytes_read=recv_bytes(client_socket,(char *)&fps_cmd.id,sizeof(fps_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for FPS_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + int rx=fps_cmd.id; + receiver[rx]->fps=(int)fps_cmd.fps; + } + g_idle_add(ext_vfo_update,(gpointer)NULL); + break; + case CMD_RESP_RX_SELECT: + { + RX_SELECT_COMMAND rx_select_cmd; + bytes_read=recv_bytes(client_socket,(char *)&rx_select_cmd.id,sizeof(rx_select_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for RX_SELECT_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + int rx=rx_select_cmd.id; + active_receiver=receiver[rx]; + } + g_idle_add(ext_vfo_update,(gpointer)NULL); + break; + case CMD_RESP_SAMPLE_RATE: + { + SAMPLE_RATE_COMMAND sample_rate_cmd; + bytes_read=recv_bytes(client_socket,(char *)&sample_rate_cmd.id,sizeof(sample_rate_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for SAMPLE_RATE_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + int rx=(int)sample_rate_cmd.id; + long long rate=ntohll(sample_rate_cmd.sample_rate); +g_print("CMD_RESP_SAMPLE_RATE: rx=%d rate=%lld\n",rx,rate); + if(rx==-1) { + radio_sample_rate=(int)rate; + for(rx=0;rxsample_rate=(int)rate; + receiver[rx]->hz_per_pixel=(double)receiver[rx]->sample_rate/(double)receiver[rx]->pixels; + } + } else { + receiver[rx]->sample_rate=(int)rate; + receiver[rx]->hz_per_pixel=(double)receiver[rx]->sample_rate/(double)receiver[rx]->pixels; + } + } + break; + case CMD_RESP_RECEIVERS: + { + RECEIVERS_COMMAND receivers_cmd; + bytes_read=recv_bytes(client_socket,(char *)&receivers_cmd.receivers,sizeof(receivers_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for RECEIVERS_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + int r=(int)receivers_cmd.receivers; +g_print("CMD_RESP_RECEIVERS: receivers=%d\n",r); + radio_change_receivers(r); + } + break; + case CMD_RESP_RIT_INCREMENT: + { + RIT_INCREMENT_COMMAND rit_increment_cmd; + bytes_read=recv_bytes(client_socket,(char *)&rit_increment_cmd.increment,sizeof(rit_increment_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for RIT_INCREMENT_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + int increment=ntohs(rit_increment_cmd.increment); +g_print("CMD_RESP_RIT_INCREMENT: increment=%d\n",increment); + rit_increment=increment; + } + break; + case CMD_RESP_FILTER_BOARD: + { + FILTER_BOARD_COMMAND filter_board_cmd; + bytes_read=recv_bytes(client_socket,(char *)&filter_board_cmd.filter_board,sizeof(filter_board_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for FILTER_BOARD_CMD\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + filter_board=(int)filter_board_cmd.filter_board; +g_print("CMD_RESP_FILTER_BOARD: board=%d\n",filter_board); + } + break; + case CMD_RESP_SWAP_IQ: + { + SWAP_IQ_COMMAND swap_iq_cmd; + bytes_read=recv_bytes(client_socket,(char *)&swap_iq_cmd.iqswap,sizeof(swap_iq_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for SWAP_IQ_COMMAND\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + iqswap=(int)swap_iq_cmd.iqswap; +g_print("CMD_RESP_IQ_SWAP: iqswap=%d\n",iqswap); + } + break; + case CMD_RESP_REGION: + { + REGION_COMMAND region_cmd; + bytes_read=recv_bytes(client_socket,(char *)®ion_cmd.region,sizeof(region_cmd)-sizeof(header)); + if(bytes_read<0) { + g_print("client_thread: read %d bytes for REGION_COMMAND\n",bytes_read); + perror("client_thread"); + // dialog box? + return NULL; + } + region=(int)region_cmd.region; +g_print("CMD_RESP_REGION: region=%d\n",region); + } + break; + + default: +g_print("client_thread: Unknown type=%d\n",ntohs(header.data_type)); + break; + } + } + return NULL; +} + +int radio_connect_remote(char *host, int port) { + struct sockaddr_in server_address; + gint on=1; + +g_print("radio_connect_remote: %s:%d\n",host,port); + client_socket=socket(AF_INET, SOCK_STREAM, 0); + if(client_socket==-1) { + g_print("radio_connect_remote: socket creation failed...\n"); + return -1; + } + + setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + setsockopt(client_socket, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)); + + struct hostent *server=gethostbyname(host); + + if(server == NULL) { + g_print("radio_connect_remote: no such host: %s\n",host); + return -1; + } + + // assign IP, PORT and bind to address + memset(&server_address,0,sizeof(server_address)); + server_address.sin_family = AF_INET; + bcopy((char *)server->h_addr,(char *)&server_address.sin_addr.s_addr,server->h_length); + server_address.sin_port = htons((short)port); + + if(connect(client_socket, (struct sockaddr *)&server_address, sizeof(server_address)) != 0) { + g_print("client_thread: connect failed\n"); + perror("client_thread"); + return -1; + } + +g_print("radio_connect_remote: socket %d bound to %s:%d\n",client_socket,host,port); + sprintf(server_host,"%s:%d",host,port); + client_thread_id=g_thread_new("remote_client",client_thread,&server_host); + return 0; +} diff --git a/client_server.h b/client_server.h new file mode 100644 index 0000000..926b93f --- /dev/null +++ b/client_server.h @@ -0,0 +1,516 @@ +/* Copyright (C) +* 2020 - John Melton, G0ORX/N6LYT +* +* 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 2 +* 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, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +#ifndef HPSDR_SERVER_H +#define HPSDR_SERVER_H + +#ifndef __APPLE__ +#define htonll htobe64 +#define ntohll be64toh +#endif + +typedef enum { + RECEIVER_DETACHED, RECEIVER_ATTACHED +} CLIENT_STATE; + +enum { + INFO_RADIO, + INFO_ADC, + INFO_RECEIVER, + INFO_TRANSMITTER, + INFO_VFO, + INFO_SPECTRUM, + INFO_AUDIO, + CMD_RESP_SPECTRUM, + CMD_RESP_AUDIO, + CMD_RESP_SAMPLE_RATE, + CMD_RESP_LOCK, + CMD_RESP_CTUN, + CMD_RESP_SPLIT, + CMD_RESP_SAT, + CMD_RESP_DUP, + CMD_RESP_STEP, + CMD_RESP_RECEIVERS, + CMD_RESP_RX_FREQ, + CMD_RESP_RX_STEP, + CMD_RESP_RX_MOVE, + CMD_RESP_RX_MOVETO, + CMD_RESP_RX_BAND, + CMD_RESP_RX_MODE, + CMD_RESP_RX_FILTER, + CMD_RESP_RX_AGC, + CMD_RESP_RX_NOISE, + CMD_RESP_RX_ZOOM, + CMD_RESP_RX_PAN, + CMD_RESP_RX_VOLUME, + CMD_RESP_RX_AGC_GAIN, + CMD_RESP_RX_ATTENUATION, + CMD_RESP_RX_SQUELCH, + CMD_RESP_RX_FPS, + CMD_RESP_RX_SELECT, + CMD_RESP_VFO, + CMD_RESP_RIT_UPDATE, + CMD_RESP_RIT_CLEAR, + CMD_RESP_RIT, + CMD_RESP_XIT_UPDATE, + CMD_RESP_XIT_CLEAR, + CMD_RESP_XIT, + CMD_RESP_RIT_INCREMENT, + CMD_RESP_FILTER_BOARD, + CMD_RESP_SWAP_IQ, + CMD_RESP_REGION, + CMD_RESP_MUTE_RX, +}; + +enum { + VFO_A_TO_B, + VFO_B_TO_A, + VFO_A_SWAP_B, +}; + +#define CLIENT_SERVER_VERSION 0LL + +#define SPECTRUM_DATA_SIZE 800 +#define AUDIO_DATA_SIZE 1024 + +#define REMOTE_SYNC (uint16_t)0xFAFA + +typedef struct _remote_rx { + gint receiver; + gboolean send_audio; + gint audio_format; + gint audio_port; + struct sockaddr_in audio_address; + gboolean send_spectrum; + gint spectrum_fps; + gint spectrum_port; + struct sockaddr_in spectrum_address; +} REMOTE_RX; + +typedef struct _remote_client { + gboolean running; + gint socket; + socklen_t address_length; + struct sockaddr_in address; + GThread *thread_id; + CLIENT_STATE state; + gint receivers; + gint spectrum_update_timer_id; + REMOTE_RX receiver[MAX_RECEIVERS]; + void *next; +} REMOTE_CLIENT; + +typedef struct __attribute__((__packed__)) _header { + uint16_t sync; + uint16_t data_type; + uint64_t version; + union { + uint64_t i; + REMOTE_CLIENT *client; + } context; +} HEADER; + +typedef struct __attribute__((__packed__)) _radio_data { + HEADER header; + char name[32]; + uint16_t protocol; + uint16_t device; + uint64_t sample_rate; + uint64_t frequency_min; + uint64_t frequency_max; + uint8_t display_filled; + uint8_t locked; + uint16_t supported_receivers; + uint16_t receivers; + uint8_t can_transmit; + uint64_t step; + uint8_t split; + uint8_t sat_mode; + uint8_t duplex; + uint8_t have_rx_gain; + uint16_t rx_gain_calibration; + uint16_t filter_board; +} RADIO_DATA; + +typedef struct __attribute__((__packed__)) _adc_data { + HEADER header; + uint8_t adc; + uint16_t filters; + uint16_t hpf; + uint16_t lpf; + uint16_t antenna; + uint8_t dither; + uint8_t random; + uint8_t preamp; + uint16_t attenuation; + uint16_t adc_attenuation; +} ADC_DATA; + +typedef struct __attribute__((__packed__)) _receiver_data { + HEADER header; + uint8_t rx; + uint16_t adc; + uint64_t sample_rate; + uint8_t displaying; + uint8_t display_panadapter; + uint8_t display_waterfall; + uint16_t fps; + uint8_t agc; + uint16_t agc_hang; + uint16_t agc_thresh; + uint8_t nb; + uint8_t nb2; + uint8_t nr; + uint8_t nr2; + uint8_t anf; + uint8_t snb; + uint16_t filter_low; + uint16_t filter_high; + uint16_t panadapter_low; + uint16_t panadapter_high; + uint16_t panadapter_step; + uint16_t waterfall_low; + uint16_t waterfall_high; + uint8_t waterfall_automatic; + uint16_t pixels; + uint16_t zoom; + uint16_t pan; + uint16_t width; + uint16_t height; + uint16_t x; + uint16_t y; + uint16_t volume; + uint16_t rf_gain; + uint16_t agc_gain; +} RECEIVER_DATA; + +typedef struct __attribute__((__packed__)) _vfo_data { + HEADER header; + uint8_t vfo; + uint16_t band; + uint16_t bandstack; + uint64_t frequency; + uint16_t mode; + uint16_t filter; + uint8_t ctun; + uint64_t ctun_frequency; + uint8_t rit_enabled; + uint64_t rit; + uint64_t lo; + uint64_t offset; +} VFO_DATA; + +typedef struct __attribute__((__packed__)) _spectrum_data { + HEADER header; + uint8_t rx; + uint64_t vfo_a_freq; + uint64_t vfo_b_freq; + uint64_t vfo_a_ctun_freq; + uint64_t vfo_b_ctun_freq; + uint64_t vfo_a_offset; + uint64_t vfo_b_offset; + uint16_t meter; + uint16_t samples; + uint16_t sample[SPECTRUM_DATA_SIZE]; +} SPECTRUM_DATA; + +typedef struct __attribute__((__packed__)) _audio_data { + HEADER header; + uint8_t rx; + uint16_t samples; + uint16_t sample[AUDIO_DATA_SIZE*2]; +} AUDIO_DATA; + +typedef struct __attribute__((__packed__)) _spectrum_command { + HEADER header; + int8_t id; + uint8_t start_stop; +} SPECTRUM_COMMAND; + +typedef struct __attribute__((__packed__)) _freq_command { + HEADER header; + uint8_t id; + uint64_t hz; +} FREQ_COMMAND; + +typedef struct __attribute__((__packed__)) _step_command { + HEADER header; + uint8_t id; + uint16_t steps; +} STEP_COMMAND; + +typedef struct __attribute__((__packed__)) _sample_rate_command { + HEADER header; + int8_t id; + uint64_t sample_rate; +} SAMPLE_RATE_COMMAND; + +typedef struct __attribute__((__packed__)) _receivers_command { + HEADER header; + uint8_t receivers; +} RECEIVERS_COMMAND; + +typedef struct __attribute__((__packed__)) _move_command { + HEADER header; + uint8_t id; + uint64_t hz; + uint8_t round; +} MOVE_COMMAND; + +typedef struct __attribute__((__packed__)) _move_to_command { + HEADER header; + uint8_t id; + uint64_t hz; +} MOVE_TO_COMMAND; + +typedef struct __attribute__((__packed__)) _zoom_command { + HEADER header; + uint8_t id; + uint16_t zoom; +} ZOOM_COMMAND; + +typedef struct __attribute__((__packed__)) _pan_command { + HEADER header; + uint8_t id; + uint16_t pan; +} PAN_COMMAND; + +typedef struct __attribute__((__packed__)) _volume_command { + HEADER header; + uint8_t id; + uint16_t volume; +} VOLUME_COMMAND; + +typedef struct __attribute__((__packed__)) _band_command { + HEADER header; + uint8_t id; + uint16_t band; +} BAND_COMMAND; + +typedef struct __attribute__((__packed__)) _mode_command { + HEADER header; + uint8_t id; + uint16_t mode; +} MODE_COMMAND; + +typedef struct __attribute__((__packed__)) _filter_command { + HEADER header; + uint8_t id; + uint16_t filter; + uint16_t filter_low; + uint16_t filter_high; +} FILTER_COMMAND; + +typedef struct __attribute__((__packed__)) _agc_command { + HEADER header; + uint8_t id; + uint16_t agc; +} AGC_COMMAND; + +typedef struct __attribute__((__packed__)) _agc_gain_command { + HEADER header; + uint8_t id; + uint16_t gain; + uint16_t hang; + uint16_t thresh; +} AGC_GAIN_COMMAND; + +typedef struct __attribute__((__packed__)) _attenuation_command { + HEADER header; + uint8_t id; + uint16_t attenuation; +} ATTENUATION_COMMAND; + +typedef struct __attribute__((__packed__)) _squelch_command { + HEADER header; + uint8_t id; + uint8_t enable; + uint16_t squelch; +} SQUELCH_COMMAND; + +typedef struct __attribute__((__packed__)) _noise_command { + HEADER header; + uint8_t id; + uint8_t nb; + uint8_t nb2; + uint8_t nr; + uint8_t nr2; + uint8_t anf; + uint8_t snb; +} NOISE_COMMAND; + +typedef struct __attribute__((__packed__)) _split_command { + HEADER header; + uint8_t split; +} SPLIT_COMMAND; + +typedef struct __attribute__((__packed__)) _sat_command { + HEADER header; + uint8_t sat; +} SAT_COMMAND; + +typedef struct __attribute__((__packed__)) _dup_command { + HEADER header; + uint8_t dup; +} DUP_COMMAND; + +typedef struct __attribute__((__packed__)) _fps_command { + HEADER header; + uint8_t id; + uint8_t fps; +} FPS_COMMAND; + +typedef struct __attribute__((__packed__)) _ctun_command { + HEADER header; + uint8_t id; + uint8_t ctun; +} CTUN_COMMAND; + +typedef struct __attribute__((__packed__)) _rx_select_command { + HEADER header; + uint8_t id; +} RX_SELECT_COMMAND; + +typedef struct __attribute__((__packed__)) _vfo_command { + HEADER header; + uint8_t id; +} VFO_COMMAND; + +typedef struct __attribute__((__packed__)) _lock_command { + HEADER header; + uint8_t lock; +} LOCK_COMMAND; + +typedef struct __attribute__((__packed__)) _rit_update_command { + HEADER header; + uint8_t id; +} RIT_UPDATE_COMMAND; + +typedef struct __attribute__((__packed__)) _rit_clear_command { + HEADER header; + uint8_t id; +} RIT_CLEAR_COMMAND; + +typedef struct __attribute__((__packed__)) _rit_command { + HEADER header; + uint8_t id; + uint16_t rit; +} RIT_COMMAND; + +typedef struct __attribute__((__packed__)) _xit_update_command { + HEADER header; +} XIT_UPDATE_COMMAND; + +typedef struct __attribute__((__packed__)) _xit_clear_command { + HEADER header; +} XIT_CLEAR_COMMAND; + +typedef struct __attribute__((__packed__)) _xit_command { + HEADER header; + uint16_t xit; +} XIT_COMMAND; + +typedef struct __attribute__((__packed__)) _rit_increment { + HEADER header; + uint16_t increment; +} RIT_INCREMENT_COMMAND; + +typedef struct __attribute__((__packed__)) _filter_board { + HEADER header; + uint8_t filter_board; +} FILTER_BOARD_COMMAND; + +typedef struct __attribute__((__packed__)) _swap_iq { + HEADER header; + uint8_t iqswap; +} SWAP_IQ_COMMAND; + +typedef struct __attribute__((__packed__)) _region { + HEADER header; + uint8_t region; +} REGION_COMMAND; + +typedef struct __attribute__((__packed__)) _mute_rx { + HEADER header; + uint8_t mute; +} MUTE_RX_COMMAND; + +extern gboolean hpsdr_server; +extern gboolean hpsdr_server; +extern gint client_socket; +extern gint start_spectrum(void *data); +extern void start_vfo_timer(); +extern gboolean remote_started; + + +extern REMOTE_CLIENT *clients; + +extern gint listen_port; + +extern int create_hpsdr_server(); +extern int destroy_hpsdr_server(); + +extern int radio_connect_remote(char *host, int port); + +extern void send_radio_data(REMOTE_CLIENT *client); +extern void send_adc_data(REMOTE_CLIENT *client,int i); +extern void send_receiver_data(REMOTE_CLIENT *client,int rx); +extern void send_vfo_data(REMOTE_CLIENT *client,int v); + +extern void send_start_spectrum(int s,int rx); +extern void send_vfo_frequency(int s,int rx,long long hz); +extern void send_vfo_move_to(int s,int rx,long long hz); +extern void send_vfo_move(int s,int rx,long long hz,int round); +extern void update_vfo_move(int rx,long long hz,int round); +extern void send_vfo_step(int s,int rx,int steps); +extern void update_vfo_step(int rx,int steps); +extern void send_zoom(int s,int rx,int zoom); +extern void send_pan(int s,int rx,int pan); +extern void send_volume(int s,int rx,int volume); +extern void send_agc(int s,int rx,int agc); +extern void send_agc_gain(int s,int rx,int gain,int hang,int thresh); +extern void send_attenuation(int s,int rx,int attenuation); +extern void send_squelch(int s,int rx,int enable,int squelch); +extern void send_noise(int s,int rx,int nb,int nb2,int nr,int nr2,int anf,int snb); +extern void send_band(int s,int rx,int band); +extern void send_mode(int s,int rx,int mode); +extern void send_filter(int s,int rx,int filter); +extern void send_split(int s,int split); +extern void send_sat(int s,int sat); +extern void send_dup(int s,int dup); +extern void send_ctun(int s,int vfo,int ctun); +extern void send_fps(int s,int rx,int fps); +extern void send_rx_select(int s,int rx); +extern void send_vfo(int s,int action); +extern void send_lock(int s,int lock); +extern void send_rit_update(int s,int rx); +extern void send_rit_clear(int s,int rx); +extern void send_rit(int s,int rx,int rit); +extern void send_sample_rate(int s,int rx,int sample_rate); +extern void send_receivers(int s,int receivers); +extern void send_rit_increment(int s,int increment); +extern void send_filter_board(int s,int filter_board); +extern void send_swap_iq(int s,int swap_iq); +extern void send_region(int s,int region); +extern void send_mute_rx(int s,int mute); + + +extern void remote_audio(RECEIVER *rx,short left_sample,short right_sample); + +#endif diff --git a/discovered.h b/discovered.h index c6bca2c..dc71bfc 100644 --- a/discovered.h +++ b/discovered.h @@ -55,7 +55,7 @@ #define NEW_DEVICE_HERMES_LITE2 1006 #ifdef SOAPYSDR -#define SOAPYSDR_USB_DEVICE 0 +#define SOAPYSDR_USB_DEVICE 2000 #endif #define STATE_AVAILABLE 2 @@ -67,9 +67,6 @@ #define SOAPYSDR_PROTOCOL 2 #endif -#ifdef REMOTE -#define REMOTE_PROTOCOL 4 -#endif #ifdef STEMLAB_DISCOVERY // A STEMlab discovered via Avahi will have this protocol until the SDR // application itself is started, at which point it will be changed to the old diff --git a/discovery.c b/discovery.c index 64973ec..c9d6c99 100644 --- a/discovery.c +++ b/discovery.c @@ -42,9 +42,6 @@ #ifdef USBOZY #include "ozyio.h" #endif -#ifdef REMOTE -#include "remote_radio.h" -#endif #ifdef STEMLAB_DISCOVERY #include "stemlab_discovery.h" #endif @@ -54,6 +51,10 @@ #include "configure.h" #endif #include "protocols.h" +#ifdef CLIENT_SERVER +#include "client_server.h" +#endif +#include "property.h" static GtkWidget *discovery_dialog; static DISCOVERED *d; @@ -67,10 +68,12 @@ GtkWidget *tcpaddr; static char ipaddr_tcp_buf[IPADDR_LEN] = "10.10.10.10"; char *ipaddr_tcp = &ipaddr_tcp_buf[0]; -#ifdef SERVER -GtkWidget *connect_addr_entry; -static char connect_addr_buffer[30]="0.0.0.0:50000"; -char *connect_addr = &connect_addr_buffer[0]; +#ifdef CLIENT_SERVER +GtkWidget *host_addr_entry; +static char host_addr_buffer[128]="g0orx.ddns.net"; +char *host_addr = &host_addr_buffer[0]; +GtkWidget *host_port_spinner; +gint host_port=45000; #endif static gboolean delete_event_cb(GtkWidget *widget, GdkEvent *event, gpointer data) { @@ -262,11 +265,30 @@ static gboolean tcp_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) return TRUE; } -#ifdef SERVER +#ifdef CLIENT_SERVER static gboolean connect_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { // connect to remote host running piHPSDR - strncpy(connect_addr, gtk_entry_get_text(GTK_ENTRY(connect_addr_entry)), 30); -g_print("connect_cb: %s\n",connect_addr); + strncpy(host_addr, gtk_entry_get_text(GTK_ENTRY(host_addr_entry)), 30); + host_port=gtk_spin_button_get_value(GTK_SPIN_BUTTON(host_port_spinner)); +g_print("connect_cb: %s:%d\n",host_addr,host_port); + setProperty("host",host_addr); + char temp[16]; + sprintf(temp,"%d",host_port); + setProperty("port",temp); + saveProperties("remote.props"); + if(radio_connect_remote(host_addr,host_port)==0) { + gtk_widget_destroy(discovery_dialog); + } else { + // dialog box to display connection error + GtkWidget *dialog=gtk_dialog_new_with_buttons("Remote Connect",GTK_WINDOW(discovery_dialog),GTK_DIALOG_DESTROY_WITH_PARENT,"OK",GTK_RESPONSE_NONE,NULL); + GtkWidget *content_area=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + char message[128]; + sprintf(message,"Connection failed to %s:%d",host_addr,host_port); + GtkWidget *label=gtk_label_new(message); + g_signal_connect_swapped(dialog,"response",G_CALLBACK(gtk_widget_destroy),dialog); + gtk_container_add(GTK_CONTAINER(content_area),label); + gtk_widget_show_all(dialog); + } return TRUE; } #endif @@ -282,7 +304,7 @@ void discovery() { // Try to locate IP addr FILE *fp=fopen("ip.addr","r"); if (fp) { - fgets(ipaddr_tcp, IPADDR_LEN,fp); + char *c=fgets(ipaddr_tcp, IPADDR_LEN,fp); fclose(fp); ipaddr_tcp[IPADDR_LEN-1]=0; // remove possible trailing newline char in ipaddr_tcp @@ -341,55 +363,6 @@ void discovery() { status_text("Discovery"); - if(devices==0) { - gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_ARROW)); - discovery_dialog = gtk_dialog_new(); - gtk_window_set_transient_for(GTK_WINDOW(discovery_dialog),GTK_WINDOW(top_window)); - gtk_window_set_title(GTK_WINDOW(discovery_dialog),"piHPSDR - Discovery"); - //gtk_window_set_decorated(GTK_WINDOW(discovery_dialog),FALSE); - - //gtk_widget_override_font(discovery_dialog, pango_font_description_from_string("FreeMono 16")); - g_signal_connect(discovery_dialog, "delete_event", G_CALLBACK(delete_event_cb), NULL); - - GdkRGBA color; - color.red = 1.0; - color.green = 1.0; - color.blue = 1.0; - color.alpha = 1.0; - gtk_widget_override_background_color(discovery_dialog,GTK_STATE_FLAG_NORMAL,&color); - - GtkWidget *content; - - content=gtk_dialog_get_content_area(GTK_DIALOG(discovery_dialog)); - - GtkWidget *grid=gtk_grid_new(); - gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); - gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - gtk_grid_set_row_spacing (GTK_GRID(grid),10); - - GtkWidget *label=gtk_label_new("No devices found!"); - gtk_grid_attach(GTK_GRID(grid),label,0,0,2,1); - - GtkWidget *exit_b=gtk_button_new_with_label("Exit"); - g_signal_connect (exit_b, "button-press-event", G_CALLBACK(exit_cb), NULL); - gtk_grid_attach(GTK_GRID(grid),exit_b,0,1,1,1); - - GtkWidget *discover_b=gtk_button_new_with_label("Retry Discovery"); - g_signal_connect (discover_b, "button-press-event", G_CALLBACK(discover_cb), NULL); - gtk_grid_attach(GTK_GRID(grid),discover_b,1,1,1,1); - - GtkWidget *tcp_b=gtk_button_new_with_label("Use new TCP Addr:"); - g_signal_connect (tcp_b, "button-press-event", G_CALLBACK(tcp_cb), NULL); - gtk_grid_attach(GTK_GRID(grid),tcp_b,0,2,1,1); - - tcpaddr=gtk_entry_new(); - gtk_entry_set_max_length(GTK_ENTRY(tcpaddr), 20); - gtk_grid_attach(GTK_GRID(grid),tcpaddr,1,2,1,1); - gtk_entry_set_text(GTK_ENTRY(tcpaddr), ipaddr_tcp); - - gtk_container_add (GTK_CONTAINER (content), grid); - gtk_widget_show_all(discovery_dialog); - } else { fprintf(stderr,"discovery: found %d devices\n", devices); gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_ARROW)); discovery_dialog = gtk_dialog_new(); @@ -416,133 +389,171 @@ void discovery() { //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); gtk_grid_set_row_spacing (GTK_GRID(grid),10); - int row; - char version[16]; - char text[256]; - for(row=0;rowprotocol,d->name); - sprintf(version,"v%d.%d", - d->software_version/10, - d->software_version%10); - switch(d->protocol) { - case ORIGINAL_PROTOCOL: - case NEW_PROTOCOL: + sprintf(version,"v%d.%d", + d->software_version/10, + d->software_version%10); + switch(d->protocol) { + case ORIGINAL_PROTOCOL: + case NEW_PROTOCOL: #ifdef USBOZY - if(d->device==DEVICE_OZY) { - sprintf(text,"%s (%s) on USB /dev/ozy", d->name, d->protocol==ORIGINAL_PROTOCOL?"Protocol 1":"Protocol 2"); - } else { + if(d->device==DEVICE_OZY) { + sprintf(text,"%s (%s) on USB /dev/ozy", d->name, d->protocol==ORIGINAL_PROTOCOL?"Protocol 1":"Protocol 2"); + } else { #endif - sprintf(text,"%s (%s %s) %s (%02X:%02X:%02X:%02X:%02X:%02X) on %s: ", - d->name, - d->protocol==ORIGINAL_PROTOCOL?"Protocol 1":"Protocol 2", - version, - inet_ntoa(d->info.network.address.sin_addr), - d->info.network.mac_address[0], - d->info.network.mac_address[1], - d->info.network.mac_address[2], - d->info.network.mac_address[3], - d->info.network.mac_address[4], - d->info.network.mac_address[5], - d->info.network.interface_name); + sprintf(text,"%s (%s %s) %s (%02X:%02X:%02X:%02X:%02X:%02X) on %s: ", + d->name, + d->protocol==ORIGINAL_PROTOCOL?"Protocol 1":"Protocol 2", + version, + inet_ntoa(d->info.network.address.sin_addr), + d->info.network.mac_address[0], + d->info.network.mac_address[1], + d->info.network.mac_address[2], + d->info.network.mac_address[3], + d->info.network.mac_address[4], + d->info.network.mac_address[5], + d->info.network.interface_name); #ifdef USBOZY - } + } #endif - break; + break; #ifdef SOAPYSDR - case SOAPYSDR_PROTOCOL: - sprintf(text,"%s (Protocol SOAPY_SDR %s) on USB",d->name,d->info.soapy.version); - break; + case SOAPYSDR_PROTOCOL: + sprintf(text,"%s (Protocol SOAPY_SDR %s) on USB",d->name,d->info.soapy.version); + break; #endif #ifdef STEMLAB_DISCOVERY - case STEMLAB_PROTOCOL: + case STEMLAB_PROTOCOL: #ifdef NO_AVAHI - sprintf(text,"Choose RedPitaya App from %s and start radio: ",inet_ntoa(d->info.network.address.sin_addr)); + sprintf(text,"Choose RedPitaya App from %s and start radio: ",inet_ntoa(d->info.network.address.sin_addr)); #else - sprintf(text, "STEMlab (%02X:%02X:%02X:%02X:%02X:%02X) on %s", - d->info.network.mac_address[0], - d->info.network.mac_address[1], - d->info.network.mac_address[2], - d->info.network.mac_address[3], - d->info.network.mac_address[4], - d->info.network.mac_address[5], - d->info.network.interface_name); + sprintf(text, "STEMlab (%02X:%02X:%02X:%02X:%02X:%02X) on %s", + d->info.network.mac_address[0], + d->info.network.mac_address[1], + d->info.network.mac_address[2], + d->info.network.mac_address[3], + d->info.network.mac_address[4], + d->info.network.mac_address[5], + d->info.network.interface_name); #endif #endif - } - - GtkWidget *label=gtk_label_new(text); - gtk_widget_override_font(label, pango_font_description_from_string("Sans 11")); - gtk_widget_set_halign (label, GTK_ALIGN_START); - gtk_widget_show(label); - gtk_grid_attach(GTK_GRID(grid),label,0,row,3,1); - - GtkWidget *start_button=gtk_button_new_with_label("Start"); - gtk_widget_override_font(start_button, pango_font_description_from_string("Sans 16")); - gtk_widget_show(start_button); - gtk_grid_attach(GTK_GRID(grid),start_button,3,row,1,1); - g_signal_connect(start_button,"button_press_event",G_CALLBACK(start_cb),(gpointer)d); + } - // if not available then cannot start it - if(d->status!=STATE_AVAILABLE) { - gtk_button_set_label(GTK_BUTTON(start_button),"In Use"); - gtk_widget_set_sensitive(start_button, FALSE); - } + GtkWidget *label=gtk_label_new(text); + gtk_widget_override_font(label, pango_font_description_from_string("Sans 11")); + gtk_widget_set_halign (label, GTK_ALIGN_START); + gtk_widget_show(label); + gtk_grid_attach(GTK_GRID(grid),label,0,row,3,1); + + GtkWidget *start_button=gtk_button_new_with_label("Start"); + gtk_widget_override_font(start_button, pango_font_description_from_string("Sans 16")); + gtk_widget_show(start_button); + gtk_grid_attach(GTK_GRID(grid),start_button,3,row,1,1); + g_signal_connect(start_button,"button_press_event",G_CALLBACK(start_cb),(gpointer)d); + + // if not available then cannot start it + if(d->status!=STATE_AVAILABLE) { + gtk_button_set_label(GTK_BUTTON(start_button),"In Use"); + gtk_widget_set_sensitive(start_button, FALSE); + } #ifdef SOAPYSDR - if(d->device!=SOAPYSDR_USB_DEVICE) { + if(d->device!=SOAPYSDR_USB_DEVICE) { #endif - // if not on the same subnet then cannot start it - if((d->info.network.interface_address.sin_addr.s_addr&d->info.network.interface_netmask.sin_addr.s_addr) != (d->info.network.address.sin_addr.s_addr&d->info.network.interface_netmask.sin_addr.s_addr)) { - gtk_button_set_label(GTK_BUTTON(start_button),"Subnet!"); - gtk_widget_set_sensitive(start_button, FALSE); - } + // if not on the same subnet then cannot start it + if((d->info.network.interface_address.sin_addr.s_addr&d->info.network.interface_netmask.sin_addr.s_addr) != (d->info.network.address.sin_addr.s_addr&d->info.network.interface_netmask.sin_addr.s_addr)) { + gtk_button_set_label(GTK_BUTTON(start_button),"Subnet!"); + gtk_widget_set_sensitive(start_button, FALSE); + } #ifdef SOAPYSDR - } + } #endif #ifdef STEMLAB_DISCOVERY - if (d->protocol == STEMLAB_PROTOCOL) { - if (d->software_version == 0) { - gtk_button_set_label(GTK_BUTTON(start_button), "Not installed"); - gtk_widget_set_sensitive(start_button, FALSE); - } else { - apps_combobox[row] = gtk_combo_box_text_new(); - gtk_widget_override_font(apps_combobox[row], pango_font_description_from_string("Sans 11")); - // We want the default selection priority for the STEMlab app to be - // RP-Trx > HAMlab-Trx > Pavel-Trx > Pavel-Rx, so we add in decreasing order and - // always set the newly added entry to be active. - if ((d->software_version & STEMLAB_PAVEL_RX) != 0) { - gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(apps_combobox[row]), - "sdr_receiver_hpsdr", "Pavel-Rx"); - gtk_combo_box_set_active_id(GTK_COMBO_BOX(apps_combobox[row]), - "sdr_receiver_hpsdr"); - } - if ((d->software_version & STEMLAB_PAVEL_TRX) != 0) { - gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(apps_combobox[row]), - "sdr_transceiver_hpsdr", "Pavel-Trx"); - gtk_combo_box_set_active_id(GTK_COMBO_BOX(apps_combobox[row]), - "sdr_transceiver_hpsdr"); - } - if ((d->software_version & HAMLAB_RP_TRX) != 0) { - gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(apps_combobox[row]), - "hamlab_sdr_transceiver_hpsdr", "HAMlab-Trx"); - gtk_combo_box_set_active_id(GTK_COMBO_BOX(apps_combobox[row]), - "hamlab_sdr_transceiver_hpsdr"); - } - if ((d->software_version & STEMLAB_RP_TRX) != 0) { - gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(apps_combobox[row]), + if (d->protocol == STEMLAB_PROTOCOL) { + if (d->software_version == 0) { + gtk_button_set_label(GTK_BUTTON(start_button), "Not installed"); + gtk_widget_set_sensitive(start_button, FALSE); + } else { + apps_combobox[row] = gtk_combo_box_text_new(); + gtk_widget_override_font(apps_combobox[row], pango_font_description_from_string("Sans 11")); + // We want the default selection priority for the STEMlab app to be + // RP-Trx > HAMlab-Trx > Pavel-Trx > Pavel-Rx, so we add in decreasing order and + // always set the newly added entry to be active. + if ((d->software_version & STEMLAB_PAVEL_RX) != 0) { + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(apps_combobox[row]), + "sdr_receiver_hpsdr", "Pavel-Rx"); + gtk_combo_box_set_active_id(GTK_COMBO_BOX(apps_combobox[row]), + "sdr_receiver_hpsdr"); + } + if ((d->software_version & STEMLAB_PAVEL_TRX) != 0) { + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(apps_combobox[row]), + "sdr_transceiver_hpsdr", "Pavel-Trx"); + gtk_combo_box_set_active_id(GTK_COMBO_BOX(apps_combobox[row]), + "sdr_transceiver_hpsdr"); + } + if ((d->software_version & HAMLAB_RP_TRX) != 0) { + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(apps_combobox[row]), + "hamlab_sdr_transceiver_hpsdr", "HAMlab-Trx"); + gtk_combo_box_set_active_id(GTK_COMBO_BOX(apps_combobox[row]), + "hamlab_sdr_transceiver_hpsdr"); + } + if ((d->software_version & STEMLAB_RP_TRX) != 0) { + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(apps_combobox[row]), "stemlab_sdr_transceiver_hpsdr", "STEMlab-Trx"); - gtk_combo_box_set_active_id(GTK_COMBO_BOX(apps_combobox[row]), - "stemlab_sdr_transceiver_hpsdr"); + gtk_combo_box_set_active_id(GTK_COMBO_BOX(apps_combobox[row]), + "stemlab_sdr_transceiver_hpsdr"); + } + gtk_widget_show(apps_combobox[row]); + gtk_grid_attach(GTK_GRID(grid), apps_combobox[row], 4, row, 1, 1); } - gtk_widget_show(apps_combobox[row]); - gtk_grid_attach(GTK_GRID(grid), apps_combobox[row], 4, row, 1, 1); } - } #endif + } } + +#ifdef CLIENT_SERVER + + loadProperties("remote.props"); + char *value; + value=getProperty("host"); + if(value!=NULL) strcpy(host_addr_buffer,value); + value=getProperty("port"); + if(value!=NULL) host_port=atoi(value); + + GtkWidget *connect_b=gtk_button_new_with_label("Connect to Server"); + g_signal_connect (connect_b, "button-press-event", G_CALLBACK(connect_cb), NULL); + gtk_grid_attach(GTK_GRID(grid),connect_b,0,row,1,1); + + host_addr_entry=gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(host_addr_entry), 30); + gtk_grid_attach(GTK_GRID(grid),host_addr_entry,1,row,1,1); + gtk_entry_set_text(GTK_ENTRY(host_addr_entry), host_addr); + + GtkWidget *host_port_label =gtk_label_new(NULL); + gtk_label_set_markup(GTK_LABEL(host_port_label), "Server Port"); + gtk_widget_show(host_port_label); + gtk_grid_attach(GTK_GRID(grid),host_port_label,2,row,1,1); + + host_port_spinner =gtk_spin_button_new_with_range(45000,55000,1); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(host_port_spinner),(double)host_port); + gtk_widget_show(host_port_spinner); + gtk_grid_attach(GTK_GRID(grid),host_port_spinner,3,row,1,1); + + row++; +#endif + #ifdef GPIO controller=CONTROLLER2_V2; gpio_set_defaults(controller); @@ -594,25 +605,9 @@ fprintf(stderr,"%p Protocol=%d name=%s\n",d,d->protocol,d->name); g_signal_connect (exit_b, "button-press-event", G_CALLBACK(exit_cb), NULL); gtk_grid_attach(GTK_GRID(grid),exit_b,3,row,1,1); -#ifdef SERVER - row++; - - GtkWidget *connect_b=gtk_button_new_with_label("Connect (Addr:Port)"); - g_signal_connect (connect_b, "button-press-event", G_CALLBACK(connect_cb), NULL); - gtk_grid_attach(GTK_GRID(grid),connect_b,0,row,1,1); - - connect_addr_entry=gtk_entry_new(); - gtk_entry_set_max_length(GTK_ENTRY(connect_addr_entry), 30); - gtk_grid_attach(GTK_GRID(grid),connect_addr_entry,1,row,1,1); - gtk_entry_set_text(GTK_ENTRY(connect_addr_entry), connect_addr); - -#endif - - gtk_container_add (GTK_CONTAINER (content), grid); gtk_widget_show_all(discovery_dialog); fprintf(stderr,"showing device dialog\n"); - } } diff --git a/exit_menu.c b/exit_menu.c index d74597f..ece8880 100644 --- a/exit_menu.c +++ b/exit_menu.c @@ -88,22 +88,29 @@ static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_d } static gboolean exit_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +g_print("exit_cb\n"); #ifdef GPIO gpio_close(); #endif - switch(protocol) { - case ORIGINAL_PROTOCOL: - old_protocol_stop(); - break; - case NEW_PROTOCOL: - new_protocol_stop(); - break; +#ifdef CLIENT_SERVER + if(!radio_is_remote) { +#endif + switch(protocol) { + case ORIGINAL_PROTOCOL: + old_protocol_stop(); + break; + case NEW_PROTOCOL: + new_protocol_stop(); + break; #ifdef SOAPYSDR - case SOAPYSDR_PROTOCOL: - soapy_protocol_stop(); - break; + case SOAPYSDR_PROTOCOL: + soapy_protocol_stop(); + break; #endif + } +#ifdef CLIENT_SERVER } +#endif radioSaveState(); _exit(0); @@ -127,7 +134,7 @@ static gboolean reboot_cb (GtkWidget *widget, GdkEventButton *event, gpointer da #endif } radioSaveState(); - system("reboot"); + int rc=system("reboot"); _exit(0); } @@ -149,7 +156,7 @@ static gboolean shutdown_cb (GtkWidget *widget, GdkEventButton *event, gpointer #endif } radioSaveState(); - system("shutdown -h -P now"); + int rc=system("shutdown -h -P now"); _exit(0); } diff --git a/ext.c b/ext.c index 29a0c77..7804134 100644 --- a/ext.c +++ b/ext.c @@ -22,6 +22,7 @@ #include #include #include +#include "main.h" #include "discovery.h" #include "receiver.h" #include "sliders.h" @@ -38,13 +39,18 @@ #endif #include "agc.h" #include "filter.h" +#include "mode.h" #include "band.h" #include "bandstack.h" #include "noise_menu.h" #include "wdsp.h" +#ifdef CLIENT_SERVER +#include "client_server.h" +#endif #include "ext.h" #include "zoompan.h" + // The following calls functions can be called usig g_idle_add int ext_vfo_mode_changed(void * data) @@ -59,6 +65,23 @@ int ext_discovery(void *data) { return 0; } +void local_set_frequency(int v,long long f) { + int b=get_band_from_frequency(f); + if(active_receiver->id==v) { + if (b != vfo[v].band) { + vfo_band_changed(active_receiver->id,b); + } + setFrequency(f); + } else if(v==VFO_B) { + // just changing VFO-B frequency + vfo[v].frequency=f; + vfo[v].band=b; + if(receivers==2) { + // need to change the receiver frequency + } + } +} + int ext_set_frequency(void *data) { // // If new frequency is outside of current band, @@ -67,20 +90,7 @@ int ext_set_frequency(void *data) { // SET_FREQUENCY *set_frequency=(SET_FREQUENCY *)data; g_print("ext_set_frequency: vfo=%d freq=%lld\n",set_frequency->vfo,set_frequency->frequency); - int b=get_band_from_frequency(set_frequency->frequency); - if(active_receiver->id==set_frequency->vfo) { - if (b != vfo[set_frequency->vfo].band) { - vfo_band_changed(b); - } - setFrequency(set_frequency->frequency); - } else if(set_frequency->vfo==VFO_B) { - // just changing VFO-B frequency - vfo[set_frequency->vfo].frequency=set_frequency->frequency; - vfo[set_frequency->vfo].band=b; - if(receivers==2) { - // need to change the receiver frequency - } - } + local_set_frequency(set_frequency->vfo,set_frequency->frequency); free(data); return 0; } @@ -180,7 +190,8 @@ int ext_calc_drive_level(void *data) { } int ext_vfo_band_changed(void *data) { - vfo_band_changed(GPOINTER_TO_INT(data)); + int b=GPOINTER_TO_INT(data); + vfo_band_changed(active_receiver->id,b); return 0; } @@ -348,9 +359,7 @@ int ext_nr_update(void *data) { mode_settings[vfo[active_receiver->id].mode].nr=0; mode_settings[vfo[active_receiver->id].mode].nr2=0; } - SetRXAANRRun(active_receiver->id, active_receiver->nr); - SetRXAEMNRRun(active_receiver->id, active_receiver->nr2); - g_idle_add(ext_vfo_update, NULL); + update_noise(); return 0; } @@ -371,9 +380,7 @@ int ext_nb_update(void *data) { mode_settings[vfo[active_receiver->id].mode].nb=0; mode_settings[vfo[active_receiver->id].mode].nb2=0; } - SetEXTANBRun(active_receiver->id, active_receiver->nb); - SetEXTNOBRun(active_receiver->id, active_receiver->nb2); - g_idle_add(ext_vfo_update, NULL); + update_noise(); return 0; } @@ -385,15 +392,13 @@ int ext_snb_update(void *data) { active_receiver->snb=0; mode_settings[vfo[active_receiver->id].mode].snb=0; } - SetRXASNBARun(active_receiver->id, active_receiver->snb); - g_idle_add(ext_vfo_update, NULL); + update_noise(); return 0; } -int ext_band_plus(void *data) { +void band_plus(int id) { long long frequency_min=radio->frequency_min; long long frequency_max=radio->frequency_max; - int id=active_receiver->id; int b=vfo[id].band; BAND *band; int found=0; @@ -409,18 +414,21 @@ int ext_band_plus(void *data) { } } } - vfo_band_changed(b); + vfo_band_changed(id,b); found=1; } } +} + +int ext_band_plus(void *data) { + band_plus(active_receiver->id); return 0; } -int ext_band_minus(void *data) { +void band_minus(int id) { long long frequency_min=radio->frequency_min; long long frequency_max=radio->frequency_max; - int id=active_receiver->id; int b=vfo[id].band; BAND *band; int found=0; @@ -434,10 +442,14 @@ int ext_band_minus(void *data) { continue; } } - vfo_band_changed(b); + vfo_band_changed(id,b); found=1; } } +} + +int ext_band_minus(void *data) { + band_minus(active_receiver->id); return 0; } @@ -460,22 +472,26 @@ int ext_bandstack_minus(void *data) { } int ext_lock_update(void *data) { - locked=locked==1?0:1; - g_idle_add(ext_vfo_update, NULL); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_lock(client_socket,locked==1?0:1); + } else { +#endif + locked=locked==1?0:1; + g_idle_add(ext_vfo_update, NULL); +#ifdef CLIENT_SERVER + } +#endif return 0; } int ext_rit_update(void *data) { - vfo[active_receiver->id].rit_enabled=vfo[active_receiver->id].rit_enabled==1?0:1; - receiver_frequency_changed(active_receiver); - g_idle_add(ext_vfo_update, NULL); + vfo_rit_update(active_receiver->id); return 0; } int ext_rit_clear(void *data) { - vfo[active_receiver->id].rit=0; - receiver_frequency_changed(active_receiver); - g_idle_add(ext_vfo_update, NULL); + vfo_rit_clear(active_receiver->id); return 0; } @@ -528,14 +544,17 @@ int ext_mode_minus(void *data) { return 0; } -int ext_ctun_update(void *data) { - int id=active_receiver->id; - vfo[id].ctun=vfo[id].ctun==1?0:1; +void ctun_update(int id,int state) { + vfo[id].ctun=state; if(!vfo[id].ctun) { vfo[id].offset=0; } vfo[id].ctun_frequency=vfo[id].frequency; - set_offset(active_receiver,vfo[id].offset); + set_offset(receiver[id],vfo[id].offset); +} + +int ext_ctun_update(void *data) { + ctun_update(active_receiver->id,vfo[active_receiver->id].ctun==1?0:1); g_idle_add(ext_vfo_update, NULL); return 0; } @@ -654,52 +673,403 @@ int ext_set_duplex(void *data) { return 0; } +#ifdef CLIENT_SERVER int ext_remote_command(void *data) { - REMOTE_COMMAND *p=(REMOTE_COMMAND *)data; - switch(p->cmd) { - case RX_FREQ_CMD: + HEADER *header=(HEADER *)data; + REMOTE_CLIENT *client=header->context.client; + int temp; + switch(ntohs(header->data_type)) { + case CMD_RESP_RX_FREQ: { - int b = get_band_from_frequency(p->data.frequency); - if (b != vfo[p->id].band) { - vfo_band_changed(b); - } - setFrequency(p->data.frequency); + FREQ_COMMAND *freq_command=(FREQ_COMMAND *)data; + temp=active_receiver->pan; + int vfo=freq_command->id; + long long f=ntohll(freq_command->hz); + local_set_frequency(vfo,f); + vfo_update(); + send_vfo_data(client,VFO_A); + send_vfo_data(client,VFO_B); + if(temp!=active_receiver->pan) { + send_pan(client->socket,active_receiver->id,active_receiver->pan); + } + } + break; + case CMD_RESP_RX_STEP: + { + STEP_COMMAND *step_command=(STEP_COMMAND *)data; + temp=active_receiver->pan; + short steps=ntohs(step_command->steps); + vfo_step(steps); + //send_vfo_data(client,VFO_A); + //send_vfo_data(client,VFO_B); + if(temp!=active_receiver->pan) { + send_pan(client->socket,active_receiver->id,active_receiver->pan); + } } break; - case RX_MOVE_CMD: - vfo_move(p->data.frequency,TRUE); + case CMD_RESP_RX_MOVE: + { + MOVE_COMMAND *move_command=(MOVE_COMMAND *)data; + temp=active_receiver->pan; + long long hz=ntohll(move_command->hz); + vfo_move(hz,move_command->round); + //send_vfo_data(client,VFO_A); + //send_vfo_data(client,VFO_B); + if(temp!=active_receiver->pan) { + send_pan(client->socket,active_receiver->id,active_receiver->pan); + } + } break; - case RX_MOVETO_CMD: - vfo_move_to(p->data.frequency); + case CMD_RESP_RX_MOVETO: + { + MOVE_TO_COMMAND *move_to_command=(MOVE_TO_COMMAND *)data; + temp=active_receiver->pan; + long long hz=ntohll(move_to_command->hz); + vfo_move_to(hz); + send_vfo_data(client,VFO_A); + send_vfo_data(client,VFO_B); + if(temp!=active_receiver->pan) { + send_pan(client->socket,active_receiver->id,active_receiver->pan); + } + } break; - case RX_MODE_CMD: - vfo_mode_changed(p->data.mode); + case CMD_RESP_RX_ZOOM: + { + ZOOM_COMMAND *zoom_command=(ZOOM_COMMAND *)data; + temp=ntohs(zoom_command->zoom); + set_zoom(zoom_command->id,(double)temp); + send_zoom(client->socket,active_receiver->id,active_receiver->zoom); + send_pan(client->socket,active_receiver->id,active_receiver->pan); + } break; - case RX_FILTER_CMD: - vfo_filter_changed(p->data.filter); + case CMD_RESP_RX_PAN: + { + PAN_COMMAND *pan_command=(PAN_COMMAND *)data; + temp=ntohs(pan_command->pan); + set_pan(pan_command->id,(double)temp); + send_pan(client->socket,active_receiver->id,active_receiver->pan); + } break; - case RX_AGC_CMD: - active_receiver->agc=p->data.agc; - set_agc(active_receiver, active_receiver->agc); - vfo_update(); + case CMD_RESP_RX_VOLUME: + { + VOLUME_COMMAND *volume_command=(VOLUME_COMMAND *)data; + temp=ntohs(volume_command->volume); + set_af_gain(volume_command->id,(double)temp/100.0); + } + break; + case CMD_RESP_RX_AGC: + { + AGC_COMMAND *agc_command=(AGC_COMMAND *)data; + RECEIVER *rx=receiver[agc_command->id]; + rx->agc=ntohs(agc_command->agc); +g_print("AGC_COMMAND: set_agc id=%d agc=%d\n",rx->id,rx->agc); + set_agc(rx,rx->agc); + send_agc(client->socket,rx->id,rx->agc); + g_idle_add(ext_vfo_update, NULL); + } + break; + case CMD_RESP_RX_AGC_GAIN: + { + AGC_GAIN_COMMAND *agc_gain_command=(AGC_GAIN_COMMAND *)data; + temp=ntohs(agc_gain_command->gain); + set_agc_gain(agc_gain_command->id,(double)temp); + RECEIVER *rx=receiver[agc_gain_command->id]; + send_agc_gain(client->socket,rx->id,(int)rx->agc_gain,(int)rx->agc_hang,(int)rx->agc_thresh); + } break; - case RX_NR_CMD: + case CMD_RESP_RX_ATTENUATION: + { + ATTENUATION_COMMAND *attenuation_command=(ATTENUATION_COMMAND *)data; + temp=ntohs(attenuation_command->attenuation); + set_attenuation(temp); + } break; - case RX_NB_CMD: + case CMD_RESP_RX_SQUELCH: + { + SQUELCH_COMMAND *squelch_command=(SQUELCH_COMMAND *)data; + receiver[squelch_command->id]->squelch_enable=squelch_command->enable; + temp=ntohs(squelch_command->squelch); + receiver[squelch_command->id]->squelch=(double)temp; + set_squelch(receiver[squelch_command->id]); + } break; - case RX_SNB_CMD: + case CMD_RESP_RX_NOISE: + { + NOISE_COMMAND *noise_command=(NOISE_COMMAND *)data; + RECEIVER *rx=receiver[noise_command->id]; + rx->nb=noise_command->nb; + rx->nb2=noise_command->nb2; + mode_settings[vfo[rx->id].mode].nb=rx->nb; + mode_settings[vfo[rx->id].mode].nb2=rx->nb2; + rx->nr=noise_command->nr; + rx->nr2=noise_command->nr2; + mode_settings[vfo[rx->id].mode].nr=rx->nr; + mode_settings[vfo[rx->id].mode].nr2=rx->nr2; + rx->anf=noise_command->anf; + mode_settings[vfo[rx->id].mode].anf=rx->anf; + rx->snb=noise_command->snb; + mode_settings[vfo[rx->id].mode].snb=rx->snb; + set_noise(); + send_noise(client->socket,rx->id,rx->nb,rx->nb2,rx->nr,rx->nr2,rx->anf,rx->snb); + } break; - case RX_SPLIT_CMD: + case CMD_RESP_RX_BAND: + { + BAND_COMMAND *band_command=(BAND_COMMAND *)data; + RECEIVER *rx=receiver[band_command->id]; + short b=htons(band_command->band); +g_print("BAND_COMMAND: id=%d band=%d\n",rx->id,b); + vfo_band_changed(rx->id,b); + send_vfo_data(client,VFO_A); + send_vfo_data(client,VFO_B); + } break; - case RX_SAT_CMD: + case CMD_RESP_RX_MODE: + { + MODE_COMMAND *mode_command=(MODE_COMMAND *)data; + RECEIVER *rx=receiver[mode_command->id]; + short m=htons(mode_command->mode); +g_print("MODE_COMMAND: id=%d mode=%d\n",rx->id,m); + vfo_mode_changed(m); + send_vfo_data(client,VFO_A); + send_vfo_data(client,VFO_B); + send_filter(client->socket,rx->id,m); + } break; - case RX_DUP_CMD: + case CMD_RESP_RX_FILTER: + { + FILTER_COMMAND *filter_command=(FILTER_COMMAND *)data; + RECEIVER *rx=receiver[filter_command->id]; + short f=htons(filter_command->filter); +g_print("FILTER_COMMAND: id=%d filter=%d\n",rx->id,f); + vfo_filter_changed(f); + send_vfo_data(client,VFO_A); + send_vfo_data(client,VFO_B); + send_filter(client->socket,rx->id,f); + } break; + case CMD_RESP_SPLIT: + { + SPLIT_COMMAND *split_command=(SPLIT_COMMAND *)data; +g_print("SPLIT_COMMAND: split=%d\n",split); + if(can_transmit) { + split=split_command->split; + tx_set_mode(transmitter,get_tx_mode()); + g_idle_add(ext_vfo_update, NULL); + } + send_split(client->socket,split); + } + break; + case CMD_RESP_SAT: + { + SAT_COMMAND *sat_command=(SAT_COMMAND *)data; + sat_mode=sat_command->sat; +g_print("SAT_COMMAND: sat_mode=%d\n",sat_mode); + g_idle_add(ext_vfo_update, NULL); + send_sat(client->socket,sat_mode); + } + break; + case CMD_RESP_DUP: + { + DUP_COMMAND *dup_command=(DUP_COMMAND *)data; + duplex=dup_command->dup; +g_print("DUP: duplex=%d\n",duplex); + g_idle_add(ext_vfo_update, NULL); + send_dup(client->socket,duplex); + } + break; + case CMD_RESP_LOCK: + { + LOCK_COMMAND *lock_command=(LOCK_COMMAND *)data; + locked=lock_command->lock; +g_print("LOCK: locked=%d\n",locked); + g_idle_add(ext_vfo_update, NULL); + send_lock(client->socket,locked); + } + break; + case CMD_RESP_CTUN: + { + CTUN_COMMAND *ctun_command=(CTUN_COMMAND *)data; +g_print("CTUN: vfo=%d ctun=%d\n",ctun_command->id,ctun_command->ctun); + int v=ctun_command->id; + vfo[v].ctun=ctun_command->ctun; + if(!vfo[v].ctun) { + vfo[v].offset=0; + } + vfo[v].ctun_frequency=vfo[v].frequency; + set_offset(active_receiver,vfo[v].offset); + g_idle_add(ext_vfo_update, NULL); + send_ctun(client->socket,v,vfo[v].ctun); + send_vfo_data(client,v); + } + break; + case CMD_RESP_RX_FPS: + { + FPS_COMMAND *fps_command=(FPS_COMMAND *)data; + int rx=fps_command->id; +g_print("FPS: rx=%d fps=%d\n",rx,fps_command->fps); + receiver[rx]->fps=fps_command->fps; + calculate_display_average(receiver[rx]); + set_displaying(receiver[rx],1); + send_fps(client->socket,rx,receiver[rx]->fps); + } + break; + case CMD_RESP_RX_SELECT: + { + RX_SELECT_COMMAND *rx_select_command=(RX_SELECT_COMMAND *)data; + int rx=rx_select_command->id; +g_print("RX_SELECT: rx=%d\n",rx); + receiver_set_active(receiver[rx]); + send_rx_select(client->socket,rx); + } + break; + case CMD_RESP_VFO: + { + VFO_COMMAND *vfo_command=(VFO_COMMAND *)data; + int action=vfo_command->id; +g_print("VFO: action=%d\n",action); + switch(action) { + case VFO_A_TO_B: + vfo_a_to_b(); + break; + case VFO_B_TO_A: + vfo_b_to_a(); + break; + case VFO_A_SWAP_B: + vfo_a_swap_b(); + break; + } + send_vfo_data(client,VFO_A); + send_vfo_data(client,VFO_B); + } + break; + case CMD_RESP_RIT_UPDATE: + { + RIT_UPDATE_COMMAND *rit_update_command=(RIT_UPDATE_COMMAND *)data; + int rx=rit_update_command->id; +g_print("RIT_UPDATE: rx=%d\n",rx); + vfo_rit_update(rx); + send_vfo_data(client,rx); + } + break; + case CMD_RESP_RIT_CLEAR: + { + RIT_CLEAR_COMMAND *rit_clear_command=(RIT_CLEAR_COMMAND *)data; + int rx=rit_clear_command->id; +g_print("RIT_CLEAR: rx=%d\n",rx); + vfo_rit_clear(rx); + send_vfo_data(client,rx); + } + break; + case CMD_RESP_RIT: + { + RIT_COMMAND *rit_command=(RIT_COMMAND *)data; + int rx=rit_command->id; + short rit=ntohs(rit_command->rit); +g_print("RIT: rx=%d rit=%d\n",rx,(int)rit); + vfo_rit(rx,(int)rit); + send_vfo_data(client,rx); + } + break; + case CMD_RESP_XIT_UPDATE: + { + XIT_UPDATE_COMMAND *xit_update_command=(XIT_UPDATE_COMMAND *)data; +g_print("XIT_UPDATE\n"); + send_vfo_data(client,VFO_A); + send_vfo_data(client,VFO_B); + } + break; + case CMD_RESP_XIT_CLEAR: + { + XIT_CLEAR_COMMAND *xit_clear_command=(XIT_CLEAR_COMMAND *)data; +g_print("XIT_CLEAR\n"); + send_vfo_data(client,VFO_A); + send_vfo_data(client,VFO_B); + } + break; + case CMD_RESP_XIT: + { + XIT_COMMAND *xit_command=(XIT_COMMAND *)data; + short xit=ntohs(xit_command->xit); +g_print("XIT_CLEAR: xit=%d\n",xit); + send_vfo_data(client,VFO_A); + send_vfo_data(client,VFO_B); + } + break; + case CMD_RESP_SAMPLE_RATE: + { + SAMPLE_RATE_COMMAND *sample_rate_command=(SAMPLE_RATE_COMMAND *)data; + int rx=(int)sample_rate_command->id; + long long rate=ntohll(sample_rate_command->sample_rate); +g_print("SAMPLE_RATE: rx=%d rate=%d\n",rx,(int)rate); + if(rx==-1) { + radio_change_sample_rate((int)rate); + send_sample_rate(client->socket,-1,radio_sample_rate); + } else { + receiver_change_sample_rate(receiver[rx],(int)rate); + send_sample_rate(client->socket,rx,receiver[rx]->sample_rate); + } + } + break; + case CMD_RESP_RECEIVERS: + { + RECEIVERS_COMMAND *receivers_command=(RECEIVERS_COMMAND *)data; + int r=receivers_command->receivers; +g_print("RECEIVERS: receivers=%d\n",r); + radio_change_receivers(r); + send_receivers(client->socket,receivers); + } + break; + case CMD_RESP_RIT_INCREMENT: + { + RIT_INCREMENT_COMMAND *rit_increment_command=(RIT_INCREMENT_COMMAND *)data; + short increment=ntohs(rit_increment_command->increment); +g_print("RIT_INCREMENT: increment=%d\n",increment); + rit_increment=(int)increment; + send_rit_increment(client->socket,rit_increment); + } + break; + case CMD_RESP_FILTER_BOARD: + { + FILTER_BOARD_COMMAND *filter_board_command=(FILTER_BOARD_COMMAND *)data; +g_print("FILTER_BOARD: board=%d\n",(int)filter_board_command->filter_board); + filter_board=(int)filter_board_command->filter_board; + load_filters(); + send_filter_board(client->socket,filter_board); + } + break; + case CMD_RESP_SWAP_IQ: + { + SWAP_IQ_COMMAND *swap_iq_command=(SWAP_IQ_COMMAND *)data; +g_print("SWAP_IQ: board=%d\n",(int)swap_iq_command->iqswap); + iqswap=(int)swap_iq_command->iqswap; + send_swap_iq(client->socket,iqswap); + } + break; + case CMD_RESP_REGION: + { + REGION_COMMAND *region_command=(REGION_COMMAND *)data; +g_print("REGION: region=%d\n",(int)region_command->region); + iqswap=(int)region_command->region; + send_region(client->socket,region); + } + break; + + + + } g_free(data); return 0; } +int ext_receiver_remote_update_display(void *data) { + RECEIVER *rx=(RECEIVER *)data; + receiver_remote_update_display(rx); + return 0; +} +#endif + int ext_anf_update(void *data) { if(active_receiver->anf==0) { active_receiver->anf=1; @@ -745,3 +1115,22 @@ int ext_pan_set(void *data) { } return 0; } + +int ext_remote_set_zoom(void *data) { + int zoom=GPOINTER_TO_INT(data); +g_print("ext_remote_set_zoom: %d\n",zoom); + remote_set_zoom(active_receiver->id,(double)zoom); + return 0; +} + +int ext_remote_set_pan(void *data) { + int pan=GPOINTER_TO_INT(data); +g_print("ext_remote_set_pan: %d\n",pan); + remote_set_pan(active_receiver->id,(double)pan); + return 0; +} + +int ext_set_title(void *data) { + gtk_window_set_title(GTK_WINDOW(top_window),(char *)data); + return 0; +} diff --git a/ext.h b/ext.h index 5af1617..51f1bcc 100644 --- a/ext.h +++ b/ext.h @@ -17,44 +17,21 @@ * */ +#ifdef CLIENT_SERVER +#include "client_server.h" +#endif // // The following calls functions can be called usig g_idle_add // Use these calls from within the rigclt daemon, or the GPIO or MIDI stuff // -enum { - RX_FREQ_CMD, - RX_MOVE_CMD, - RX_MOVETO_CMD, - RX_MODE_CMD, - RX_FILTER_CMD, - RX_AGC_CMD, - RX_NR_CMD, - RX_NB_CMD, - RX_SNB_CMD, - RX_SPLIT_CMD, - RX_SAT_CMD, - RX_DUP_CMD -}; - -typedef struct _REMOTE_COMMAND { - int id; - int cmd; - union { - long long frequency; - int mode; - int filter; - int agc; - int nr; - int nb; - int snb; - int split; - int sat; - int dup; - } data; -} REMOTE_COMMAND; +#ifdef CLIENT_SERVER +extern int ext_remote_command(void *data); +extern int ext_receiver_remote_update_display(void *data); +#endif +extern void local_set_frequency(int v,long long f); extern int ext_discovery(void *data); extern int ext_vfo_update(void *data); extern int ext_set_frequency(void *data); @@ -78,7 +55,9 @@ extern int ext_nr_update(void *data); extern int ext_nb_update(void *data); extern int ext_snb_update(void *data); extern int ext_anf_update(void *data); +extern void band_plus(int id); extern int ext_band_plus(void *data); +extern void band_minus(int id); extern int ext_band_minus(void *data); extern int ext_bandstack_plus(void *data); extern int ext_bandstack_minus(void *data); @@ -94,6 +73,7 @@ extern int ext_mode_plus(void *data); extern int ext_mode_minus(void *data); extern int ext_b_to_a(void *data); extern int ext_a_swap_b(void *data); +extern void ctun_update(int id,int state); extern int ext_ctun_update(void *data); extern int ext_agc_update(void *data); extern int ext_split_toggle(void *data); @@ -118,41 +98,45 @@ extern int ext_function_update(void *data); extern int ext_tx_set_ps(void *data); #endif -int ext_update_vfo_step(void *data); -int ext_vfo_step(void *data); -int ext_vfo_id_step(void *data); -int ext_vfo_mode_changed(void *data); -int ext_set_af_gain(void *data); -int ext_set_mic_gain(void *data); -int ext_set_agc_gain(void *data); -int ext_set_drive(void *data); -int ext_vfo_a_swap_b(void *data); -int ext_vfo_a_to_b(void *data); -int ext_vfo_b_to_a(void *data); -int ext_update_att_preamp(void *data); -int ext_set_alex_attenuation(void *data); -int ext_set_attenuation_value(void *data); -int ext_set_compression(void *data); - -int ext_start_rx(void *data); -int ext_start_tx(void *data); -int ext_diversity_update(void *data); -int ext_diversity_change_gain(void *data); -int ext_diversity_change_phase(void *data); -int ext_sat_update(void *data); -int ext_set_rf_gain(void *data); -int ext_set_duplex(void *data); - -int ext_update_noise(void *data); +extern int ext_update_vfo_step(void *data); +extern int ext_vfo_step(void *data); +extern int ext_vfo_id_step(void *data); +extern int ext_vfo_mode_changed(void *data); +extern int ext_set_af_gain(void *data); +extern int ext_set_mic_gain(void *data); +extern int ext_set_agc_gain(void *data); +extern int ext_set_drive(void *data); +extern int ext_vfo_a_swap_b(void *data); +extern int ext_vfo_a_to_b(void *data); +extern int ext_vfo_b_to_a(void *data); +extern int ext_update_att_preamp(void *data); +extern int ext_set_alex_attenuation(void *data); +extern int ext_set_attenuation_value(void *data); +extern int ext_set_compression(void *data); + +extern int ext_start_rx(void *data); +extern int ext_start_tx(void *data); +extern int ext_diversity_update(void *data); +extern int ext_diversity_change_gain(void *data); +extern int ext_diversity_change_phase(void *data); +extern int ext_sat_update(void *data); +extern int ext_set_rf_gain(void *data); +extern int ext_set_duplex(void *data); + +extern int ext_update_noise(void *data); #ifdef PURESIGNAL -int ext_start_ps(void *data); +extern int ext_start_ps(void *data); #endif -int ext_mute_update(void *data); +extern int ext_mute_update(void *data); + +extern int ext_zoom_update(void *data); +extern int ext_zoom_set(void *data); +extern int ext_pan_update(void *data); +extern int ext_pan_set(void *data); + +extern int ext_remote_set_zoom(void *data); +extern int ext_remote_set_pan(void *data); +extern int ext_set_title(void *data); -int ext_zoom_update(void *data); -int ext_zoom_set(void *data); -int ext_pan_update(void *data); -int ext_pan_set(void *data); -int ext_remote_command(void *data); diff --git a/freqent_menu.c b/freqent_menu.c index b378b3a..18803fa 100644 --- a/freqent_menu.c +++ b/freqent_menu.c @@ -120,22 +120,25 @@ static gboolean freqent_select_cb (GtkWidget *widget, gpointer data) { f = ((long long)(atof(buffer)*mult)+5)/10; sprintf(output, "%lld", f); gtk_label_set_markup (GTK_LABEL (label), output); - int b=get_band_from_frequency(f); - if(b!=band_get_current()) { - BAND *band=band_set_current(b); - set_mode(active_receiver,entry->mode); - FILTER* band_filters=filters[entry->mode]; - FILTER* band_filter=&band_filters[entry->filter]; - set_filter(active_receiver,band_filter->low,band_filter->high); - if(active_receiver->id==0) { - set_alex_rx_antenna(band->alexRxAntenna); - set_alex_tx_antenna(band->alexTxAntenna); - set_alex_attenuation(band->alexAttenuation); + if(radio_is_remote) { + send_vfo_frequency(client_socket,active_receiver->id,f); + } else { + int b=get_band_from_frequency(f); + if(b!=band_get_current()) { + BAND *band=band_set_current(b); + set_mode(active_receiver,entry->mode); + FILTER* band_filters=filters[entry->mode]; + FILTER* band_filter=&band_filters[entry->filter]; + set_filter(active_receiver,band_filter->low,band_filter->high); + if(active_receiver->id==0) { + set_alex_rx_antenna(band->alexRxAntenna); + set_alex_tx_antenna(band->alexTxAntenna); + set_alex_attenuation(band->alexAttenuation); + } } + setFrequency(f); + g_idle_add(ext_vfo_update,NULL); } - setFrequency(f); - g_idle_add(ext_vfo_update,NULL); - set = 1; } } diff --git a/gpio.c b/gpio.c index 4e277e9..d6d22d6 100644 --- a/gpio.c +++ b/gpio.c @@ -2064,40 +2064,13 @@ static void encoder_changed(int action,int pos) { set_drive(value); break; case ENCODER_RIT: - value=(double)vfo[active_receiver->id].rit; - value+=(double)(pos*rit_increment); - if(value<-10000.0) { - value=-10000.0; - } else if(value>10000.0) { - value=10000.0; - } - vfo[active_receiver->id].rit=(int)value; - receiver_frequency_changed(active_receiver); - g_idle_add(ext_vfo_update,NULL); + vfo_rit(active_receiver->id,pos); break; case ENCODER_RIT_RX1: - value=(double)vfo[receiver[0]->id].rit; - value+=(double)(pos*rit_increment); - if(value<-10000.0) { - value=-10000.0; - } else if(value>10000.0) { - value=10000.0; - } - vfo[receiver[0]->id].rit=(int)value; - receiver_frequency_changed(receiver[0]); - g_idle_add(ext_vfo_update,NULL); + vfo_rit(receiver[0]->id,pos); break; case ENCODER_RIT_RX2: - value=(double)vfo[receiver[1]->id].rit; - value+=(double)(pos*rit_increment); - if(value<-10000.0) { - value=-10000.0; - } else if(value>10000.0) { - value=10000.0; - } - vfo[receiver[1]->id].rit=(int)value; - receiver_frequency_changed(receiver[1]); - g_idle_add(ext_vfo_update,NULL); + vfo_rit(receiver[1]->id,pos); break; case ENCODER_XIT: value=(double)transmitter->xit; @@ -2223,6 +2196,7 @@ static void encoder_changed(int action,int pos) { update_diversity_phase((double)pos*0.1); break; case ENCODER_ZOOM: +g_print("GPIO: ENCODER_ZOOM: update_zoom: pos=%d\n",pos); update_zoom((double)pos); break; case ENCODER_PAN: diff --git a/main.c b/main.c index 39cdbb4..bc29204 100644 --- a/main.c +++ b/main.c @@ -146,19 +146,25 @@ gboolean main_delete (GtkWidget *widget) { #ifdef GPIO gpio_close(); #endif - switch(protocol) { - case ORIGINAL_PROTOCOL: - old_protocol_stop(); - break; - case NEW_PROTOCOL: - new_protocol_stop(); - break; +#ifdef CLIENT_SERVER + if(!radio_is_remote) { +#endif + switch(protocol) { + case ORIGINAL_PROTOCOL: + old_protocol_stop(); + break; + case NEW_PROTOCOL: + new_protocol_stop(); + break; #ifdef SOAPYSDR - case SOAPYSDR_PROTOCOL: - soapy_protocol_stop(); - break; + case SOAPYSDR_PROTOCOL: + soapy_protocol_stop(); + break; #endif + } +#ifdef CLIENT_SERVER } +#endif radioSaveState(); } _exit(0); @@ -182,7 +188,7 @@ static int init(void *data) { // Depending on the WDSP version, the file is wdspWisdom or wdspWisdom00. // sem_trywait() is not elegant, replaced this with wisdom_running variable. // - getcwd(wisdom_directory, sizeof(wisdom_directory)); + char *c=getcwd(wisdom_directory, sizeof(wisdom_directory)); strcpy(&wisdom_directory[strlen(wisdom_directory)],"/"); fprintf(stderr,"Securing wisdom file in directory: %s\n", wisdom_directory); status_text("Creating FFTW Wisdom file ..."); diff --git a/new_menu.c b/new_menu.c index ba24cfe..0bf1aeb 100644 --- a/new_menu.c +++ b/new_menu.c @@ -60,6 +60,9 @@ #include "gpio.h" #include "old_protocol.h" #include "new_protocol.h" +#ifdef CLIENT_SERVER +#include "server_menu.h" +#endif static GtkWidget *menu_b=NULL; @@ -453,6 +456,18 @@ static gboolean test_cb (GtkWidget *widget, GdkEventButton *event, gpointer data return TRUE; } +#ifdef CLIENT_SERVER +void start_server() { + cleanup(); + server_menu(top_window); +} + +static gboolean server_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + start_server(); + return TRUE; +} +#endif + void new_menu() { int i; @@ -624,6 +639,13 @@ void new_menu() i++; } +#ifdef CLIENT_SERVER + GtkWidget *server_b=gtk_button_new_with_label("Server"); + g_signal_connect (server_b, "button-press-event", G_CALLBACK(server_cb), NULL); + gtk_grid_attach(GTK_GRID(grid),server_b,(i%5),i/5,1,1); + i++; +#endif + GtkWidget *about_b=gtk_button_new_with_label("About"); g_signal_connect (about_b, "button-press-event", G_CALLBACK(about_b_cb), NULL); gtk_grid_attach(GTK_GRID(grid),about_b,(i%5),i/5,1,1); diff --git a/new_menu.h b/new_menu.h index 3fbf617..78699d2 100644 --- a/new_menu.h +++ b/new_menu.h @@ -22,6 +22,9 @@ extern void start_diversity(); #ifdef PURESIGNAL extern void start_ps(); #endif +#ifdef CLIENT_SERVER +extern void start_server(); +#endif extern void encoder_step(int encoder,int step); diff --git a/new_protocol.c b/new_protocol.c index 3aef1bd..40a33e1 100644 --- a/new_protocol.c +++ b/new_protocol.c @@ -150,11 +150,6 @@ static long micsamples_sequence=0; // This is shared with new_protocol_programmer.c int response; -//static sem_t send_high_priority_sem; -//static int send_high_priority=0; -//static sem_t send_general_sem; -//static int send_general=0; - #ifdef __APPLE__ static sem_t *command_response_sem_ready; static sem_t *command_response_sem_buffer; diff --git a/noise_menu.c b/noise_menu.c index bbef41b..f426b97 100644 --- a/noise_menu.c +++ b/noise_menu.c @@ -60,7 +60,7 @@ static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_d return FALSE; } -void update_noise() { +void set_noise() { SetEXTANBRun(active_receiver->id, active_receiver->nb); SetEXTNOBRun(active_receiver->id, active_receiver->nb2); SetRXAANRRun(active_receiver->id, active_receiver->nr); @@ -70,6 +70,18 @@ void update_noise() { g_idle_add(ext_vfo_update,NULL); } +void update_noise() { +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_noise(client_socket,active_receiver->id,active_receiver->nb,active_receiver->nb2,active_receiver->nr,active_receiver->nr2,active_receiver->anf,active_receiver->snb); + } else { +#endif + set_noise(); +#ifdef CLIENT_SERVER + } +#endif +} + static void nb_none_cb(GtkToggleButton *widget, gpointer data) { if(gtk_toggle_button_get_active(widget)) { active_receiver->nb=0; diff --git a/noise_menu.h b/noise_menu.h index c133727..a145076 100644 --- a/noise_menu.h +++ b/noise_menu.h @@ -20,3 +20,4 @@ extern void noise_menu(GtkWidget *parent); extern void update_noise(); +extern void set_noise(); diff --git a/pa_menu.h b/pa_menu.h index b985f76..03f440b 100644 --- a/pa_menu.h +++ b/pa_menu.h @@ -18,7 +18,6 @@ */ #include -#include #include #include diff --git a/radio.c b/radio.c index 19f6698..62bba24 100644 --- a/radio.c +++ b/radio.c @@ -24,8 +24,11 @@ #include #include #include +#include +#include #include #include +#include #include @@ -74,8 +77,8 @@ // we need here to make a strict compiler happy. void MIDIstartup(); #endif -#ifdef SERVER -#include "hpsdr_server.h" +#ifdef CLIENT_SERVER +#include "client_server.h" #endif #define min(x,y) (xid); void reconfigure_radio() { int i; int y; -//g_print("reconfigure_radio: receivers=%d\n",receivers); +g_print("reconfigure_radio: receivers=%d\n",receivers); rx_height=display_height-VFO_HEIGHT; if(display_zoompan) { rx_height-=ZOOMPAN_HEIGHT; @@ -435,6 +441,227 @@ static gboolean menu_cb (GtkWidget *widget, GdkEventButton *event, gpointer data return TRUE; } +static void create_visual() { + int y=0; + + fixed=gtk_fixed_new(); + g_object_ref(grid); // so it does not get deleted + gtk_container_remove(GTK_CONTAINER(top_window),grid); + gtk_container_add(GTK_CONTAINER(top_window), fixed); + +//g_print("radio: vfo_init\n"); + vfo_panel = vfo_init(VFO_WIDTH,VFO_HEIGHT,top_window); + gtk_fixed_put(GTK_FIXED(fixed),vfo_panel,0,y); + +//g_print("radio: meter_init\n"); + meter = meter_init(METER_WIDTH,METER_HEIGHT,top_window); + gtk_fixed_put(GTK_FIXED(fixed),meter,VFO_WIDTH,y); + + + GtkWidget *minimize_b=gtk_button_new_with_label("Hide"); + gtk_widget_override_font(minimize_b, pango_font_description_from_string("FreeMono Bold 10")); + gtk_widget_set_size_request (minimize_b, MENU_WIDTH, MENU_HEIGHT); + g_signal_connect (minimize_b, "button-press-event", G_CALLBACK(minimize_cb), NULL) ; + gtk_fixed_put(GTK_FIXED(fixed),minimize_b,VFO_WIDTH+METER_WIDTH,y); + y+=MENU_HEIGHT; + + GtkWidget *menu_b=gtk_button_new_with_label("Menu"); + gtk_widget_override_font(menu_b, pango_font_description_from_string("FreeMono Bold 10")); + gtk_widget_set_size_request (menu_b, MENU_WIDTH, MENU_HEIGHT); + g_signal_connect (menu_b, "button-press-event", G_CALLBACK(menu_cb), NULL) ; + gtk_fixed_put(GTK_FIXED(fixed),menu_b,VFO_WIDTH+METER_WIDTH,y); + y+=MENU_HEIGHT; + + + rx_height=display_height-VFO_HEIGHT; + if(display_zoompan) { + rx_height-=ZOOMPAN_HEIGHT; + } + if(display_sliders) { + rx_height-=SLIDERS_HEIGHT; + } + if(display_toolbar) { + rx_height-=TOOLBAR_HEIGHT; + } + + // + // To be on the safe side, we create ALL receiver panels here + // If upon startup, we only should display one panel, we do the switch below + // + for(int i=0;ix=0; + receiver[i]->y=y; + // Upon startup, if RIT or CTUN is active, tell WDSP. +#ifdef CLIENT_SERVER + if(!radio_is_remote) { +#endif + set_displaying(receiver[i],1); + set_offset(receiver[i],vfo[i].offset); +#ifdef CLIENT_SERVER + } +#endif + gtk_fixed_put(GTK_FIXED(fixed),receiver[i]->panel,0,y); + g_object_ref((gpointer)receiver[i]->panel); + y+=rx_height/RECEIVERS; + } + + // + // Sanity check: in old protocol, all receivers must have the same sample rate + // + if((protocol==ORIGINAL_PROTOCOL) && (RECEIVERS==2) && (receiver[0]->sample_rate!=receiver[1]->sample_rate)) { + receiver[1]->sample_rate=receiver[0]->sample_rate; + } + + active_receiver=receiver[0]; + +// TEMP +#ifdef CLIENT_SERVER +if(!radio_is_remote) { +#endif + //g_print("Create transmitter\n"); + if(can_transmit) { + double pk; + if(duplex) { + transmitter=create_transmitter(CHANNEL_TX, buffer_size, fft_size, updates_per_second, display_width/4, display_height/2); + } else { + int tx_height=display_height-VFO_HEIGHT; + if(display_zoompan) tx_height-=ZOOMPAN_HEIGHT; + if(display_sliders) tx_height-=SLIDERS_HEIGHT; + if(display_toolbar) tx_height-=TOOLBAR_HEIGHT; + transmitter=create_transmitter(CHANNEL_TX, buffer_size, fft_size, updates_per_second, display_width, tx_height); + } + transmitter->x=0; + transmitter->y=VFO_HEIGHT; + + calcDriveLevel(); + +#ifdef PURESIGNAL + tx_set_ps_sample_rate(transmitter,protocol==NEW_PROTOCOL?192000:active_receiver->sample_rate); + receiver[PS_TX_FEEDBACK]=create_pure_signal_receiver(PS_TX_FEEDBACK, buffer_size,protocol==ORIGINAL_PROTOCOL?active_receiver->sample_rate:192000,display_width); + receiver[PS_RX_FEEDBACK]=create_pure_signal_receiver(PS_RX_FEEDBACK, buffer_size,protocol==ORIGINAL_PROTOCOL?active_receiver->sample_rate:192000,display_width); + switch (protocol) { + case NEW_PROTOCOL: + pk = 0.2899; + break; + case ORIGINAL_PROTOCOL: + switch (device) { + case DEVICE_HERMES_LITE2: + pk = 0.2300; + break; + default: + pk = 0.4067; + break; + } + } + SetPSHWPeak(transmitter->id, pk); +#endif + + } +#ifdef CLIENT_SERVER +} +#endif + +#ifdef AUDIO_WATERFALL + audio_waterfall=audio_waterfall_init(200,100); + gtk_fixed_put(GTK_FIXED(fixed),audio_waterfall,0,VFO_HEIGHT+20); +#endif + + gboolean init_gpio=FALSE; +#ifdef LOCALCW + init_gpio=TRUE; +#endif +#ifdef PTT + init_gpio=TRUE; +#endif +#ifdef GPIO + init_gpio=TRUE; +#endif + + if(init_gpio) { +#ifdef GPIO + if(gpio_init()<0) { + g_print("GPIO failed to initialize\n"); + } +#endif + } + +#ifdef LOCALCW + // init local keyer if enabled + if (cw_keyer_internal == 0) { + g_print("Initialize keyer.....\n"); + keyer_update(); + } +#endif + +#ifdef CLIENT_SERVER + if(!radio_is_remote) { +#endif + switch(protocol) { + case ORIGINAL_PROTOCOL: + old_protocol_init(0,display_width,receiver[0]->sample_rate); + break; + case NEW_PROTOCOL: + new_protocol_init(display_width); + break; +#ifdef SOAPYSDR + case SOAPYSDR_PROTOCOL: + soapy_protocol_init(0,false); + break; +#endif + } +#ifdef CLIENT_SERVER + } +#endif + + if(display_zoompan) { + zoompan = zoompan_init(display_width,ZOOMPAN_HEIGHT); + gtk_fixed_put(GTK_FIXED(fixed),zoompan,0,y); + y+=ZOOMPAN_HEIGHT; + } + + if(display_sliders) { +//g_print("create sliders\n"); + sliders = sliders_init(display_width,SLIDERS_HEIGHT); + gtk_fixed_put(GTK_FIXED(fixed),sliders,0,y); + y+=SLIDERS_HEIGHT; + } + + + if(display_toolbar) { + toolbar = toolbar_init(display_width,TOOLBAR_HEIGHT,top_window); + gtk_fixed_put(GTK_FIXED(fixed),toolbar,0,y); + y+=TOOLBAR_HEIGHT; + } + +// +// Now, if there should only one receiver be displayed +// at startup, do the change. We must momentarily fake +// the number of receivers otherwise radio_change_receivers +// will do nothing. +// +g_print("create_visual: receivers=%d RECEIVERS=%d\n",receivers,RECEIVERS); + if (receivers != RECEIVERS) { + int r=receivers; + receivers=RECEIVERS; +g_print("create_visual: calling radio_change_receivers: receivers=%d r=%d\n",receivers,r); + radio_change_receivers(r); + } + + //gtk_widget_show_all (fixed); + gtk_widget_show_all (top_window); + +} + void start_radio() { int i; int y; @@ -621,27 +848,12 @@ void start_radio() { // // A semaphore for safely writing to the props file // -#ifdef __APPLE__ - sem_unlink("PROPERTY"); - property_sem=sem_open("PROPERTY", O_CREAT | O_EXCL, 0700, 0); - rc=(property_sem == SEM_FAILED); -#else - rc=sem_init(&property_sem, 0, 0); -#endif - if(rc!=0) { - g_print("start_radio: sem_init failed for property_sem: %d\n", rc); - exit(-1); - } -#ifdef __APPLE__ - sem_post(property_sem); -#else - sem_post(&property_sem); -#endif + g_mutex_init(&property_mutex); // // Create text for the top line of the piHPSDR window // - char text[256]; + char text[1024]; switch(protocol) { case ORIGINAL_PROTOCOL: case NEW_PROTOCOL: @@ -666,7 +878,7 @@ void start_radio() { char version[32]; char mac[32]; char ip[32]; - char iface[32]; + char iface[64]; switch(protocol) { case ORIGINAL_PROTOCOL: @@ -860,6 +1072,7 @@ void start_radio() { if(device==SOAPYSDR_USB_DEVICE) { iqswap=1; receivers=1; + filter_board=NONE; } #endif @@ -984,194 +1197,7 @@ void start_radio() { radio_change_region(region); - y=0; - - fixed=gtk_fixed_new(); - g_object_ref(grid); // so it does not get deleted - gtk_container_remove(GTK_CONTAINER(top_window),grid); - gtk_container_add(GTK_CONTAINER(top_window), fixed); - -//g_print("radio: vfo_init\n"); - vfo_panel = vfo_init(VFO_WIDTH,VFO_HEIGHT,top_window); - gtk_fixed_put(GTK_FIXED(fixed),vfo_panel,0,y); - -//g_print("radio: meter_init\n"); - meter = meter_init(METER_WIDTH,METER_HEIGHT,top_window); - gtk_fixed_put(GTK_FIXED(fixed),meter,VFO_WIDTH,y); - - - GtkWidget *minimize_b=gtk_button_new_with_label("Hide"); - gtk_widget_override_font(minimize_b, pango_font_description_from_string("FreeMono Bold 10")); - gtk_widget_set_size_request (minimize_b, MENU_WIDTH, MENU_HEIGHT); - g_signal_connect (minimize_b, "button-press-event", G_CALLBACK(minimize_cb), NULL) ; - gtk_fixed_put(GTK_FIXED(fixed),minimize_b,VFO_WIDTH+METER_WIDTH,y); - y+=MENU_HEIGHT; - - GtkWidget *menu_b=gtk_button_new_with_label("Menu"); - gtk_widget_override_font(menu_b, pango_font_description_from_string("FreeMono Bold 10")); - gtk_widget_set_size_request (menu_b, MENU_WIDTH, MENU_HEIGHT); - g_signal_connect (menu_b, "button-press-event", G_CALLBACK(menu_cb), NULL) ; - gtk_fixed_put(GTK_FIXED(fixed),menu_b,VFO_WIDTH+METER_WIDTH,y); - y+=MENU_HEIGHT; - - - rx_height=display_height-VFO_HEIGHT; - if(display_zoompan) { - rx_height-=ZOOMPAN_HEIGHT; - } - if(display_sliders) { - rx_height-=SLIDERS_HEIGHT; - } - if(display_toolbar) { - rx_height-=TOOLBAR_HEIGHT; - } - - // - // To be on the safe side, we create ALL receiver panels here - // If upon startup, we only should display one panel, we do the switch below - // - for(i=0;ix=0; - receiver[i]->y=y; - gtk_fixed_put(GTK_FIXED(fixed),receiver[i]->panel,0,y); - g_object_ref((gpointer)receiver[i]->panel); - set_displaying(receiver[i],1); - y+=rx_height/RECEIVERS; - // Upon startup, if RIT or CTUN is active, tell WDSP. - set_offset(receiver[i],vfo[i].offset); - } - - // - // Sanity check: in old protocol, all receivers must have the same sample rate - // - if((protocol==ORIGINAL_PROTOCOL) && (RECEIVERS==2) && (receiver[0]->sample_rate!=receiver[1]->sample_rate)) { - receiver[1]->sample_rate=receiver[0]->sample_rate; - } - - active_receiver=receiver[0]; - - //g_print("Create transmitter\n"); - if(can_transmit) { - double pk; - if(duplex) { - transmitter=create_transmitter(CHANNEL_TX, buffer_size, fft_size, updates_per_second, display_width/4, display_height/2); - } else { - int tx_height=display_height-VFO_HEIGHT; - if(display_zoompan) tx_height-=ZOOMPAN_HEIGHT; - if(display_sliders) tx_height-=SLIDERS_HEIGHT; - if(display_toolbar) tx_height-=TOOLBAR_HEIGHT; - transmitter=create_transmitter(CHANNEL_TX, buffer_size, fft_size, updates_per_second, display_width, tx_height); - } - transmitter->x=0; - transmitter->y=VFO_HEIGHT; - - calcDriveLevel(); - -#ifdef PURESIGNAL - tx_set_ps_sample_rate(transmitter,protocol==NEW_PROTOCOL?192000:active_receiver->sample_rate); - receiver[PS_TX_FEEDBACK]=create_pure_signal_receiver(PS_TX_FEEDBACK, buffer_size,protocol==ORIGINAL_PROTOCOL?active_receiver->sample_rate:192000,display_width); - receiver[PS_RX_FEEDBACK]=create_pure_signal_receiver(PS_RX_FEEDBACK, buffer_size,protocol==ORIGINAL_PROTOCOL?active_receiver->sample_rate:192000,display_width); - switch (protocol) { - case NEW_PROTOCOL: - pk = 0.2899; - break; - case ORIGINAL_PROTOCOL: - switch (device) { - case DEVICE_HERMES_LITE2: - pk = 0.2300; - break; - default: - pk = 0.4067; - break; - } - } - SetPSHWPeak(transmitter->id, pk); -#endif - - } - -#ifdef AUDIO_WATERFALL - audio_waterfall=audio_waterfall_init(200,100); - gtk_fixed_put(GTK_FIXED(fixed),audio_waterfall,0,VFO_HEIGHT+20); -#endif - - gboolean init_gpio=FALSE; -#ifdef LOCALCW - init_gpio=TRUE; -#endif -#ifdef PTT - init_gpio=TRUE; -#endif -#ifdef GPIO - init_gpio=TRUE; -#endif - - if(init_gpio) { -#ifdef GPIO - if(gpio_init()<0) { - g_print("GPIO failed to initialize\n"); - } -#endif - } - -#ifdef LOCALCW - // init local keyer if enabled - if (cw_keyer_internal == 0) { - g_print("Initialize keyer.....\n"); - keyer_update(); - } -#endif - - switch(protocol) { - case ORIGINAL_PROTOCOL: - old_protocol_init(0,display_width,receiver[0]->sample_rate); - break; - case NEW_PROTOCOL: - new_protocol_init(display_width); - break; -#ifdef SOAPYSDR - case SOAPYSDR_PROTOCOL: - soapy_protocol_init(0,false); - break; -#endif - } - - if(display_zoompan) { - zoompan = zoompan_init(display_width,ZOOMPAN_HEIGHT); - gtk_fixed_put(GTK_FIXED(fixed),zoompan,0,y); - y+=ZOOMPAN_HEIGHT; - } - - if(display_sliders) { -//g_print("create sliders\n"); - sliders = sliders_init(display_width,SLIDERS_HEIGHT); - gtk_fixed_put(GTK_FIXED(fixed),sliders,0,y); - y+=SLIDERS_HEIGHT; - } - - - if(display_toolbar) { - toolbar = toolbar_init(display_width,TOOLBAR_HEIGHT,top_window); - gtk_fixed_put(GTK_FIXED(fixed),toolbar,0,y); - y+=TOOLBAR_HEIGHT; - } - -// -// Now, if there should only one receiver be displayed -// at startup, do the change. We must momentarily fake -// the number of receivers otherwise radio_change_receivers -// will do nothing. -// - if (receivers != RECEIVERS) { - i=receivers, - receivers=RECEIVERS; - radio_change_receivers(i); - } - - gtk_widget_show_all (fixed); - + create_visual(); // save every 30 seconds //save_timer_id=gdk_threads_add_timeout(30000, save_cb, NULL); @@ -1245,10 +1271,11 @@ void start_radio() { MIDIstartup(); #endif -#ifdef SERVER - create_hpsdr_server(); +#ifdef CLIENT_SERVER + if(hpsdr_server) { + create_hpsdr_server(); + } #endif - } void disable_rigctl() { @@ -1258,17 +1285,23 @@ void disable_rigctl() { void radio_change_receivers(int r) { +g_print("radio_change_receivers: from %d to %d\n",receivers,r); // The button in the radio menu will call this function even if the // number of receivers has not changed. if (receivers == r) return; - g_print("radio_change_receivers: from %d to %d\n",receivers,r); // // When changing the number of receivers, restart the // old protocol // - if (protocol == ORIGINAL_PROTOCOL) { - old_protocol_stop(); +#ifdef CLIENT_SERVER + if(!radio_is_remote) { +#endif + if (protocol == ORIGINAL_PROTOCOL) { + old_protocol_stop(); + } +#ifdef CLIENT_SERVER } +#endif switch(r) { case 1: set_displaying(receiver[1],0); @@ -1283,12 +1316,18 @@ void radio_change_receivers(int r) { } reconfigure_radio(); active_receiver=receiver[0]; - if(protocol==NEW_PROTOCOL) { - schedule_high_priority(); - } - if (protocol == ORIGINAL_PROTOCOL) { - old_protocol_run(); +#ifdef CLIENT_SERVER + if(!radio_is_remote) { +#endif + if(protocol==NEW_PROTOCOL) { + schedule_high_priority(); + } + if (protocol == ORIGINAL_PROTOCOL) { + old_protocol_run(); + } +#ifdef CLIENT_SERVER } +#endif } void radio_change_sample_rate(int rate) { @@ -1781,20 +1820,29 @@ void set_alex_attenuation(int v) { } void radioRestoreState() { - char name[32]; - char *value; - int i; + char name[32]; + char *value; + int i; g_print("radioRestoreState: %s\n",property_path); -//g_print("sem_wait\n"); -#ifdef __APPLE__ - sem_wait(property_sem); -#else - sem_wait(&property_sem); + g_mutex_lock(&property_mutex); + loadProperties(property_path); + + value=getProperty("display_filled"); + if(value) display_filled=atoi(value); + value=getProperty("display_zoompan"); + if(value) display_zoompan=atoi(value); + value=getProperty("display_sliders"); + if(value) display_sliders=atoi(value); + value=getProperty("display_toolbar"); + if(value) display_toolbar=atoi(value); + +#ifdef CLIENT_SERVER + if(radio_is_remote) { +#ifdef CLIENT_SERVER +#endif + } else { #endif -//g_print("sem_wait: returner\n"); - loadProperties(property_path); - value=getProperty("diversity_enabled"); if (value) diversity_enabled=atoi(value); value=getProperty("diversity_gain"); @@ -1830,8 +1878,6 @@ g_print("radioRestoreState: %s\n",property_path); } value=getProperty("updates_per_second"); if(value) updates_per_second=atoi(value); - value=getProperty("display_filled"); - if(value) display_filled=atoi(value); value=getProperty("display_detector_mode"); if(value) display_detector_mode=atoi(value); value=getProperty("display_average_mode"); @@ -1842,12 +1888,6 @@ g_print("radioRestoreState: %s\n",property_path); if(value) panadapter_high=atoi(value); value=getProperty("panadapter_low"); if(value) panadapter_low=atoi(value); - value=getProperty("display_zoompan"); - if(value) display_zoompan=atoi(value); - value=getProperty("display_sliders"); - if(value) display_sliders=atoi(value); - value=getProperty("display_toolbar"); - if(value) display_toolbar=atoi(value); value=getProperty("waterfall_high"); if(value) waterfall_high=atoi(value); value=getProperty("waterfall_low"); @@ -2013,51 +2053,89 @@ g_print("radioRestoreState: %s\n",property_path); if(value) mute_rx_while_transmitting=atoi(value); #ifdef SOAPYSDR - if(device==SOAPYSDR_USB_DEVICE) { - char name[128]; - for(int i=0;iinfo.soapy.rx_gains;i++) { - sprintf(name,"radio.adc[0].rx_gain.%s",radio->info.soapy.rx_gain[i]) ; - value=getProperty(name); - if(value!=NULL) adc[0].rx_gain[i]=atoi(value); - } - value=getProperty("radio.adc[0].agc"); - if(value!=NULL) adc[0].agc=atoi(value); - value=getProperty("radio.adc[0].antenna"); - if(value!=NULL) adc[0].antenna=atoi(value); - - value=getProperty("radio.dac[0].antenna"); - if(value!=NULL) dac[0].antenna=atoi(value); - for(int i=0;iinfo.soapy.tx_gains;i++) { - sprintf(name,"radio.dac[0].tx_gain.%s",radio->info.soapy.tx_gain[i]); - value=getProperty(name); - if(value!=NULL) dac[0].tx_gain[i]=atoi(value); + if(device==SOAPYSDR_USB_DEVICE) { + char name[128]; + for(int i=0;iinfo.soapy.rx_gains;i++) { + sprintf(name,"radio.adc[0].rx_gain.%s",radio->info.soapy.rx_gain[i]) ; + value=getProperty(name); + if(value!=NULL) adc[0].rx_gain[i]=atoi(value); + } + value=getProperty("radio.adc[0].agc"); + if(value!=NULL) adc[0].agc=atoi(value); + value=getProperty("radio.adc[0].antenna"); + if(value!=NULL) adc[0].antenna=atoi(value); + + value=getProperty("radio.dac[0].antenna"); + if(value!=NULL) dac[0].antenna=atoi(value); + for(int i=0;iinfo.soapy.tx_gains;i++) { + sprintf(name,"radio.dac[0].tx_gain.%s",radio->info.soapy.tx_gain[i]); + value=getProperty(name); + if(value!=NULL) dac[0].tx_gain[i]=atoi(value); + } } - } #endif - value=getProperty("radio.display_sequence_errors"); - if(value!=NULL) display_sequence_errors=atoi(value); + value=getProperty("radio.display_sequence_errors"); + if(value!=NULL) display_sequence_errors=atoi(value); + + -//g_print("sem_post\n"); -#ifdef __APPLE__ - sem_post(property_sem); -#else - sem_post(&property_sem); +#ifdef CLIENT_SERVER + } #endif + +#ifdef CLIENT_SERVER + value=getProperty("radio.hpsdr_server"); + if(value!=NULL) hpsdr_server=atoi(value); + value=getProperty("radio.hpsdr_server.listen_port"); + if(value!=NULL) listen_port=atoi(value); +#endif + + g_mutex_unlock(&property_mutex); } void radioSaveState() { - int i; - char value[80]; - char name[32]; + int i; + char value[80]; + char name[32]; + g_print("radioSaveState: %s\n",property_path); -#ifdef __APPLE__ - sem_wait(property_sem); -#else - sem_wait(&property_sem); + + g_mutex_lock(&property_mutex); + clearProperties(); +#ifdef GPIO + if(controller!=NO_CONTROLLER) { + gpio_save_actions(); + } +#endif + sprintf(value,"%d",receivers); + setProperty("receivers",value); + for(i=0;iname,server); + radio_is_remote=TRUE; +#ifdef GPIO + switch(controller) { + case CONTROLLER2_V1: + case CONTROLLER2_V2: + display_zoompan=1; + display_sliders=0; + display_toolbar=0; + break; + default: + display_zoompan=1; + display_sliders=1; + display_toolbar=1; + break; + } +#else + display_zoompan=1; + display_sliders=1; + display_toolbar=1; +#endif + radioRestoreState(); + create_visual(); + for(int i=0;ilocal_audio) { + audio_open_output(receiver[i]); + } + } + reconfigure_radio(); + g_idle_add(ext_vfo_update,(gpointer)NULL); + gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_ARROW)); +#ifdef MIDI + MIDIstartup(); +#endif + for(int i=0;iVFO Encoder Divisor:"); gtk_grid_attach(GTK_GRID(grid),vfo_divisor_label,col,row,1,1); @@ -662,6 +682,7 @@ void radio_menu(GtkWidget *parent) { gtk_grid_attach(GTK_GRID(grid),vfo_divisor,col,row,1,1); g_signal_connect(vfo_divisor,"value_changed",G_CALLBACK(vfo_divisor_value_changed_cb),NULL); row++; +#endif GtkWidget *iqswap_b=gtk_check_button_new_with_label("Swap IQ"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (iqswap_b), iqswap); diff --git a/radio_menu.h b/radio_menu.h index 7af7eab..b2d495d 100644 --- a/radio_menu.h +++ b/radio_menu.h @@ -19,3 +19,4 @@ extern void radio_menu(GtkWidget *parent); extern void setDuplex(void); +extern void load_filters(void); diff --git a/receiver.c b/receiver.c index 8ae57f2..c6e1ec0 100644 --- a/receiver.c +++ b/receiver.c @@ -51,6 +51,9 @@ #endif #include "ext.h" #include "new_menu.h" +#ifdef CLIENT_SERVER +#include "client_server.h" +#endif #define min(x,y) (xbutton==3) { - g_idle_add(ext_start_rx,NULL); - } - - // setup the transmitter mode and filter - tx_set_mode(transmitter,get_tx_mode()); - - //g_print("receiver: %d adc=%d attenuation=%d rx_gain_calibration=%d\n",rx->id,rx->adc,adc_attenuation[rx->adc],rx_gain_calibration); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_rx_select(client_socket,rx->id); + } else { +#endif + receiver_set_active(rx); + if(event->button==3) { + g_idle_add(ext_start_rx,NULL); + } +#ifdef CLIENT_SERVER + } +#endif } else { if(pressed) { int x=(int)event->x; @@ -161,117 +175,7 @@ void receiver_save_state(RECEIVER *rx) { char name[128]; char value[128]; - sprintf(name,"receiver.%d.alex_antenna",rx->id); - sprintf(value,"%d",rx->alex_antenna); - setProperty(name,value); - -#ifdef PURESIGNAL - // - // for PS_RX_RECEIVER, *only* save the ALEX antenna setting - // and then return quickly. - // - if (rx->id == PS_RX_FEEDBACK) return; -#endif - - sprintf(name,"receiver.%d.sample_rate",rx->id); - sprintf(value,"%d",rx->sample_rate); - setProperty(name,value); - sprintf(name,"receiver.%d.adc",rx->id); - sprintf(value,"%d",rx->adc); - setProperty(name,value); - sprintf(name,"receiver.%d.filter_low",rx->id); - sprintf(value,"%d",rx->filter_low); - setProperty(name,value); - sprintf(name,"receiver.%d.filter_high",rx->id); - sprintf(value,"%d",rx->filter_high); - setProperty(name,value); - sprintf(name,"receiver.%d.fps",rx->id); - sprintf(value,"%d",rx->fps); - setProperty(name,value); - sprintf(name,"receiver.%d.panadapter_low",rx->id); - sprintf(value,"%d",rx->panadapter_low); - setProperty(name,value); - sprintf(name,"receiver.%d.panadapter_high",rx->id); - sprintf(value,"%d",rx->panadapter_high); - setProperty(name,value); - sprintf(name,"receiver.%d.panadapter_step",rx->id); - sprintf(value,"%d",rx->panadapter_step); - setProperty(name,value); - sprintf(name,"receiver.%d.display_waterfall",rx->id); - sprintf(value,"%d",rx->display_waterfall); - setProperty(name,value); - sprintf(name,"receiver.%d.waterfall_low",rx->id); - sprintf(value,"%d",rx->waterfall_low); - setProperty(name,value); - sprintf(name,"receiver.%d.waterfall_high",rx->id); - sprintf(value,"%d",rx->waterfall_high); - setProperty(name,value); - sprintf(name,"receiver.%d.waterfall_automatic",rx->id); - sprintf(value,"%d",rx->waterfall_automatic); - setProperty(name,value); - - sprintf(name,"receiver.%d.alex_attenuation",rx->id); - sprintf(value,"%d",rx->alex_attenuation); - setProperty(name,value); - sprintf(name,"receiver.%d.volume",rx->id); - sprintf(value,"%f",rx->volume); - setProperty(name,value); - sprintf(name,"receiver.%d.rf_gain",rx->id); - sprintf(value,"%f",rx->rf_gain); - setProperty(name,value); - sprintf(name,"receiver.%d.agc",rx->id); - sprintf(value,"%d",rx->agc); - setProperty(name,value); - sprintf(name,"receiver.%d.agc_gain",rx->id); - sprintf(value,"%f",rx->agc_gain); - setProperty(name,value); - sprintf(name,"receiver.%d.agc_slope",rx->id); - sprintf(value,"%f",rx->agc_slope); - setProperty(name,value); - sprintf(name,"receiver.%d.agc_hang_threshold",rx->id); - sprintf(value,"%f",rx->agc_hang_threshold); - setProperty(name,value); - - sprintf(name,"receiver.%d.dither",rx->id); - sprintf(value,"%d",rx->dither); - setProperty(name,value); - sprintf(name,"receiver.%d.random",rx->id); - sprintf(value,"%d",rx->random); - setProperty(name,value); - sprintf(name,"receiver.%d.preamp",rx->id); - sprintf(value,"%d",rx->preamp); - setProperty(name,value); - sprintf(name,"receiver.%d.nb",rx->id); - sprintf(value,"%d",rx->nb); - setProperty(name,value); - sprintf(name,"receiver.%d.nb2",rx->id); - sprintf(value,"%d",rx->nb2); - setProperty(name,value); - sprintf(name,"receiver.%d.nr",rx->id); - sprintf(value,"%d",rx->nr); - setProperty(name,value); - sprintf(name,"receiver.%d.nr2",rx->id); - sprintf(value,"%d",rx->nr2); - setProperty(name,value); - sprintf(name,"receiver.%d.anf",rx->id); - sprintf(value,"%d",rx->anf); - setProperty(name,value); - sprintf(name,"receiver.%d.snb",rx->id); - sprintf(value,"%d",rx->snb); - setProperty(name,value); - sprintf(name,"receiver.%d.nr_agc",rx->id); - sprintf(value,"%d",rx->nr_agc); - setProperty(name,value); - sprintf(name,"receiver.%d.nr2_gain_method",rx->id); - sprintf(value,"%d",rx->nr2_gain_method); - setProperty(name,value); - sprintf(name,"receiver.%d.nr2_npe_method",rx->id); - sprintf(value,"%d",rx->nr2_npe_method); - setProperty(name,value); - sprintf(name,"receiver.%d.nr2_ae",rx->id); - sprintf(value,"%d",rx->nr2_ae); - setProperty(name,value); - + g_print("receiver_save_state: %d\n",rx->id); sprintf(name,"receiver.%d.audio_channel",rx->id); sprintf(value,"%d",rx->audio_channel); setProperty(name,value); @@ -296,27 +200,144 @@ void receiver_save_state(RECEIVER *rx) { sprintf(value,"%d",rx->mute_radio); setProperty(name,value); - sprintf(name,"receiver.%d.low_latency",rx->id); - sprintf(value,"%d",rx->low_latency); - setProperty(name,value); +#ifdef CLIENT_SERVER + if(!radio_is_remote) { +#endif + sprintf(name,"receiver.%d.alex_antenna",rx->id); + sprintf(value,"%d",rx->alex_antenna); + setProperty(name,value); - sprintf(name,"receiver.%d.deviation",rx->id); - sprintf(value,"%d",rx->deviation); - setProperty(name,value); +#ifdef PURESIGNAL + // + // for PS_RX_RECEIVER, *only* save the ALEX antenna setting + // and then return quickly. + // + if (rx->id == PS_RX_FEEDBACK) return; +#endif - sprintf(name,"receiver.%d.squelch_enable",rx->id); - sprintf(value,"%d",rx->squelch_enable); - setProperty(name,value); - sprintf(name,"receiver.%d.squelch",rx->id); - sprintf(value,"%f",rx->squelch); - setProperty(name,value); + sprintf(name,"receiver.%d.sample_rate",rx->id); + sprintf(value,"%d",rx->sample_rate); + setProperty(name,value); + sprintf(name,"receiver.%d.adc",rx->id); + sprintf(value,"%d",rx->adc); + setProperty(name,value); + sprintf(name,"receiver.%d.filter_low",rx->id); + sprintf(value,"%d",rx->filter_low); + setProperty(name,value); + sprintf(name,"receiver.%d.filter_high",rx->id); + sprintf(value,"%d",rx->filter_high); + setProperty(name,value); + sprintf(name,"receiver.%d.fps",rx->id); + sprintf(value,"%d",rx->fps); + setProperty(name,value); + sprintf(name,"receiver.%d.panadapter_low",rx->id); + sprintf(value,"%d",rx->panadapter_low); + setProperty(name,value); + sprintf(name,"receiver.%d.panadapter_high",rx->id); + sprintf(value,"%d",rx->panadapter_high); + setProperty(name,value); + sprintf(name,"receiver.%d.panadapter_step",rx->id); + sprintf(value,"%d",rx->panadapter_step); + setProperty(name,value); + sprintf(name,"receiver.%d.display_waterfall",rx->id); + sprintf(value,"%d",rx->display_waterfall); + setProperty(name,value); + sprintf(name,"receiver.%d.waterfall_low",rx->id); + sprintf(value,"%d",rx->waterfall_low); + setProperty(name,value); + sprintf(name,"receiver.%d.waterfall_high",rx->id); + sprintf(value,"%d",rx->waterfall_high); + setProperty(name,value); + sprintf(name,"receiver.%d.waterfall_automatic",rx->id); + sprintf(value,"%d",rx->waterfall_automatic); + setProperty(name,value); + + sprintf(name,"receiver.%d.alex_attenuation",rx->id); + sprintf(value,"%d",rx->alex_attenuation); + setProperty(name,value); + sprintf(name,"receiver.%d.volume",rx->id); + sprintf(value,"%f",rx->volume); + setProperty(name,value); + sprintf(name,"receiver.%d.rf_gain",rx->id); + sprintf(value,"%f",rx->rf_gain); + setProperty(name,value); + sprintf(name,"receiver.%d.agc",rx->id); + sprintf(value,"%d",rx->agc); + setProperty(name,value); + sprintf(name,"receiver.%d.agc_gain",rx->id); + sprintf(value,"%f",rx->agc_gain); + setProperty(name,value); + sprintf(name,"receiver.%d.agc_slope",rx->id); + sprintf(value,"%f",rx->agc_slope); + setProperty(name,value); + sprintf(name,"receiver.%d.agc_hang_threshold",rx->id); + sprintf(value,"%f",rx->agc_hang_threshold); + setProperty(name,value); - sprintf(name,"receiver.%d.zoom",rx->id); - sprintf(value,"%d",rx->zoom); - setProperty(name,value); - sprintf(name,"receiver.%d.pan",rx->id); - sprintf(value,"%d",rx->pan); - setProperty(name,value); + sprintf(name,"receiver.%d.dither",rx->id); + sprintf(value,"%d",rx->dither); + setProperty(name,value); + sprintf(name,"receiver.%d.random",rx->id); + sprintf(value,"%d",rx->random); + setProperty(name,value); + sprintf(name,"receiver.%d.preamp",rx->id); + sprintf(value,"%d",rx->preamp); + setProperty(name,value); + sprintf(name,"receiver.%d.nb",rx->id); + sprintf(value,"%d",rx->nb); + setProperty(name,value); + sprintf(name,"receiver.%d.nb2",rx->id); + sprintf(value,"%d",rx->nb2); + setProperty(name,value); + sprintf(name,"receiver.%d.nr",rx->id); + sprintf(value,"%d",rx->nr); + setProperty(name,value); + sprintf(name,"receiver.%d.nr2",rx->id); + sprintf(value,"%d",rx->nr2); + setProperty(name,value); + sprintf(name,"receiver.%d.anf",rx->id); + sprintf(value,"%d",rx->anf); + setProperty(name,value); + sprintf(name,"receiver.%d.snb",rx->id); + sprintf(value,"%d",rx->snb); + setProperty(name,value); + sprintf(name,"receiver.%d.nr_agc",rx->id); + sprintf(value,"%d",rx->nr_agc); + setProperty(name,value); + sprintf(name,"receiver.%d.nr2_gain_method",rx->id); + sprintf(value,"%d",rx->nr2_gain_method); + setProperty(name,value); + sprintf(name,"receiver.%d.nr2_npe_method",rx->id); + sprintf(value,"%d",rx->nr2_npe_method); + setProperty(name,value); + sprintf(name,"receiver.%d.nr2_ae",rx->id); + sprintf(value,"%d",rx->nr2_ae); + setProperty(name,value); + + sprintf(name,"receiver.%d.low_latency",rx->id); + sprintf(value,"%d",rx->low_latency); + setProperty(name,value); + + sprintf(name,"receiver.%d.deviation",rx->id); + sprintf(value,"%d",rx->deviation); + setProperty(name,value); + + sprintf(name,"receiver.%d.squelch_enable",rx->id); + sprintf(value,"%d",rx->squelch_enable); + setProperty(name,value); + sprintf(name,"receiver.%d.squelch",rx->id); + sprintf(value,"%f",rx->squelch); + setProperty(name,value); + + sprintf(name,"receiver.%d.zoom",rx->id); + sprintf(value,"%d",rx->zoom); + setProperty(name,value); + sprintf(name,"receiver.%d.pan",rx->id); + sprintf(value,"%d",rx->pan); + setProperty(name,value); +#ifdef CLIENT_SERVER + } +#endif } void receiver_restore_state(RECEIVER *rx) { @@ -324,137 +345,6 @@ void receiver_restore_state(RECEIVER *rx) { char *value; fprintf(stderr,"receiver_restore_state: id=%d\n",rx->id); - sprintf(name,"receiver.%d.alex_antenna",rx->id); - value=getProperty(name); - if(value) rx->alex_antenna=atoi(value); - -#ifdef PURESIGNAL - // - // for PS_RX_RECEIVER, *only* restore the ALEX antenna and setting - // and then return quickly - // - if (rx->id == PS_RX_FEEDBACK) return; -#endif - - sprintf(name,"receiver.%d.sample_rate",rx->id); - value=getProperty(name); - if(value) rx->sample_rate=atoi(value); - sprintf(name,"receiver.%d.adc",rx->id); - value=getProperty(name); - if(value) rx->adc=atoi(value); - // - // Do not specify a second ADC if there is only one - // - if (n_adc == 1) rx->adc=0; - sprintf(name,"receiver.%d.filter_low",rx->id); - value=getProperty(name); - if(value) rx->filter_low=atoi(value); - sprintf(name,"receiver.%d.filter_high",rx->id); - value=getProperty(name); - if(value) rx->filter_high=atoi(value); - sprintf(name,"receiver.%d.fps",rx->id); - value=getProperty(name); - if(value) rx->fps=atoi(value); -/* - sprintf(name,"receiver.%d.frequency",rx->id); - value=getProperty(name); - if(value) rx->frequency=atoll(value); - sprintf(name,"receiver.%d.display_frequency",rx->id); - value=getProperty(name); - if(value) rx->display_frequency=atoll(value); - sprintf(name,"receiver.%d.dds_frequency",rx->id); - value=getProperty(name); - if(value) rx->dds_frequency=atoll(value); - sprintf(name,"receiver.%d.dds_offset",rx->id); - value=getProperty(name); - if(value) rx->dds_offset=atoll(value); - sprintf(name,"receiver.%d.rit",rx->id); - value=getProperty(name); - if(value) rx->rit=atoi(value); -*/ - sprintf(name,"receiver.%d.panadapter_low",rx->id); - value=getProperty(name); - if(value) rx->panadapter_low=atoi(value); - sprintf(name,"receiver.%d.panadapter_high",rx->id); - value=getProperty(name); - if(value) rx->panadapter_high=atoi(value); - sprintf(name,"receiver.%d.panadapter_step",rx->id); - value=getProperty(name); - if(value) rx->panadapter_step=atoi(value); - sprintf(name,"receiver.%d.display_waterfall",rx->id); - value=getProperty(name); - if(value) rx->display_waterfall=atoi(value); - sprintf(name,"receiver.%d.waterfall_low",rx->id); - value=getProperty(name); - if(value) rx->waterfall_low=atoi(value); - sprintf(name,"receiver.%d.waterfall_high",rx->id); - value=getProperty(name); - if(value) rx->waterfall_high=atoi(value); - sprintf(name,"receiver.%d.waterfall_automatic",rx->id); - value=getProperty(name); - if(value) rx->waterfall_automatic=atoi(value); - - sprintf(name,"receiver.%d.alex_attenuation",rx->id); - value=getProperty(name); - if(value) rx->alex_attenuation=atoi(value); - sprintf(name,"receiver.%d.volume",rx->id); - value=getProperty(name); - if(value) rx->volume=atof(value); - sprintf(name,"receiver.%d.rf_gain",rx->id); - value=getProperty(name); - if(value) rx->rf_gain=atof(value); - sprintf(name,"receiver.%d.agc",rx->id); - value=getProperty(name); - if(value) rx->agc=atoi(value); - sprintf(name,"receiver.%d.agc_gain",rx->id); - value=getProperty(name); - if(value) rx->agc_gain=atof(value); - sprintf(name,"receiver.%d.agc_slope",rx->id); - value=getProperty(name); - if(value) rx->agc_slope=atof(value); - sprintf(name,"receiver.%d.agc_hang_threshold",rx->id); - value=getProperty(name); - if(value) rx->agc_hang_threshold=atof(value); - - sprintf(name,"receiver.%d.dither",rx->id); - value=getProperty(name); - if(value) rx->dither=atoi(value); - sprintf(name,"receiver.%d.random",rx->id); - value=getProperty(name); - if(value) rx->random=atoi(value); - sprintf(name,"receiver.%d.preamp",rx->id); - value=getProperty(name); - if(value) rx->preamp=atoi(value); - sprintf(name,"receiver.%d.nb",rx->id); - value=getProperty(name); - if(value) rx->nb=atoi(value); - sprintf(name,"receiver.%d.nb2",rx->id); - value=getProperty(name); - if(value) rx->nb2=atoi(value); - sprintf(name,"receiver.%d.nr",rx->id); - value=getProperty(name); - if(value) rx->nr=atoi(value); - sprintf(name,"receiver.%d.nr2",rx->id); - value=getProperty(name); - if(value) rx->nr2=atoi(value); - sprintf(name,"receiver.%d.anf",rx->id); - value=getProperty(name); - if(value) rx->anf=atoi(value); - sprintf(name,"receiver.%d.snb",rx->id); - value=getProperty(name); - if(value) rx->snb=atoi(value); - sprintf(name,"receiver.%d.nr_agc",rx->id); - value=getProperty(name); - if(value) rx->nr_agc=atoi(value); - sprintf(name,"receiver.%d.nr2_gain_method",rx->id); - value=getProperty(name); - if(value) rx->nr2_gain_method=atoi(value); - sprintf(name,"receiver.%d.nr2_npe_method",rx->id); - value=getProperty(name); - if(value) rx->nr2_npe_method=atoi(value); - sprintf(name,"receiver.%d.ae",rx->id); - value=getProperty(name); - if(value) rx->nr2_ae=atoi(value); sprintf(name,"receiver.%d.audio_channel",rx->id); value=getProperty(name); @@ -482,27 +372,166 @@ fprintf(stderr,"receiver_restore_state: id=%d\n",rx->id); sprintf(name,"receiver.%d.mute_radio",rx->id); value=getProperty(name); if(value) rx->mute_radio=atoi(value); - sprintf(name,"receiver.%d.low_latency",rx->id); - value=getProperty(name); - if(value) rx->low_latency=atoi(value); - sprintf(name,"receiver.%d.deviation",rx->id); - value=getProperty(name); - if(value) rx->deviation=atoi(value); +#ifdef CLIENT_SERVER + if(!radio_is_remote) { +#endif + sprintf(name,"receiver.%d.alex_antenna",rx->id); + value=getProperty(name); + if(value) rx->alex_antenna=atoi(value); - sprintf(name,"receiver.%d.squelch_enable",rx->id); +#ifdef PURESIGNAL + // + // for PS_RX_RECEIVER, *only* restore the ALEX antenna and setting + // and then return quickly + // + if (rx->id == PS_RX_FEEDBACK) return; +#endif + + sprintf(name,"receiver.%d.sample_rate",rx->id); + value=getProperty(name); + if(value) rx->sample_rate=atoi(value); + sprintf(name,"receiver.%d.adc",rx->id); + value=getProperty(name); + if(value) rx->adc=atoi(value); + // + // Do not specify a second ADC if there is only one + // + if (n_adc == 1) rx->adc=0; + sprintf(name,"receiver.%d.filter_low",rx->id); + value=getProperty(name); + if(value) rx->filter_low=atoi(value); + sprintf(name,"receiver.%d.filter_high",rx->id); + value=getProperty(name); + if(value) rx->filter_high=atoi(value); + sprintf(name,"receiver.%d.fps",rx->id); + value=getProperty(name); + if(value) rx->fps=atoi(value); +/* + sprintf(name,"receiver.%d.frequency",rx->id); value=getProperty(name); - if(value) rx->squelch_enable=atoi(value); - sprintf(name,"receiver.%d.squelch",rx->id); + if(value) rx->frequency=atoll(value); + sprintf(name,"receiver.%d.display_frequency",rx->id); value=getProperty(name); - if(value) rx->squelch=atof(value); - - sprintf(name,"receiver.%d.zoom",rx->id); + if(value) rx->display_frequency=atoll(value); + sprintf(name,"receiver.%d.dds_frequency",rx->id); value=getProperty(name); - if(value) rx->zoom=atoi(value); - sprintf(name,"receiver.%d.pan",rx->id); + if(value) rx->dds_frequency=atoll(value); + sprintf(name,"receiver.%d.dds_offset",rx->id); + value=getProperty(name); + if(value) rx->dds_offset=atoll(value); + sprintf(name,"receiver.%d.rit",rx->id); value=getProperty(name); - if(value) rx->pan=atoi(value); + if(value) rx->rit=atoi(value); +*/ + sprintf(name,"receiver.%d.panadapter_low",rx->id); + value=getProperty(name); + if(value) rx->panadapter_low=atoi(value); + sprintf(name,"receiver.%d.panadapter_high",rx->id); + value=getProperty(name); + if(value) rx->panadapter_high=atoi(value); + sprintf(name,"receiver.%d.panadapter_step",rx->id); + value=getProperty(name); + if(value) rx->panadapter_step=atoi(value); + sprintf(name,"receiver.%d.display_waterfall",rx->id); + value=getProperty(name); + if(value) rx->display_waterfall=atoi(value); + sprintf(name,"receiver.%d.waterfall_low",rx->id); + value=getProperty(name); + if(value) rx->waterfall_low=atoi(value); + sprintf(name,"receiver.%d.waterfall_high",rx->id); + value=getProperty(name); + if(value) rx->waterfall_high=atoi(value); + sprintf(name,"receiver.%d.waterfall_automatic",rx->id); + value=getProperty(name); + if(value) rx->waterfall_automatic=atoi(value); + + sprintf(name,"receiver.%d.alex_attenuation",rx->id); + value=getProperty(name); + if(value) rx->alex_attenuation=atoi(value); + sprintf(name,"receiver.%d.volume",rx->id); + value=getProperty(name); + if(value) rx->volume=atof(value); + sprintf(name,"receiver.%d.rf_gain",rx->id); + value=getProperty(name); + if(value) rx->rf_gain=atof(value); + sprintf(name,"receiver.%d.agc",rx->id); + value=getProperty(name); + if(value) rx->agc=atoi(value); + sprintf(name,"receiver.%d.agc_gain",rx->id); + value=getProperty(name); + if(value) rx->agc_gain=atof(value); + sprintf(name,"receiver.%d.agc_slope",rx->id); + value=getProperty(name); + if(value) rx->agc_slope=atof(value); + sprintf(name,"receiver.%d.agc_hang_threshold",rx->id); + value=getProperty(name); + if(value) rx->agc_hang_threshold=atof(value); + + sprintf(name,"receiver.%d.dither",rx->id); + value=getProperty(name); + if(value) rx->dither=atoi(value); + sprintf(name,"receiver.%d.random",rx->id); + value=getProperty(name); + if(value) rx->random=atoi(value); + sprintf(name,"receiver.%d.preamp",rx->id); + value=getProperty(name); + if(value) rx->preamp=atoi(value); + sprintf(name,"receiver.%d.nb",rx->id); + value=getProperty(name); + if(value) rx->nb=atoi(value); + sprintf(name,"receiver.%d.nb2",rx->id); + value=getProperty(name); + if(value) rx->nb2=atoi(value); + sprintf(name,"receiver.%d.nr",rx->id); + value=getProperty(name); + if(value) rx->nr=atoi(value); + sprintf(name,"receiver.%d.nr2",rx->id); + value=getProperty(name); + if(value) rx->nr2=atoi(value); + sprintf(name,"receiver.%d.anf",rx->id); + value=getProperty(name); + if(value) rx->anf=atoi(value); + sprintf(name,"receiver.%d.snb",rx->id); + value=getProperty(name); + if(value) rx->snb=atoi(value); + sprintf(name,"receiver.%d.nr_agc",rx->id); + value=getProperty(name); + if(value) rx->nr_agc=atoi(value); + sprintf(name,"receiver.%d.nr2_gain_method",rx->id); + value=getProperty(name); + if(value) rx->nr2_gain_method=atoi(value); + sprintf(name,"receiver.%d.nr2_npe_method",rx->id); + value=getProperty(name); + if(value) rx->nr2_npe_method=atoi(value); + sprintf(name,"receiver.%d.ae",rx->id); + value=getProperty(name); + if(value) rx->nr2_ae=atoi(value); + + sprintf(name,"receiver.%d.low_latency",rx->id); + value=getProperty(name); + if(value) rx->low_latency=atoi(value); + + sprintf(name,"receiver.%d.deviation",rx->id); + value=getProperty(name); + if(value) rx->deviation=atoi(value); + + sprintf(name,"receiver.%d.squelch_enable",rx->id); + value=getProperty(name); + if(value) rx->squelch_enable=atoi(value); + sprintf(name,"receiver.%d.squelch",rx->id); + value=getProperty(name); + if(value) rx->squelch=atof(value); + + sprintf(name,"receiver.%d.zoom",rx->id); + value=getProperty(name); + if(value) rx->zoom=atoi(value); + sprintf(name,"receiver.%d.pan",rx->id); + value=getProperty(name); + if(value) rx->pan=atoi(value); +#ifdef CLIENT_SERVER + } +#endif } void reconfigure_receiver(RECEIVER *rx,int height) { @@ -512,6 +541,8 @@ void reconfigure_receiver(RECEIVER *rx,int height) { // which is the full or half of the height depending on whether BOTH // are displayed // + + g_mutex_lock(&rx->display_mutex); int myheight=(rx->display_panadapter && rx->display_waterfall) ? height/2 : height; rx->height=height; // total height @@ -558,13 +589,14 @@ fprintf(stderr,"reconfigure_receiver: waterfall set_size_request: width:%d heigh } gtk_widget_show_all(rx->panel); + g_mutex_unlock(&rx->display_mutex); } static gint update_display(gpointer data) { RECEIVER *rx=(RECEIVER *)data; int rc; -//fprintf(stderr,"update_display: %d displaying=%d\n",rx->id,rx->displaying); +//g_print("update_display: rx=%d displaying=%d\n",rx->id,rx->displaying); if(rx->displaying) { if(rx->pixels>0) { @@ -580,8 +612,8 @@ static gint update_display(gpointer data) { } g_mutex_unlock(&rx->display_mutex); if(active_receiver==rx) { - double m=GetRXAMeter(rx->id,smeter)+meter_calibration; - meter_update(rx,SMETER,m,0.0,0.0,0.0); + rx->meter=GetRXAMeter(rx->id,smeter)+meter_calibration; + meter_update(rx,SMETER,rx->meter,0.0,0.0,0.0); } return TRUE; } @@ -589,14 +621,38 @@ static gint update_display(gpointer data) { return FALSE; } +void receiver_remote_update_display(RECEIVER *rx) { + if(rx->displaying) { + if(rx->pixels>0) { + g_mutex_lock(&rx->display_mutex); + if(rx->display_panadapter) { + rx_panadapter_update(rx); + } + if(rx->display_waterfall) { + waterfall_update(rx); + } + if(active_receiver==rx) { + meter_update(rx,SMETER,rx->meter,0.0,0.0,0.0); + } + g_mutex_unlock(&rx->display_mutex); + } + } +} + void set_displaying(RECEIVER *rx,int state) { rx->displaying=state; - if(state) { - if(rx->update_timer_id>=0) g_source_remove(rx->update_timer_id); - rx->update_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,1000/rx->fps, update_display, rx, NULL); - } else { - rx->update_timer_id=-1; +#ifdef CLIENT_SERVER + if(!radio_is_remote) { +#endif + if(state) { + if(rx->update_timer_id>=0) g_source_remove(rx->update_timer_id); + rx->update_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,1000/rx->fps, update_display, rx, NULL); + } else { + rx->update_timer_id=-1; + } +#ifdef CLIENT_SERVER } +#endif } void set_mode(RECEIVER *rx,int m) { @@ -1271,22 +1327,29 @@ static void process_rx_buffer(RECEIVER *rx) { if(rx->local_audio) { if((rx!=active_receiver && rx->mute_when_not_active) || rx->mute_radio) { - audio_write(rx,0.0F,0.0F); + left_sample=0.0; + right_sample=0.0; } else { switch(rx->audio_channel) { case STEREO: - audio_write(rx,(float)left_sample,(float)right_sample); break; case LEFT: - audio_write(rx,(float)left_sample,0.0F); + right_sample=0.0; break; case RIGHT: - audio_write(rx,0.0F,(float)right_sample); + left_sample=0.0; break; } } + audio_write(rx,(float)left_sample,(float)right_sample); } +#ifdef CLIENT_SERVER + if(clients!=NULL) { + remote_audio(rx,left_audio_sample,right_audio_sample); + } +#endif + if(rx==active_receiver) { switch(protocol) { case ORIGINAL_PROTOCOL: @@ -1390,13 +1453,10 @@ void add_div_iq_samples(RECEIVER *rx, double i0, double q0, double i1, double q1 } void receiver_change_zoom(RECEIVER *rx,double zoom) { - if(rx->pixel_samples!=NULL) { - g_free(rx->pixel_samples); - } - rx->pixels=rx->width*(int)zoom; - rx->pixel_samples=g_new(float,rx->pixels); - rx->hz_per_pixel=(double)rx->sample_rate/(double)rx->pixels; +g_print("receiver_change_zoom: %d %f\n",rx->id,zoom); rx->zoom=(int)zoom; + rx->pixels=rx->width*rx->zoom; + rx->hz_per_pixel=(double)rx->sample_rate/(double)rx->pixels; if(zoom==1) { rx->pan=0; } else { @@ -1409,8 +1469,18 @@ void receiver_change_zoom(RECEIVER *rx,double zoom) { rx->pan=(rx->pixels/2)-(rx->width/2); } } - rx->zoom=(int)zoom; - init_analyzer(rx); +#ifdef CLIENT_SERVER + if(!radio_is_remote) { +#endif + if(rx->pixel_samples!=NULL) { + g_free(rx->pixel_samples); + } + rx->pixel_samples=g_new(float,rx->pixels); + init_analyzer(rx); +#ifdef CLIENT_SERVER + } +#endif +g_print("receiver_change_zoom: pixels=%d zoom=%d pan=%d\n",rx->pixels,rx->zoom,rx->pan); } void receiver_change_pan(RECEIVER *rx,double pan) { @@ -1419,3 +1489,9 @@ void receiver_change_pan(RECEIVER *rx,double pan) { } } +#ifdef CLIENT_SERVER +void receiver_create_remote(RECEIVER *rx) { + // receiver structure allready setup + create_visual(rx); +} +#endif diff --git a/receiver.h b/receiver.h index 2913815..41a7cb0 100644 --- a/receiver.h +++ b/receiver.h @@ -49,6 +49,8 @@ typedef struct _receiver { gdouble agc_gain; gdouble agc_slope; gdouble agc_hang_threshold; + gdouble agc_hang; + gdouble agc_thresh; gint fps; gint displaying; audio_t audio_channel; @@ -68,6 +70,7 @@ typedef struct _receiver { gint display_panadapter; gint display_waterfall; gint update_timer_id; + gdouble meter; gdouble hz_per_pixel; @@ -182,4 +185,13 @@ extern gboolean receiver_scroll_event(GtkWidget *widget, GdkEventScroll *event, extern void set_displaying(RECEIVER *rx,int state); +extern void receiver_restore_state(RECEIVER *rx); + +extern void receiver_set_active(RECEIVER *rx); + +#ifdef CLIENT_SERVER +extern void receiver_create_remote(RECEIVER *rx); +extern void receiver_remote_update_display(RECEIVER *rx); +#endif + #endif diff --git a/rigctl.c b/rigctl.c index ba0c1b4..2a6f087 100644 --- a/rigctl.c +++ b/rigctl.c @@ -1,4 +1,3 @@ - /* TS-2000 emulation via TCP * Copyright (C) 2016 Steve Wilson * This program is free software; you can redistribute it and/or @@ -52,18 +51,19 @@ #include "store.h" #include "ext.h" #include "rigctl_menu.h" +#include "noise_menu.h" #include "new_protocol.h" #ifdef LOCALCW #include "iambic.h" // declare keyer_update() #endif #include +#define NEW_PARSER + // IP stuff below #include #include //inet_addr -//#define RIGCTL_DEBUG - int rigctl_port_base=19090; int rigctl_enable=0; @@ -79,7 +79,7 @@ static const int TelnetPortC = 19092; // max number of bytes we can get at once #define MAXDATASIZE 2000 -void parse_cmd (); +int parse_cmd (void *data); int connect_cnt = 0; int rigctlGetFilterLow(); @@ -91,8 +91,6 @@ int rigctl_busy = 0; // Used to tell rigctl_menu that launch has already occure int cat_control; extern int enable_tx_equalizer; -//extern int serial_baud_rate; -//extern int serial_parity; typedef struct {GMutex m; } GT_MUTEX; GT_MUTEX * mutex_a; @@ -113,6 +111,7 @@ static GThread *rigctl_cw_thread_id = NULL; static int server_running; static GThread *serial_server_thread_id = NULL; +static gboolean serial_running=FALSE; static int server_socket=-1; static int server_address_length; @@ -121,13 +120,17 @@ static struct sockaddr_in server_address; static int rigctl_timer = 0; typedef struct _client { - int socket; - // Dl1YCF change from int to socklen_t + int fd; socklen_t address_length; struct sockaddr_in address; GThread *thread_id; } CLIENT; +typedef struct _command { + CLIENT *client; + char *command; +} COMMAND; + int fd; // Serial port file descriptor static CLIENT client[MAX_CLIENTS]; @@ -166,26 +169,26 @@ void close_rigctl_ports() { linger.l_onoff = 1; linger.l_linger = 0; - fprintf(stderr,"close_rigctl_ports: server_socket=%d\n",server_socket); + g_print("close_rigctl_ports: server_socket=%d\n",server_socket); server_running=0; for(i=0;i=0) { - fprintf(stderr,"setting SO_LINGER to 0 for server_socket: %d\n",server_socket); + g_print("setting SO_LINGER to 0 for server_socket: %d\n",server_socket); if(setsockopt(server_socket,SOL_SOCKET,SO_LINGER,(const char *)&linger,sizeof(linger))==-1) { perror("setsockopt(...,SO_LINGER,...) failed for server"); } - fprintf(stderr,"closing server_socket: %d\n",server_socket); + g_print("closing server_socket: %d\n",server_socket); close(server_socket); server_socket=-1; } @@ -613,24 +616,24 @@ static gpointer rigctl_cw_thread(gpointer data) // This looks up the frequency of the Active receiver with // protection for 1 versus 2 receivers long long rigctl_getFrequency() { - if(receivers == 1) { - return vfo[VFO_A].frequency; - } else { - return vfo[active_receiver->id].frequency; - } + if(receivers == 1) { + return vfo[VFO_A].frequency; + } else { + return vfo[active_receiver->id].frequency; + } } // Looks up entry INDEX_NUM in the command structure and // returns the command string // -void send_resp (int client_sock,char * msg) { - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: RESP=%s\n",msg); - #endif - if(client_sock == -1) { // Serial port - write(fd,msg,strlen(msg)); - } else { // TCP/IP port - write(client_sock, msg, strlen(msg)); - } +void send_resp (int fd,char * msg) { + if(rigctl_debug) g_print("RIGCTL: RESP=%s\n",msg); + int length=strlen(msg); + int written=0; + + while(writtensocket); + g_print("rigctl_client: starting rigctl_client: socket=%d\n",client->fd); - g_mutex_lock(&mutex_a->m); - cat_control++; -//#ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: CTLA INC cat_contro=%d\n",cat_control); -//#endif - g_mutex_unlock(&mutex_a->m); - g_idle_add(ext_vfo_update,NULL); + g_mutex_lock(&mutex_a->m); + cat_control++; + if(rigctl_debug) g_print("RIGCTL: CTLA INC cat_contro=%d\n",cat_control); + g_mutex_unlock(&mutex_a->m); + g_idle_add(ext_vfo_update,NULL); - int save_flag = 0; // Used to concatenate two cmd lines together - int semi_number = 0; - int i; - char * work_ptr; - char work_buf[MAXDATASIZE]; - int numbytes; - char cmd_input[MAXDATASIZE] ; - char cmd_save[80]; - - while(server_running && (numbytes=recv(client->socket , cmd_input , MAXDATASIZE-2 , 0)) > 0 ) { - for(i=0;im); - parse_cmd(work_ptr,strlen(work_ptr),client->socket); - g_mutex_unlock(&mutex_b->m); - work_ptr = strtok(NULL,";"); - } - for(i=0;isocket!=-1) { - fprintf(stderr,"setting SO_LINGER to 0 for client_socket: %d\n",client->socket); + int save_flag = 0; // Used to concatenate two cmd lines together + int semi_number = 0; + int i; + char * work_ptr; + char work_buf[MAXDATASIZE]; + int numbytes; + char cmd_input[MAXDATASIZE] ; + char cmd_save[80]; + + char *command=g_new(char,MAXDATASIZE); + int command_index=0; + + while(server_running && (numbytes=recv(client->fd , cmd_input , MAXDATASIZE-2 , 0)) > 0 ) { + for(i=0;iclient=client; + info->command=command; + g_idle_add(parse_cmd,info); + command=g_new(char,MAXDATASIZE); + command_index=0; + } + } + } +g_print("RIGCTL: Leaving rigctl_client thread"); + if(client->fd!=-1) { + g_print("setting SO_LINGER to 0 for client_socket: %d\n",client->fd); struct linger linger = { 0 }; linger.l_onoff = 1; linger.l_linger = 0; - if(setsockopt(client->socket,SOL_SOCKET,SO_LINGER,(const char *)&linger,sizeof(linger))==-1) { + if(setsockopt(client->fd,SOL_SOCKET,SO_LINGER,(const char *)&linger,sizeof(linger))==-1) { perror("setsockopt(...,SO_LINGER,...) failed for client"); } - close(client->socket); - client->socket=-1; + close(client->fd); + client->fd=-1; // Decrement CAT_CONTROL g_mutex_lock(&mutex_a->m); cat_control--; -#ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: CTLA DEC - cat_control=%d\n",cat_control); -#endif + if(rigctl_debug) g_print("RIGCTL: CTLA DEC - cat_control=%d\n",cat_control); g_mutex_unlock(&mutex_a->m); g_idle_add(ext_vfo_update,NULL); } @@ -828,2930 +800,2256 @@ int rit_on () { } } } -// -// TS-2000 parser -// -- Now extended with zzid_flag to indicate PSDR extended command set -// -void parse_cmd ( char * cmd_input,int len,int client_sock) { - int work_int; - int zzid_flag; - double forward; - double reverse; - double vswr; - char msg[200]; - char buf[200]; - BANDSTACK_ENTRY *entry; - // Parse the cmd_input - //int space = command.indexOf(' '); - //char cmd_char = com_head->cmd_string[0]; // Assume the command is first thing! - char cmd_str[3]; - struct timespec nap; - static struct timespec throttle={0,0}; - - - // Put in a throttle here - we have an issue with issuing to many - // GUI commands. - - if ((throttle.tv_sec !=0) || (throttle.tv_nsec != 0)) { - clock_gettime(CLOCK_MONOTONIC, &nap); - // calculate amount of time we should go for a nap. - nap.tv_sec =throttle.tv_sec - nap.tv_sec; - nap.tv_nsec=throttle.tv_nsec - nap.tv_nsec + RIGCTL_THROTTLE_NSEC; - while (nap.tv_nsec < 0) { - nap.tv_nsec += NSEC_PER_SEC; - nap.tv_sec--; - } - nanosleep(&nap, NULL); - } - // set new time stamp - clock_gettime(CLOCK_MONOTONIC, &throttle); - - // On with the rest of the show.. - cmd_str[0] = cmd_input[0]; - cmd_str[1] = cmd_input[1]; - cmd_str[2] = '\0'; - - // Added support for PSDR extended command set - they all start - // with ZZ so: - // - // Check to see if first part of string is ZZ - if so - // strip the ZZ out and set the zzid_flag = 1; - - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: CMD=%s\n",cmd_input); - #endif - zzid_flag = 0; // Set to indicate we haven't seen ZZ - char * zzid_ptr; - char temp[80]; - int cnt; - if(strcmp(cmd_str,"ZZ")==0) { - - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: Init=%s\n",cmd_str); - #endif - - // Adjust the Parse input like there hadn't been a ZZ in front - but - // set the ZZ flag to indicate we saw it. - zzid_ptr = &temp[0]; - - // It is 4AM and this was the only safe way for me to get a strcpy to work - // so - there ya go... - for(cnt=2; cnt<=len;cnt++) { - //fprintf(stderr,"[%d]=%c:",cnt,cmd_input[cnt]); - *zzid_ptr++= cmd_input[cnt]; - } - temp[len+1] = '\0'; - - strcpy(cmd_input,temp); - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: Cmd_input=%s\n",cmd_input); - #endif - // - cmd_str[0] = cmd_input[0]; - cmd_str[1] = cmd_input[1]; - cmd_str[2] = '\0'; - zzid_flag = 1; - len = strlen (temp); - } - - if(strcmp(cmd_str,"AC")==0) { - // TS-2000 - AC - STEP Command - // PiHPSDR - ZZAC - Step Command - if(zzid_flag ==1) { // Set or Read the Step Size (replaces ZZST) - if(len <= 2) { - switch(step) { - case 1: work_int = 0; break; - case 10: work_int = 1; break; - case 25: work_int = 2; break; - case 50: work_int = 3; break; - case 100: work_int = 4; break; - case 250: work_int = 5; break; - case 500: work_int = 6; break; - case 1000: work_int = 7; break; - case 2500: work_int = 8; break; - case 5000: work_int = 9; break; - case 6250: work_int = 10; break; - case 9000: work_int = 11; break; - case 10000: work_int = 12; break; - case 12500: work_int = 13; break; - case 15000: work_int = 14; break; - case 20000: work_int = 15; break; - case 25000: work_int = 16; break; - case 30000: work_int = 17; break; - case 50000: work_int = 18; break; - case 100000: work_int = 19; break; - default: - work_int = 0; - fprintf(stderr,"RIGCTL: ERROR step out of range\n"); - send_resp(client_sock,"?;"); - break; - } - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RESP: ZZAC%02d;",work_int); - #endif - sprintf(msg,"ZZAC%02d;",work_int); - send_resp(client_sock,msg); - - } else { // Legal vals between 00 and 22. - switch(atoi(&cmd_input[2])) { - case 0: step = 1; break; - case 1: step = 10; break; - case 2: step = 25; break; - case 3: step = 50; break; - case 4: step = 100; break; - case 5: step = 250; break; - case 6: step = 500; break; - case 7: step = 1000; break; - case 8: step = 2500; break; - case 9: step = 5000; break; - case 10: step = 6250; break; - case 11: step = 9000; break; - case 12: step = 10000; break; - case 13: step = 12500; break; - case 14: step = 15000; break; - case 15: step = 20000; break; - case 16: step = 25000; break; - case 17: step = 30000; break; - case 18: step = 50000; break; - case 19: step = 100000; break; - default: - fprintf(stderr,"RIGCTL: ERROR - ZZAC out of range\n"); - send_resp(client_sock,"?;"); - } - g_idle_add(ext_vfo_update,NULL); - } - } else { // Sets or reads the internal antenna tuner status - // P1 0:RX-AT Thru, 1: RX-AT IN - // P2 0: TX-AT Thru 1: TX-AT In - // - if(len <= 2) { - send_resp(client_sock,"AC000;"); - } - } - } - else if((strcmp(cmd_str,"AD")==0) && (zzid_flag==1)) { - // PiHPSDR - ZZAD - Move VFO A Down by step - //vfo_step(-1); - int lcl_step = -1; - g_idle_add(ext_vfo_step,(gpointer)(long)lcl_step); - g_idle_add(ext_vfo_update,NULL); - } - else if(strcmp(cmd_str,"AG")==0) { - if(zzid_flag == 1) { - // PiHPSDR - ZZAG - Set/read Audio Gain - // Values are 000-100 - if(len<=2) { // Send ZZAGxxx; - active_receiver->volume 0.00-1.00 - sprintf(msg,"ZZAG%03d;",(int) (roundf(active_receiver->volume *100.0))); - send_resp(client_sock,msg); - } else { // Set Audio Gain - work_int = atoi(&cmd_input[2]); - active_receiver->volume = ((double) work_int)/100.0; - g_idle_add(ext_update_af_gain,NULL); - } - } else { - // TS-2000 - AG - Set Audio Gain - // AG123; Value of 0- - // AG1 = Sub receiver - what is the value set - // Response - AG<0/1>123; Where 123 is 0-260 - int lcl_receiver; - if(receivers == 1) { - lcl_receiver = 0; - } else { - lcl_receiver = active_receiver->id; - } - if(len>4) { // Set Audio Gain - if((atoi(&cmd_input[3]) >=0) && (atoi(&cmd_input[3])<=260)) { - active_receiver->volume = ((double) atoi(&cmd_input[3]))/260; - g_idle_add(ext_update_af_gain,NULL); - } else { - send_resp(client_sock,"?;"); - } - } else { // Read Audio Gain - sprintf(msg,"AG%1d%03d;",lcl_receiver,(int) (260 * active_receiver->volume)); - send_resp(client_sock,msg); - } - } - } - else if((strcmp(cmd_str,"AI")==0) && (zzid_flag == 0)) { - // TS-2000 - AI- Allow rebroadcast of set frequency after set - not supported - if(len <=2) { - //send_resp(client_sock,"AI0;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"AL")==0) && (zzid_flag == 0)) { - // TS-2000 - AL - Set/Reads the auto Notch level - not supported - if(len <=2) { - //send_resp(client_sock,"AL000;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"AM")==0) && (zzid_flag == 0)) { - // TS-2000 - AM - Sets or reads the Auto Mode - not supported - if(len <=2) { - //send_resp(client_sock,"AM0;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"AN")==0) && (zzid_flag == 0)) { - // TS-2000 - AN - Selects the antenna connector (ANT1/2) - not supported - if(len <=2) { - //send_resp(client_sock,"AN0;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"AP")==0) && (zzid_flag == 1)) { - // PiHPSDR - ZZAP - Set/Read Power Amp Settings. - // format - P1P1P1 P2P2.P2 - // P1 - Band P2 - 3.1 float WITH decimal point required! - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: ZZAP len=%d\n",len); - #endif - if(len<=5) { // Read Command - work_int = lookup_band(atoi(&cmd_input[2])); - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL ZZAP work_int=%d\n",work_int); - #endif - BAND *band = band_get_band(work_int); - sprintf(msg,"ZZAP%03d%3.1f;",atoi(&cmd_input[2]),band->pa_calibration); - send_resp(client_sock,msg); - } else { - /* isolate the command band from the value */ - char lcl_char = cmd_input[5];; - cmd_input[5]='\0'; // Make a temp string - work_int = atoi(&cmd_input[2]); - cmd_input[5] = lcl_char; // Restore the orig string.. - double lcl_float = atof(&cmd_input[5]); - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL ZZAP - band=%d setting=%3.1f\n",work_int, lcl_float); - #endif - work_int = lookup_band(work_int); - - // Sequence below lifted from pa_menu - BAND *band = band_get_band(work_int); - band->pa_calibration = lcl_float; - work_int = VFO_A; - if(split) work_int = VFO_B; - int b = vfo[work_int].band; - BAND *current = band_get_band(b); - if(band == current) { - g_idle_add( ext_calc_drive_level,(gpointer) NULL); - //g_idle_add( ext_calc_tune_drive_level,(gpointer) NULL); - } - } - } - else if(strcmp(cmd_str,"AR")==0) { - if(zzid_flag ==1) { - // PiHPSDR - ZZAR - Set or reads the RX1 AGC Threshold Control - if(len <=2) { // Read Response - // X is +/- sign - if(active_receiver->agc_gain >=0) { - sprintf(msg,"ZZAR+%03d;",(int)active_receiver->agc_gain); - } else { - sprintf(msg,"ZZAR-%03d;",abs((int)active_receiver->agc_gain)); - } - send_resp(client_sock,msg); - } else { - double new_gain = (double) atoi(&cmd_input[2]); - double *p_gain=malloc(sizeof(double)); - *p_gain=new_gain; - g_idle_add(ext_update_agc_gain,(gpointer)p_gain); - } - } else { - // TS-2000 - AR - Sets or reads the ASC function on/off - not supported - if(len <=2) { - //send_resp(client_sock,"AR0;"); - send_resp(client_sock,"?;"); - } - } - } - else if((strcmp(cmd_str,"AS")==0) && (zzid_flag == 0)) { - // TS-2000 - AS - Sets/reads automode function parameters - // AS<2xP2><11P3>; - // AS<2xP2><11P3>; - if(len < 6) { - /* sprintf(msg,"AS%1d%02d%011lld%01d;", - 0, // P1 - 0, // Automode - getFrequency(), - rigctlGetMode()); - send_resp(client_sock,msg);*/ - send_resp(client_sock,"?;"); - - } - } - else if((strcmp(cmd_str,"AT")==0) && (zzid_flag==1)) { - // PiHPSDR - ZZAT - Move VFO A Up by step - //vfo_step(1); - int lcl_step = 1; - g_idle_add(ext_vfo_step,(gpointer)(long) lcl_step); - g_idle_add(ext_vfo_update,NULL); - } - // PiHPSDR - ZZAU - Reserved for Audio UDP stream start/stop - else if((strcmp(cmd_str,"BC")==0) && (zzid_flag == 0)) { - // TS-2000 - BC - Beat Cancellor OFF - not supported - if(len <=2) { - //send_resp(client_sock,"BC0;"); - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"BD")==0) { - // PiHPSDR - ZZBD - Moves down the frequency band selector - // TS-2000 - BD - Moves down the frequency band selector - // No response - // This reacts to both BD and ZZBD - only works for active receiver - int cur_band = vfo[active_receiver->id].band; - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: BD - current band=%d\n",cur_band); - #endif - if(cur_band == 0) { - #ifdef SOAPYSDR - cur_band = band472; - #else - cur_band = band6; - #endif - } else { - --cur_band; - } - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: BD - new band=%d\n",cur_band); - #endif - g_idle_add(ext_vfo_band_changed,(gpointer)(long)cur_band); - } - else if((strcmp(cmd_str,"BP")==0) && (zzid_flag == 0)) { - // TS-2000 - BP - Reads the manual beat canceller freq - not supported - if(len <=2) { - //send_resp(client_sock,"BP000;"); - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"BS")==0) { - if(zzid_flag == 1) { - // PiHPSDR - ZZBS - Read the RX1 Band switch - int cur_band = vfo[active_receiver->id].band; - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: BS - band=%d\n",cur_band); - #endif - - switch(cur_band) { - case 0: work_int = 160; break; - case 1: work_int = 80; break; - case 2: work_int = 60; break; - case 3: work_int = 40; break; - case 4: work_int = 30; break; - case 5: work_int = 20; break; - case 6: work_int = 17; break; - case 7: work_int = 15; break; - case 8: work_int = 12; break; - case 9: work_int = 10; break; - case 10: work_int = 6; break; - case 11: work_int = 888; break; - case 12: work_int = 999; break; - case 13: work_int = 136; break; - case 14: work_int = 472; break; - } - sprintf(msg,"ZZBS%03d;",work_int); - send_resp(client_sock,msg); - - } else { - // Sets or reads Beat Canceller status - if(len <=2) { - //send_resp(client_sock,"BS0;"); - send_resp(client_sock,"?;"); - } - } - } - else if(strcmp(cmd_str,"BU")==0) { - // PiHPSDR - ZZBU - Moves Up the frequency band - // TS-2000 - BU - Moves Up the frequency band - // No response - int cur_band = vfo[active_receiver->id].band; - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: BU - Max Band = %d current band=%d\n",BANDS,cur_band); - #endif - if(cur_band >= 10) { - cur_band = band160; - } else { - ++cur_band; - } - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: BU - new band=%d\n",cur_band); - #endif - g_idle_add(ext_vfo_band_changed,(gpointer)(long)cur_band); - } - else if((strcmp(cmd_str,"BY")==0) && (zzid_flag == 0)) { - // TS-2000 - BY - Read the busy signal status - if(len <=2) { - //send_resp(client_sock,"BY00;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"CA")==0) && (zzid_flag == 0)) { - // TS-2000 - CA - Sets/reads cw auto tune f(x) status - not supported - if(len <=2) { - //send_resp(client_sock,"CA0;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"CB")==0) && (zzid_flag==1)) { - // PIHPSDR - ZZCB - Sets/reads CW Break In checkbox status - // P1 = 0 for disabled, 1 for enabled - if(len <= 2) { - sprintf(msg,"ZZCB%01d;",cw_breakin); - send_resp(client_sock,msg); - } else { - cw_breakin = atoi(&cmd_input[2]); - } - } - else if((strcmp(cmd_str,"CG")==0) && (zzid_flag == 0)) { - // TS-2000 - CD - Sets/Reads the carrier gain status - not supported - // 0-100 legal values - if(len <=2) { - //send_resp(client_sock,"CG000;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"CH")==0) && (zzid_flag == 0)) { - // TS-2000 - CH - Sets the current frequency to call Channel -no response - } - else if((strcmp(cmd_str,"CI")==0) && (zzid_flag == 0)) { - // TS-2000 - CI - In VFO md or Mem recall md, sets freq 2 call channel - no response - } - else if((strcmp(cmd_str,"CL")==0) && (zzid_flag == 1)) { - // PiHPSDR - ZZCL - CW Pitch set - // 0200 - 1200 - if(len <=2) { - sprintf(msg,"ZZCL%04d;",cw_keyer_sidetone_frequency); - send_resp(client_sock,msg); - } else { - int local_freq = atoi(&cmd_input[2]); - if((local_freq >= 200) && (local_freq <=1200)) { - cw_keyer_sidetone_frequency = atoi(&cmd_input[2]); - g_idle_add(ext_vfo_update,NULL); - } else { - fprintf(stderr,"RIGCTL: ZZCL illegal freq=%d\n",local_freq); - } - } - } - else if((strcmp(cmd_str,"CM")==0) && (zzid_flag == 0)) { - // TS-2000 - CM - Sets or reads the packet cluster tune f(x) on/off -not supported - // 0-100 legal values - if(len <=2) { - //send_resp(client_sock,"CM0;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"CN")==0) && (zzid_flag == 0)) { - // TS-2000 - CN - Sets and reads CTSS function - 01-38 legal values - // Stored locally in rigctl - not used. - if(len >2) { - ctcss_tone = atoi(&cmd_input[2]); - if((ctcss_tone > 0) && (ctcss_tone <= 39)) { - switch(ctcss_tone) { - case 1: transmitter->ctcss_frequency = (double) 67.0;break; - case 2: transmitter->ctcss_frequency = (double) 71.9;break; - case 3: transmitter->ctcss_frequency = (double) 74.4;break; - case 4: transmitter->ctcss_frequency = (double) 77.0;break; - case 5: transmitter->ctcss_frequency = (double) 79.7;break; - case 6: transmitter->ctcss_frequency = (double) 82.5;break; - case 7: transmitter->ctcss_frequency = (double) 85.4;break; - case 8: transmitter->ctcss_frequency = (double) 88.5;break; - case 9: transmitter->ctcss_frequency = (double) 91.5;break; - case 10: transmitter->ctcss_frequency = (double) 94.8;break; - case 11: transmitter->ctcss_frequency = (double) 97.4;break; - case 12: transmitter->ctcss_frequency = (double) 100.0;break; - case 13: transmitter->ctcss_frequency = (double) 103.5;break; - case 14: transmitter->ctcss_frequency = (double) 107.2;break; - case 15: transmitter->ctcss_frequency = (double) 110.9;break; - case 16: transmitter->ctcss_frequency = (double) 114.8;break; - case 17: transmitter->ctcss_frequency = (double) 118.8;break; - case 18: transmitter->ctcss_frequency = (double) 123.0;break; - case 19: transmitter->ctcss_frequency = (double) 127.3;break; - case 20: transmitter->ctcss_frequency = (double) 131.8;break; - case 21: transmitter->ctcss_frequency = (double) 136.5;break; - case 22: transmitter->ctcss_frequency = (double) 141.3;break; - case 23: transmitter->ctcss_frequency = (double) 146.2;break; - case 24: transmitter->ctcss_frequency = (double) 151.4;break; - case 25: transmitter->ctcss_frequency = (double) 156.7;break; - case 26: transmitter->ctcss_frequency = (double) 162.2;break; - case 27: transmitter->ctcss_frequency = (double) 167.9;break; - case 28: transmitter->ctcss_frequency = (double) 173.8;break; - case 29: transmitter->ctcss_frequency = (double) 179.9;break; - case 30: transmitter->ctcss_frequency = (double) 186.2;break; - case 31: transmitter->ctcss_frequency = (double) 192.8;break; - case 32: transmitter->ctcss_frequency = (double) 203.5;break; - case 33: transmitter->ctcss_frequency = (double) 210.7;break; - case 34: transmitter->ctcss_frequency = (double) 218.1;break; - case 35: transmitter->ctcss_frequency = (double) 225.7;break; - case 36: transmitter->ctcss_frequency = (double) 233.6;break; - case 37: transmitter->ctcss_frequency = (double) 241.8;break; - case 38: transmitter->ctcss_frequency = (double) 250.3;break; - case 39: transmitter->ctcss_frequency = (double) 1750.0;break; - } - transmitter_set_ctcss(transmitter,transmitter->ctcss,transmitter->ctcss_frequency); - } - } else { - ctcss_tone = -1; - if(transmitter->ctcss_frequency == (double) 67.0) { - ctcss_tone = 1; - } else if (transmitter->ctcss_frequency == (double) 71.9) { - ctcss_tone = 2; - } else if (transmitter->ctcss_frequency == (double) 74.4) { - ctcss_tone = 3; - } else if (transmitter->ctcss_frequency == (double) 77.0) { - ctcss_tone = 4; - } else if (transmitter->ctcss_frequency == (double) 79.7) { - ctcss_tone = 5; - } else if (transmitter->ctcss_frequency == (double) 82.5) { - ctcss_tone = 6; - } else if (transmitter->ctcss_frequency == (double) 85.4) { - ctcss_tone = 7; - } else if (transmitter->ctcss_frequency == (double) 88.5) { - ctcss_tone = 8; - } else if (transmitter->ctcss_frequency == (double) 91.5) { - ctcss_tone = 9; - } else if (transmitter->ctcss_frequency == (double) 94.8) { - ctcss_tone = 10; - } else if (transmitter->ctcss_frequency == (double) 97.4) { - ctcss_tone = 11; - } else if (transmitter->ctcss_frequency == (double) 100.0) { - ctcss_tone = 12; - } else if (transmitter->ctcss_frequency == (double) 103.5) { - ctcss_tone = 13; - } else if (transmitter->ctcss_frequency == (double) 107.2) { - ctcss_tone = 14; - } else if (transmitter->ctcss_frequency == (double) 110.9) { - ctcss_tone = 15; - } else if (transmitter->ctcss_frequency == (double) 114.8) { - ctcss_tone = 16; - } else if (transmitter->ctcss_frequency == (double) 118.8) { - ctcss_tone = 17; - } else if (transmitter->ctcss_frequency == (double) 123.0) { - ctcss_tone = 18; - } else if (transmitter->ctcss_frequency == (double) 127.3) { - ctcss_tone = 19; - } else if (transmitter->ctcss_frequency == (double) 131.8) { - ctcss_tone = 20; - } else if (transmitter->ctcss_frequency == (double) 136.5) { - ctcss_tone = 21; - } else if (transmitter->ctcss_frequency == (double) 141.3) { - ctcss_tone = 22; - } else if (transmitter->ctcss_frequency == (double) 146.2) { - ctcss_tone = 23; - } else if (transmitter->ctcss_frequency == (double) 151.4) { - ctcss_tone = 24; - } else if (transmitter->ctcss_frequency == (double) 156.7) { - ctcss_tone = 25; - } else if (transmitter->ctcss_frequency == (double) 162.2) { - ctcss_tone = 26; - } else if (transmitter->ctcss_frequency == (double) 167.9) { - ctcss_tone = 27; - } else if (transmitter->ctcss_frequency == (double) 173.8) { - ctcss_tone = 28; - } else if (transmitter->ctcss_frequency == (double) 179.9) { - ctcss_tone = 29; - } else if (transmitter->ctcss_frequency == (double) 186.2) { - ctcss_tone = 30; - } else if (transmitter->ctcss_frequency == (double) 192.8) { - ctcss_tone = 31; - } else if (transmitter->ctcss_frequency == (double) 203.5) { - ctcss_tone = 32; - } else if (transmitter->ctcss_frequency == (double) 210.7) { - ctcss_tone = 33; - } else if (transmitter->ctcss_frequency == (double) 218.1) { - ctcss_tone = 34; - } else if (transmitter->ctcss_frequency == (double) 225.7) { - ctcss_tone = 35; - } else if (transmitter->ctcss_frequency == (double) 233.6) { - ctcss_tone = 36; - } else if (transmitter->ctcss_frequency == (double) 241.8) { - ctcss_tone = 37; - } else if (transmitter->ctcss_frequency == (double) 250.3) { - ctcss_tone = 38; - } else if (transmitter->ctcss_frequency == (double) 1750.0) { - ctcss_tone = 39; - } else { - send_resp(client_sock,"?;"); - } - if(ctcss_tone != -1) { - sprintf(msg,"CN%02d;",ctcss_tone); - send_resp(client_sock,msg); - } - } - } - // ZZCS - Keyer Speed implemented within "KS" command - else if((strcmp(cmd_str,"CT")==0) && (zzid_flag == 0)) { - // TS-2000 - CS - Sets and reads CTSS function status - // Stored locally in rigctl - not used. - if(len <=2) { - sprintf(msg,"CT%01d;",transmitter->ctcss); - send_resp(client_sock,msg); - } else { - if((atoi(&cmd_input[2]) == 0) ||(atoi(&cmd_input[2]) == 1)) { - transmitter->ctcss = atoi(&cmd_input[2]); - transmitter_set_ctcss(transmitter,transmitter->ctcss,transmitter->ctcss_frequency); - } else { - send_resp(client_sock,"?;"); - } - } - } - else if((strcmp(cmd_str,"DA")==0) && (zzid_flag == 1)) { - // PiHPSDR - DA - Set/Clear Waterfall Automatic on Display Menu - if(len <=2) { - sprintf(msg,"ZZDA%0d;",active_receiver->waterfall_automatic); - send_resp(client_sock,msg); - } else { - if((cmd_input[2] == '0') || (cmd_input[2] == '1')) { - active_receiver->waterfall_automatic = atoi(&cmd_input[2]); - } else { - send_resp(client_sock,"?;"); - } - } - } - else if((strcmp(cmd_str,"DC")==0) && (zzid_flag == 0)) { - // TS-2000 - DC - Sets/Reads TX band status - if(len <=2) { - //send_resp(client_sock,"DC00;"); - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"DN")==0) { - // TS-2000 - DN - Emulate Mic down key - Not supported - // PiHPSDR - ZZDN - Set/Read Waterfall Lo Limit - int lcl_waterfall_low; - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: DN - init val=%d\n",active_receiver->waterfall_low); - #endif - if(zzid_flag == 1) { // ZZDN - if(len<=2) { - if(active_receiver->waterfall_low <0) { - sprintf(msg,"ZZDN-%03d;",abs(active_receiver->waterfall_low)); - } else { - sprintf(msg,"ZZDN+%03d;",active_receiver->waterfall_low); - } - send_resp(client_sock,msg); - } else { - lcl_waterfall_low = atoi(&cmd_input[3]); - if((lcl_waterfall_low >= -200) && (lcl_waterfall_low <=200)) { - if(cmd_input[2]=='-') { - //waterfall_low = lcl_waterfall_low; - active_receiver->waterfall_low = -lcl_waterfall_low; - } else { - active_receiver->waterfall_low = lcl_waterfall_low; - } - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: DN - fin val=%d\n",active_receiver->waterfall_low); - #endif - } else { - fprintf(stderr,"RIGCTL: ZZDN illegal val=%d\n",lcl_waterfall_low); - send_resp(client_sock,"?;"); - } - } - } - } - else if((strcmp(cmd_str,"DO")==0) && zzid_flag == 1) { - // PiHPSDR - ZZDO - Set/Read Waterfall Hi Limit - if(len<=2) { - if(active_receiver->waterfall_high <0) { - sprintf(msg,"ZZDO-%03d;",abs(active_receiver->waterfall_high)); - } else { - sprintf(msg,"ZZDO+%03d;",active_receiver->waterfall_high); - } - send_resp(client_sock,msg); - } else { - int lcl_waterfall_high = atoi(&cmd_input[3]); - if((lcl_waterfall_high >= -200) && (lcl_waterfall_high <=200)) { - if(cmd_input[2]=='-') { - active_receiver->waterfall_high = -lcl_waterfall_high; - } else { - active_receiver->waterfall_high = lcl_waterfall_high; - } - } else { - fprintf(stderr,"RIGCTL: ZZDO illegal val=%d\n",lcl_waterfall_high); - send_resp(client_sock,"?;"); - } - } - } - else if((strcmp(cmd_str,"DQ")==0) && (zzid_flag == 0)) { - // TS-2000 - DQ - ETs/and reads the DCS function status - not supported - if(len <=2) { - //send_resp(client_sock,"DQ0;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"DU")==0) && zzid_flag ==1) { - // PiHPSDR - ZZDU - Read Status Word - NOT compatible with PSDR!! - int smeter = (int) GetRXAMeter(active_receiver->id, smeter) ; - sprintf(msg,"ZZDU%1d%1d%1d%1d%1d%1d%1d%1d%1d%06d%1d%03d%1c%1d%1d%1d%1c%06lld%1d%011lld%011lld%c%03d%1d%1d%1d%1d;", - split, //P1 - tune, // P2, - mox, // P3 - receivers, // P4 - active_receiver->id, // P5 - active_receiver->alex_antenna, // P6 - rit_on(), // P7 - active_receiver->agc, // P8 - vfo[active_receiver->id].mode, //P9 - (int) step, // P10 - vfo[active_receiver->id].band, // P11 6d - ((int) transmitter->drive)*100, // P12 - (int)active_receiver->agc_gain >=0 ? '+' : '-', // P13 sign - (int)active_receiver->agc_gain, // P13 3d - (int)active_receiver->volume, // P14 3d - vfo[active_receiver->id].rit_enabled, - vfo[active_receiver->id].rit >=0 ? '+' : '-', // P15 sign - vfo[active_receiver->id].rit, // P15 6d - vfo[active_receiver->id].ctun, // P16 1d - vfo[active_receiver->id].frequency, // P17 11d - vfo[active_receiver->id].ctun_frequency, // P18 11d - smeter>=0 ? '+': '-', - abs(smeter), - active_receiver->nr , active_receiver->nr2 , - active_receiver->anf , active_receiver->snb); - send_resp(client_sock,msg); - } - - else if((strcmp(cmd_str,"EA")==0) && zzid_flag ==1) { - // PiHPSDR - ZZEA - sets/reads RX EQ values - if(len<=2) { - sprintf(msg,"ZZEA%1d%1c%03d%1c%03d%1c%03d%1c%03d;", - enable_rx_equalizer, - rx_equalizer[0]>=0? '+' : '-', - abs((int) rx_equalizer[0]), - rx_equalizer[1]>=0? '+' : '-', - abs((int) rx_equalizer[1]), - rx_equalizer[2]>=0? '+' : '-', - abs((int) rx_equalizer[2]), - rx_equalizer[3]>=0? '+' : '-', - abs((int) rx_equalizer[3])); - send_resp(client_sock,msg); - - } else { - //if(len !=19) { - // fprintf(stderr,"RIGCTL: ZZEA - incorrect number of arguments\n"); - // send_resp(client_sock,"?;"); - // return; - // } - double work_do; - enable_rx_equalizer = atoi(&cmd_input[2]); - work_do = (double) atoi(&cmd_input[3]); - if((work_do < -12) || (work_do > 15)) { - fprintf(stderr,"RIGCTL: ZZEA - Preamp arg out of range=%d \n",(int) work_do); - send_resp(client_sock,"?;"); - return; - } - rx_equalizer[0] = work_do; - - work_do = (double) atoi(&cmd_input[7]); - if((work_do < -12) || (work_do > 15)) { - fprintf(stderr,"RIGCTL: ZZEA - Low arg out of range=%d \n",(int) work_do); - send_resp(client_sock,"?;"); - return; - } - rx_equalizer[1] = work_do; - - work_do = (double) atoi(&cmd_input[11]); - if((work_do < -12) || (work_do > 15)) { - fprintf(stderr,"RIGCTL: ZZEA - Mid arg out of range=%d \n",(int) work_do); - send_resp(client_sock,"?;"); - return; - } - rx_equalizer[2] = work_do; - - work_do = (double) atoi(&cmd_input[15]); - if((work_do < -12) || (work_do > 15)) { - fprintf(stderr,"RIGCTL: ZZEA - Hi arg out of range=%d \n",(int) work_do); - send_resp(client_sock,"?;"); - return; - } - rx_equalizer[3] = work_do; - - SetRXAGrphEQ(active_receiver->id, rx_equalizer); - } - } - else if((strcmp(cmd_str,"EB")==0) && zzid_flag ==1) { - // PiHPSDR - ZZEB - sets/reads TX EQ values - if(len<=2) { - sprintf(msg,"ZZEB%1d%1c%03d%1c%03d%1c%03d%1c%03d;", - enable_tx_equalizer, - tx_equalizer[0]>=0? '+' : '-', - abs((int) tx_equalizer[0]), - tx_equalizer[1]>=0? '+' : '-', - abs((int) tx_equalizer[1]), - tx_equalizer[2]>=0? '+' : '-', - abs((int) tx_equalizer[2]), - tx_equalizer[3]>=0? '+' : '-', - abs((int) tx_equalizer[3])); - send_resp(client_sock,msg); - - } else { - if(len !=19) { - fprintf(stderr,"RIGCTL: ZZEB - incorrect number of arguments\n"); - send_resp(client_sock,"?;"); - return; - } - double work_do; - enable_tx_equalizer = atoi(&cmd_input[2]); - - work_do = (double) atoi(&cmd_input[3]); - if((work_do < -12) || (work_do > 15)) { - fprintf(stderr,"RIGCTL: ZZEB - Preamp arg out of range=%d \n",(int) work_do); - send_resp(client_sock,"?;"); - return; - } - tx_equalizer[0] = work_do; - - work_do = (double) atoi(&cmd_input[7]); - if((work_do < -12) || (work_do > 15)) { - fprintf(stderr,"RIGCTL: ZZEB - Low arg out of range=%d \n",(int) work_do); - send_resp(client_sock,"?;"); - return; - } - tx_equalizer[1] = work_do; - - work_do = (double) atoi(&cmd_input[11]); - if((work_do < -12) || (work_do > 15)) { - fprintf(stderr,"RIGCTL: ZZEB - Mid arg out of range=%d \n",(int) work_do); - send_resp(client_sock,"?;"); - return; - } - tx_equalizer[2] = work_do; - - work_do = (double) atoi(&cmd_input[15]); - if((work_do < -12) || (work_do > 15)) { - fprintf(stderr,"RIGCTL: ZZEB - Hi arg out of range=%d \n",(int) work_do); - send_resp(client_sock,"?;"); - return; - } - tx_equalizer[3] = work_do; - - SetTXAGrphEQ(transmitter->id, tx_equalizer); - } - } - else if(strcmp(cmd_str,"EX")==0) { // Set/reads the extension menu - // This routine only can look up specific information; - // And only performs reads at this point.. - // EX P1 P1 P1 P2 P2 P3 P4 ; - Read command - int p5=0; - strncpy(buf,cmd_input,9); // Get the front of the response - if(len == 10) { // Read command - // CW Sidetone frequendcy - if(strncmp(&cmd_input[2],"031",3) == 0) { - if(cw_keyer_sidetone_frequency <=400) { - p5 = 0; - } else if (cw_keyer_sidetone_frequency <=450) { - p5 = 1; - } else if (cw_keyer_sidetone_frequency <=500) { - p5 = 2; - } else if (cw_keyer_sidetone_frequency <=550) { - p5 = 3; - } else if (cw_keyer_sidetone_frequency <=600) { - p5 = 4; - } else if (cw_keyer_sidetone_frequency <=650) { - p5 = 5; - } else if (cw_keyer_sidetone_frequency <=700) { - p5 = 6; - } else if (cw_keyer_sidetone_frequency <=750) { - p5 = 7; - } else if (cw_keyer_sidetone_frequency <=800) { - p5 = 8; - } else if (cw_keyer_sidetone_frequency <=850) { - p5 = 9; - } - sprintf(msg,"%s%01d;",buf,p5); - send_resp(client_sock,msg); - // SPLIT - } else if(strncmp(&cmd_input[2],"06A",3) == 0) { - sprintf(msg,"%s%01d;",buf,split); - send_resp(client_sock,msg); - } else { - send_resp(client_sock,"?;"); - } - } - } - else if(strcmp(cmd_str,"FA")==0) { - // PiHPSDR - ZZFA - VFO A frequency - // TS2000 - FA - VFO A frequency - // LEN=7 - set frequency - // Next data will be rest of freq - if(len == 13) { //We are receiving freq info - new_freqA = atoll(&cmd_input[2]); - long long *p=malloc(sizeof(long long)); - *p= new_freqA; - g_idle_add(ext_set_frequency,(gpointer)p); - g_idle_add(ext_vfo_update,NULL); - return; - } else { - if(len==2) { - if(zzid_flag == 0) { - if(vfo[VFO_A].ctun == 1) { - sprintf(msg,"FA%011lld;",vfo[VFO_A].frequency+vfo[VFO_A].offset); - } else { - sprintf(msg,"FA%011lld;",vfo[VFO_A].frequency); - } - } else { - if(vfo[VFO_A].ctun == 1) { - sprintf(msg,"ZZFA%011lld;",vfo[VFO_A].frequency+vfo[VFO_A].offset); - } else { - sprintf(msg,"ZZFA%011lld;",vfo[VFO_A].frequency); - } - } - //fprintf(stderr,"RIGCTL: FA=%s\n",msg); - send_resp(client_sock,msg); - } - } - } - else if(strcmp(cmd_str,"FB")==0) { - // TS-2000 - FB - VFO B frequency - // PiHPSDR - ZZFB - VFO B frequency - if(len==13) { //We are receiving freq info - new_freqB = atoll(&cmd_input[2]); - long long *p=malloc(sizeof(long long)); - *p=new_freqB; - g_idle_add(ext_set_frequency,(gpointer)p); - g_idle_add(ext_vfo_update,NULL); - //new_freqB = atoll(&cmd_input[2]); - //set_freqB(new_freqB); - //setFrequency(new_freqA); - //g_idle_add(ext_vfo_update,NULL); - } else if(len == 2) { - if(zzid_flag == 0) { - if(vfo[VFO_B].ctun == 1) { - sprintf(msg,"FB%011lld;",vfo[VFO_B].frequency + vfo[VFO_B].offset); - } else { - sprintf(msg,"FB%011lld;",vfo[VFO_B].frequency); - } - } else { - if(vfo[VFO_B].ctun == 1) { - sprintf(msg,"ZZFB%011lld;",vfo[VFO_B].frequency + vfo[VFO_B].offset); - } else { - sprintf(msg,"ZZFB%011lld;",vfo[VFO_B].frequency); - } - } - send_resp(client_sock,msg); - } - } - /* Not supported */ - else if(strcmp(cmd_str,"FC")==0) { // Set Sub receiver freq - // LEN=7 - set frequency - // Next data will be rest of freq - // Len<7 - frequency? - if(len>4) { //We are receiving freq info - //long long new_freqA = atoll(&cmd_input[2]); - //setFrequency(new_freqA); - } else { - sprintf(msg,"FC%011lld;",rigctl_getFrequency()); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"FD")==0) & (zzid_flag==0)) { - // TS-2000 - FD - Read the filter display dot pattern - send_resp(client_sock,"FD00000000;"); - } - else if((strcmp(cmd_str,"FH")==0) & (zzid_flag==1)) { - // PiHPSDR - ZZFH - Set/Read Selected current DSP Filter Low High - // P1 = (0)XXXX 5 chars --9999-09999 - if(len<=2) { - sprintf(msg,"ZZFH%05d;",active_receiver->filter_high); - send_resp(client_sock,msg); - } else { - // Insure that we have a variable filter selected! - if(vfo[active_receiver->id].filter > 9) { - work_int = atoi(&cmd_input[2]); - if((work_int >= -9999) && (work_int <=9999)) { - active_receiver->filter_high = work_int; - } else { - fprintf(stderr,"RIGCTL Warning ZZFH Value=%d out of range\n",work_int); - send_resp(client_sock,"?;"); - } - } else { - fprintf(stderr,"RIGCTL Warning ZZFH not applied - VAR1/2 not selected\n"); - send_resp(client_sock,"?;"); - } - } - } - else if((strcmp(cmd_str,"FI")==0) & (zzid_flag==1)) { - // PiHPSDR - ZZFI - Set/Read current DSP filter selected filter - if(len<=2) { - sprintf(msg,"ZZFI%02d;",vfo[active_receiver->id].filter); - send_resp(client_sock,msg); - } else { - work_int = atoi(&cmd_input[2]); - if((work_int >=0) && (work_int<=11)) { - g_idle_add(filter_select,(gpointer)(long)work_int); - } else { - fprintf(stderr,"RIGCTL: ERROR ZZFI incorrect filter value=%d",work_int); - send_resp(client_sock,"?;"); - } - } - } - else if((strcmp(cmd_str,"FL")==0) & (zzid_flag==1)) { - // PiHPSDR - ZZFL - Set/Read Selected current DSP Filter Low - // P1 = (0)XXXX 5 chars --9999-09999 - if(len<=2) { - sprintf(msg,"ZZFL%05d;",active_receiver->filter_low); - send_resp(client_sock,msg); - } else { - // Insure that we have a variable filter selected! - if(vfo[active_receiver->id].filter > 9) { - work_int = atoi(&cmd_input[2]); - if((work_int >= -9999) && (work_int <=9999)) { - active_receiver->filter_low = work_int; - } else { - fprintf(stderr,"RIGCTL Warning ZZFH Value=%d out of range\n",work_int); - send_resp(client_sock,"?;"); - } - } else { - fprintf(stderr,"RIGCTL Warning ZZFH not applied - VAR1/2 not selected\n"); - send_resp(client_sock,"?;"); - } - } - } - else if((strcmp(cmd_str,"FR")==0) && (zzid_flag == 0)) { - // TS-2000 - FR - Set/reads the extension menu - if(len <=2) { - if(receivers == 1) { - sprintf(msg,"FR0;"); - } else { - sprintf(msg,"FR%1d;",active_receiver->id); - } - send_resp(client_sock,msg); - } else if (receivers != 1) { - lcl_cmd = atoi(&cmd_input[2]); - if(active_transmitter != lcl_cmd) { - split = 1; - } - if(active_receiver->id != lcl_cmd) { - //active_receiver->id = lcl_cmd; - active_receiver = receiver[lcl_cmd]; - g_idle_add(ext_vfo_update,NULL); - // SDW - //g_idle_add(active_receiver_changed,NULL); - } - } - } - else if((strcmp(cmd_str,"FS")==0) && (zzid_flag == 0)) { - // TS-2000 - FS - Set/reads fine funct status - - if(len <=2) { - sprintf(msg,"FS%1d;",fine); - send_resp(client_sock,msg); - } else { - int lcl_fine; - lcl_fine = atoi(&cmd_input[2]); - if((lcl_fine >=0) && (lcl_fine <=1)) { - fine = lcl_fine; - } else { - send_resp(client_sock,"?;"); - } - } - } - else if(strcmp(cmd_str,"FT")==0) { - // TS-2000 - FT - Set/Read Active Transmitter - // PiHPSDR - ZZFT - Set/Read Active Transmitter - if(len <=2) { - if(zzid_flag == 0) { - sprintf(msg,"FT%1d;",active_transmitter); - } else { - sprintf(msg,"ZZFT%1d;",active_transmitter); - } - send_resp(client_sock,msg); - } else { - lcl_cmd = atoi(&cmd_input[2]); - if((lcl_cmd ==0) ||(lcl_cmd == 1)) { - if(lcl_cmd != active_receiver->id) { - split = 1; - } else { - split = 0; - } - active_transmitter = lcl_cmd; - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: FT New=%d\n",active_transmitter); - #endif - g_idle_add(ext_vfo_update,NULL); - } else { - send_resp(client_sock,"?;"); - } - } - } - else if((strcmp(cmd_str,"FW")==0) & (zzid_flag==0)) { - // TS-2000 - FW - Sets/Read DSP receive filter width in hz 0-9999hz - // CW - legal values 50 80 100 150 200 300 400 500 600 1000 2000 - // Pi HPSDR map 50 100 100 100 250 250 400 500 600 1000 - // 25 750 - BAND *band=band_get_band(vfo[active_receiver->id].band); - BANDSTACK *bandstack=band->bandstack; - BANDSTACK_ENTRY *entry=&bandstack->entry[vfo[active_receiver->id].bandstack]; - FILTER* band_filters=filters[vfo[active_receiver->id].mode]; - FILTER* band_filter=&band_filters[vfo[active_receiver->id].filter]; - int cur_rad_mode= vfo[active_receiver->id].mode; - // SDW1 - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: FW - active recv mode =%d\n",cur_rad_mode); - #endif - if((cur_rad_mode == modeCWL) || (cur_rad_mode == modeCWU)) { - if(len <=2) { - // CW filter high and low are always the same and the filter value is 2*filter val - int filter_val = abs(band_filter->high * 2); - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: Filter Value=%d\n",filter_val); - #endif - switch(filter_val) { - case 25: - case 50: - work_int = 50; - break; - case 100: - work_int = 100; - break; - case 250: - work_int = 300; - break; - case 400: - work_int = 400; - break; - case 500: - work_int = 500; - break; - case 600: - work_int = 600; - break; - case 750: - work_int = 1000; - break; - case 800: - work_int = 1000; - break; - case 1000: - work_int = 1000; - break; - default: work_int = 500; - break; - } - sprintf(msg,"FW%04d;",work_int); - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: FW Filter Act=%d work_int=%d\n",band_filter->high,work_int); - #endif - send_resp(client_sock,msg); - } else { - int f; - // Try to set filters here! - // CW - legal values 50 80 100 150 200 300 400 500 600 1000 2000 - // Pi HPSDR map 50 100 100 100 250 250 400 500 600 1000 - // 25 750 - work_int = atoi(&cmd_input[2]); - switch (work_int) { - case 50: f= 8; break; - case 80: f= 7; break; - case 100: f= 7; break; - case 150: f= 7; break; - case 200: f= 6; break; - case 300: f= 6; break; - case 400: f= 5; break; - case 500: f= 4; break; - case 600: f= 3; break; - case 1000: f= 0; break; - case 2000: f= 0; break; - default: f=10; break; - } - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: FW CW Filter width=%d piHPSDR type=%d\n", work_int, f); - #endif - g_idle_add(ext_vfo_filter_changed,(gpointer)(long)f); - } - } else { - /* Not in CW mode */ - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"GT")==0) { - // TS-2000 - GT - Sets/Reads AGC Constant - // PiHPSDR - ZZGT - AGC Constant 0-4 are legal values - if(zzid_flag == 0) { - // Sets/Read AGC constant status 000-020 - // Map 000 - Off, 001-4 - Fast, 4-9 - Medium 10-14 Slow 15-20 Long - //fprintf(stderr,"GT command seen\n"); - int agc_resp = 0; - if(len <=2) { - - switch(active_receiver->agc) { - case AGC_OFF : agc_resp = 0; break; - case AGC_FAST: agc_resp = 5; break; - case AGC_MEDIUM: agc_resp = 10; break; - case AGC_SLOW: agc_resp = 15; break; - case AGC_LONG: agc_resp = 20; break; - default: agc_resp = 0; - } - if(zzid_flag == 0) { - sprintf(msg,"GT%03d;",agc_resp); - } else { - sprintf(msg,"ZZGT%03d;",agc_resp); - } - send_resp(client_sock,msg); - } else { - //fprintf(stderr,"GT command Set\n"); - agc_resp = atoi(&cmd_input[2]); - - // AGC powers of 84 is broken Hamlib... - // Hamlib TS 2000 is broken here - - if(agc_resp == 0) { - active_receiver->agc = AGC_OFF; - } else if((agc_resp >0 && agc_resp <= 5) || (agc_resp == 84)) { - active_receiver->agc = AGC_FAST; - // fprintf(stderr,"GT command FAST\n"); - } else if((agc_resp >6 && agc_resp <= 10) || (agc_resp == 2*84)) { - active_receiver->agc = AGC_MEDIUM; - // fprintf(stderr,"GT command MED\n"); - } else if((agc_resp >11 && agc_resp <= 15) || (agc_resp == 3*84)) { - active_receiver->agc = AGC_SLOW; - //fprintf(stderr,"GT command SLOW\n"); - } else if((agc_resp >16 && agc_resp <= 20) || (agc_resp == 4*84)) { - active_receiver->agc = AGC_LONG; - // fprintf(stderr,"GT command LONG\n"); - } - g_idle_add(ext_vfo_update,NULL); - - } - } else { - if(len<=2) { - sprintf(msg,"ZZGT%01d;",active_receiver->agc); - send_resp(client_sock,msg); - } else { - int lcl_agc = atoi(&cmd_input[2]); - if(lcl_agc >= AGC_OFF && lcl_agc<=AGC_FAST) { - active_receiver->agc = lcl_agc; - g_idle_add(ext_vfo_update,NULL); - } - } - } - } - else if(strcmp(cmd_str,"ID")==0) { - // TS-2000 - ID - Read ID - Default to TS-2000 which is type 019. - // PiHPSDR - ZZID - Read ID - 240, i.e. hamlib number - if(zzid_flag == 0) { - sprintf(msg,"ID019;"); - } else { - sprintf(msg,"ZZID240;"); - } - send_resp(client_sock,msg); - } - else if((strcmp(cmd_str,"IF")==0) && (zzid_flag == 0)) { - // TS-2000 - IF - Reads Transceiver status - // IF - // P1: FFFFFFFFFFF -11 chars : Frequency in Hz (blanks are "0") - // P2: OFFS - 4 chars : Offset in powers of 10 - // P3: RITXIT - 6 chars : RIT/XIT Frequency, Not supported = "000000" - // P4: R - 1 char : RIT Status "1"= On, "0"= off - // P5: X - 1 char : XIT Status "1"= On, "0"= off - // P6: 0 - 1 char : Channel Bank number - not used (see MC command) - // P7: 00 - 2 chars : Channel Bank number - not used - // P8: C - 1 char : Mox Status "1"= TX, "0"= RX - // P9: M - 1 char : Operating mode (see MD command) - // P10: V - 1 char : VFO Split status - not supported - // P11: 0 - 1 char : Scan status - not supported - // P12: A - 1 char : same as FT command - // P13: 0 - 1 char : CTCSS tone - not used - // P14: 00 - 2 chars : More tone control - // P15: 0 - 1 char : Shift status - - // convert first half of the msg - // IF P1 P2 P3 P4 P5 P6 - sprintf(msg,"IF%011lld%04lld%06lld%01d%01d%01d", - //getFrequency(), - rigctl_getFrequency(), // P1 - step, // P2 - vfo[active_receiver->id].rit, // P3 - rit_on(), // P4 - rit_on(), // P5 - 0 // P6 - ); - - // convert second half of the msg - // P7 P8 P9 P10 P11 P12 P13 P14 P15; - sprintf(msg+26,"%02d%01d%01d%01d%01d%01d%01d%02d%01d;", - 0, // P7 - mox, // P8 - rigctlGetMode(), // P9 - 0, // P10 - 0, // P11 - ft_read(), // P12 - transmitter->ctcss, // P14 - convert_ctcss(), // P13 - 0); // P15 - send_resp(client_sock,msg); - } - else if(strcmp(cmd_str,"IS")==0) { // Sets/Reas IF shift funct status - if(len <=2) { - send_resp(client_sock,"IS00000;"); - } - } - else if(((strcmp(cmd_str,"KS")==0) && (zzid_flag == 0)) || // Dl1YCF added () to improve readablity - ((strcmp(cmd_str,"CS")==0) && (zzid_flag==1))) { // Dl1YCF added () to improve readablity - // TS-2000 - KS - Set/Reads keying speed 0-060 max - // PiHPSDR - ZZCS - Sets/Reads Keying speed - if(len <=2) { - if(zzid_flag ==0) { - sprintf(msg,"KS%03d;",cw_keyer_speed); - } else { - sprintf(msg,"ZZCS%02d;",cw_keyer_speed); - } - send_resp(client_sock,msg); - } else { - int key_speed; - key_speed = atoi(&cmd_input[2]); - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: Set CW speed=%d",key_speed); - #endif - if(key_speed >= 1 && key_speed <= 60) { - cw_keyer_speed=key_speed; -#ifdef LOCALCW - // tell keyer - keyer_update(); -#endif - g_idle_add(ext_vfo_update,NULL); - } else { - send_resp(client_sock,"?;"); - } - } - } - else if((strcmp(cmd_str,"KY")==0) && (zzid_flag == 0)) - { - if (cw_busy < 0) cat_cw_seen=1; - // - // Hamlib produces timeout errors if we are busy here for - // seconds. Therefore we just move the data into a buffer - // that is processed by a separate thread. - // Note that here we only makes a 0 --> 1 transition for cw_busy, - // and the CW thread only makes a 1 --> 0 transition, so we do not - // need a mutex and/or atomic updates here. - // - // Note: The "KY;" command is used to query if we are busy. We return: - // - if we can accept new data (buffer space available) : "KY0;" - // - if buffer is full: "KY1;" - // - // Note: cw_busy == -1 indicates a "purge KY" situation, where - // all KY commands are accepted and data is discared silently - // In this case cw_busy is left untouched here. - // - if (len <= 2) { - if (cw_busy == 1) { - send_resp(client_sock,"KY1;"); - } else { - send_resp(client_sock,"KY0;"); - } - } else { - // - We silently ignore buffer overruns. This does not happen if - // "busy" is correctly queried. - // - Note further that the space immediately following "KY" is *not* - // part of the message. - if ((cw_busy==0) && (len > 3)) { - // A CW text will be sent. Copy incoming data to buffer - strncpy(cw_buf, cmd_input+3, 29); - // Kenwood protocol allows for at most 24 characters, so - // this seems pure paranoia -- but who knows? - cw_buf[29]=0; - cw_busy=1; - } - // cwbusy == -1 or empty text: do nothing - } - } - else if(strcmp(cmd_str,"LK")==0) { - // TS-2000 - LK - Set/read key lock function status - // PiHPSDR - ZZLK - Set/read key lock function status - if(len <=2) { - if(zzid_flag == 0) { - sprintf(msg,"LK%01d%01d;",locked,locked); - } else { - sprintf(msg,"ZZLK%01d%01d;",locked,locked); - } - send_resp(client_sock,msg); - } else { - if((cmd_input[2] == '1') || (cmd_input[3]=='1')) { - locked = 1; - } else { - locked = 0; - } - g_idle_add(ext_vfo_update,NULL); - } - } - else if(strcmp(cmd_str,"LM")==0) { - // TS-2000 - LM - Set/Read DRU 3A keyer recording status - not supported - if(len <=2) { - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"LT")==0) { - // TS-2000 - LT - Set/read Alt function - not supported - if(len <=2) { - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"MC")==0) { - // TS-2000 - MC - Recalls or reads memory channel - not supported - if(len <=2) { - send_resp(client_sock,"?;"); // Link this to band stack at some point - } - } - else if((strcmp(cmd_str,"MD")==0) && (zzid_flag == 0)) { - // TS-2000 - MD - Set/Read Mode - // Mode - digit selects mode - // 1 = LSB - // 2 = USB - // 3 = CWU - // 4 = FM - // 5 = AM - // 6 = DIGL - // 7 = CWL - // 9 = DIGU - int new_mode; - if(len > 2) { // Set Mode - switch(atoi(&cmd_input[2])) { - case 1: - new_mode = modeLSB; - break; - case 2: - new_mode = modeUSB; - break; - case 3: - new_mode = modeCWU; - break; - case 4: - new_mode = modeFMN; - break; - case 5: - new_mode = modeAM; - break; - case 6: - new_mode = modeDIGL; - break; - case 7: - new_mode = modeCWL; - break; - case 9: - new_mode = modeDIGU; - break; - default: - break; - #ifdef RIGCTL_DEBUG - fprintf(stderr,"MD command Unknown\n"); - #endif - } - g_idle_add(ext_vfo_mode_changed, (void *) (long) new_mode); - } else { // Read Mode - int curr_mode; - switch (vfo[active_receiver->id].mode) { - case modeLSB: curr_mode = 1; - break; - case modeUSB: curr_mode = 2; - break; - case modeCWL: curr_mode = 7; // CWL - break; - case modeCWU: curr_mode = 3; // CWU - break; - case modeFMN: curr_mode = 4; // FMN - break; - case modeAM: curr_mode = 5; // AM - break; - case modeDIGU: curr_mode = 9; // DIGU - break; - case modeDIGL: curr_mode = 6; // DIGL - break; - default: - #ifdef RIGCTL_DEBUG - fprintf(stderr, - "RIGCTL: MD command doesn't support %d\n", - vfo[active_receiver->id].mode); - #endif - break; - } - sprintf(msg,"MD%1d;",curr_mode); - send_resp(client_sock,msg); - } - } - else if((strcmp(cmd_str,"MD")==0) && (zzid_flag == 1)) { - // PiHPSDR - ZZMD - Set/Read Modulation Mode - if(len <= 2) { // Set Mode - sprintf(msg,"ZZMD%02d;",vfo[active_receiver->id].mode); - send_resp(client_sock,msg); - } else { - work_int = atoi(&cmd_input[2]); - if((work_int >=0) && (work_int <=11)) { - // Other stuff to switch modes goes here.. - // since new_mode has the interpreted command in - // in it now. - entry= (BANDSTACK_ENTRY *) - bandstack_entry_get_current(); - entry->mode=work_int; - set_mode(active_receiver,entry->mode); - FILTER* band_filters=filters[entry->mode]; - FILTER* band_filter=&band_filters[entry->filter]; - //setFilter(band_filter->low,band_filter->high); - set_filter(active_receiver,band_filter->low,band_filter->high); - /* Need a way to update VFO info here..*/ - g_idle_add(ext_vfo_update,NULL); - } else { - fprintf(stderr,"RIGCTL: Error - ZZMD - Illegal cmd received=%d",work_int); - } - } - } - else if((strcmp(cmd_str,"MF")==0) && (zzid_flag == 0)) { - // TS-2000 - MF - Set/read menu A/B - not supported - if(len <=2) { - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"MG")==0) { - // PiHPSDR - ZZMG - Mic Gain P1=+/-P2=2digits (-10-50) - // TS-2000 - MG - Mike Gain - 3 digits - if(zzid_flag == 0) { - if(len <=2) { - work_int = (int) ((mic_gain +10.0)* 100.0/60.0); - sprintf(msg,"MG%03d;",work_int); - send_resp(client_sock,msg); - } else { - int tval = atoi(&cmd_input[2]); - new_vol = (double) (tval * 60/100) - 10; - double *p_mic_gain=malloc(sizeof(double)); - *p_mic_gain=new_vol; - g_idle_add(ext_set_mic_gain,(void *)p_mic_gain); - } - } else { - if(len <=2) { - sprintf(msg,"ZZMG%c%02d;",mic_gain>=0 ? '+' : '-',abs((int)mic_gain)); - send_resp(client_sock,msg); - } else { - int new_vol = atoi(&cmd_input[2]); - if((new_vol >= -10) && (new_vol <= 50)) { - double *p_mic_gain=malloc(sizeof(double)); - *p_mic_gain=new_vol; - g_idle_add(ext_set_mic_gain,(void *)p_mic_gain); - } else { - send_resp(client_sock,"?;"); - } - } - } - } - else if((strcmp(cmd_str,"ML")==0) && (zzid_flag == 0)) { - // TS-2000 - ML - Set/read the monitor function level - not supported - if(len <=2) { - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"MO")==0) { - // TS-2000 - MO - Set Monitor on/off - not supported - if(len <=2) { - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"MR")==0) && (zzid_flag == 0)) { - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: Command seen\n"); - #endif - - // TS-2000 - MR - Read Memory Channel data - sprintf(msg,"MR%1d%1d%02d%011lld%1d%1d%1d%02d%02d%03d%1d%1d%09d%02d%1d%08d;", - 0, // P1 - Rx Freq - 1 Tx Freq - 0, // P2 Bankd and channel number -- see MC comment - 0, // P3 - see MC comment - rigctl_getFrequency(), // P4 - frequency - rigctlGetMode(), // P5 - Mode - locked, // P6 - Locked status - transmitter->ctcss, // P7 - O-off, 1-tone, 2-CTCSS, 3 =DCS - convert_ctcss(), // P8 - Tone Number - see page 35 - convert_ctcss(), // P9 - CTCSS tone number - see CN command - 0, // P10 - DCS code - see QC command - 0, // P11 - Reverse status - 0, // P12 - Shift status - see OS command - 0, // P13 - Offset freq - see OS command - 0, // P14 - Step Size - see ST command - 0, // P15 - Memory Group Number (0-9) - 0); // P16 - Memory Name - 8 char max - send_resp(client_sock,msg); - //send_resp(client_sock,"?;"); - } - else if((strcmp(cmd_str,"MT")==0) && (zzid_flag == 1)) { - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: MT Command seen\n"); - #endif - // PiHPSDR - ZZMT - Read TX Meter Mode - // Mapped from PSDR - // 0= ALC Peak - // 1= ALC Average - // 2= ALG Gain - int * p_alc; - if(len<=2) { - switch((int)alc) { - case TXA_ALC_PK: work_int = 0; break; - case TXA_ALC_AV: work_int = 1; break; - case TXA_ALC_GAIN: work_int = 2; break; - default: work_int = 0; - } - sprintf(msg,"ZZMT%01d;",(int)work_int); - send_resp(client_sock,msg); - } else { - work_int = atoi(&cmd_input[2]); - switch (work_int) { - case 0: work_int = TXA_ALC_PK; break; - case 1: work_int = TXA_ALC_AV; break; - case 2: work_int = TXA_ALC_GAIN; break; - default: work_int = TXA_ALC_PK; - } - p_alc=(int *) malloc(sizeof(double)); - *p_alc=work_int; - g_idle_add(set_alc,(gpointer )p_alc); - } - } - else if(strcmp(cmd_str,"MU")==0) { if(zzid_flag == 1) { - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: MU Command seen\n"); - #endif - // PiHPSDR - ZZMU - Sets or Read the MultiRX status - if(len<=2) { - #ifdef RIGCTL_DEBUG - fprintf(stderr,"ZZMU =%d\n",receivers); - #endif - sprintf(msg,"ZZMU%1d;",receivers); - send_resp(client_sock,msg); - } else { - int lcl_rcvr = atoi(&cmd_input[2]); - #ifdef RIGCTL_DEBUG - fprintf(stderr,"ZZMU Set=%d\n",lcl_rcvr); - #endif - /*if (lcl_rcvr <1 || lcl_rcvr >2) { - fprintf(stderr,"RIGCTL: ZZMU - illegal recevier number\n"); - return; - }*/ - g_idle_add(ext_radio_change_sample_rate,(gpointer)(long)lcl_rcvr); - g_idle_add(ext_vfo_update,NULL); - } - - } else { - // TS-2000 - MU - Set/Read Memory Group Data - not supported - if(len <=2) { - send_resp(client_sock,"MU0000000000;"); - } - } - } - else if((strcmp(cmd_str,"MW")==0) && (zzid_flag == 0)) { - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: MW Command seen\n"); - #endif - // TS-2000 - MW - Store Data to Memory Channel -not supported - } - else if(strcmp(cmd_str,"NB")==0) { - // PiHPSDR - ZZNB - Set/Read Noise Blanker func status (on/off) - // TS-2000 - NB - Set/Read Noise Blanker func status (on/off) - if(len <=2) { - if (zzid_flag == 0) { - sprintf(msg,"NB%1d;",active_receiver->snb); - } else { - sprintf(msg,"ZZNB%1d;",active_receiver->snb); - } - send_resp(client_sock,msg); - } else { - if(cmd_input[2]=='0') { // Turn off ANF - active_receiver->snb=0; - } else { // Turn on ANF - active_receiver->snb=1; - } - // Update filters - SetRXASNBARun(active_receiver->id, active_receiver->snb); - g_idle_add(ext_vfo_update,NULL); - } - } - else if((strcmp(cmd_str,"NE")==0) && (zzid_flag == 1)) { - // PiHPSDR - ZZNE - NPS AE FIlter - DSP Menu - // P1 - 0=Off - // P1 - 1=On - if(len<=2) { - sprintf(msg,"ZZNE%1d;",(int) active_receiver->nr2_ae); - send_resp(client_sock,msg); - } else { - work_int = atoi(&cmd_input[2]); - if(work_int >=0 && work_int <=1) { - active_receiver->nr2_ae = work_int; - SetRXAEMNRaeRun(active_receiver->id, active_receiver->nr2_ae); - } else { - fprintf(stderr,"RIGCTL: ZZNE - ERROR illegal value=%d s/b 0 to 2\n",work_int); - send_resp(client_sock,"?;"); - } - } - } - else if((strcmp(cmd_str,"NG")==0) && (zzid_flag == 1)) { - // PiHPSDR - ZZNG - NR Pre AGC/Post AGC- DSP Menu - if(len<=2) { - sprintf(msg,"ZZNG%1d;",(int) active_receiver->nr_agc); - send_resp(client_sock,msg); - } else { - work_int = atoi(&cmd_input[2]); - if(work_int >=0 && work_int <=1) { - active_receiver->nr_agc = atoi(&cmd_input[2]); - SetRXAEMNRPosition(active_receiver->id, active_receiver->nr_agc); - } else { - fprintf(stderr,"RIGCTL: ZZNG - illegal value=%d s/b 0 or 1\n",work_int); - send_resp(client_sock,"?;"); - } - } - } - - else if((strcmp(cmd_str,"NM")==0) && (zzid_flag == 1)) { - // PiHPSDR - ZZNM - NR2 Gain Method - DSP Menu - // P1 - 0=Linear - // P1 - 1=Log - // P1 - 2=Gamma - if(len<=2) { - sprintf(msg,"ZZNM%1d;",(int) active_receiver->nr2_gain_method); - send_resp(client_sock,msg); - } else { - work_int = atoi(&cmd_input[2]); - if(work_int >=0 && work_int <=2) { - active_receiver->nr2_gain_method = work_int; - SetRXAEMNRgainMethod(active_receiver->id, active_receiver->nr2_gain_method); - } else { - fprintf(stderr,"RIGCTL: ZZNM - illegal value=%d s/b 0 to 2\n",work_int); - send_resp(client_sock,"?;"); - } - } - } - else if(strcmp(cmd_str,"AB")==0) { - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: Command seen\n"); - #endif - } - else if((strcmp(cmd_str,"NP")==0) && (zzid_flag == 1)) { - // PiHPSDR - ZZNP - NPS Method - DSP Menu - // P1 - 0=OSMS - // P1 - 1=MMSE - if(len<=2) { - sprintf(msg,"ZZNP%1d;",(int) active_receiver->nr2_npe_method); - send_resp(client_sock,msg); - } else { - work_int = atoi(&cmd_input[2]); - if(work_int >=0 && work_int <=1) { - active_receiver->nr2_npe_method = work_int; - SetRXAEMNRnpeMethod(active_receiver->id, active_receiver->nr2_npe_method); - } else { - fprintf(stderr, "RIGCTL: ZZNP - ERROR illegal value=%d s/b 0 to 2\n",work_int); - send_resp(client_sock,"?;"); - } - } - } - else if(strcmp(cmd_str,"NL")==0) {if(zzid_flag == 0) { - // TS-2000 - NL - Set/Read Noise Reduction Level - Not Supported - if(len <=2) { - send_resp(client_sock,"?;"); - } - } else { - // PiHPSDR - ZZNL - AGC Hang Threshold - DSP Menu slider - // P1P1P1 - 0 - 100 - if(len <=2) { - sprintf(msg,"ZZNL%03d;",(int) active_receiver->agc_hang_threshold); - send_resp(client_sock,msg); - } else { - work_int = atoi(&cmd_input[2]); - if((work_int >= 0) && (work_int<=100)) { - active_receiver->agc_hang_threshold = work_int; - if(active_receiver->agc==AGC_LONG || active_receiver->agc==AGC_SLOW) { - SetRXAAGCHangThreshold(active_receiver->id, (int)active_receiver->agc_hang_threshold); - } - } - } - } - } - else if(strcmp(cmd_str,"NR")==0) { - // TS-2000 - NR - Set/Read Noise Reduction function status - // PiHPSDR - ZZNR - Set/Read Noise Reduction function status - if(len <=2) { - if(zzid_flag == 0) { - if (active_receiver->nr==1 && active_receiver->nr2==0) { - send_resp(client_sock,"NR1;"); - } else if (active_receiver->nr==1 && active_receiver->nr2==1) { - send_resp(client_sock,"NR2;"); - } else { - send_resp(client_sock,"NR0;"); - } - } else { - if (active_receiver->nr==1 && active_receiver->nr2==0) { - send_resp(client_sock,"ZZNR1;"); - } else if (active_receiver->nr==1 && active_receiver->nr2==1) { - send_resp(client_sock,"ZZNR2;"); - } else { - send_resp(client_sock,"ZZNR0;"); - } - } - } else { - if((atoi(&cmd_input[2]) >=0) && (atoi(&cmd_input[2]) <=2)) { - if(cmd_input[2] == '0') { - active_receiver->nr = 0; - active_receiver->nr2 = 0; - } else if(cmd_input[2] == '1') { - active_receiver->nr = 1; - } else if(cmd_input[2] == '2') { - active_receiver->nr2 = 1; - } - SetRXAANRRun(active_receiver->id, active_receiver->nr); - SetRXAEMNRRun(active_receiver->id, active_receiver->nr2); - g_idle_add(ext_vfo_update,NULL); - } else { - send_resp(client_sock,"?;"); - } - } - } - else if(strcmp(cmd_str,"NT")==0) { - // TS-2000 - NT - Set/Read autonotch function - - // PiHPSDR - ZZNT - Sets/reads ANF status - if(len <=2) { - if(zzid_flag == 0) { - sprintf(msg,"NT%1d;",active_receiver->anf); - } else { - sprintf(msg,"ZZNT%1d;",active_receiver->anf); - } - send_resp(client_sock,msg); - } else { - if((atoi(&cmd_input[2]) >=0) && (atoi(&cmd_input[2]) <=1)) { - if(cmd_input[2] == '0') { // Clear ANF - active_receiver->anf = 0; - } else { // Set ANF - active_receiver->anf = 1; - } - } else { - send_resp(client_sock,"?;"); - } - } - SetRXAANFRun(active_receiver->id, active_receiver->anf); - g_idle_add(ext_vfo_update,NULL); - } - else if((strcmp(cmd_str,"OA")==0) && (zzid_flag ==1)) { - // PiHPSDR - ZZOA - Set/Read RX Antenna by band - // P1P1P1 - Band - // P2 - 1,2,3,EXT1,EXT2, XVTR - int int_band; - int b; - if(len<=5) { - int_band = atoi(&cmd_input[2]); - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL OA band =%d\n",int_band); - #endif - //b = lookup_band(int_band); - BAND *band=band_get_band(int_band); - work_int = band->alexRxAntenna; - sprintf(msg,"ZZOA%03d%1d;",int_band,work_int); - send_resp(client_sock,msg); - } else { - char lcl_char = cmd_input[5]; - cmd_input[5] = '\0'; - b = atoi(&cmd_input[2]); - //b = lookup_band(int_band); - cmd_input[5] = lcl_char; - work_int = atoi(&cmd_input[5]); - if(work_int >=0 && work_int <=5) { - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL ZZOA Band=%d Val=%d\n",b,work_int); - #endif - BAND *band=band_get_band(b); - band->alexRxAntenna = work_int; - } else { - fprintf(stderr,"RIGCTL ZZOA illegal val Band=%d Val=%d\n",b,work_int); - } - } - } - else if((strcmp(cmd_str,"OB")==0) && (zzid_flag ==1)) { - // PiHPSDR - ZZOB - Set/Read TX Antenna by band - // P1P1P1 - Band - // P2 - 1,2,3 - int int_band; - int b ; - if(len<=5) { - int_band = atoi(&cmd_input[2]); - //b = lookup_band(int_band); - b = int_band; - BAND *band=band_get_band(b); - work_int = band->alexTxAntenna; - sprintf(msg,"ZZOB%03d%1d;",int_band,work_int); - send_resp(client_sock,msg); - - } else { - char lcl_char = cmd_input[5]; - cmd_input[5] = '\0'; - int_band = atoi(&cmd_input[2]); - //b = lookup_band(int_band); - b = int_band; - cmd_input[5] = lcl_char; - work_int = atoi(&cmd_input[5]); - if(work_int >=0 && work_int <=2) { - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL ZZOB Band=%d Val=%d\n",int_band,work_int); - #endif - BAND *band=band_get_band(b); - band->alexTxAntenna = work_int; - } else { - fprintf(stderr,"RIGCTL ZZOB illegal val Band=%d Val=%d\n",int_band,work_int); - } - } - } - else if((strcmp(cmd_str,"OF")==0) && (zzid_flag == 0)) { - // TS-2000 - OF - Set/Read Offset freq (9 digits - hz) -not supported - if(len <=2) { - //send_resp(client_sock,"OF000000000;"); - send_resp(client_sock,"?;"); - } - } - /* Not Supported */ - else if((strcmp(cmd_str,"OI")==0) && (zzid_flag == 0)) { - // TS-2000 - OI - Read Memory Channel Data - not supported - /*if(len <=2) { - sprintf(msg,"OI%011lld%04d%06d%1d%1d%1d%02d%1d%1d%1d%1d%1d%1d%02d%1d;", - rigctl_getFrequency(), - 0, // P2 - Freq Step size - 0, // P3 - Rit/Xit Freq - 0, // P4 - RIT off/Rit On - 0, // P5 - XIT off/on - 0, // P6 - Channel - 0, // P7 - Bank - 0, // P8 - 0RX, 1TX - rigctlGetMode(), // P10 - MD - 0, // P11 - SC command - 0, // P12 Split op - SP command - 0, // P13 Off, 1, 2, - 0,// P14 Tone freq - See TN command - 0,0); - */ - send_resp(client_sock,"?;"); - } - else if(strcmp(cmd_str,"OS")==0) { - // TS-2000 - OS - Set/Read Offset freq (9 digits - hz) -not supported - if(len <=2) { - //send_resp(client_sock,"OS0;"); - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"PA")==0) { - // TS-2000 - PA - Set/Read Preamp function status - // PiHPSDR - ZZPA - Set/Read Preamp function status - // Note that currently, preamp switching is only done for CHARLY25 - if(len <=2) { - if(zzid_flag == 0) { - sprintf(msg,"PA%1d%1d;",active_receiver->preamp,active_receiver->preamp); - } else { - sprintf(msg,"ZZPA%1d;",active_receiver->preamp); - } - send_resp(client_sock,msg); - } else { - work_int = atoi(&cmd_input[2]); - if((work_int >= 0) && (work_int <= 1)) { - active_receiver->preamp = work_int; - } else { - send_resp(client_sock,"?;"); - } - } - } - else if(strcmp(cmd_str,"PB")==0) { - // TS-2000 - PB - DRU-3A Playback status - not supported - if(len <=2) { - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"PC")==0) { - // TS-2000 - PC - Set/Read Drive Power output - // PiHPSDR - ZZPC - Set/Read Drive Power output - if(len<=2) { - if(zzid_flag == 0) { - sprintf(msg,"PC%03d;",(int) transmitter->drive); - } else { - sprintf(msg,"ZZPC%03d;",(int) transmitter->drive); - } - send_resp(client_sock,msg); - } else { - int lcl_pc = atoi(&cmd_input[2]); - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: PC received=%d\n",lcl_pc); - #endif - if((lcl_pc >=0) && (lcl_pc<=100)) { - // Power Control - 3 digit number- 0 to 100 - //Scales to 0.00-1.00 - - double drive_val = - (double)(atoi(&cmd_input[2])); - // setDrive(drive_val); - double *p_drive=malloc(sizeof(double)); - *p_drive=drive_val; - g_idle_add(update_drive,(gpointer)p_drive); - //set_drive(drive_val); - } else { - fprintf(stderr,"RIGCTL: PC received=%d - Illegal value\n",lcl_pc); - send_resp(client_sock,"?;"); - } - } - } - else if((strcmp(cmd_str,"PI")==0) && (zzid_flag == 0)) - { - // TS-2000 - PI - Store the programmable memory channel - not supported - } - else if(strcmp(cmd_str,"PK")==0) { - // TS-2000 - PK - Reads the packet cluster data - not supported - // send_resp(client_sock,"PK000000000000000000000000000000000000000000000000;"); - send_resp(client_sock,"?;"); - - } - else if((strcmp(cmd_str,"PL")==0) && (zzid_flag == 0)) { - // TS-2000 - PL - Set/Read Speech processor level - // PL 000 000 ; - // P1 000 - min-100 max - // P2 000 - min - 100 max - double lcl_comp_level; - if(len <=2) { - // send_resp(client_sock,"PL000000;"); - lcl_comp_level = 100 *(transmitter->compressor_level)/20; - sprintf(msg,"PL%03d000;",(int)lcl_comp_level); - send_resp(client_sock,msg); - } else { - // Isolate 1st command - cmd_input[5] = '\0'; - lcl_comp_level = 20.0 *(((double)atoi(&cmd_input[2]))/100.0); - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL - PR new level=%f4.1",lcl_comp_level); - #endif - transmitter_set_compressor_level(transmitter,lcl_comp_level); - g_idle_add(ext_vfo_update,NULL); - //transmitter->compressor_level = lcl_comp_level; - } - } - else if((strcmp(cmd_str,"PM")==0) && ( zzid_flag == 0)) { - // TS-2000 - PM - Recalls the Programmable memory - not supported - if(len <=2) { - //send_resp(client_sock,"PM0;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"PR")==0) && (zzid_flag == 0)) { - // TS-2000 - PR - Sets/reads the speech processor function on/off - // 0 - off, 1=on - if(len <=2) { - sprintf(msg,"PR%01d;",transmitter->compressor); - send_resp(client_sock,msg); - } else { - transmitter_set_compressor(transmitter,atoi(&cmd_input[2])); - - g_idle_add(ext_vfo_update,NULL); - //transmitter->compressor = atoi(&cmd_input[2]); - } - } - else if(strcmp(cmd_str,"PS")==0) { - // PiHPSDR - ZZPS - Sets/reads Power on/off state- always on - // TS-2000 - PS - Sets/reads Power on/off state - // 0 - off, 1=on - if(len <=2) { - send_resp(client_sock,"PS1;"); // Lets pretend we're powered up ;-) - } - } - else if(strcmp(cmd_str,"PZ")==0) { if(zzid_flag == 1) { - // PiHPSDR - ZZPZ - Sets/Reads Radio Sample Rate - // Valid values are 048000, 096000, 192000, 384000 - #ifdef RIGCTL_DEBUG - fprintf(stderr,"ZZPZ command\n"); - #endif - if(len<=2) { - sprintf(msg,"ZZPZ%06d;",active_receiver->sample_rate); - send_resp(client_sock,msg); - } else { - long lcl_rate = atoi(&cmd_input[2]); - #ifdef RIGCTL_DEBUG - fprintf(stderr,"ZZPZ Set=%ld\n",lcl_rate); - #endif - if (lcl_rate !=48000L && lcl_rate !=96000L && - lcl_rate !=192000L && lcl_rate != 384000L) { - fprintf(stderr,"RIGCTL: ZZPZ - illegal frequency=%ld\n",lcl_rate); - send_resp(client_sock,"?;"); - return; - } - - g_idle_add(ext_radio_change_sample_rate,(gpointer)(long)lcl_rate); - g_idle_add(ext_vfo_update,NULL); - } - } - } - else if(strcmp(cmd_str,"QC")==0) { - // TS-2000 - QC - Sets/reads DCS code - not supported - // Codes numbered from 000 to 103. - if(len <=2) { - //send_resp(client_sock,"QC000;"); - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"QI")==0) { - // TS-2000 - QI - Store the settings in quick memory - not supported - } - else if(strcmp(cmd_str,"QR")==0) { - // TS-2000 - QR - Send the Quick memory channel data - not supported - // P1 - Quick mem off, 1 quick mem on - // P2 - Quick mem channel number - if(len <=2) { - //send_resp(client_sock,"QR00;"); - send_resp(client_sock,"?;"); - } - } - - else if((strcmp(cmd_str,"RA")==0) && (zzid_flag == 0)) { -#ifdef NOTSUPPORTED - // TS-2000 - RA - Sets/reads Attenuator function status - // 00-off, 1-99 -on - Main and sub receivers reported - int lcl_attenuation; - float calc_atten; - if(len <=2) { - //send_resp(client_sock,"RA0000;"); - calc_atten = round((float)adc_attenuation[active_receiver->adc]*99.0/30.0); - if(calc_atten > 99.0) { - calc_atten = 99.0; - } - sprintf(msg,"RA%02d%02d;",(int)calc_atten,(int)calc_atten); - send_resp(client_sock,msg); - } else { - lcl_attenuation = atoi(&cmd_input[2]); - if((lcl_attenuation >=0) && (lcl_attenuation <= 99)) { - lcl_attenuation = (int)((float)lcl_attenuation * 30.0/99.0); - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: lcl_att=%d\n",lcl_attenuation); - #endif - //set_attenuation(lcl_attenuation); - set_attenuation_value((double) lcl_attenuation); - g_idle_add(ext_vfo_update,NULL); - } else { -#endif - send_resp(client_sock,"?;"); - //} - //} - } - else if(strcmp(cmd_str,"RC")==0) { - // TS-2000 - RC - Clears the RIT offset freq - // PiHPSDR - ZZRC - Clears the RIT offset freq - vfo[active_receiver->id].rit = 0; - g_idle_add(ext_vfo_update,NULL); - } - else if(strcmp(cmd_str,"RD")==0) { // - // TS-2000 - RD - Move the RIT offset freq down - P1=rit_increment! - // P1=No Argument - decrement frequency - // P1=NonZero - load rit offset - // FS controls fine variable 1 or 0. rit increment 1 hz or 10hz - // PiHPSDR - ZZRD - Move the RIT offset freq down by rit_increment - int lcl_rit; - int lcl_rit_increment = fine ? 1 : 10; - if(len <=2) { - vfo[active_receiver->id].rit = vfo[active_receiver->id].rit-lcl_rit_increment; - } else { - if(len > 3) { - lcl_rit = atoi(&cmd_input[2]); - if((lcl_rit >=0) &&(lcl_rit <=99999)) { - vfo[active_receiver->id].rit = -lcl_rit; - } else { - send_resp(client_sock,"?;"); - } - } - } - g_idle_add(ext_vfo_update,NULL); - } - else if((strcmp(cmd_str,"RF")==0) && (zzid_flag == 1)) { - // PiHPSDR - ZZRR - Read Forward Power - forward = transmitter->fwd; - sprintf(msg,"RF%09.7f;",forward); - send_resp(client_sock,msg); - } - else if(strcmp(cmd_str,"RG")==0) { - // TS-2000 - RG - RF Gain Control - // PiHPSDR - ZZRG - AGC Gain Control -20 to 120 legal range - // TS 2000 settings 0-255 value scaled to -20 to 120 range - if(zzid_flag == 0) { - if(len>4) { // Set Audio Gain - int base_value = atoi(&cmd_input[2]); - double new_gain = roundf(((((double) base_value+1)/256.0) * 141.0))- 21.0; - //set_agc_gain(new_gain); - double *p_gain=malloc(sizeof(double)); - *p_gain=new_gain; - g_idle_add(ext_update_agc_gain,(gpointer)p_gain); - } else { // Read Audio Gain - double lcl_gain = (active_receiver->agc_gain+21.0)/141.0; - sprintf(msg,"RG%03d;",(int)((256.0 * lcl_gain) -1)); - send_resp(client_sock,msg); - } - } else { - // Pi HPSDR version - if(len <= 2) { - if(active_receiver->agc_gain<0) { - sprintf(msg,"ZZRG-%03d;",(int) abs((int)active_receiver->agc_gain)); - } else { - sprintf(msg,"ZZRG+%03d;",(int)active_receiver->agc_gain); - } - send_resp(client_sock,msg); - - } else { - work_int = atoi(&cmd_input[3]); - if(cmd_input[2] == '-') { // Negative number found - work_int = -work_int; - } - if((work_int >= -20) && (work_int <=120)) { - double *p_gain=malloc(sizeof(double)); - *p_gain=(double) work_int; - g_idle_add(ext_update_agc_gain,(gpointer)p_gain); - } else { - fprintf(stderr,"RIGCTL: ZZRG ERROR - Illegal AGC Value=%d\n", work_int); - send_resp(client_sock,"?;"); - } - } - } - g_idle_add(ext_vfo_update,NULL); - } - else if((strcmp(cmd_str,"RL")==0) && (zzid_flag == 0)) { - // TS-2000 - RL - Set/read Noise reduction level - not supported - if(len <=2) { - //send_resp(client_sock,"RL00;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"RM")==0) && (zzid_flag == 0)) { - // TS-2000 - RM - Set/read Meter function - not supported - // P1- 0, unsel, 1 SWR, 2 Comp, 3 ALC - // P2 - 4 dig - Meter value in dots - 000-0030 - if(len <=2) { - //send_resp(client_sock,"RM00000;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"RR")==0) && (zzid_flag == 1)) { - // PiHPSDR - ZZRR - Read Reverse Power - reverse = transmitter->rev; - sprintf(msg,"RR%09.7f;",reverse); - send_resp(client_sock,msg); - } - else if((strcmp(cmd_str,"RS")==0) && (zzid_flag == 1)) { - // PiHPSDR - ZZRS - Read SWR - forward = transmitter->fwd; - reverse = transmitter->rev; - vswr = (forward+reverse)/(forward-reverse); - sprintf(msg,"RS%04.2f;",vswr); - send_resp(client_sock,msg); - } - else if(strcmp(cmd_str,"RT")==0) { - // TS-2000 - RT - Set/read the RIT function status - // PiHPSDR - ZZRT - Set/read the RIT function status - int lcl_rit_val; - if(len <=2) { - if(zzid_flag == 0) { - sprintf(msg,"RT%01d;",rit_on()); - } else { - sprintf(msg,"ZZRT%01d;",rit_on()); - } - send_resp(client_sock,msg); - } else { - lcl_rit_val = atoi(&cmd_input[2]); - if((lcl_rit_val >=0) && (lcl_rit_val <=1)) { - vfo[active_receiver->id].rit = lcl_rit_val; - } else { - send_resp(client_sock,"?;"); - } - } - } - else if(strcmp(cmd_str,"RU")==0) { - // TS-2000 - RU - Set/move RIT frequency up - // PiHPSDR - ZZRU - Set/move RIT frequency up - int lcl_incr; - if(len <=2) { - lcl_incr = fine ? 1 : 10; - vfo[active_receiver->id].rit = vfo[active_receiver->id].rit+lcl_incr; - } else { - if(len > 3) { - lcl_incr = atoi(&cmd_input[2]); - if((lcl_incr >=0) && (lcl_incr <= 99999)) { - vfo[active_receiver->id].rit = lcl_incr; - } else { - send_resp(client_sock,"?;"); - } - } - } - g_idle_add(ext_vfo_update,NULL); - } - else if(strcmp(cmd_str,"RX")==0) { - // TS-2000 - RX - Unkey Xmitter - // PiHPSDR - ZZRX - Unkey Xmitter - //setMox(0); - if(!((vfo[active_receiver->id].mode == modeCWL) || - (vfo[active_receiver->id].mode == modeCWU))) { - #ifdef RIGCTL_DEBUG - fprintf(stderr, "RIGCTL: Inside RX command\n"); - #endif - mox_state=0; - g_idle_add(ext_mox_update,(gpointer)(long)mox_state); - g_idle_add(ext_vfo_update,NULL); - } else { - // Clear External MOX in CW mode - g_idle_add(ext_mox_update,(gpointer)(long)0); // Turn on xmitter (set Mox) - } - } - else if(strcmp(cmd_str,"SA")==0) { - // TS-2000 - SA - Set/reads satellite mode status - not supported - // 0-main, 1=sub - if(len <=2) { - //send_resp(client_sock,"SA000000000000000;"); - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"SB")==0) { - // TS-2000 - SB - Set/read the SUB TF-W status - not supported - if(len <=2) { - //send_resp(client_sock,"SB0;"); - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"SC")==0) { - // TS-2000 - SC - Set/read the Scan function status - not supported - if(len <=2) { - //send_resp(client_sock,"SC0;"); - send_resp(client_sock,"?;"); - } - } - else if(((strcmp(cmd_str,"SD")==0) && (zzid_flag == 0)) || // Dl1YCF added () to improve readablity - ((strcmp(cmd_str,"CD")==0) && (zzid_flag ==1))) { // Dl1YCF added () to improve readablity - // PiHPSDR - ZZCD - Set/Read CW Keyer Hang Time - // TS-2000 - SD - Set/Read Break In Delay - // - // 0000-1000 ms (in steps of 50 ms) 0000 is full break in - int local_cw_breakin=cw_keyer_hang_time; - // Limit report value to 1000 for TS 2000 - if(local_cw_breakin > 1000) { local_cw_breakin = 1000; } - if(len <=2) { - if(zzid_flag == 0) { // TS 2000 - sprintf(msg,"SD%04d;",local_cw_breakin); - } else { // ZZ command response - sprintf(msg,"ZZCD%04d;",local_cw_breakin); - } - send_resp(client_sock,msg); - } else { - local_cw_breakin = atoi(&cmd_input[2]); - if(cw_keyer_hang_time <= 1000) { - if(local_cw_breakin==0) { - cw_breakin = 1; - } else { - cw_breakin = 0; - } - cw_keyer_hang_time = local_cw_breakin; - } - } - - } - else if(strcmp(cmd_str,"SH")==0) { - // TS-2000 - SH - Set/read the DSP filter settings - not supported - if(len <=2) { - // send_resp(client_sock,"SH00;"); - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"SI")==0) { - // TS-2000 - SI - Enters the satellite memory name - not supported - } - else if(strcmp(cmd_str,"SL")==0) { - // TS-2000 - SL - Set/read the DSP filter settings - not supported - if(len <=2) { - //send_resp(client_sock,"SL00;"); - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"SM")==0) { - // PiHPSDR - ZZSM - Read SMeter - same range as TS 2000 - // TI-2000 - SM - Read SMETER - // SM0: main receiver, SM1: sub receiver - // Resp= SM0xxxx or SM1yyyy; xxxx between 0000 and 0030, yyyy between 0000 and 0015. - double level=0.0; - - int r=0; - if(cmd_input[2] == '0') { - r=0; - } else if(cmd_input[2] == '1') { - if(receivers==2) { - r=1; - } - } - level = GetRXAMeter(receiver[r]->id, smeter); - - if(r == 0) { - // DL1YCF: In the "main" bar graph, each bar counts 4 dB. - // S9+60 has 30 bars, S9 has 15 bars, S7 has 12 bars, and so on - // since S9 is about -73 dBm, the correct formula for converting - // dBm to bars is 15 + (level+73)/4 or 0.25*level + 33.25. - // The problem is now that S1 has 3 bars, such that 0 bars would - // correspond to S0 - 6dB. If one assumes that S0 corresponds - // to 0 bars, then it follows that the slope is 2 dB per bar - // below S1. This assumption is used in hamlib, and thus followed here. - if (level <= -121.0) { - new_level = (int) round(0.50*level+63.50); // valid up to S1 = -48 dBm - } else { - new_level = (int) round(0.25*level+33.25); // valid if at least S1 - } - // Clip - if(new_level < 0) { new_level = 0; } - if(new_level > 30) { new_level = 30;} - } else { - // DL1YCF: studying the pictures in the TS2000 manual, - // for the "sub" display we have 0-9 small bars for S0 -S9, and in addition 1-6 - // large bars for S9+10, ..., S9+60. So the slope is 6 dB per par - // up to S9, and 10 dB per bar beyond. - if (level <= -73.0) { - new_level = (int) round(0.16667*level+21.16667); // valid up to S9 - } else { - new_level = (int) round(0.1*level+16.3); // valid if at least S9 - } - // Clip - if(new_level < 0) { new_level = 0; } - if(new_level > 15) { new_level = 15;} - } - - if(zzid_flag == 0) { - sprintf(msg,"SM%1c%04d;", - cmd_input[2],new_level); - } else { - sprintf(msg,"ZZSM%1c%04d;", - cmd_input[2],new_level); - } - send_resp(client_sock,msg); - } - - else if(strcmp(cmd_str,"SQ")==0) { - // TS-2000 - SQ - Set/read the squelch level - not supported - // P1 - 0- main, 1=sub - // P2 - 0-255 - float float_sq; - - if(len <=3) { - float_sq = (float) active_receiver->squelch; - float_sq = roundf((float_sq/100.0)*256.0); - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: float_sq=%6.2f\n", - float_sq); - #endif - sprintf(msg,"SQ0%03d;",(int) float_sq); - send_resp(client_sock,msg); - } else { // Set the value - int lcl_sq = atoi(&cmd_input[3]); // Note we skip the first char! - if((lcl_sq >= 0) && (lcl_sq <=255)) { - float_sq = roundf(((float)lcl_sq/256.0)*100); - active_receiver->squelch = (int)float_sq; - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: SetSq float_sq=%6.2f\n", - float_sq); - #endif - - //setSquelch(active_receiver); - g_idle_add(ext_update_squelch,NULL); - g_idle_add(ext_vfo_update,NULL); - } else { - send_resp(client_sock,"?;"); - } - } - } - - else if(strcmp(cmd_str,"SR")==0) { - // TS-2000 - SR - Resets the transceiver - not supported - } - else if(strcmp(cmd_str,"SS")==0) { - // TS-2000 - SS - Set/read Scan pause freq - not supported - if(len <=2) { - //send_resp(client_sock,"SS0;"); - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"ST")==0) { - // TS-2000 - ST - Set/read the multi/ch control freq steps - // PiHPSDR - ZZST - Set/read the multi/ch control freq steps - // SSB/CW/FSK - values 00-03 - // 00: 1KHz, 01: 2.5Khz 02:5KHz 03: 10Khz - // AM/FM mode 00-09 - // 00: 5KHz, - // 01: 6.25KHz, - // 02: 10Khz, - // 03: 12.5Khz, - // 04: 15Khz, - // 05: 20Khz, - // 06: 25KHz - // 07: 30Khz - // 08: 50Khz - // 09: 100Khz - if(zzid_flag == 0) { - int coded_step_val; - entry= (BANDSTACK_ENTRY *) - bandstack_entry_get_current(); - if(len <=2) { - switch(entry->mode) { - case modeLSB: - case modeUSB: - case modeCWL: - case modeCWU: - case modeDIGU: - case modeDIGL: - if(step >0 && step <= 1000) { - coded_step_val = 0; - } else if (step >1000 && step <=2500) { - coded_step_val = 1; - } else if (step >2500 && step <=5000) { - coded_step_val = 2; - } else { - coded_step_val = 3; - } - break; - case modeFMN: - case modeAM: - if(step >0 && step <= 5000) { - coded_step_val = 0; - } else if (step >5000 && step <=6250) { - coded_step_val = 1; - } else if (step >6250 && step <=10000) { - coded_step_val = 2; - } else if (step >10000 && step <=12500) { - coded_step_val = 3; - } else if (step >12500 && step <=15000) { - coded_step_val = 4; - } else if (step >15000 && step <=20000) { - coded_step_val = 5; - } else if (step >20000 && step <=25000) { - coded_step_val = 6; - } else if (step >25000 && step <=30000) { - coded_step_val = 7; - } else if (step >30000 && step <=50000) { - coded_step_val = 8; - } else if (step >50000 && step <=100000) { - coded_step_val = 9; - } else { - coded_step_val = 0; - } - break; - } - sprintf(msg,"ST%02d;",coded_step_val); - send_resp(client_sock,msg); - } else { - coded_step_val = atoi(&cmd_input[2]); - switch(entry->mode) { - case modeLSB: - case modeUSB: - case modeCWL: - case modeCWU: - case modeDIGU: - case modeDIGL: - if(coded_step_val==0) { step = 1000;} - if(coded_step_val==1) { step = 2500;} - if(coded_step_val==2) { step = 5000;} - if(coded_step_val==3) { step = 10000;} - break; - case modeFMN: - case modeAM: - switch(coded_step_val) { - case 0: step = 5000; break; - case 1: step = 6250; break; - case 2: step = 10000; break; - case 3: step = 12500; break; - case 4: step = 15000; break; - case 5: step = 20000; break; - case 6: step = 25000; break; - case 7: step = 30000; break; - case 8: step = 50000; break; - case 9: step = 100000; break; - default: break; // No change if not a valid number - } - default: break; // No change if not a valid number - } - } - } else { - // Pi HPSDR handling - if(len <= 2) { - sprintf(msg,"ZZST%06lld;", step); - send_resp(client_sock,msg); - } else { - int okay= 0; - work_int = atoi(&cmd_input[2]); - switch(work_int) { - case 100000: okay = 1; break; - case 50000: okay = 1; break; - case 30000: okay = 1; break; - case 25000: okay = 1; break; - case 20000: okay = 1; break; - case 15000: okay = 1; break; - case 12500: okay = 1; break; - case 10000: okay = 1; break; - case 9000: okay = 1; break; - case 6250: okay = 1; break; - case 5000: okay = 1; break; - case 2500: okay = 1; break; - case 1000: okay = 1; break; - case 500: okay = 1; break; - case 250: okay = 1; break; - case 100: okay = 1; break; - case 50: okay = 1; break; - case 10: okay = 1; break; - case 1: okay = 1; break; - default: okay = 0; break; - } - if(okay == 0) { - fprintf(stderr,"RIGCTL: ZZST ERROR - illegal step val=%d\n",work_int); - send_resp(client_sock,"?;"); - } else { - step = work_int; - } - } - } - g_idle_add(ext_vfo_update,NULL); - } - else if((strcmp(cmd_str,"SU")==0) && (zzid_flag == 0)) { - // TS-2000 - SU - Set/read the scan pause freq - not supported - if(len <=2) { - //send_resp(client_sock,"SU00000000000;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"SV")==0) && (zzid_flag == 0)) { - // TS-2000 - SV - Execute the memory transfer function - not supported - } - else if((strcmp(cmd_str,"TC")==0) && (zzid_flag == 0)) { - // TS-2000 - TC - Set/read the internal TNC mode - not supported - if(len <=2) { - //send_resp(client_sock,"TC00;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"TD")==0) && (zzid_flag == 0)) { - // TS-2000 - TD - Sends the DTMF memory channel - not supported - } - else if((strcmp(cmd_str,"TI")==0) && (zzid_flag == 0)) { - // TS-2000 - TI - Reads the TNC LED status - not supported - if(len <=2) { - //send_resp(client_sock,"TI00;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"TN")==0) && (zzid_flag == 0)) { - // TS-2000 - TN - Set/Read sub tone freq - not supported - if(len <=2) { - //send_resp(client_sock,"TN00;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"TO")==0) && (zzid_flag == 0)) { - // TI-2000 - TO - Set/Read tone function - not supported - if(len <=2) { - //send_resp(client_sock,"TO0;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"TS")==0) && (zzid_flag == 0)) { - // TI-2000 - TS - Set/Read TF Set function status - if(len <=2) { - //send_resp(client_sock,"TS0;"); - send_resp(client_sock,"?;"); - } - } - else if(strcmp(cmd_str,"TX")==0) { - // TS-2000 - TX - Key Xmitter - P1 - transmit on main/sub freq - // PiHPSDR - ZZTX - Key Xmitter - P1 - transmit on main/sub freq - if(!((vfo[active_receiver->id].mode == modeCWL) || - (vfo[active_receiver->id].mode == modeCWU))) { - //*if(len >=3) { - // K5JAE: The TS 2000 real hardware does not respond - // to this command, thus hamlib is not expecting response. - //send_resp(client_sock,"TX0;"); */ - mox_state = 1; - g_idle_add(ext_mox_update,(gpointer)(long)mox_state); - g_idle_add(ext_vfo_update,NULL); - } else { - g_idle_add(ext_mox_update,(gpointer)(long)1); // Turn on External MOX - } - } - else if(strcmp(cmd_str,"TY")==0) { - // TI-2000 - TY -- Set/Read uP firmware type - if(len <=2) { - send_resp(client_sock,"TY000;"); - } - } - else if((strcmp(cmd_str,"UA")==0) && (zzid_flag == 1)) { - // PiHPSDR - ZZUA - Xvrt Set/Read - // RW P1 - 1 Char - Entry number 0-7 - // W P1 - Disable PA - 1 char - // W P2 - 15 Char - Title - 16th char with last being '\0' - // W P3 - 11 Chars - Min Freq HZ - // W P4 - 11 Chars - Max Freq HZ - // W P5 - 11 Chars - Low Freq HZ - char lcl_buf[] = " "; - char tempc; - if(len<=3) { - work_int = atoi(&cmd_input[2]); - if((work_int >=0) && (work_int <=7)) { - BAND *xvtr=band_get_band(BANDS+work_int); - strcpy(lcl_buf,xvtr->title); - lcl_buf[strlen(lcl_buf)] = ' '; // Replace the last entry with ' '; - lcl_buf[15] = '\0'; - sprintf(msg,"ZZUA%1d%1d%s%011lld%011lld%011lld;",work_int,xvtr->disablePA,lcl_buf, - xvtr->frequencyMin,xvtr->frequencyMax,xvtr->frequencyLO); - send_resp(client_sock,msg); - } - } else if(len==52) { - - tempc = cmd_input[3]; - cmd_input[3] = '\0'; - work_int = atoi(&cmd_input[2]); - cmd_input[3] = tempc; - if((work_int >=0) && (work_int <=7)) { - - BAND *xvtr=band_get_band(BANDS+work_int); - tempc = cmd_input[4]; - cmd_input[4]='\0'; - xvtr->disablePA = atoi(&cmd_input[3]); - cmd_input[4]=tempc; - - /* Get the title of the XVTR */ - tempc = cmd_input[19]; - cmd_input[19] = '\0'; - strncpy(xvtr->title,&cmd_input[4],16); - cmd_input[19] = tempc; - - /* Pull out the Min freq */ - tempc = cmd_input[30]; - cmd_input[30]='\0'; - xvtr->frequencyMin = (long long) atoi(&cmd_input[19]); - cmd_input[30] = tempc; - - /* Pull out the Max freq */ - tempc = cmd_input[41]; - cmd_input[41]='\0'; - xvtr->frequencyMax = (long long) atoi(&cmd_input[30]); - cmd_input[41] = tempc; - - - /* Pull out the LO freq */ - xvtr->frequencyLO = (long long) atoi(&cmd_input[41]); - } else { - fprintf(stderr,"RIGCTL: ERROR ZZUA - incorrect length command received=%d",len); - send_resp(client_sock,"?;"); - } - } - } - else if((strcmp(cmd_str,"UL")==0) && (zzid_flag == 0)) { - // TS-2000 - UL - Detects the PLL unlock status - not supported - if(len <=2) { - //send_resp(client_sock,"UL0;"); - send_resp(client_sock,"?;"); - } - } - else if((strcmp(cmd_str,"UP")==0) && (zzid_flag == 0)) { - // TS-2000 - UP - Emulates the mic up key - } - else if(strcmp(cmd_str,"VD")==0) { - // TS-2000 - VD - Sets/Reads VOX delay time - 0000-3000ms in steps of 150 - // PiHPSDR - ZZVD - Sets/Reads VOX Hang time - // We want vox_hang variable in Pi HPSDR - // Max value in variable in ms... so 250 = 250ms - if(len <=2) { - work_int = (int) vox_hang; - if(zzid_flag == 0) { - sprintf(msg,"VD%04d;",work_int); - } else { - sprintf(msg,"ZZVD%04d;",work_int); - } - send_resp(client_sock,msg); - } else { - work_int = atoi(&cmd_input[2]); - // Bounds check for legal values for Pi HPSDR - if(work_int > 1000) { work_int = 1000; } - if(work_int < 0) { work_int = 0; } - vox_hang = (double) work_int; - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: Vox hang=%0.20f\n",vox_hang); - #endif - } - } - else if(strcmp(cmd_str,"VG")==0) { - // TI-2000 - VG - Sets/Reads VOX gain 000-009 - // PiHPSDR - ZZVG - Set/Read VOX Threshold - 0-1000 - // We want vox_threshold variable in Pi HPSDR - // Max value in variable 0.1 - // 3 char 000-009 valid ranges - if(len <=2) { - if(zzid_flag == 0) { - work_int = (int) ((vox_threshold) * 100.0); - sprintf(msg,"VG00%1d;",work_int); - } else { - work_int = (int) ((vox_threshold) * 1000.0); - sprintf(msg,"ZZVG%04d;",work_int); - } - send_resp(client_sock,msg); - } else { - work_int = atoi(&cmd_input[2]); - if((work_int >=0) && (work_int<=9)) { - if(zzid_flag == 0) { - // Set the threshold here - vox_threshold = ((double) work_int)/10.0; - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: Vox thresh=%0.20f\n",vox_threshold); - #endif - } else { - vox_threshold = ((double) work_int)/1000.0; - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: Vox thresh=%0.20f\n",vox_threshold); - #endif - } - } else { - send_resp(client_sock,"?;"); - } - } - } - else if((strcmp(cmd_str,"VR")==0) && (zzid_flag == 0)) { - // TS-2000 - VR - Emulates the voice 1/2 key - not supported - } - else if(strcmp(cmd_str,"VX")==0) { - // TS-2000 - VX - Sets/reads vox f(x) state - // PiHPSDR - ZZVX - Set/Read VOX enabled - if(len <=2) { - if(zzid_flag == 0 ) { - sprintf(msg,"VX%1d;",vox_enabled); - } else { - sprintf(msg,"ZZVX%1d;",vox_enabled); - } - send_resp(client_sock,msg); - } else { - work_int = atoi(&cmd_input[2]); - if(work_int==1) { vox_enabled = 1; vox= 1;} - if(work_int!=1) { vox_enabled = 0; vox=0; } - } - } - else if((strcmp(cmd_str,"XC")==0) && (zzid_flag == 1)) { - // PiHPSDR - ZZXC - Terminate "CW" via ZZXO/ZZXT (Key up and MOX off) - cw_hold_key(0); - g_idle_add(ext_mox_update,(gpointer)(long)0); - CAT_cw_is_active=0; - } - else if((strcmp(cmd_str,"XI")==0) && (zzid_flag == 1)) { - // PiHPSDR - ZZXI - Prepeare for "CW" via ZZXO/ZZXT (MOX on) - CAT_cw_is_active=1; - g_idle_add(ext_mox_update,(gpointer)(long)1); - } - else if((strcmp(cmd_str,"XO")==0) && (zzid_flag == 1)) { - // PiHPSDR - ZZXO - Turn CW Note off when in CW mode - cw_hold_key(0); - } - else if(strcmp(cmd_str,"XT")==0) { - if(zzid_flag == 0 ) { - // TS-2000 - XT - Sets/reads the XIT f(x) state - not supported - if(len <=2) { - //send_resp(client_sock,"XT0;"); - send_resp(client_sock,"?;"); - } - } else { - // PiHPSDR - ZZXT - Turn CW Note on when in CW mode - cw_hold_key(1); - } - } - else if((strcmp(cmd_str,"XX")==0) && (zzid_flag == 0)) { // - // Format RL01234: First dig 0=neg, 1=pos number - // 1-4- digital offset in hertz. - if(len > 4) { // It is set instead of a read - digl_pol = (cmd_input[2]=='0') ? -1 : 1; - digl_offset = atoi(&cmd_input[3]); - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL:RL set %d %d\n",digl_pol,digl_offset); - #endif - } else { - if(digl_pol==1) { // Nah - its a read - sprintf(msg,"RL1%04d;",0); - } else { - sprintf(msg,"RL0%04d;",0); - } - send_resp(client_sock,msg); - #ifdef RIGCTL_DEBUG - fprintf(stderr,":%s\n",msg); - #endif - } - } - else if(strcmp(cmd_str,"XY")==0) { // set/read RTTY DIGL offset frequency - Not available - just store values - // Format RL01234: First dig 0=neg, 1=pos number - // 1-4- digital offset in hertz. - if(len > 4) { // It is set instead of a read - digl_pol = (cmd_input[2]=='0') ? -1 : 1; - digl_offset = atoi(&cmd_input[3]); - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL:RL set %d %d\n",digl_pol,digl_offset); - #endif - } else { - if(digl_pol==1) { // Nah - its a read - sprintf(msg,"RL1%04d;",0); - } else { - sprintf(msg,"RL0%04d;",0); - } - send_resp(client_sock,msg); - #ifdef RIGCTL_DEBUG - fprintf(stderr,":%s\n",msg); - #endif - } - } - else { - fprintf(stderr,"RIGCTL: UNKNOWN=%s\n",cmd_str); - } + +gboolean parse_extended_cmd (char *command,CLIENT *client) { + gboolean implemented=TRUE; + char reply[256]; + reply[0]='\0'; + switch(command[2]) { + case 'A': //ZZAx + switch(command[3]) { + case 'A': //ZZAA + implemented=FALSE; + break; + case 'B': //ZZAB + implemented=FALSE; + break; + case 'C': //ZZAC + // sets or reads the Step Size + if(command[4]==';') { + // read the step size + int i=0; + for(i=0;i<=14;i++) { + if(steps[i]==step) break; + } + if(i<=14) { + // send reply back + sprintf(reply,"ZZAC%02d;",i); + send_resp(client->fd,reply) ; + } + } else if(command[6]==';') { + // set the step size + int i=atoi(&command[4]) ; + if(i>=0 && i<=14) { + step=steps[i]; + vfo_update(); + } + } else { + } + break; + case 'D': //ZZAD + // move VFO A down by selected step + if(command[6]==';') { + int step_index=atoi(&command[4]); + long long hz=0; + if(step_index>=0 && step_index<=14) { + hz=(long long)steps[step_index]; + } + if(hz!=0LL) { + vfo_id_move(VFO_A,-hz,FALSE); + } + } else { + } + break; + case 'E': //ZZAE + // move VFO A down nn tune steps + if(command[6]==';') { + int steps=atoi(&command[4]); + vfo_id_step(VFO_A,-steps); + } + break; + case 'F': //ZZAF + // move VFO A up nn tune steps + if(command[6]==';') { + int steps=atoi(&command[4]); + vfo_id_step(VFO_A,steps); + } + break; + case 'G': //ZZAG + // read/set audio gain + if(command[4]==';') { + // send reply back + sprintf(reply,"ZZAG%03d;",(int)(active_receiver->volume*100.0)); + send_resp(client->fd,reply) ; + } else { + int gain=atoi(&command[4]); + active_receiver->volume=(double)gain/100.0; + update_af_gain(); + } + break; + case 'I': //ZZAI + implemented=FALSE; + break; + case 'P': //ZZAP + implemented=FALSE; + break; + case 'R': //ZZAR + // read/set RX0 AGC Threshold + if(command[4]==';') { + // send reply back + sprintf(reply,"ZZAR%+04d;",(int)(receiver[0]->agc_gain)); + send_resp(client->fd,reply) ; + } else { + int threshold=atoi(&command[4]); + set_agc_gain(VFO_A,(double)threshold); + } + break; + case 'S': //ZZAS + // read/set RX1 AGC Threshold + if(receivers==2) { + if(command[4]==';') { + // send reply back + sprintf(reply,"ZZAS%+04d;",(int)(receiver[1]->agc_gain)); + send_resp(client->fd,reply) ; + } else { + int threshold=atoi(&command[4]); + set_agc_gain(VFO_B,(double)threshold); + } + } + break; + case 'T': //ZZAT + implemented=FALSE; + break; + case 'U': //ZZAU + // move VFO A up by selected step + if(command[6]==';') { + int step_index=atoi(&command[4]); + long long hz=0; + if(step_index>=0 && step_index<=14) { + hz=(long long)steps[step_index]; + } + if(hz!=0LL) { + vfo_id_move(VFO_A,hz,FALSE); + } + } else { + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'B': //ZZBx + switch(command[3]) { + case 'A': //ZZBA + // move RX2 down one band + if(command[4]==';') { + if(receivers==2) { + band_minus(receiver[1]->id); + } + } + break; + case 'B': //ZZBB + // move RX2 up one band + if(command[4]==';') { + if(receivers==2) { + band_plus(receiver[1]->id); + } + } + break; + case 'D': //ZZBD + // move RX1 down one band + if(command[4]==';') { + band_minus(receiver[0]->id); + } + break; + case 'E': //ZZBE + // move VFO B down nn tune steps + if(command[6]==';') { + int steps=atoi(&command[4]); + vfo_id_step(VFO_B,-steps); + } + + break; + case 'F': //ZZBF + // move VFO B up nn tune steps + if(command[6]==';') { + int steps=atoi(&command[4]); + vfo_id_step(VFO_B,+steps); + } + break; + case 'G': //ZZBG + implemented=FALSE; + break; + case 'I': //ZZBI + implemented=FALSE; + break; + case 'M': //ZZBM + // move VFO B down by selected step + if(command[6]==';') { + int step_index=atoi(&command[4]); + long long hz=0; + if(step_index>=0 && step_index<=14) { + hz=(long long)steps[step_index]; + } + if(hz!=0LL) { + vfo_id_move(VFO_B,-hz,FALSE); + } + } else { + } + + break; + case 'P': //ZZBP + // move VFO B up by selected step + if(command[6]==';') { + int step_index=atoi(&command[4]); + long long hz=0; + if(step_index>=0 && step_index<=14) { + hz=(long long)steps[step_index]; + } + if(hz!=0LL) { + vfo_id_move(VFO_B,hz,FALSE); + } + } else { + } + break; + case 'R': //ZZBR + implemented=FALSE; + break; + case 'S': //ZZBS + // set/read RX1 band switch + if(command[4]==';') { + int b; + switch(vfo[VFO_A].band) { + case band136: + b=136; + break; + case band472: + b=472; + break; + case band160: + b=160; + break; + case band80: + b=80; + break; + case band60: + b=60; + break; + case band40: + b=40; + break; + case band30: + b=30; + break; + case band20: + b=20; + break; + case band17: + b=17; + break; + case band15: + b=15; + break; + case band12: + b=12; + break; + case band10: + b=10; + break; + case band6: + b=6; + break; + case bandGen: + b=888; + break; + case bandWWV: + b=999; + break; + default: + b=20; + break; + } + sprintf(reply,"ZZBS%03d;",b); + send_resp(client->fd,reply) ; + } else if(command[7]==';') { + int band=band20; + int b=atoi(&command[4]); + switch(b) { + case 136: + band=band136; + break; + case 472: + band=band472; + break; + case 160: + band=band160; + break; + case 80: + band=band80; + break; + case 60: + band=band60; + break; + case 40: + band=band40; + break; + case 30: + band=band30; + break; + case 20: + band=band20; + break; + case 17: + band=band17; + break; + case 15: + band=band15; + break; + case 12: + band=band12; + break; + case 10: + band=band10; + break; + case 6: + band=band6; + break; + case 888: + band=bandGen; + break; + case 999: + band=bandWWV; + break; + } + vfo_band_changed(VFO_A,band); + } + break; + case 'T': //ZZBT + // set/read RX2 band switch + break; + case 'U': //ZZBU + // move RX1 up one band + if(command[4]==';') { + band_plus(receiver[0]->id); + } + break; + case 'Y': //ZZBY + // closes console (ignored) + break; + default: + implemented=FALSE; + break; + } + break; + case 'C': //ZZCx + switch(command[3]) { + case 'B': //ZZCB + implemented=FALSE; + break; + case 'D': //ZZCD + implemented=FALSE; + break; + case 'F': //ZZCF + implemented=FALSE; + break; + case 'I': //ZZCI + implemented=FALSE; + break; + case 'L': //ZZCL + implemented=FALSE; + break; + case 'M': //ZZCM + implemented=FALSE; + break; + case 'N': //ZZCN + // set/read VFO A CTUN + if(command[4]==';') { + // return the CTUN status + sprintf(reply,"ZZCN%d;",vfo[VFO_A].ctun); + send_resp(client->fd,reply) ; + } else if(command[5]==';') { + int state=atoi(&command[4]); + ctun_update(VFO_A,state); + vfo_update(); + } + break; + case 'O': //ZZCO + // set/read VFO B CTUN + if(command[4]==';') { + // return the CTUN status + sprintf(reply,"ZZCO%d;",vfo[VFO_B].ctun); + send_resp(client->fd,reply) ; + } else if(command[5]==';') { + int state=atoi(&command[4]); + ctun_update(VFO_B,state); + vfo_update(); + } + break; + case 'P': //ZZCP + // set/read compander + if(command[4]==';') { + sprintf(reply,"ZZCP%d;",0); + send_resp(client->fd,reply) ; + } else if(command[5]==';') { + // ignore + } + break; + case 'S': //ZZCS + implemented=FALSE; + break; + case 'T': //ZZCT + implemented=FALSE; + break; + case 'U': //ZZCU + implemented=FALSE; + break; + default: + implemented=FALSE; + break; + } + break; + case 'D': //ZZDx + switch(command[3]) { + case 'A': //ZZDA + break; + case 'B': //ZZDB + // set/read RX Reference + if(command[4]==';') { + sprintf(reply,"ZZDB%d;",0); // currently always 0 + send_resp(client->fd,reply) ; + } else if(command[5]==';') { + // ignore + } + break; + case 'C': //ZZDC + // set/get diversity gain + if(command[4]==';') { + sprintf(reply,"ZZDC%04d;",(int)div_gain); + send_resp(client->fd,reply) ; + } else if(command[8]==';') { + // ignore + } + break; + case 'D': //ZZDD + // set/get diversity phase + if(command[4]==';') { + sprintf(reply,"ZZDD%04d;",(int)div_phase); + send_resp(client->fd,reply) ; + } else if(command[8]==';') { + // ignore + } + case 'E': //ZZDE + implemented=FALSE; + break; + case 'F': //ZZDF + implemented=FALSE; + break; + case 'M': //ZZDM + // set/read Display Mode + if(command[4]==';') { + int v=0; + if(active_receiver->display_waterfall) { + v=8; + } else { + v=2; + } + sprintf(reply,"ZZDM%d;",v); + send_resp(client->fd,reply) ; + } else { + } + break; + case 'N': //ZZDN + // set/read waterfall low + if(command[4]==';') { + sprintf(reply,"ZZDN%+4d;",active_receiver->waterfall_low); + send_resp(client->fd,reply) ; + } else { + } + break; + case 'O': //ZZDO + // set/read waterfall high + if(command[4]==';') { + sprintf(reply,"ZZDO%+4d;",active_receiver->waterfall_high); + send_resp(client->fd,reply) ; + } else { + } + break; + case 'P': //ZZDP + // set/read panadapter high + if(command[4]==';') { + sprintf(reply,"ZZDP%+4d;",active_receiver->panadapter_high); + send_resp(client->fd,reply) ; + } else { + } + break; + case 'Q': //ZZDQ + // set/read panadapter low + if(command[4]==';') { + sprintf(reply,"ZZDQ%+4d;",active_receiver->panadapter_low); + send_resp(client->fd,reply) ; + } else { + } + break; + case 'R': //ZZDR + // set/read panadapter step + if(command[4]==';') { + sprintf(reply,"ZZDR%2d;",active_receiver->panadapter_step); + send_resp(client->fd,reply) ; + } else { + } + break; + case 'U': //ZZDU + implemented=FALSE; + break; + case 'X': //ZZDX + implemented=FALSE; + break; + case 'Y': //ZZDY + implemented=FALSE; + break; + default: + implemented=FALSE; + break; + } + break; + case 'E': //ZZEx + switch(command[3]) { + case 'A': //ZZEA + // set/read rx equalizer values + if(command[4]==';') { + sprintf(reply,"ZZEA%03d%03d%03d%03d%03d00000000000000000000;",3,rx_equalizer[0],rx_equalizer[1],rx_equalizer[2],rx_equalizer[3]); + send_resp(client->fd,reply) ; + } else if(command[37]==';') { + char temp[4]; + temp[3]='\0'; + strncpy(temp,&command[4],3); + int bands=atoi(temp); + if(bands==3) { + strncpy(temp,&command[7],3); + rx_equalizer[0]=atoi(temp); + strncpy(temp,&command[10],3); + rx_equalizer[1]=atoi(temp); + strncpy(temp,&command[13],3); + rx_equalizer[2]=atoi(temp); + } else { + } + } else { + } + break; + case 'B': //ZZEB + // set/read tx equalizer values + if(command[4]==';') { + sprintf(reply,"ZZEB%03d%03d%03d%03d%03d00000000000000000000;",3,tx_equalizer[0],tx_equalizer[1],tx_equalizer[2],tx_equalizer[3]); + send_resp(client->fd,reply) ; + } else if(command[37]==';') { + char temp[4]; + temp[3]='\0'; + strncpy(temp,&command[4],3); + int bands=atoi(temp); + if(bands==3) { + strncpy(temp,&command[7],3); + tx_equalizer[0]=atoi(temp); + strncpy(temp,&command[10],3); + tx_equalizer[1]=atoi(temp); + strncpy(temp,&command[13],3); + tx_equalizer[2]=atoi(temp); + } else { + } + } else { + } + break; + case 'M': //ZZEM + implemented=FALSE; + break; + case 'R': //ZZER + // set/read rx equalizer + if(command[4]==';') { + sprintf(reply,"ZZER%d;",enable_rx_equalizer); + send_resp(client->fd,reply) ; + } else if(command[5]==';') { + enable_rx_equalizer=atoi(&command[4]); + } else { + } + break; + case 'T': //ZZET + // set/read tx equalizer + if(command[4]==';') { + sprintf(reply,"ZZET%d;",enable_tx_equalizer); + send_resp(client->fd,reply) ; + } else if(command[5]==';') { + enable_tx_equalizer=atoi(&command[4]); + } else { + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'F': //ZZFx + switch(command[3]) { + case 'A': //ZZFA + // set/read VFO-A frequency + if(command[4]==';') { + if(vfo[VFO_A].ctun) { + sprintf(reply,"ZZFA%011lld;",vfo[VFO_A].ctun_frequency); + } else { + sprintf(reply,"ZZFA%011lld;",vfo[VFO_A].frequency); + } + send_resp(client->fd,reply) ; + } else if(command[15]==';') { + long long f=atoll(&command[4]); + local_set_frequency(VFO_A,f); + vfo_update(); + } + break; + case 'B': //ZZFB + // set/read VFO-B frequency + if(command[4]==';') { + if(vfo[VFO_B].ctun) { + sprintf(reply,"ZZFB%011lld;",vfo[VFO_B].ctun_frequency); + } else { + sprintf(reply,"ZZFB%011lld;",vfo[VFO_B].frequency); + } + send_resp(client->fd,reply) ; + } else if(command[15]==';') { + long long f=atoll(&command[4]); + local_set_frequency(VFO_B,f); + vfo_update(); + } + break; + case 'D': //ZZFD + // set/read deviation + if(command[4]==';') { + sprintf(reply,"ZZFD%d;",active_receiver->deviation==2500?0:1); + send_resp(client->fd,reply) ; + } else if(command[5]==';') { + int d=atoi(&command[4]); + if(d==0) { + active_receiver->deviation=2500; + } else if(d==1) { + active_receiver->deviation=5000; + } else { + } + vfo_update(); + } + break; + case 'H': //ZZFH + // set/read RX1 filter high + if(command[4]==';') { + sprintf(reply,"ZZFH%05d;",receiver[0]->filter_high); + send_resp(client->fd,reply) ; + } else if(command[9]==';') { + int fh=atoi(&command[4]); + fh=fmin(9999,fh); + fh=fmax(-9999,fh); + // make sure filter is filterVar1 + if(vfo[VFO_A].filter!=filterVar1) { + vfo_filter_changed(filterVar1); + } + FILTER *mode_filters=filters[vfo[VFO_A].mode]; + FILTER *filter=&mode_filters[filterVar1]; + filter->high=fh; + vfo_filter_changed(filterVar1); + } + break; + case 'I': //ZZFI + // set/read RX1 DSP receive filter + if(command[4]==';') { + sprintf(reply,"ZZFI%02d;",vfo[VFO_A].filter); + send_resp(client->fd,reply) ; + } else if(command[6]==';') { + int filter=atoi(&command[4]); + // update RX1 filter + } + break; + case 'J': //ZZFJ + // set/read RX2 DSP receive filter + if(command[4]==';') { + sprintf(reply,"ZZFJ%02d;",vfo[VFO_B].filter); + send_resp(client->fd,reply) ; + } else if(command[6]==';') { + int filter=atoi(&command[4]); + // update RX2 filter + } + break; + case 'L': //ZZFL + // set/read RX1 filter low + if(command[4]==';') { + sprintf(reply,"ZZFL%05d;",receiver[0]->filter_low); + send_resp(client->fd,reply) ; + } else if(command[9]==';') { + int fl=atoi(&command[4]); + fl=fmin(9999,fl); + fl=fmax(-9999,fl); + // make sure filter is filterVar1 + if(vfo[VFO_A].filter!=filterVar1) { + vfo_filter_changed(filterVar1); + } + FILTER *mode_filters=filters[vfo[VFO_A].mode]; + FILTER *filter=&mode_filters[filterVar1]; + filter->low=fl; + vfo_filter_changed(filterVar1); + } + break; + case 'M': //ZZFM + implemented=FALSE; + break; + case 'R': //ZZFR + implemented=FALSE; + break; + case 'S': //ZZFS + implemented=FALSE; + break; + case 'V': //ZZFV + implemented=FALSE; + break; + case 'W': //ZZFW + implemented=FALSE; + break; + case 'X': //ZZFX + implemented=FALSE; + break; + case 'Y': //ZZFY + implemented=FALSE; + break; + default: + implemented=FALSE; + break; + } + break; + case 'G': //ZZGx + switch(command[3]) { + case 'E': //ZZGE + implemented=FALSE; + break; + case 'L': //ZZGL + implemented=FALSE; + break; + case 'T': //ZZGT + // set/read RX1 AGC + if(command[4]==';') { + sprintf(reply,"ZZGT%d;",receiver[0]->agc); + send_resp(client->fd,reply) ; + } else if(command[5]==';') { + int agc=atoi(&command[4]); + // update RX1 AGC + receiver[0]->agc=agc; + vfo_update(); + } + break; + case 'U': //ZZGU + // set/read RX2 AGC + if(command[4]==';') { + sprintf(reply,"ZZGU%d;",receiver[1]->agc); + send_resp(client->fd,reply) ; + } else if(command[5]==';') { + int agc=atoi(&command[4]); + // update RX2 AGC + receiver[1]->agc=agc; + vfo_update(); + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'H': //ZZHx + switch(command[3]) { + case 'A': //ZZHA + implemented=FALSE; + break; + case 'R': //ZZHR + implemented=FALSE; + break; + case 'T': //ZZHT + implemented=FALSE; + break; + case 'U': //ZZHU + implemented=FALSE; + break; + case 'V': //ZZHV + implemented=FALSE; + break; + case 'W': //ZZHW + implemented=FALSE; + break; + case 'X': //ZZHX + implemented=FALSE; + break; + default: + implemented=FALSE; + break; + } + break; + case 'I': //ZZIx + switch(command[3]) { + case 'D': //ZZID + strcpy(reply,"ZZID240;"); + send_resp(client->fd,reply) ; + break; + case 'F': //ZZIF + implemented=FALSE; + break; + case 'O': //ZZIO + implemented=FALSE; + break; + case 'S': //ZZIS + implemented=FALSE; + break; + case 'T': //ZZIT + implemented=FALSE; + break; + case 'U': //ZZIU + implemented=FALSE; + break; + default: + implemented=FALSE; + break; + } + break; + case 'K': //ZZKx + switch(command[3]) { + case 'M': //ZZIM + implemented=FALSE; + break; + case 'O': //ZZIO + implemented=FALSE; + break; + case 'S': //ZZIS + implemented=FALSE; + break; + case 'Y': //ZZIY + implemented=FALSE; + break; + default: + implemented=FALSE; + break; + } + break; + case 'L': //ZZLx + switch(command[3]) { + case 'A': //ZZLA + // read/set RX0 gain + if(command[4]==';') { + // send reply back + sprintf(reply,"ZZLA%03d;",(int)(receiver[0]->volume*100.0)); + send_resp(client->fd,reply) ; + } else { + int gain=atoi(&command[4]); + receiver[0]->volume=(double)gain/100.0; + update_af_gain(); + } + break; + case 'B': //ZZLB + implemented=FALSE; + break; + case 'C': //ZZLC + // read/set RX1 gain + if(receivers==2) { + if(command[4]==';') { + // send reply back + sprintf(reply,"ZZLC%03d;",(int)(receiver[1]->volume*100.0)); + send_resp(client->fd,reply) ; + } else { + int gain=atoi(&command[4]); + receiver[1]->volume=(double)gain/100.0; + update_af_gain(); + } + } + break; + case 'D': //ZZLD + implemented=FALSE; + break; + case 'E': //ZZLE + implemented=FALSE; + break; + case 'F': //ZZLF + implemented=FALSE; + break; + case 'G': //ZZLG + implemented=FALSE; + break; + case 'H': //ZZLH + implemented=FALSE; + break; + case 'I': //ZZLI + if(transmitter!=NULL) { + if(command[4]==';') { + // send reply back + sprintf(reply,"ZZLI%d;",transmitter->puresignal); + send_resp(client->fd,reply) ; + } else { + int ps=atoi(&command[4]); + transmitter->puresignal=ps; + } + vfo_update(); + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'M': //ZZMx + switch(command[3]) { + case 'A': //ZZMA + implemented=FALSE; + break; + case 'B': //ZZMB + implemented=FALSE; + break; + case 'D': //ZZMD + // set/read RX1 operating mode + if(command[4]==';') { + sprintf(reply,"ZZMD%02d;",vfo[VFO_A].mode); + send_resp(client->fd,reply); + } else if(command[6]==';') { + vfo_mode_changed(atoi(&command[4])); + } + break; + case 'E': //ZZME + // set/read RX2 operating mode + if(command[4]==';') { + sprintf(reply,"ZZMD%02d;",vfo[VFO_B].mode); + send_resp(client->fd,reply); + } else if(command[6]==';') { + vfo_mode_changed(atoi(&command[4])); + } + break; + case 'G': //ZZMG + // set/read mic gain + if(command[4]==';') { + sprintf(reply,"ZZMG%03d;",(int)mic_gain); + send_resp(client->fd,reply); + } else if(command[7]==';') { + mic_gain=(double)atoi(&command[4]); + } + break; + case 'L': //ZZML + // read DSP modes and indexes + if(command[4]==';') { + sprintf(reply,"ZZML LSB00: USB01: DSB02: CWL03: CWU04: FMN05: AM06:DIGU07:SPEC08:DIGL09: SAM10: DRM11;"); + send_resp(client->fd,reply); + } + break; + case 'N': //ZZMN + // read Filter Names and indexes + if(command[6]==';') { + int mode=atoi(&command[4])-1; + FILTER *f=filters[mode]; + sprintf(reply,"ZZMN"); + char temp[32]; + for(int i=0;ifd,reply); + } + break; + case 'O': //ZZMO + // set/read MON status + if(command[4]==';') { + sprintf(reply,"ZZMO%d;",0); + send_resp(client->fd,reply); + } + break; + case 'R': //ZZMR + // set/read RX Meter mode + if(command[4]==';') { + sprintf(reply,"ZZMR%d;",smeter+1); + send_resp(client->fd,reply); + } else if(command[5]==';') { + smeter=atoi(&command[4])-1; + } + break; + case 'S': //ZZMS + implemented=FALSE; + break; + case 'T': //ZZMT + if(command[4]==';') { + sprintf(reply,"ZZMT%02d;",1); // forward power + send_resp(client->fd,reply); + } else { + } + break; + case 'U': //ZZMU + implemented=FALSE; + break; + case 'V': //ZZMV + implemented=FALSE; + break; + case 'W': //ZZMW + implemented=FALSE; + break; + case 'X': //ZZMX + implemented=FALSE; + break; + case 'Y': //ZZMY + implemented=FALSE; + break; + case 'Z': //ZZMZ + implemented=FALSE; + break; + default: + implemented=FALSE; + break; + + } + break; + case 'N': //ZZNx + switch(command[3]) { + case 'A': //ZZNA + // set/read RX1 NB1 + if(command[4]==';') { + sprintf(reply,"ZZNA%d;",receiver[0]->nb); + send_resp(client->fd,reply); + } else if(command[5]==';') { + receiver[0]->nb=atoi(&command[4]); + if(receiver[0]->nb) { + receiver[0]->nb2=0; + } + update_noise(); + } + break; + case 'B': //ZZNB + // set/read RX1 NB2 + if(command[4]==';') { + sprintf(reply,"ZZNB%d;",receiver[0]->nb2); + send_resp(client->fd,reply); + } else if(command[5]==';') { + receiver[0]->nb2=atoi(&command[4]); + if(receiver[0]->nb2) { + receiver[0]->nb=0; + } + update_noise(); + } + break; + case 'C': //ZZNC + // set/read RX2 NB1 + if(command[4]==';') { + sprintf(reply,"ZZNC%d;",receiver[1]->nb); + send_resp(client->fd,reply); + } else if(command[5]==';') { + receiver[1]->nb=atoi(&command[4]); + if(receiver[1]->nb) { + receiver[1]->nb2=0; + } + update_noise(); + } + break; + case 'D': //ZZND + // set/read RX2 NB2 + if(command[4]==';') { + sprintf(reply,"ZZND%d;",receiver[1]->nb2); + send_resp(client->fd,reply); + } else if(command[5]==';') { + receiver[1]->nb2=atoi(&command[4]); + if(receiver[1]->nb2) { + receiver[1]->nb=0; + } + update_noise(); + } + break; + case 'L': //ZZNL + // set/read NB1 threshold + implemented=FALSE; + break; + case 'M': //ZZNM + // set/read NB2 threshold + implemented=FALSE; + break; + case 'N': //ZZNN + // set/read RX1 SNB status + if(command[4]==';') { + sprintf(reply,"ZZNN%d;",receiver[0]->snb); + send_resp(client->fd,reply); + } else if(command[5]==';') { + receiver[0]->snb=atoi(&command[4]); + update_noise(); + } + break; + case 'O': //ZZNO + // set/read RX2 SNB status + if(command[4]==';') { + sprintf(reply,"ZZNO%d;",receiver[1]->snb); + send_resp(client->fd,reply); + } else if(command[5]==';') { + receiver[1]->snb=atoi(&command[4]); + update_noise(); + } + break; + case 'R': //ZZNR + // set/read RX1 NR + if(command[4]==';') { + sprintf(reply,"ZZNR%d;",receiver[0]->nr); + send_resp(client->fd,reply); + } else if(command[5]==';') { + receiver[0]->nr=atoi(&command[4]); + if(receiver[0]->nr) { + receiver[0]->nr2=0; + } + update_noise(); + } + break; + case 'S': //ZZNS + // set/read RX1 NR2 + if(command[4]==';') { + sprintf(reply,"ZZNS%d;",receiver[0]->nr2); + send_resp(client->fd,reply); + } else if(command[5]==';') { + receiver[0]->nr2=atoi(&command[4]); + if(receiver[0]->nr2) { + receiver[0]->nr=0; + } + update_noise(); + } + break; + case 'T': //ZZNT + // set/read RX1 ANF + if(command[4]==';') { + sprintf(reply,"ZZNT%d;",receiver[0]->anf); + send_resp(client->fd,reply); + } else if(command[5]==';') { + receiver[0]->anf=atoi(&command[4]); + update_noise(); + } + break; + case 'U': //ZZNU + // set/read RX2 ANF + if(command[4]==';') { + sprintf(reply,"ZZNU%d;",receiver[1]->anf); + send_resp(client->fd,reply); + } else if(command[5]==';') { + receiver[1]->anf=atoi(&command[4]); + update_noise(); + } + break; + case 'V': //ZZNV + // set/read RX2 NR + if(command[4]==';') { + sprintf(reply,"ZZNV%d;",receiver[1]->nr); + send_resp(client->fd,reply); + } else if(command[5]==';') { + receiver[1]->nr=atoi(&command[4]); + if(receiver[1]->nr) { + receiver[1]->nr2=0; + } + update_noise(); + } + break; + case 'W': //ZZNW + // set/read RX2 NR2 + if(command[4]==';') { + sprintf(reply,"ZZNW%d;",receiver[1]->nr2); + send_resp(client->fd,reply); + } else if(command[5]==';') { + receiver[1]->nr2=atoi(&command[4]); + if(receiver[1]->nr2) { + receiver[1]->nr=0; + } + update_noise(); + } + break; + default: + implemented=FALSE; + break; + } + case 'O': //ZZOx + switch(command[3]) { + default: + implemented=FALSE; + break; + } + break; + case 'P': //ZZPx + switch(command[3]) { + case 'A': //ZZPA + // set/read preamp setting + if(command[4]==';') { + int a=adc[receiver[0]->adc].attenuation; + if(a==0) { + a=1; + } else if(a<=-30) { + a=4; + } else if(a<=-20) { + a=0; + } else if(a<=-10) { + a=2; + } else { + a=3; + } + sprintf(reply,"ZZPA%d;",a); + send_resp(client->fd,reply); + } else if(command[5]==';') { + int a=atoi(&command[4]); + switch(a) { + case 0: + adc[receiver[0]->adc].attenuation=-20; + break; + case 1: + adc[receiver[0]->adc].attenuation=0; + break; + case 2: + adc[receiver[0]->adc].attenuation=-10; + break; + case 3: + adc[receiver[0]->adc].attenuation=-20; + break; + case 4: + adc[receiver[0]->adc].attenuation=-30; + break; + default: + adc[receiver[0]->adc].attenuation=0; + break; + } + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'Q': //ZZQx + switch(command[3]) { + default: + implemented=FALSE; + break; + } + break; + case 'R': //ZZRx + switch(command[3]) { + case 'C': //ZZRC + // clear RIT frequency + if(command[4]==';') { + vfo[VFO_A].rit=0; + vfo_update(); + } + break; + case 'D': //ZZRD + // decrement RIT frequency + if(command[4]==';') { + if(vfo[VFO_A].mode==modeCWL || vfo[VFO_A].mode==modeCWU) { + vfo[VFO_A].rit-=10; + } else { + vfo[VFO_A].rit-=50; + } + vfo_update(); + } else if(command[9]==';') { + vfo[VFO_A].rit=atoi(&command[4]); + vfo_update(); + } + break; + case 'F': //ZZRF + // set/read RIT frequency + if(command[4]==';') { + sprintf(reply,"ZZRF%+5lld;",vfo[VFO_A].rit); + send_resp(client->fd,reply); + } else if(command[9]==';') { + vfo[VFO_A].rit=atoi(&command[4]); + vfo_update(); + } + break; + case 'M': //ZZRM + // read meter value + if(command[5]==';') { + int m=atoi(&command[4]); + sprintf(reply,"ZZRM%d%20d;",smeter,(int)receiver[0]->meter); + send_resp(client->fd,reply); + } + break; + case 'S': //ZZRS + // set/read RX2 enable + if(command[4]==';') { + sprintf(reply,"ZZRS%d;",receivers==2); + send_resp(client->fd,reply); + } else if(command[5]==';') { + int state=atoi(&command[4]); + if(state) { + radio_change_receivers(2); + } else { + radio_change_receivers(1); + } + } + break; + case 'T': //ZZRT + // set/read RIT enable + if(command[4]==';') { + sprintf(reply,"ZZRT%d;",vfo[VFO_A].rit_enabled); + send_resp(client->fd,reply); + } else if(command[5]==';') { + vfo[VFO_A].rit_enabled=atoi(&command[4]); + vfo_update(); + } + break; + case 'U': //ZZRU + // increments RIT Frequency + if(command[4]==';') { + if(vfo[VFO_A].mode==modeCWL || vfo[VFO_A].mode==modeCWU) { + vfo[VFO_A].rit+=10; + } else { + vfo[VFO_A].rit+=50; + } + vfo_update(); + } else if(command[9]==';') { + vfo[VFO_A].rit=atoi(&command[4]); + vfo_update(); + } + break; + default: + implemented=FALSE; + break; + } + case 'S': //ZZSx + switch(command[3]) { + case 'A': //ZZSA + // move VFO A down one step + if(command[4]==';') { + vfo_step(-1); + } + break; + case 'B': //ZZSB + // move VFO A up one step + if(command[4]==';') { + vfo_step(1); + } + break; + case 'D': //ZZSD + implemented=FALSE; + break; + case 'F': //ZZSF + implemented=FALSE; + break; + case 'G': //ZZSG + // move VFO B down 1 step + if(command[4]==';') { + vfo_id_step(VFO_B,-1); + } + break; + case 'H': //ZZSH + // move VFO B up 1 step + if(command[4]==';') { + vfo_id_step(VFO_B,1); + } + break; + case 'M': //ZZSM + // reads the S Meter (in dB) + if(command[5]==';') { + int v=atoi(&command[4]); + if(v==VFO_A || v==VFO_B) { + double m=receiver[v]->meter; + m=fmax(-140.0,m); + m=fmin(-10.0,m); + sprintf(reply,"ZZSM%d%03d;",v,(int)((m+140.0)*2)); + send_resp(client->fd,reply); + } + } + break; + case 'N': //ZZSN + implemented=FALSE; + break; + case 'P': //ZZSP + // set/read split + if(command[4]==';') { + sprintf(reply,"ZZSP%d;",split); + send_resp(client->fd,reply) ; + } else if(command[5]==';') { + split=atoi(&command[4]); + tx_set_mode(transmitter,get_tx_mode()); + vfo_update(); + } + break; + case 'R': //ZZSR + implemented=FALSE; + break; + case 'S': //ZZSS + implemented=FALSE; + break; + case 'T': //ZZST + implemented=FALSE; + break; + case 'U': //ZZSU + implemented=FALSE; + break; + case 'V': //ZZSV + implemented=FALSE; + break; + case 'W': //ZZSW + // set/read split + if(command[4]==';') { + sprintf(reply,"ZZSW%d;",split); + send_resp(client->fd,reply) ; + } else if(command[5]==';') { + split=atoi(&command[4]); + tx_set_mode(transmitter,get_tx_mode()); + vfo_update(); + } + break; + case 'Y': //ZZSY + implemented=FALSE; + break; + case 'Z': //ZZSZ + implemented=FALSE; + break; + default: + implemented=FALSE; + break; + } + break; + case 'T': //ZZTx + switch(command[3]) { + case 'A': //ZZTA + implemented=FALSE; + break; + case 'B': //ZZTB + implemented=FALSE; + break; + case 'F': //ZZTF + implemented=FALSE; + break; + case 'H': //ZZTH + implemented=FALSE; + break; + case 'I': //ZZTI + implemented=FALSE; + break; + case 'L': //ZZTL + implemented=FALSE; + break; + case 'M': //ZZTM + implemented=FALSE; + break; + case 'O': //ZZTO + implemented=FALSE; + break; + case 'P': //ZZTP + implemented=FALSE; + break; + case 'S': //ZZTS + implemented=FALSE; + break; + case 'U': //ZZTU + // sets or reads TUN status + if(command[4]==';') { + sprintf(reply,"ZZTU%d;",tune); + send_resp(client->fd,reply) ; + } else if(command[5]==';') { + tune_update(atoi(&command[4])); + } + break; + case 'V': //ZZTV + implemented=FALSE; + break; + case 'X': //ZZTX + // sets or reads MOX status + if(command[4]==';') { + sprintf(reply,"ZZTX%d;",mox); + send_resp(client->fd,reply) ; + } else if(command[5]==';') { + mox_update(atoi(&command[4])); + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'U': //ZZUx + switch(command[3]) { + case 'A': //ZZUA + implemented=FALSE; + break; + case 'S': //ZZUS + implemented=FALSE; + break; + case 'T': //ZZUT + implemented=FALSE; + break; + case 'X': //ZZUX + implemented=FALSE; + break; + case 'Y': //ZZUY + implemented=FALSE; + break; + default: + implemented=FALSE; + break; + } + break; + case 'V': //ZZVx + switch(command[3]) { + case 'A': //ZZVA + implemented=FALSE; + break; + case 'B': //ZZVB + implemented=FALSE; + break; + case 'C': //ZZVC + implemented=FALSE; + break; + case 'D': //ZZVD + implemented=FALSE; + break; + case 'E': //ZZVE + implemented=FALSE; + break; + case 'F': //ZZVF + implemented=FALSE; + break; + case 'H': //ZZVH + implemented=FALSE; + break; + case 'I': //ZZVI + implemented=FALSE; + break; + case 'J': //ZZVJ + implemented=FALSE; + break; + case 'K': //ZZVK + implemented=FALSE; + break; + case 'L': //ZZVL + // set/get VFO Lock + implemented=FALSE; + break; + case 'M': //ZZVM + implemented=FALSE; + break; + case 'N': //ZZVN + implemented=FALSE; + break; + case 'O': //ZZVO + implemented=FALSE; + break; + case 'P': //ZZVP + implemented=FALSE; + break; + case 'Q': //ZZVQ + implemented=FALSE; + break; + case 'R': //ZZVR + implemented=FALSE; + break; + case 'S': //ZZVS + implemented=FALSE; + break; + case 'T': //ZZVT + implemented=FALSE; + break; + case 'U': //ZZVU + implemented=FALSE; + break; + case 'V': //ZZVV + implemented=FALSE; + break; + case 'W': //ZZVW + implemented=FALSE; + break; + case 'X': //ZZVX + implemented=FALSE; + break; + case 'Y': //ZZVY + implemented=FALSE; + break; + case 'Z': //ZZVZ + implemented=FALSE; + break; + default: + implemented=FALSE; + break; + } + break; + case 'W': //ZZWx + switch(command[3]) { + case 'A': //ZZWA + implemented=FALSE; + break; + case 'B': //ZZWB + implemented=FALSE; + break; + case 'C': //ZZWC + implemented=FALSE; + break; + case 'D': //ZZWD + implemented=FALSE; + break; + case 'E': //ZZWE + implemented=FALSE; + break; + case 'F': //ZZWF + implemented=FALSE; + break; + case 'G': //ZZWG + implemented=FALSE; + break; + case 'H': //ZZWH + implemented=FALSE; + break; + case 'J': //ZZWJ + implemented=FALSE; + break; + case 'K': //ZZWK + implemented=FALSE; + break; + case 'L': //ZZWL + implemented=FALSE; + break; + case 'M': //ZZWM + implemented=FALSE; + break; + case 'N': //ZZWN + implemented=FALSE; + break; + case 'O': //ZZWO + implemented=FALSE; + break; + case 'P': //ZZWP + implemented=FALSE; + break; + case 'Q': //ZZWQ + implemented=FALSE; + break; + case 'R': //ZZWR + implemented=FALSE; + break; + case 'S': //ZZWS + implemented=FALSE; + break; + case 'T': //ZZWT + implemented=FALSE; + break; + case 'U': //ZZWU + implemented=FALSE; + break; + case 'V': //ZZWV + implemented=FALSE; + break; + case 'W': //ZZWW + implemented=FALSE; + break; + default: + implemented=FALSE; + break; + } + break; + case 'X': //ZZXx + switch(command[3]) { + case 'C': //ZZXC + // clear transmitter XIT + if(command[4]==';') { + transmitter->xit=0; + vfo_update(); + } + break; + case 'F': //ZZXF + // set/read XIT + if(command[4]==';') { + sprintf(reply,"ZZXT%+05lld;",transmitter->xit); + send_resp(client->fd,reply) ; + } else if(command[9]==';') { + transmitter->xit=(long long)atoi(&command[4]); + vfo_update(); + } + break; + case 'H': //ZZXH + implemented=FALSE; + break; + case 'N': //ZZXN + // read combined RX1 status + if(command[4]==';') { + int status=0; + status=status|((receiver[0]->agc)&0x03); + int a=adc[receiver[0]->adc].attenuation; + if(a==0) { + a=1; + } else if(a<=-30) { + a=4; + } else if(a<=-20) { + a=0; + } else if(a<=-10) { + a=2; + } else { + a=3; + } + status=status|((a&0x03)<<3); + status=status|((receiver[0]->squelch_enable&0x01)<<6); + status=status|((receiver[0]->nb&0x01)<<7); + status=status|((receiver[0]->nb2&0x01)<<8); + status=status|((receiver[0]->nr&0x01)<<9); + status=status|((receiver[0]->nr2&0x01)<<10); + status=status|((receiver[0]->snb&0x01)<<11); + status=status|((receiver[0]->anf&0x01)<<12); + sprintf(reply,"ZZXN%04d;",status); + send_resp(client->fd,reply); + } + break; + case 'O': //ZZXO + // read combined RX2 status + if(receivers==2) { + if(command[4]==';') { + int status=0; + status=status|((receiver[1]->agc)&0x03); + int a=adc[receiver[1]->adc].attenuation; + if(a==0) { + a=1; + } else if(a<=-30) { + a=4; + } else if(a<=-20) { + a=0; + } else if(a<=-10) { + a=2; + } else { + a=3; + } + status=status|((a&0x03)<<3); + status=status|((receiver[1]->squelch_enable&0x01)<<6); + status=status|((receiver[1]->nb&0x01)<<7); + status=status|((receiver[1]->nb2&0x01)<<8); + status=status|((receiver[1]->nr&0x01)<<9); + status=status|((receiver[1]->nr2&0x01)<<10); + status=status|((receiver[1]->snb&0x01)<<11); + status=status|((receiver[1]->anf&0x01)<<12); + sprintf(reply,"ZZXO%04d;",status); + send_resp(client->fd,reply); + } + } + break; + case 'S': //ZZXS + /// set/read XIT enable + if(command[4]==';') { + sprintf(reply,"ZZXS%d;",transmitter->xit_enabled); + send_resp(client->fd,reply); + } else if(command[5]==';') { + transmitter->xit_enabled=atoi(&command[4]); + vfo_update(); + } + break; + case 'T': //ZZXT + implemented=FALSE; + break; + case 'V': //ZZXV + // read combined VFO status + if(command[4]==';') { + int status=0; + if(vfo[VFO_A].rit_enabled) { + status=status|0x01; + } + if(locked) { + status=status|0x02; + status=status|0x04; + } + if(split) { + status=status|0x08; + } + if(vfo[VFO_A].ctun) { + status=status|0x10; + } + if(vfo[VFO_B].ctun) { + status=status|0x20; + } + if(mox) { + status=status|0x40; + } + if(tune) { + status=status|0x80; + } + sprintf(reply,"ZZXV%03d;",status); + send_resp(client->fd,reply); + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'Y': //ZZYx + switch(command[3]) { + case 'A': //ZZYA + implemented=FALSE; + break; + case 'B': //ZZYB + implemented=FALSE; + break; + case 'C': //ZZYC + implemented=FALSE; + break; + case 'R': //ZZYR + // switch receivers + if(command[5]==';') { + int v=atoi(&command[4]); + if(v==0) { + active_receiver=receiver[0]; + } else if(v==1) { + if(receivers==2) { + active_receiver=receiver[1]; + } + } + vfo_update(); + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'Z': //ZZZx + switch(command[3]) { + case 'A': //ZZZA + implemented=FALSE; + break; + case 'B': //ZZZB + implemented=FALSE; + break; + case 'Z': //ZZZZ + implemented=FALSE; + break; + default: + implemented=FALSE; + break; + } + break; + default: + implemented=FALSE; + break; + } + return implemented; } -// -// End of Parser -// +// called with g_idle_add so that the processing is running on the main thread +int parse_cmd(void *data) { + COMMAND *info=(COMMAND *)data; + CLIENT *client=info->client; + char *command=info->command; + char reply[80]; + reply[0]='\0'; + gboolean implemented=TRUE; + + switch(command[0]) { + case 'A': + switch(command[1]) { + case 'G': //AG + // set/read AF Gain + if(command[3]==';') { + // send reply back + sprintf(reply,"AG0%03d;",(int)(receiver[0]->volume*100.0)); + send_resp(client->fd,reply) ; + } else if(command[6]==';') { + int gain=atoi(&command[3]); + receiver[0]->volume=(double)gain/100.0; + update_af_gain(); + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'B': + switch(command[1]) { + case 'D': //BD + //band down 1 band + band_minus(receiver[0]->id); + break; + case 'U': //BU + //band up 1 band + band_plus(receiver[0]->id); + break; + default: + implemented=FALSE; + break; + } + break; + case 'C': + switch(command[1]) { + default: + implemented=FALSE; + break; + } + break; + case 'D': + switch(command[1]) { + case 'N': //DN + // move VFO A down 1 step size + vfo_id_step(VFO_A,-1); + break; + default: + implemented=FALSE; + break; + } + break; + case 'E': + switch(command[1]) { + default: + implemented=FALSE; + break; + } + break; + case 'F': + switch(command[1]) { + case 'A': //FA + // set/read VFO-A frequency + if(command[2]==';') { + if(vfo[VFO_A].ctun) { + sprintf(reply,"FA%011lld;",vfo[VFO_A].ctun_frequency); + } else { + sprintf(reply,"FA%011lld;",vfo[VFO_A].frequency); + } + send_resp(client->fd,reply) ; + } else if(command[13]==';') { + long long f=atoll(&command[2]); + local_set_frequency(VFO_A,f); + vfo_update(); + } + break; + case 'B': //FB + // set/read VFO-B frequency + if(command[2]==';') { + if(vfo[VFO_B].ctun) { + sprintf(reply,"FB%011lld;",vfo[VFO_B].ctun_frequency); + } else { + sprintf(reply,"FB%011lld;",vfo[VFO_B].frequency); + } + send_resp(client->fd,reply) ; + } else if(command[13]==';') { + long long f=atoll(&command[2]); + local_set_frequency(VFO_B,f); + vfo_update(); + } + break; + case 'R': //FR + // set/read transceiver receive VFO + if(command[2]==';') { + sprintf(reply,"FR0;"); + send_resp(client->fd,reply) ; + } else if(command[3]==';') { + // ignore set command + } + break; + case 'T': //FT + // set/read transceiver transmit VFO + if(command[2]==';') { + sprintf(reply,"FT%d;",split); + send_resp(client->fd,reply) ; + } else if(command[3]==';') { + split=atoi(&command[2]); + tx_set_mode(transmitter,get_tx_mode()); + vfo_update(); + } + break; + case 'W': //FW + // set/read filter width + implemented=FALSE; + break; + default: + implemented=FALSE; + break; + } + break; + case 'G': + switch(command[1]) { + case 'T': //GT + // set/read RX1 AGC + if(command[2]==';') { + sprintf(reply,"GT%03d;",receiver[0]->agc); + send_resp(client->fd,reply) ; + } else if(command[5]==';') { + // update RX1 AGC + receiver[0]->agc=atoi(&command[2]); + vfo_update(); + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'H': + switch(command[1]) { + default: + implemented=FALSE; + break; + } + break; + case 'I': + switch(command[1]) { + case 'D': //ID + // get ID + strcpy(reply,"ID019;"); + send_resp(client->fd,reply); + break; + case 'F': //IF + sprintf(reply,"IF%011lld%04lld%+06lld%d%d000%d%d%d0%d0000;", + vfo[VFO_A].ctun?vfo[VFO_A].ctun_frequency:vfo[VFO_A].frequency, + step,vfo[VFO_A].rit,vfo[VFO_A].rit_enabled,transmitter==NULL?0:transmitter->xit_enabled, + mox,split,0,split?1:0); + send_resp(client->fd,reply); + break; + default: + implemented=FALSE; + break; + } + break; + case 'J': + switch(command[1]) { + default: + implemented=FALSE; + break; + } + break; + case 'K': + switch(command[1]) { + default: + implemented=FALSE; + break; + } + break; + case 'L': + switch(command[1]) { + default: + implemented=FALSE; + break; + } + break; + case 'M': + switch(command[1]) { + case 'D': //MD + // set/read operating mode + if(command[2]==';') { + sprintf(reply,"MD%d;",vfo[VFO_A].mode+1); + send_resp(client->fd,reply); + } else if(command[3]==';') { + vfo_mode_changed(atoi(&command[2])-1); + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'N': + switch(command[1]) { + case 'B': //NB + // set/read NB1 + if(command[2]==';') { + sprintf(reply,"NB%d;",active_receiver->nb); + send_resp(client->fd,reply); + } else if(command[3]==';') { + active_receiver->nb=atoi(&command[2]); + if(active_receiver->nb) { + active_receiver->nb2=0; + } + update_noise(); + } + break; + case 'T': //NT + // set/read ANF + if(command[2]==';') { + sprintf(reply,"NT%d;",active_receiver->anf); + send_resp(client->fd,reply); + } else if(command[3]==';') { + active_receiver->anf=atoi(&command[2]); + SetRXAANFRun(active_receiver->id, active_receiver->anf); + vfo_update(); + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'O': + switch(command[1]) { + default: + implemented=FALSE; + break; + } + break; + case 'P': + switch(command[1]) { + case 'C': //PC + // set/read PA Power + if(command[2]==';') { + sprintf(reply,"PC%03d;",(int)transmitter->drive); + send_resp(client->fd,reply); + } else if(command[5]==';') { + setDrive((double)atoi(&command[2])); + } + break; + case 'S': //PS + // set/read Power (always ON) + if(command[2]==';') { + sprintf(reply,"PS1;"); + send_resp(client->fd,reply); + } else if(command[3]==';') { + // ignore set + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'Q': + switch(command[1]) { + default: + implemented=FALSE; + break; + } + break; + case 'R': + switch(command[1]) { + case 'C': //RC + // clears RIT + if(command[2]==';') { + vfo[VFO_A].rit=0; + vfo_update(); + } + break; + case 'D': //RD + // decrements RIT Frequency + if(command[2]==';') { + if(vfo[VFO_A].mode==modeCWL || vfo[VFO_A].mode==modeCWU) { + vfo[VFO_A].rit-=10; + } else { + vfo[VFO_A].rit-=50; + } + vfo_update(); + } else if(command[7]==';') { + vfo[VFO_A].rit=atoi(&command[2]); + vfo_update(); + } + break; + case 'T': //RT + // set/read RIT enable + if(command[2]==';') { + sprintf(reply,"RT%d;",vfo[VFO_A].rit_enabled); + send_resp(client->fd,reply); + } else if(command[3]==';') { + vfo[VFO_A].rit_enabled=atoi(&command[2]); + vfo_update(); + } + break; + case 'U': //RU + // increments RIT Frequency + if(command[2]==';') { + if(vfo[VFO_A].mode==modeCWL || vfo[VFO_A].mode==modeCWU) { + vfo[VFO_A].rit+=10; + } else { + vfo[VFO_A].rit+=50; + } + vfo_update(); + } else if(command[7]==';') { + vfo[VFO_A].rit=atoi(&command[2]); + vfo_update(); + } + break; + case 'X': //RX + // set transceiver to RX mode + if(command[2]==';') { + mox_update(0); + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'S': + switch(command[1]) { + case 'M': //SM + // read the S meter + if(command[3]==';') { + int id=atoi(&command[2]); + if(id==0 || id==1) { + sprintf(reply,"SM%04d;",(int)receiver[id]->meter); + send_resp(client->fd,reply); + } + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'T': + switch(command[1]) { + case 'X': //TX + // set transceiver to TX mode + if(command[2]==';') { + mox_update(1); + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'U': + switch(command[1]) { + case 'P': //UP + // move VFO A up by step + if(command[2]==';') { + vfo_step(1); + } + default: + implemented=FALSE; + break; + } + break; + case 'V': + switch(command[1]) { + default: + implemented=FALSE; + break; + } + break; + case 'W': + switch(command[1]) { + default: + implemented=FALSE; + break; + } + break; + case 'X': + switch(command[1]) { + case 'T': //XT + // set/read XIT enable + if(command[2]==';') { + sprintf(reply,"XT%d;",transmitter->xit_enabled); + send_resp(client->fd,reply); + } else if(command[3]==';') { + transmitter->xit_enabled=atoi(&command[2]); + vfo_update(); + } + break; + default: + implemented=FALSE; + break; + } + break; + case 'Y': + switch(command[1]) { + default: + implemented=FALSE; + break; + } + break; + case 'Z': + switch(command[1]) { + case 'Z': + implemented=parse_extended_cmd (command,client); + break; + default: + implemented=FALSE; + break; + } + break; + default: + implemented=FALSE; + break; + } + + if(!implemented) { + g_print("RIGCTL: UNIMPLEMENTED COMMAND: %s\n",info->command); + } + + g_free(info->command); + g_free(info); + return 0; +} // Serial Port Launch int set_interface_attribs (int fd, int speed, int parity) @@ -3760,7 +3058,7 @@ int set_interface_attribs (int fd, int speed, int parity) memset (&tty, 0, sizeof tty); if (tcgetattr (fd, &tty) != 0) { - fprintf (stderr,"RIGCTL: Error %d from tcgetattr", errno); + g_print ("RIGCTL: Error %d from tcgetattr", errno); return -1; } @@ -3789,7 +3087,7 @@ int set_interface_attribs (int fd, int speed, int parity) if (tcsetattr (fd, TCSANOW, &tty) != 0) { - fprintf(stderr, "RIGCTL: Error %d from tcsetattr", errno); + g_print( "RIGCTL: Error %d from tcsetattr", errno); return -1; } return 0; @@ -3801,113 +3099,99 @@ void set_blocking (int fd, int should_block) memset (&tty, 0, sizeof tty); if (tcgetattr (fd, &tty) != 0) { - fprintf (stderr,"RIGCTL: Error %d from tggetattr\n", errno); + g_print ("RIGCTL: Error %d from tggetattr\n", errno); return; } tty.c_cc[VMIN] = should_block ? 1 : 0; tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout if (tcsetattr (fd, TCSANOW, &tty) != 0) - fprintf (stderr,"RIGCTL: error %d setting term attributes\n", errno); + g_print("RIGCTL: error %d setting term attributes\n", errno); } + static gpointer serial_server(gpointer data) { // We're going to Read the Serial port and // when we get data we'll send it to parse_cmd - char ser_buf[MAXDATASIZE]; - char work_buf[MAXDATASIZE]; - char *p; - char *d; - char save_buf[MAXDATASIZE] = ""; - int str_len; + CLIENT *client=(CLIENT *)data; + char cmd_input[MAXDATASIZE]; + char *command=g_new(char,MAXDATASIZE); + int command_index=0; + int numbytes; + int i; cat_control++; - while(1) { - int num_chars = read (fd, ser_buf, sizeof ser_buf); - if( num_chars != 0) { - //fprintf(stderr,"RIGCTL: RECEVIED=%s<<\n",ser_buf); - strcat(work_buf,ser_buf); - strcpy(ser_buf,""); // Clear away serial buffer - p = &work_buf[0]; - while((d=strstr(p,";")) != NULL) { - *d = '\0'; - g_mutex_lock(&mutex_b->m); - - g_mutex_unlock(&mutex_b->m); - p = ++d; - //fprintf(stderr,"RIGCTL: STRLEFT=%s\n",p); - } - strcpy(save_buf,p); - for(str_len=0; str_len<=1999; str_len++) { - ser_buf[str_len] = '\0'; - work_buf[str_len] = '\0'; - } - strcpy(work_buf,save_buf); - for(str_len=0; str_len<=1999; str_len++) { - save_buf[str_len] = '\0'; + serial_running=TRUE; + while(serial_running) { + numbytes = read (fd, cmd_input, sizeof cmd_input); + if(numbytes>0) { + for(i=0;iclient=client; + info->command=command; + g_mutex_lock(&mutex_busy->m); + g_idle_add(parse_cmd,info); + g_mutex_unlock(&mutex_busy->m); + + command=g_new(char,MAXDATASIZE); + command_index=0; } -/* - if(strstr(ser_buf,";") != NULL) { - p = strtok(ser_buf,s); - fprintf(stderr,"RIGCTL: Tok=%s\n",p); - while(p != NULL) { - strcpy(work_buf,p); - g_mutex_lock(&mutex_b->m); - parse_cmd(work_buf,strlen(work_buf),-1); - g_mutex_unlock(&mutex_b->m); - p = strtok(NULL,s); - fprintf(stderr,"RIGCTL: Tok=%s\n",p); - } - } else { - strcat(work_buf,ser_buf); - fprintf(stderr,"RIGCTL: Work_buf=%s\n",work_buf); - } -*/ - } /*else { - usleep(100L); - }*/ + } + } else if(numbytes<0) { + break; + } + //usleep(100L); } + close(client->fd); + cat_control--; } int launch_serial () { - fprintf(stderr,"RIGCTL: Launch Serial port %s\n",ser_port); - - + g_print("RIGCTL: Launch Serial port %s\n",ser_port); if(mutex_b_exists == 0) { mutex_b = g_new(GT_MUTEX,1); g_mutex_init(&mutex_b->m); mutex_b_exists = 1; } + + if(mutex_busy==NULL) { + mutex_busy = g_new(GT_MUTEX,1); + g_print("launch_serial: mutex_busy=%p\n",mutex_busy); + g_mutex_init(&mutex_busy->m); + } fd = open (ser_port, O_RDWR | O_NOCTTY | O_SYNC); if (fd < 0) { - fprintf (stderr,"RIGCTL: Error %d opening %s: %s\n", errno, ser_port, strerror (errno)); + g_print("RIGCTL: Error %d opening %s: %s\n", errno, ser_port, strerror (errno)); return 0 ; } - //set_interface_attribs (fd, B38400, 0); // set speed to 115,200 bps, 8n1 (no parity) - set_interface_attribs (fd, serial_baud_rate, 0); - /* - if(serial_parity == 1) { - set_interface_attribs (fd, PARENB, 0); - } - if(serial_parity == 2) { - set_interface_attribs (fd, PARODD, 0); - } - */ + + g_print("serial port fd=%d\n",fd); + + set_interface_attribs (fd, serial_baud_rate, serial_parity); set_blocking (fd, 1); // set no blocking - - serial_server_thread_id = g_thread_new( "Serial server", serial_server, NULL); - if( ! serial_server_thread_id ) + CLIENT *serial_client=g_new(CLIENT,1); + serial_client->fd=fd; + + serial_server_thread_id = g_thread_new( "Serial server", serial_server, serial_client); + if(!serial_server_thread_id ) { - fprintf(stderr,"g_thread_new failed on serial_server\n"); + g_free(serial_client); + g_print("g_thread_new failed on serial_server\n"); return 0; } return 1; } + // Serial Port close void disable_serial () { - fprintf(stderr,"RIGCTL: Disable Serial port %s\n",ser_port); - cat_control--; + g_print("RIGCTL: Disable Serial port %s\n",ser_port); + serial_running=FALSE; } // @@ -3916,7 +3200,7 @@ void disable_serial () { // void launch_rigctl () { - fprintf(stderr, "LAUNCHING RIGCTL!!\n"); + g_print( "LAUNCHING RIGCTL!!\n"); rigctl_busy = 1; mutex_a = g_new(GT_MUTEX,1); @@ -3931,11 +3215,15 @@ void launch_rigctl () { mutex_c = g_new(GT_MUTEX,1); g_mutex_init(&mutex_c->m); + mutex_busy = g_new(GT_MUTEX,1); +g_print("launch_rigctl: mutex_busy=%p\n",mutex_busy); + g_mutex_init(&mutex_busy->m); + // This routine encapsulates the thread call rigctl_server_thread_id = g_thread_new( "rigctl server", rigctl_server, (gpointer)(long)rigctl_port_base); if( ! rigctl_server_thread_id ) { - fprintf(stderr,"g_thread_new failed on rigctl_server\n"); + g_print("g_thread_new failed on rigctl_server\n"); } } @@ -3964,7 +3252,7 @@ void set_freqB(long long new_freqB) { int set_alc(gpointer data) { int * lcl_ptr = (int *) data; alc = *lcl_ptr; - fprintf(stderr,"RIGCTL: set_alc=%d\n",alc); + g_print("RIGCTL: set_alc=%d\n",alc); return 0; } @@ -3990,3 +3278,5 @@ int lookup_band(int val) { } return work_int; } + + diff --git a/rigctl_menu.c b/rigctl_menu.c index de45624..289c2dd 100644 --- a/rigctl_menu.c +++ b/rigctl_menu.c @@ -33,15 +33,15 @@ #include "vfo.h" int serial_enable; -char ser_port[64]="/dev/ttyUSB0"; -int serial_baud_rate = B4800; +char ser_port[64]="/dev/ttyACM0"; +int serial_baud_rate = B9600; int serial_parity = 0; // 0=none, 1=even, 2=odd +gboolean rigctl_debug=FALSE; static GtkWidget *parent_window=NULL; - static GtkWidget *menu_b=NULL; - static GtkWidget *dialog=NULL; +static GtkWidget *serial_port_entry; static void cleanup() { if(dialog!=NULL) { @@ -66,10 +66,14 @@ static void rigctl_value_changed_cb(GtkWidget *widget, gpointer data) { } static void serial_value_changed_cb(GtkWidget *widget, gpointer data) { - sprintf(ser_port,"/dev/ttyUSB%0d",(int) gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget))); + sprintf(ser_port,"/dev/ttyACM%0d",(int) gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget))); fprintf(stderr,"RIGCTL_MENU: New Serial port=%s\n",ser_port); } +static void rigctl_debug_cb(GtkWidget *widget, gpointer data) { + rigctl_debug=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); +} + static void rigctl_enable_cb(GtkWidget *widget, gpointer data) { rigctl_enable=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); if(rigctl_enable) { @@ -80,6 +84,7 @@ static void rigctl_enable_cb(GtkWidget *widget, gpointer data) { } static void serial_enable_cb(GtkWidget *widget, gpointer data) { + strcpy(ser_port,gtk_entry_get_text(GTK_ENTRY(serial_port_entry))); serial_enable=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); if(serial_enable) { if(launch_serial() == 0) { @@ -93,7 +98,7 @@ static void serial_enable_cb(GtkWidget *widget, gpointer data) { // Set Baud Rate static void baud_rate_cb(GtkWidget *widget, gpointer data) { serial_baud_rate = GPOINTER_TO_INT(data); - fprintf(stderr,"RIGCTL_MENU: Baud rate changed\n"); + fprintf(stderr,"RIGCTL_MENU: Baud rate changed: %d\n",serial_baud_rate); } // Set Parity 0=None, 1=Even, 2=0dd @@ -130,7 +135,12 @@ void rigctl_menu(GtkWidget *parent) { g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); - + GtkWidget *rigctl_debug_b=gtk_check_button_new_with_label("Debug"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rigctl_debug_b), rigctl_debug); + gtk_widget_show(rigctl_debug_b); + gtk_grid_attach(GTK_GRID(grid),rigctl_debug_b,3,0,1,1); + g_signal_connect(rigctl_debug_b,"toggled",G_CALLBACK(rigctl_debug_cb),NULL); + GtkWidget *rigctl_enable_b=gtk_check_button_new_with_label("Rigctl Enable"); //gtk_widget_override_font(tx_out_of_band_b, pango_font_description_from_string("Arial 18")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rigctl_enable_b), rigctl_enable); @@ -148,7 +158,7 @@ void rigctl_menu(GtkWidget *parent) { //gtk_widget_override_font(rigctl_r, pango_font_description_from_string("Arial 18")); gtk_spin_button_set_value(GTK_SPIN_BUTTON(rigctl_port_spinner),(double)19090); gtk_widget_show(rigctl_port_spinner); - gtk_grid_attach(GTK_GRID(grid),rigctl_port_spinner,1,2,1,1); + gtk_grid_attach(GTK_GRID(grid),rigctl_port_spinner,1,2,2,1); g_signal_connect(rigctl_port_spinner,"value_changed",G_CALLBACK(rigctl_value_changed_cb),NULL); /* Put the Serial Port stuff here */ @@ -159,14 +169,21 @@ void rigctl_menu(GtkWidget *parent) { g_signal_connect(serial_enable_b,"toggled",G_CALLBACK(serial_enable_cb),NULL); GtkWidget *serial_text_label=gtk_label_new(NULL); - gtk_label_set_markup(GTK_LABEL(serial_text_label), "Serial Port: /dev/ttyUSB"); + gtk_label_set_markup(GTK_LABEL(serial_text_label), "Serial Port: "); gtk_grid_attach(GTK_GRID(grid),serial_text_label,0,4,1,1); + serial_port_entry=gtk_entry_new(); + gtk_entry_set_text(GTK_ENTRY(serial_port_entry),ser_port); + gtk_widget_show(serial_port_entry); + gtk_grid_attach(GTK_GRID(grid),serial_port_entry,1,4,2,1); + +/* GtkWidget *serial_port_spinner =gtk_spin_button_new_with_range(0,7,1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(serial_port_spinner),(double)0); gtk_widget_show(serial_port_spinner); gtk_grid_attach(GTK_GRID(grid),serial_port_spinner,1,4,1,1); g_signal_connect(serial_port_spinner,"value_changed",G_CALLBACK(serial_value_changed_cb),NULL); +*/ // Serial baud rate here GtkWidget *baud_rate_label =gtk_label_new(NULL); @@ -198,8 +215,8 @@ void rigctl_menu(GtkWidget *parent) { gtk_grid_attach(GTK_GRID(grid),baud_rate_b38400,4,5,1,1); g_signal_connect(baud_rate_b38400,"toggled",G_CALLBACK(baud_rate_cb),(gpointer *) B38400); - // Serial parity /* + // Serial parity GtkWidget *parity_label =gtk_label_new("Parity:"); gtk_widget_show(parity_label); gtk_grid_attach(GTK_GRID(grid),parity_label,0,6,1,1); @@ -223,6 +240,7 @@ void rigctl_menu(GtkWidget *parent) { g_signal_connect(parity_odd_b,"toggled",G_CALLBACK(parity_cb),(gpointer *) 1); */ + // Below stays put gtk_container_add(GTK_CONTAINER(content),grid); diff --git a/rigctl_menu.h b/rigctl_menu.h index bfb2719..64a9d27 100644 --- a/rigctl_menu.h +++ b/rigctl_menu.h @@ -18,7 +18,6 @@ */ #include -#include #include #include @@ -29,3 +28,5 @@ extern void disable_serial(); extern int serial_baud_rate; extern int serial_parity; + +extern gboolean rigctl_debug; diff --git a/rx_panadapter.c b/rx_panadapter.c index a05a45c..56bee49 100644 --- a/rx_panadapter.c +++ b/rx_panadapter.c @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -40,6 +41,9 @@ #ifdef GPIO #include "gpio.h" #endif +#ifdef CLIENT_SERVER +#include "client_server.h" +#endif //static float panadapter_max=-60.0; //static float panadapter_min=-160.0; @@ -396,27 +400,35 @@ void rx_panadapter_update(RECEIVER *rx) { } } - // agc - if(rx->agc!=AGC_OFF) { - double hang=0.0; - double thresh=0; +#ifdef CLIENT_SERVER + if(clients!=NULL) { + cairo_select_font_face(cr, "FreeMono", + CAIRO_FONT_SLANT_NORMAL, + CAIRO_FONT_WEIGHT_NORMAL); + cairo_set_source_rgb (cr, 0.5, 0.5, 0.5); + cairo_set_font_size(cr, 22); + inet_ntop(AF_INET, &(((struct sockaddr_in *)&clients->address)->sin_addr),text,64); + cairo_text_extents(cr, text, &extents); + cairo_move_to(cr, ((double)display_width/2.0)-(extents.width/2.0), (double)display_height/2.0); + cairo_show_text(cr, text); + } +#endif - GetRXAAGCHangLevel(rx->id, &hang); - GetRXAAGCThresh(rx->id, &thresh, 4096.0, (double)rx->sample_rate); - double knee_y=thresh+(double)adc_attenuation[rx->adc]; + // agc + if(rx->agc!=AGC_OFF) { + double knee_y=rx->agc_thresh+(double)adc_attenuation[rx->adc]; if (filter_board == ALEX && rx->adc == 0) knee_y += (double)(10*rx->alex_attenuation); knee_y = floor((rx->panadapter_high - knee_y) * (double) display_height / (rx->panadapter_high - rx->panadapter_low)); - double hang_y=hang+(double)adc_attenuation[rx->adc]; + double hang_y=rx->agc_hang+(double)adc_attenuation[rx->adc]; if (filter_board == ALEX && rx->adc == 0) hang_y += (double)(10*rx->alex_attenuation); hang_y = floor((rx->panadapter_high - hang_y) * (double) display_height / (rx->panadapter_high - rx->panadapter_low)); -//fprintf(stderr,"hang=%f thresh=%f hang_y=%f knee_y=%f\n",rx1_hang,rx1_thresh,hang_y,knee_y); if(rx->agc!=AGC_MEDIUM && rx->agc!=AGC_FAST) { if(active) { cairo_set_source_rgb (cr, 1.0, 1.0, 0.0); @@ -463,13 +475,21 @@ void rx_panadapter_update(RECEIVER *rx) { // signal double s1,s2; - samples[rx->pan]=-200.0; - samples[display_width-1+rx->pan]=-200.0; + int pan=rx->pan; +#ifdef CLIENT_SERVER + if(radio_is_remote) { + pan=0; + } +#endif + + samples[pan]=-200.0; + samples[display_width-1+pan]=-200.0; if(have_rx_gain) { - s1=(double)samples[rx->pan]+rx_gain_calibration-adc_attenuation[rx->adc]; + s1=(double)samples[pan]+rx_gain_calibration-adc_attenuation[rx->adc]; } else { - s1=(double)samples[rx->pan]+(double)adc_attenuation[rx->adc]; + s1=(double)samples[pan]+(double)adc_attenuation[rx->adc]; } + cairo_move_to(cr, 0.0, s1); if (filter_board == ALEX && rx->adc == 0) s1 += (double)(10*rx->alex_attenuation); if (filter_board == CHARLY25) { if (rx->preamp) s1 -= 18.0; @@ -487,9 +507,9 @@ void rx_panadapter_update(RECEIVER *rx) { cairo_move_to(cr, 0.0, s1); for(i=1;ipan]+rx_gain_calibration-adc_attenuation[rx->adc]; + s2=(double)samples[i+pan]+rx_gain_calibration-adc_attenuation[rx->adc]; } else { - s2=(double)samples[i+rx->pan]+(double)adc_attenuation[rx->adc]; + s2=(double)samples[i+pan]+(double)adc_attenuation[rx->adc]; } if (filter_board == ALEX && rx->adc == 0) s2 += (double)(10*rx->alex_attenuation); if (filter_board == CHARLY25) { diff --git a/server_menu.c b/server_menu.c new file mode 100644 index 0000000..5de9827 --- /dev/null +++ b/server_menu.c @@ -0,0 +1,121 @@ + +/* Copyright (C) +* 2020 - John Melton, G0ORX/N6LYT +* +* 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 2 +* 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, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "new_menu.h" +#include "server_menu.h" +#include "radio.h" +#include "client_server.h" + +static GtkWidget *parent_window=NULL; + +static GtkWidget *menu_b=NULL; + +static GtkWidget *dialog=NULL; + +static void cleanup() { + if(dialog!=NULL) { + gtk_widget_destroy(dialog); + dialog=NULL; + sub_menu=NULL; + } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); + return TRUE; +} + +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + +static void server_enable_cb(GtkWidget *widget, gpointer data) { + hpsdr_server=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + if(hpsdr_server) { + create_hpsdr_server(); + } else { + destroy_hpsdr_server(); + } +} + +static void port_value_changed_cb(GtkWidget *widget, gpointer data) { + listen_port = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget)); +} + +void server_menu(GtkWidget *parent) { + parent_window=parent; + + dialog=gtk_dialog_new(); + gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - Server"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); + + GdkRGBA color; + color.red = 1.0; + color.green = 1.0; + color.blue = 1.0; + color.alpha = 1.0; + gtk_widget_override_background_color(dialog,GTK_STATE_FLAG_NORMAL,&color); + + GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + + GtkWidget *grid=gtk_grid_new(); + gtk_grid_set_column_spacing (GTK_GRID(grid),10); + + GtkWidget *close_b=gtk_button_new_with_label("Close"); + g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); + gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); + + + GtkWidget *server_enable_b=gtk_check_button_new_with_label("Server Enable"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (server_enable_b), hpsdr_server); + gtk_widget_show(server_enable_b); + gtk_grid_attach(GTK_GRID(grid),server_enable_b,0,1,1,1); + g_signal_connect(server_enable_b,"toggled",G_CALLBACK(server_enable_cb),NULL); + + GtkWidget *server_port_label =gtk_label_new(NULL); + gtk_label_set_markup(GTK_LABEL(server_port_label), "Server Port"); + gtk_widget_show(server_port_label); + gtk_grid_attach(GTK_GRID(grid),server_port_label,0,2,1,1); + + GtkWidget *server_port_spinner =gtk_spin_button_new_with_range(45000,55000,1); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(server_port_spinner),(double)listen_port); + gtk_widget_show(server_port_spinner); + gtk_grid_attach(GTK_GRID(grid),server_port_spinner,1,2,1,1); + g_signal_connect(server_port_spinner,"value_changed",G_CALLBACK(port_value_changed_cb),NULL); + + gtk_container_add(GTK_CONTAINER(content),grid); + + sub_menu=dialog; + + gtk_widget_show_all(dialog); + +} + diff --git a/server_menu.h b/server_menu.h new file mode 100644 index 0000000..33aea78 --- /dev/null +++ b/server_menu.h @@ -0,0 +1,20 @@ +/* Copyright (C) +* 2020 - John Melton, G0ORX/N6LYT +* +* 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 2 +* 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, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ + +extern void server_menu(GtkWidget *parent); diff --git a/sliders.c b/sliders.c index 37fa7a3..5fb8acf 100644 --- a/sliders.c +++ b/sliders.c @@ -56,6 +56,9 @@ #include "property.h" #include "main.h" #include "ext.h" +#ifdef CLIENT_SERVER +#include "client_server.h" +#endif static int width; static int height; @@ -141,19 +144,16 @@ int scale_timeout_cb(gpointer data) { } static void attenuation_value_changed_cb(GtkWidget *widget, gpointer data) { - if (have_rx_gain) { - //redfined the att slider to a rx-gain slider. - //AD9866 contains a pga amplifier from -12 - 48 dB - //from -12 to 0; the rx-gain slider functions as an att slider - //from 0 - 48 db; the rx-gain slider functions as a gain slider with att = 0; - //att set to 20 for good power measurement. - int rx_gain_slider_value = (int)gtk_range_get_value(GTK_RANGE(attenuation_scale)); - adc_attenuation[active_receiver->adc]= rx_gain_slider_value; - set_attenuation(adc_attenuation[active_receiver->adc]); + adc_attenuation[active_receiver->adc]=(int)gtk_range_get_value(GTK_RANGE(attenuation_scale)); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_attenuation(client_socket,active_receiver->id,(int)adc_attenuation[active_receiver->adc]); } else { - adc_attenuation[active_receiver->adc]=(int)gtk_range_get_value(GTK_RANGE(attenuation_scale)); +#endif set_attenuation(adc_attenuation[active_receiver->adc]); +#ifdef CLIENT_SERVER } +#endif } void set_attenuation_value(double value) { @@ -277,12 +277,24 @@ static void c25_preamp_combobox_changed(GtkWidget *widget, gpointer data) { static void agcgain_value_changed_cb(GtkWidget *widget, gpointer data) { active_receiver->agc_gain=gtk_range_get_value(GTK_RANGE(agc_scale)); - SetRXAAGCTop(active_receiver->id, active_receiver->agc_gain); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_agc_gain(client_socket,active_receiver->id,(int)active_receiver->agc_gain,(int)active_receiver->agc_hang,(int)active_receiver->agc_thresh); + } else { +#endif + SetRXAAGCTop(active_receiver->id, active_receiver->agc_gain); + GetRXAAGCHangLevel(active_receiver->id, &active_receiver->agc_hang); + GetRXAAGCThresh(active_receiver->id, &active_receiver->agc_thresh, 4096.0, (double)active_receiver->sample_rate); +#ifdef CLIENT_SERVER + } +#endif } void set_agc_gain(int rx,double value) { receiver[rx]->agc_gain=value; SetRXAAGCTop(receiver[rx]->id, receiver[rx]->agc_gain); + GetRXAAGCHangLevel(receiver[rx]->id, &receiver[rx]->agc_hang); + GetRXAAGCThresh(receiver[rx]->id, &receiver[rx]->agc_thresh, 4096.0, (double)receiver[rx]->sample_rate); if(display_sliders) { gtk_range_set_value (GTK_RANGE(agc_scale),receiver[rx]->agc_gain); } else { @@ -322,7 +334,17 @@ void update_agc_gain(double gain) { static void afgain_value_changed_cb(GtkWidget *widget, gpointer data) { active_receiver->volume=gtk_range_get_value(GTK_RANGE(af_gain_scale))/100.0; - SetRXAPanelGain1 (active_receiver->id, active_receiver->volume); + +#ifdef CLIENT_SERVER + if(radio_is_remote) { + int v=(int)(active_receiver->volume*100.0); + send_volume(client_socket,active_receiver->id,v); + } else { +#endif + SetRXAPanelGain1 (active_receiver->id, active_receiver->volume); +#ifdef CLIENT_SERVER + } +#endif } void update_af_gain() { @@ -605,12 +627,28 @@ int update_drive(void *data) { static void squelch_value_changed_cb(GtkWidget *widget, gpointer data) { active_receiver->squelch=gtk_range_get_value(GTK_RANGE(widget)); - setSquelch(active_receiver); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_squelch(client_socket,active_receiver->id,active_receiver->squelch_enable,active_receiver->squelch); + } else { +#endif + setSquelch(active_receiver); +#ifdef CLIENT_SERVER + } +#endif } static void squelch_enable_cb(GtkWidget *widget, gpointer data) { active_receiver->squelch_enable=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); - setSquelch(active_receiver); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_squelch(client_socket,active_receiver->id,active_receiver->squelch_enable,active_receiver->squelch); + } else { +#endif + setSquelch(active_receiver); +#ifdef CLIENT_SERVER + } +#endif } static void compressor_value_changed_cb(GtkWidget *widget, gpointer data) { @@ -624,7 +662,6 @@ static void compressor_enable_cb(GtkWidget *widget, gpointer data) { transmitter_set_compressor(transmitter,gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))); // This value is now also reflected in the VFO panel g_idle_add(ext_vfo_update, NULL); - } void set_squelch() { diff --git a/soapy_discovery.c b/soapy_discovery.c index 8b50de9..a41da2a 100644 --- a/soapy_discovery.c +++ b/soapy_discovery.c @@ -258,11 +258,13 @@ fprintf(stderr,"Tx gains: \n"); void soapy_discovery() { size_t length; int i,j; + SoapySDRKwargs input_args={}; SoapySDRKwargs args={}; fprintf(stderr,"soapy_discovery\n"); rtlsdr_count=0; - SoapySDRKwargs *results = SoapySDRDevice_enumerate(NULL, &length); + SoapySDRKwargs_set(&input_args, "hostname", "pluto.local"); + SoapySDRKwargs *results = SoapySDRDevice_enumerate(&input_args, &length); fprintf(stderr,"soapy_discovery: length=%d\n",(int)length); for (i = 0; i < length; i++) { for (size_t j = 0; j < results[i].size; j++) { diff --git a/soapy_protocol.c b/soapy_protocol.c index 23ce181..c10550a 100644 --- a/soapy_protocol.c +++ b/soapy_protocol.c @@ -52,7 +52,7 @@ #include "ext.h" #include "error_handler.h" -static double bandwidth=2500000.0; +static double bandwidth=2000000.0; static SoapySDRDevice *soapy_device; static SoapySDRStream *rx_stream; diff --git a/toolbar.c b/toolbar.c index 991b456..fa08056 100644 --- a/toolbar.c +++ b/toolbar.c @@ -46,6 +46,9 @@ #include "new_menu.h" #include "button_text.h" #include "ext.h" +#ifdef CLIENT_SERVER +#include "client_server.h" +#endif int function=0; @@ -82,13 +85,7 @@ static gint xit_minus_timer=-1; static gboolean rit_timer_cb(gpointer data) { int i=GPOINTER_TO_INT(data); - vfo[active_receiver->id].rit+=(i*rit_increment); - if(vfo[active_receiver->id].rit>10000) vfo[active_receiver->id].rit=10000; - if(vfo[active_receiver->id].rit<-10000) vfo[active_receiver->id].rit=-10000; - if(protocol==NEW_PROTOCOL) { - schedule_high_priority(); - } - g_idle_add(ext_vfo_update,NULL); + vfo_rit(active_receiver->id,i); return TRUE; } @@ -253,87 +250,168 @@ void noise_cb(GtkWidget *widget, gpointer data) { void ctun_cb (GtkWidget *widget, gpointer data) { int id=active_receiver->id; - vfo[id].ctun=vfo[id].ctun==1?0:1; - if(!vfo[id].ctun) { - vfo[id].offset=0; +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_ctun(client_socket,id,vfo[id].ctun==1?0:1); + } else { +#endif + vfo[id].ctun=vfo[id].ctun==1?0:1; + if(!vfo[id].ctun) { + vfo[id].offset=0; + } + vfo[id].ctun_frequency=vfo[id].frequency; + set_offset(active_receiver,vfo[id].offset); + g_idle_add(ext_vfo_update,NULL); +#ifdef CLIENT_SERVER } - vfo[id].ctun_frequency=vfo[id].frequency; - set_offset(active_receiver,vfo[id].offset); - g_idle_add(ext_vfo_update,NULL); +#endif } static void atob_cb (GtkWidget *widget, gpointer data) { - vfo_a_to_b(); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_vfo(client_socket,VFO_A_TO_B); + } else { +#endif + vfo_a_to_b(); +#ifdef CLIENT_SERVER + } +#endif } static void btoa_cb (GtkWidget *widget, gpointer data) { - vfo_b_to_a(); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_vfo(client_socket,VFO_B_TO_A); + } else { +#endif + vfo_b_to_a(); +#ifdef CLIENT_SERVER + } +#endif } static void aswapb_cb (GtkWidget *widget, gpointer data) { - vfo_a_swap_b(); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_vfo(client_socket,VFO_A_SWAP_B); + } else { +#endif + vfo_a_swap_b(); +#ifdef CLIENT_SERVER + } +#endif } static void split_cb (GtkWidget *widget, gpointer data) { - g_idle_add(ext_split_toggle,NULL); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_split(client_socket,split==1?0:1); + } else { +#endif + g_idle_add(ext_split_toggle,NULL); +#ifdef CLIENT_SERVER + } +#endif } static void duplex_cb (GtkWidget *widget, gpointer data) { if(can_transmit && !isTransmitting()) { - duplex=(duplex==1)?0:1; - g_idle_add(ext_set_duplex,NULL); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_dup(client_socket,duplex==1?0:1); + } else { +#endif + duplex=(duplex==1)?0:1; + g_idle_add(ext_set_duplex,NULL); +#ifdef CLIENT_SERVER + } +#endif } } static void sat_cb (GtkWidget *widget, gpointer data) { + int temp; if(can_transmit) { if(sat_mode==SAT_MODE) { - sat_mode=SAT_NONE; + temp=SAT_NONE; } else { - sat_mode=SAT_MODE; + temp=SAT_MODE; } - g_idle_add(ext_vfo_update,NULL); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_sat(client_socket,temp); + } else { +#endif + sat_mode=temp; + g_idle_add(ext_vfo_update,NULL); +#ifdef CLIENT_SERVER + } +#endif } } static void rsat_cb (GtkWidget *widget, gpointer data) { + int temp; if(can_transmit) { if(sat_mode==RSAT_MODE) { - sat_mode=SAT_NONE; + temp=SAT_NONE; } else { - sat_mode=RSAT_MODE; + temp=RSAT_MODE; } - g_idle_add(ext_vfo_update,NULL); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_sat(client_socket,temp); + } else { +#endif + sat_mode=temp; + g_idle_add(ext_vfo_update,NULL); +#ifdef CLIENT_SERVER + } +#endif } } static void rit_enable_cb(GtkWidget *widget, gpointer data) { - vfo[active_receiver->id].rit_enabled=vfo[active_receiver->id].rit_enabled==1?0:1; - if(protocol==NEW_PROTOCOL) { - schedule_high_priority(); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_rit_update(client_socket,active_receiver->id); + } else { +#endif + vfo_rit_update(active_receiver->id); +#ifdef CLIENT_SERVER } - g_idle_add(ext_vfo_update,NULL); +#endif } static void rit_cb(GtkWidget *widget, gpointer data) { int i=GPOINTER_TO_INT(data); - vfo[active_receiver->id].rit+=i*rit_increment; - if(vfo[active_receiver->id].rit>10000) vfo[active_receiver->id].rit=10000; - if(vfo[active_receiver->id].rit<-10000) vfo[active_receiver->id].rit=-10000; - if(protocol==NEW_PROTOCOL) { - schedule_high_priority(); - } - g_idle_add(ext_vfo_update,NULL); - if(i<0) { - rit_minus_timer=g_timeout_add(200,rit_timer_cb,GINT_TO_POINTER(i)); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_rit(client_socket,active_receiver->id,i); } else { - rit_plus_timer=g_timeout_add(200,rit_timer_cb,GINT_TO_POINTER(i)); +#endif + vfo_rit(active_receiver->id,i); + if(i<0) { + rit_minus_timer=g_timeout_add(200,rit_timer_cb,GINT_TO_POINTER(i)); + } else { + rit_plus_timer=g_timeout_add(200,rit_timer_cb,GINT_TO_POINTER(i)); + } +#ifdef CLIENT_SERVER } +#endif } static void rit_clear_cb(GtkWidget *widget, gpointer data) { - vfo[active_receiver->id].rit=0; - g_idle_add(ext_vfo_update,NULL); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_rit_clear(client_socket,active_receiver->id); + } else { +#endif + vfo_rit_clear(active_receiver->id); +#ifdef CLIENT_SERVER + } +#endif } static void xit_enable_cb(GtkWidget *widget, gpointer data) { @@ -405,7 +483,7 @@ static void yes_cb(GtkWidget *widget, gpointer data) { static void halt_cb(GtkWidget *widget, gpointer data) { stop(); - system("shutdown -h -P now"); + int rc=system("shutdown -h -P now"); _exit(0); } @@ -453,8 +531,16 @@ static void exit_cb(GtkWidget *widget, gpointer data) { } void lock_cb(GtkWidget *widget, gpointer data) { - locked=locked==1?0:1; - g_idle_add(ext_vfo_update,NULL); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_lock(client_socket,locked==1?0:1); + } else { +#endif + locked=locked==1?0:1; + g_idle_add(ext_vfo_update,NULL); +#ifdef CLIENT_SERVER + } +#endif } void mox_cb(GtkWidget *widget, gpointer data) { diff --git a/update.c b/update.c index 8487fac..63acc33 100644 --- a/update.c +++ b/update.c @@ -23,7 +23,7 @@ int check_update() { FILE* f=fopen("latest","r"); if(f) { - fgets(new_version,sizeof(new_version),f); + char *c=fgets(new_version,sizeof(new_version),f); fclose(f); } else { fprintf(stderr,"check_update: could not read latest version\n"); diff --git a/vfo.c b/vfo.c index 16a00f7..78fcd52 100644 --- a/vfo.c +++ b/vfo.c @@ -52,6 +52,9 @@ #include "wdsp.h" #include "new_menu.h" #include "rigctl.h" +#ifdef CLIENT_SERVER +#include "client_server.h" +#endif #include "ext.h" static GtkWidget *parent_window; @@ -61,8 +64,8 @@ static int my_height; static GtkWidget *vfo_panel; static cairo_surface_t *vfo_surface = NULL; -int steps[]={1,10,25,50,100,250,500,1000,2500,5000,6250,9000,10000,12500,15000,20000,25000,30000,50000,100000,0}; -char *step_labels[]={"1Hz","10Hz","25Hz","50Hz","100Hz","250Hz","500Hz","1kHz","2.5kHz","5kHz","6.25kHz","9kHz","10kHz","12.5kHz","15kHz","20kHz","25kHz","30kHz","50kHz","100kHz",0}; +int steps[]={1,10,25,50,100,250,500,1000,5000,9000,10000,100000,250000,500000,1000000,0}; +char *step_labels[]={"1Hz","10Hz","25Hz","50Hz","100Hz","250Hz","500Hz","1kHz","5kHz","9kHz","10kHz","100kHz","250KHz","500KHz","1MHz",0}; static GtkWidget* menu=NULL; static GtkWidget* band_menu=NULL; @@ -263,10 +266,15 @@ void vfo_xvtr_changed() { } } -void vfo_band_changed(int b) { +void vfo_band_changed(int id,int b) { BANDSTACK *bandstack; - int id=active_receiver->id; +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_band(client_socket,id,b); + return; + } +#endif if(id==0) { vfo_save_bandstack(); @@ -390,6 +398,13 @@ void vfo_bandstack_changed(int b) { void vfo_mode_changed(int m) { int id=active_receiver->id; +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_mode(client_socket,id,m); + return; + } +#endif + vfo[id].mode=m; // // Change to the filter/NR combination stored for this mode @@ -432,6 +447,12 @@ void vfo_mode_changed(int m) { void vfo_filter_changed(int f) { int id=active_receiver->id; +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_filter(client_socket,id,f); + return; + } +#endif // store changed filter in the mode settings mode_settings[vfo[id].mode].filter = f; @@ -545,6 +566,14 @@ void vfo_step(int steps) { int sid; RECEIVER *other_receiver; +#ifdef CLIENT_SERVER + if(radio_is_remote) { + //send_vfo_step(client_socket,id,steps); + update_vfo_step(id,steps); + return; + } +#endif + if(!locked) { if(vfo[id].ctun) { @@ -660,12 +689,19 @@ void vfo_id_step(int id, int steps) { } } -void vfo_move(long long hz,int round) { - int id=active_receiver->id; +void vfo_id_move(int id,long long hz,int round) { long long delta; int sid; RECEIVER *other_receiver; +#ifdef CLIENT_SERVER + if(radio_is_remote) { + //send_vfo_move(client_socket,id,hz,round); + update_vfo_move(id,hz,round); + return; + } +#endif + if(!locked) { if(vfo[id].ctun) { // don't let ctun go beyond end of passband @@ -726,11 +762,15 @@ void vfo_move(long long hz,int round) { } break; } - receiver_frequency_changed(active_receiver); + receiver_frequency_changed(receiver[id]); g_idle_add(ext_vfo_update,NULL); } } +void vfo_move(long long hz,int round) { + vfo_id_move(active_receiver->id,hz,round); +} + void vfo_move_to(long long hz) { // hz is the offset from the min displayed frequency int id=active_receiver->id; @@ -741,6 +781,13 @@ void vfo_move_to(long long hz) { int sid; RECEIVER *other_receiver; +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_vfo_move_to(client_socket,id,hz); + return; + } +#endif + if(vfo[id].mode!=modeCWL && vfo[id].mode!=modeCWU) { offset=(hz/step)*step; } @@ -1232,3 +1279,28 @@ long long get_tx_freq() { return vfo[txvfo].frequency; } } +void vfo_rit_update(int rx) { + vfo[receiver[rx]->id].rit_enabled=vfo[receiver[rx]->id].rit_enabled==1?0:1; + receiver_frequency_changed(receiver[rx]); + g_idle_add(ext_vfo_update, NULL); +} + +void vfo_rit_clear(int rx) { + vfo[receiver[rx]->id].rit=0; + receiver_frequency_changed(receiver[rx]); + g_idle_add(ext_vfo_update, NULL); +} + +void vfo_rit(int rx,int i) { + double value=(double)vfo[receiver[rx]->id].rit; + value+=(double)(i*rit_increment); + if(value<-10000.0) { + value=-10000.0; + } else if(value>10000.0) { + value=10000.0; + } + vfo[receiver[rx]->id].rit=(int)value; + receiver_frequency_changed(receiver[rx]); + g_idle_add(ext_vfo_update,NULL); +} + diff --git a/vfo.h b/vfo.h index 9efd1b5..4204c3a 100644 --- a/vfo.h +++ b/vfo.h @@ -72,6 +72,7 @@ extern GtkWidget* vfo_init(int width,int height,GtkWidget *parent); extern void vfo_step(int steps); extern void vfo_id_step(int id, int steps); extern void vfo_move(long long hz,int round); +extern void vfo_id_move(int id,long long hz,int round); extern void vfo_move_to(long long hz); extern void vfo_update(); extern void set_frequency(); @@ -81,7 +82,7 @@ extern void vfo_restore_state(); extern void modesettings_save_state(); extern void modesettings_restore_state(); -extern void vfo_band_changed(int b); +extern void vfo_band_changed(int id,int b); extern void vfo_bandstack_changed(int b); extern void vfo_mode_changed(int m); extern void vfo_filter_changed(int f); @@ -94,4 +95,9 @@ extern int get_tx_mode(); extern long long get_tx_freq(); extern void vfo_xvtr_changed(); + +extern void vfo_rit_update(int rx); +extern void vfo_rit_clear(int rx); +extern void vfo_rit(int rx,int i); + #endif diff --git a/vfo_menu.c b/vfo_menu.c index 47ad316..c868989 100644 --- a/vfo_menu.c +++ b/vfo_menu.c @@ -150,10 +150,18 @@ static gboolean freqent_select_cb (GtkWidget *widget, gpointer data) { f = ((long long)(atof(buffer)*mult)+5)/10; sprintf(output, "%lld", f); gtk_label_set_markup (GTK_LABEL (label), output); - fp=g_new(SET_FREQUENCY,1); - fp->vfo=v; - fp->frequency = f; - g_idle_add(ext_set_frequency, fp); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + send_vfo_frequency(client_socket,active_receiver->id,f); + } else { +#endif + fp=g_new(SET_FREQUENCY,1); + fp->vfo=v; + fp->frequency = f; + g_idle_add(ext_set_frequency, fp); +#ifdef CLIENT_SERVER + } +#endif set = 1; } } diff --git a/waterfall.c b/waterfall.c index 8166d08..479398c 100644 --- a/waterfall.c +++ b/waterfall.c @@ -27,6 +27,9 @@ #include "radio.h" #include "vfo.h" #include "waterfall.h" +#ifdef CLIENT_SERVER +#include "client_server.h" +#endif static int colorLowR=0; // black @@ -171,11 +174,18 @@ void waterfall_update(RECEIVER *rx) { unsigned char *p; p=pixels; samples=rx->pixel_samples; + int pan=rx->pan; +#ifdef CLIENT_SERVER + if(radio_is_remote) { + pan=0; + } +#endif + for(i=0;ipan]+(float)(rx_gain_calibration-adc_attenuation[rx->adc]); + sample=samples[i+pan]+(float)(rx_gain_calibration-adc_attenuation[rx->adc]); } else { - sample=samples[i+rx->pan]+(float)adc_attenuation[rx->adc]; + sample=samples[i+pan]+(float)adc_attenuation[rx->adc]; } average+=(int)sample; if(sample<(float)rx->waterfall_low) { diff --git a/zoompan.c b/zoompan.c index 3fc6bc5..8d46e31 100644 --- a/zoompan.c +++ b/zoompan.c @@ -29,6 +29,9 @@ #include "vfo.h" #include "sliders.h" #include "zoompan.h" +#ifdef CLIENT_SERVER +#include "client_server.h" +#endif static int width; static int height; @@ -36,41 +39,61 @@ static int height; static GtkWidget *zoompan; static GtkWidget *zoom_label; static GtkWidget *zoom_scale; +static gulong zoom_signal_id; static GtkWidget *pan_label; static GtkWidget *pan_scale; +static gulong pan_signal_id; +static GMutex pan_zoom_mutex; static GdkRGBA white; static GdkRGBA gray; int zoompan_active_receiver_changed(void *data) { if(display_zoompan) { + g_mutex_lock(&pan_zoom_mutex); gtk_range_set_value(GTK_RANGE(zoom_scale),active_receiver->zoom); gtk_range_set_range(GTK_RANGE(pan_scale),0.0,(double)(active_receiver->zoom==1?active_receiver->pixels:active_receiver->pixels-active_receiver->width)); gtk_range_set_value (GTK_RANGE(pan_scale),active_receiver->pan); if(active_receiver->zoom == 1) { gtk_widget_set_sensitive(pan_scale, FALSE); } + g_mutex_unlock(&pan_zoom_mutex); } return FALSE; } static void zoom_value_changed_cb(GtkWidget *widget, gpointer data) { +g_print("zoom_value_changed_cb\n"); + g_mutex_lock(&pan_zoom_mutex); g_mutex_lock(&active_receiver->display_mutex); - receiver_change_zoom(active_receiver,gtk_range_get_value(GTK_RANGE(zoom_scale))); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + int zoom=(int)gtk_range_get_value(GTK_RANGE(zoom_scale)); + active_receiver->zoom=zoom; + send_zoom(client_socket,active_receiver->id,zoom); + } else { +#endif + receiver_change_zoom(active_receiver,gtk_range_get_value(GTK_RANGE(zoom_scale))); +#ifdef CLIENT_SERVER + } +#endif + g_signal_handler_block(G_OBJECT(pan_scale),pan_signal_id); gtk_range_set_range(GTK_RANGE(pan_scale),0.0,(double)(active_receiver->zoom==1?active_receiver->pixels:active_receiver->pixels-active_receiver->width)); gtk_range_set_value (GTK_RANGE(pan_scale),active_receiver->pan); + g_signal_handler_unblock(G_OBJECT(pan_scale),pan_signal_id); if(active_receiver->zoom==1) { gtk_widget_set_sensitive(pan_scale, FALSE); } else { gtk_widget_set_sensitive(pan_scale, TRUE); } g_mutex_unlock(&active_receiver->display_mutex); + g_mutex_unlock(&pan_zoom_mutex); vfo_update(); } void set_zoom(int rx,double value) { +g_print("set_zoom: %f\n",value); receiver[rx]->zoom=value; - receiver_change_zoom(active_receiver,value); if(display_zoompan) { gtk_range_set_value (GTK_RANGE(zoom_scale),receiver[rx]->zoom); } else { @@ -104,7 +127,20 @@ void set_zoom(int rx,double value) { vfo_update(); } +void remote_set_zoom(int rx,double value) { +g_print("remote_set_zoom: rx=%d zoom=%f\n",rx,value); + g_mutex_lock(&pan_zoom_mutex); + g_signal_handler_block(G_OBJECT(zoom_scale),zoom_signal_id); + g_signal_handler_block(G_OBJECT(pan_scale),pan_signal_id); + set_zoom(rx,value); + g_signal_handler_unblock(G_OBJECT(pan_scale),pan_signal_id); + g_signal_handler_unblock(G_OBJECT(zoom_scale),zoom_signal_id); + g_mutex_unlock(&pan_zoom_mutex); +g_print("remote_set_zoom: EXIT\n"); +} + void update_zoom(double zoom) { +g_print("update_zoom: %f\n",zoom); int z=active_receiver->zoom+(int)zoom; if(z>MAX_ZOOM) z=MAX_ZOOM; if(z<1) z=1; @@ -112,10 +148,22 @@ void update_zoom(double zoom) { } static void pan_value_changed_cb(GtkWidget *widget, gpointer data) { +g_print("pan_value_changed_cb\n"); + g_mutex_lock(&pan_zoom_mutex); +#ifdef CLIENT_SERVER + if(radio_is_remote) { + int pan=(int)gtk_range_get_value(GTK_RANGE(pan_scale)); + send_pan(client_socket,active_receiver->id,pan); + g_mutex_unlock(&pan_zoom_mutex); + return; + } +#endif receiver_change_pan(active_receiver,gtk_range_get_value(GTK_RANGE(pan_scale))); + g_mutex_unlock(&pan_zoom_mutex); } void set_pan(int rx,double value) { +g_print("set_pan: %f\n",value); receiver[rx]->pan=(int)value; if(display_zoompan) { gtk_range_set_value (GTK_RANGE(pan_scale),receiver[rx]->pan); @@ -149,13 +197,26 @@ void set_pan(int rx,double value) { } } +void remote_set_pan(int rx,double value) { +g_print("remote_set_pan: rx=%d pan=%f\n",rx,value); + g_mutex_lock(&pan_zoom_mutex); + g_signal_handler_block(G_OBJECT(pan_scale),pan_signal_id); + gtk_range_set_range(GTK_RANGE(pan_scale),0.0,(double)(receiver[rx]->zoom==1?receiver[rx]->pixels:receiver[rx]->pixels-receiver[rx]->width)); + set_pan(rx,value); + g_signal_handler_unblock(G_OBJECT(pan_scale),pan_signal_id); + g_mutex_unlock(&pan_zoom_mutex); +g_print("remote_set_pan: EXIT\n"); +} + void update_pan(double pan) { + g_mutex_lock(&pan_zoom_mutex); if(active_receiver->zoom>1) { int p=active_receiver->pan+(int)pan; if(p<0) p=0; if(p>(active_receiver->pixels-active_receiver->width)) p=active_receiver->pixels-active_receiver->width; set_pan(active_receiver->id,(double)p); } + g_mutex_lock(&pan_zoom_mutex); } GtkWidget *zoompan_init(int my_width, int my_height) { @@ -180,25 +241,27 @@ fprintf(stderr,"zoompan_init: width=%d height=%d\n", width,height); gtk_range_set_value (GTK_RANGE(zoom_scale),active_receiver->zoom); gtk_widget_show(zoom_scale); gtk_grid_attach(GTK_GRID(zoompan),zoom_scale,1,0,2,1); - g_signal_connect(G_OBJECT(zoom_scale),"value_changed",G_CALLBACK(zoom_value_changed_cb),NULL); + zoom_signal_id=g_signal_connect(G_OBJECT(zoom_scale),"value_changed",G_CALLBACK(zoom_value_changed_cb),NULL); pan_label=gtk_label_new("Pan:"); gtk_widget_override_font(pan_label, pango_font_description_from_string("Sans 10")); gtk_widget_show(pan_label); gtk_grid_attach(GTK_GRID(zoompan),pan_label,3,0,1,1); - pan_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0,active_receiver->zoom==1?active_receiver->pixels:active_receiver->pixels-active_receiver->width,1.0); + pan_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0,active_receiver->zoom==1?active_receiver->width:active_receiver->width*(active_receiver->zoom-1),1.0); gtk_widget_override_font(pan_scale, pango_font_description_from_string("Sans 10")); gtk_scale_set_draw_value (GTK_SCALE(pan_scale), FALSE); gtk_range_set_increments (GTK_RANGE(pan_scale),10.0,10.0); gtk_range_set_value (GTK_RANGE(pan_scale),active_receiver->pan); gtk_widget_show(pan_scale); gtk_grid_attach(GTK_GRID(zoompan),pan_scale,4,0,5,1); - g_signal_connect(G_OBJECT(pan_scale),"value_changed",G_CALLBACK(pan_value_changed_cb),NULL); + pan_signal_id=g_signal_connect(G_OBJECT(pan_scale),"value_changed",G_CALLBACK(pan_value_changed_cb),NULL); if(active_receiver->zoom == 1) { gtk_widget_set_sensitive(pan_scale, FALSE); } + g_mutex_init(&pan_zoom_mutex); + return zoompan; } diff --git a/zoompan.h b/zoompan.h index 833d6f7..c4f36df 100644 --- a/zoompan.h +++ b/zoompan.h @@ -28,4 +28,7 @@ extern void update_zoom(double zoom); extern void set_pan(int rx,double value); extern void set_zoom(int rx,double value); + +extern void remote_set_pan(int rx,double value); +extern void remote_set_zoom(int rx,double value); #endif -- 2.45.2