kopia lustrzana https://github.com/Hamlib/Hamlib
rodzic
a4c10c3206
commit
ca763d4ff1
441
src/multicast.c
441
src/multicast.c
|
@ -86,27 +86,21 @@ static int multicast_status_changed(RIG *rig)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void json_add_string(char *msg, const char *key, const char *value)
|
||||
void json_add_string(char *msg, const char *key, const char *value,
|
||||
int addComma)
|
||||
{
|
||||
if (strlen(msg) != 0)
|
||||
{
|
||||
strcat(msg, ",\n");
|
||||
}
|
||||
|
||||
strcat(msg, "\"");
|
||||
strcat(msg, key);
|
||||
strcat(msg, "\": ");
|
||||
strcat(msg, "\"");
|
||||
strcat(msg, value);
|
||||
strcat(msg, "\"");
|
||||
|
||||
if (addComma) { strcat(msg, ",\n"); }
|
||||
}
|
||||
|
||||
void json_add_int(char *msg, const char *key, const int number)
|
||||
void json_add_int(char *msg, const char *key, const int number, int addComma)
|
||||
{
|
||||
if (strlen(msg) != 0)
|
||||
{
|
||||
strcat(msg, ",\n");
|
||||
}
|
||||
|
||||
strcat(msg, "\"");
|
||||
strcat(msg, key);
|
||||
|
@ -114,6 +108,11 @@ void json_add_int(char *msg, const char *key, const int number)
|
|||
char tmp[64];
|
||||
sprintf(tmp, "%d", number);
|
||||
strcat(msg, tmp);
|
||||
|
||||
if (addComma)
|
||||
{
|
||||
strcat(msg, ",\n");
|
||||
}
|
||||
}
|
||||
|
||||
void json_add_double(char *msg, const char *key, const double value)
|
||||
|
@ -131,49 +130,52 @@ void json_add_double(char *msg, const char *key, const double value)
|
|||
strcat(msg, tmp);
|
||||
}
|
||||
|
||||
void json_add_boolean(char *msg, const char *key, const int value)
|
||||
void json_add_boolean(char *msg, const char *key, const int value, int addComma)
|
||||
{
|
||||
if (strlen(msg) != 0)
|
||||
{
|
||||
strcat(msg, ",\n");
|
||||
}
|
||||
|
||||
strcat(msg, "\"");
|
||||
strcat(msg, key);
|
||||
strcat(msg, "\": ");
|
||||
char tmp[64];
|
||||
sprintf(tmp, "%s", value == 0 ? "False" : "True");
|
||||
sprintf(tmp, "%s", value == 0 ? "false" : "true");
|
||||
strcat(msg, tmp);
|
||||
|
||||
if (addComma)
|
||||
{
|
||||
strcat(msg, ",\n");
|
||||
}
|
||||
}
|
||||
|
||||
void json_add_time(char *msg)
|
||||
void json_add_time(char *msg, int addComma)
|
||||
{
|
||||
char mydate[256];
|
||||
date_strget(mydate, sizeof(mydate), 0);
|
||||
|
||||
if (strlen(msg) != 0)
|
||||
|
||||
strcat(msg, "\"Time\": \"");
|
||||
strcat(msg, mydate);
|
||||
strcat(msg, "\"");
|
||||
|
||||
if (addComma)
|
||||
{
|
||||
strcat(msg, ",\n");
|
||||
}
|
||||
|
||||
strcat(msg, "\"Time\": ");
|
||||
strcat(msg, mydate);
|
||||
}
|
||||
|
||||
void json_add_vfoA(RIG *rig, char *msg)
|
||||
{
|
||||
strcat(msg, "{\n");
|
||||
json_add_string(msg, "Name", "VFOA");
|
||||
json_add_int(msg, "Freq", rig->state.cache.freqMainA);
|
||||
json_add_string(msg, "Name", "VFOA", 1);
|
||||
json_add_int(msg, "Freq", rig->state.cache.freqMainA, 1);
|
||||
|
||||
if (strlen(rig_strrmode(rig->state.cache.modeMainA)) > 0)
|
||||
{
|
||||
json_add_string(msg, "Mode", rig_strrmode(rig->state.cache.modeMainA));
|
||||
json_add_string(msg, "Mode", rig_strrmode(rig->state.cache.modeMainA), 1);
|
||||
}
|
||||
|
||||
if (rig->state.cache.widthMainA > 0)
|
||||
{
|
||||
json_add_int(msg, "Width", rig->state.cache.widthMainA);
|
||||
json_add_int(msg, "Width", rig->state.cache.widthMainA, 1);
|
||||
}
|
||||
|
||||
// what about full duplex? rx_vfo would be in rx all the time?
|
||||
|
@ -181,70 +183,70 @@ void json_add_vfoA(RIG *rig, char *msg)
|
|||
{
|
||||
if (rig->state.tx_vfo && (RIG_VFO_B | RIG_VFO_MAIN_B))
|
||||
{
|
||||
json_add_boolean(msg, "RX", !rig->state.cache.ptt);
|
||||
json_add_boolean(msg, "TX", 0);
|
||||
json_add_boolean(msg, "RX", !rig->state.cache.ptt, 1);
|
||||
json_add_boolean(msg, "TX", 0, 0);
|
||||
}
|
||||
else // we must be in reverse split
|
||||
{
|
||||
json_add_boolean(msg, "RX", 0);
|
||||
json_add_boolean(msg, "TX", rig->state.cache.ptt);
|
||||
json_add_boolean(msg, "RX", 0, 1);
|
||||
json_add_boolean(msg, "TX", rig->state.cache.ptt, 0);
|
||||
}
|
||||
}
|
||||
else if (rig->state.current_vfo && (RIG_VFO_A | RIG_VFO_MAIN_A))
|
||||
{
|
||||
json_add_boolean(msg, "RX", !rig->state.cache.ptt);
|
||||
json_add_boolean(msg, "TX", rig->state.cache.ptt);
|
||||
json_add_boolean(msg, "RX", !rig->state.cache.ptt, 1);
|
||||
json_add_boolean(msg, "TX", rig->state.cache.ptt, 0);
|
||||
}
|
||||
else // VFOB must be active so never RX or TX
|
||||
{
|
||||
json_add_boolean(msg, "RX", 0);
|
||||
json_add_boolean(msg, "TX", 0);
|
||||
json_add_boolean(msg, "RX", 0, 1);
|
||||
json_add_boolean(msg, "TX", 0, 0);
|
||||
}
|
||||
|
||||
strcat(msg, "\n}\n");
|
||||
strcat(msg, "\n}");
|
||||
}
|
||||
|
||||
void json_add_vfoB(RIG *rig, char *msg)
|
||||
{
|
||||
strcat(msg, "{\n");
|
||||
json_add_string(msg, "Name", "VFOB");
|
||||
json_add_int(msg, "Freq", rig->state.cache.freqMainB);
|
||||
strcat(msg, ",\n{\n");
|
||||
json_add_string(msg, "Name", "VFOB", 1);
|
||||
json_add_int(msg, "Freq", rig->state.cache.freqMainB, 1);
|
||||
|
||||
if (strlen(rig_strrmode(rig->state.cache.modeMainB)) > 0)
|
||||
{
|
||||
json_add_string(msg, "Mode", rig_strrmode(rig->state.cache.modeMainB));
|
||||
json_add_string(msg, "Mode", rig_strrmode(rig->state.cache.modeMainB), 1);
|
||||
}
|
||||
|
||||
if (rig->state.cache.widthMainB > 0)
|
||||
{
|
||||
json_add_int(msg, "Width", rig->state.cache.widthMainB);
|
||||
json_add_int(msg, "Width", rig->state.cache.widthMainB, 1);
|
||||
}
|
||||
|
||||
if (rig->state.rx_vfo != rig->state.tx_vfo && rig->state.cache.split)
|
||||
{
|
||||
if (rig->state.tx_vfo && (RIG_VFO_B | RIG_VFO_MAIN_B))
|
||||
{
|
||||
json_add_boolean(msg, "RX", 0);
|
||||
json_add_boolean(msg, "TX", rig->state.cache.ptt);
|
||||
json_add_boolean(msg, "RX", 0, 1);
|
||||
json_add_boolean(msg, "TX", rig->state.cache.ptt, 0);
|
||||
}
|
||||
else // we must be in reverse split
|
||||
{
|
||||
json_add_boolean(msg, "RX", rig->state.cache.ptt);
|
||||
json_add_boolean(msg, "TX", 0);
|
||||
json_add_boolean(msg, "RX", rig->state.cache.ptt, 1);
|
||||
json_add_boolean(msg, "TX", 0, 0);
|
||||
}
|
||||
}
|
||||
else if (rig->state.current_vfo && (RIG_VFO_A | RIG_VFO_MAIN_A))
|
||||
{
|
||||
json_add_boolean(msg, "RX", !rig->state.cache.ptt);
|
||||
json_add_boolean(msg, "TX", rig->state.cache.ptt);
|
||||
json_add_boolean(msg, "RX", !rig->state.cache.ptt, 1);
|
||||
json_add_boolean(msg, "TX", rig->state.cache.ptt, 0);
|
||||
}
|
||||
else // VFOB must be active so always RX or TX
|
||||
{
|
||||
json_add_boolean(msg, "RX", 1);
|
||||
json_add_boolean(msg, "TX", 1);
|
||||
json_add_boolean(msg, "RX", 1, 1);
|
||||
json_add_boolean(msg, "TX", 1, 0);
|
||||
}
|
||||
|
||||
strcat(msg, "\n},\n");
|
||||
strcat(msg, "\n}\n]\n");
|
||||
}
|
||||
|
||||
static int multicast_send_json(RIG *rig)
|
||||
|
@ -255,13 +257,16 @@ static int multicast_send_json(RIG *rig)
|
|||
msg[0] = 0;
|
||||
snprintf(buf, sizeof(buf), "%s:%s", rig->caps->model_name,
|
||||
rig->state.rigport.pathname);
|
||||
json_add_string(msg, "ID", buf);
|
||||
json_add_time(msg);
|
||||
json_add_int(msg, "Sequence", rig->state.multicast->seqnumber++);
|
||||
json_add_string(msg, "VFOCurr", rig_strvfo(rig->state.current_vfo));
|
||||
json_add_int(msg, "Split", rig->state.cache.split);
|
||||
strcat(msg, ",\n\"VFOs\": [\n{\n");
|
||||
strcat(msg, "{\n");
|
||||
json_add_string(msg, "ID", buf, 1);
|
||||
json_add_time(msg, 1);
|
||||
json_add_int(msg, "Sequence", rig->state.multicast->seqnumber++, 1);
|
||||
json_add_string(msg, "VFOCurr", rig_strvfo(rig->state.current_vfo), 1);
|
||||
json_add_int(msg, "Split", rig->state.cache.split, 1);
|
||||
strcat(msg, "\"VFOs\": [\n");
|
||||
json_add_vfoA(rig, msg);
|
||||
json_add_vfoB(rig, msg);
|
||||
strcat(msg, "}\n");
|
||||
|
||||
// send the thing
|
||||
multicast_send(rig, msg, strlen(msg));
|
||||
|
@ -322,196 +327,198 @@ void *multicast_thread(void *vrig)
|
|||
#ifdef WIN32
|
||||
static char *GetWinsockLastError(char *errorBuffer, DWORD errorBufferSize)
|
||||
{
|
||||
void GetWinsockErrorString(char *errorBuffer, DWORD errorBufferSize) {
|
||||
int errorCode = WSAGetLastError();
|
||||
DWORD charsWritten;
|
||||
void GetWinsockErrorString(char *errorBuffer, DWORD errorBufferSize)
|
||||
{
|
||||
int errorCode = WSAGetLastError();
|
||||
DWORD charsWritten;
|
||||
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
errorCode,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
errorBuffer,
|
||||
errorBufferSize,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
errorCode,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
errorBuffer,
|
||||
errorBufferSize,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
int multicast_init(RIG *rig, char *addr, int port)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WSADATA wsaData;
|
||||
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
|
||||
int multicast_init(RIG * rig, char *addr, int port)
|
||||
{
|
||||
char errorMessage[1024];
|
||||
fprintf(stderr, "WSAStartup failed: %s\n", GetWinsockLastError(errorMessage, sizeof(errorMessage)));
|
||||
return 1;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
WSADATA wsaData;
|
||||
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
|
||||
{
|
||||
char errorMessage[1024];
|
||||
fprintf(stderr, "WSAStartup failed: %s\n", GetWinsockLastError(errorMessage,
|
||||
sizeof(errorMessage)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (rig->state.multicast == NULL)
|
||||
{
|
||||
rig->state.multicast = calloc(1, sizeof(struct multicast_s));
|
||||
}
|
||||
else if (rig->state.multicast->multicast_running) { return RIG_OK; } // we only need one port
|
||||
if (rig->state.multicast == NULL)
|
||||
{
|
||||
rig->state.multicast = calloc(1, sizeof(struct multicast_s));
|
||||
}
|
||||
else if (rig->state.multicast->multicast_running) { return RIG_OK; } // we only need one port
|
||||
|
||||
//rig->state.multicast->mreq = {0};
|
||||
//rig->state.multicast->mreq = {0};
|
||||
|
||||
if (addr == NULL) { addr = RIG_MULTICAST_ADDR; }
|
||||
if (addr == NULL) { addr = RIG_MULTICAST_ADDR; }
|
||||
|
||||
if (port == 0) { port = RIG_MULTICAST_PORT; }
|
||||
if (port == 0) { port = RIG_MULTICAST_PORT; }
|
||||
|
||||
// Create a UDP socket
|
||||
rig->state.multicast->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
// Create a UDP socket
|
||||
rig->state.multicast->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
||||
if (rig->state.multicast->sock < 0)
|
||||
{
|
||||
if (rig->state.multicast->sock < 0)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int err = WSAGetLastError();
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: socket: WSAGetLastError=%d\n", __func__, err);
|
||||
int err = WSAGetLastError();
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: socket: WSAGetLastError=%d\n", __func__, err);
|
||||
#else
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: socket: %s\n", __func__, strerror(errno));
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: socket: %s\n", __func__, strerror(errno));
|
||||
#endif
|
||||
return -RIG_EIO;
|
||||
return -RIG_EIO;
|
||||
}
|
||||
|
||||
// Set the SO_REUSEADDR option to allow multiple processes to use the same address
|
||||
int optval = 1;
|
||||
|
||||
if (setsockopt(rig->state.multicast->sock, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char *)&optval,
|
||||
sizeof(optval)) < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno));
|
||||
return -RIG_EIO;
|
||||
}
|
||||
|
||||
// Bind the socket to any available local address and the specified port
|
||||
struct sockaddr_in saddr = {0};
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
saddr.sin_port = htons(port);
|
||||
|
||||
if (bind(rig->state.multicast->sock, (struct sockaddr *)&saddr,
|
||||
sizeof(saddr)) < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: bind: %s\n", __func__, strerror(errno));
|
||||
return -RIG_EIO;
|
||||
}
|
||||
|
||||
// Construct the multicast group address
|
||||
// struct ip_mreq mreq = {0};
|
||||
rig->state.multicast->mreq.imr_multiaddr.s_addr = inet_addr(addr);
|
||||
rig->state.multicast->mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
// Set the multicast TTL (time-to-live) to limit the scope of the packets
|
||||
char ttl = 1;
|
||||
|
||||
if (setsockopt(rig->state.multicast->sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
|
||||
sizeof(ttl)) < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno));
|
||||
return -RIG_EIO;
|
||||
}
|
||||
|
||||
// Join the multicast group
|
||||
if (setsockopt(rig->state.multicast->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
||||
(char *)&rig->state.multicast->mreq, sizeof(rig->state.multicast->mreq)) < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno));
|
||||
return -RIG_EIO;
|
||||
}
|
||||
|
||||
// prime the dest_addr for the send routine
|
||||
rig->state.multicast->dest_addr.sin_family = AF_INET;
|
||||
rig->state.multicast->dest_addr.sin_addr.s_addr = inet_addr(addr);
|
||||
rig->state.multicast->dest_addr.sin_port = htons(port);
|
||||
|
||||
printf("starting thread\n");
|
||||
|
||||
rig->state.multicast->runflag = 1;
|
||||
pthread_create(&rig->state.multicast->threadid, NULL, multicast_thread,
|
||||
(void *)rig);
|
||||
//printf("threadid=%ld\n", rig->state.multicast->threadid);
|
||||
rig->state.multicast->multicast_running = 1;
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
// Set the SO_REUSEADDR option to allow multiple processes to use the same address
|
||||
int optval = 1;
|
||||
|
||||
if (setsockopt(rig->state.multicast->sock, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char *)&optval,
|
||||
sizeof(optval)) < 0)
|
||||
void multicast_close(RIG * rig)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno));
|
||||
return -RIG_EIO;
|
||||
int retval;
|
||||
|
||||
// Leave the multicast group
|
||||
if ((retval = setsockopt(rig->state.multicast->sock, IPPROTO_IP,
|
||||
IP_DROP_MEMBERSHIP, (char *)&rig->state.multicast->mreq,
|
||||
sizeof(rig->state.multicast->mreq))) < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
// Close the socket
|
||||
if ((retval = close(rig->state.multicast->sock)))
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: close: %s\n", __func__, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
// Bind the socket to any available local address and the specified port
|
||||
struct sockaddr_in saddr = {0};
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
saddr.sin_port = htons(port);
|
||||
|
||||
if (bind(rig->state.multicast->sock, (struct sockaddr *)&saddr,
|
||||
sizeof(saddr)) < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: bind: %s\n", __func__, strerror(errno));
|
||||
return -RIG_EIO;
|
||||
}
|
||||
|
||||
// Construct the multicast group address
|
||||
// struct ip_mreq mreq = {0};
|
||||
rig->state.multicast->mreq.imr_multiaddr.s_addr = inet_addr(addr);
|
||||
rig->state.multicast->mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
// Set the multicast TTL (time-to-live) to limit the scope of the packets
|
||||
char ttl = 1;
|
||||
|
||||
if (setsockopt(rig->state.multicast->sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
|
||||
sizeof(ttl)) < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno));
|
||||
return -RIG_EIO;
|
||||
}
|
||||
|
||||
// Join the multicast group
|
||||
if (setsockopt(rig->state.multicast->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
||||
(char *)&rig->state.multicast->mreq, sizeof(rig->state.multicast->mreq)) < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno));
|
||||
return -RIG_EIO;
|
||||
}
|
||||
|
||||
// prime the dest_addr for the send routine
|
||||
rig->state.multicast->dest_addr.sin_family = AF_INET;
|
||||
rig->state.multicast->dest_addr.sin_addr.s_addr = inet_addr(addr);
|
||||
rig->state.multicast->dest_addr.sin_port = htons(port);
|
||||
|
||||
printf("starting thread\n");
|
||||
|
||||
rig->state.multicast->runflag = 1;
|
||||
pthread_create(&rig->state.multicast->threadid, NULL, multicast_thread,
|
||||
(void *)rig);
|
||||
//printf("threadid=%ld\n", rig->state.multicast->threadid);
|
||||
rig->state.multicast->multicast_running = 1;
|
||||
return RIG_OK;
|
||||
}
|
||||
|
||||
void multicast_close(RIG *rig)
|
||||
{
|
||||
int retval;
|
||||
|
||||
// Leave the multicast group
|
||||
if ((retval = setsockopt(rig->state.multicast->sock, IPPROTO_IP,
|
||||
IP_DROP_MEMBERSHIP, (char *)&rig->state.multicast->mreq,
|
||||
sizeof(rig->state.multicast->mreq))) < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
// Close the socket
|
||||
if ((retval = close(rig->state.multicast->sock)))
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: close: %s\n", __func__, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
// if msglen=0 msg is assumed to be a string
|
||||
int multicast_send(RIG *rig, const char *msg, int msglen)
|
||||
{
|
||||
// Construct the message to send
|
||||
if (msglen == 0) { msglen = strlen((char *)msg); }
|
||||
|
||||
// Send the message to the multicast group
|
||||
ssize_t num_bytes = sendto(rig->state.multicast->sock, msg, msglen, 0,
|
||||
(struct sockaddr *)&rig->state.multicast->dest_addr,
|
||||
sizeof(rig->state.multicast->dest_addr));
|
||||
|
||||
if (num_bytes < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: sendto: %s\n", __func__, strerror(errno));
|
||||
return -RIG_EIO;
|
||||
}
|
||||
else
|
||||
int multicast_send(RIG * rig, const char *msg, int msglen)
|
||||
{
|
||||
// Construct the message to send
|
||||
if (msglen == 0) { msglen = strlen((char *)msg); }
|
||||
|
||||
// Send the message to the multicast group
|
||||
ssize_t num_bytes = sendto(rig->state.multicast->sock, msg, msglen, 0,
|
||||
(struct sockaddr *)&rig->state.multicast->dest_addr,
|
||||
sizeof(rig->state.multicast->dest_addr));
|
||||
|
||||
if (num_bytes < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: sendto: %s\n", __func__, strerror(errno));
|
||||
return -RIG_EIO;
|
||||
}
|
||||
else
|
||||
{
|
||||
// printf("Sent %zd bytes to multicast group %s:%d\n", num_bytes, MULTICAST_ADDR,
|
||||
// PORT);
|
||||
}
|
||||
}
|
||||
|
||||
return num_bytes;
|
||||
}
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
//#define TEST
|
||||
#ifdef TEST
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
RIG *rig;
|
||||
rig_model_t myrig_model;
|
||||
rig_set_debug_level(RIG_DEBUG_NONE);
|
||||
|
||||
if (argc > 1) { myrig_model = atoi(argv[1]); }
|
||||
else
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
myrig_model = 1035;
|
||||
RIG *rig;
|
||||
rig_model_t myrig_model;
|
||||
rig_set_debug_level(RIG_DEBUG_NONE);
|
||||
|
||||
if (argc > 1) { myrig_model = atoi(argv[1]); }
|
||||
else
|
||||
{
|
||||
myrig_model = 1035;
|
||||
}
|
||||
|
||||
rig = rig_init(myrig_model);
|
||||
|
||||
if (rig == NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
strncpy(rig->state.rigport.pathname, "/dev/ttyUSB0", HAMLIB_FILPATHLEN - 1);
|
||||
rig->state.rigport.parm.serial.rate = 38400;
|
||||
rig_open(rig);
|
||||
multicast_init(rig, "224.0.0.1", 4532);
|
||||
pthread_join(rig->state.multicast->threadid, NULL);
|
||||
pthread_exit(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rig = rig_init(myrig_model);
|
||||
|
||||
if (rig == NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
strncpy(rig->state.rigport.pathname, "/dev/ttyUSB0", HAMLIB_FILPATHLEN - 1);
|
||||
rig->state.rigport.parm.serial.rate = 38400;
|
||||
rig_open(rig);
|
||||
multicast_init(rig, "224.0.0.1", 4532);
|
||||
pthread_join(rig->state.multicast->threadid, NULL);
|
||||
pthread_exit(NULL);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -90,7 +90,7 @@ int main()
|
|||
}
|
||||
|
||||
buffer[bytes_received] = '\0';
|
||||
printf("Received: %s\n", buffer);
|
||||
printf("%s\n", buffer);
|
||||
}
|
||||
|
||||
// Drop membership before closing the socket
|
||||
|
|
Ładowanie…
Reference in New Issue