diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index b33f8a8..3f98358 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -77,6 +77,8 @@ static void sigHandler2(int signum) } #endif +static CMMDVMHost* host = NULL; + const char* HEADER1 = "This software is for use on amateur radio networks only,"; const char* HEADER2 = "it is to be used for educational purposes only. Its use on"; const char* HEADER3 = "commercial networks is strictly prohibited."; @@ -112,10 +114,11 @@ int main(int argc, char** argv) do { m_signal = 0; - CMMDVMHost* host = new CMMDVMHost(std::string(iniFile)); + host = new CMMDVMHost(std::string(iniFile)); ret = host->run(); delete host; + host = NULL; switch (m_signal) { case 2: @@ -289,7 +292,11 @@ int CMMDVMHost::run() return 1; } - m_mqtt = new CMQTTConnection(m_conf.getMQTTHost(), m_conf.getMQTTPort(), m_conf.getMQTTName(), m_conf.getMQTTKeepalive()); + std::vector> subscriptions; + subscriptions.push_back(std::make_pair("display", CMMDVMHost::onDisplay)); + subscriptions.push_back(std::make_pair("command", CMMDVMHost::onCommand)); + + m_mqtt = new CMQTTConnection(m_conf.getMQTTHost(), m_conf.getMQTTPort(), m_conf.getMQTTName(), subscriptions, m_conf.getMQTTKeepalive()); ret = m_mqtt->open(); if (!ret) { ::fprintf(stderr, "MMDVMHost: unable to start the MQTT Publisher\n"); @@ -2796,3 +2803,11 @@ void CMMDVMHost::writeJSONMessage(const std::string& message) WriteJSON("MMDVM", json); } +void CMMDVMHost::onCommand(const std::string& command) +{ +} + +void CMMDVMHost::onDisplay(const std::string& message) +{ +} + diff --git a/MMDVMHost.h b/MMDVMHost.h index 3643097..b454314 100644 --- a/MMDVMHost.h +++ b/MMDVMHost.h @@ -49,99 +49,102 @@ class CMMDVMHost { public: - CMMDVMHost(const std::string& confFile); - ~CMMDVMHost(); + CMMDVMHost(const std::string& confFile); + ~CMMDVMHost(); - int run(); + int run(); - void buildNetworkStatusString(std::string &str); - void buildNetworkHostsString(std::string &str); + void buildNetworkStatusString(std::string &str); + void buildNetworkHostsString(std::string &str); private: - CConf m_conf; - CModem* m_modem; - CDStarControl* m_dstar; - CDMRControl* m_dmr; - CYSFControl* m_ysf; - CP25Control* m_p25; - CNXDNControl* m_nxdn; - CM17Control* m_m17; - CPOCSAGControl* m_pocsag; - CFMControl* m_fm; - CAX25Control* m_ax25; - CDStarNetwork* m_dstarNetwork; - CDMRNetwork* m_dmrNetwork; - CYSFNetwork* m_ysfNetwork; - CP25Network* m_p25Network; - INXDNNetwork* m_nxdnNetwork; - CM17Network* m_m17Network; - CPOCSAGNetwork* m_pocsagNetwork; - CFMNetwork* m_fmNetwork; - CAX25Network* m_ax25Network; - unsigned char m_mode; - unsigned int m_dstarRFModeHang; - unsigned int m_dmrRFModeHang; - unsigned int m_ysfRFModeHang; - unsigned int m_p25RFModeHang; - unsigned int m_nxdnRFModeHang; - unsigned int m_m17RFModeHang; - unsigned int m_fmRFModeHang; - unsigned int m_dstarNetModeHang; - unsigned int m_dmrNetModeHang; - unsigned int m_ysfNetModeHang; - unsigned int m_p25NetModeHang; - unsigned int m_nxdnNetModeHang; - unsigned int m_m17NetModeHang; - unsigned int m_pocsagNetModeHang; - unsigned int m_fmNetModeHang; - CTimer m_modeTimer; - CTimer m_dmrTXTimer; - CTimer m_cwIdTimer; - bool m_duplex; - unsigned int m_timeout; - bool m_dstarEnabled; - bool m_dmrEnabled; - bool m_ysfEnabled; - bool m_p25Enabled; - bool m_nxdnEnabled; - bool m_m17Enabled; - bool m_pocsagEnabled; - bool m_fmEnabled; - bool m_ax25Enabled; - unsigned int m_cwIdTime; - CDMRLookup* m_dmrLookup; - CNXDNLookup* m_nxdnLookup; - std::string m_callsign; - unsigned int m_id; - std::string m_cwCallsign; - bool m_lockFileEnabled; - std::string m_lockFileName; - CRemoteControl* m_remoteControl; - bool m_fixedMode; + CConf m_conf; + CModem* m_modem; + CDStarControl* m_dstar; + CDMRControl* m_dmr; + CYSFControl* m_ysf; + CP25Control* m_p25; + CNXDNControl* m_nxdn; + CM17Control* m_m17; + CPOCSAGControl* m_pocsag; + CFMControl* m_fm; + CAX25Control* m_ax25; + CDStarNetwork* m_dstarNetwork; + CDMRNetwork* m_dmrNetwork; + CYSFNetwork* m_ysfNetwork; + CP25Network* m_p25Network; + INXDNNetwork* m_nxdnNetwork; + CM17Network* m_m17Network; + CPOCSAGNetwork* m_pocsagNetwork; + CFMNetwork* m_fmNetwork; + CAX25Network* m_ax25Network; + unsigned char m_mode; + unsigned int m_dstarRFModeHang; + unsigned int m_dmrRFModeHang; + unsigned int m_ysfRFModeHang; + unsigned int m_p25RFModeHang; + unsigned int m_nxdnRFModeHang; + unsigned int m_m17RFModeHang; + unsigned int m_fmRFModeHang; + unsigned int m_dstarNetModeHang; + unsigned int m_dmrNetModeHang; + unsigned int m_ysfNetModeHang; + unsigned int m_p25NetModeHang; + unsigned int m_nxdnNetModeHang; + unsigned int m_m17NetModeHang; + unsigned int m_pocsagNetModeHang; + unsigned int m_fmNetModeHang; + CTimer m_modeTimer; + CTimer m_dmrTXTimer; + CTimer m_cwIdTimer; + bool m_duplex; + unsigned int m_timeout; + bool m_dstarEnabled; + bool m_dmrEnabled; + bool m_ysfEnabled; + bool m_p25Enabled; + bool m_nxdnEnabled; + bool m_m17Enabled; + bool m_pocsagEnabled; + bool m_fmEnabled; + bool m_ax25Enabled; + unsigned int m_cwIdTime; + CDMRLookup* m_dmrLookup; + CNXDNLookup* m_nxdnLookup; + std::string m_callsign; + unsigned int m_id; + std::string m_cwCallsign; + bool m_lockFileEnabled; + std::string m_lockFileName; + CRemoteControl* m_remoteControl; + bool m_fixedMode; - void readParams(); - bool createModem(); - bool createDStarNetwork(); - bool createDMRNetwork(); - bool createYSFNetwork(); - bool createP25Network(); - bool createNXDNNetwork(); - bool createM17Network(); - bool createPOCSAGNetwork(); - bool createFMNetwork(); - bool createAX25Network(); + void readParams(); + bool createModem(); + bool createDStarNetwork(); + bool createDMRNetwork(); + bool createYSFNetwork(); + bool createP25Network(); + bool createNXDNNetwork(); + bool createM17Network(); + bool createPOCSAGNetwork(); + bool createFMNetwork(); + bool createAX25Network(); - void remoteControl(); - void processModeCommand(unsigned char mode, unsigned int timeout); - void processEnableCommand(bool& mode, bool enabled); + void remoteControl(); + void processModeCommand(unsigned char mode, unsigned int timeout); + void processEnableCommand(bool& mode, bool enabled); - void setMode(unsigned char mode); + void setMode(unsigned char mode); - void createLockFile(const char* mode) const; - void removeLockFile() const; + void createLockFile(const char* mode) const; + void removeLockFile() const; - void writeJSONMode(const std::string& mode); - void writeJSONMessage(const std::string& message); + void writeJSONMode(const std::string& mode); + void writeJSONMessage(const std::string& message); + + static void onDisplay(const std::string& message); + static void onCommand(const std::string& command); }; #endif diff --git a/MQTTConnection.cpp b/MQTTConnection.cpp index a149615..69190b8 100644 --- a/MQTTConnection.cpp +++ b/MQTTConnection.cpp @@ -23,10 +23,11 @@ #include -CMQTTConnection::CMQTTConnection(const std::string& host, unsigned short port, const std::string& name, unsigned int keepalive, MQTT_QOS qos) : +CMQTTConnection::CMQTTConnection(const std::string& host, unsigned short port, const std::string& name, const std::vector>& subs, unsigned int keepalive, MQTT_QOS qos) : m_host(host), m_port(port), m_name(name), +m_subs(subs), m_keepalive(keepalive), m_qos(qos), m_mosq(NULL), @@ -54,6 +55,8 @@ bool CMQTTConnection::open() } ::mosquitto_connect_callback_set(m_mosq, onConnect); + ::mosquitto_subscribe_callback_set(m_mosq, onSubscribe); + ::mosquitto_message_callback_set(m_mosq, onMessage); ::mosquitto_disconnect_callback_set(m_mosq, onDisconnect); int rc = ::mosquitto_connect(m_mosq, m_host.c_str(), m_port, m_keepalive); @@ -111,9 +114,57 @@ void CMQTTConnection::onConnect(mosquitto* mosq, void* obj, int rc) assert(obj != NULL); ::fprintf(stdout, "MQTT: on_connect: %s\n", ::mosquitto_connack_string(rc)); + if (rc != 0) { + ::mosquitto_disconnect(mosq); + return; + } CMQTTConnection* p = static_cast(obj); p->m_connected = true; + + for (std::vector>::const_iterator it = p->m_subs.cbegin(); it != p->m_subs.cend(); ++it) { + std::string topic = (*it).first; + + char topicEx[100U]; + ::sprintf(topicEx, "%s/%s", p->m_name.c_str(), topic.c_str()); + + rc = ::mosquitto_subscribe(mosq, NULL, topicEx, MQTT_QOS_AT_LEAST_ONCE); + if (rc != MOSQ_ERR_SUCCESS) { + ::fprintf(stderr, "MQTT: error subscribing to %s - %s\n", topicEx, ::mosquitto_strerror(rc)); + ::mosquitto_disconnect(mosq); + } + } +} + +void CMQTTConnection::onSubscribe(mosquitto* mosq, void* obj, int mid, int qosCount, const int* grantedQOS) +{ + assert(mosq != NULL); + assert(obj != NULL); + assert(grantedQOS != NULL); + + for (int i = 0; i < qosCount; i++) + ::fprintf(stdout, "MQTT: on_subscribe: %d:%d\n", i, grantedQOS[i]); +} + +void CMQTTConnection::onMessage(mosquitto* mosq, void* obj, const mosquitto_message* message) +{ + assert(mosq != NULL); + assert(obj != NULL); + assert(message != NULL); + + CMQTTConnection* p = static_cast(obj); + + for (std::vector>::const_iterator it = p->m_subs.cbegin(); it != p->m_subs.cend(); ++it) { + std::string topic = (*it).first; + + char topicEx[100U]; + ::sprintf(topicEx, "%s/%s", p->m_name.c_str(), topic.c_str()); + + if (::strcmp(topicEx, message->topic) == 0) { + (*it).second(std::string((char*)message->payload, message->payloadlen)); + break; + } + } } void CMQTTConnection::onDisconnect(mosquitto* mosq, void* obj, int rc) diff --git a/MQTTConnection.h b/MQTTConnection.h index 2a0adfe..dedfc76 100644 --- a/MQTTConnection.h +++ b/MQTTConnection.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 by Jonathan Naylor G4KLX + * Copyright (C) 2022,2023 by Jonathan Naylor G4KLX * * 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 @@ -21,6 +21,7 @@ #include +#include #include enum MQTT_QOS { @@ -31,7 +32,7 @@ enum MQTT_QOS { class CMQTTConnection { public: - CMQTTConnection(const std::string& host, unsigned short port, const std::string& name, unsigned int keepalive, MQTT_QOS qos = MQTT_QOS_EXACTLY_ONCE); + CMQTTConnection(const std::string& host, unsigned short port, const std::string& name, const std::vector>& subs, unsigned int keepalive, MQTT_QOS qos = MQTT_QOS_EXACTLY_ONCE); ~CMQTTConnection(); bool open(); @@ -44,12 +45,15 @@ private: std::string m_host; unsigned short m_port; std::string m_name; + std::vector> m_subs; unsigned int m_keepalive; MQTT_QOS m_qos; mosquitto* m_mosq; bool m_connected; static void onConnect(mosquitto* mosq, void* obj, int rc); + static void onSubscribe(mosquitto* mosq, void* obj, int mid, int qosCount, const int* grantedQOS); + static void onMessage(mosquitto* mosq, void* obj, const mosquitto_message* message); static void onDisconnect(mosquitto* mosq, void* obj, int rc); };