#include<sys/socket.h>\r
#include<arpa/inet.h> //inet_addr\r
\r
-#define RIGCTL_DEBUG\r
+#undef RIGCTL_DEBUG\r
\r
// the port client will be connecting to\r
#define TELNET_PORT 19090 // This is the HAMLIB port\r
static pthread_t rigctl_thread_id;\r
static void * rigctl (void * arg);\r
\r
+int squelch=100; //local sim of squelch level\r
// This stuff from the telnet server\r
int sockfd, numbytes;\r
char buf[MAXDATASIZE];\r
int digu_pol = 0;\r
double new_vol = 0;\r
\r
+// Radio functions - \r
+// Memory channel stuff and things that aren't \r
+// implemented - but here for a more complete emulation\r
+int ctcss_tone; // Numbers 01-38 are legal values - set by CN command, read by CT command\r
+int ctcss_mode; // Numbers 0/1 - on off.\r
+\r
// Now my stuff\r
//\r
// Looks up entry INDEX_NUM in the command structure and\r
int semi_number = 0;\r
int i;\r
char * work_ptr;\r
+ char work_buf[MAXDATASIZE];\r
\r
for(;;) {\r
fprintf(stderr,"RIGCTL - New run\n");\r
while((numbytes=recv(client_sock , cmd_input , MAXDATASIZE-2 , 0)) > 0 ) {\r
- cmd_input[numbytes+1]='\0'; // Turn into a C string\r
- i=strlen(cmd_input);\r
+ //cmd_input[numbytes+1]='\0'; // Turn into a C string\r
+ //i=strlen(cmd_input);\r
+ //#ifdef RIGCTL_DEBUG\r
+ //fprintf(stderr,"RIGCTL: RCVD=%s NB=%d LEN=%d\n",cmd_input,numbytes,i);\r
+ //#endif\r
+ for(i=0;i<numbytes;i++) { work_buf[i] = cmd_input[i]; }\r
+ work_buf[i+1] = '\0';\r
#ifdef RIGCTL_DEBUG\r
- fprintf(stderr,"RIGCTL: RCVD=%s NB=%d LEN=%d\n",cmd_input,numbytes,i);\r
+ fprintf(stderr,"RIGCTL: RCVD=%s<-\n",work_buf);\r
#endif\r
- \r
+\r
// Need to handle two cases\r
// 1. Command is short, i.e. no semicolon - that will set save_flag=1 and\r
// read another line..\r
parse_cmd(work_ptr,strlen(work_ptr));\r
work_ptr = strtok(NULL,";");\r
}\r
+ for(i=0;i<MAXDATASIZE;i++){\r
+ cmd_input[i] = '\0'; \r
+ work_buf[i] = '\0'; // Clear the input buffer\r
+ }\r
}\r
// Got here because pipe closed \r
}\r
\r
void parse_cmd ( char * cmd_input,int len) {\r
int work_int; \r
+ int new_low, new_high;\r
double meter;\r
+ BANDSTACK_ENTRY *entry;\r
// Parse the cmd_input\r
//int space = command.indexOf(' ');\r
//char cmd_char = com_head->cmd_string[0]; // Assume the command is first thing!\r
} \r
}\r
else if(strcmp(cmd_str,"CN")==0) { // Sets and reads CTSS function - 01-38 legal values\r
+ // Stored locally in rigctl - not used.\r
if(len <=2) {\r
- send_resp("CN00;");\r
- } \r
+ sprintf(msg,"CN%02d;",ctcss_tone);\r
+ send_resp(msg);\r
+ } else {\r
+ ctcss_tone = atoi(&cmd_input[2]);\r
+ }\r
}\r
else if(strcmp(cmd_str,"CT")==0) { // Sets and reads CTSS function status\r
+ // Stored locally in rigctl - not used.\r
if(len <=2) {\r
- send_resp("CT0;");\r
- } \r
+ sprintf(msg,"CT%01d;",ctcss_mode);\r
+ send_resp(msg);\r
+ } else {\r
+ ctcss_mode = atoi(&cmd_input[2]);\r
+ }\r
}\r
else if(strcmp(cmd_str,"DC")==0) { // Sets/Reads TX band status\r
if(len <=2) {\r
} \r
}\r
else if(strcmp(cmd_str,"EX")==0) { // Set/reads the extension menu\r
- if(len <=12) {\r
- send_resp("EX00000000000000000000000;");\r
- } \r
+ cmd_input[9] = '\0'; // Make sure we have a C string\r
+ sprintf(msg,"EX%s0;",&cmd_input[2]);\r
+ send_resp(msg);\r
}\r
else if(strcmp(cmd_str,"FA")==0) { // VFO A frequency\r
// LEN=7 - set frequency\r
// Next data will be rest of freq\r
if(len == 13) { //We are receiving freq info\r
long long new_freqA = atoll(&cmd_input[2]);\r
- setFrequency(new_freqA);\r
- g_idle_add(vfo_update,NULL);\r
+ set_band(new_freqA);\r
+ //setFrequency(new_freqA);\r
+ //g_idle_add(vfo_update,NULL);\r
} else {\r
if(len==2) {\r
sprintf(msg,"FA%011lld;",getFrequency());\r
else if(strcmp(cmd_str,"FB")==0) { // VFO B frequency\r
if(len==13) { //We are receiving freq info\r
long long new_freqA = atoll(&cmd_input[2]); \r
- setFrequency(new_freqA);\r
- g_idle_add(vfo_update,NULL);\r
+ set_band(new_freqA);\r
+ //setFrequency(new_freqA);\r
+ //g_idle_add(vfo_update,NULL);\r
} else if(len == 2) {\r
sprintf(msg,"FB%011lld;",getFrequency());\r
send_resp(msg);\r
} \r
} \r
else if(strcmp(cmd_str,"FW")==0) { // Sets/Reas DSP receive filter width in hz 0-9999hz \r
- if(len <=2) {\r
- send_resp("FW0000;");\r
- } \r
+ // CW - legal values 50 80 100 150 200 300 400 500 600 1000 2000\r
+ // PiHPSDR map 50 100 100 100 250 250 400 500 600 1000\r
+ // 25 750\r
+ entry= (BANDSTACK_ENTRY *) \r
+ bandstack_entry_get_current();\r
+ FILTER* band_filters=filters[entry->mode];\r
+ FILTER* band_filter=&band_filters[entry->filter];\r
+ if(len <=2) {\r
+ // CW filter high and low are always the same and the filter value is 2*filter val\r
+ int filter_val = band_filter->high * 2;\r
+ switch(filter_val) {\r
+ case 25: \r
+ case 50:\r
+ work_int = 50;\r
+ break;\r
+ case 100:\r
+ work_int = 100; \r
+ break;\r
+ case 250:\r
+ work_int = 300; \r
+ break;\r
+ case 400:\r
+ work_int = 400; \r
+ break;\r
+ case 500:\r
+ work_int = 500; \r
+ break;\r
+ case 600:\r
+ work_int = 600; \r
+ break;\r
+ case 750:\r
+ work_int = 1000; \r
+ break;\r
+ case 800:\r
+ work_int = 1000; \r
+ break;\r
+ case 1000:\r
+ work_int = 1000; \r
+ break;\r
+ default: work_int = 500; \r
+ break;\r
+ } \r
+ sprintf(msg,"FW%04d;",work_int);\r
+ #ifdef RIGCTL_DEBUG\r
+ fprintf(stderr,"RIGCTL: FW Filter Act=%d work_int=%d\n",band_filter->high,work_int);\r
+ #endif\r
+ send_resp(msg);\r
+ } else {\r
+ // Try to set filters here!\r
+ // CW - legal values 50 80 100 150 200 300 400 500 600 1000 2000\r
+ // PiHPSDR map 50 100 100 100 250 250 400 500 600 1000\r
+ // 25 750\r
+ work_int = atoi(&cmd_input[2]);\r
+ switch (work_int) {\r
+\r
+ case 50: new_low = 25; new_high = 25; break;\r
+ case 80: new_low = 50; new_high = 50; break;\r
+ case 100: new_low = 50; new_high = 50; break;\r
+ case 150: new_low = 50; new_high = 50; break;\r
+ case 200: new_low = 125; new_high = 125; break;\r
+ case 300: new_low = 125; new_high = 125; break;\r
+ case 400: new_low = 200; new_high = 200; break;\r
+ case 500: new_low = 250; new_high = 250; break;\r
+ case 600: new_low = 300; new_high = 300; break;\r
+ case 1000: new_low = 500; new_high = 500; break;\r
+ case 2000: new_low = 500; new_high = 500; break;\r
+ default: new_low = band_filter->low;\r
+ new_high = band_filter->high;\r
+\r
+ }\r
+ #ifdef RIGCTL_DEBUG\r
+ fprintf(stderr,"RIGCTL: FW Filter new_low=%d new_high=%d\n",new_low,new_high);\r
+ #endif\r
+ // entry->filter = new_low * 2 ;\r
+ setFilter(new_low,new_high);\r
+ g_idle_add(vfo_update,NULL);\r
+ }\r
} \r
else if(strcmp(cmd_str,"GT")==0) { // Sets/Reas AGC constant status\r
if(len <=2) {\r
// 0 - 1 char - Shift status\r
sprintf(msg,"IF%011lld%04d%06d%1d%1d%1d%02d%01d%01d%01d%01d%01d%01d%02d%01d;",\r
getFrequency(),\r
- 0, // Shift Offset\r
+ step, // Shift Offset\r
0, // Rit Freq\r
0, // Rit Status\r
0, // XIT Status\r
0, // VFO Status\r
0, // Scan status\r
0, // FT command \r
- 0, // CTSS Tone\r
+ ctcss_tone, // CTSS Tone\r
0, // More tone control\r
0); // Shift status\r
send_resp(msg);\r
} \r
else if(strcmp(cmd_str,"KS")==0) { // Sets/Reads keying freq - 0-060 max\r
if(len <=2) {\r
- send_resp("KS000;");\r
- } \r
+ sprintf(msg,"KS%03d;",cw_keyer_speed);\r
+ send_resp(msg);\r
+ } else {\r
+ int key_speed;\r
+ key_speed = atoi(&cmd_input[2]);\r
+ if(key_speed >1 && key_speed <= 60) {\r
+ cw_keyer_speed=key_speed;\r
+ g_idle_add(vfo_update,NULL);\r
+ } \r
+ }\r
} \r
else if(strcmp(cmd_str,"KY")==0) { // Convert char to morse code\r
if(len <=2) {\r
} \r
else if(strcmp(cmd_str,"LK")==0) { // Set/read key lock function status\r
if(len <=2) {\r
- send_resp("LK00;");\r
- } \r
+ sprintf(msg,"LK%01d%01d;",locked,locked);\r
+ send_resp(msg);\r
+ } else {\r
+ if(cmd_input[3] == '0') {\r
+ locked = 0;\r
+ } else if(cmd_input[3] == '1') {\r
+ locked = 1;\r
+ }\r
+ g_idle_add(vfo_update,NULL);\r
+ }\r
} \r
else if(strcmp(cmd_str,"LM")==0) { // Set/read DRU 3A unit or elect keyer recording status\r
if(len <=2) {\r
// Other stuff to switch modes goes here..\r
// since new_mode has the interpreted command in \r
// in it now.\r
- BANDSTACK_ENTRY *entry;\r
entry= (BANDSTACK_ENTRY *) \r
bandstack_entry_get_current();\r
entry->mode=new_mode;\r
else if(strcmp(cmd_str,"MG")==0) { // Mike Gain - 3 digit value \r
if(len <=2) {\r
work_int = (int) ((mic_gain +10.0)* 100.0/60.0);\r
- sprintf(msg,"MG%03d",work_int);\r
+ sprintf(msg,"MG%03d;",work_int);\r
send_resp(msg);\r
} else {\r
int tval = atoi(&cmd_input[2]); \r
0, // P3 - see MC comment \r
getFrequency(), // P4 - frequency\r
rigctlGetMode(), // P5 - Mode\r
- 0, // P6 - Locked status\r
+ locked, // P6 - Locked status\r
0, // P7 - O-off, 1-tone, 2-CTCSS, 3 =DCS\r
- 0, // P8 - Tone Numbe3r - see page 35\r
- 0, // P9 - CTCSS tone number - see CN command\r
+ 0, // P8 - Tone Number - see page 35\r
+ ctcss_tone, // P9 - CTCSS tone number - see CN command\r
0, // P10 - DCS code - see QC command \r
0, // P11 - Reverse status\r
0, // P12 - Shift status - see OS command\r
send_resp("NR1;"); \r
} else if (nr2 == 1) { \r
send_resp("NR2;"); \r
+ } else {\r
+ send_resp("NR0;"); \r
}\r
} else {\r
if(cmd_input[2] == '0') {\r
if(new_level < 0) { new_level = 0; }\r
if(new_level > 15) { new_level = 15;}\r
}\r
- #ifdef RIGCTL_DEBUG\r
- fprintf(stderr,"RIGCTL: SM level=%.21f new_level=%d\n",\r
- level,new_level);\r
- #endif\r
sprintf(msg,"SM%1c%04d;",\r
cmd_input[2],new_level);\r
send_resp(msg);\r
else if(strcmp(cmd_str,"SQ")==0) { // Set/read the squelch level\r
// P1 - 0- main, 1=sub\r
// P2 - 0-255\r
- if(len <=2) {\r
- send_resp("SQ0000;"); \r
+ if(len <=3) {\r
+ sprintf(msg,"SQ%04d;",squelch);\r
+ send_resp(msg);\r
+ } else {\r
+ squelch = atoi(&cmd_input[2]);\r
}\r
}\r
else if(strcmp(cmd_str,"SR")==0) { // Resets the transceiver\r
}\r
}\r
else if(strcmp(cmd_str,"ST")==0) { // Set/read the multi/ch control freq steps\r
- if(len <=2) {\r
- send_resp("ST00;"); \r
+ // SSB/CW/FSK - values 00-03\r
+ // 00: 1KHz, 01: 2.5Khz 02:5KHz 03: 10Khz\r
+ // AM/FM mode 00-09\r
+ // 00: 5KHz, \r
+ // 01: 6.25KHz, \r
+ // 02:10Khz, \r
+ // 03: 12.5Khz,\r
+ // 04: 15Khz, \r
+ // 05: 20Khz, \r
+ // 06: 25KHz\r
+ // 07: 30Khz\r
+ // 08: 50Khz\r
+ // 09: 100Khz \r
+ int coded_step_val;\r
+ entry= (BANDSTACK_ENTRY *) \r
+ bandstack_entry_get_current();\r
+ if(len <=2) {\r
+ switch(entry->mode) {\r
+ case modeLSB: \r
+ case modeUSB: \r
+ case modeCWL: \r
+ case modeCWU: \r
+ case modeDIGU: \r
+ case modeDIGL: \r
+ if(step >0 && step <= 1000) {\r
+ coded_step_val = 0; \r
+ } else if (step >1000 && step <=2500) {\r
+ coded_step_val = 1; \r
+ } else if (step >2500 && step <=5000) {\r
+ coded_step_val = 2; \r
+ } else {\r
+ coded_step_val = 3; \r
+ }\r
+ break;\r
+ case modeFMN: \r
+ case modeAM: \r
+ if(step >0 && step <= 5000) {\r
+ coded_step_val = 0; \r
+ } else if (step >5000 && step <=6250) {\r
+ coded_step_val = 1; \r
+ } else if (step >6250 && step <=10000) {\r
+ coded_step_val = 2; \r
+ } else if (step >10000 && step <=12500) {\r
+ coded_step_val = 3; \r
+ } else if (step >12500 && step <=15000) {\r
+ coded_step_val = 4; \r
+ } else if (step >15000 && step <=20000) {\r
+ coded_step_val = 5; \r
+ } else if (step >20000 && step <=25000) {\r
+ coded_step_val = 6; \r
+ } else if (step >25000 && step <=30000) {\r
+ coded_step_val = 7; \r
+ } else if (step >30000 && step <=50000) {\r
+ coded_step_val = 8; \r
+ } else if (step >50000 && step <=100000) {\r
+ coded_step_val = 9; \r
+ } else {\r
+ coded_step_val = 0; \r
+ }\r
+ break;\r
+ } \r
+ sprintf(msg,"ST%02d;",coded_step_val);\r
+ send_resp(msg); \r
+ } else {\r
+ coded_step_val = atoi(&cmd_input[2]); \r
+ switch(entry->mode) {\r
+ case modeLSB: \r
+ case modeUSB: \r
+ case modeCWL: \r
+ case modeCWU: \r
+ case modeDIGU: \r
+ case modeDIGL: \r
+ if(coded_step_val==0) { step = 1000;}\r
+ if(coded_step_val==1) { step = 2500;}\r
+ if(coded_step_val==2) { step = 5000;}\r
+ if(coded_step_val==3) { step = 10000;}\r
+ break; \r
+ case modeFMN: \r
+ case modeAM: \r
+ switch(coded_step_val) {\r
+ case 0: step = 5000; break;\r
+ case 1: step = 6250; break;\r
+ case 2: step = 10000; break;\r
+ case 3: step = 12500; break;\r
+ case 4: step = 15000; break;\r
+ case 5: step = 20000; break;\r
+ case 6: step = 25000; break;\r
+ case 7: step = 30000; break;\r
+ case 8: step = 50000; break;\r
+ case 9: step = 100000; break;\r
+ default: break; // No change if not a valid number\r
+ } \r
+ default: break; // No change if not a valid number\r
+ } \r
+ g_idle_add(vfo_update,NULL);\r
}\r
}\r
else if(strcmp(cmd_str,"SU")==0) { // Set/read the scan pause freq\r
else if(strcmp(cmd_str,"UP")==0) { // Emulates the mic up key\r
}\r
else if(strcmp(cmd_str,"VD")==0) { // Sets/Reads VOX dleay time - 0000-3000ms in steps of 150\r
+ // We want vox_hang variable in PiHPSDR\r
+ // Max value in variable in ms... so 250 = 250ms\r
+ #ifdef RIGCTL_DEBUG\r
+ fprintf(stderr,"RIGCTL: Vox hang=%0.20f\n",vox_hang);\r
+ #endif\r
if(len <=2) {\r
- send_resp("VD0000;"); \r
+ work_int = (int) vox_hang;\r
+ sprintf(msg,"VD%04d;",work_int); \r
+ send_resp(msg);\r
+ } else {\r
+ work_int = atoi(&cmd_input[2]);\r
+ // Bounds check for legal values for PiHPSDR\r
+ if(work_int > 1000) { work_int = 1000; }\r
+ if(work_int < 0) { work_int = 0; }\r
+ vox_hang = (double) work_int;\r
+ #ifdef RIGCTL_DEBUG\r
+ fprintf(stderr,"RIGCTL: Vox hang=%0.20f\n",vox_hang);\r
+ #endif\r
}\r
}\r
else if(strcmp(cmd_str,"VG")==0) { // Sets/Reads VOX gain 000-009\r
+ // We want vox_threshold variable in PiHPSDR\r
+ // Max value in variable 0.1 \r
+ // 3 char 000-009 valid ranges\r
+ #ifdef RIGCTL_DEBUG\r
+ fprintf(stderr,"RIGCTL: Vox thesh=%0.20f\n",vox_threshold);\r
+ #endif\r
if(len <=2) {\r
- send_resp("VG000;"); \r
+ work_int = (int) ((vox_threshold) * 100.0);\r
+ sprintf(msg,"VG00%1d;",work_int);\r
+ send_resp(msg);\r
+ } else {\r
+ // Set the threshold here\r
+ work_int = atoi(&cmd_input[2]);\r
+ vox_threshold = ((double) work_int)/100.0;\r
+ #ifdef RIGCTL_DEBUG\r
+ fprintf(stderr,"RIGCTL: Vox thresh=%0.20f\n",vox_threshold);\r
+ #endif\r
}\r
}\r
- else if(strcmp(cmd_str,"VG")==0) { // Emulates the voide 1/2 key\r
+ else if(strcmp(cmd_str,"VR")==0) { // Emulates the voice 1/2 key\r
}\r
else if(strcmp(cmd_str,"VX")==0) { // Sets/reads vox f(x) state\r
if(len <=2) {\r
- send_resp("VX0;"); \r
+ sprintf(msg,"VX%1d;",vox_enabled); \r
+ send_resp(msg);\r
+ } else {\r
+ work_int = atoi(&cmd_input[2]);\r
+ if(work_int>1) { vox_enabled = 1; vox= 1;}\r
+ if(work_int<1) { vox_enabled = 0; vox=0; }\r
}\r
}\r
else if(strcmp(cmd_str,"XT")==0) { // Sets/reads the XIT f(x) state\r
}\r
}\r
else {\r
- fprintf(stderr,"RIGCTL: UNKNOWN\n");\r
+ fprintf(stderr,"RIGCTL: UNKNOWN=%s\n",cmd_str);\r
}\r
}\r
//\r
};\r
int rigctlSetFilterHigh(int val){\r
};\r
+\r
+void set_band(long long new_freqA) { \r
+\r
+ BANDSTACK_ENTRY *entry;\r
+ int b = get_band_from_frequency(new_freqA);\r
+ if(b == -1) { // Out of ham bands...\r
+ setFrequency(new_freqA);\r
+ g_idle_add(vfo_update,NULL);\r
+ return;\r
+ } \r
+\r
+ if(b==band_get_current()) {\r
+ entry = bandstack_entry_next(); \r
+ setFrequency(new_freqA);\r
+ g_idle_add(vfo_update,NULL);\r
+ return;\r
+ } else {\r
+ BAND* band=band_set_current(b);\r
+ entry=bandstack_entry_get_current();\r
+ }\r
+ setMode(entry->mode);\r
+ FILTER* band_filters=filters[entry->mode];\r
+ FILTER* band_filter=&band_filters[entry->filter];\r
+ setFilter(band_filter->low,band_filter->high);\r
+ setFrequency(new_freqA);\r
+\r
+ BAND *band=band_get_current_band();\r
+ set_alex_rx_antenna(band->alexRxAntenna);\r
+ set_alex_tx_antenna(band->alexTxAntenna);\r
+ set_alex_attenuation(band->alexAttenuation);\r
+\r
+ setFrequency(new_freqA);\r
+ g_idle_add(vfo_update,NULL);\r
+\r
+\r
+ calcDriveLevel();\r
+ calcTuneDriveLevel();\r
+}\r