Browse Source

CCallsign now uses uint64_t for coded callsign

master
Tom Early 12 months ago
parent
commit
00935d32cd
  1. 2
      .gitignore
  2. 4
      Makefile
  3. 71
      callsign.cpp
  4. 8
      callsign.h
  5. 24
      m17protocol.cpp
  6. 2
      m17protocol.h
  7. 28
      test-all.cpp

2
.gitignore

@ -8,4 +8,4 @@ configure.mk
configure.h
reflector.cfg
mrefd
crc-test
test-all

4
Makefile

@ -43,9 +43,9 @@ DEPS = $(SRCS:.cpp=.d)
EXE=mrefd
all : $(EXE) crc-test
all : $(EXE) test-all
crc-test : crc-test.o crc.o
test-all : test-all.o crc.o callsign.o
$(CC) $^ -o $@
$(EXE) : $(OBJS)

71
callsign.cpp

@ -18,7 +18,6 @@
#include <iostream>
#include "configure.h"
#include "callsign.h"
#define M17CHARACTERS " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/."
@ -26,7 +25,7 @@
CCallsign::CCallsign()
{
memset(cs, 0, sizeof(cs));
memset(code, 0, sizeof(code));
coded = 0;
}
CCallsign::CCallsign(const std::string &callsign)
@ -44,54 +43,63 @@ void CCallsign::CSIn(const std::string &callsign)
const std::string m17_alphabet(M17CHARACTERS);
memset(cs, 0, sizeof(cs));
memcpy(cs, callsign.c_str(), (callsign.size()<10) ? callsign.size() : 9); // no more than 9 chars
uint64_t encoded = 0;
coded = 0;
for( int i=int(callsign.size()-1); i>=0; i-- ) {
auto pos = m17_alphabet.find(cs[i]);
if (pos == std::string::npos) {
pos = 0;
}
cs[i] = m17_alphabet[pos]; // replace with valid character
encoded *= 40;
encoded += pos;
// cs[i] = m17_alphabet[pos]; // replace with valid character
coded *= 40;
coded += pos;
}
// strip trailing spaces (just to be nice!)
auto len = strlen(cs);
while ((' ' == cs[len-1]) && len)
cs[--len] = 0;
// auto len = strlen(cs);
// while ((' ' == cs[len-1]) && len)
// cs[--len] = 0;
// fill in the encoded value
for (int i=0; i<6; i++) {
code[i] = (encoded >> (8*(5-i)) & 0xFFU);
}
}
const std::string CCallsign::GetCS(unsigned len) const
{
if (len > 9)
len = 9;
std::string rval(cs);
if (len)
rval.resize(len, ' ');
return rval;
}
void CCallsign::CodeIn(const uint8_t *in)
{
const std::string m17_alphabet(M17CHARACTERS);
memset(cs, 0, 10);
uint64_t coded = in[0];
coded = in[0];
for (int i=1; i<6; i++)
coded = (coded << 8) | in[i];
if (coded > 0xee6b27ffffffu) {
std::cerr << "Callsign code is too large, 0x" << std::hex << coded << std::dec << std::endl;
return;
}
memcpy(code, in, 6);
auto c = coded;
int i = 0;
while (coded) {
cs[i++] = m17_alphabet[coded % 40];
coded /= 40;
while (c) {
cs[i++] = m17_alphabet[c % 40];
c /= 40;
}
}
const std::string CCallsign::GetCS(unsigned len) const
void CCallsign::CodeOut(uint8_t *out) const
{
if (len > 9)
len = 9;
std::string rval(cs);
rval.resize(len, ' ');
return rval;
memset(out, 0, 6);
auto c = coded;
auto pout = out+5;
while (c)
{
*pout-- = c % 0x100u;
c /= 0x100u;
}
}
char CCallsign::GetModule() const
@ -107,25 +115,14 @@ bool CCallsign::HasSameCallsign(const CCallsign &call) const
return (this->GetCS(8) == call.GetCS(8));
}
bool CCallsign::HasValidModule() const
{
auto i = GetModule() - 'A';
if (i >= 0)
{
if (i < NB_OF_MODULES)
return true;
}
return false;
}
bool CCallsign::operator==(const CCallsign &rhs) const
{
return (0 == memcmp(code, rhs.code, 6));
return coded == rhs.coded;
}
bool CCallsign::operator!=(const CCallsign &rhs) const
{
return (0 != memcmp(code, rhs.code, 6));
return coded != rhs.coded;
}
bool CCallsign::HasSameCallsignWithWildcard(const CCallsign &callsign) const

8
callsign.h

@ -30,17 +30,17 @@ public:
CCallsign(const uint8_t *code);
void CSIn(const std::string &cs);
void CodeIn(const uint8_t *code);
const std::string GetCS(unsigned len = 9) const;
void CodeOut(uint8_t *out) const { memcpy(out, code, 6); };
const std::string GetCS(unsigned len = 0) const;
void CodeOut(uint8_t *out) const;
size_t Hash() const { return coded; }
bool operator==(const CCallsign &rhs) const;
bool operator!=(const CCallsign &rhs) const;
char GetModule(void) const;
bool HasValidModule() const;
bool HasSameCallsignWithWildcard(const CCallsign &callsign) const;
void SetModule(char m);
friend std::ostream &operator<<(std::ostream &stream, const CCallsign &call);
bool HasSameCallsign(const CCallsign &call) const;
private:
uint8_t code[6];
uint64_t coded;
char cs[10];
};

24
m17protocol.cpp

@ -440,13 +440,10 @@ void CM17Protocol::HandlePeerLinks(void)
{
if ( (*it).GetCallsign().HasSameCallsignWithWildcard(CCallsign("M17-*")) )
{
if ( nullptr == peers->FindPeer((*it).GetCallsign()) )
{
// send connect packet to re-initiate peer link
EncodeInterlinkConnectPacket(connect, (*it).GetModules());
Send(connect.magic, sizeof(SInterConnect), (*it).GetIp());
std::cout << "Sent connect packet to M17 peer " << (*it).GetCallsign() << " @ " << (*it).GetIp() << " for module(s) " << (*it).GetModules() << std::endl;
}
// send connect packet to re-initiate peer link
EncodeInterlinkConnectPacket(connect, (*it).GetModules());
Send(connect.magic, sizeof(SInterConnect), (*it).GetIp());
std::cout << "Sent connect packet to M17 peer " << (*it).GetCallsign() << " @ " << (*it).GetIp() << " for module(s) " << (*it).GetModules() << std::endl;
}
}
@ -547,6 +544,17 @@ bool CM17Protocol::IsValidKeepAlive(const uint8_t *buf, CCallsign &cs)
return false;
}
bool CM17Protocol::HasValidModule(const CCallsign &cs) const
{
auto i = cs.GetModule() - 'A';
if (i >= 0)
{
if (i < NB_OF_MODULES)
return true;
}
return false;
}
bool CM17Protocol::IsValidPacket(const uint8_t *buf, bool is_internal, std::unique_ptr<CPacket> &packet)
{
if (0 == memcmp(buf, "M17 ", 4)) // we tested the size before we got here
@ -555,7 +563,7 @@ bool CM17Protocol::IsValidPacket(const uint8_t *buf, bool is_internal, std::uniq
packet = std::unique_ptr<CPacket>(new CPacket(buf, is_internal));
// check validity of packet
auto dest = packet->GetDestCallsign();
if (dest.HasValidModule() && dest.HasSameCallsign(GetReflectorCallsign()))
if (HasValidModule(dest) && dest.HasSameCallsign(GetReflectorCallsign()))
{
if (std::regex_match(packet->GetSourceCallsign().GetCS(), clientRegEx))
{ // looks like a valid source

2
m17protocol.h

@ -62,6 +62,8 @@ protected:
bool IsValidInterlinkConnect(const uint8_t *, CCallsign &, char *);
bool IsVaildInterlinkAcknowledge(const uint8_t *, CCallsign &, char *);
bool HasValidModule(const CCallsign &cs) const;
// packet encoding helpers
void EncodeKeepAlivePacket(uint8_t *);
void EncodeConnectAckPacket(uint8_t *);

crc-test.cpp → test-all.cpp

@ -2,9 +2,37 @@
#include <cstring>
#include "crc.h"
#include "callsign.h"
int main()
{
if (sizeof(uint64_t) != sizeof(size_t))
{
printf("ERROR! Type size_t is not 64 bits.\n");
return 1;
}
std::string callsign("M17-USA A");
CCallsign cs(callsign);
auto coded = cs.Hash();
if (coded == 0x05f74c74caedu)
{
uint8_t code[6] = { 0 };
auto c = coded;
for (int i=5; c; i--)
{
code[i] = c % 0x100u;
c /= 0x100u;
}
CCallsign cs1(code);
printf("Callsign %s is 0x%lx and decodes back to %s\n", callsign.c_str(), coded, cs1.GetCS().c_str());
}
else
{
printf("ERROR with callsign encoding!\n");
return 1;
}
CCRC crc;
unsigned char string[256];
Loading…
Cancel
Save