Skip to content

Commit

Permalink
Re-arrange Mac Address handling and add MACAddressSource
Browse files Browse the repository at this point in the history
  • Loading branch information
jp-bennett committed Dec 7, 2024
1 parent 5938278 commit 0da54c7
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 24 deletions.
3 changes: 2 additions & 1 deletion bin/config-dist.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,5 @@ General:
MaxNodes: 200
MaxMessageQueue: 100
ConfigDirectory: /etc/meshtasticd/config.d/
# MACAddress: AA:BB:CC:DD:EE:FF
# MACAddress: AA:BB:CC:DD:EE:FF
# MACAddressSource: eth0
112 changes: 90 additions & 22 deletions src/platform/portduino/PortduinoGlue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,27 @@
#include "sleep.h"
#include "target_specific.h"

#include <Utility.h>
#include <assert.h>

#include "PortduinoGlue.h"
#include "api/ServerAPI.h"
#include "linux/gpio/LinuxGPIOPin.h"
#include "meshUtils.h"
#include "yaml-cpp/yaml.h"
#include <Utility.h>
#include <assert.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <map>
#include <sys/ioctl.h>
#include <unistd.h>

std::map<configNames, int> settingsMap;
std::map<configNames, std::string> settingsStrings;
std::ofstream traceFile;
char *configPath = nullptr;
char *optionMac = nullptr;

// FIXME - move setBluetoothEnable into a HALPlatform class
void setBluetoothEnable(bool enable)
Expand Down Expand Up @@ -49,6 +54,10 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
case 'c':
configPath = arg;
break;
case 'h':
optionMac = arg;
break;

case ARGP_KEY_ARG:
return 0;
default:
Expand All @@ -61,6 +70,7 @@ void portduinoCustomInit()
{
static struct argp_option options[] = {{"port", 'p', "PORT", 0, "The TCP port to use."},
{"config", 'c', "CONFIG_PATH", 0, "Full path of the .yaml config file to use."},
{"hwid", 'h', "HWID", 0, "The mac address to assign to this virtual machine"},
{0}};
static void *childArguments;
static char doc[] = "Meshtastic native build.";
Expand All @@ -72,17 +82,46 @@ void portduinoCustomInit()

void getMacAddr(uint8_t *dmac)
{
if (settingsStrings[mac_address].length() > 11) {
dmac[0] = std::stoi(settingsStrings[mac_address].substr(0, 2), nullptr, 16);
dmac[1] = std::stoi(settingsStrings[mac_address].substr(2, 2), nullptr, 16);
dmac[2] = std::stoi(settingsStrings[mac_address].substr(4, 2), nullptr, 16);
dmac[3] = std::stoi(settingsStrings[mac_address].substr(6, 2), nullptr, 16);
dmac[4] = std::stoi(settingsStrings[mac_address].substr(8, 2), nullptr, 16);
dmac[5] = std::stoi(settingsStrings[mac_address].substr(10, 2), nullptr, 16);
// We should store this value, and short-circuit all this if it's already been set.
if (optionMac != nullptr && strlen(optionMac) > 0) {
if (strlen(optionMac) >= 12) {
MAC_from_string(optionMac, dmac);
std::cout << optionMac << std::endl;
} else {
uint32_t hwId = sscanf(optionMac, "%u", &hwId);
dmac[0] = 0x80;
dmac[1] = 0;
dmac[2] = hwId >> 24;
dmac[3] = hwId >> 16;
dmac[4] = hwId >> 8;
dmac[5] = hwId & 0xff;
}
} else if (settingsStrings[mac_address].length() > 11) {
MAC_from_string(settingsStrings[mac_address], dmac);
std::cout << settingsStrings[mac_address] << std::endl;
exit;
} else {
_getMacAddr(dmac);

struct hci_dev_info di;
di.dev_id = 0;
bdaddr_t bdaddr;
char addr[18];
int btsock;
btsock = socket(AF_BLUETOOTH, SOCK_RAW, 1);
if (btsock < 0) { // If anything fails, just return with the default value
return;
}

if (ioctl(btsock, HCIGETDEVINFO, (void *)&di)) {
return;
}

dmac[0] = di.bdaddr.b[5];
dmac[1] = di.bdaddr.b[4];
dmac[2] = di.bdaddr.b[3];
dmac[3] = di.bdaddr.b[2];
dmac[4] = di.bdaddr.b[1];
dmac[5] = di.bdaddr.b[0];
}
}

Expand Down Expand Up @@ -166,11 +205,12 @@ void portduinoSetup()

uint8_t dmac[6];
getMacAddr(dmac);
if (dmac[0] == 128 && dmac[1] == 0 && dmac[2] == 0 && dmac[3] == 0 && dmac[4] == 0 && dmac[5] == 1) {
std::cout << "*** Blank MAC Address not allowed! " << std::endl;
if (dmac[0] == 0 && dmac[1] == 0 && dmac[2] == 0 && dmac[3] == 0 && dmac[4] == 0 && dmac[5] == 0) {
std::cout << "*** Blank MAC Address not allowed!" << std::endl;
std::cout << "Please set a MAC Address in config.yaml using either MACAddress or MACAddressSource." << std::endl;
exit(EXIT_FAILURE);
}

printBytes("MAC Address: ", dmac, 6);
// Rather important to set this, if not running simulated.
randomSeed(time(NULL));

Expand Down Expand Up @@ -443,15 +483,27 @@ bool loadConfig(const char *configPath)
settingsStrings[webserverrootpath] = (yamlConfig["Webserver"]["RootPath"]).as<std::string>("");
}

settingsMap[maxnodes] = (yamlConfig["General"]["MaxNodes"]).as<int>(200);
settingsMap[maxtophone] = (yamlConfig["General"]["MaxMessageQueue"]).as<int>(100);
settingsStrings[config_directory] = (yamlConfig["General"]["ConfigDirectory"]).as<std::string>("");
settingsStrings[mac_address] = (yamlConfig["General"]["MACAddress"]).as<std::string>("");
if (yamlConfig["General"]) {
settingsMap[maxnodes] = (yamlConfig["General"]["MaxNodes"]).as<int>(200);
settingsMap[maxtophone] = (yamlConfig["General"]["MaxMessageQueue"]).as<int>(100);
settingsStrings[config_directory] = (yamlConfig["General"]["ConfigDirectory"]).as<std::string>("");
if ((yamlConfig["General"]["MACAddress"]).as<std::string>("") != "" &&
(yamlConfig["General"]["MACAddressSource"]).as<std::string>("") != "") {
std::cout << "Cannot set both MACAddress and MACAddressSource!" << std::endl;
exit(EXIT_FAILURE);
}
settingsStrings[mac_address] = (yamlConfig["General"]["MACAddress"]).as<std::string>("");
if ((yamlConfig["General"]["MACAddressSource"]).as<std::string>("") != "") {
std::ifstream infile("/sys/class/net/" + (yamlConfig["General"]["MACAddressSource"]).as<std::string>("") +
"/address");
std::getline(infile, settingsStrings[mac_address]);
}

// https://stackoverflow.com/a/20326454
settingsStrings[mac_address].erase(
std::remove(settingsStrings[mac_address].begin(), settingsStrings[mac_address].end(), ':'),
settingsStrings[mac_address].end());
// https://stackoverflow.com/a/20326454
settingsStrings[mac_address].erase(
std::remove(settingsStrings[mac_address].begin(), settingsStrings[mac_address].end(), ':'),
settingsStrings[mac_address].end());
}
} catch (YAML::Exception &e) {
std::cout << "*** Exception " << e.what() << std::endl;
return false;
Expand All @@ -463,4 +515,20 @@ bool loadConfig(const char *configPath)
static bool ends_with(std::string_view str, std::string_view suffix)
{
return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
}

bool MAC_from_string(std::string mac_str, uint8_t *dmac)
{
mac_str.erase(std::remove(mac_str.begin(), mac_str.end(), ':'), mac_str.end());
if (mac_str.length() == 12) {
dmac[0] = std::stoi(settingsStrings[mac_address].substr(0, 2), nullptr, 16);
dmac[1] = std::stoi(settingsStrings[mac_address].substr(2, 2), nullptr, 16);
dmac[2] = std::stoi(settingsStrings[mac_address].substr(4, 2), nullptr, 16);
dmac[3] = std::stoi(settingsStrings[mac_address].substr(6, 2), nullptr, 16);
dmac[4] = std::stoi(settingsStrings[mac_address].substr(8, 2), nullptr, 16);
dmac[5] = std::stoi(settingsStrings[mac_address].substr(10, 2), nullptr, 16);
return true;
} else {
return false;
}
}
3 changes: 2 additions & 1 deletion src/platform/portduino/PortduinoGlue.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,5 @@ extern std::ofstream traceFile;
int initGPIOPin(int pinNum, std::string gpioChipname);
bool loadConfig(const char *configPath);
static bool ends_with(std::string_view str, std::string_view suffix);
void getMacAddr(uint8_t *dmac);
void getMacAddr(uint8_t *dmac);
bool MAC_from_string(std::string mac_str, uint8_t *dmac);

0 comments on commit 0da54c7

Please sign in to comment.