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 // ********************* sockaddr and sockaddr_in **********************
25 // struct sockaddr {
26 // unsigned short sa_family; // address family, AF_xxx
27 // char sa_data[14]; // 14 bytes of protocol address
28 // sa_family can be a variety of things,
29 // but it'll be AF_INET for everything we do
30 // in this document. sa_data contains a destination
31 // address and port number for the socket.
32 // This is rather unwieldy since you don't
33 // want to tediously pack the address in
34 // the sa_data by hand.
35 //
36 // To deal with struct sockaddr, programmers
37 // created a parallel structure:
38 // struct sockaddr_in ("in" for "Internet".)
39 // struct sockaddr_in {
40 // short int sin_family; // Address family
41 // unsigned short int sin_port; // Port number
42 // struct in_addr sin_addr; // Internet address
43 // unsigned char sin_zero[8]; // Same size as struct sockaddr
44 // **********************************************************************
45
46 #include <ctype.h>
47 #include <unistd.h>
48 #include "globdef.h"
49
50 #if(OSNUM == OSNUM_WINDOWS)
51 #include <windows.h>
52 #include <winsock.h>
53 #define RECV_FLAG 0
54 typedef struct{
55 struct in_addr imr_multiaddr; /* IP multicast address of group */
56 struct in_addr imr_interface; /* local IP address of interface */
57 }IP_MREQ;
58 WSADATA wsadata;
59 #ifndef IP_ADD_MEMBERSHIP
60 #define IP_ADD_MEMBERSHIP 12
61 #endif
62 #define INVSOCK INVALID_SOCKET
63 #define CLOSE_FD closesocket
64 #endif
65
66 #if(OSNUM == OSNUM_LINUX)
67 #include <fcntl.h>
68 #include <sys/ioctl.h>
69 #include <sys/socket.h>
70 #include <arpa/inet.h>
71 #include <netinet/in.h>
72 #include <sys/time.h>
73 #include <string.h>
74 #include <netdb.h>
75 #include <unistd.h>
76 #include <semaphore.h>
77 #include <pthread.h>
78 #include <errno.h>
79 #include <unistd.h>
80 #include <string.h>
81 #ifdef MSG_WAITALL
82 #define RECV_FLAG MSG_WAITALL
83 #else
84 #define RECV_FLAG 0
85 #endif
86 #define IP_MREQ struct ip_mreq
87 #define INVSOCK -1
88 #define CLOSE_FD close
89 #endif
90
91 #include "uidef.h"
92 #include "fft1def.h"
93 #include "fft2def.h"
94 #include "vernr.h"
95 #include "caldef.h"
96 #include "screendef.h"
97 #include "rusage.h"
98 #include "thrdef.h"
99 #include "keyboard_def.h"
100 #include "seldef.h"
101 #include "options.h"
102 #include "sigdef.h"
103
104 // ******************** addresses and ports ***************************
105 // These defininitions should be in agreement with current rules.
106 #define NET_MULTI_MINPORT 50000
107 #define NET_MULTI_MAXPORT 65000
108 #define CONNPORT 49812 // This is outside the range ..MINPORT to ..MAXPORT
109 #define DEFAULT_MULTI_GROUP "239.255.0.00"
110 #define MULTI_GROUP_OFFSET 10
111 char netsend_rx_multi_group[20]=DEFAULT_MULTI_GROUP;
112 char netrec_rx_multi_group[20]=DEFAULT_MULTI_GROUP;
113 char par_netsend_filename[]={"par_netsend_ip"};
114 char par_netrec_filename[]={"par_netrec_ip"};
115 // ***********************************************************************
116
117 // Line numbers for network parameters (for par_network)
118 #define NNLINE 4
119 #define NN_BASE 1
120 #define NN_SENDAD 2
121 #define NN_RECAD 3
122 #define NN_OUT_ZERO 4 // Defines the port address offsets.
123 #define NN_RAWOUT16 4
124 #define NN_RAWOUT18 5
125 #define NN_RAWOUT24 6
126 #define NN_FFT1OUT 7
127 #define NN_TIMF2OUT 8
128 #define NN_FFT2OUT 9
129 #define NN_BASEBOUT 10
130 #define NN_BASEBRAWOUT 11
131 #define NN_RX 12
132
133 struct sockaddr_in netsend_addr_rxraw16;
134 struct sockaddr_in netsend_addr_rxraw18;
135 struct sockaddr_in netsend_addr_rxraw24;
136 struct sockaddr_in netsend_addr_rxfft1;
137 struct sockaddr_in netsend_addr_rxtimf2;
138 struct sockaddr_in netsend_addr_rxfft2;
139 struct sockaddr_in netsend_addr_rxbaseb;
140 struct sockaddr_in netsend_addr_rxbasebraw;
141 struct sockaddr_in netrec_addr;
142 struct sockaddr_in netmaster_addr;
143 struct sockaddr_in slave_addr;
144
145 #define NETHEADER_SIZE 6
146 #define FFT1_INFOSIZ 3
147 fd_set master_readfds;
148 fd_set rx_input_fds;
149
150 void net_read( void *buf, int bytes);
151 void net_write(FD fd, void *buf, int size);
152
153 ;
154 int no_of_net_freq=0;
155 int no_of_subslaves=0;
156 double net_start_time;
157 int net_write_errors;
158
159
chk_send(int fd,char * buf,int len,struct sockaddr * to,int tolen)160 void chk_send(int fd, char *buf, int len, struct sockaddr *to,
161 int tolen)
162 {
163 #if(OSNUM == OSNUM_WINDOWS)
164 int ierr;
165 #endif
166 double dt1;
167 char s[80];
168 int kk, net_written;
169 float t1;
170 net_written=sendto(fd, buf ,len, 0, to, tolen);
171 if(net_written==len)return;
172 // There was an error.
173 // We do not expect short writes, but try to handle them anywaqy.
174 // The "normal" error would be that the call would block.
175 // Wait here for the time of maximum 2 blocks of our input data stream
176 // to see if the situation improves.
177 if(net_written == -1)
178 {
179 #if(OSNUM == OSNUM_WINDOWS)
180 ierr=WSAGetLastError();
181 if(ierr != WSAEWOULDBLOCK)goto show_errors;
182 #endif
183 #if(OSNUM == OSNUM_LINUX)
184 if(errno != EAGAIN)goto show_errors;
185 #endif
186 kk=0;
187 }
188 else
189 {
190 kk=net_written;
191 }
192 t1=0.5/snd[RXAD].interrupt_rate;
193 dt1=current_time()-netstart_time-accumulated_netwait_time;
194 while(dt1 > 0)
195 {
196 // sleep in time chunks that are at least half the time to fill
197 // our A/D input buffer.
198 // (It would be possible to actually monitor the buffer pointers,
199 // but since there are several sound systems there would be
200 // several routines to write.)
201 lir_sleep(1000*t1);
202 net_written=sendto(fd, &buf[kk] ,len-kk, 0, to, tolen);
203 if(kill_all_flag)return;
204 if(net_written == -1)
205 {
206 #if(OSNUM == OSNUM_WINDOWS)
207 ierr=WSAGetLastError();
208 if(ierr != WSAEWOULDBLOCK)goto show_errors;
209 #endif
210 #if(OSNUM == OSNUM_LINUX)
211 if(errno != EAGAIN)goto show_errors;
212 #endif
213 }
214 else
215 {
216 kk+=net_written;
217 }
218 if(kk == len)return;
219 dt1=current_time()-netstart_time-accumulated_netwait_time;
220 }
221 #if DUMPFILE == TRUE
222 DEB" short write %d (%d)",kk, len);
223 #endif
224 return;
225 show_errors:;
226 net_write_errors++;
227 sprintf(s,"NET_WRITE ERROR %d",net_write_errors);
228 wg_error(s,WGERR_NETWR);
229 #if DUMPFILE == TRUE
230 // ***********************************************
231 DEB"\nNetwork write error: ");
232 #if(OSNUM == OSNUM_WINDOWS)
233 DEB"sendto error code %d ",ierr);
234 switch (ierr)
235 {
236 case WSAEINVAL:
237 DEB"WSAEINVAL");
238 break;
239
240 case WSAEINTR:
241 DEB"WSAEINTR");
242 break;
243
244 case WSAEINPROGRESS:
245 DEB"WSAEINPROGRESS");
246 break;
247
248 case WSAEFAULT:
249 DEB"WSAEFAULT");
250 break;
251
252 case WSAENETRESET:
253 DEB"WSAENETRESET");
254 break;
255
256 case WSAENOBUFS:
257 DEB"WSAENOBUFS");
258 break;
259
260 case WSAENOTCONN:
261 DEB"WSAENOTCONN");
262 break;
263
264 case WSAENOTSOCK:
265 DEB"WSAENOTSOCK");
266 break;
267
268 case WSAEOPNOTSUPP:
269 DEB"WSAEOPNOTSUPP");
270 break;
271
272 case WSAESHUTDOWN:
273 DEB"WSAESHUTDOWN");
274 break;
275
276 case WSAEWOULDBLOCK:
277 DEB"WSAEWOULDBLOCK");
278 break;
279
280 case WSAEMSGSIZE:
281 DEB"WSAEMSGSIZE");
282 break;
283
284 case WSAECONNABORTED:
285 DEB"WSAECONNABORTED");
286 break;
287
288 case WSAECONNRESET:
289 DEB"WSAECONNRESET");
290 break;
291
292 case WSAEADDRNOTAVAIL:
293 DEB"WSAEADDRNOTAVAIL");
294 break;
295
296 case WSAENETUNREACH:
297 DEB"WSAENETUNREACH");
298 break;
299
300 case WSAEHOSTUNREACH:
301 DEB"WSAEHOSTUNREACH");
302 break;
303
304 case WSAETIMEDOUT:
305 DEB"WSAETIMEDOUT");
306 break;
307
308 case WSANOTINITIALISED:
309 DEB"WSANOTINITIALISED");
310 break;
311
312 case WSAENETDOWN:
313 DEB"WSAENETDOWN");
314 break;
315
316 case WSAEACCES:
317 DEB"WSAEACCES");
318 break;
319
320 case WSAEAFNOSUPPORT:
321 DEB"WSAEAFNOSUPPORT");
322 break;
323
324 case WSAEDESTADDRREQ:
325 DEB"WSAEDESTADDRREQ");
326 break;
327
328 default:
329 DEB"unknown");
330 }
331 #endif
332 #if(OSNUM == OSNUM_LINUX)
333 switch (errno)
334 {
335 case ENETUNREACH:
336 DEB"Network unreachable");
337 break;
338
339 case EAGAIN:
340 DEB"Operation would block");
341 break;
342
343 case EINTR:
344 DEB"Interrupted by a signal");
345 break;
346
347 default:
348 DEB" errno=%d",errno);
349 }
350 #endif
351 #endif
352 }
353
lir_send_raw16(void)354 void lir_send_raw16(void)
355 {
356 chk_send(netfd.send_rx_raw16,(char*)&net_rxdata_16,sizeof(NET_RX_STRUCT),
357 (struct sockaddr *) &netsend_addr_rxraw16,
358 sizeof(netsend_addr_rxraw16));
359 }
360
lir_send_raw18(void)361 void lir_send_raw18(void)
362 {
363 chk_send(netfd.send_rx_raw18,(char*)&net_rxdata_18,sizeof(NET_RX_STRUCT),
364 (struct sockaddr *) &netsend_addr_rxraw18,
365 sizeof(netsend_addr_rxraw18));
366 }
367
lir_send_raw24(void)368 void lir_send_raw24(void)
369 {
370 chk_send(netfd.send_rx_raw24,(char*)&net_rxdata_24,sizeof(NET_RX_STRUCT),
371 (struct sockaddr *) &netsend_addr_rxraw24,
372 sizeof(netsend_addr_rxraw24));
373 }
374
lir_send_fft1(void)375 void lir_send_fft1(void)
376 {
377 chk_send(netfd.send_rx_fft1,(char*)&net_rxdata_fft1,sizeof(NET_RX_STRUCT),
378 (struct sockaddr *) &netsend_addr_rxfft1,
379 sizeof(netsend_addr_rxfft1));
380 }
381
lir_send_timf2(void)382 void lir_send_timf2(void)
383 {
384 chk_send(netfd.send_rx_timf2,(char*)&net_rxdata_timf2,sizeof(NET_RX_STRUCT),
385 (struct sockaddr *) &netsend_addr_rxtimf2,
386 sizeof(netsend_addr_rxtimf2));
387 }
388
lir_send_fft2(void)389 void lir_send_fft2(void)
390 {
391 chk_send(netfd.send_rx_fft2,(char*)&net_rxdata_fft2,sizeof(NET_RX_STRUCT),
392 (struct sockaddr *) &netsend_addr_rxfft2,
393 sizeof(netsend_addr_rxfft2));
394 }
395
lir_send_baseb(void)396 void lir_send_baseb(void)
397 {
398 chk_send(netfd.send_rx_baseb,(char*)&net_rxdata_baseb,sizeof(NET_RX_STRUCT),
399 (struct sockaddr *) &netsend_addr_rxbaseb,
400 sizeof(netsend_addr_rxbaseb));
401 }
402
lir_send_basebraw(void)403 void lir_send_basebraw(void)
404 {
405 chk_send(netfd.send_rx_basebraw,(char*)&net_rxdata_basebraw,
406 sizeof(NET_RX_STRUCT), (struct sockaddr *) &netsend_addr_rxbasebraw,
407 sizeof(netsend_addr_rxbasebraw));
408 }
409
close_network_sockets(void)410 void close_network_sockets(void)
411 {
412 int i;
413 FD *net_fds;
414 if(ui.network_flag==0)return;
415 net_fds=(FD*)(&netfd);
416 for(i=0; i<MAX_NET_FD; i++)
417 {
418 if(net_fds[i] != INVSOCK)
419 {
420 CLOSE_FD(net_fds[i]);
421 net_fds[i]=INVSOCK;
422 }
423 }
424 #if(OSNUM == OSNUM_WINDOWS)
425 WSACleanup();
426 #endif
427 }
428
net_input_error(void)429 void net_input_error(void)
430 {
431 char s[80];
432 net_no_of_errors++;
433 if(net_no_of_errors > 2)
434 {
435 sprintf(s,"Network error %d",net_no_of_errors-2);
436 wg_error(s,WGERR_RXIN);
437 }
438 }
439
440 #define MAX_FREQLIST_TIME 3
441 #define NETFREQ_TOL 10000
442
update_freqlist(void)443 void update_freqlist(void)
444 {
445 float t1;
446 int i, j, k, m, xpos;
447 int tmp_curx[MAX_FREQLIST];
448 // Data from netfreq_list will be distributed on the network.
449 // When we run as a master, netslaves_selfreq[] contains
450 // the frequencies reported to us by slaves.
451 // A value of -1 means that no frequency is selected.
452 // We may also have frequencies that belong to subslaves
453 // in netfreq_list.
454 // Start by removing old entries from both lists.
455 t1=current_time()-net_start_time;
456 i=0;
457 while(i<no_of_netslaves)
458 {
459 if(t1-netslaves_time[i] > MAX_FREQLIST_TIME)
460 {
461 netslaves_selfreq[i]=-1;
462 }
463 i++;
464 }
465 i=0;
466 j=MAX_FREQLIST-1;
467 while(netfreq_list[i] >= 0)
468 {
469 if(t1-netfreq_time[i] > MAX_FREQLIST_TIME)
470 {
471 netfreq_list[i]=-1;
472 if(j != MAX_FREQLIST-1)j=i;
473 }
474 i++;
475 }
476 if(j != MAX_FREQLIST-1)
477 {
478 k=j+1;
479 while(k<i)
480 {
481 if(t1-netfreq_time[i] <= MAX_FREQLIST_TIME)
482 {
483 netfreq_list[j]=netfreq_list[k];
484 netfreq_time[j]=netfreq_time[k];
485 j++;
486 }
487 k++;
488 }
489 }
490 // Make sure that all frequencies that we have in netslaves_selfreq
491 // are present in netfreq_list. Update to the most recent value
492 // if we are within NETFREQ_TOL
493 i=0;
494 while(i<no_of_netslaves)
495 {
496 if( netslaves_selfreq[i]>=0 )
497 {
498 j=0;
499 while(netfreq_list[j] >= 0)
500 {
501 if(abs(netfreq_list[j]-netslaves_selfreq[i]) < NETFREQ_TOL)
502 {
503 netfreq_list[j]=netslaves_selfreq[i];
504 netfreq_time[j]=netslaves_time[i];
505 goto updated;
506 }
507 j++;
508 }
509 if(j >= MAX_FREQLIST)
510 {
511 lirerr(1254);
512 return;
513 }
514 netfreq_list[j]=netslaves_selfreq[i];
515 netfreq_time[j]=netslaves_time[i];
516 }
517 updated:;
518 i++;
519 }
520 k=0;
521 m=0;
522 // Compute cursor locations.
523 while(netfreq_list[k] >= 0)
524 {
525 xpos=0.5+wg_first_xpixel+(0.001*netfreq_list[k]-wg_first_frequency)
526 /wg_hz_per_pixel;
527 if(xpos > wg_first_xpixel && xpos < wg_last_xpixel)
528 {
529 tmp_curx[m]=xpos;
530 m++;
531 }
532 k++;
533 }
534 while(sc[SC_SHOW_FFT1]!=sd[SC_SHOW_FFT1])
535 {
536 if(kill_all_flag ||
537 thread_command_flag[THREAD_LIR_SERVER] != THRFLAG_ACTIVE)return;
538 lir_sleep(10000);
539 }
540 // Remove cursors no longer present.
541 for(i=0; i<MAX_FREQLIST; i++)
542 {
543 if(new_netfreq_curx[i] >= 0)
544 {
545 for(j=0; j<m; j++)
546 {
547 if( tmp_curx[j] == new_netfreq_curx[i])
548 {
549 k=1;
550 tmp_curx[j]=-1;
551 goto nxt_i;
552 }
553 }
554 new_netfreq_curx[i]=-1;
555 }
556 nxt_i:;
557 }
558 // Add new cursors.
559 j=0;
560 for(i=0; i<m; i++)
561 {
562 if(tmp_curx[i] >= 0)
563 {
564 while(new_netfreq_curx[j] >= 0)j++;
565 new_netfreq_curx[j]=tmp_curx[i];
566 j++;
567 }
568 }
569 // Do not show slaves that listen to our own frequency.
570 for(j=0; j<MAX_FREQLIST; j++)
571 {
572 if(new_netfreq_curx[j] >= 0)
573 {
574 for(i=0; i<genparm[MIX1_NO_OF_CHANNELS]; i++)
575 {
576 if(new_mix1_curx[i]==new_netfreq_curx[j])
577 {
578 new_netfreq_curx[j]=-1;
579 mix1_curx[i]=-1;
580 }
581 }
582 }
583 }
584 sc[SC_SHOW_FFT1]++;
585 lir_set_event(EVENT_SCREEN);
586 }
587
588
589
remove_from_freqlist(int ifr)590 void remove_from_freqlist(int ifr)
591 {
592 int j;
593 j=0;
594 while(netfreq_list[j] >= 0)
595 {
596 if(abs(netfreq_list[j]-ifr) < NETFREQ_TOL)
597 {
598 while(netfreq_list[j] >= 0)
599 {
600 netfreq_list[j]=netfreq_list[j+1];
601 j++;
602 }
603 if( (ui.network_flag&NET_RX_INPUT)!=0)
604 {
605 slave_msg.type=NETMSG_REMOVE_SUBSLAVE;
606 slave_msg.frequency=ifr;
607 net_write(netfd.master, &slave_msg, sizeof(slave_msg));
608 }
609 return;
610 }
611 j++;
612 }
613 }
614
net_send_slaves_freq(void)615 void net_send_slaves_freq(void)
616 {
617 int intbuf[MAX_NETSLAVES];
618 int i, k;
619 slave_msg.type=NETMSG_OWN_FREQ;
620 if(mix1_selfreq[0] >= 0)
621 {
622 slave_msg.frequency=1000*mix1_selfreq[0];
623 }
624 else
625 {
626 slave_msg.frequency=-1;
627 }
628 net_write(netfd.master, &slave_msg, sizeof(slave_msg));
629 if(kill_all_flag) return;
630 k=0;
631 for(i=0; i<no_of_netslaves; i++)
632 {
633 if( netslaves_selfreq[i]>=0 )
634 {
635 intbuf[k]=netslaves_selfreq[i];
636 k++;
637 }
638 }
639 if(k>0)
640 {
641 slave_msg.type=NETMSG_SUBSLAVE_FREQ;
642 slave_msg.frequency=k;
643 net_write(netfd.master, &slave_msg, sizeof(slave_msg));
644 if(kill_all_flag) return;
645 net_write(netfd.master, &intbuf, k*sizeof(int));
646 }
647 }
648
649
650
lir_netread_rxin(void * buf)651 void lir_netread_rxin(void *buf)
652 {
653 NET_RX_STRUCT *msg;
654 char s[80];
655 fd_set testfds;
656 struct timeval timeout;
657 int nbytes;
658 msg=(NET_RX_STRUCT*)buf;
659 while( !kill_all_flag )
660 {
661 testfds=rx_input_fds;
662 timeout.tv_sec=0;
663 timeout.tv_usec=300000;
664 if( select(FD_SETSIZE, &testfds, (fd_set *)0,
665 (fd_set *)0, &timeout) > 0)
666 {
667 if(FD_ISSET(netfd.rec_rx,&testfds))
668 {
669 nbytes=recv(netfd.rec_rx,buf,sizeof(NET_RX_STRUCT), RECV_FLAG);
670 if(nbytes != sizeof(NET_RX_STRUCT))
671 {
672 sprintf(s,"NET RX ERROR. Received %d Expected %d",
673 nbytes,(int)sizeof(NET_RX_STRUCT));
674 lir_text(0,10,s);
675 lir_text(0,11,"Incompatible Linrad version?");
676 }
677 if(fg.passband_center != msg[0].passband_center ||
678 fg.passband_direction != msg[0].passband_direction ||
679 fft1_direction != fg.passband_direction)
680 {
681 fg.passband_center = msg[0].passband_center;
682 fg.passband_direction = msg[0].passband_direction;
683 fft1_direction=fg.passband_direction;
684 }
685 return;
686 }
687 }
688 }
689 }
690
691
thread_rx_fft1_netinput(void)692 void thread_rx_fft1_netinput(void)
693 {
694 #if RUSAGE_OLD == TRUE
695 int local_workload_counter;
696 #endif
697 int rxin_local_workload_reset;
698 int i, k;
699 int read_time;
700 float *net_floatbuf;
701 double read_start_time,total_reads;
702 int timing_loop_counter,timing_loop_counter_max,initial_skip_flag;
703 unsigned int netrd_fft1_ia;
704 int netrd_fft1_ib;
705 unsigned short int block_cnt;
706 #if OSNUM == OSNUM_LINUX
707 clear_thread_times(THREAD_RX_FFT1_NETINPUT);
708 #endif
709 #if RUSAGE_OLD == TRUE
710 local_workload_counter=workload_counter;
711 #endif
712 while( all_threads_started != TRUE)
713 {
714 lir_sleep(30000);
715 if(kill_all_flag) goto fft1net_rxin_error_exit;
716 }
717 net_floatbuf=(float*)&net_rxdata_fft1.buf[0];
718 netrd_fft1_ia=0;
719 lir_netread_rxin(&net_rxdata_fft1);
720 if(kill_all_flag) goto fft1net_rxin_error_exit;
721 netrd_fft1_ib=0;
722 block_cnt=net_rxdata_fft1.block_no;
723 #include "timing_setup.c"
724 timing_loop_counter_max=ui.rx_ad_speed*2*sizeof(float)
725 /(NET_MULTICAST_PAYLOAD*(1-fft1_interleave_ratio));
726 if(timing_loop_counter_max == 0)timing_loop_counter_max=1;
727 if( (ui.rx_input_mode&DWORD_INPUT) != 0)timing_loop_counter_max*=2;
728 timing_loop_counter=timing_loop_counter_max;
729 thread_status_flag[THREAD_RX_FFT1_NETINPUT]=THRFLAG_ACTIVE;
730 while(thread_command_flag[THREAD_RX_FFT1_NETINPUT] == THRFLAG_ACTIVE)
731 {
732 readfft1:;
733 #include "input_speed.c"
734 #if RUSAGE_OLD == TRUE
735 if(local_workload_counter != workload_counter)
736 {
737 local_workload_counter=workload_counter;
738 make_thread_times(THREAD_RX_FFT1_NETINPUT);
739 }
740 #endif
741 while(netrd_fft1_ia<NET_MULTICAST_PAYLOAD/sizeof(float))
742 {
743 fft1_float[fft1_pa+netrd_fft1_ib ]=net_floatbuf[netrd_fft1_ia ];
744 netrd_fft1_ib++;
745 netrd_fft1_ia++;
746 if(netrd_fft1_ib >= fft1_block)goto new_transform;
747 }
748 netrd_fft1_ia=0;
749 lir_netread_rxin(&net_rxdata_fft1);
750 if(kill_all_flag) goto fft1net_rxin_error_exit;
751 block_cnt++;
752 k=net_rxdata_fft1.ptr/(int)(sizeof(float));
753 if( block_cnt != net_rxdata_fft1.block_no || netrd_fft1_ib!=k)
754 {
755 // The block number (or data pointer) is incorrect. Some data is lost!!
756 net_input_error();
757 i=net_rxdata_fft1.block_no-block_cnt;
758 i=(i+0x10000)&0xffff;
759 i*=NET_MULTICAST_PAYLOAD/sizeof(float);
760 i+=k-netrd_fft1_ib;
761 if(i>0 && i<2*fft1_block)
762 {
763 // We have lost less than two transforms.
764 // Fill in zeroes and update pointers. The user may not notice.....
765 while(i>0)
766 {
767 i--;
768 fft1_float[fft1_pa+netrd_fft1_ib ]=0;
769 netrd_fft1_ib++;
770 netrd_fft1_ia++;
771 if(netrd_fft1_ia>=NET_MULTICAST_PAYLOAD/sizeof(float))
772 {
773 netrd_fft1_ia=0;
774 block_cnt++;
775 }
776 if(netrd_fft1_ib >= fft1_block)
777 {
778 netrd_fft1_ib=0;
779 fft1_pa=(fft1_pa+fft1_block)&fft1_mask;
780 fft1_na=fft1_pa/fft1_block;
781 if(fft1_nm != fft1n_mask)fft1_nm++;
782 lir_set_event(EVENT_TIMF1);
783 }
784 }
785 }
786 else
787 {
788 block_cnt=net_rxdata_fft1.block_no;
789 netrd_fft1_ib=net_rxdata_fft1.ptr/sizeof(float);
790 }
791 }
792 goto readfft1;
793 new_transform:;
794 netrd_fft1_ib=0;
795 fft1_pa=(fft1_pa+fft1_block)&fft1_mask;
796 fft1_na=fft1_pa/fft1_block;
797 if(fft1_nm != fft1n_mask)fft1_nm++;
798 lir_set_event(EVENT_TIMF1);
799 if(kill_all_flag) goto fft1net_rxin_error_exit;
800 read_time=ms_since_midnight(FALSE);
801 if(abs(latest_listsend_time-read_time) > 1500)
802 {
803 latest_listsend_time=read_time;
804 net_send_slaves_freq();
805 }
806 }
807 fft1net_rxin_error_exit:;
808 CLOSE_FD(netfd.rec_rx);
809 netfd.rec_rx=-1;
810 thread_status_flag[THREAD_RX_FFT1_NETINPUT]=THRFLAG_RETURNED;
811 while(thread_command_flag[THREAD_RX_FFT1_NETINPUT] != THRFLAG_NOT_ACTIVE)
812 {
813 lir_sleep(1000);
814 }
815 }
816
817
818
thread_rx_raw_netinput(void)819 void thread_rx_raw_netinput(void)
820 {
821 #if RUSAGE_OLD == TRUE
822 int local_workload_counter;
823 #endif
824 int rxin_local_workload_reset;
825 int use_float;
826 int i;
827 int netrd_ia;
828 int netrd_ib;
829 unsigned short int block_cnt;
830 double read_start_time,total_reads;
831 int timing_loop_counter,timing_loop_counter_max,initial_skip_flag;
832 float *z;
833 #if OSNUM == OSNUM_LINUX
834 clear_thread_times(THREAD_RX_RAW_NETINPUT);
835 #endif
836 #if RUSAGE_OLD == TRUE
837 local_workload_counter=workload_counter;
838 #endif
839 while( all_threads_started != TRUE)
840 {
841 lir_sleep(30000);
842 if(kill_all_flag) goto rawnet_rxin_error_exit;
843
844 }
845 save_rw_bytes=(18*snd[RXAD].block_bytes)/32;
846 use_float=FALSE;
847 switch(ui.network_flag&NET_RX_INPUT)
848 {
849 case NET_RXIN_BASEB:
850 case NET_RXIN_RAW16:
851 lir_netread_rxin(&net_rxdata_16);
852 netrd_ib=net_rxdata_16.ptr;
853 netrd_ia=0;
854 block_cnt=net_rxdata_16.block_no;
855 break;
856
857 case NET_RXIN_RAW18:
858 lir_netread_rxin(&net_rxdata_18);
859 netrd_ib=net_rxdata_18.ptr;
860 netrd_ia=0;
861 block_cnt=net_rxdata_18.block_no;
862 break;
863
864 case NET_RXIN_BASEBRAW:
865 case NET_RXIN_RAW24:
866 lir_netread_rxin(&net_rxdata_24);
867 netrd_ib=net_rxdata_24.ptr;
868 netrd_ia=0;
869 block_cnt=net_rxdata_24.block_no;
870 break;
871
872 case NET_RXIN_TIMF2:
873 lir_netread_rxin(&net_rxdata_16);
874 netrd_ib=net_rxdata_16.ptr;
875 netrd_ia=0;
876 block_cnt=net_rxdata_16.block_no;
877 if(net_rxdata_16.userx_no < 0)use_float=TRUE;
878 break;
879
880 default:
881 lirerr(285613);
882 goto rawnet_rxin_error_exit;
883 }
884 #include "timing_setup.c"
885 timing_loop_counter_max=ui.rx_ad_speed*2*sizeof(float)
886 /(NET_MULTICAST_PAYLOAD*(1-fft1_interleave_ratio));
887 if(timing_loop_counter_max == 0)timing_loop_counter_max=1;
888 if( (ui.rx_input_mode&DWORD_INPUT) != 0)timing_loop_counter_max*=2;
889 timing_loop_counter=timing_loop_counter_max;
890 thread_status_flag[THREAD_RX_RAW_NETINPUT]=THRFLAG_ACTIVE;
891 while(thread_command_flag[THREAD_RX_RAW_NETINPUT] ==
892 THRFLAG_ACTIVE && !kill_all_flag)
893 {
894 #include "input_speed.c"
895 #if RUSAGE_OLD == TRUE
896 if(local_workload_counter != workload_counter)
897 {
898 local_workload_counter=workload_counter;
899 make_thread_times(THREAD_RX_RAW_NETINPUT);
900 }
901 #endif
902 switch(ui.network_flag&NET_RX_INPUT)
903 {
904 case NET_RXIN_BASEB:
905 case NET_RXIN_RAW16:
906 read16:;
907 while(netrd_ia<NET_MULTICAST_PAYLOAD)
908 {
909 rxin_char[netrd_ib ]=net_rxdata_16.buf[netrd_ia ];
910 rxin_char[netrd_ib+1]=net_rxdata_16.buf[netrd_ia+1];
911 netrd_ib+=2;
912 netrd_ia+=2;
913 if(netrd_ib >= snd[RXAD].block_bytes)goto read16x;
914 }
915 netrd_ia=0;
916 lir_netread_rxin(&net_rxdata_16);
917 if(kill_all_flag) goto rawnet_rxin_error_exit;
918 block_cnt++;
919 if( block_cnt != net_rxdata_16.block_no ||
920 (int)netrd_ib!=net_rxdata_16.ptr)
921 {
922 // The block number (or data pointer) is incorrect. Some data is lost!!
923 net_input_error();
924 i=net_rxdata_16.block_no-block_cnt;
925 i=(i+0x10000)&0xffff;
926 i*=NET_MULTICAST_PAYLOAD;
927 i+=net_rxdata_16.ptr-netrd_ib;
928 if(i>0 && i < 2*fft1_blockbytes)
929 {
930 // We have lost less than two transforms.
931 // Fill in zeroes and update pointers. The user will not notice.....
932 while( i>0)
933 {
934 i--;
935 rxin_char[netrd_ib ]=0;
936 rxin_char[netrd_ib+1]=0;
937 netrd_ib+=2;
938 netrd_ia+=2;
939 if(netrd_ia>=NET_MULTICAST_PAYLOAD)
940 {
941 netrd_ia=0;
942 block_cnt++;
943 }
944 if(netrd_ib >= snd[RXAD].block_bytes)
945 {
946 netrd_ib=0;
947 finish_rx_read();
948 }
949 }
950 }
951 else
952 {
953 block_cnt=net_rxdata_16.block_no;
954 netrd_ib=net_rxdata_16.ptr;
955 }
956 }
957 goto read16;
958 read16x:;
959 netrd_ib=0;
960 break;
961
962 case NET_RXIN_RAW18:
963 read18:;
964 while(netrd_ia<NET_MULTICAST_PAYLOAD)
965 {
966 rawsave_tmp[netrd_ib ]=net_rxdata_18.buf[netrd_ia ];
967 rawsave_tmp[netrd_ib+1]=net_rxdata_18.buf[netrd_ia+1];
968 netrd_ib+=2;
969 netrd_ia+=2;
970 if(netrd_ib >= save_rw_bytes)goto new_blk_18;
971 }
972 netrd_ia=0;
973 lir_netread_rxin(&net_rxdata_18);
974 if(kill_all_flag) goto rawnet_rxin_error_exit;
975 block_cnt++;
976 if( block_cnt != net_rxdata_18.block_no ||
977 (int)netrd_ib!=net_rxdata_18.ptr)
978 // The block number (or data pointer) is incorrect. Some data is lost!!
979 {
980 net_input_error();
981 i=net_rxdata_18.block_no-block_cnt;
982 i=(i+0x10000)&0xffff;
983 i*=NET_MULTICAST_PAYLOAD;
984 i+=net_rxdata_18.ptr-netrd_ib;
985 if(i>0 && i < 2*fft1_blockbytes*18/32)
986 {
987 // We have lost less than two transforms.
988 // Fill in zeroes and update pointers. The user will not notice.....
989 while( i > 0)
990 {
991 i--;
992 rawsave_tmp[netrd_ib ]=0;
993 rawsave_tmp[netrd_ib+1]=0;
994 netrd_ib+=2;
995 netrd_ia+=2;
996 if(netrd_ia>=NET_MULTICAST_PAYLOAD)
997 {
998 netrd_ia=0;
999 block_cnt++;
1000 }
1001 if(netrd_ib >= save_rw_bytes)
1002 {
1003 netrd_ib=0;
1004 expand_rawdat();
1005 finish_rx_read();
1006 }
1007 }
1008 }
1009 else
1010 {
1011 block_cnt=net_rxdata_18.block_no;
1012 netrd_ib=net_rxdata_18.ptr;
1013 }
1014 }
1015 goto read18;
1016 new_blk_18:;
1017 netrd_ib=0;
1018 expand_rawdat();
1019 break;
1020
1021 case NET_RXIN_BASEBRAW:
1022 case NET_RXIN_RAW24:
1023 read24:;
1024 while(netrd_ia<NET_MULTICAST_PAYLOAD)
1025 {
1026 rxin_char[netrd_ib ]=0;
1027 rxin_char[netrd_ib+1]=net_rxdata_24.buf[netrd_ia ];
1028 rxin_char[netrd_ib+2]=net_rxdata_24.buf[netrd_ia+1];
1029 rxin_char[netrd_ib+3]=net_rxdata_24.buf[netrd_ia+2];
1030 netrd_ib+=4;
1031 netrd_ia+=3;
1032 if(netrd_ib >= snd[RXAD].block_bytes)goto new_blk_24;
1033 }
1034 netrd_ia=0;
1035 lir_netread_rxin(&net_rxdata_24);
1036 if(kill_all_flag) goto rawnet_rxin_error_exit;
1037 block_cnt++;
1038 if( block_cnt != net_rxdata_24.block_no ||
1039 (int)netrd_ib!=net_rxdata_24.ptr)
1040 {
1041 // The block number (or data pointer) is incorrect. Some data is lost!!
1042 net_input_error();
1043 i=net_rxdata_24.block_no-block_cnt;
1044 i=(i+0x10000)&0xffff;
1045 i*=NET_MULTICAST_PAYLOAD;
1046 i+=net_rxdata_24.ptr-netrd_ib;
1047 if(i>0 && i < 2*fft1_blockbytes)
1048 {
1049 // We have lost less than two transforms.
1050 // Fill in zeroes and update pointers. The user will not notice.....
1051 while( i>0 )
1052 {
1053 rxin_char[netrd_ib ]=0;
1054 rxin_char[netrd_ib+1]=0;
1055 rxin_char[netrd_ib+2]=0;
1056 rxin_char[netrd_ib+3]=0;
1057 netrd_ib+=4;
1058 netrd_ia+=3;
1059 if(netrd_ia>=NET_MULTICAST_PAYLOAD)
1060 {
1061 netrd_ia=0;
1062 block_cnt++;
1063 }
1064 if(netrd_ib >= snd[RXAD].block_bytes)
1065 {
1066 netrd_ib=0;
1067 finish_rx_read();
1068 }
1069 }
1070 }
1071 else
1072 {
1073 block_cnt=net_rxdata_24.block_no;
1074 netrd_ib=net_rxdata_24.ptr;
1075 }
1076 }
1077 goto read24;
1078 new_blk_24:;
1079 netrd_ib=0;
1080 break;
1081
1082 case NET_RXIN_TIMF2:
1083 if(use_float)
1084 {
1085 z=(float*)net_rxdata_16.buf;
1086 readfloat:;
1087 while(netrd_ia<NET_MULTICAST_PAYLOAD)
1088 {
1089 rxin_int[netrd_ib/4]=256*z[netrd_ia/4];
1090 netrd_ib+=4;
1091 netrd_ia+=4;
1092 if(netrd_ib >= snd[RXAD].block_bytes)goto readfloatx;
1093 }
1094 netrd_ia=0;
1095 lir_netread_rxin(&net_rxdata_16);
1096 if(kill_all_flag) goto rawnet_rxin_error_exit;
1097 block_cnt++;
1098 if( block_cnt != net_rxdata_16.block_no ||
1099 (int)netrd_ib!=net_rxdata_16.ptr)
1100 {
1101 // The block number (or data pointer) is incorrect. Some data is lost!!
1102 net_input_error();
1103 i=net_rxdata_16.block_no-block_cnt;
1104 i=(i+0x10000)&0xffff;
1105 i*=NET_MULTICAST_PAYLOAD;
1106 i+=net_rxdata_16.ptr-netrd_ib;
1107 if(i>0 && i < 2*fft1_blockbytes)
1108 {
1109 // We have lost less than two transforms.
1110 // Fill in zeroes and update pointers. The user will not notice.....
1111 while( i>0)
1112 {
1113 i--;
1114 rawsave_tmp[netrd_ib ]=0;
1115 rawsave_tmp[netrd_ib+1]=0;
1116 netrd_ib+=2;
1117 netrd_ia+=2;
1118 if(netrd_ia>=NET_MULTICAST_PAYLOAD)
1119 {
1120 netrd_ia=0;
1121 block_cnt++;
1122 }
1123 if(netrd_ib >= snd[RXAD].block_bytes)
1124 {
1125 netrd_ib=0;
1126 finish_rx_read();
1127 }
1128 }
1129 }
1130 else
1131 {
1132 block_cnt=net_rxdata_16.block_no;
1133 netrd_ib=net_rxdata_16.ptr;
1134 }
1135 }
1136 goto readfloat;
1137 readfloatx:;
1138 netrd_ib=0;
1139
1140 }
1141 else
1142 {
1143 goto read16;
1144 }
1145 break;
1146 }
1147 finish_rx_read();
1148 }
1149 rawnet_rxin_error_exit:;
1150 CLOSE_FD(netfd.rec_rx);
1151 netfd.rec_rx=-1;
1152 thread_status_flag[THREAD_RX_RAW_NETINPUT]=THRFLAG_RETURNED;
1153 while(thread_command_flag[THREAD_RX_RAW_NETINPUT] != THRFLAG_NOT_ACTIVE)
1154 {
1155 lir_sleep(1000);
1156 }
1157 }
1158
thread_lir_server(void)1159 void thread_lir_server(void)
1160 {
1161 #if RUSAGE_OLD == TRUE
1162 int local_workload_counter;
1163 #endif
1164 FILE *file;
1165 int i, j, k, kk, ifr, ie;
1166 char s[80];
1167 float *tmpbuf;
1168 float t1;
1169 int intbuf[10+MAX_NETSLAVES];
1170 struct timeval timeout;
1171 FD client_sockfd;
1172 fd_set testfds;
1173 int nread;
1174 FD fd;
1175 int client_len;
1176 struct sockaddr_in client_address;
1177 int netdat[FFT1_INFOSIZ];
1178 int listupd_count;
1179 #if OSNUM == OSNUM_LINUX
1180 clear_thread_times(THREAD_LIR_SERVER);
1181 #endif
1182 #if RUSAGE_OLD == TRUE
1183 local_workload_counter=workload_counter;
1184 #endif
1185 net_start_time=current_time();
1186 listupd_count=0;
1187 thread_status_flag[THREAD_LIR_SERVER]=THRFLAG_ACTIVE;
1188 while(!kill_all_flag &&
1189 thread_command_flag[THREAD_LIR_SERVER] == THRFLAG_ACTIVE)
1190 {
1191 listupd_count++;
1192 if(listupd_count > 5)
1193 {
1194 listupd_count=0;
1195 update_freqlist();
1196 }
1197 testfds=master_readfds;
1198 timeout.tv_sec=0;
1199 timeout.tv_usec=300000;
1200 ie=select(FD_SETSIZE, &testfds, (fd_set *)0, (fd_set *)0, &timeout);
1201 if(ie > 0)
1202 {
1203 #if RUSAGE_OLD == TRUE
1204 if(local_workload_counter != workload_counter)
1205 {
1206 local_workload_counter=workload_counter;
1207 make_thread_times(THREAD_LIR_SERVER);
1208 }
1209 #endif
1210 if(FD_ISSET(netfd.any_slave,&testfds))
1211 {
1212 if(no_of_netslaves >= MAX_NETSLAVES)
1213 {
1214 lirerr(1270);
1215 goto netserver_error_exit;
1216 }
1217 client_len = sizeof(client_address);
1218 client_sockfd = accept(netfd.any_slave,
1219 (struct sockaddr *)&client_address, (void*)&client_len);
1220 FD_SET(client_sockfd, &master_readfds);
1221 netfd.slaves[no_of_netslaves]=client_sockfd;
1222 lir_fillbox(5*no_of_netslaves,0,3,3,10);
1223 no_of_netslaves++;
1224 }
1225 for(i = 0; i < no_of_netslaves; i++)
1226 {
1227 if(FD_ISSET(netfd.slaves[i],&testfds))
1228 {
1229 fd=netfd.slaves[i];
1230 {
1231 nread=recv(fd, (char*)&slave_msg, sizeof(slave_msg), MSG_PEEK);
1232 if(nread <= 0)
1233 {
1234 // A slave is disconnected.
1235 slave_cls:;
1236 if(netslaves_selfreq[i] >= 0)
1237 {
1238 remove_from_freqlist(netslaves_selfreq[i]);
1239 }
1240 j=i;
1241 while(j < no_of_netslaves-1)
1242 {
1243 netfd.slaves[j]=netfd.slaves[j+1];
1244 netslaves_selfreq[j]=netslaves_selfreq[j+1];
1245 netslaves_time[j]=netslaves_time[j+1];
1246 j++;
1247 }
1248 no_of_netslaves--;
1249 lir_fillbox(5*no_of_netslaves,0,3,3,0);
1250 CLOSE_FD(fd);
1251 FD_CLR(fd, &master_readfds);
1252 update_freqlist();
1253 listupd_count=0;
1254 }
1255 else
1256 {
1257 // Check that we get the setup information correctly
1258 // and exit if all seems ok.
1259 if(nread < (int)(sizeof(slave_msg)))
1260 {
1261 lirerr(886942);
1262 lir_sleep(10000);
1263 nread=recv(fd, (char*)&slave_msg, sizeof(slave_msg), MSG_PEEK);
1264 }
1265 if(nread == (int)(sizeof(slave_msg)))
1266 {
1267 recv(fd, (char*)&slave_msg, sizeof(slave_msg),0);
1268 switch (slave_msg.type)
1269 {
1270 case NETMSG_OWN_FREQ:
1271 for(i=0; i<no_of_netslaves; i++)
1272 {
1273 if(netfd.slaves[i] == fd)
1274 {
1275 ifr=slave_msg.frequency;
1276 if( netslaves_selfreq[i] != ifr &&
1277 netslaves_selfreq[i] >= 0)
1278 {
1279 remove_from_freqlist(netslaves_selfreq[i]);
1280 }
1281 netslaves_selfreq[i]=ifr;
1282 netslaves_time[i]=current_time()-net_start_time;
1283 }
1284 }
1285 update_freqlist();
1286 listupd_count=0;
1287 break;
1288
1289 case NETMSG_SUBSLAVE_FREQ:
1290 if(slave_msg.frequency <1)
1291 {
1292 lirerr(1256);
1293 goto netserver_error_exit;
1294 }
1295 if(slave_msg.frequency >MAX_NETSLAVES-1)
1296 {
1297 lirerr(1257);
1298 goto netserver_error_exit;
1299 }
1300 lir_sleep(30000);
1301 k=slave_msg.frequency;
1302 nread=recv(fd, (char*)&intbuf, k*sizeof(int), MSG_PEEK);
1303 if(nread == 0)goto slave_cls;
1304 if(nread == k*(int)(sizeof(int)))
1305 {
1306 recv(fd, (char*)&intbuf, k*sizeof(int),0);
1307 // Check if the frequency is already on the list.
1308 // And add it if it is missing.
1309 t1=current_time()-net_start_time;
1310 k--;
1311 while(k>=0)
1312 {
1313 i=0;
1314 while(netfreq_list[i] > 0)
1315 {
1316 if(abs(netfreq_list[i]-intbuf[k])<NETFREQ_TOL)
1317 {
1318 goto nextk;
1319 }
1320 i++;
1321 }
1322 while(netfreq_list[i] > 0)i++;
1323 if(i >= MAX_FREQLIST)
1324 {
1325 lirerr(1254);
1326 goto netserver_error_exit;
1327 }
1328 nextk:;
1329 netfreq_list[i]=intbuf[k];
1330 netfreq_time[i]=t1;
1331 k--;
1332 }
1333 update_freqlist();
1334 listupd_count=0;
1335 }
1336 else
1337 {
1338 recv(fd, (char*)&intbuf, nread,0);
1339 }
1340 break;
1341
1342 case NETMSG_REMOVE_SUBSLAVE:
1343 remove_from_freqlist(slave_msg.frequency);
1344 break;
1345
1346 case NETMSG_MODE_REQUEST:
1347 intbuf[0]=ui.rx_ad_speed;
1348 intbuf[1]=ui.rx_ad_channels;
1349 intbuf[2]=ui.rx_rf_channels;
1350 intbuf[3]=ui.rx_input_mode;
1351 intbuf[4]=snd[RXAD].block_bytes;
1352 intbuf[5]=fft1_size;
1353 intbuf[6]=fft1_n;
1354 intbuf[7]=genparm[FIRST_FFT_SINPOW];
1355 net_write(fd,intbuf,8*sizeof(int));
1356 if(kill_all_flag)goto netserver_error_exit;
1357 break;
1358
1359 case NETMSG_TIMF2MODE_REQUEST:
1360 intbuf[0]=ui.rx_ad_speed;
1361 intbuf[1]=2*ui.rx_rf_channels;
1362 intbuf[2]=ui.rx_rf_channels;
1363 intbuf[3]=IQ_DATA;
1364 if(swfloat)intbuf[3]+=DWORD_INPUT;
1365 if(ui.rx_rf_channels == 2)intbuf[3]+=TWO_CHANNELS;
1366 intbuf[4]=snd[RXAD].block_bytes;
1367 intbuf[5]=0;
1368 intbuf[6]=0;
1369 intbuf[7]=0;
1370 net_write(fd,intbuf,8*sizeof(int));
1371 if(kill_all_flag)goto netserver_error_exit;
1372 break;
1373
1374 case NETMSG_BASEBMODE_REQUEST:
1375 intbuf[0]=genparm[DA_OUTPUT_SPEED];
1376 intbuf[1]=2*ui.rx_rf_channels;
1377 intbuf[2]=ui.rx_rf_channels;
1378 intbuf[3]=IQ_DATA;
1379 if(ui.rx_rf_channels == 2)intbuf[3]+=TWO_CHANNELS;
1380 intbuf[4]=basebnet_block_bytes;
1381 intbuf[5]=0;
1382 intbuf[6]=0;
1383 intbuf[7]=0;
1384 net_write(fd,intbuf,8*sizeof(int));
1385 if(kill_all_flag)goto netserver_error_exit;
1386 break;
1387
1388 case NETMSG_BASEBRAWMODE_REQUEST:
1389 intbuf[0]=basebraw_sampling_speed+0.5;
1390 intbuf[1]=basebraw_ad_channels;
1391 intbuf[2]=basebraw_rf_channels;
1392 intbuf[3]=basebraw_mode;
1393 if(basebraw_rf_channels == 2)intbuf[3]+=TWO_CHANNELS;
1394 intbuf[4]=basebrawnet_block_bytes;
1395 intbuf[5]=0;
1396 intbuf[6]=0;
1397 intbuf[7]=0;
1398 net_write(fd,intbuf,8*sizeof(int));
1399 if(kill_all_flag)goto netserver_error_exit;
1400 break;
1401
1402 case NETMSG_CAL_REQUEST:
1403 if( (fft1_calibrate_flag&CALAMP) == CALAMP &&
1404 diskread_flag < 2)
1405 {
1406 make_filfunc_filename(s);
1407 file = fopen(s, "rb");
1408 if(file == NULL)
1409 {
1410 lirerr(1062);
1411 goto netserver_error_exit;
1412 }
1413 // Send a flag so the client knows data will come.
1414 s[0]=TRUE;
1415 net_write(fd,s,sizeof(char));
1416 if(kill_all_flag)goto netserver_error_exit;
1417 // Read 10 integers. Send only [7], a flag that will tell the client
1418 // whether the data is in the time or frequency domain and [0] and [1]
1419 // which is the size.
1420 i=fread(intbuf, sizeof(int),10,file);
1421 if(i != 10)
1422 {
1423 cal_error:;
1424 fclose(file);
1425 lirerr(1062);
1426 goto netserver_error_exit;
1427 }
1428 intbuf[2]=intbuf[7];
1429 net_write(fd,intbuf,3*sizeof(int));
1430 if(kill_all_flag)goto netserver_error_exit;
1431 if(intbuf[7] == 0)
1432 {
1433 k=intbuf[1];
1434 }
1435 else
1436 {
1437 k=intbuf[7];
1438 }
1439 kk=twice_rxchan*sizeof(float);
1440 tmpbuf=malloc(kk*k);
1441 if(tmpbuf == NULL)
1442 {
1443 lirerr(1290);
1444 goto netserver_error_exit;
1445 }
1446 i=fread(tmpbuf, kk, k, file);
1447 if(i != k)goto cal_error;
1448 lir_sched_yield();
1449 net_write(fd, tmpbuf, kk*k);
1450 if(kill_all_flag)goto netserver_error_exit;
1451 lir_sched_yield();
1452 i=fread(tmpbuf, sizeof(float),k, file);
1453 if(i != k)goto cal_error;
1454 lir_sched_yield();
1455 net_write(fd, tmpbuf, sizeof(float)*k);
1456 if(kill_all_flag)goto netserver_error_exit;
1457 fclose(file);
1458 free(tmpbuf);
1459 lir_sched_yield();
1460 }
1461 else
1462 {
1463 // Send a flag so the client knows there is no calibration function.
1464 s[0]=FALSE;
1465 net_write(fd,s,sizeof(char));
1466 }
1467 break;
1468
1469 case NETMSG_CALIQ_REQUEST:
1470 if( (fft1_calibrate_flag&CALIQ) == CALIQ &&
1471 diskread_flag < 2)
1472 {
1473 make_iqcorr_filename(s);
1474 file = fopen(s, "rb");
1475 if(file == NULL)
1476 {
1477 lirerr(1062);
1478 goto netserver_error_exit;
1479 }
1480 // Send a flag so the client knows data will come.
1481 s[0]=TRUE;
1482 net_write(fd,s,sizeof(char));
1483 // Read 10 integers. Send only the first, the number of segments for
1484 // the calibration function.
1485 i=fread(intbuf, sizeof(int),10,file);
1486 if(i != 10)goto cal_error;
1487 net_write(fd,intbuf,sizeof(int));
1488 kk=twice_rxchan*sizeof(float)*4*intbuf[0];
1489 tmpbuf=malloc(kk);
1490 if(tmpbuf == NULL)
1491 {
1492 lirerr(1291);
1493 goto netserver_error_exit;
1494 }
1495 i=fread(tmpbuf, 1, kk, file);
1496 if(i != kk)goto cal_error;
1497 fclose(file);
1498 lir_sched_yield();
1499 net_write(fd,tmpbuf, kk);
1500 lir_sched_yield();
1501 }
1502 else
1503 {
1504 s[0]=FALSE;
1505 net_write(fd,s,sizeof(char));
1506 }
1507 break;
1508
1509 case NETMSG_FFT1INFO_REQUEST:
1510 netdat[0]=genparm[FIRST_FFT_SINPOW];
1511 netdat[1]=genparm[FIRST_FFT_BANDWIDTH];
1512 netdat[2]=genparm[FIRST_FFT_VERNR];
1513 net_write(fd,netdat, FFT1_INFOSIZ*sizeof(int));
1514 break;
1515
1516 case NETMSG_SET_MASTER_FREQUENCY:
1517 t1=slave_msg.frequency;
1518 if(t1 < mix1_lowest_fq)t1=mix1_lowest_fq;
1519 if(t1 > mix1_highest_fq)t1=mix1_highest_fq;
1520 make_new_signal(0, t1);
1521 sc[SC_FREQ_READOUT]++;
1522 if(genparm[SECOND_FFT_ENABLE] != 0)sc[SC_HG_FQ_SCALE]++;
1523 if(genparm[AFC_ENABLE]==0)sc[SC_BG_FQ_SCALE]++;
1524 if(genparm[AFC_ENABLE]!=0)sc[SC_BG_FQ_SCALE]++;
1525 lir_set_event(EVENT_SCREEN);
1526 baseb_reset_counter++;
1527 break;
1528
1529 default:
1530 DEB"ILLEGAL NET MESSAGE");
1531 break;
1532 }
1533 }
1534 else
1535 {
1536 }
1537 }
1538 }
1539 }
1540 }
1541 }
1542 }
1543 netserver_error_exit:;
1544 for(i = 0; i < no_of_netslaves; i++)
1545 {
1546 fd=netfd.slaves[i];
1547 {
1548 CLOSE_FD(fd);
1549 }
1550 }
1551
1552
1553 thread_status_flag[THREAD_LIR_SERVER]=THRFLAG_RETURNED;
1554 while(thread_command_flag[THREAD_LIR_SERVER] != THRFLAG_NOT_ACTIVE)
1555 {
1556 lir_sleep(1000);
1557 }
1558 }
1559
read_netgroup(char * group,int group_offset,int verbose,char * filename)1560 void read_netgroup(char *group, int group_offset, int verbose, char *filename)
1561 {
1562 FILE *netad;
1563 char sep;
1564 char s[80], ss[400];
1565 int i, n, k;
1566 sprintf(group,"%s",DEFAULT_MULTI_GROUP);
1567 if(group_offset >=0)
1568 {
1569 sprintf(&group[MULTI_GROUP_OFFSET],"%d", group_offset);
1570 }
1571 else
1572 {
1573 netad=fopen(filename, "r");
1574 if(netad==NULL)
1575 {
1576 sprintf(s,"%s.txt",filename);
1577 netad=fopen(s, "r");
1578 if(netad == NULL)goto file_error;
1579 }
1580 k=fread(group,1,20,netad);
1581 fclose(netad);
1582 if(k < 7)goto file_error;
1583 i=0;
1584 n=0;
1585 while(i<k && (group[i] == '.' || (group[i] >='0' && group[i] <= '9')))
1586 {
1587 if(group[i] == '.')
1588 {
1589 n++;
1590 if(n > 3)
1591 {
1592 group[i]=0;
1593 i=18;
1594 }
1595 }
1596 i++;
1597 }
1598 if(i < 7)goto file_error;
1599 group[i]=0;
1600 }
1601 return;
1602 file_error:;
1603 if(verbose)
1604 {
1605 #if(OSNUM == OSNUM_LINUX)
1606 sep='/';
1607 #endif
1608 #if(OSNUM == OSNUM_WINDOWS)
1609 sep='\\';
1610 #endif
1611 clear_screen();
1612 sprintf(s,"Could not read file %s%c%s",getcwd(ss,400),sep,filename);
1613 lir_text(10,10,s);
1614 sprintf(s,"Create %s with a text editor.",filename);
1615 lir_text(10,11,s);
1616 lir_text(10,12,"One line only. Format: 10.0.0.35");
1617 sprintf(s,"Without the file Linrad will use %s",DEFAULT_MULTI_GROUP);
1618 lir_text(10,14,s);
1619 lir_text(20,16,press_any_key);
1620 await_keyboard();
1621 clear_screen();
1622 }
1623 }
1624
net_addr_strings(int vrb)1625 void net_addr_strings(int vrb)
1626 {
1627 read_netgroup(netsend_rx_multi_group, net.send_group, vrb, par_netsend_filename);
1628 read_netgroup(netrec_rx_multi_group, net.rec_group, vrb, par_netrec_filename);
1629 }
1630
read_netpar(void)1631 int read_netpar(void)
1632 {
1633 int i, j, k;
1634 FILE *file;
1635 int *netparm;
1636 char *parinfo;
1637 netparm=(int*)&net;
1638 file = fopen(network_filename, "rb");
1639 if (file == NULL)
1640 {
1641 net_default:;
1642 net.send_group=0;
1643 net.rec_group=0;
1644 net.port=NET_MULTI_MINPORT;
1645 net.send_raw=0;
1646 net.send_fft1=0;
1647 net.send_fft2=0;
1648 net.send_timf2=0;
1649 net.receive_raw=NET_RXIN_RAW16;
1650 net.receive_fft1=0;
1651 net.receive_baseb=0;
1652 net.receive_basebraw=0;
1653 net.receive_timf2=0;
1654 net.check=NET_VERNR;
1655 return FALSE;
1656 }
1657 else
1658 {
1659 parinfo=malloc(4096);
1660 if(parinfo == NULL)
1661 {
1662 fclose(file);
1663 lir_errcod=1078;
1664 return FALSE;
1665 }
1666 for(i=0; i<4096; i++) parinfo[i]=0;
1667 i=fread(parinfo,1,4095,file);
1668 fclose(file);
1669 file=NULL;
1670 if(i == 4095)
1671 {
1672 goto net_default;
1673 }
1674 k=0;
1675 for(i=0; i<MAX_NET_INTPAR; i++)
1676 {
1677 while(parinfo[k]==' ' ||
1678 parinfo[k]== '\n' )k++;
1679 j=0;
1680 while(parinfo[k]== net_intpar_text[i][j])
1681 {
1682 k++;
1683 j++;
1684 }
1685 if(net_intpar_text[i][j] != 0)goto net_default;
1686 while(parinfo[k]!='[')k++;
1687 sscanf(&parinfo[k],"[%d]",&netparm[i]);
1688 while(parinfo[k]!='\n')k++;
1689 }
1690 }
1691 if(net.send_group < -1 || net.send_group > 15)goto net_default;
1692 if(net.rec_group < -1 || net.rec_group > 15)goto net_default;
1693 if(net.port < NET_MULTI_MINPORT || net.port > NET_MULTI_MAXPORT)goto net_default;
1694 if(net.send_raw < 0 || net.send_raw >
1695 (NET_RXOUT_RAW16|NET_RXOUT_RAW18|NET_RXOUT_RAW24))goto net_default;
1696 if(net.send_fft1 != 0 && net.send_fft1 != NET_RXOUT_FFT1)goto net_default;
1697 if(net.send_fft2 != 0 && net.send_fft2 != NET_RXOUT_FFT2)goto net_default;
1698 if(net.send_timf2 != 0 && net.send_timf2 != NET_RXOUT_TIMF2)goto net_default;
1699 if(net.receive_raw != 0 &&
1700 net.receive_raw != NET_RXIN_RAW16 &&
1701 net.receive_raw != NET_RXIN_RAW18 &&
1702 net.receive_raw != NET_RXIN_RAW24 )goto net_default;
1703 if(net.receive_fft1 != 0 && net.receive_fft1 != NET_RXIN_FFT1)goto net_default;
1704 if(net.receive_baseb != 0 && net.receive_baseb != NET_RXIN_BASEB)goto net_default;
1705 if(net.receive_basebraw != 0 && net.receive_basebraw != NET_RXIN_BASEBRAW)goto net_default;
1706 if(net.receive_timf2 != 0 && net.receive_timf2 != NET_RXIN_TIMF2)goto net_default;
1707 i=0;
1708 if(net.receive_raw != 0)i++;
1709 if(net.receive_fft1 != 0)i++;
1710 if(net.receive_baseb != 0)i++;
1711 if(net.receive_basebraw != 0)i++;
1712 if(net.receive_timf2 != 0)i++;
1713 if(net.send_raw != 0 && (net.receive_raw+net.receive_fft1+net.receive_baseb+
1714 net.receive_basebraw+net.receive_timf2) != 0)goto net_default;
1715 if(net.send_fft1 != 0 && net.receive_fft1 != 0)goto net_default;
1716 if(net.check != NET_VERNR)goto net_default;
1717 return TRUE;
1718 }
1719
init_network(void)1720 void init_network(void)
1721 {
1722 fd_set fds, testfds;
1723 struct timeval timeout;
1724 int kk, mm, wtcnt;
1725 float *tmpbuf;
1726 int intbuf[10];
1727 char s[80];
1728 char *ss;
1729 IP_MREQ mreq;
1730 int i, j, k;
1731 int server_flag;
1732 unsigned char *ip;
1733 int nbytes;
1734 char msgx[sizeof(NET_RX_STRUCT)+2];
1735 NET_RX_STRUCT *msg;
1736 int *net_fds;
1737 #if(OSNUM == OSNUM_LINUX)
1738 unsigned int addrlen;
1739 #endif
1740 #if(OSNUM == OSNUM_WINDOWS)
1741 int addrlen;
1742 unsigned long int on;
1743 on=1;
1744 #endif
1745 net_fds=(int*)(&netfd);
1746 for(i=0; i<MAX_NET_FD; i++)
1747 {
1748 net_fds[i]=-1;
1749 }
1750 net_write_errors=0;
1751 no_of_netslaves=0;
1752 netfft1_blknum=0;
1753 netraw16_blknum=0;
1754 netraw18_blknum=0;
1755 netraw24_blknum=0;
1756 nettimf2_blknum=0;
1757 netfft2_blknum=0;
1758 netbaseb_blknum=0;
1759 netbasebraw_blknum=0;
1760 next_blkptr_16=0;
1761 next_blkptr_18=0;
1762 next_blkptr_24=0;
1763 next_blkptr_fft1=0;
1764 next_blkptr_baseb=0;
1765 next_blkptr_basebraw=0;
1766 netsend_ptr_16=0;
1767 netsend_ptr_18=0;
1768 netsend_ptr_24=0;
1769 netsend_ptr_fft1=0;
1770 netsend_ptr_timf2=0;
1771 netsend_ptr_fft2=0;
1772 netsend_ptr_baseb=0;
1773 netsend_ptr_basebraw=0;
1774 for(i=0; i<MAX_FREQLIST; i++)
1775 {
1776 netfreq_list[i]=-1;
1777 netfreq_curx[i]=-1;
1778 new_netfreq_curx[i]=-1;
1779 }
1780 latest_listsend_time=0;
1781 net_no_of_errors=0;
1782 msg=(NET_RX_STRUCT*)msgx;
1783 clear_screen();
1784 server_flag=FALSE;
1785 if(read_netpar()==FALSE)
1786 {
1787 lirerr(1265);
1788 return;
1789 }
1790 net_addr_strings(FALSE);
1791 #if(OSNUM == OSNUM_WINDOWS)
1792 if(WSAStartup(2, &wsadata) != 0)
1793 {
1794 lirerr(1263);
1795 return;
1796 }
1797 #endif
1798 if( (ui.network_flag & NET_RXOUT_RAW16) != 0)
1799 {
1800 if ((netfd.send_rx_raw16=socket(AF_INET,SOCK_DGRAM,0)) == INVSOCK)
1801 {
1802 lirerr(1249);
1803 return;
1804 }
1805 #if(OSNUM == OSNUM_WINDOWS)
1806 if (ioctlsocket(netfd.send_rx_raw16, FIONBIO, &on) < 0)lirerr(889666);
1807 #endif
1808 #if(OSNUM == OSNUM_LINUX)
1809 fcntl(netfd.send_rx_raw16, F_SETFD, O_NONBLOCK);
1810 #endif
1811 memset(&netsend_addr_rxraw16,0,sizeof(netsend_addr_rxraw16));
1812 netsend_addr_rxraw16.sin_family=AF_INET;
1813 netsend_addr_rxraw16.sin_addr.s_addr=inet_addr(netsend_rx_multi_group);
1814 netsend_addr_rxraw16.sin_port=htons(net.port);
1815 server_flag=TRUE;
1816 }
1817 if( (ui.network_flag & NET_RXOUT_RAW18) != 0)
1818 {
1819 if ((netfd.send_rx_raw18=socket(AF_INET,SOCK_DGRAM,0)) == INVSOCK)
1820 {
1821 lirerr(1249);
1822 return;
1823 }
1824 #if(OSNUM == OSNUM_WINDOWS)
1825 if (ioctlsocket(netfd.send_rx_raw18, FIONBIO, &on) < 0)lirerr(889666);
1826 #endif
1827 #if(OSNUM == OSNUM_LINUX)
1828 fcntl(netfd.send_rx_raw18, F_SETFD, O_NONBLOCK);
1829 #endif
1830 memset(&netsend_addr_rxraw18,0,sizeof(netsend_addr_rxraw18));
1831 netsend_addr_rxraw18.sin_family=AF_INET;
1832 netsend_addr_rxraw18.sin_addr.s_addr=inet_addr(netsend_rx_multi_group);
1833 netsend_addr_rxraw18.sin_port=htons(net.port+1);
1834 server_flag=TRUE;
1835 }
1836 if( (ui.network_flag & NET_RXOUT_RAW24) != 0)
1837 {
1838 if ((netfd.send_rx_raw24=socket(AF_INET,SOCK_DGRAM,0)) == INVSOCK)
1839 {
1840 lirerr(1249);
1841 return;
1842 }
1843 #if(OSNUM == OSNUM_WINDOWS)
1844 if (ioctlsocket(netfd.send_rx_raw24, FIONBIO, &on) < 0)lirerr(889666);
1845 #endif
1846 #if(OSNUM == OSNUM_LINUX)
1847 fcntl(netfd.send_rx_raw24, F_SETFD, O_NONBLOCK);
1848 #endif
1849 memset(&netsend_addr_rxraw24,0,sizeof(netsend_addr_rxraw24));
1850 netsend_addr_rxraw24.sin_family=AF_INET;
1851 netsend_addr_rxraw24.sin_addr.s_addr=inet_addr(netsend_rx_multi_group);
1852 netsend_addr_rxraw24.sin_port=htons(net.port+2);
1853 server_flag=TRUE;
1854 }
1855 if( (ui.network_flag & NET_RXOUT_FFT1) != 0)
1856 {
1857 if ((netfd.send_rx_fft1=socket(AF_INET,SOCK_DGRAM,0)) == INVSOCK)
1858 {
1859 lirerr(1249);
1860 return;
1861 }
1862 #if(OSNUM == OSNUM_WINDOWS)
1863 if (ioctlsocket(netfd.send_rx_fft1, FIONBIO, &on) < 0)lirerr(889666);
1864 #endif
1865 #if(OSNUM == OSNUM_LINUX)
1866 fcntl(netfd.send_rx_fft1, F_SETFD, O_NONBLOCK);
1867 #endif
1868 memset(&netsend_addr_rxfft1,0,sizeof(netsend_addr_rxfft1));
1869 netsend_addr_rxfft1.sin_family=AF_INET;
1870 netsend_addr_rxfft1.sin_addr.s_addr=inet_addr(netsend_rx_multi_group);
1871 netsend_addr_rxfft1.sin_port=htons(net.port+3);
1872 server_flag=TRUE;
1873 }
1874 if( (ui.network_flag & NET_RXOUT_TIMF2) != 0)
1875 {
1876 if ((netfd.send_rx_timf2=socket(AF_INET,SOCK_DGRAM,0)) == INVSOCK)
1877 {
1878 lirerr(1249);
1879 return;
1880 }
1881 #if(OSNUM == OSNUM_WINDOWS)
1882 if (ioctlsocket(netfd.send_rx_timf2, FIONBIO, &on) < 0)lirerr(889666);
1883 #endif
1884 #if(OSNUM == OSNUM_LINUX)
1885 fcntl(netfd.send_rx_timf2, F_SETFD, O_NONBLOCK);
1886 #endif
1887 memset(&netsend_addr_rxtimf2,0,sizeof(netsend_addr_rxtimf2));
1888 netsend_addr_rxtimf2.sin_family=AF_INET;
1889 netsend_addr_rxtimf2.sin_addr.s_addr=inet_addr(netsend_rx_multi_group);
1890 netsend_addr_rxtimf2.sin_port=htons(net.port+4);
1891 server_flag=TRUE;
1892 }
1893 if( (ui.network_flag & NET_RXOUT_FFT2) != 0)
1894 {
1895 if ((netfd.send_rx_fft2=socket(AF_INET,SOCK_DGRAM,0)) == INVSOCK)
1896 {
1897 lirerr(1249);
1898 return;
1899 }
1900 #if(OSNUM == OSNUM_WINDOWS)
1901 if (ioctlsocket(netfd.send_rx_fft2, FIONBIO, &on) < 0)lirerr(889666);
1902 #endif
1903 #if(OSNUM == OSNUM_LINUX)
1904 i=fcntl(netfd.send_rx_fft2, F_SETFL, O_NONBLOCK);
1905 #endif
1906 memset(&netsend_addr_rxfft2,0,sizeof(netsend_addr_rxfft2));
1907 netsend_addr_rxfft2.sin_family=AF_INET;
1908 netsend_addr_rxfft2.sin_addr.s_addr=inet_addr(netsend_rx_multi_group);
1909 netsend_addr_rxfft2.sin_port=htons(net.port+5);
1910 }
1911 if( (ui.network_flag & NET_RXOUT_BASEB) != 0)
1912 {
1913 if ((netfd.send_rx_baseb=socket(AF_INET,SOCK_DGRAM,0)) == INVSOCK)
1914 {
1915 lirerr(1249);
1916 return;
1917 }
1918 #if(OSNUM == OSNUM_WINDOWS)
1919 if (ioctlsocket(netfd.send_rx_baseb, FIONBIO, &on) < 0)lirerr(889666);
1920 #endif
1921 #if(OSNUM == OSNUM_LINUX)
1922 i=fcntl(netfd.send_rx_baseb, F_SETFL, O_NONBLOCK);
1923 #endif
1924 memset(&netsend_addr_rxbaseb,0,sizeof(netsend_addr_rxbaseb));
1925 netsend_addr_rxbaseb.sin_family=AF_INET;
1926 netsend_addr_rxbaseb.sin_addr.s_addr=inet_addr(netsend_rx_multi_group);
1927 netsend_addr_rxbaseb.sin_port=htons(net.port+6);
1928 server_flag=TRUE;
1929 }
1930 if( (ui.network_flag & NET_RXOUT_BASEBRAW) != 0)
1931 {
1932 if ((netfd.send_rx_basebraw=socket(AF_INET,SOCK_DGRAM,0)) == INVSOCK)
1933 {
1934 lirerr(1249);
1935 return;
1936 }
1937 #if(OSNUM == OSNUM_WINDOWS)
1938 if (ioctlsocket(netfd.send_rx_basebraw, FIONBIO, &on) < 0)lirerr(889666);
1939 #endif
1940 #if(OSNUM == OSNUM_LINUX)
1941 i=fcntl(netfd.send_rx_basebraw, F_SETFL, O_NONBLOCK);
1942 #endif
1943 memset(&netsend_addr_rxbasebraw,0,sizeof(netsend_addr_rxbasebraw));
1944 netsend_addr_rxbasebraw.sin_family=AF_INET;
1945 netsend_addr_rxbasebraw.sin_addr.s_addr=inet_addr(netsend_rx_multi_group);
1946 netsend_addr_rxbasebraw.sin_port=htons(net.port+7);
1947 server_flag=TRUE;
1948 }
1949 if(server_flag == TRUE)
1950 {
1951 // We are sending input to another Linrad program.
1952 // Or maybe timf2 data to MAP65.
1953 if( (ui.rx_input_mode&DWORD_INPUT) == 0)
1954 {
1955 if( (ui.network_flag&NET_RXOUT_RAW18)!=0)
1956 {
1957 lirerr(1250);
1958 return;
1959 }
1960 if( (ui.network_flag&NET_RXOUT_RAW24)!=0)
1961 {
1962 lirerr(1251);
1963 return;
1964 }
1965 }
1966 // Set up the file descriptor for our server.
1967 netfd.any_slave=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1968 if(netfd.any_slave == INVSOCK)
1969 {
1970 lirerr(1249);
1971 return;
1972 }
1973 // Set small buffers. We use TCP and will not loose data anyway.
1974 // A small buffer will use up CPU time in small chunks so
1975 // it will be harmless to the time-critical DSP processing
1976 // and UDP network services.
1977 i=8192;
1978 setsockopt(netfd.rec_rx,SOL_SOCKET,SO_RCVBUF,(char*)&i,sizeof(int));
1979 setsockopt(netfd.rec_rx,SOL_SOCKET,SO_SNDBUF,(char*)&i,sizeof(int));
1980 i=net.send_raw+net.send_fft1+net.send_fft2+
1981 net.send_timf2+net.send_baseb+net.send_basebraw;
1982 if( ((i ^ ui.network_flag)&NET_RX_OUTPUT)!=0)
1983 {
1984 lirerr(1252);
1985 return;
1986 }
1987 memset(&slave_addr,0,sizeof(slave_addr));
1988 slave_addr.sin_family = AF_INET;
1989 slave_addr.sin_addr.s_addr = htonl(INADDR_ANY);
1990 k=0;
1991 // Listen to CONNPORT or any of the following 10 ports.
1992 nxt_port:;
1993 slave_addr.sin_port = htons(CONNPORT+k);
1994 i=bind(netfd.any_slave, (struct sockaddr *)&slave_addr, sizeof(slave_addr));
1995 if(i!=0)
1996 {
1997 k++;
1998 if(k<10)goto nxt_port;
1999 lirerr(1275);
2000 return;
2001 }
2002 i=listen(netfd.any_slave, 5);
2003 if(i!=0)
2004 {
2005 lirerr(1276);
2006 return;
2007 }
2008 FD_ZERO(&master_readfds);
2009 FD_SET(netfd.any_slave, &master_readfds);
2010 }
2011 if( (ui.network_flag & NET_RX_INPUT) != 0)
2012 {
2013 i=ui.network_flag|=net.receive_raw+net.receive_fft1;
2014 if( ((i ^ ui.network_flag)&NET_RX_INPUT)!=0)lirerr(1252);
2015 if ((netfd.rec_rx=socket(AF_INET,SOCK_DGRAM,0)) == INVSOCK)
2016 {
2017 lirerr(1249);
2018 return;
2019 }
2020 // Set a big RX buffer. Defaults: Linux=109568 and Windows=8192.
2021 // Set the TX buffer small. We will not send on this socket.
2022
2023 i=131072;
2024 setsockopt(netfd.rec_rx,SOL_SOCKET,SO_RCVBUF,(char*)&i,sizeof(int));
2025 i=8192;
2026 setsockopt(netfd.rec_rx,SOL_SOCKET,SO_SNDBUF,(char*)&i,sizeof(int));
2027 // allow multiple sockets to use the same PORT number
2028 k=1;
2029 i=setsockopt(netfd.rec_rx,SOL_SOCKET,SO_REUSEADDR,(char*)&k,sizeof(int));
2030 if(i < 0)
2031 {
2032 lirerr(1266);
2033 return;
2034 }
2035 memset(&netrec_addr,0,sizeof(netrec_addr));
2036 netrec_addr.sin_family=AF_INET;
2037 netrec_addr.sin_addr.s_addr=htonl(INADDR_ANY);
2038 rx_input_thread=THREAD_RX_RAW_NETINPUT;
2039 switch (ui.network_flag & NET_RX_INPUT)
2040 {
2041 case NET_RXIN_RAW16:
2042 ss="RAW16";
2043 i=0;
2044 break;
2045
2046 case NET_RXIN_RAW18:
2047 ss="RAW18";
2048 i=1;
2049 break;
2050
2051 case NET_RXIN_RAW24:
2052 ss="RAW24";
2053 i=2;
2054 break;
2055
2056 case NET_RXIN_FFT1:
2057 ss="FFT1";
2058 i=3;
2059 rx_input_thread=THREAD_RX_FFT1_NETINPUT;
2060 break;
2061
2062 case NET_RXIN_TIMF2:
2063 ss="TIMF2";
2064 i=4;
2065 break;
2066
2067 case NET_RXIN_BASEB:
2068 ss="BASEBAND16";
2069 i=6;
2070 break;
2071
2072 case NET_RXIN_BASEBRAW:
2073 ss="BASEBAND24";
2074 i=7;
2075 break;
2076
2077 default:
2078 lirerr(1253);
2079 return;
2080 }
2081 sprintf(s,"Listening to network for %s RX input",ss);
2082 lir_text(0,1,s);
2083 sprintf(s,"Group %s, port %d", netrec_rx_multi_group, net.port+i);
2084 lir_text(0,2,s);
2085 lir_sched_yield();
2086 lir_refresh_screen();
2087 netrec_addr.sin_port=htons(net.port+i);
2088 // bind to receive address
2089 if (bind(netfd.rec_rx,(struct sockaddr *) &netrec_addr,
2090 sizeof(netrec_addr)) < 0)
2091 {
2092 lirerr(1267);
2093 return;
2094 }
2095 // use setsockopt() to request that the kernel join a multicast group
2096 mreq.imr_multiaddr.s_addr=inet_addr(netrec_rx_multi_group);
2097 if( (mreq.imr_multiaddr.s_addr&0xff) >= 224 &&
2098 (mreq.imr_multiaddr.s_addr&0xff) < 240)
2099 {
2100 mreq.imr_interface.s_addr=htonl(INADDR_ANY);
2101 if (setsockopt(netfd.rec_rx,IPPROTO_IP,IP_ADD_MEMBERSHIP,
2102 (char*)&mreq,sizeof(mreq)) < 0)
2103 {
2104 lirerr(1268);
2105 return;
2106 }
2107 }
2108 // Go into an endless loop waiting for multicast to be received
2109 // from another Linrad system.
2110 nbytes=0;
2111 i=0;
2112 test_keyboard();
2113 FD_ZERO(&fds);
2114 FD_SET(netfd.rec_rx, &fds);
2115 wtcnt=0;
2116 while(nbytes <= 0 && lir_inkey == 0)
2117 {
2118 if(kill_all_flag)return;
2119 testfds=fds;
2120 timeout.tv_sec=0;
2121 timeout.tv_usec=30000;
2122 if( select(FD_SETSIZE, &testfds, (fd_set *)0, (fd_set *)0, &timeout) > 0)
2123 {
2124 if(FD_ISSET(netfd.rec_rx,&testfds))
2125 {
2126 memset(&netmaster_addr,0,sizeof(netmaster_addr));
2127 addrlen=sizeof(netmaster_addr);
2128 nbytes=recvfrom(netfd.rec_rx,(char*)msg,sizeof(NET_RX_STRUCT)+1,0,
2129 (struct sockaddr *) &netmaster_addr, &addrlen);
2130 if(nbytes != sizeof(NET_RX_STRUCT))
2131 {
2132 i++;
2133 sprintf(s,"NET RX ERROR %d received %d expected %d",i,
2134 nbytes,(int)sizeof(NET_RX_STRUCT));
2135 lir_text(1,4,s);
2136 nbytes=0;
2137 }
2138 lir_sched_yield();
2139 lir_refresh_screen();
2140 }
2141 }
2142 else
2143 {
2144 wtcnt++;
2145 if(wtcnt > 999)wtcnt=0;
2146 sprintf(s,"%d ",wtcnt);
2147 lir_text(5,0,s);
2148 lir_refresh_screen();
2149 lir_sleep(100000);
2150 test_keyboard();
2151 }
2152 }
2153 if(lir_inkey != 0)
2154 {
2155 lir_inkey=0;
2156 lirerr(1269);
2157 return;
2158 }
2159 ip=(unsigned char*)&netmaster_addr.sin_addr.s_addr;
2160 sprintf(s,"received %s data from %d.%d.%d.%d", ss,
2161 ip[0], ip[1], ip[2], ip[3]);
2162 lir_text(1,4,s);
2163 lir_sched_yield();
2164 lir_refresh_screen();
2165 i=0;
2166 if ((netfd.master = socket(AF_INET, SOCK_STREAM, 0)) == INVSOCK)
2167 {
2168 lirerr(1249);
2169 return;
2170 }
2171 netmaster_addr.sin_family=AF_INET;
2172 netmaster_addr.sin_port=htons(CONNPORT);
2173 j = connect(netfd.master, (struct sockaddr *)&netmaster_addr,
2174 sizeof(netmaster_addr) );
2175 lir_sleep(100000);
2176 while(j == -1 && lir_inkey == 0)
2177 {
2178 sprintf(s,"Trying to connect %d, errno=%d",i,errno);
2179 lir_text(1,5,s);
2180 lir_refresh_screen();
2181 j = connect(netfd.master, (struct sockaddr *)&netmaster_addr,
2182 sizeof(netmaster_addr) );
2183 test_keyboard();
2184 if(kill_all_flag) return;
2185 i++;
2186 lir_sleep(100000);
2187 }
2188 if(lir_inkey != 0)
2189 {
2190 lir_inkey=0;
2191 lirerr(1269);
2192 return;
2193 }
2194 lir_sched_yield();
2195 lir_refresh_screen();
2196 clear_lines(5,5);
2197 lir_text(1,5,"Connect sucessful !!");
2198 lir_text(1,6,"Waiting for mode info");
2199 lir_refresh_screen();
2200 if( (ui.network_flag&NET_RXIN_BASEB) !=0)
2201 {
2202 slave_msg.type=NETMSG_BASEBMODE_REQUEST;
2203 }
2204 else
2205 {
2206 if( (ui.network_flag&NET_RXIN_BASEBRAW) !=0)
2207 {
2208 slave_msg.type=NETMSG_BASEBRAWMODE_REQUEST;
2209 }
2210 else
2211 {
2212 if( (ui.network_flag&NET_RXIN_TIMF2) !=0)
2213 {
2214 slave_msg.type=NETMSG_TIMF2MODE_REQUEST;
2215 }
2216 else
2217 {
2218 slave_msg.type=NETMSG_MODE_REQUEST;
2219 }
2220 }
2221 }
2222 slave_msg.frequency=-1;
2223 net_write(netfd.master, &slave_msg, sizeof(slave_msg));
2224 if(kill_all_flag)return;
2225 net_read(intbuf,8*sizeof(int));
2226 if(kill_all_flag)return;
2227 ui.rx_ad_speed=intbuf[0];
2228 ui.rx_ad_channels=intbuf[1];
2229 ui.rx_rf_channels=intbuf[2];
2230 ui.rx_input_mode=intbuf[3];
2231 snd[RXAD].block_bytes=intbuf[4];
2232 if( (ui.network_flag & NET_RXIN_FFT1) != 0)
2233 {
2234 fft1_size=intbuf[5];
2235 fft1_n=intbuf[6];
2236 }
2237 init_genparm(FALSE);
2238 if( (ui.network_flag & NET_RXIN_FFT1) != 0)
2239 {
2240 genparm[FIRST_FFT_SINPOW]=intbuf[7];
2241 }
2242 if( (ui.rx_input_mode&DWORD_INPUT) != 0 &&
2243 (ui.network_flag&NET_RXIN_RAW16) !=0 )
2244 {
2245 ui.rx_input_mode&=DWORD_INPUT^0xffffffff;
2246 snd[RXAD].block_bytes/=2;
2247 }
2248 fg.passband_direction=0;
2249 fft1_direction=0;
2250 get_wideband_sizes();
2251 if(kill_all_flag) return;
2252 get_buffers(1);
2253 if(kill_all_flag) return;
2254 mm=2*ui.rx_rf_channels;
2255 fft1_calibrate_flag=0;
2256 clear_screen();
2257 if( (ui.network_flag & NET_RXIN_TIMF2) != 0)
2258 {
2259 s[0]=FALSE;
2260 }
2261 else
2262 {
2263 lir_text(1,6,"Waiting for filter calibration info");
2264 lir_refresh_screen();
2265 slave_msg.type=NETMSG_CAL_REQUEST;
2266 slave_msg.frequency=-1;
2267 net_write(netfd.master, &slave_msg, sizeof(slave_msg));
2268 if(kill_all_flag)return;
2269 net_read(s,sizeof(char));
2270 lir_refresh_screen();
2271 }
2272 if(s[0] == TRUE)
2273 {
2274 // The master says there is a calibration function get it.
2275 net_read(intbuf,3*sizeof(int));
2276 if(kill_all_flag)return;
2277 if(intbuf[2] == 0)
2278 {
2279 // The filtercorr function is saved in the frequency domain in
2280 // intbuf[1] points.
2281 // This format is used during the initialisation procedures and
2282 // it may be kept for normal operation in case the number of points
2283 // will not be reduced by saving in the time domain.
2284 tmpbuf=malloc(intbuf[1]*(mm+1)*sizeof(float));
2285 if( tmpbuf == NULL )
2286 {
2287 lirerr(1293);
2288 return;
2289 }
2290 net_read(tmpbuf, mm*sizeof(float)*intbuf[1]);
2291 if(kill_all_flag)return;
2292 net_read(&tmpbuf[mm*intbuf[1]], sizeof(float)*intbuf[1]);
2293 if(kill_all_flag)return;
2294 use_filtercorr_fd(intbuf[0], intbuf[1], tmpbuf, &tmpbuf[mm*intbuf[1]]);
2295
2296 }
2297 else
2298 {
2299 // The correction function was stored in the time domain in intbuf[2] points
2300 // We have to reduce the number of points.
2301 tmpbuf=malloc(intbuf[2]*(mm+1)*sizeof(float));
2302 if( tmpbuf == NULL )
2303 {
2304 lirerr(1055);
2305 return;
2306 }
2307 net_read(tmpbuf, mm*sizeof(float)*intbuf[2]);
2308 if(kill_all_flag)return;
2309 net_read(&tmpbuf[mm*intbuf[2]], sizeof(float)*intbuf[2]);
2310 if(kill_all_flag)return;
2311 use_filtercorr_td(intbuf[2], tmpbuf, &tmpbuf[mm*intbuf[2]]);
2312 }
2313 }
2314 else
2315 {
2316 clear_fft1_filtercorr();
2317 }
2318 if( (ui.network_flag & NET_RXIN_TIMF2) == 0)
2319 {
2320 lir_text(1,6,"Waiting for I/Q balance calibration info");
2321 slave_msg.type=NETMSG_CALIQ_REQUEST;
2322 slave_msg.frequency=-1;
2323 net_write(netfd.master, &slave_msg, sizeof(slave_msg));
2324 if(kill_all_flag)return;
2325 net_read(s,sizeof(char));
2326 if(kill_all_flag)return;
2327 }
2328 if(s[0] == TRUE)
2329 {
2330 net_read(intbuf,sizeof(int));
2331 if(kill_all_flag)return;
2332 bal_segments=intbuf[0];
2333 kk=twice_rxchan*sizeof(float)*4*bal_segments;
2334 contracted_iq_foldcorr=malloc(kk);
2335 if(contracted_iq_foldcorr == NULL)
2336 {
2337 lirerr(1049);
2338 return;
2339 }
2340 net_read(contracted_iq_foldcorr, kk);
2341 if(kill_all_flag)return;
2342 use_iqcorr();
2343 free(contracted_iq_foldcorr);
2344 }
2345 if( (ui.network_flag&(NET_RXIN_BASEB+NET_RXIN_BASEBRAW)) ==0)
2346 {
2347 fg.passband_center=msg[0].passband_center;
2348 fg.passband_direction=msg[0].passband_direction;
2349 freq_from_file=TRUE;
2350 }
2351 if( (ui.network_flag&NET_RXIN_TIMF2) != 0)
2352 {
2353 fg.passband_direction=-1;
2354 }
2355 fft1_direction=fg.passband_direction;
2356 FD_ZERO(&rx_input_fds);
2357 FD_SET(netfd.rec_rx, &rx_input_fds);
2358 clear_lines(0,8);
2359 lir_refresh_screen();
2360 return;
2361 }
2362 // We do not use the network for input.
2363 // This means we run as a master. Prepare to listen for
2364 // slaves that want to connect to us.
2365 get_wideband_sizes();
2366 if(kill_all_flag) return;
2367 get_buffers(1);
2368 if(kill_all_flag) return;
2369 }
2370
sendraw_text(int mask,int bits,int offset)2371 void sendraw_text( int mask, int bits, int offset)
2372 {
2373 char ss[80], s[80];
2374 sprintf(s,"%2d: Send raw data in %d bit format ",offset, bits);
2375 if( (net.send_raw&mask) == 0)
2376 {
2377 strcat(s,"OFF");
2378 }
2379 else
2380 {
2381 settextcolor(14);
2382 sprintf(ss,"ON (port=%d)",net.port+offset-NN_OUT_ZERO);
2383 strcat(s,ss);
2384 }
2385 lir_text(1,NNLINE+offset,s);
2386 settextcolor(7);
2387 }
2388
sendfft_text(int flag,int no,int offset)2389 void sendfft_text( int flag, int no, int offset)
2390 {
2391 char ss[80], s[80];
2392 sprintf(s,"%2d: Send FFT%d transforms ",offset, no);
2393 if( flag == FALSE)
2394 {
2395 strcat(s,"OFF");
2396 }
2397 else
2398 {
2399 settextcolor(14);
2400 sprintf(ss,"ON (port=%d)",net.port+offset-NN_OUT_ZERO);
2401 strcat(s,ss);
2402 }
2403 lir_text(1,NNLINE+offset,s);
2404 settextcolor(7);
2405 }
2406
get_ip_address(int * line,int idir)2407 int get_ip_address(int *line, int idir)
2408 {
2409 char s[80];
2410 char *nam;
2411 unsigned b1, b2, b3, b4;
2412 unsigned char c;
2413 char textbuf[80];
2414 int length ;
2415 int input;
2416 int i, iw;
2417 char *dir[2]={"SEND","RECEIVE"};
2418 FILE *file;
2419 sprintf(s,"Default multicast %s address range is",dir[idir]);
2420 lir_text(10,line[0],s);
2421 sprintf(s,"%s to",DEFAULT_MULTI_GROUP);
2422 lir_text(53,line[0],s);
2423 s[MULTI_GROUP_OFFSET]='1';
2424 s[1+MULTI_GROUP_OFFSET]='5';
2425 s[2+MULTI_GROUP_OFFSET]=0;
2426 lir_text(53+MULTI_GROUP_OFFSET+6,line[0],&s[0]);
2427 line[0]+=2;
2428 sprintf(s,"Enter 0 to 15 to select an IP address within the default range");
2429 if(idir == 0)
2430 {
2431 lir_text(10,line[0],s);
2432 line[0]++;
2433 lir_text(10,line[0],
2434 "Or enter -1 to specify a different IP address (p.e. 127.0.0.1):");
2435 i=74;
2436 }
2437 else
2438 {
2439 lir_text(10,line[0],
2440 "The receive address is not used if you send to this computer (unicast)");
2441 line[0]+=2;
2442 lir_text(10,line[0],s);
2443 line[0]++;
2444 lir_text(10,line[0],
2445 "Or enter -1 to specify a different multicast IP address in the");
2446 line[0]++;
2447 lir_text(10,line[0], "range 224.0.0.1 to 239.255.255.255:");
2448 i=46;
2449 }
2450 input=lir_get_integer(i,line[0],2,-1,15);
2451 line[0]++;
2452 if(kill_all_flag) return 0;
2453 if (input == -1)
2454 {
2455 line[0]+=2;
2456 specify:
2457 lir_text(10,line[0],"Specify different IP address: ");
2458 length=lir_get_text(40, line[0], textbuf);
2459 if(kill_all_flag) return 0;
2460 // validate format of IP address
2461 if ((length < 7) || (length > 15)) goto format_error;
2462 if (strspn(textbuf, "0123456789.") < strlen(textbuf)) goto format_error;
2463 if (sscanf(textbuf, "%3u.%3u.%3u.%3u%c", &b1, &b2, &b3, &b4, &c) != 4)
2464 goto format_error;
2465 if ((b1 | b2 | b3 | b4) > 255) goto format_error;
2466 goto save;
2467 format_error:;
2468 lir_text(10,line[0]+1,"IP address format-error: Try again ");
2469 goto specify;
2470 save:;
2471 // save IP address in nam file
2472 if(idir == 0) nam=par_netsend_filename;
2473 else nam=par_netrec_filename;
2474 file = fopen(nam, "w");
2475 iw=fwrite(textbuf,1,length,file);
2476 fclose(file);
2477 if(iw != length)
2478 {
2479 lirerr(125532);
2480 }
2481 }
2482 return input;
2483 }
2484
2485
set_network_flag(int old_flag)2486 void set_network_flag(int old_flag)
2487 {
2488 int k;
2489 ui.network_flag=0;
2490 if( ui.rx_addev_no == NETWORK_DEVICE_CODE)
2491 {
2492 k=(net.receive_raw&(NET_RXIN_RAW16+NET_RXIN_RAW18+NET_RXIN_RAW24))+
2493 (net.receive_fft1&NET_RXIN_FFT1)+
2494 (net.receive_baseb&NET_RXIN_BASEB)+
2495 (net.receive_basebraw&NET_RXIN_BASEBRAW)+
2496 (net.receive_timf2&NET_RXIN_TIMF2);
2497 ui.network_flag|=k;
2498 }
2499 if( (old_flag&NET_RX_OUTPUT) != 0)
2500 {
2501 ui.network_flag&=NET_RX_INPUT;
2502 k=(net.send_raw&(NET_RXOUT_RAW16|NET_RXOUT_RAW18|NET_RXOUT_RAW24))+
2503 (net.send_fft1&NET_RXOUT_FFT1)+
2504 (net.send_fft2&NET_RXOUT_FFT2)+
2505 (net.send_timf2&NET_RXOUT_TIMF2)+
2506 (net.send_baseb&NET_RXOUT_BASEB)+
2507 (net.send_basebraw&NET_RXOUT_BASEBRAW);
2508 ui.network_flag|=k;
2509 }
2510 }
2511
verify_network(int setup)2512 void verify_network(int setup)
2513 {
2514 char *msg;
2515 int old_network_flag;
2516 int i, line, quit_flag;
2517 char s[80];
2518 char ss[20];
2519 FILE *file;
2520 int *netparm;
2521 netparm=(int*)&net;
2522 if(ui.network_flag == 0)return;
2523 if(ui.use_extio != 0)
2524 {
2525 ui.network_flag&=NET_RX_OUTPUT;
2526 }
2527 old_network_flag=ui.network_flag;
2528 if(read_netpar()==FALSE)
2529 {
2530 if(!setup)
2531 {
2532 if( ui.rx_addev_no == NETWORK_DEVICE_CODE)
2533 {
2534 ui.rx_addev_no=DISABLED_DEVICE_CODE;
2535 ui.network_flag=0;
2536 return;
2537 }
2538 }
2539 }
2540 else
2541 {
2542 if(!setup)
2543 {
2544 set_network_flag(old_network_flag);
2545
2546 if( ui.rx_addev_no == NETWORK_DEVICE_CODE)
2547 {
2548 if( (ui.network_flag&NET_RX_INPUT) == 0)
2549 {
2550 ui.rx_addev_no=DISABLED_DEVICE_CODE;
2551 }
2552 }
2553 else
2554 {
2555 ui.network_flag&=NET_RX_OUTPUT;
2556 }
2557 return;
2558 }
2559 }
2560 msg="";
2561 do_setup:;
2562 quit_flag=FALSE;
2563 clear_screen();
2564 settextcolor(15);
2565 lir_text(0,1,msg);
2566 settextcolor(7);
2567 net_addr_strings(TRUE);
2568 lir_text(3,3,"CURRENT NETWORK SETTINGS ARE:");
2569 sprintf(s,"%2d: Base port = %d ", NN_BASE, net.port);
2570 lir_text(1,NN_BASE+NNLINE,s);
2571 sprintf(s,"%2d: SEND address = %s ",NN_SENDAD, netsend_rx_multi_group);
2572 lir_text(1,NN_SENDAD+NNLINE,s);
2573 sprintf(s,"%2d: RECEIVE address = %s ",NN_RECAD, netrec_rx_multi_group);
2574 lir_text(1,NN_RECAD+NNLINE,s);
2575 sendraw_text(NET_RXOUT_RAW16,16,NN_RAWOUT16);
2576 sendraw_text(NET_RXOUT_RAW18,18,NN_RAWOUT18);
2577 sendraw_text(NET_RXOUT_RAW24,24,NN_RAWOUT24);
2578 sendfft_text(net.send_fft1, 1, NN_FFT1OUT);
2579 sprintf(s,"%2d: Send timf2 (blanker output) ",NN_TIMF2OUT);
2580 if( net.send_timf2 == FALSE)
2581 {
2582 strcat(s,"OFF");
2583 }
2584 else
2585 {
2586 settextcolor(14);
2587 sprintf(ss,"ON (port=%d)",net.port+NN_TIMF2OUT-NN_OUT_ZERO);
2588 strcat(s,ss);
2589 }
2590 lir_text(1,NNLINE+NN_TIMF2OUT,s);
2591 settextcolor(7);
2592 sprintf(s,"%2d: Send baseband (resampled,16 bit) ",NN_BASEBOUT);
2593 if( net.send_baseb == FALSE)
2594 {
2595 strcat(s,"OFF");
2596 }
2597 else
2598 {
2599 settextcolor(14);
2600 sprintf(ss,"ON (port=%d)",net.port+NN_BASEBOUT-NN_OUT_ZERO);
2601 strcat(s,ss);
2602 }
2603 lir_text(1,NNLINE+NN_BASEBOUT,s);
2604 settextcolor(7);
2605 sprintf(s,"%2d: Send baseband raw (24 bit)",NN_BASEBRAWOUT);
2606 if( net.send_basebraw == FALSE)
2607 {
2608 strcat(s,"OFF");
2609 }
2610 else
2611 {
2612 settextcolor(14);
2613 sprintf(ss,"ON (port=%d)",net.port+NN_BASEBRAWOUT-NN_OUT_ZERO);
2614 strcat(s,ss);
2615 }
2616 lir_text(1,NNLINE+NN_BASEBRAWOUT,s);
2617 settextcolor(7);
2618 sendfft_text(net.send_fft2, 2, NN_FFT2OUT);
2619 sprintf(s,"%2d: RX input from network ",NN_RX);
2620 if( net.receive_raw+net.receive_fft1+net.receive_baseb+
2621 net.receive_basebraw+net.receive_timf2 == 0)
2622 {
2623 strcat(s,"OFF");
2624 }
2625 else
2626 {
2627 if( ui.rx_addev_no != NETWORK_DEVICE_CODE ||
2628 (ui.network_flag&NET_RX_INPUT) == 0)
2629 {
2630 strcat(s,"-- ");
2631 }
2632 else
2633 {
2634 strcat(s,"ON ");
2635 settextcolor(14);
2636 }
2637 if( net.receive_fft1 == NET_RXIN_FFT1)
2638 {
2639 strcat(s,"(FFT1 transforms)");
2640 }
2641 else
2642 {
2643 if( net.receive_baseb == NET_RXIN_BASEB)
2644 {
2645 strcat(s,"(Baseband, resampled 16 bit)");
2646 }
2647 else
2648 {
2649 if( net.receive_basebraw == NET_RXIN_BASEBRAW)
2650 {
2651 strcat(s,"(Baseband, raw, 24 bit)");
2652 }
2653 else
2654 {
2655 if( net.receive_timf2 == NET_RXIN_TIMF2)
2656 {
2657 strcat(s,"(timf2)");
2658 }
2659 else
2660 {
2661 strcat(s,"(Raw data, ");
2662 if( net.receive_raw == NET_RXIN_RAW16)
2663 {
2664 strcat(s,"16");
2665 }
2666 else
2667 {
2668 if( net.receive_raw == NET_RXIN_RAW18)
2669 {
2670 strcat(s,"18");
2671 }
2672 else
2673 {
2674 if( net.receive_raw == NET_RXIN_RAW24)
2675 {
2676 strcat(s,"24");
2677 }
2678 else
2679 {
2680 lirerr(42962);
2681 return;
2682 }
2683 }
2684 }
2685 strcat(s," bit)");
2686 }
2687 }
2688 }
2689 }
2690 }
2691 lir_text(1,NNLINE+NN_RX,s);
2692 settextcolor(7);
2693 line=1+NNLINE+NN_RX;
2694 lir_text(1,line,"F1: Help");
2695 line+=2;
2696 lir_text(0,line,"On exit from this routine network transmit will be OFF.");
2697 line++;
2698 lir_text(0,line,"The screen shows what will become enabled when send");
2699 line++;
2700 lir_text(0,line,
2701 "is enabled (with ""T"" on the main menu)");
2702 line++;
2703 lir_text(0,line,remind_parsave);
2704 line+=2;
2705 lir_text(0,line, "Enter a line number to change, 0 to exit =>");
2706 i=lir_get_integer(44,line,2,0,NN_RX);
2707 if(kill_all_flag) return;
2708
2709 if(lir_inkey == F1_KEY || lir_inkey == '!')
2710 {
2711 help_message(315);
2712 goto do_setup;
2713 }
2714 line+=3;
2715 switch (i)
2716 {
2717 case NN_RX:
2718 lir_text(10,line,"Set receive format.");
2719 lir_text(10,line+2,"A=Raw 16 bit");
2720 lir_text(10,line+3,"B=Raw 18 bit");
2721 lir_text(10,line+4,"C=Raw 24 bit");
2722 lir_text(10,line+5,"D=FFT1 transforms");
2723 lir_text(10,line+6,"E=Baseband, resampled,16 bit");
2724 lir_text(10,line+7,"F=Baseband, raw,24 bit");
2725 lir_text(10,line+8,"G=timf2 (int16 or float32)");
2726 lir_text(10,line+9,"Z=None");
2727 get_r:;
2728 to_upper_await_keyboard();
2729 if(kill_all_flag) return;
2730 net.receive_raw=0;
2731 net.receive_fft1=0;
2732 net.receive_baseb=0;
2733 net.receive_basebraw=0;
2734 net.receive_timf2=0;
2735 switch (lir_inkey)
2736 {
2737 case 'A':
2738 net.receive_raw=NET_RXIN_RAW16;
2739 break;
2740
2741 case 'B':
2742 net.receive_raw=NET_RXIN_RAW18;
2743 break;
2744
2745 case 'C':
2746 net.receive_raw=NET_RXIN_RAW24;
2747 break;
2748
2749 case 'D':
2750 net.receive_fft1=NET_RXIN_FFT1;
2751 break;
2752
2753 case 'E':
2754 net.receive_baseb=NET_RXIN_BASEB;
2755 break;
2756
2757 case 'F':
2758 net.receive_basebraw=NET_RXIN_BASEBRAW;
2759 break;
2760
2761 case 'G':
2762 net.receive_timf2=NET_RXIN_TIMF2;
2763 break;
2764
2765 case 'Z':
2766 break;
2767
2768 default:
2769 goto get_r;
2770 }
2771 if(net.receive_raw != 0)net.send_raw=0;
2772 if(net.receive_fft1 != 0)
2773 {
2774 net.send_raw=0;
2775 net.send_fft1=0;
2776 }
2777 break;
2778
2779 case NN_BASE:
2780 sprintf(s,"Base port (%d to %d) =>",NET_MULTI_MINPORT, NET_MULTI_MAXPORT);
2781 lir_text(10,line,s);
2782 net.port=lir_get_integer(40,line,5,NET_MULTI_MINPORT,NET_MULTI_MAXPORT);
2783 net.port=(net.port/10)*10;
2784 break;
2785
2786 case NN_SENDAD:
2787 net.send_group=get_ip_address(&line, 0);
2788 break;
2789
2790 case NN_RECAD:
2791 lir_text(10,line,"New RECEIVE address (0 to 15) =>");
2792 net.rec_group=get_ip_address(&line, 1);
2793 break;
2794
2795 case NN_RAWOUT16:
2796 net.send_raw^=NET_RXOUT_RAW16;
2797 break;
2798
2799 case NN_RAWOUT18:
2800 net.send_raw^=NET_RXOUT_RAW18;
2801 break;
2802
2803 case NN_RAWOUT24:
2804 net.send_raw^=NET_RXOUT_RAW24;
2805 break;
2806
2807 case NN_FFT1OUT:
2808 net.send_fft1^=NET_RXOUT_FFT1;
2809 break;
2810
2811 case NN_TIMF2OUT:
2812 net.send_timf2^=NET_RXOUT_TIMF2;
2813 break;
2814
2815 case NN_FFT2OUT:
2816 net.send_fft2^=NET_RXOUT_FFT2;
2817 break;
2818
2819 case NN_BASEBOUT:
2820 net.send_baseb^=NET_RXOUT_BASEB;
2821 break;
2822
2823 case NN_BASEBRAWOUT:
2824 net.send_basebraw^=NET_RXOUT_BASEBRAW;
2825 break;
2826
2827 case 0:
2828 quit_flag=TRUE;
2829 break;
2830 }
2831 if(kill_all_flag)return;
2832 if(net.send_fft1 != 0)net.receive_fft1=0;
2833 if(net.send_raw != 0)
2834 {
2835 net.receive_raw=0;
2836 net.receive_fft1=0;
2837 }
2838 set_network_flag(old_network_flag);
2839 if( (old_network_flag&NET_RX_OUTPUT) != 0 &&
2840 (ui.network_flag&NET_RX_OUTPUT) == 0)
2841 {
2842 msg="You have to enable at least one mode to start network transmit.";
2843 goto do_setup;
2844 }
2845 if( ui.rx_addev_no == NETWORK_DEVICE_CODE &&
2846 (ui.network_flag&NET_RX_INPUT) == 0)
2847 {
2848 msg="Select what format to use for input";
2849 goto do_setup;
2850 }
2851 if( (old_network_flag&NET_RX_INPUT) == 0)
2852 {
2853 ui.network_flag&=NET_RX_OUTPUT;
2854 }
2855 if( (old_network_flag&NET_RX_OUTPUT) == 0)
2856 {
2857 ui.network_flag&=NET_RX_INPUT;
2858 }
2859 if(!quit_flag)
2860 {
2861 msg="";
2862 goto do_setup;
2863 }
2864 file = fopen(network_filename, "w");
2865 if (file == NULL)
2866 {
2867 lirerr(1029);
2868 return;
2869 }
2870 for(i=0; i<MAX_NET_INTPAR; i++)
2871 {
2872 fprintf(file,"%s [%d]\n",net_intpar_text[i],netparm[i]);
2873 }
2874 parfile_end(file);
2875 }
2876
net_read(void * buf,int bytes)2877 void net_read( void *buf, int bytes)
2878 {
2879 int i, network_nread;
2880 char s[80];
2881 int nread, rdbytes;
2882 int prtwait, netwait;
2883 netwait=0;
2884 prtwait=0;
2885 network_nread=0;
2886 #if(OSNUM == OSNUM_LINUX)
2887 ioctl(netfd.master, FIONREAD, &network_nread);
2888 #endif
2889 #if(OSNUM == OSNUM_WINDOWS)
2890 network_nread=recv(netfd.master, buf, bytes, MSG_PEEK);
2891 #endif
2892 rdbytes=0;
2893 while(rdbytes < bytes)
2894 {
2895 nread=network_nread;
2896 if(nread > 0)
2897 {
2898 if(nread+rdbytes > bytes)nread=bytes-rdbytes;
2899 i=recv(netfd.master, buf+rdbytes, nread, 0);
2900 if(i==0)
2901 {
2902 lirerr(1273);
2903 return;
2904 }
2905 if(i==-1)
2906 {
2907 lirerr(1274);
2908 return;
2909 }
2910 rdbytes+=i;
2911 network_nread-=i;
2912 }
2913 else
2914 {
2915 if(prtwait==0)
2916 {
2917 sprintf(s,"WAITING FOR NETWORK %d ",netwait);
2918 lir_text(5,8,s);
2919 prtwait=-5;
2920 }
2921 prtwait++;
2922 netwait++;
2923 lir_sleep(10000);
2924 #if(OSNUM == OSNUM_LINUX)
2925 ioctl(netfd.master, FIONREAD, &network_nread);
2926 #endif
2927 #if(OSNUM == OSNUM_WINDOWS)
2928 network_nread=recv(netfd.master, buf+rdbytes, bytes-rdbytes, MSG_PEEK);
2929 #endif
2930 lir_refresh_screen();
2931 test_keyboard();
2932 if(kill_all_flag) return;
2933 if(lir_inkey != 0)
2934 {
2935 process_current_lir_inkey();
2936 }
2937 if(kill_all_flag) return;
2938 }
2939 }
2940 }
2941
net_write(FD fd,void * buf,int size)2942 void net_write(FD fd, void *buf, int size)
2943 {
2944 struct timeval timeout;
2945 int i, j, ptr, remaining;
2946 fd_set fds, testfds;
2947 FD_ZERO(&fds);
2948 FD_SET(fd, &fds);
2949 ptr=0;
2950 remaining=size;
2951 while(remaining > 0)
2952 {
2953 lir_sched_yield();
2954 j=remaining;
2955 if(remaining > 1500)
2956 {
2957 j=1500;
2958 if(j>remaining/2)j=remaining/2;
2959 }
2960 testfds=fds;
2961 timeout.tv_sec=0;
2962 timeout.tv_usec=10000;
2963 if( select(FD_SETSIZE, (fd_set *)0, &testfds, (fd_set *)0, &timeout) > 0)
2964 {
2965 if(FD_ISSET(fd,&testfds))
2966 {
2967 i=send(fd, buf+ptr, j,0);
2968 if(i>0)
2969 {
2970 remaining-=i;
2971 ptr+=i;
2972 }
2973 else
2974 {
2975 if(i==0)
2976 {
2977 lirerr(1264);
2978 }
2979 else
2980 {
2981 #if(OSNUM == OSNUM_WINDOWS)
2982 i=WSAGetLastError();
2983 DEB"\nerror code=%d",i);
2984 #endif
2985 #if(OSNUM == OSNUM_LINUX)
2986 DEB"\nerrno=%d",errno);
2987 #endif
2988 lirerr(1101);
2989 }
2990 return;
2991 }
2992 }
2993 if(kill_all_flag) return;
2994 }
2995 }
2996 }
2997
2998
2999