#12 #9 continue RSMS1A reverse engineering

pull/32/head
Geoffrey Merck 4 years ago
parent 707491d836
commit 30e8be7ea7

@ -45,7 +45,7 @@ bool CGPSACollector::isValidGPSA(const std::string& gpsa)
if(gpsa.length() < 10U || !boost::starts_with(gpsa, "$$CRC"))
return false;
auto csum = CAPRSUtils::calcIcomCRC(gpsa);
auto csum = CAPRSUtils::calcGPSAIcomCRC(gpsa);
auto csumStr = CStringUtils::string_format("%04X", csum);
auto expectedCsum = gpsa.substr(5U, APRS_CSUM_LENGTH);
bool res = ::strcasecmp(csumStr.c_str(), expectedCsum.c_str()) == 0;

@ -0,0 +1,86 @@
/*
* Copyright (C) 2021-2022 by Geoffrey Merck F4FXL / KC3FRA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "RSMS1AMessageBuilder.h"
#include "StringUtils.h"
std::vector<char> CRSMS1AMessageBuilder::m_charsToEscape = {-17, 0, 17, 19, -2, -25, 26, -3, -1, 36, 13, 44};
void CRSMS1AMessageBuilder::buildMessage(std::string& message, const std::string& sender, const std::string& recipient, const std::string body)
{
std::string bodyTmp(body);
auto bodyCrc = calculateBodyCRC(body);
bodyTmp.push_back(bodyCrc);
escapeBody(bodyTmp, std::string(bodyTmp));
std::string header = CStringUtils::string_format("%s,%s,0011", sender.c_str(), recipient.c_str());
char c1, c2;
calcMsgIcomCRC(header, c1, c2);
header.push_back(c1);
header.push_back(c2);
message = "$$Msg," + header + bodyTmp + '\n';
}
char CRSMS1AMessageBuilder::calculateBodyCRC(const std::string& body)
{
if(body.length() == 1)
return body[0];
int num = 0;
for(auto c : body) {
num += c;
}
return (char)((num & 255) /*- 128*/);
}
void CRSMS1AMessageBuilder::escapeBody(std::string output, const std::string& body)
{
output.clear();
for(char c : body) {
if(std::find(m_charsToEscape.begin(), m_charsToEscape.end(), c) != m_charsToEscape.end()) {
output.push_back(-17);
}
output.push_back(c);
}
}
void CRSMS1AMessageBuilder::calcMsgIcomCRC(const std::string& msg, char& c1, char& c2)
{
int num = 0;
for(unsigned int i = 0U; i < msg.length(); i++) {
num += msg[i];
}
c1 = doWhatever((char)((num >> 4) & 15));
c2 = doWhatever((char)(num & 15));
}
char CRSMS1AMessageBuilder::doWhatever(char b2) {
int i;
int i2 = b2 & 255;
if (i2 >= 0 && i2 <= 9) {
i = b2 + 48;
} else if (10 > i2 || i2 > 15) {
return 0;
} else {
i = b2 + 55;
}
return (char) i;
}

@ -0,0 +1,37 @@
/*
* Copyright (C) 2021-2022 by Geoffrey Merck F4FXL / KC3FRA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#pragma once
#include <string>
#include <vector>
class CRSMS1AMessageBuilder
{
public:
static void buildMessage(std::string& message, const std::string& sender, const std::string& recipient, const std::string body);
private:
static void calcMsgIcomCRC(const std::string& msg, char& c1, char& c2);
static void escapeBody(std::string output, const std::string& body);
static void escapeBytes(std::vector<char> output, const std::vector<char> input);
static char calculateBodyCRC(const std::string& body);
static char doWhatever(char b2);
static std::vector<char> m_charsToEscape;
};

@ -57,6 +57,10 @@ bool CRSMS1AMessageCollector::isValidMsg(const std::string& msg)
bool ret = splits.size() >= 4
&& !splits[1].empty()
&& !splits[2].empty();
CUtils::dump("RS-MS1A:", (unsigned char *)msg.c_str(), msg.length() + 1U);
CLog::logDebug("RS-MS1A: %s", msg.c_str());
return ret;
//TODO 2022-01-01 figure out what the heck it is about thic strange CRCs

@ -0,0 +1,61 @@
/*
* Copyright (C) 2021-2022 by Geoffrey Merck F4FXL / KC3FRA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <gtest/gtest.h>
#include "../../RSMS1AMessageBuilder.h"
namespace RSMS1AMessageBuilder
{
class RSMS1AMessageBuilder_buildMessage : public ::testing::Test {
};
TEST_F(RSMS1AMessageBuilder_buildMessage, testABC)
{
std::string message;
CRSMS1AMessageBuilder::buildMessage(message, "KC3FRA", "F4FXL", "ABC");
EXPECT_STREQ(message.c_str(), "$$Msg,KC3FRA,F4FXL,001118ABCF\n");
}
TEST_F(RSMS1AMessageBuilder_buildMessage, testA)
{
std::string message;
CRSMS1AMessageBuilder::buildMessage(message, "KC3FRA", "F4FXL", "A");
EXPECT_STREQ(message.c_str(), "$$Msg,KC3FRA,F4FXL,001118AA\n");
}
TEST_F(RSMS1AMessageBuilder_buildMessage, testAA)
{
std::string message;
CRSMS1AMessageBuilder::buildMessage(message, "KC3FRA", "F4FXL", "AA");
EXPECT_STREQ(message.c_str(), "$$Msg,KC3FRA,F4FXL,001118AA\02\n");
}
TEST_F(RSMS1AMessageBuilder_buildMessage, testSalutCommentVasTu)
{
std::string message;
CRSMS1AMessageBuilder::buildMessage(message, "KC3FRA", "F4FXL", "Salut, comment vas tu?");
EXPECT_STREQ(message.c_str(), "$$Msg,KC3FRA,F4FXL,001118Saluto, comment vas tu?\x7A\n");
}
};
Loading…
Cancel
Save

Powered by TurnKey Linux.