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