1 // Copyright (c) <2012> <Leif Asbrink>
2 //
3 // Permission is hereby granted, free of charge, to any person
4 // obtaining a copy of this software and associated documentation
5 // files (the "Software"), to deal in the Software without restriction,
6 // including without limitation the rights to use, copy, modify,
7 // merge, publish, distribute, sublicense, and/or sell copies of
8 // the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
16 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
22 
23 
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <string.h>
27 #include "globdef.h"
28 
29 #if(OSNUM == OSNUM_WINDOWS)
30 #include <windows.h>
31 #include <winsock.h>
32 #define RECV_FLAG 0
33 #ifndef IP_ADD_MEMBERSHIP
34 #define IP_ADD_MEMBERSHIP 12
35 #endif
36 #define INVSOCK INVALID_SOCKET
37 #define CLOSE_FD closesocket
38 typedef struct{
39 struct in_addr imr_multiaddr;   /* IP multicast address of group */
40 struct in_addr imr_interface;   /* local IP address of interface */
41 }IP_MREQ;
42 extern WSADATA wsadata;
43 
44 #endif
45 
46 #if(OSNUM == OSNUM_LINUX)
47 #include <fcntl.h>
48 #include <sys/ioctl.h>
49 #include <sys/socket.h>
50 #include <arpa/inet.h>
51 #include <netinet/in.h>
52 #include <sys/time.h>
53 #include <string.h>
54 #include <netdb.h>
55 #include <unistd.h>
56 #include <semaphore.h>
57 #include <pthread.h>
58 #include <errno.h>
59 #include <unistd.h>
60 #include <string.h>
61 #ifdef MSG_WAITALL
62 #define RECV_FLAG MSG_WAITALL
63 #else
64 #define RECV_FLAG 0
65 #endif
66 #define IP_MREQ struct ip_mreq
67 #define INVSOCK -1
68 #define CLOSE_FD close
69 #endif
70 
71 #include "uidef.h"
72 #include "sdrdef.h"
73 #include "vernr.h"
74 #include "rusage.h"
75 #include "thrdef.h"
76 #include "fft1def.h"
77 #include "screendef.h"
78 
79 void net_write(FD fd, void *buf, int size);
80 
81 P_SDRIP sdrip;
82 
83 char *sdrip_parfil_name="par_sdrip";
84 char *sdrip_parm_text[MAX_SDRIP_PARM]={"IP1",
85                                        "IP2",
86                                        "IP3",
87                                        "IP4",
88                                        "Port",
89                                        "Rate dividend",
90                                        "Format",
91                                        "UDP size",
92                                        "Dither",
93                                        "ADgain",
94                                        "RF filter",
95                                        "Connect",
96                                        "Clock adjust",
97                                        "Check"
98                                        };
99 char *pkgsize[2]={"Large","Small"};
100 char *onoff[2]={"OFF","ON"};
101 char *adgains[2]={"1.0","1.5"};
102 char *inp_connect[2]={"Normal","Converter"};
103 char *rffil[2]={"Auto","Bypass"};
104 
105 FD sdrip_fd;
106 struct sockaddr_in sdrip_addr;
107 
verify_sdrip_parameters(void)108 int verify_sdrip_parameters(void)
109 {
110 float t1;
111 if(sdrip.ip0 < 0 || sdrip.ip0 > 255 ||
112    sdrip.ip1 < 0 || sdrip.ip1 > 255 ||
113    sdrip.ip2 < 0 || sdrip.ip2 > 255 ||
114    sdrip.ip3 < 0 || sdrip.ip3 > 255 ||
115    sdrip.port < 0 || sdrip.port > 65535 ||
116    sdrip.udp_size < 0 || sdrip.udp_size > 1 ||
117    sdrip.dither < 0 || sdrip.dither > 1 ||
118    sdrip.adgain < 0 || sdrip.adgain > 1 ||
119    sdrip.rf_filter < 0 || sdrip.rf_filter > 1 ||
120    sdrip.connect < 0 || sdrip.connect > 1 ||
121    abs(sdrip.clock_adjust) > 10000 ||
122    sdrip.check != SDRIP_PAR_VERNR)
123   {
124   return FALSE;
125   }
126 else
127   {
128   if(sdrip.format != 16 && sdrip.format != 24)return FALSE;
129   t1=SDRIP_SAMPLING_CLOCK_DIV10/sdrip.rate_dividend;
130   if(t1 < 32000)return FALSE;
131   if(sdrip.format == 16)
132     {
133     if(t1 > 2000001.)return FALSE;
134     }
135   else
136     {
137     if(t1 > 1333334.0)return FALSE;
138     }
139   return TRUE;
140   }
141 }
142 
143 
display_sdrip_parm_info(int * line)144 int display_sdrip_parm_info(int *line)
145 {
146 char s[80];
147 int errcod;
148 errcod=read_sdrpar(sdrip_parfil_name, MAX_SDRIP_PARM,
149                                      sdrip_parm_text, (int*)((void*)&sdrip));
150 if(errcod == 0)
151   {
152   settextcolor(7);
153   sprintf(s,"IP address         = %d.%d.%d.%d",
154                           sdrip.ip0,sdrip.ip1,sdrip.ip2,sdrip.ip3);
155   lir_text(24,line[0],s);
156   line[0]++;
157   SNDLOG"\n%s",s);
158   sprintf(s,"Port               = %d",sdrip.port);
159   lir_text(24,line[0],s);
160   line[0]++;
161   sprintf(s,"Sampling speed     = %.0f kHz   (dividend=%d)",
162                        8000.0/sdrip.rate_dividend,sdrip.rate_dividend);
163   lir_text(24,line[0],s);
164   line[0]++;
165   sprintf(s,"Bits per sample    = %d",sdrip.format);
166   lir_text(24,line[0],s);
167   line[0]++;
168   sprintf(s,"UDP packet size    = %s",pkgsize[sdrip.udp_size]);
169   lir_text(24,line[0],s);
170   line[0]++;
171   sprintf(s,"Dither             = %s",onoff[sdrip.dither]);
172   lir_text(24,line[0],s);
173   line[0]++;
174   sprintf(s,"A/D gain           = %s",adgains[sdrip.adgain]);
175   lir_text(24,line[0],s);
176   line[0]++;
177   sprintf(s,"RF filter          = %s",rffil[sdrip.rf_filter]);
178   lir_text(24,line[0],s);
179   line[0]++;
180   sprintf(s,"Input connection   = %s",inp_connect[sdrip.connect]);
181   lir_text(24,line[0],s);
182   }
183 return (errcod);
184 }
185 
186 
open_sdrip(void)187 void open_sdrip(void)
188 {
189 int i, j;
190 unsigned char *ip;
191 char s[80];
192 sdr=-1;
193 #if(OSNUM == OSNUM_WINDOWS)
194 if(WSAStartup(2, &wsadata) != 0)
195   {
196   lirerr(1263);
197   return;
198   }
199 #endif
200 memset(&sdrip_addr, 0, sizeof(sdrip_addr));
201 sdrip_addr.sin_family=AF_INET;
202 sdrip_addr.sin_port=htons(sdrip.port);
203 ip=(unsigned char*)&sdrip_addr.sin_addr.s_addr;
204 ip[0]=sdrip.ip0;
205 ip[1]=sdrip.ip1;
206 ip[2]=sdrip.ip2;
207 ip[3]=sdrip.ip3;
208 if ((sdrip_fd = socket(AF_INET, SOCK_STREAM, 0)) == INVSOCK)
209   {
210   lirerr(1249);
211   return;
212   }
213 j=connect(sdrip_fd, (struct sockaddr *)&sdrip_addr, sizeof(sdrip_addr));
214 lir_sleep(30000);
215 i=0;
216 lir_inkey=0;
217 s[0]=0;
218 while(j == -1 && lir_inkey == 0)
219   {
220   if(i > 2)sprintf(s,"Trying to connect %d,  errno=%d",i,errno);
221   lir_text(1,5,s);
222   lir_refresh_screen();
223   j=connect(sdrip_fd, (struct sockaddr *)&sdrip_addr, sizeof(sdrip_addr));
224   test_keyboard();
225   if(kill_all_flag)return;
226   i++;
227   lir_sleep(30000);
228   }
229 if(lir_inkey != 0)
230   {
231   lir_inkey=0;
232   return;
233   }
234 sdr=0;
235 }
236 
sdrip_setup_header(int * line)237 void sdrip_setup_header(int *line)
238 {
239 char s[80];
240 clear_screen();
241 line[0]=2;
242 settextcolor(13);
243 lir_text(20,line[0],"Installation routine for SDR-IP");
244 settextcolor(7);
245 line[0]+=2;
246 sprintf(s,"IP address = %d.%d.%d.%d",sdrip.ip0,sdrip.ip1,sdrip.ip2,sdrip.ip3);
247 lir_text(10,line[0],s);
248 line[0]++;
249 sprintf(s,"Port = %d",sdrip.port);
250 lir_text(16,line[0],s);
251 line[0]+=2;
252 lir_refresh_screen();
253 }
254 
close_sdrip(void)255 void close_sdrip(void)
256 {
257 CLOSE_FD(sdrip_fd);
258 sdr=-1;
259 }
260 
init_sdrip(void)261 void init_sdrip(void)
262 {
263 int i, errcod, line, length;
264 char msg[20], s[80], textbuf[80];
265 unsigned b0, b1, b2, b3;
266 unsigned char c;
267 float t1;
268 FILE *sdrip_file;
269 int *sdr_pi;
270 errcod=read_sdrpar(sdrip_parfil_name, MAX_SDRIP_PARM,
271                                      sdrip_parm_text, (int*)((void*)&sdrip));
272 if(errcod != 0)
273   {
274   sdrip.ip0=10;
275   sdrip.ip1=0;
276   sdrip.ip2=0;
277   sdrip.ip3=93;
278   sdrip.port=50000;
279   sdrip.rate_dividend=100;
280   sdrip.format=24;
281   sdrip.udp_size=0;
282   sdrip.dither=0;
283   sdrip.adgain=0;
284   sdrip.connect=0;
285   sdrip.clock_adjust=0;
286   sdrip.check=SDRIP_PAR_VERNR;
287   }
288 restart:;
289 sdrip_setup_header(&line);
290 lir_text(0,line,"Press MENU button on the SDR-IP and set 'TCP/UDP Settings' to");
291 line++;
292 lir_text(0,line,"'Manual Both Same' with address and port as specified above");
293 line++;
294 lir_text(0,line,"or change address and port to agree with your SDR-IP");
295 line+=4;
296 lir_text(12,line,"A=Change IP address.");
297 line++;
298 lir_text(12,line,"B=Change port.");
299 line++;
300 lir_text(12,line,"C=Connect to the SDR-IP");
301 line++;
302 lir_text(12,line,"X=Skip and return to previous menu.");
303 line+=2;
304 await_processed_keyboard();
305 if(kill_all_flag)return;
306 switch (lir_inkey)
307   {
308   case 'A':
309 specify:
310   lir_text(10,line,"Specify new IP address:");
311   length=lir_get_text(40, line, textbuf);
312   if(kill_all_flag) return;
313 // validate format of IP address
314   if ((length < 7) || (length > 15))  goto format_error;
315   if (strspn(textbuf, "0123456789.") < strlen(textbuf)) goto format_error;
316   if (sscanf(textbuf, "%3u.%3u.%3u.%3u%c", &b0, &b1, &b2, &b3, &c) != 4)
317                                                         goto format_error;
318   if ((b0 | b1 | b2 | b3) > 255)
319     {
320 format_error:;
321     lir_text(10,line+1,"IP address format-error: Try again ");
322     goto specify;
323     }
324   sdrip.ip0=b0;
325   sdrip.ip1=b1;
326   sdrip.ip2=b2;
327   sdrip.ip3=b3;
328   break;
329 
330   case 'B':
331   lir_text(10,line,"New port number:");
332   sdrip.port=lir_get_integer(28,line,5,0,65535);
333   break;
334 
335   case 'C':
336   clear_screen();
337   open_sdrip();
338   if(sdr == 0)goto verify_open;
339   break;
340 
341   case 'X':
342   return;
343   }
344 if(kill_all_flag)return;
345 goto restart;
346 verify_open:;
347 sdrip_setup_header(&line);
348 msg[0]=0x04;
349 msg[1]=0x20;
350 msg[2]=0x01;
351 msg[3]=0x00;
352 net_write(sdrip_fd,msg,4);
353 lir_sleep(100000);
354 recv(sdrip_fd,textbuf,80,0);
355 sprintf(s,"Target Name = %s",&textbuf[4]);
356 lir_text(9,line,s);
357 line++;
358 lir_refresh_screen();
359 msg[2]=0x02;
360 net_write(sdrip_fd,msg,4);
361 lir_sleep(100000);
362 recv(sdrip_fd,textbuf,80,0);
363 sprintf(s,"Serial number = %s",&textbuf[4]);
364 lir_text(7,line,s);
365 line++;
366 lir_refresh_screen();
367 msg[2]=0x03;
368 net_write(sdrip_fd,msg,4);
369 lir_sleep(100000);
370 recv(sdrip_fd,textbuf,80,0);
371 t1=256*textbuf[5]+textbuf[4];
372 sprintf(s,"Interface version = %f",0.01*t1);
373 lir_text(3,line,s);
374 line++;
375 lir_refresh_screen();
376 msg[2]=0x04;
377 net_write(sdrip_fd,msg,4);
378 lir_sleep(100000);
379 recv(sdrip_fd,textbuf,80,0);
380 t1=256*textbuf[5]+textbuf[4];
381 sprintf(s,"Boot code version = %f",0.01*t1);
382 lir_text(3,line,s);
383 line++;
384 lir_refresh_screen();
385 msg[3]=0x01;
386 net_write(sdrip_fd,msg,4);
387 lir_sleep(100000);
388 recv(sdrip_fd,textbuf,80,0);
389 t1=256*textbuf[5]+textbuf[4];
390 sprintf(s,"Firmware version = %f",0.01*t1);
391 lir_text(4,line,s);
392 line++;
393 lir_refresh_screen();
394 msg[3]=0x02;
395 net_write(sdrip_fd,msg,4);
396 lir_sleep(100000);
397 recv(sdrip_fd,textbuf,80,0);
398 t1=256*textbuf[5]+textbuf[4];
399 sprintf(s,"Hardware version = %f",0.01*t1);
400 lir_text(4,line,s);
401 line++;
402 lir_refresh_screen();
403 msg[2]=0x09;
404 msg[3]=0x00;
405 net_write(sdrip_fd,msg,4);
406 lir_sleep(100000);
407 recv(sdrip_fd,textbuf,80,0);
408 t1=256*textbuf[5]+textbuf[4];
409 sprintf(s,"Product ID [%x][%x][%x][%x]",
410                   textbuf[4],textbuf[5],textbuf[6],textbuf[7]);
411 lir_text(4,line,s);
412 line+=2;
413 lir_text(10,line,"Use this hardware? (Y/N)");
414 lir_inkey=0;
415 while(lir_inkey != 'Y')
416   {
417   if(kill_all_flag)goto sdrip_errexit;
418   await_processed_keyboard();
419   if(lir_inkey == 'N')goto restart;
420   }
421 setpar:;
422 sdrip_setup_header(&line);
423 lir_text(0,line,"Set global parameters for the SDR-IP");
424 line++;
425 sprintf(s,"A => Rate dividend = %d (for a sampling rate of %.0f kHz)",
426                              sdrip.rate_dividend, 8000.0/sdrip.rate_dividend);
427 lir_text(0,line,s);
428 line++;
429 sprintf(s,"B => Bits per sample = %d",sdrip.format);
430 lir_text(0,line,s);
431 line++;
432 sprintf(s,"C => UDP packet size = %s",pkgsize[sdrip.udp_size]);
433 lir_text(0,line,s);
434 line++;
435 sprintf(s,"D => Dither %s",onoff[sdrip.dither]);
436 lir_text(0,line,s);
437 line++;
438 sprintf(s,"E => A/D gain %s",adgains[sdrip.adgain]);
439 lir_text(0,line,s);
440 line++;
441 sprintf(s,"F => Input connection %s",inp_connect[sdrip.connect]);
442 lir_text(0,line,s);
443 line++;
444 sprintf(s,"X => Save settings in %s and exit",sdrip_parfil_name);
445 lir_text(0,line,s);
446 line++;
447 await_processed_keyboard();
448 if(kill_all_flag)goto sdrip_errexit;
449 switch (lir_inkey)
450   {
451   case 'A':
452   if(sdrip.format == 16)
453     {
454     i=4;
455     }
456   else
457     {
458     i=6;
459     }
460   sprintf(s,"Enter new rate dividend (%d to 250) =>",i);
461   lir_text(0,line+1,s);
462   sdrip.rate_dividend=lir_get_integer(37,line+1,3,i,250);
463   clear_lines(line+1,line+1);
464   break;
465 
466   case 'B':
467   if(sdrip.format == 16)
468     {
469     sdrip.format=24;
470     }
471   else
472     {
473     sdrip.format=16;
474     }
475   break;
476 
477   case 'C':
478   sdrip.udp_size^=1;
479   break;
480 
481   case 'D':
482   sdrip.dither^=1;
483   break;
484 
485   case 'E':
486   sdrip.adgain^=1;
487   break;
488 
489   case 'F':
490   sdrip.connect^=1;
491   break;
492 
493   case 'X':
494   adjusted_sdr_clock=10.*SDRIP_SAMPLING_CLOCK_DIV10+sdrip.clock_adjust;
495   ui.rx_ad_speed=adjusted_sdr_clock/(10*sdrip.rate_dividend);
496   ui.rx_input_mode=IQ_DATA+DIGITAL_IQ;
497   if(sdrip.format == 24)ui.rx_input_mode+=DWORD_INPUT;
498   ui.rx_rf_channels=1;
499   ui.rx_ad_channels=2;
500   ui.rx_admode=0;
501   sdrip.check=SDRIP_PAR_VERNR;
502   sdrip_file=fopen(sdrip_parfil_name,"w");
503   if(sdrip_file == NULL)
504     {
505 sdrip_errexit:;
506     CLOSE_FD(sdrip_fd);
507 #if(OSNUM == OSNUM_WINDOWS)
508     WSACleanup();
509 #endif
510     clear_screen();
511     return;
512     }
513   sdr_pi=(int*)(&sdrip);
514   for(i=0; i<MAX_SDRIP_PARM; i++)
515     {
516     fprintf(sdrip_file,"%s [%d]\n",sdrip_parm_text[i],sdr_pi[i]);
517     }
518   parfile_end(sdrip_file);
519   ui.rx_addev_no=SDRIP_DEVICE_CODE;
520 #if(OSNUM == OSNUM_WINDOWS)
521   WSACleanup();
522 #endif
523   return;
524   }
525 goto setpar;
526 }
527 
set_sdrip_att(void)528 void set_sdrip_att(void)
529 {
530 char msg[20], textbuf[80];
531 msg[0]=0x06;
532 msg[1]=0x00;
533 msg[2]=0x38;
534 msg[3]=0x00;
535 msg[4]=0x00;
536 msg[5]=fg.gain;
537 net_write(sdrip_fd,msg,6);
538 lir_sleep(100000);
539 recv(sdrip_fd,textbuf,80,0);
540 }
541 
set_sdrip_frequency(void)542 void set_sdrip_frequency(void)
543 {
544 double dt1;
545 char msg[20], textbuf[80];
546 unsigned int *sr;
547 unsigned int ii;
548 msg[0]=0x0a;
549 msg[1]=0x00;
550 msg[2]=0x20;
551 msg[3]=0x00;
552 msg[4]=0x00;
553 sr=(unsigned int*)&msg[6];
554 dt1=fg.passband_center*1000000+0.5;
555 if(dt1 < 0 || dt1 > adjusted_sdr_clock/2)
556   {
557   fg.passband_center=7.05;
558   dt1=fg.passband_center*1000000;
559   }
560 sr[0]=dt1/256;
561 dt1-=256*sr[0];
562 ii=dt1;
563 if(ii > 255)ii=255;
564 msg[5]=ii;
565 net_write(sdrip_fd,msg,10);
566 lir_sleep(100000);
567 recv(sdrip_fd,textbuf,80,0);
568 msg[4]=0x01;
569 net_write(sdrip_fd,msg,10);
570 lir_sleep(100000);
571 recv(sdrip_fd,textbuf,80,0);
572 }
573 
sdrip_input(void)574 void sdrip_input(void)
575 {
576 #if RUSAGE_OLD == TRUE
577 int local_workload_counter;
578 #endif
579 struct sockaddr_in udp_addr;
580 FD udp_fd;
581 int i,errcod;
582 int rxin_local_workload_reset;
583 int pkg_size;
584 int timf1_netptr;
585 short int pkg_chk;
586 int sdrip_mode;
587 int *sr;
588 char *tmpbuf;
589 char s[80], msg[20], textbuf[80];
590 double dt1, read_start_time, total_reads;
591 short int *ichk;
592 int timing_loop_counter,timing_loop_counter_max,initial_skip_flag;
593 float t1;
594 int local_att_counter;
595 int local_nco_counter;
596 short int pkg_number;
597 int err;
598 #if(OSNUM == OSNUM_WINDOWS)
599 char optval;
600 #endif
601 #if(OSNUM == OSNUM_LINUX)
602 int optval;
603 struct timeval timeout;
604 clear_thread_times(THREAD_SDRIP_INPUT);
605 #endif
606 #if RUSAGE_OLD == TRUE
607 local_workload_counter=workload_counter;
608 #endif
609 local_att_counter=sdr_att_counter;
610 local_nco_counter=sdr_nco_counter;
611 errcod=0;
612 pkg_number=0;
613 dt1=current_time();
614 errcod=read_sdrpar(sdrip_parfil_name, MAX_SDRIP_PARM,
615                                      sdrip_parm_text, (int*)((void*)&sdrip));
616 if(errcod != 0)
617   {
618 parerr:;
619   errcod=1170;
620   goto sdrip_init_error_exit;
621   }
622 i=verify_sdrip_parameters();
623 if(i == FALSE)goto parerr;
624 while(sdr == -1)
625   {
626   open_sdrip();
627   lir_sleep(30000);
628   if(sdr == -1)
629     {
630     sprintf(s,"Waiting %.2f", current_time()-dt1);
631     lir_text(0,screen_last_line,s);
632     lir_refresh_screen();
633     if(kill_all_flag)goto sdrip_init_error_exit;
634     }
635   }
636 adjusted_sdr_clock=10.*SDRIP_SAMPLING_CLOCK_DIV10+sdrip.clock_adjust;
637 t1=ui.rx_ad_speed-adjusted_sdr_clock/(10*sdrip.rate_dividend);
638 if(fabs(t1/ui.rx_ad_speed) > 0.0001)
639   {
640   errcod=1330;
641   goto sdrip_error_exit;
642   }
643 // Set the DDC output sampling rate.
644 msg[0]=0x09;
645 msg[1]=0x00;
646 msg[2]=0xb8;
647 msg[3]=0x00;
648 msg[4]=0x00;
649 sr=(int*)&msg[5];
650 sr[0]=SDRIP_SAMPLING_CLOCK_DIV10/sdrip.rate_dividend;
651 net_write(sdrip_fd,msg,9);
652 lir_sleep(100000);
653 recv(sdrip_fd,textbuf,80,0);
654 // Set the RF filter mode.
655 msg[0]=0x06;
656 msg[1]=0x00;
657 msg[2]=0x44;
658 msg[3]=0x00;
659 msg[4]=0x00;
660 if(sdrip.rf_filter == 0)
661   {
662   msg[5]=0x00;
663   }
664 else
665   {
666   msg[5]=0x0b;
667   }
668 net_write(sdrip_fd,msg,6);
669 lir_sleep(100000);
670 recv(sdrip_fd,textbuf,80,0);
671 // Set the A/D mode.
672 msg[0]=0x06;
673 msg[1]=0x00;
674 msg[2]=0x8a;
675 msg[3]=0x00;
676 msg[4]=0x00;
677 if(sdrip.dither != 0)msg[4]|=1;
678 if(sdrip.adgain != 0)msg[4]|=2;
679 if(sdrip.connect != 0)msg[4]|=4;
680 msg[5]=0x01;
681 net_write(sdrip_fd,msg,6);
682 lir_sleep(100000);
683 recv(sdrip_fd,textbuf,80,0);
684 // Set the data output packet size.
685 msg[0]=0x05;
686 msg[1]=0x00;
687 msg[2]=0xc4;
688 msg[3]=0x00;
689 msg[4]=sdrip.udp_size;
690 sdrip_mode=sdrip.udp_size;
691 net_write(sdrip_fd,msg,5);
692 lir_sleep(100000);
693 recv(sdrip_fd,textbuf,80,0);
694 set_sdrip_att();
695 set_sdrip_frequency();
696 fft1_block_timing();
697 if(thread_command_flag[THREAD_SCREEN]!=THRFLAG_NOT_ACTIVE)
698   {
699   while(thread_status_flag[THREAD_SCREEN]!=THRFLAG_ACTIVE &&
700         thread_status_flag[THREAD_SCREEN]!=THRFLAG_IDLE &&
701         thread_status_flag[THREAD_SCREEN]!=THRFLAG_SEM_WAIT)
702     {
703     if(thread_command_flag[THREAD_SDRIP_INPUT] ==
704                                            THRFLAG_KILL)goto sdrip_error_exit;
705     lir_sleep(10000);
706     }
707   }
708 // Set the receiver state.
709 msg[0]=0x08;
710 msg[1]=0x00;
711 msg[2]=0x18;
712 msg[3]=0x00;
713 msg[4]=0x80;        // Set complex contigous data.
714 msg[5]=0x02;        // set run/stop to RUN
715 if(sdrip.format == 16)
716   {
717   msg[6]=0x00;
718   }
719 else
720   {
721   sdrip_mode|=2;
722   msg[6]=0x80;
723   }
724 msg[7]=1;
725 net_write(sdrip_fd,msg,8);
726 lir_sleep(100000);
727 recv(sdrip_fd,textbuf,80,0);
728 if ((udp_fd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) == INVSOCK)
729   {
730   lirerr(1284);
731   goto sdrip_exit;
732   }
733 optval=TRUE;
734 err=setsockopt( udp_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval) );
735 if(err != 0)
736   {
737   lirerr(1392);
738   goto sdrip_exit;
739   }
740 #if OSNUM == OSNUM_LINUX
741 timeout.tv_sec=1;
742 timeout.tv_usec=0;
743 err=setsockopt( udp_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout) );
744 if(err != 0)
745   {
746   lirerr(1392);
747   goto sdrip_exit;
748   }
749 #endif
750 i=131072;
751 err=setsockopt(udp_fd,SOL_SOCKET,SO_RCVBUF,(char*)&i,sizeof(int));
752 if(err != 0)
753   {
754   lirerr(1392);
755   goto sdrip_exit;
756   }
757 i=8192;
758 err=setsockopt(udp_fd,SOL_SOCKET,SO_SNDBUF,(char*)&i,sizeof(int));
759 if(err != 0)
760   {
761   lirerr(1392);
762   goto sdrip_exit;
763   }
764 memset(&udp_addr, 0, sizeof(udp_addr));
765 udp_addr.sin_family=AF_INET;
766 udp_addr.sin_port=htons(sdrip.port);
767 udp_addr.sin_addr.s_addr = htonl(INADDR_ANY );
768 // bind to the SDR-IP address and port.
769 if (bind(udp_fd, (struct sockaddr *)&udp_addr, sizeof(udp_addr)) < 0)
770   {
771   lirerr(1302);
772   goto sdrip_udp_exit;
773   }
774 tmpbuf=malloc(1444);
775 if(tmpbuf == NULL)goto sdrip_udp_exit;
776 // sdrip_mode == 0 => large UDP, 16 bit
777 // sdrip_mode == 1 => small UDP, 16 bit
778 // sdrip_mode == 2 => large UDP, 24 bit
779 // sdrip_mode == 3 => small UDP, 24 bit
780 timf1_netptr=timf1p_pa;
781 switch (sdrip_mode)
782   {
783   case 0:
784   pkg_size=1028;
785   pkg_chk=0x8404;
786   break;
787 
788   case 1:
789   pkg_size=516;
790   pkg_chk=0x8204;
791 
792   break;
793 
794   case 2:
795   pkg_size=1444;
796   pkg_chk=0x85a4;
797 
798   break;
799 
800   case 3:
801   pkg_size=388;
802   pkg_chk=0x8184;
803 
804   break;
805 
806   default:
807   pkg_size=0;
808   pkg_chk=0;
809   lirerr(46295);
810   goto sdrip_udpbuf_exit;
811   }
812 #include "timing_setup.c"
813 thread_status_flag[THREAD_SDRIP_INPUT]=THRFLAG_ACTIVE;
814 while(thread_command_flag[THREAD_SDRIP_INPUT] == THRFLAG_ACTIVE)
815   {
816 #if RUSAGE_OLD == TRUE
817   if(local_workload_counter != workload_counter)
818     {
819     local_workload_counter=workload_counter;
820     make_thread_times(THREAD_SDRIP_INPUT);
821     }
822 #endif
823   if(local_att_counter != sdr_att_counter)
824     {
825     if(thread_status_flag[THREAD_SYSCALL] == THRFLAG_SEM_WAIT &&
826        thread_command_flag[THREAD_SYSCALL] == THRFLAG_ACTIVE)
827       {
828       thread_command_flag[THREAD_SYSCALL]=THRFLAG_SET_SDRIP_ATT;
829       lir_set_event(EVENT_SYSCALL);
830       }
831     if( thread_status_flag[THREAD_SYSCALL] == THRFLAG_IDLE &&
832         thread_command_flag[THREAD_SYSCALL]==THRFLAG_SET_SDRIP_ATT)
833       {
834       local_att_counter=sdr_att_counter;
835       thread_command_flag[THREAD_SYSCALL]=THRFLAG_ACTIVE;
836       lir_set_event(EVENT_SYSCALL);
837       }
838     }
839   if(local_nco_counter != sdr_nco_counter)
840     {
841     if(thread_status_flag[THREAD_SYSCALL] == THRFLAG_SEM_WAIT &&
842        thread_command_flag[THREAD_SYSCALL] == THRFLAG_ACTIVE)
843       {
844       thread_command_flag[THREAD_SYSCALL]=THRFLAG_SET_SDRIP_FREQUENCY;
845       lir_set_event(EVENT_SYSCALL);
846       }
847     if( thread_status_flag[THREAD_SYSCALL] == THRFLAG_IDLE &&
848         thread_command_flag[THREAD_SYSCALL]==THRFLAG_SET_SDRIP_FREQUENCY)
849       {
850       local_nco_counter=sdr_nco_counter;
851       thread_command_flag[THREAD_SYSCALL]=THRFLAG_ACTIVE;
852       lir_set_event(EVENT_SYSCALL);
853       }
854     }
855   ichk=(short int*)tmpbuf;
856 recv_again:;
857   i=recv(udp_fd, tmpbuf, pkg_size, 0);
858   if(kill_all_flag)goto sdrip_udpbuf_exit;
859   if(ichk[0] != pkg_chk)goto recv_again;
860 // In case the packet number is totally wrong, just
861 // set pkg_number to the current package number.
862   if(pkg_number-ichk[1] < 0 || pkg_number-ichk[1]> 15)pkg_number=ichk[1];
863 // Fill zeroes in case the packet number does not agree
864 // with pkg_number and increase pkg_number until we
865 // reach agreement. Then fill the current data from the buffer.
866   if(sdrip.format == 16)
867     {
868     while(pkg_number != ichk[1])
869       {
870       for(i=4; i<pkg_size; i++)
871         {
872         timf1_char[timf1_netptr]=0;
873         timf1_netptr=(timf1_netptr+1)&timf1_bytemask;
874         }
875       pkg_number++;
876       }
877     for(i=4; i<pkg_size; i++)
878       {
879       timf1_char[timf1_netptr]=tmpbuf[i];
880       timf1_netptr=(timf1_netptr+1)&timf1_bytemask;
881       }
882     pkg_number++;
883 
884     }
885   else
886     {
887     while(pkg_number != ichk[1])
888       {
889       for(i=4; i<pkg_size; i+=3)
890         {
891         timf1_char[timf1_netptr  ]=0;
892         timf1_char[timf1_netptr+1]=0;
893         timf1_char[timf1_netptr+2]=0;
894         timf1_char[timf1_netptr+3]=0;
895         timf1_netptr=(timf1_netptr+4)&timf1_bytemask;
896         }
897       pkg_number++;
898       }
899     for(i=4; i<pkg_size; i+=3)
900       {
901       timf1_char[timf1_netptr  ]=0;
902       timf1_char[timf1_netptr+1]=tmpbuf[i  ];
903       timf1_char[timf1_netptr+2]=tmpbuf[i+1];
904       timf1_char[timf1_netptr+3]=tmpbuf[i+2];
905       timf1_netptr=(timf1_netptr+4)&timf1_bytemask;
906       }
907     pkg_number++;
908     }
909   while( ((timf1_netptr-timf1p_pa+timf1_bytes)&timf1_bytemask) >
910                                      2*snd[RXAD].block_bytes)
911     {
912 #include "input_speed.c"
913     finish_rx_read();
914     }
915   if(kill_all_flag) goto sdrip_udpbuf_exit;
916   }
917 sdrip_udpbuf_exit:;
918 free(tmpbuf);
919 sdrip_udp_exit:;
920 CLOSE_FD(udp_fd);
921 sdrip_exit:;
922 // Set the receiver state.
923 msg[0]=0x08;
924 msg[1]=0x00;
925 msg[2]=0x18;
926 msg[3]=0x00;
927 msg[4]=0x80;        // Set complex contigous data.
928 msg[5]=0x01;        // set run/stop to STOP
929 if(sdrip.format == 16)
930   {
931   msg[6]=0x00;
932   }
933 else
934   {
935   msg[6]=0x80;
936   }
937 msg[7]=0x01;
938 net_write(sdrip_fd,msg,8);
939 lir_sleep(100000);
940 recv(sdrip_fd,textbuf,80,0);
941 sdrip_error_exit:;
942 close_sdrip();
943 sdrip_init_error_exit:;
944 if(errcod != 0)lirerr(errcod);
945 thread_status_flag[THREAD_SDRIP_INPUT]=THRFLAG_RETURNED;
946 while(thread_command_flag[THREAD_SDRIP_INPUT] != THRFLAG_NOT_ACTIVE)
947   {
948   lir_sleep(1000);
949   }
950 }
951