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