From 19be1db46ce191795ef78704d6b26f4f1813dcb1 Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Fri, 15 Mar 2024 19:16:44 -0400 Subject: [PATCH] M17 - IP Frame WIP2; --- src/dsd_main.c | 4 +++ src/dsd_rigctl.c | 9 +++--- src/m17.c | 75 +++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 77 insertions(+), 11 deletions(-) diff --git a/src/dsd_main.c b/src/dsd_main.c index 1127021..05df745 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -3071,6 +3071,10 @@ main (int argc, char **argv) if (curr != NULL) state.m17_vox = atoi(curr); + curr = strtok(NULL, ":"); //m17 UDP/IP Frame enable + if (curr != NULL) + opts.m17_use_ip = atoi(curr); + M17END: ; //do nothing //check to make sure can value is no greater than 15 (4 bit value) diff --git a/src/dsd_rigctl.c b/src/dsd_rigctl.c index 410cb4d..7ed7973 100644 --- a/src/dsd_rigctl.c +++ b/src/dsd_rigctl.c @@ -338,17 +338,18 @@ int udp_socket_blasterA(dsd_opts * opts, dsd_state * state, size_t nsam, void * int m17_socket_blaster(dsd_opts * opts, dsd_state * state, size_t nsam, void * data) { UNUSED(state); - size_t err = 0; + unsigned long long int err = 0; //listen with: - //54 packed bytes + //XX packed bytes //socat stdio udp-listen:17000 | (decoder) //send audio or data to socket err = sendto(opts->m17_udp_sock, data, nsam, 0, (const struct sockaddr * ) & addressM17, sizeof(struct sockaddr_in)); - if (err < 0) fprintf (stderr, "\n UDP SENDTO ERR %ld", err); //return value here is size_t number of characters sent, or -1 for failure - if (err < nsam) fprintf (stderr, "\n UDP Underflow %ld", err); //I'm not even sure if this is possible + //RETURN Value should be ACKN or NACK, or PING, or PONG + + return (err); } int udp_socket_connect(dsd_opts * opts, dsd_state * state) diff --git a/src/m17.c b/src/m17.c index b5e4c66..8a162be 100644 --- a/src/m17.c +++ b/src/m17.c @@ -1366,7 +1366,7 @@ void encodeM17RF (dsd_opts * opts, dsd_state * state, uint8_t * input, int type) void encodeM17STR(dsd_opts * opts, dsd_state * state) { - //WIP: Finish creating audio of the encoded signal + //WIP: IP Frame Things and User Variables for Reflectors, etc uint8_t nil[368]; //empty array to send to RF during Preamble, EOT Marker, or Dead Air memset (nil, 0, sizeof(nil)); @@ -1381,6 +1381,7 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) int use_ip = 0; //1 to enable IP Frame Broadcast over UDP int udpport = 17000; //port number for M17 IP Frmae (default is 17000) sprintf (opts->m17_hostname, "%s", "127.0.0.1"); //enter IP address or hostname here + uint8_t reflector_module = 0x41; //'A', single letter reflector module A-Z, 0x41 is A uint8_t can = 7; //channel access number //numerical representation of dst and src after b40 encoding, or special/reserved value unsigned long long int dst = 0; @@ -1421,7 +1422,7 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) //WIP: Open UDP port to 17000 and see if any other config info is necessary for running standard IP frames, etc, //or perhaps just also configure an input format for that ip streaming method, may need to handle UDP control packets (conn, ackn, nack, ping, pong, disc) int sock_err; - if (use_ip == 1) + if (opts->m17_use_ip == 1) { opts->m17_portno = udpport; sock_err = udp_socket_connectM17(opts, state); @@ -1430,13 +1431,21 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) fprintf (stderr, "Error Configuring UDP Socket for M17 IP Frame :( \n"); use_ip = 0; } - else opts->m17_use_ip = 1; + else use_ip = 1; } - //TODO: See if we need to send a conn and/or receice any ackn/nack/ping/pong commands later + //TODO: See if we need to send a conn and/or receive any ackn/nack/ping/pong commands later //WIP: Standard IP Framing uint8_t magic[4] = {0x4D, 0x31, 0x37, 0x20}; - uint8_t sid[2]; memset (sid, 0, sizeof(sid)); + uint8_t ackn[4] = {0x41, 0x43, 0x4B, 0x4E}; UNUSED(ackn); + uint8_t nack[4] = {0x4E, 0x41, 0x43, 0x4B}; UNUSED(nack); + uint8_t conn[11]; memset (conn, 0, sizeof(conn)); + uint8_t disc[10]; memset (disc, 0, sizeof(disc)); + uint8_t ping[10]; memset (ping, 0, sizeof(ping)); + uint8_t pong[10]; memset (pong, 0, sizeof(pong)); + uint8_t retn[10]; memset (retn, 0, sizeof(retn)); + int udp_return = 0; UNUSED(udp_return); + uint8_t sid[2]; memset (sid, 0, sizeof(sid)); //NONCE time_t ts = time(NULL); //timestamp since epoch / "Unix Time" @@ -1552,6 +1561,54 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) } //end CSD conversion + //Setup conn, disc, ping, pong values + conn[0] = 0x43; conn[1] = 0x4F; conn[2] = 0x4E; conn[3] = 0x4E; conn[10] = reflector_module; + disc[0] = 0x44; disc[1] = 0x49; disc[2] = 0x53; disc[3] = 0x43; + ping[0] = 0x50; ping[1] = 0x49; ping[2] = 0x4E; ping[3] = 0x47; + pong[0] = 0x50; pong[1] = 0x4F; pong[2] = 0x4E; pong[3] = 0x47; + + for (i = 0; i < 6; i++) + { + conn[i+4] = (src >> 48-(8*i)) & 0xFF; + disc[i+4] = (src >> 48-(8*i)) & 0xFF; + ping[i+4] = (src >> 48-(8*i)) & 0xFF; + pong[i+4] = (src >> 48-(8*i)) & 0xFF; + } + + //debug + // fprintf (stderr, " CONN: "); + // for (i = 0; i < 11; i++) + // fprintf (stderr, " %02X", conn[i]); + + //SEND CONN to reflector + if (use_ip == 1) + udp_return = m17_socket_blaster (opts, state, 11, conn); + + //WIP: Read UDP ACKN/NACK value, disable use_ip if NULL or nack return + // if (use_ip && udp_return) //disabled for now, need to look into how to view the return or received value + // { + // retn[0] = (udp_return >> 24) & 0xFF; + // retn[1] = (udp_return >> 16) & 0xFF; + // retn[2] = (udp_return >> 8) & 0xFF; + // retn[3] = (udp_return >> 0) & 0xFF; + // if (memcmp (nack, retn, 4) == 0) use_ip = 0; + + // if (use_ip) fprintf (stderr, "\n Connected to reflector successfully!"); + // else fprintf (stderr, "\n NACK from reflector!"); + + // //debug + // fprintf (stderr, " RETURN: %08llX; RETN: ", udp_return); + // for (i = 0; i < 4; i++) + // fprintf (stderr, " %02X", retn[i]); + + // memset (retn, 0, sizeof(retn)); + // } + // else + // { + // use_ip = 0; + // fprintf (stderr, "\n No Reply from Reflector!"); + // } + //load dst and src values into the LSF for (i = 0; i < 48; i++) m17_lsf[i] = (dst >> 47ULL-(unsigned long long int)i) & 1; for (i = 0; i < 48; i++) m17_lsf[i+48] = (src >> 47ULL-(unsigned long long int)i) & 1; @@ -2071,8 +2128,8 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) // } //WIP: Send packed IP frame to UDP port 17000 if opened successfully - if (opts->m17_use_ip == 1) - m17_socket_blaster (opts, state, 54, m17_ip_packed); + if (use_ip == 1) + udp_return = m17_socket_blaster (opts, state, 54, m17_ip_packed); //increment lich_cnt, reset on 6 lich_cnt++; @@ -2246,6 +2303,10 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) ncursesPrinter(opts, state); } + + //SEND DISC to reflector + if (use_ip == 1) + udp_return = m17_socket_blaster (opts, state, 10, disc); //free allocated memory free(samp1);