2
2
// This file is part of Dire Wolf, an amateur radio packet TNC.
3
3
//
4
4
// Copyright (C) 2011-2014, 2015 John Langner, WB2OSZ
5
+ // Copyright (C) 2016 Angus Ainslie angus at akkea.ca, VE6GUS
5
6
//
6
7
// This program is free software: you can redistribute it and/or modify
7
8
// it under the terms of the GNU General Public License as published by
130
131
131
132
void hex_dump (unsigned char * p , int len ); // This should be in a .h file.
132
133
134
+ // TODO: no idea how to do this on windows
135
+ #if __WIN32__
136
+ #define MAX_NET_CLIENTS 1
137
+ #else
138
+ #define MAX_NET_CLIENTS 4
139
+ #endif
133
140
134
- static kiss_frame_t kf ; /* Accumulated KISS frame and state of decoder. */
135
- // TODO: multiple instances if multiple KISS network clients!
141
+ static kiss_frame_t kf [ MAX_NET_CLIENTS ] ; /* Accumulated KISS frame and state of decoder. */
142
+ // TODO: multiple instances if multiple KISS network clients!
136
143
137
144
138
- static int client_sock ; /* File descriptor for socket for */
139
- /* communication with client application. */
140
- /* Set to -1 if not connected. */
141
- /* (Don't use SOCKET type because it is unsigned.) */
145
+ static int client_sock [ MAX_NET_CLIENTS ] ; /* File descriptor for socket for */
146
+ /* communication with client application. */
147
+ /* Set to -1 if not connected. */
148
+ /* (Don't use SOCKET type because it is unsigned.) */
142
149
143
150
144
151
// TODO: define in one place, use everywhere.
@@ -196,16 +203,18 @@ void kissnet_init (struct misc_config_s *mc)
196
203
int e ;
197
204
#endif
198
205
int kiss_port = mc -> kiss_port ;
206
+ int i ;
199
207
200
208
201
209
#if DEBUG
202
210
text_color_set (DW_COLOR_DEBUG );
203
211
dw_printf ("kissnet_init ( %d )\n" , kiss_port );
204
212
#endif
205
213
206
- memset (& kf , 0 , sizeof (kf ));
207
-
208
- client_sock = -1 ;
214
+ for ( i = 0 ; i < MAX_NET_CLIENTS ; i ++ ) {
215
+ client_sock [i ] = -1 ;
216
+ memset (& kf , 0 , sizeof (kf ));
217
+ }
209
218
210
219
if (kiss_port == 0 ) {
211
220
text_color_set (DW_COLOR_INFO );
@@ -352,8 +361,12 @@ static THREAD_F connect_listen_thread (void *arg)
352
361
353
362
while (1 ) {
354
363
355
- while (client_sock > 0 ) {
356
- SLEEP_SEC (1 ); /* Already connected. Try again later. */
364
+ i = 0
365
+ while (client_sock [i ] > 0 ) {
366
+ if (( ++ i % MAX_NET_CLIENTS ) == 0 ) {
367
+ SLEEP_SEC (1 ); /* All clients already connected. Try again later. */
368
+ i = 0 ;
369
+ }
357
370
}
358
371
359
372
#define QUEUE_SIZE 5
@@ -368,9 +381,9 @@ static THREAD_F connect_listen_thread (void *arg)
368
381
text_color_set (DW_COLOR_INFO );
369
382
dw_printf ("Ready to accept KISS client application on port %s ...\n" , kiss_port_str );
370
383
371
- client_sock = accept (listen_sock , NULL , NULL );
384
+ client_sock [ i ] = accept (listen_sock , NULL , NULL );
372
385
373
- if (client_sock == -1 ) {
386
+ if (client_sock [ i ] == -1 ) {
374
387
text_color_set (DW_COLOR_ERROR );
375
388
dw_printf ("Accept failed with error: %d\n" , WSAGetLastError ());
376
389
closesocket (listen_sock );
@@ -392,6 +405,7 @@ static THREAD_F connect_listen_thread (void *arg)
392
405
int kiss_port = (int )(long )arg ;
393
406
int listen_sock ;
394
407
int bcopt = 1 ;
408
+ int i ;
395
409
396
410
listen_sock = socket (AF_INET ,SOCK_STREAM ,0 );
397
411
if (listen_sock == -1 ) {
@@ -418,12 +432,12 @@ static THREAD_F connect_listen_thread (void *arg)
418
432
#endif
419
433
420
434
if (bind (listen_sock ,(struct sockaddr * )& sockaddr ,sizeof (sockaddr )) == -1 ) {
421
- text_color_set (DW_COLOR_ERROR );
422
- dw_printf ("Bind failed with error: %d\n" , errno );
423
- dw_printf ("%s\n" , strerror (errno ));
424
- dw_printf ("Some other application is probably already using port %d.\n" , kiss_port );
425
- dw_printf ("Try using a different port number with KISSPORT in the configuration file.\n" );
426
- return (NULL );
435
+ text_color_set (DW_COLOR_ERROR );
436
+ dw_printf ("Bind failed with error: %d\n" , errno );
437
+ dw_printf ("%s\n" , strerror (errno ));
438
+ dw_printf ("Some other application is probably already using port %d.\n" , kiss_port );
439
+ dw_printf ("Try using a different port number with KISSPORT in the configuration file.\n" );
440
+ return (NULL );
427
441
}
428
442
429
443
getsockname ( listen_sock , (struct sockaddr * )(& sockaddr ), & sockaddr_size );
@@ -435,8 +449,12 @@ static THREAD_F connect_listen_thread (void *arg)
435
449
436
450
while (1 ) {
437
451
438
- while (client_sock > 0 ) {
439
- SLEEP_SEC (1 ); /* Already connected. Try again later. */
452
+ i = 0 ;
453
+ while (client_sock [i ] > 0 ) {
454
+ if (( ++ i % MAX_NET_CLIENTS ) == 0 ) {
455
+ i = 0 ;
456
+ SLEEP_SEC (1 ); /* Already connected. Try again later. */
457
+ }
440
458
}
441
459
442
460
#define QUEUE_SIZE 5
@@ -449,12 +467,12 @@ static THREAD_F connect_listen_thread (void *arg)
449
467
}
450
468
451
469
text_color_set (DW_COLOR_INFO );
452
- dw_printf ("Ready to accept KISS client application on port %d ...\n" , kiss_port );
470
+ dw_printf ("Ready to accept KISS client %d application on port %d ...\n" , i , kiss_port );
453
471
454
- client_sock = accept (listen_sock , (struct sockaddr * )(& sockaddr ),& sockaddr_size );
472
+ client_sock [ i ] = accept (listen_sock , (struct sockaddr * )(& sockaddr ),& sockaddr_size );
455
473
456
474
text_color_set (DW_COLOR_INFO );
457
- dw_printf ("\nConnected to KISS client application ...\n\n" );
475
+ dw_printf ("\nConnected to KISS client %d application on fd %d ...\n\n" , i , client_sock [ i ] );
458
476
459
477
}
460
478
#endif
@@ -491,64 +509,66 @@ void kissnet_send_rec_packet (int chan, unsigned char *fbuf, int flen)
491
509
unsigned char kiss_buff [2 * AX25_MAX_PACKET_LEN ];
492
510
int kiss_len ;
493
511
int err ;
494
-
495
-
496
- if (client_sock == -1 ) {
497
- return ;
498
- }
499
- if (flen < 0 ) {
500
- flen = strlen ((char * )fbuf );
501
- if (kiss_debug ) {
502
- kiss_debug_print (TO_CLIENT , "Fake command prompt" , fbuf , flen );
503
- }
504
- strlcpy ((char * )kiss_buff , (char * )fbuf , sizeof (kiss_buff ));
505
- kiss_len = strlen ((char * )kiss_buff );
506
- }
507
- else {
508
-
509
-
510
- unsigned char stemp [AX25_MAX_PACKET_LEN + 1 ];
511
-
512
- assert (flen < (int )(sizeof (stemp )));
513
-
514
- stemp [0 ] = (chan << 4 ) + 0 ;
515
- memcpy (stemp + 1 , fbuf , flen );
516
-
517
- if (kiss_debug >= 2 ) {
518
- /* AX.25 frame with the CRC removed. */
519
- text_color_set (DW_COLOR_DEBUG );
520
- dw_printf ("\n" );
521
- dw_printf ("Packet content before adding KISS framing and any escapes:\n" );
522
- hex_dump (fbuf , flen );
523
- }
524
-
525
- kiss_len = kiss_encapsulate (stemp , flen + 1 , kiss_buff );
526
-
527
- /* This has the escapes and the surrounding FENDs. */
528
-
529
- if (kiss_debug ) {
530
- kiss_debug_print (TO_CLIENT , NULL , kiss_buff , kiss_len );
531
- }
532
- }
512
+ int i ;
513
+
514
+ for ( i = 0 ; i < MAX_NET_CLIENTS ; i ++ ) {
515
+ if (client_sock [i ] == -1 ) {
516
+ return ;
517
+ }
518
+ if (flen < 0 ) {
519
+ flen = strlen ((char * )fbuf );
520
+ if (kiss_debug ) {
521
+ kiss_debug_print (TO_CLIENT , "Fake command prompt" , fbuf , flen );
522
+ }
523
+ strlcpy ((char * )kiss_buff , (char * )fbuf , sizeof (kiss_buff ));
524
+ kiss_len = strlen ((char * )kiss_buff );
525
+ }
526
+ else {
527
+
528
+
529
+ unsigned char stemp [AX25_MAX_PACKET_LEN + 1 ];
530
+
531
+ assert (flen < (int )(sizeof (stemp )));
532
+
533
+ stemp [0 ] = (chan << 4 ) + 0 ;
534
+ memcpy (stemp + 1 , fbuf , flen );
535
+
536
+ if (kiss_debug >= 2 ) {
537
+ /* AX.25 frame with the CRC removed. */
538
+ text_color_set (DW_COLOR_DEBUG );
539
+ dw_printf ("\n" );
540
+ dw_printf ("Packet content before adding KISS framing and any escapes:\n" );
541
+ hex_dump (fbuf , flen );
542
+ }
543
+
544
+ kiss_len = kiss_encapsulate (stemp , flen + 1 , kiss_buff );
545
+
546
+ /* This has the escapes and the surrounding FENDs. */
547
+
548
+ if (kiss_debug ) {
549
+ kiss_debug_print (TO_CLIENT , NULL , kiss_buff , kiss_len );
550
+ }
551
+ }
533
552
534
553
#if __WIN32__
535
- err = send (client_sock , (char * )kiss_buff , kiss_len , 0 );
536
- if (err == SOCKET_ERROR )
537
- {
538
- text_color_set (DW_COLOR_ERROR );
539
- dw_printf ("\nError %d sending message to KISS client application. Closing connection.\n\n" , WSAGetLastError ());
540
- closesocket (client_sock );
541
- client_sock = -1 ;
542
- WSACleanup ();
543
- }
554
+ err = send (client_sock [ i ] , (char * )kiss_buff , kiss_len , 0 );
555
+ if (err == SOCKET_ERROR )
556
+ {
557
+ text_color_set (DW_COLOR_ERROR );
558
+ dw_printf ("\nError %d sending message to KISS client application. Closing connection.\n\n" , WSAGetLastError ());
559
+ closesocket (client_sock [ i ] );
560
+ client_sock [ i ] = -1 ;
561
+ WSACleanup ();
562
+ }
544
563
#else
545
- err = write (client_sock , kiss_buff , kiss_len );
546
- if (err <= 0 )
547
- {
548
- text_color_set (DW_COLOR_ERROR );
549
- dw_printf ("\nError sending message to KISS client application. Closing connection.\n\n" );
550
- close (client_sock );
551
- client_sock = -1 ;
564
+ err = write (client_sock [i ], kiss_buff , kiss_len );
565
+ if (err <= 0 )
566
+ {
567
+ text_color_set (DW_COLOR_ERROR );
568
+ dw_printf ("\nError sending message to KISS client application. Closing connection %d.\n\n" , i );
569
+ close (client_sock [i ]);
570
+ client_sock [i ] = -1 ;
571
+ }
552
572
}
553
573
#endif
554
574
@@ -635,20 +655,21 @@ static int read_from_socket (int fd, char *ptr, int len)
635
655
/* Return one byte (value 0 - 255) */
636
656
637
657
638
- static int kiss_get (void )
658
+ static int kiss_get ( int socket_id )
639
659
{
640
660
unsigned char ch ;
641
661
int n ;
642
662
643
663
while (1 ) {
644
664
645
- while (client_sock <= 0 ) {
665
+ #if __WIN32__
666
+ while (client_sock [socket_id ] <= 0 ) {
646
667
SLEEP_SEC (1 ); /* Not connected. Try again later. */
647
668
}
648
-
669
+ #endif
649
670
/* Just get one byte at a time. */
650
671
651
- n = read_from_socket (client_sock , (char * )(& ch ), 1 );
672
+ n = read_from_socket (client_sock [ socket_id ] , (char * )(& ch ), 1 );
652
673
653
674
if (n == 1 ) {
654
675
#if DEBUG9
@@ -670,11 +691,13 @@ static int kiss_get (void)
670
691
text_color_set (DW_COLOR_ERROR );
671
692
dw_printf ("\nError reading KISS byte from client application. Closing connection.\n\n" );
672
693
#if __WIN32__
673
- closesocket (client_sock );
694
+ closesocket (client_sock [ socket_id ] );
674
695
#else
675
- close (client_sock );
696
+ close (client_sock [ socket_id ] );
676
697
#endif
677
- client_sock = -1 ;
698
+ client_sock [socket_id ] = -1 ;
699
+
700
+ return ( -1 );
678
701
}
679
702
}
680
703
@@ -683,15 +706,65 @@ static int kiss_get (void)
683
706
static THREAD_F kissnet_listen_thread (void * arg )
684
707
{
685
708
unsigned char ch ;
686
-
709
+ int i = 0 ;
710
+ int count ;
711
+ int max_fd ;
712
+ fd_set set ;
713
+ struct timeval tv ;
687
714
#if DEBUG
688
715
text_color_set (DW_COLOR_DEBUG );
689
- dw_printf ("kissnet_listen_thread ( socket = %d )\n" , client_sock );
716
+ dw_printf ("kissnet_listen_thread ( socket = %d )\n" , client_sock [ i ] );
690
717
#endif
691
718
692
719
while (1 ) {
693
- ch = kiss_get ();
694
- kiss_rec_byte (& kf , ch , kiss_debug , kissnet_send_rec_packet );
720
+ #if __WIN32__
721
+ ch = kiss_get ( i );
722
+ kiss_rec_byte (& kf [i ], ch , kiss_debug , kissnet_send_rec_packet );
723
+ #else
724
+ FD_ZERO ( & set );
725
+ for ( max_fd = 0 , i = 0 ; i < MAX_NET_CLIENTS ; i ++ )
726
+ if ( client_sock [i ] > 0 ) {
727
+ FD_SET ( client_sock [i ], & set );
728
+ if ( client_sock [i ] > max_fd )
729
+ max_fd = client_sock [i ];
730
+ }
731
+
732
+ if ( max_fd == 0 ) {
733
+ SLEEP_SEC (1 );
734
+ continue ;
735
+ }
736
+ else
737
+ {
738
+ tv .tv_sec = 1 ;
739
+ tv .tv_usec = 0 ;
740
+ count = select ( max_fd + 1 , & set , NULL , NULL , & tv );
741
+ }
742
+
743
+ if ( count > 0 ) {
744
+ for ( i = 0 ; i < MAX_NET_CLIENTS ; i ++ ) {
745
+ if ( client_sock [i ] > 0 && FD_ISSET ( client_sock [i ], & set )) {
746
+ ch = kiss_get ( i );
747
+ if ( ch != -1 )
748
+ kiss_rec_byte (& kf [i ], ch , kiss_debug ,
749
+ kissnet_send_rec_packet );
750
+ }
751
+ }
752
+ }
753
+ else if ( count == 0 )
754
+ {
755
+ #if DEBUG
756
+ dw_printf ("kissnet_listen_thread timeout\n" );
757
+ #endif
758
+ }
759
+ else
760
+ {
761
+ // TODO : Should we do something here ?
762
+ #if DEBUG
763
+ dw_printf ("kissnet_listen_thread error\n" );
764
+ #endif
765
+ }
766
+
767
+ #endif
695
768
}
696
769
697
770
#if __WIN32__
0 commit comments