diff --git a/Conf.cpp b/Conf.cpp index c92a9e0..06e3cb4 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -87,6 +87,8 @@ m_dmrIdLookupTime(0U), m_nxdnIdLookupFile(), m_nxdnIdLookupTime(0U), m_modemPort(), +m_modemProtocol("uart"), +m_modemAddress(0x22), m_modemRXInvert(false), m_modemTXInvert(false), m_modemPTTInvert(false), @@ -405,6 +407,10 @@ bool CConf::read() } else if (section == SECTION_MODEM) { if (::strcmp(key, "Port") == 0) m_modemPort = value; + else if (::strcmp(key, "Protocol") == 0) + m_modemProtocol = value; + else if (::strcmp(key, "Address") == 0) + m_modemAddress = (unsigned int)::strtoul(value, NULL, 16); else if (::strcmp(key, "RXInvert") == 0) m_modemRXInvert = ::atoi(value) == 1; else if (::strcmp(key, "TXInvert") == 0) @@ -913,6 +919,16 @@ std::string CConf::getModemPort() const return m_modemPort; } +std::string CConf::getModemProtocol() const +{ + return m_modemProtocol; +} + +unsigned int CConf::getModemAddress() const +{ + return m_modemAddress; +} + bool CConf::getModemRXInvert() const { return m_modemRXInvert; diff --git a/Conf.h b/Conf.h index 56130c4..8243cd6 100644 --- a/Conf.h +++ b/Conf.h @@ -70,6 +70,8 @@ public: // The Modem section std::string getModemPort() const; + std::string getModemProtocol() const; + unsigned int getModemAddress() const; bool getModemRXInvert() const; bool getModemTXInvert() const; bool getModemPTTInvert() const; @@ -292,6 +294,8 @@ private: unsigned int m_nxdnIdLookupTime; std::string m_modemPort; + std::string m_modemProtocol; + unsigned int m_modemAddress; bool m_modemRXInvert; bool m_modemTXInvert; bool m_modemPTTInvert; diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index c9868c3..dd17a13 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -235,7 +235,7 @@ int CMMDVMHost::run() return -1; } - // Double check it worked (AKA Paranoia) + // Double check it worked (AKA Paranoia) if (::setuid(0) != -1){ ::fprintf(stderr, "It's possible to regain root - something is wrong!, exiting\n"); return -1; @@ -453,7 +453,7 @@ int CMMDVMHost::run() LogInfo(" Embedded LC Only: %s", embeddedLCOnly ? "yes" : "no"); LogInfo(" Dump Talker Alias Data: %s", dumpTAData ? "yes" : "no"); LogInfo(" Prefixes: %u", prefixes.size()); - + if (blackList.size() > 0U) LogInfo(" Source ID Black List: %u", blackList.size()); if (whiteList.size() > 0U) @@ -1045,6 +1045,8 @@ int CMMDVMHost::run() bool CMMDVMHost::createModem() { std::string port = m_conf.getModemPort(); + std::string protocol = m_conf.getModemProtocol(); + unsigned int address = m_conf.getModemAddress(); bool rxInvert = m_conf.getModemRXInvert(); bool txInvert = m_conf.getModemTXInvert(); bool pttInvert = m_conf.getModemPTTInvert(); @@ -1074,6 +1076,10 @@ bool CMMDVMHost::createModem() LogInfo("Modem Parameters"); LogInfo(" Port: %s", port.c_str()); + if (protocol == "i2c"){ + LogInfo(" Protocol: %s", protocol.c_str()); + LogInfo(" i2c Address: %u", address); + } LogInfo(" RX Invert: %s", rxInvert ? "yes" : "no"); LogInfo(" TX Invert: %s", txInvert ? "yes" : "no"); LogInfo(" PTT Invert: %s", pttInvert ? "yes" : "no"); @@ -1095,7 +1101,7 @@ bool CMMDVMHost::createModem() LogInfo(" RX Frequency: %uHz (%uHz)", rxFrequency, rxFrequency + rxOffset); LogInfo(" TX Frequency: %uHz (%uHz)", txFrequency, txFrequency + txOffset); - m_modem = new CModem(port, m_duplex, rxInvert, txInvert, pttInvert, txDelay, dmrDelay, trace, debug); + m_modem = new CModem(port, protocol, address, m_duplex, rxInvert, txInvert, pttInvert, txDelay, dmrDelay, trace, debug); m_modem->setModeParams(m_dstarEnabled, m_dmrEnabled, m_ysfEnabled, m_p25Enabled, m_nxdnEnabled, m_pocsagEnabled); m_modem->setLevels(rxLevel, cwIdTXLevel, dstarTXLevel, dmrTXLevel, ysfTXLevel, p25TXLevel, nxdnTXLevel, pocsagTXLevel); m_modem->setRFParams(rxFrequency, rxOffset, txFrequency, txOffset, txDCOffset, rxDCOffset, rfLevel, pocsagFrequency); diff --git a/Modem.cpp b/Modem.cpp index ec36877..f356836 100644 --- a/Modem.cpp +++ b/Modem.cpp @@ -92,8 +92,10 @@ const unsigned int MAX_RESPONSES = 30U; const unsigned int BUFFER_LENGTH = 2000U; -CModem::CModem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, unsigned int txDelay, unsigned int dmrDelay, bool trace, bool debug) : +CModem::CModem(const std::string& port, const std::string& protocol, unsigned int address, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, unsigned int txDelay, unsigned int dmrDelay, bool trace, bool debug) : m_port(port), +m_protocol(protocol), +m_address(address), m_dmrColorCode(0U), m_ysfLoDev(false), m_ysfTXHang(4U), @@ -124,7 +126,7 @@ m_nxdnEnabled(false), m_pocsagEnabled(false), m_rxDCOffset(0), m_txDCOffset(0), -m_serial(port, SERIAL_115200, true), +m_serial(port, SERIAL_115200, protocol, address, true), m_buffer(NULL), m_length(0U), m_offset(0U), @@ -510,7 +512,7 @@ void CModem::clock(unsigned int ms) bool dacOverflow = (m_buffer[5U] & 0x20U) == 0x20U; if (dacOverflow) LogError("MMDVM DAC levels have overflowed"); - + m_cd = (m_buffer[5U] & 0x40U) == 0x40U; m_dstarSpace = m_buffer[6U]; @@ -1288,7 +1290,7 @@ bool CModem::setFrequency() { unsigned char buffer[20U]; unsigned char len; - + if (m_hwType == HWT_DVMEGA) len = 12U; else { diff --git a/Modem.h b/Modem.h index b753529..b63f443 100644 --- a/Modem.h +++ b/Modem.h @@ -34,7 +34,7 @@ enum RESP_TYPE_MMDVM { class CModem { public: - CModem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, unsigned int txDelay, unsigned int dmrDelay, bool trace, bool debug); + CModem(const std::string& port, const std::string& protocol, unsigned int address, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, unsigned int txDelay, unsigned int dmrDelay, bool trace, bool debug); ~CModem(); void setRFParams(unsigned int rxFrequency, int rxOffset, unsigned int txFrequency, int txOffset, int txDCOffset, int rxDCOffset, float rfLevel, unsigned int pocsagFrequency); @@ -96,6 +96,8 @@ public: private: std::string m_port; + std::string m_protocol; + unsigned int m_address; unsigned int m_dmrColorCode; bool m_ysfLoDev; unsigned int m_ysfTXHang; diff --git a/SerialController.cpp b/SerialController.cpp index 7856c24..9ddfe39 100644 --- a/SerialController.cpp +++ b/SerialController.cpp @@ -35,12 +35,13 @@ #include #include #include +#include #endif #if defined(_WIN32) || defined(_WIN64) -CSerialController::CSerialController(const std::string& device, SERIAL_SPEED speed, bool assertRTS) : +CSerialController::CSerialController(const std::string& device, SERIAL_SPEED speed, const std::string& protocol, unsigned int address, bool assertRTS) : m_device(device), m_speed(speed), m_assertRTS(assertRTS), @@ -221,9 +222,11 @@ void CSerialController::close() #else -CSerialController::CSerialController(const std::string& device, SERIAL_SPEED speed, bool assertRTS) : +CSerialController::CSerialController(const std::string& device, SERIAL_SPEED speed, const std::string& protocol, unsigned int address, bool assertRTS) : m_device(device), m_speed(speed), +m_protocol(protocol), +m_address(address), m_assertRTS(assertRTS), m_fd(-1) { @@ -237,6 +240,26 @@ CSerialController::~CSerialController() bool CSerialController::open() { assert(m_fd == -1); + + if (m_protocol == "i2c"){ + m_fd = ::open(m_device.c_str(), O_RDWR); + if (m_fd < 0) { + LogError("Cannot open device - %s", m_device.c_str()); + return false; + } + if (::ioctl(m_fd, I2C_TENBIT, 0) < 0) { + LogError("CI2C: failed to set 7bitaddress"); + } + if (::ioctl(m_fd, I2C_SLAVE, m_address) < 0) { + LogError("CI2C: Failed to acquire bus access/talk to slave 0x%u", m_address); + ::close(m_fd); + return false; + } + + LogError("Conntected to Modem via i2c"); + + } else { + #if defined(__APPLE__) m_fd = ::open(m_device.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); /*open in block mode under OSX*/ #else @@ -340,7 +363,7 @@ bool CSerialController::open() } y |= TIOCM_RTS; - + if (::ioctl(m_fd, TIOCMSET, &y) < 0) { LogError("Cannot set the control attributes for %s", m_device.c_str()); ::close(m_fd); @@ -351,6 +374,7 @@ bool CSerialController::open() #if defined(__APPLE__) setNonblock(false); #endif + } return true; } @@ -380,6 +404,19 @@ int CSerialController::read(unsigned char* buffer, unsigned int length) unsigned int offset = 0U; while (offset < length) { + if (m_protocol == "i2c"){ + ssize_t n = ::read(m_fd, buffer + offset, 1U); + if (n < 0) { + if (errno != EAGAIN) { + LogError("Error returned from read(), errno=%d", errno); + return -1; + } + } + + if (n > 0) + offset += n; + } else { + fd_set fds; FD_ZERO(&fds); FD_SET(m_fd, &fds); @@ -412,6 +449,7 @@ int CSerialController::read(unsigned char* buffer, unsigned int length) if (len > 0) offset += len; } + } } return length; @@ -448,8 +486,12 @@ int CSerialController::write(const unsigned char* buffer, unsigned int length) unsigned int ptr = 0U; while (ptr < length) { ssize_t n = 0U; + if (m_protocol == "i2c"){ + n = ::write(m_fd, buffer + ptr, 1U); + } else { if (canWrite()) n = ::write(m_fd, buffer + ptr, length - ptr); + } if (n < 0) { if (errno != EAGAIN) { LogError("Error returned from write(), errno=%d", errno); diff --git a/SerialController.h b/SerialController.h index 63bd8be..8c074da 100644 --- a/SerialController.h +++ b/SerialController.h @@ -42,7 +42,7 @@ enum SERIAL_SPEED { class CSerialController : public ISerialPort { public: - CSerialController(const std::string& device, SERIAL_SPEED speed, bool assertRTS = false); + CSerialController(const std::string& device, SERIAL_SPEED speed, const std::string& protocol = "uart", unsigned int address = 0x22, bool assertRTS = false); virtual ~CSerialController(); virtual bool open(); @@ -60,6 +60,8 @@ public: private: std::string m_device; SERIAL_SPEED m_speed; + std::string m_protocol; + unsigned int m_address; bool m_assertRTS; #if defined(_WIN32) || defined(_WIN64) HANDLE m_handle;