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
}
}
#include "receiver.h"
#include "vfo.h"
#include "button_text.h"
+#include "client_server.h"
static GtkWidget *parent_window=NULL;
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;
}
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<BANDS+XVTRS;i++) {
band=(BAND*)band_get_band(i);
--- /dev/null
+/* 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 <gtk/gtk.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <string.h>
+#include <strings.h>
+#ifndef __APPLE__
+#include <endian.h>
+#endif
+#include <semaphore.h>
+
+#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;r<receivers;r++) {
+ RECEIVER *rx=receiver[r];
+ if(client->receiver[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;i<rx->width;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;i<RECEIVERS;i++) {
+ send_receiver_data(client,i);
+ }
+ send_vfo_data(client,VFO_A);
+ send_vfo_data(client,VFO_B);
+
+ // get and parse client commands
+ while(client->running) {
+ 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;i<samples;i++) {
+ sample=ntohs(spectrum_data.sample[i]);
+ receiver[r]->pixel_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;i<samples;i++) {
+ left_sample=ntohs(audio_data.sample[(i*2)]);
+ right_sample=ntohs(audio_data.sample[(i*2)+1]);
+ audio_write(rx,(float)left_sample/32767.0,(float)right_sample/32767.0);
+ }
+ }
+ }
+ break;
+ case CMD_RESP_RX_ZOOM:
+ {
+ ZOOM_COMMAND zoom_cmd;
+ bytes_read=recv_bytes(client_socket,(char *)&zoom_cmd.id,sizeof(zoom_cmd)-sizeof(header));
+ if(bytes_read<0) {
+ g_print("client_thread: read %d bytes for ZOOM_CMD\n",bytes_read);
+ perror("client_thread");
+ // dialog box?
+ return NULL;
+ }
+ int rx=zoom_cmd.id;
+ short zoom=ntohs(zoom_cmd.zoom);
+g_print("CMD_RESP_RX_ZOOM: zoom=%d rx[%d]->zoom=%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;rx<receivers;rx++) {
+ receiver[rx]->sample_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;
+}
--- /dev/null
+/* 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
#define NEW_DEVICE_HERMES_LITE2 1006
#ifdef SOAPYSDR
-#define SOAPYSDR_USB_DEVICE 0
+#define SOAPYSDR_USB_DEVICE 2000
#endif
#define STATE_AVAILABLE 2
#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
#ifdef USBOZY
#include "ozyio.h"
#endif
-#ifdef REMOTE
-#include "remote_radio.h"
-#endif
#ifdef STEMLAB_DISCOVERY
#include "stemlab_discovery.h"
#endif
#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;
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) {
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
// 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
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();
//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;row<devices;row++) {
- d=&discovered[row];
+ int row=0;
+ if(devices==0) {
+ GtkWidget *label=gtk_label_new("No local devices found!");
+ gtk_grid_attach(GTK_GRID(grid),label,0,row,3,1);
+ row++;
+ } else {
+ char version[16];
+ char text[256];
+ for(row=0;row<devices;row++) {
+ d=&discovered[row];
fprintf(stderr,"%p Protocol=%d name=%s\n",d,d->protocol,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), "<b>Server Port</b>");
+ 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);
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");
- }
}
}
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);
#endif
}
radioSaveState();
- system("reboot");
+ int rc=system("reboot");
_exit(0);
}
#endif
}
radioSaveState();
- system("shutdown -h -P now");
+ int rc=system("shutdown -h -P now");
_exit(0);
}
#include <stdio.h>
#include <stdint.h>
#include <gtk/gtk.h>
+#include "main.h"
#include "discovery.h"
#include "receiver.h"
#include "sliders.h"
#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)
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,
//
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;
}
}
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;
}
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;
}
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;
}
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;
}
}
}
- 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;
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;
}
}
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;
}
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;
}
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;
}
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;
+}
*
*/
+#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);
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);
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);
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);
f = ((long long)(atof(buffer)*mult)+5)/10;
sprintf(output, "<big>%lld</big>", 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;
}
}
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;
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:
#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);
// 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 ...");
#include "gpio.h"
#include "old_protocol.h"
#include "new_protocol.h"
+#ifdef CLIENT_SERVER
+#include "server_menu.h"
+#endif
static GtkWidget *menu_b=NULL;
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;
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);
#ifdef PURESIGNAL
extern void start_ps();
#endif
+#ifdef CLIENT_SERVER
+extern void start_server();
+#endif
extern void encoder_step(int encoder,int step);
// 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;
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);
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;
extern void noise_menu(GtkWidget *parent);
extern void update_noise();
+extern void set_noise();
*/
#include <gtk/gtk.h>
-#include <semaphore.h>
#include <stdio.h>
#include <string.h>
#include <semaphore.h>
#include <math.h>
#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <netdb.h>
#include <wdsp.h>
// 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) (x<y?x:y)
static gint save_timer_id;
DISCOVERED *radio=NULL;
+#ifdef CLIENT_SERVER
+ gboolean radio_is_remote=FALSE;
+#endif
char property_path[128];
-#ifdef __APPLE__
- sem_t *property_sem;
-#else
- sem_t property_sem;
-#endif
+ GMutex property_mutex;
RECEIVER *receiver[MAX_RECEIVERS];
RECEIVER *active_receiver;
int receivers=RECEIVERS;
+ADC adc[2];
+DAC dac[2];
+int adc_attenuation[2];
+
int locked=0;
long long step=100;
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;
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;i<RECEIVERS;i++) {
+#ifdef CLIENT_SERVER
+ if(radio_is_remote) {
+ receiver_create_remote(receiver[i]);
+ } else {
+#endif
+ receiver[i]=create_receiver(i, buffer_size, fft_size, display_width, updates_per_second, display_width, rx_height/RECEIVERS);
+ setSquelch(receiver[i]);
+#ifdef CLIENT_SERVER
+ }
+#endif
+ receiver[i]->x=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;
//
// 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:
char version[32];
char mac[32];
char ip[32];
- char iface[32];
+ char iface[64];
switch(protocol) {
case ORIGINAL_PROTOCOL:
if(device==SOAPYSDR_USB_DEVICE) {
iqswap=1;
receivers=1;
+ filter_board=NONE;
}
#endif
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;i<RECEIVERS;i++) {
- receiver[i]=create_receiver(i, buffer_size, fft_size, display_width, updates_per_second, display_width, rx_height/RECEIVERS);
- setSquelch(receiver[i]);
- receiver[i]->x=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);
MIDIstartup();
#endif
-#ifdef SERVER
- create_hpsdr_server();
+#ifdef CLIENT_SERVER
+ if(hpsdr_server) {
+ create_hpsdr_server();
+ }
#endif
-
}
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);
}
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) {
}
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");
}
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");
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");
if(value) mute_rx_while_transmitting=atoi(value);
#ifdef SOAPYSDR
- if(device==SOAPYSDR_USB_DEVICE) {
- char name[128];
- for(int i=0;i<radio->info.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;i<radio->info.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;i<radio->info.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;i<radio->info.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;i<receivers;i++) {
+ receiver_save_state(receiver[i]);
+ }
+
+ sprintf(value,"%d",display_filled);
+ setProperty("display_filled",value);
+ sprintf(value,"%d",display_zoompan);
+ setProperty("display_zoompan",value);
+ sprintf(value,"%d",display_sliders);
+ setProperty("display_sliders",value);
+ sprintf(value,"%d",display_toolbar);
+ setProperty("display_toolbar",value);
+
+ if(can_transmit) {
+#ifdef PURESIGNAL
+ // The only variables of interest in this receiver are
+ // the alex_antenna an the adc
+ receiver_save_state(receiver[PS_RX_FEEDBACK]);
+#endif
+ transmitter_save_state(transmitter);
+ }
+
+#ifdef CLIENT_SERVER
+ if(!radio_is_remote) {
#endif
- clearProperties();
sprintf(value,"%d",diversity_enabled);
setProperty("diversity_enabled",value);
sprintf(value,"%f",div_gain);
setProperty("tx_out_of_band",value);
sprintf(value,"%d",updates_per_second);
setProperty("updates_per_second",value);
- sprintf(value,"%d",display_filled);
- setProperty("display_filled",value);
sprintf(value,"%d",display_detector_mode);
setProperty("display_detector_mode",value);
sprintf(value,"%d",display_average_mode);
setProperty("panadapter_high",value);
sprintf(value,"%d",panadapter_low);
setProperty("panadapter_low",value);
- sprintf(value,"%d",display_zoompan);
- setProperty("display_zoompan",value);
- sprintf(value,"%d",display_sliders);
- setProperty("display_sliders",value);
- sprintf(value,"%d",display_toolbar);
- setProperty("display_toolbar",value);
sprintf(value,"%d",waterfall_high);
setProperty("waterfall_high",value);
sprintf(value,"%d",waterfall_low);
sprintf(value,"%d",iqswap);
setProperty("iqswap",value);
+#ifdef CLIENT_SERVER
+ sprintf(value,"%d",hpsdr_server);
+ setProperty("radio.hpsdr_server",value);
+ sprintf(value,"%d",listen_port);
+ setProperty("radio.hpsdr_server.listen_port",value);
+#endif
+
vfo_save_state();
modesettings_save_state();
- sprintf(value,"%d",receivers);
- setProperty("receivers",value);
- for(i=0;i<receivers;i++) {
- receiver_save_state(receiver[i]);
- }
- if(can_transmit) {
-#ifdef PURESIGNAL
- // The only variables of interest in this receiver are
- // the alex_antenna an the adc
- receiver_save_state(receiver[PS_RX_FEEDBACK]);
-#endif
- transmitter_save_state(transmitter);
- }
sprintf(value,"%d",duplex);
setProperty("duplex",value);
bandSaveState();
memSaveState();
-#ifdef GPIO
- if(controller!=NO_CONTROLLER) {
- gpio_save_actions();
- }
-#endif
-
sprintf(value,"%d",rigctl_enable);
setProperty("rigctl_enable",value);
sprintf(value,"%d",rigctl_port_base);
sprintf(value,"%d",display_sequence_errors);
setProperty("radio.display_sequence_errors",value);
-
- saveProperties(property_path);
-g_print("sem_post\n");
-#ifdef __APPLE__
- sem_post(property_sem);
-#else
- sem_post(&property_sem);
+#ifdef CLIENT_SERVER
+ }
#endif
+
+ saveProperties(property_path);
+ g_mutex_unlock(&property_mutex);
}
void calculate_display_average(RECEIVER *rx) {
}
}
+#ifdef CLIENT_SERVER
+int remote_start(void *data) {
+ char *server=(char *)data;
+ sprintf(property_path,"%s@%s.props",radio->name,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;i<receivers;i++) {
+ receiver_restore_state(receiver[i]);
+ if(receiver[i]->local_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;i<receivers;i++) {
+ gint timer_id=gdk_threads_add_timeout_full(G_PRIORITY_DEFAULT_IDLE,100, start_spectrum, receiver[i], NULL);
+ }
+ start_vfo_timer();
+ remote_started=TRUE;
+ return 0;
+}
+#endif
};
extern DISCOVERED *radio;
+#ifdef CLIENT_SERVER
+extern gboolean radio_is_remote;
+#endif
extern GtkWidget *fixed;
//extern int tune_drive_level;
//extern int drive_level;
-int receivers;
+extern int receivers;
-ADC adc[2];
-DAC dac[2];
-int adc_attenuation[2];
+extern ADC adc[2];
+extern DAC dac[2];
+extern int adc_attenuation[2];
-int locked;
+extern int locked;
extern long long step;
extern int rit_increment;
extern gboolean display_sequence_errors;
extern gint sequence_errors;
+extern GMutex property_mutex;
+
+#ifdef CLIENT_SERVER
+extern gboolean server;
+#endif
extern void radio_stop();
extern void reconfigure_radio();
extern void disable_rigctl();
+#ifdef CLIENT_SERVER
+extern int remote_start(void *data);
+#endif
+
#endif
#include "gpio.h"
#include "vfo.h"
#include "ext.h"
+#ifdef CLIENT_SERVER
+#include "client_server.h"
+#endif
static GtkWidget *parent_window=NULL;
static GtkWidget *menu_b=NULL;
g_idle_add(ext_vfo_update, NULL);
}
-static void load_filters(void) {
+void load_filters(void) {
if(filter_board==N2ADR) {
// set OC filters
BAND *band;
static void sample_rate_cb(GtkToggleButton *widget, gpointer data) {
if(gtk_toggle_button_get_active(widget)) {
- radio_change_sample_rate(GPOINTER_TO_INT(data));
+#ifdef CLIENT_SERVER
+ if(radio_is_remote) {
+ send_sample_rate(client_socket,-1,GPOINTER_TO_INT(data));
+ } else {
+#endif
+ radio_change_sample_rate(GPOINTER_TO_INT(data));
+ }
+#ifdef CLIENT_SERVER
}
+#endif
}
static void receivers_cb(GtkToggleButton *widget, gpointer data) {
return;
}
if(gtk_toggle_button_get_active(widget)) {
- radio_change_receivers(GPOINTER_TO_INT(data));
+#ifdef CLIENT_SERVER
+ if(radio_is_remote) {
+ send_receivers(client_socket,GPOINTER_TO_INT(data));
+ } else {
+#endif
+ radio_change_receivers(GPOINTER_TO_INT(data));
+#ifdef CLIENT_SERVER
+ }
+#endif
}
}
col++;
row=1;
+#ifdef GPIO
GtkWidget *vfo_divisor_label=gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(vfo_divisor_label), "<b>VFO Encoder Divisor:</b>");
gtk_grid_attach(GTK_GRID(grid),vfo_divisor_label,col,row,1,1);
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);
extern void radio_menu(GtkWidget *parent);
extern void setDuplex(void);
+extern void load_filters(void);
#endif
#include "ext.h"
#include "new_menu.h"
+#ifdef CLIENT_SERVER
+#include "client_server.h"
+#endif
#define min(x,y) (x<y?x:y)
return TRUE;
}
+void receiver_set_active(RECEIVER *rx) {
+ active_receiver=rx;
+ g_idle_add(menu_active_receiver_changed,NULL);
+ g_idle_add(ext_vfo_update,NULL);
+ g_idle_add(zoompan_active_receiver_changed,NULL);
+ g_idle_add(sliders_active_receiver_changed,NULL);
+ // setup the transmitter mode and filter
+ if(can_transmit) {
+ tx_set_mode(transmitter,get_tx_mode());
+ }
+}
+
gboolean receiver_button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data) {
RECEIVER *rx=(RECEIVER *)data;
if(making_active) {
- active_receiver=rx;
making_active=FALSE;
- g_idle_add(menu_active_receiver_changed,NULL);
- g_idle_add(ext_vfo_update,NULL);
- g_idle_add(zoompan_active_receiver_changed,NULL);
- g_idle_add(sliders_active_receiver_changed,NULL);
- if(event->button==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;
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);
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) {
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);
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) {
// 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
}
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) {
}
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;
}
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) {
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:
}
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 {
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) {
}
}
+#ifdef CLIENT_SERVER
+void receiver_create_remote(RECEIVER *rx) {
+ // receiver structure allready setup
+ create_visual(rx);
+}
+#endif
gdouble agc_gain;
gdouble agc_slope;
gdouble agc_hang_threshold;
+ gdouble agc_hang;
+ gdouble agc_thresh;
gint fps;
gint displaying;
audio_t audio_channel;
gint display_panadapter;
gint display_waterfall;
gint update_timer_id;
+ gdouble meter;
gdouble hz_per_pixel;
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
-
/* TS-2000 emulation via TCP
* Copyright (C) 2016 Steve Wilson <wevets@gmail.com>
* This program is free software; you can redistribute it and/or
#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 <math.h>
+#define NEW_PARSER
+
// IP stuff below
#include <sys/socket.h>
#include <arpa/inet.h> //inet_addr
-//#define RIGCTL_DEBUG
-
int rigctl_port_base=19090;
int rigctl_enable=0;
// 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();
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;
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;
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];
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<MAX_CLIENTS;i++) {
- if(client[i].socket!=-1) {
- fprintf(stderr,"setting SO_LINGER to 0 for client_socket: %d\n",client[i].socket);
- if(setsockopt(client[i].socket,SOL_SOCKET,SO_LINGER,(const char *)&linger,sizeof(linger))==-1) {
+ if(client[i].fd!=-1) {
+ g_print("setting SO_LINGER to 0 for client_socket: %d\n",client[i].fd);
+ if(setsockopt(client[i].fd,SOL_SOCKET,SO_LINGER,(const char *)&linger,sizeof(linger))==-1) {
perror("setsockopt(...,SO_LINGER,...) failed for client");
}
- fprintf(stderr,"closing client socket: %d\n",client[i].socket);
- close(client[i].socket);
- client[i].socket=-1;
+ g_print("closing client socket: %d\n",client[i].fd);
+ close(client[i].fd);
+ client[i].fd=-1;
}
}
if(server_socket>=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;
}
// 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(written<length) {
+ written+=write(fd,&msg[written],length-written);
+ }
+
}
//
int on=1;
int i;
- fprintf(stderr,"rigctl_server: starting server on port %d\n",port);
+ g_print("rigctl_server: starting server on port %d\n",port);
server_socket=socket(AF_INET,SOCK_STREAM,0);
if(server_socket<0) {
}
for(i=0;i<MAX_CLIENTS;i++) {
- client[i].socket=-1;
+ client[i].fd=-1;
}
server_running=1;
// find a spare thread
for(i=0;i<MAX_CLIENTS;i++) {
- if(client[i].socket==-1) {
+ if(client[i].fd==-1) {
- fprintf(stderr,"Using client: %d\n",i);
+ g_print("Using client: %d\n",i);
- client[i].socket=accept(server_socket,(struct sockaddr*)&client[i].address,&client[i].address_length);
- if(client[i].socket<0) {
+ client[i].fd=accept(server_socket,(struct sockaddr*)&client[i].address,&client[i].address_length);
+ if(client[i].fd<0) {
perror("rigctl_server: client accept failed");
continue;
}
client[i].thread_id = g_thread_new("rigctl client", rigctl_client, (gpointer)&client[i]);
if(client[i].thread_id==NULL) {
- fprintf(stderr,"g_thread_new failed (n rigctl_client\n");
- fprintf(stderr,"setting SO_LINGER to 0 for client_socket: %d\n",client[i].socket);
+ g_print("g_thread_new failed (n rigctl_client\n");
+ g_print("setting SO_LINGER to 0 for client_socket: %d\n",client[i].fd);
struct linger linger = { 0 };
linger.l_onoff = 1;
linger.l_linger = 0;
- if(setsockopt(client[i].socket,SOL_SOCKET,SO_LINGER,(const char *)&linger,sizeof(linger))==-1) {
+ if(setsockopt(client[i].fd,SOL_SOCKET,SO_LINGER,(const char *)&linger,sizeof(linger))==-1) {
perror("setsockopt(...,SO_LINGER,...) failed for client");
}
- close(client[i].socket);
+ close(client[i].fd);
}
}
}
static gpointer rigctl_client (gpointer data) {
- CLIENT *client=(CLIENT *)data;
+ CLIENT *client=(CLIENT *)data;
- fprintf(stderr,"rigctl_client: starting rigctl_client: socket=%d\n",client->socket);
+ 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;i<numbytes;i++) { work_buf[i] = cmd_input[i]; }
- work_buf[i+1] = '\0';
- #ifdef RIGCTL_DEBUG
- fprintf(stderr,"RIGCTL: RCVD=%s<-\n",work_buf);
- #endif
-
- // Need to handle two cases
- // 1. Command is short, i.e. no semicolon - that will set save_flag=1 and
- // read another line..
- // 2. 1 to N commands per line. Turns out N1MM sends multiple commands per line
-
- if(save_flag == 0) { // Count the number of semicolons if we aren't already in mode 1.
- semi_number = 0;
- for(i=0;i<numbytes;i++) {
- if(cmd_input[i] == ';') { semi_number++;};
- }
- }
- if((save_flag == 0) && (semi_number == 0)) {
- cmd_input[numbytes] = '\0'; // Turn it into a C string
- strcpy(cmd_save,cmd_input); // And save a copy of it till next time through
- save_flag = 1;
- } else if(save_flag == 1) {
- save_flag = 0;
- cmd_input[numbytes] = '\0'; // Turn it into a C string
- strcat(cmd_save,cmd_input);
- strcpy(cmd_input,cmd_save); // Cat them together and replace cmd_input
- numbytes = strlen(cmd_input);
- }
-
- if(save_flag != 1) {
- work_ptr = strtok(cmd_input,";");
- while(work_ptr != NULL) {
- // Lock so only one user goes into this at a time
- g_mutex_lock(&mutex_b->m);
- parse_cmd(work_ptr,strlen(work_ptr),client->socket);
- g_mutex_unlock(&mutex_b->m);
- work_ptr = strtok(NULL,";");
- }
- for(i=0;i<MAXDATASIZE;i++){
- cmd_input[i] = '\0';
- work_buf[i] = '\0'; // Clear the input buffer
- }
- }
- // Got here because socket closed
- }
-fprintf(stderr,"RIGCTL: Leaving rigctl_client thread");
- if(client->socket!=-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;i<numbytes;i++) {
+ command[command_index]=cmd_input[i];
+ command_index++;
+ if(cmd_input[i]==';') {
+ command[command_index]='\0';
+ if(rigctl_debug) g_print("RIGCTL: command=%s\n",command);
+ COMMAND *info=g_new(COMMAND,1);
+ info->client=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);
}
}
}
}
-//
-// 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<P1><2xP2><11P3><P4>;
- // AS<P1><2xP2><11P3><P4>;
- 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;i<FILTERS;i++) {
+ sprintf(temp,"%5s%5d%5d",f[i].title,f[i].high,f[i].low);
+ strcat(reply,temp);
+ }
+ strcat(reply,";");
+ send_resp(client->fd,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)
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;
}
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;
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;i<numbytes;i++) {
+ command[command_index]=cmd_input[i];
+ command_index++;
+ if(cmd_input[i]==';') {
+ command[command_index]='\0';
+ if(rigctl_debug) g_print("RIGCTL: command=%s\n",command);
+ COMMAND *info=g_new(COMMAND,1);
+ info->client=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;
}
//
//
void launch_rigctl () {
- fprintf(stderr, "LAUNCHING RIGCTL!!\n");
+ g_print( "LAUNCHING RIGCTL!!\n");
rigctl_busy = 1;
mutex_a = g_new(GT_MUTEX,1);
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");
}
}
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;
}
}
return work_int;
}
+
+
#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) {
}
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) {
}
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) {
// 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
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);
//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 */
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), "<b>Serial Port: /dev/ttyUSB</b>");
+ gtk_label_set_markup(GTK_LABEL(serial_text_label), "<b>Serial Port: </b>");
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);
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);
g_signal_connect(parity_odd_b,"toggled",G_CALLBACK(parity_cb),(gpointer *) 1);
*/
+
// Below stays put
gtk_container_add(GTK_CONTAINER(content),grid);
*/
#include <gtk/gtk.h>
-#include <semaphore.h>
#include <stdio.h>
#include <string.h>
extern int serial_baud_rate;
extern int serial_parity;
+
+extern gboolean rigctl_debug;
#include <stdlib.h>
#include <string.h>
#include <semaphore.h>
+#include <arpa/inet.h>
#include <wdsp.h>
#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;
}
}
- // 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);
// 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;
cairo_move_to(cr, 0.0, s1);
for(i=1;i<display_width;i++) {
if(have_rx_gain) {
- s2=(double)samples[i+rx->pan]+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) {
--- /dev/null
+
+/* 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 <gtk/gtk.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#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), "<b>Server Port</b>");
+ 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);
+
+}
+
--- /dev/null
+/* 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);
#include "property.h"
#include "main.h"
#include "ext.h"
+#ifdef CLIENT_SERVER
+#include "client_server.h"
+#endif
static int width;
static int height;
}
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) {
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 {
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() {
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) {
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() {
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++) {
#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;
#include "new_menu.h"
#include "button_text.h"
#include "ext.h"
+#ifdef CLIENT_SERVER
+#include "client_server.h"
+#endif
int function=0;
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;
}
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) {
static void halt_cb(GtkWidget *widget, gpointer data) {
stop();
- system("shutdown -h -P now");
+ int rc=system("shutdown -h -P now");
_exit(0);
}
}
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) {
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");
#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;
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;
}
}
-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();
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
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;
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) {
}
}
-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
}
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;
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;
}
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);
+}
+
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();
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);
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
f = ((long long)(atof(buffer)*mult)+5)/10;
sprintf(output, "<big>%lld</big>", 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;
}
}
#include "radio.h"
#include "vfo.h"
#include "waterfall.h"
+#ifdef CLIENT_SERVER
+#include "client_server.h"
+#endif
static int colorLowR=0; // black
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;i<width;i++) {
if(have_rx_gain) {
- sample=samples[i+rx->pan]+(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) {
#include "vfo.h"
#include "sliders.h"
#include "zoompan.h"
+#ifdef CLIENT_SERVER
+#include "client_server.h"
+#endif
static int width;
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 {
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;
}
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);
}
}
+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) {
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;
}
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