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
128
129
#include "kiss_frame.h"
129
130
#include "xmit.h"
130
131
132
+ // TODO: no idea how to do this on windows
133
+ #if __WIN32__
134
+ #define MAX_NET_CLIENTS 1
135
+ #else
136
+ #define MAX_NET_CLIENTS 4
137
+ #endif
131
138
132
- static kiss_frame_t kf ; /* Accumulated KISS frame and state of decoder. */
133
- // TODO: multiple instances if multiple KISS network clients!
139
+ static kiss_frame_t kf [ MAX_NET_CLIENTS ] ; /* Accumulated KISS frame and state of decoder. */
140
+ // TODO: multiple instances if multiple KISS network clients!
134
141
135
142
136
- static int client_sock ; /* File descriptor for socket for */
137
- /* communication with client application. */
138
- /* Set to -1 if not connected. */
139
- /* (Don't use SOCKET type because it is unsigned.) */
143
+ static int client_sock [ MAX_NET_CLIENTS ] ; /* File descriptor for socket for */
144
+ /* communication with client application. */
145
+ /* Set to -1 if not connected. */
146
+ /* (Don't use SOCKET type because it is unsigned.) */
140
147
141
148
142
149
static void * connect_listen_thread (void * arg );
@@ -187,16 +194,18 @@ void kissnet_init (struct misc_config_s *mc)
187
194
#endif
188
195
int e ;
189
196
int kiss_port = mc -> kiss_port ;
197
+ int i ;
190
198
191
199
192
200
#if DEBUG
193
201
text_color_set (DW_COLOR_DEBUG );
194
202
dw_printf ("kissnet_init ( %d )\n" , kiss_port );
195
203
#endif
196
204
197
- memset (& kf , 0 , sizeof (kf ));
198
-
199
- client_sock = -1 ;
205
+ for ( i = 0 ; i < MAX_NET_CLIENTS ; i ++ ) {
206
+ client_sock [i ] = -1 ;
207
+ memset (& kf , 0 , sizeof (kf ));
208
+ }
200
209
201
210
if (kiss_port == 0 ) {
202
211
text_color_set (DW_COLOR_INFO );
@@ -343,8 +352,12 @@ static void * connect_listen_thread (void *arg)
343
352
344
353
while (1 ) {
345
354
346
- while (client_sock > 0 ) {
347
- SLEEP_SEC (1 ); /* Already connected. Try again later. */
355
+ i = 0
356
+ while (client_sock [i ] > 0 ) {
357
+ if (( ++ i % MAX_NET_CLIENTS ) == 0 ) {
358
+ SLEEP_SEC (1 ); /* All clients already connected. Try again later. */
359
+ i = 0 ;
360
+ }
348
361
}
349
362
350
363
#define QUEUE_SIZE 5
@@ -359,9 +372,9 @@ static void * connect_listen_thread (void *arg)
359
372
text_color_set (DW_COLOR_INFO );
360
373
dw_printf ("Ready to accept KISS client application on port %s ...\n" , kiss_port_str );
361
374
362
- client_sock = accept (listen_sock , NULL , NULL );
375
+ client_sock [ i ] = accept (listen_sock , NULL , NULL );
363
376
364
- if (client_sock == -1 ) {
377
+ if (client_sock [ i ] == -1 ) {
365
378
text_color_set (DW_COLOR_ERROR );
366
379
dw_printf ("Accept failed with error: %d\n" , WSAGetLastError ());
367
380
closesocket (listen_sock );
@@ -383,6 +396,7 @@ static void * connect_listen_thread (void *arg)
383
396
int kiss_port = (int )(long )arg ;
384
397
int listen_sock ;
385
398
int bcopt = 1 ;
399
+ int i ;
386
400
387
401
listen_sock = socket (AF_INET ,SOCK_STREAM ,0 );
388
402
if (listen_sock == -1 ) {
@@ -409,12 +423,12 @@ static void * connect_listen_thread (void *arg)
409
423
#endif
410
424
411
425
if (bind (listen_sock ,(struct sockaddr * )& sockaddr ,sizeof (sockaddr )) == -1 ) {
412
- text_color_set (DW_COLOR_ERROR );
413
- dw_printf ("Bind failed with error: %d\n" , errno );
414
- dw_printf ("%s\n" , strerror (errno ));
415
- dw_printf ("Some other application is probably already using port %d.\n" , kiss_port );
416
- dw_printf ("Try using a different port number with KISSPORT in the configuration file.\n" );
417
- return (NULL );
426
+ text_color_set (DW_COLOR_ERROR );
427
+ dw_printf ("Bind failed with error: %d\n" , errno );
428
+ dw_printf ("%s\n" , strerror (errno ));
429
+ dw_printf ("Some other application is probably already using port %d.\n" , kiss_port );
430
+ dw_printf ("Try using a different port number with KISSPORT in the configuration file.\n" );
431
+ return (NULL );
418
432
}
419
433
420
434
getsockname ( listen_sock , (struct sockaddr * )(& sockaddr ), & sockaddr_size );
@@ -426,8 +440,12 @@ static void * connect_listen_thread (void *arg)
426
440
427
441
while (1 ) {
428
442
429
- while (client_sock > 0 ) {
430
- SLEEP_SEC (1 ); /* Already connected. Try again later. */
443
+ i = 0 ;
444
+ while (client_sock [i ] > 0 ) {
445
+ if (( ++ i % MAX_NET_CLIENTS ) == 0 ) {
446
+ i = 0 ;
447
+ SLEEP_SEC (1 ); /* Already connected. Try again later. */
448
+ }
431
449
}
432
450
433
451
#define QUEUE_SIZE 5
@@ -440,12 +458,12 @@ static void * connect_listen_thread (void *arg)
440
458
}
441
459
442
460
text_color_set (DW_COLOR_INFO );
443
- dw_printf ("Ready to accept KISS client application on port %d ...\n" , kiss_port );
461
+ dw_printf ("Ready to accept KISS client %d application on port %d ...\n" , i , kiss_port );
444
462
445
- client_sock = accept (listen_sock , (struct sockaddr * )(& sockaddr ),& sockaddr_size );
463
+ client_sock [ i ] = accept (listen_sock , (struct sockaddr * )(& sockaddr ),& sockaddr_size );
446
464
447
465
text_color_set (DW_COLOR_INFO );
448
- dw_printf ("\nConnected to KISS client application ...\n\n" );
466
+ dw_printf ("\nConnected to KISS client %d application on fd %d ...\n\n" , i , client_sock [ i ] );
449
467
450
468
}
451
469
#endif
@@ -483,64 +501,66 @@ void kissnet_send_rec_packet (int chan, unsigned char *fbuf, int flen)
483
501
int kiss_len ;
484
502
int j ;
485
503
int err ;
486
-
487
-
488
- if (client_sock == -1 ) {
489
- return ;
490
- }
491
- if (flen < 0 ) {
492
- flen = strlen ((char * )fbuf );
493
- if (kiss_debug ) {
494
- kiss_debug_print (TO_CLIENT , "Fake command prompt" , fbuf , flen );
495
- }
496
- strlcpy ((char * )kiss_buff , (char * )fbuf , sizeof (kiss_buff ));
497
- kiss_len = strlen ((char * )kiss_buff );
498
- }
499
- else {
500
-
501
-
502
- unsigned char stemp [AX25_MAX_PACKET_LEN + 1 ];
503
-
504
- assert (flen < sizeof (stemp ));
505
-
506
- stemp [0 ] = (chan << 4 ) + 0 ;
507
- memcpy (stemp + 1 , fbuf , flen );
508
-
509
- if (kiss_debug >= 2 ) {
510
- /* AX.25 frame with the CRC removed. */
511
- text_color_set (DW_COLOR_DEBUG );
512
- dw_printf ("\n" );
513
- dw_printf ("Packet content before adding KISS framing and any escapes:\n" );
514
- hex_dump (fbuf , flen );
515
- }
516
-
517
- kiss_len = kiss_encapsulate (stemp , flen + 1 , kiss_buff );
518
-
519
- /* This has the escapes and the surrounding FENDs. */
520
-
521
- if (kiss_debug ) {
522
- kiss_debug_print (TO_CLIENT , NULL , kiss_buff , kiss_len );
523
- }
524
- }
504
+ int i ;
505
+
506
+ for ( i = 0 ; i < MAX_NET_CLIENTS ; i ++ ) {
507
+ if (client_sock [i ] == -1 ) {
508
+ continue ;
509
+ }
510
+ if (flen < 0 ) {
511
+ flen = strlen ((char * )fbuf );
512
+ if (kiss_debug ) {
513
+ kiss_debug_print (TO_CLIENT , "Fake command prompt" , fbuf , flen );
514
+ }
515
+ strlcpy ((char * )kiss_buff , (char * )fbuf , sizeof (kiss_buff ));
516
+ kiss_len = strlen ((char * )kiss_buff );
517
+ }
518
+ else {
519
+
520
+
521
+ unsigned char stemp [AX25_MAX_PACKET_LEN + 1 ];
522
+
523
+ assert (flen < sizeof (stemp ));
524
+
525
+ stemp [0 ] = (chan << 4 ) + 0 ;
526
+ memcpy (stemp + 1 , fbuf , flen );
527
+
528
+ if (kiss_debug >= 2 ) {
529
+ /* AX.25 frame with the CRC removed. */
530
+ text_color_set (DW_COLOR_DEBUG );
531
+ dw_printf ("\n" );
532
+ dw_printf ("Packet content before adding KISS framing and any escapes:\n" );
533
+ hex_dump (fbuf , flen );
534
+ }
535
+
536
+ kiss_len = kiss_encapsulate (stemp , flen + 1 , kiss_buff );
537
+
538
+ /* This has the escapes and the surrounding FENDs. */
539
+
540
+ if (kiss_debug ) {
541
+ kiss_debug_print (TO_CLIENT , NULL , kiss_buff , kiss_len );
542
+ }
543
+ }
525
544
526
545
#if __WIN32__
527
- err = send (client_sock , (char * )kiss_buff , kiss_len , 0 );
528
- if (err == SOCKET_ERROR )
529
- {
530
- text_color_set (DW_COLOR_ERROR );
531
- dw_printf ("\nError %d sending message to KISS client application. Closing connection.\n\n" , WSAGetLastError ());
532
- closesocket (client_sock );
533
- client_sock = -1 ;
534
- WSACleanup ();
535
- }
546
+ err = send (client_sock [ i ] , (char * )kiss_buff , kiss_len , 0 );
547
+ if (err == SOCKET_ERROR )
548
+ {
549
+ text_color_set (DW_COLOR_ERROR );
550
+ dw_printf ("\nError %d sending message to KISS client application. Closing connection.\n\n" , WSAGetLastError ());
551
+ closesocket (client_sock [ i ] );
552
+ client_sock [ i ] = -1 ;
553
+ WSACleanup ();
554
+ }
536
555
#else
537
- err = write (client_sock , kiss_buff , kiss_len );
538
- if (err <= 0 )
539
- {
540
- text_color_set (DW_COLOR_ERROR );
541
- dw_printf ("\nError sending message to KISS client application. Closing connection.\n\n" );
542
- close (client_sock );
543
- client_sock = -1 ;
556
+ err = write (client_sock [i ], kiss_buff , kiss_len );
557
+ if (err <= 0 )
558
+ {
559
+ text_color_set (DW_COLOR_ERROR );
560
+ dw_printf ("\nError sending message to KISS client application. Closing connection %d.\n\n" , i );
561
+ close (client_sock [i ]);
562
+ client_sock [i ] = -1 ;
563
+ }
544
564
}
545
565
#endif
546
566
@@ -626,20 +646,21 @@ static int read_from_socket (int fd, char *ptr, int len)
626
646
/* Return one byte (value 0 - 255) */
627
647
628
648
629
- static int kiss_get (void )
649
+ static int kiss_get ( int socket_id )
630
650
{
631
651
unsigned char ch ;
632
652
int n ;
633
653
634
654
while (1 ) {
635
655
636
- while (client_sock <= 0 ) {
656
+ #if __WIN32__
657
+ while (client_sock [socket_id ] <= 0 ) {
637
658
SLEEP_SEC (1 ); /* Not connected. Try again later. */
638
659
}
639
-
660
+ #endif
640
661
/* Just get one byte at a time. */
641
662
642
- n = read_from_socket (client_sock , (char * )(& ch ), 1 );
663
+ n = read_from_socket (client_sock [ socket_id ] , (char * )(& ch ), 1 );
643
664
644
665
if (n == 1 ) {
645
666
#if DEBUG9
@@ -661,11 +682,13 @@ static int kiss_get (void)
661
682
text_color_set (DW_COLOR_ERROR );
662
683
dw_printf ("\nError reading KISS byte from clent application. Closing connection.\n\n" );
663
684
#if __WIN32__
664
- closesocket (client_sock );
685
+ closesocket (client_sock [ socket_id ] );
665
686
#else
666
- close (client_sock );
687
+ close (client_sock [ socket_id ] );
667
688
#endif
668
- client_sock = -1 ;
689
+ client_sock [socket_id ] = -1 ;
690
+
691
+ return ( -1 );
669
692
}
670
693
}
671
694
@@ -674,15 +697,65 @@ static int kiss_get (void)
674
697
static void * kissnet_listen_thread (void * arg )
675
698
{
676
699
unsigned char ch ;
677
-
700
+ int i = 0 ;
701
+ int count ;
702
+ int max_fd ;
703
+ fd_set set ;
704
+ struct timeval tv ;
678
705
#if DEBUG
679
706
text_color_set (DW_COLOR_DEBUG );
680
- dw_printf ("kissnet_listen_thread ( socket = %d )\n" , client_sock );
707
+ dw_printf ("kissnet_listen_thread ( socket = %d )\n" , client_sock [ i ] );
681
708
#endif
682
709
683
710
while (1 ) {
684
- ch = kiss_get ();
685
- kiss_rec_byte (& kf , ch , kiss_debug , kissnet_send_rec_packet );
711
+ #if __WIN32__
712
+ ch = kiss_get ( i );
713
+ kiss_rec_byte (& kf [i ], ch , kiss_debug , kissnet_send_rec_packet );
714
+ #else
715
+ FD_ZERO ( & set );
716
+ for ( max_fd = 0 , i = 0 ; i < MAX_NET_CLIENTS ; i ++ )
717
+ if ( client_sock [i ] > 0 ) {
718
+ FD_SET ( client_sock [i ], & set );
719
+ if ( client_sock [i ] > max_fd )
720
+ max_fd = client_sock [i ];
721
+ }
722
+
723
+ if ( max_fd == 0 ) {
724
+ SLEEP_SEC (1 );
725
+ continue ;
726
+ }
727
+ else
728
+ {
729
+ tv .tv_sec = 1 ;
730
+ tv .tv_usec = 0 ;
731
+ count = select ( max_fd + 1 , & set , NULL , NULL , & tv );
732
+ }
733
+
734
+ if ( count > 0 ) {
735
+ for ( i = 0 ; i < MAX_NET_CLIENTS ; i ++ ) {
736
+ if ( client_sock [i ] > 0 && FD_ISSET ( client_sock [i ], & set )) {
737
+ ch = kiss_get ( i );
738
+ if ( ch != -1 )
739
+ kiss_rec_byte (& kf [i ], ch , kiss_debug ,
740
+ kissnet_send_rec_packet );
741
+ }
742
+ }
743
+ }
744
+ else if ( count == 0 )
745
+ {
746
+ #if DEBUG
747
+ dw_printf ("kissnet_listen_thread timeout\n" );
748
+ #endif
749
+ }
750
+ else
751
+ {
752
+ // TODO : Should we do something here ?
753
+ #if DEBUG
754
+ dw_printf ("kissnet_listen_thread error\n" );
755
+ #endif
756
+ }
757
+
758
+ #endif
686
759
}
687
760
688
761
return (NULL ); /* to suppress compiler warning. */
0 commit comments