mirror of https://github.com/wb2osz/direwolf.git
Issue 186 - Copy KISS frames between TCP KISS clients.
This commit is contained in:
parent
c13375a9ab
commit
ecf5fd1d59
13
config.c
13
config.c
|
@ -854,6 +854,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
|||
p_misc_config->agwpe_port = DEFAULT_AGWPE_PORT;
|
||||
p_misc_config->kiss_port = DEFAULT_KISS_PORT;
|
||||
p_misc_config->enable_kiss_pt = 0; /* -p option */
|
||||
p_misc_config->kiss_copy = 0;
|
||||
|
||||
/* Defaults from http://info.aprs.net/index.php?title=SmartBeaconing */
|
||||
|
||||
|
@ -4332,6 +4333,16 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* KISSCOPY - Data from network KISS client is copied to all others.
|
||||
*/
|
||||
|
||||
else if (strcasecmp(t, "KISSCOPY") == 0) {
|
||||
p_misc_config->kiss_copy = 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GPSNMEA - Device name for reading from GPS receiver.
|
||||
*/
|
||||
|
@ -4712,6 +4723,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
|||
p_misc_config->maxframe_basic = n;
|
||||
}
|
||||
else {
|
||||
p_misc_config->maxframe_basic = AX25_K_MAXFRAME_BASIC_DEFAULT;
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("Line %d: Invalid MAXFRAME value outside range of %d to %d. Using default %d.\n",
|
||||
line, AX25_K_MAXFRAME_BASIC_MIN, AX25_K_MAXFRAME_BASIC_MAX, p_misc_config->maxframe_basic);
|
||||
|
@ -4737,6 +4749,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
|
|||
p_misc_config->maxframe_extended = n;
|
||||
}
|
||||
else {
|
||||
p_misc_config->maxframe_extended = AX25_K_MAXFRAME_EXTENDED_DEFAULT;
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("Line %d: Invalid EMAXFRAME value outside of range %d to %d. Using default %d.\n",
|
||||
line, AX25_K_MAXFRAME_EXTENDED_MIN, AX25_K_MAXFRAME_EXTENDED_MAX, p_misc_config->maxframe_extended);
|
||||
|
|
1
config.h
1
config.h
|
@ -35,6 +35,7 @@ struct misc_config_s {
|
|||
|
||||
int agwpe_port; /* Port number for the "AGW TCPIP Socket Interface" */
|
||||
int kiss_port; /* Port number for the "TCP KISS" protocol. */
|
||||
int kiss_copy; /* Data from network KISS client is copied to all others. */
|
||||
int enable_kiss_pt; /* Enable pseudo terminal for KISS. */
|
||||
/* Want this to be off by default because it hangs */
|
||||
/* after a while if nothing is reading from other end. */
|
||||
|
|
39
kiss_frame.c
39
kiss_frame.c
|
@ -93,6 +93,7 @@
|
|||
#include "tq.h"
|
||||
#include "xmit.h"
|
||||
#include "version.h"
|
||||
#include "kissnet.h"
|
||||
|
||||
|
||||
/* In server.c. Should probably move to some misc. function file. */
|
||||
|
@ -506,7 +507,7 @@ void kiss_rec_byte (kiss_frame_t *kf, unsigned char ch, int debug, int client, v
|
|||
* debug - Debug option is selected.
|
||||
*
|
||||
* client - Client app number for TCP KISS.
|
||||
* Ignored for pseudo termal and serial port.
|
||||
* Should be -1 for pseudo termal and serial port.
|
||||
*
|
||||
* sendfun - Function to send something to the client application.
|
||||
* "Set Hardware" can send a response.
|
||||
|
@ -522,7 +523,7 @@ void kiss_rec_byte (kiss_frame_t *kf, unsigned char ch, int debug, int client, v
|
|||
|
||||
void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug, int client, void (*sendfun)(int,int,unsigned char*,int,int))
|
||||
{
|
||||
int port;
|
||||
int port; // Should rename to chan because that's what we use everywhere else.
|
||||
int cmd;
|
||||
packet_t pp;
|
||||
alevel_t alevel;
|
||||
|
@ -534,6 +535,10 @@ void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug, int cli
|
|||
{
|
||||
case KISS_CMD_DATA_FRAME: /* 0 = Data Frame */
|
||||
|
||||
if (client >= 0) {
|
||||
kissnet_copy (kiss_msg, kiss_len, port, cmd, client);
|
||||
}
|
||||
|
||||
/* Special hack - Discard apparently bad data from Linux AX25. */
|
||||
|
||||
/* Note July 2017: There is a variant of of KISS, called SMACK, that assumes */
|
||||
|
@ -545,6 +550,36 @@ void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug, int cli
|
|||
/* Our current default is a maximum of 6 channels but it is easily */
|
||||
/* increased by changing one number and recompiling. */
|
||||
|
||||
// Additional information, from Mike Playle, December 2018, for Issue #42
|
||||
//
|
||||
// I came across this the other day with Xastir, and took a quick look.
|
||||
// The problem is fixable without the kiss_frame.c hack, which doesn't help with Xastir anyway.
|
||||
//
|
||||
// Workaround
|
||||
//
|
||||
// After the kissattach command, put the interface into CRC mode "none" with a command like this:
|
||||
//
|
||||
// # kissparms -c 1 -p radio
|
||||
//
|
||||
// Analysis
|
||||
//
|
||||
// The source of this behaviour is the kernel's KISS implementation:
|
||||
//
|
||||
// https://elixir.bootlin.com/linux/v4.9/source/drivers/net/hamradio/mkiss.c#L489
|
||||
//
|
||||
// It defaults to starting in state CRC_MODE_SMACK_TEST and ending up in mode CRC_NONE
|
||||
// after the first two packets, which have their framing byte modified by this code in the process.
|
||||
// It looks to me like deliberate behaviour on the kernel's part.
|
||||
//
|
||||
// Setting the CRC mode explicitly before sending any packets stops this state machine from running.
|
||||
//
|
||||
// Is this a bug? I don't know - that's up to you! Maybe it would make sense for Direwolf to set
|
||||
// the CRC mode itself, or to expect this behaviour and ignore these flags on the first packets
|
||||
// received from the Linux pty.
|
||||
//
|
||||
// This workaround seems sound to me, though, so perhaps this is just a documentation issue.
|
||||
|
||||
|
||||
if (kiss_len > 16 &&
|
||||
(port == 2 || port == 8) &&
|
||||
kiss_msg[1] == 'Q' << 1 &&
|
||||
|
|
87
kissnet.c
87
kissnet.c
|
@ -159,6 +159,7 @@ static THREAD_F connect_listen_thread (void *arg);
|
|||
static THREAD_F kissnet_listen_thread (void *arg);
|
||||
|
||||
|
||||
static struct misc_config_s *s_misc_config_p;
|
||||
|
||||
static int kiss_debug = 0; /* Print information flowing from and to client. */
|
||||
|
||||
|
@ -204,6 +205,8 @@ void kissnet_init (struct misc_config_s *mc)
|
|||
pthread_t cmd_listen_tid[MAX_NET_CLIENTS];
|
||||
int e;
|
||||
#endif
|
||||
s_misc_config_p = mc;
|
||||
|
||||
int kiss_port = mc->kiss_port; /* default 8001 but easily changed. */
|
||||
|
||||
|
||||
|
@ -650,6 +653,90 @@ void kissnet_send_rec_packet (int chan, int kiss_cmd, unsigned char *fbuf, int f
|
|||
} /* end kissnet_send_rec_packet */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
*
|
||||
* Name: kissnet_copy
|
||||
*
|
||||
* Purpose: Send data from one network KISS client to all others.
|
||||
*
|
||||
* Inputs: in_msg - KISS frame data without the framing or escapes.
|
||||
* The first byte is channel (port) and command (should be data).
|
||||
*
|
||||
* in_len - Number of bytes in above.
|
||||
*
|
||||
* chan - Channel. Redundant because it is also in first byte of kiss_msg.
|
||||
* Not currently used.
|
||||
*
|
||||
* cmd - KISS command nybble. Redundant because it is in first byte.
|
||||
* Should be 0 because I'm expecting this only for data.
|
||||
*
|
||||
* from_client - Number of network (TCP) client instance.
|
||||
* Should be 0, 1, 2, ...
|
||||
*
|
||||
*
|
||||
* Global In: kiss_copy - From misc. configuration.
|
||||
* This enables the feature.
|
||||
*
|
||||
*
|
||||
* Description: Send message to any attached network KISS clients, other than the one where it came from.
|
||||
* Enable this by putting KISSCOPY in the configuration file.
|
||||
* Note that this applies only to network (TCP) KISS clients, not serial port, or pseudo terminal.
|
||||
*
|
||||
*
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
|
||||
void kissnet_copy (unsigned char *in_msg, int in_len, int chan, int cmd, int from_client)
|
||||
{
|
||||
unsigned char kiss_buff[2 * AX25_MAX_PACKET_LEN];
|
||||
int kiss_len;
|
||||
int err;
|
||||
int send_to;
|
||||
|
||||
(void) chan;
|
||||
(void) cmd;
|
||||
|
||||
if (s_misc_config_p->kiss_copy) {
|
||||
|
||||
for (send_to = 0; send_to < MAX_NET_CLIENTS; send_to++) {
|
||||
|
||||
if (send_to != from_client && client_sock[send_to] != -1) {
|
||||
|
||||
kiss_len = kiss_encapsulate (in_msg, in_len, kiss_buff);
|
||||
|
||||
/* This has the escapes and the surrounding FENDs. */
|
||||
|
||||
if (kiss_debug) {
|
||||
kiss_debug_print (TO_CLIENT, NULL, kiss_buff, kiss_len);
|
||||
}
|
||||
|
||||
#if __WIN32__
|
||||
err = SOCK_SEND(client_sock[send_to], (char*)kiss_buff, kiss_len);
|
||||
if (err == SOCKET_ERROR)
|
||||
{
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("\nError %d copying message to KISS client %d application. Closing connection.\n\n", WSAGetLastError(), send_to);
|
||||
closesocket (client_sock[send_to]);
|
||||
client_sock[send_to] = -1;
|
||||
WSACleanup();
|
||||
}
|
||||
#else
|
||||
err = SOCK_SEND (client_sock[send_to], kiss_buff, kiss_len);
|
||||
if (err <= 0)
|
||||
{
|
||||
text_color_set(DW_COLOR_ERROR);
|
||||
dw_printf ("\nError copying message to KISS client %d application. Closing connection.\n\n", send_to);
|
||||
close (client_sock[send_to]);
|
||||
client_sock[send_to] = -1;
|
||||
}
|
||||
#endif
|
||||
} // if origin and destination different.
|
||||
} // loop over all KISS network clients.
|
||||
} // Feature enabled.
|
||||
|
||||
} /* end kissnet_copy */
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue