diff --git a/src/mididevice.cpp b/src/mididevice.cpp index d657103..576821f 100644 --- a/src/mididevice.cpp +++ b/src/mididevice.cpp @@ -715,6 +715,11 @@ void CMIDIDevice::HandleSystemExclusive(const uint8_t* pMessage, const size_t nL //TODO: add code for storing a bank bulk upload LOGNOTE("Currently code for storing a bulk bank upload is missing!"); break; + case 455: + // Parameter 155 + 300 added by Synth_Dexed = 455 + LOGDBG("Operators enabled: %d%d%d%d%d%d", (pMessage[5] & 0x20) ? 1 : 0, (pMessage[5] & 0x10) ? 1 : 0, (pMessage[5] & 0x08) ? 1 : 0, (pMessage[5] & 0x04) ? 1 : 0, (pMessage[5] & 0x02) ? 1 : 0, (pMessage[5] & 0x01) ? 1 : 0); + m_pSynthesizer->setOPMask(pMessage[5], nTG); + break; default: if(sysex_return >= 300 && sysex_return < 500) { diff --git a/src/minidexed.cpp b/src/minidexed.cpp index fd6cdd8..537d15f 100644 --- a/src/minidexed.cpp +++ b/src/minidexed.cpp @@ -1215,6 +1215,7 @@ void CMiniDexed::SetTGParameter (TTGParameter Parameter, int nValue, unsigned nT case TGParameterUnisonSpread: m_nUnisonSpread[nTG] = constrain(nValue, 0, 99); break; + case TGParameterMIDIChannel: SetMIDIChannel(nValue, nTG); break; @@ -2450,7 +2451,7 @@ void CMiniDexed::UpdateNetwork() } if (m_pConfig->GetNetworkFTPEnabled()) { - m_pFTPDaemon = new CFTPDaemon(FTPUSERNAME, FTPPASSWORD); + m_pFTPDaemon = new CFTPDaemon(FTPUSERNAME, FTPPASSWORD, m_pmDNSPublisher, m_pConfig); if (!m_pFTPDaemon->Initialize()) { diff --git a/src/net/applemidi.cpp b/src/net/applemidi.cpp index e14b216..82014e1 100644 --- a/src/net/applemidi.cpp +++ b/src/net/applemidi.cpp @@ -457,7 +457,7 @@ bool ParseMIDIPacket(const u8* pBuffer, size_t nSize, TRTPMIDI* pOutPacket, CApp return ParseMIDICommandSection(pMIDICommandSection, nRemaining, pHandler); } -CAppleMIDIParticipant::CAppleMIDIParticipant(CBcmRandomNumberGenerator* pRandom, CAppleMIDIHandler* pHandler) +CAppleMIDIParticipant::CAppleMIDIParticipant(CBcmRandomNumberGenerator* pRandom, CAppleMIDIHandler* pHandler, const char* pSessionName) : CTask(TASK_STACK_SIZE, true), m_pRandom(pRandom), @@ -489,7 +489,9 @@ CAppleMIDIParticipant::CAppleMIDIParticipant(CBcmRandomNumberGenerator* pRandom, m_nSequence(0), m_nLastFeedbackSequence(0), - m_nLastFeedbackTime(0) + m_nLastFeedbackTime(0), + + m_pSessionName(pSessionName) { } @@ -802,8 +804,11 @@ bool CAppleMIDIParticipant::SendAcceptInvitationPacket(CSocket* pSocket, CIPAddr {'\0'} }; - // TODO: configurable name - strncpy(AcceptPacket.Name, "MiniDexed", sizeof(AcceptPacket.Name)); + // Use hostname as the session name + if (m_pSessionName && m_pSessionName[0]) + strncpy(AcceptPacket.Name, m_pSessionName, sizeof(AcceptPacket.Name)); + else + strncpy(AcceptPacket.Name, "MiniDexed", sizeof(AcceptPacket.Name)); #ifdef APPLEMIDI_DEBUG LOGNOTE("--> Accept invitation"); diff --git a/src/net/applemidi.h b/src/net/applemidi.h index 3df68ae..a774592 100644 --- a/src/net/applemidi.h +++ b/src/net/applemidi.h @@ -39,7 +39,7 @@ public: class CAppleMIDIParticipant : protected CTask { public: - CAppleMIDIParticipant(CBcmRandomNumberGenerator* pRandom, CAppleMIDIHandler* pHandler); + CAppleMIDIParticipant(CBcmRandomNumberGenerator* pRandom, CAppleMIDIHandler* pHandler, const char* pSessionName); virtual ~CAppleMIDIParticipant() override; bool Initialize(); @@ -106,6 +106,8 @@ private: u16 m_nSequence = 0; u16 m_nLastFeedbackSequence = 0; u64 m_nLastFeedbackTime = 0; + + const char* m_pSessionName; }; #endif \ No newline at end of file diff --git a/src/net/ftpdaemon.cpp b/src/net/ftpdaemon.cpp index 0cab51c..015dbc9 100644 --- a/src/net/ftpdaemon.cpp +++ b/src/net/ftpdaemon.cpp @@ -34,11 +34,13 @@ LOGMODULE("ftpd"); constexpr u16 ListenPort = 21; constexpr u8 MaxConnections = 1; -CFTPDaemon::CFTPDaemon(const char* pUser, const char* pPassword) +CFTPDaemon::CFTPDaemon(const char* pUser, const char* pPassword, CmDNSPublisher* pMDNSPublisher, CConfig* pConfig) : CTask(TASK_STACK_SIZE, true), m_pListenSocket(nullptr), m_pUser(pUser), - m_pPassword(pPassword) + m_pPassword(pPassword), + m_pmDNSPublisher(pMDNSPublisher), + m_pConfig(pConfig) { } @@ -106,6 +108,6 @@ void CFTPDaemon::Run() } // Spawn new worker - new CFTPWorker(pConnection, m_pUser, m_pPassword); + new CFTPWorker(pConnection, m_pUser, m_pPassword, m_pmDNSPublisher, m_pConfig); } } \ No newline at end of file diff --git a/src/net/ftpdaemon.h b/src/net/ftpdaemon.h index 4d75762..77afb14 100644 --- a/src/net/ftpdaemon.h +++ b/src/net/ftpdaemon.h @@ -25,11 +25,13 @@ #include #include +#include "mdnspublisher.h" +#include "../config.h" class CFTPDaemon : protected CTask { public: - CFTPDaemon(const char* pUser, const char* pPassword); + CFTPDaemon(const char* pUser, const char* pPassword, CmDNSPublisher* pMDNSPublisher, CConfig* pConfig); virtual ~CFTPDaemon() override; bool Initialize(); @@ -42,6 +44,8 @@ private: const char* m_pUser; const char* m_pPassword; + CmDNSPublisher* m_pmDNSPublisher; + CConfig* m_pConfig; }; #endif \ No newline at end of file diff --git a/src/net/ftpworker.cpp b/src/net/ftpworker.cpp index 28415e2..a19cfde 100644 --- a/src/net/ftpworker.cpp +++ b/src/net/ftpworker.cpp @@ -126,7 +126,7 @@ inline bool DirectoryCaseInsensitiveAscending(const TDirectoryListEntry& EntryA, } -CFTPWorker::CFTPWorker(CSocket* pControlSocket, const char* pExpectedUser, const char* pExpectedPassword) +CFTPWorker::CFTPWorker(CSocket* pControlSocket, const char* pExpectedUser, const char* pExpectedPassword, CmDNSPublisher* pMDNSPublisher, CConfig* pConfig) : CTask(TASK_STACK_SIZE), m_LogName(), m_pExpectedUser(pExpectedUser), @@ -142,7 +142,9 @@ CFTPWorker::CFTPWorker(CSocket* pControlSocket, const char* pExpectedUser, const m_DataType(TDataType::ASCII), m_TransferMode(TTransferMode::Active), m_CurrentPath(), - m_RenameFrom() + m_RenameFrom(), + m_pmDNSPublisher(pMDNSPublisher), + m_pConfig(pConfig) { ++s_nInstanceCount; m_LogName.Format("ftpd[%d]", s_nInstanceCount); @@ -562,7 +564,7 @@ bool CFTPWorker::Passive(const char* pArgs) IPAddress[2], IPAddress[3], (m_nDataSocketPort >> 8) & 0xFF, - m_nDataSocketPort & 0xFF + (m_nDataSocketPort & 0xFF) ); SendStatus(TFTPStatus::EnteringPassiveMode, Buffer); @@ -1058,9 +1060,24 @@ bool CFTPWorker::Bye(const char* pArgs) SendStatus(TFTPStatus::ClosingControl, "Goodbye."); delete m_pControlSocket; m_pControlSocket = nullptr; - + + // Unpublish the mDNS services + if (m_pmDNSPublisher && m_pConfig) + { + m_pmDNSPublisher->UnpublishService(m_pConfig->GetNetworkHostname()); + m_pmDNSPublisher->UnpublishService(m_pConfig->GetNetworkHostname(), CmDNSPublisher::ServiceTypeAppleMIDI, 5004); + m_pmDNSPublisher->UnpublishService(m_pConfig->GetNetworkHostname(), CmDNSPublisher::ServiceTypeFTP, 21); + } + + // Non-blocking 2 second delay before reboot + CTimer* const pTimer = CTimer::Get(); + unsigned int start = pTimer->GetTicks(); + while ((pTimer->GetTicks() - start) < 2 * HZ) { + CScheduler::Get()->Yield(); + } + // Reboot the system if the user disconnects in order to apply any changes made - reboot (); + reboot(); return true; } diff --git a/src/net/ftpworker.h b/src/net/ftpworker.h index 62e60ed..17abfda 100644 --- a/src/net/ftpworker.h +++ b/src/net/ftpworker.h @@ -27,6 +27,8 @@ #include #include #include +#include "../config.h" +#include "mdnspublisher.h" // TODO: These may be incomplete/inaccurate enum TFTPStatus @@ -79,7 +81,7 @@ struct TDirectoryListEntry; class CFTPWorker : protected CTask { public: - CFTPWorker(CSocket* pControlSocket, const char* pExpectedUser, const char* pExpectedPassword); + CFTPWorker(CSocket* pControlSocket, const char* pExpectedUser, const char* pExpectedPassword, CmDNSPublisher* pMDNSPublisher, CConfig* pConfig); virtual ~CFTPWorker() override; virtual void Run() override; @@ -142,6 +144,9 @@ private: CString m_CurrentPath; CString m_RenameFrom; + CmDNSPublisher* m_pmDNSPublisher; + CConfig* m_pConfig; + static void FatFsPathToFTPPath(const char* pInBuffer, char* pOutBuffer, size_t nSize); static void FTPPathToFatFsPath(const char* pInBuffer, char* pOutBuffer, size_t nSize); diff --git a/src/net/mdnspublisher.cpp b/src/net/mdnspublisher.cpp index fbeb549..49ae79b 100644 --- a/src/net/mdnspublisher.cpp +++ b/src/net/mdnspublisher.cpp @@ -131,6 +131,45 @@ boolean CmDNSPublisher::UnpublishService (const char *pServiceName) delete pService; return TRUE; } +boolean CmDNSPublisher::UnpublishService(const char *pServiceName, const char *pServiceType, u16 usServicePort) +{ + if (!m_bRunning) + { + return FALSE; + } + assert(pServiceName); + assert(pServiceType); + m_Mutex.Acquire(); + TService *pService = nullptr; + TPtrListElement *pElement = m_ServiceList.GetFirst(); + while (pElement) + { + pService = static_cast(CPtrList::GetPtr(pElement)); + assert(pService); + if (pService->ServiceName.Compare(pServiceName) == 0 && + pService->ServiceType.Compare(pServiceType) == 0 && + pService->usServicePort == usServicePort) + { + m_ServiceList.Remove(pElement); + break; + } + pService = nullptr; + pElement = m_ServiceList.GetNext(pElement); + } + m_Mutex.Release(); + if (!pService) + { + return FALSE; + } + LOGDBG("Unpublish service %s %s %u", (const char *)pService->ServiceName, (const char *)pService->ServiceType, pService->usServicePort); + SendResponse(pService, FALSE); + for (unsigned i = 0; i < pService->nTextRecords; i++) + { + delete pService->ppText[i]; + } + delete pService; + return TRUE; +} void CmDNSPublisher::Run (void) { assert (m_pNet); diff --git a/src/net/mdnspublisher.h b/src/net/mdnspublisher.h index 6b132a7..c26f6ea 100644 --- a/src/net/mdnspublisher.h +++ b/src/net/mdnspublisher.h @@ -32,6 +32,7 @@ class CmDNSPublisher : public CTask /// mDNS / Bonjour client task { public: static constexpr const char *ServiceTypeAppleMIDI = "_apple-midi._udp"; + static constexpr const char *ServiceTypeFTP = "_ftp._tcp"; public: /// \param pNet Pointer to the network subsystem object CmDNSPublisher (CNetSubSystem *pNet); @@ -50,6 +51,12 @@ public: /// \param pServiceName Name of the service to be unpublished (same as when published) /// \return Operation successful? boolean UnpublishService (const char *pServiceName); + /// \brief Stop publishing a service + /// \param pServiceName Name of the service to be unpublished + /// \param pServiceType Type of the service to be unpublished + /// \param usServicePort Port number of the service to be unpublished + /// \return Operation successful? + boolean UnpublishService (const char *pServiceName, const char *pServiceType, u16 usServicePort); void Run (void) override; private: static const unsigned MaxTextRecords = 10; diff --git a/src/performanceconfig.cpp b/src/performanceconfig.cpp index ee25b21..de561c8 100644 --- a/src/performanceconfig.cpp +++ b/src/performanceconfig.cpp @@ -33,7 +33,6 @@ LOGMODULE ("Performance"); #define PERFORMANCE_DIR "performance" #define DEFAULT_PERFORMANCE_FILENAME "performance.ini" #define DEFAULT_PERFORMANCE_NAME "Default" -#define DEFAULT_PERFORMANCE_BANK_NAME "Default" CPerformanceConfig::CPerformanceConfig (FATFS *pFileSystem) : m_Properties (DEFAULT_PERFORMANCE_FILENAME, pFileSystem) @@ -1182,10 +1181,6 @@ bool CPerformanceConfig::ListPerformanceBanks() } unsigned nNumBanks = 0; - - // Add in the default performance directory as the first bank - m_PerformanceBankName[0] = DEFAULT_PERFORMANCE_BANK_NAME; - nNumBanks = 1; m_nLastPerformanceBank = 0; // List directories with names in format 01_Perf Bank Name @@ -1291,10 +1286,7 @@ std::string CPerformanceConfig::GetPerformanceBankName(unsigned nBankID) { return m_PerformanceBankName[nBankID]; } - else - { - return DEFAULT_PERFORMANCE_BANK_NAME; - } + return ""; } std::string CPerformanceConfig::AddPerformanceBankDirName(unsigned nBankID) @@ -1304,12 +1296,6 @@ std::string CPerformanceConfig::AddPerformanceBankDirName(unsigned nBankID) { // Performance Banks directories in format "001_Bank Name" std::string Index; - if (nBankID == 0) - { - // Legacy: Bank 1 is the default performance directory - return ""; - } - if (nBankID < 9) { Index = "00" + std::to_string(nBankID+1); diff --git a/src/udpmididevice.cpp b/src/udpmididevice.cpp index 4b0d1c7..1934e42 100644 --- a/src/udpmididevice.cpp +++ b/src/udpmididevice.cpp @@ -46,7 +46,7 @@ CUDPMIDIDevice::~CUDPMIDIDevice (void) boolean CUDPMIDIDevice::Initialize (void) { - m_pAppleMIDIParticipant = new CAppleMIDIParticipant(&m_Random, this); + m_pAppleMIDIParticipant = new CAppleMIDIParticipant(&m_Random, this, m_pConfig->GetNetworkHostname()); if (!m_pAppleMIDIParticipant->Initialize()) { LOGERR("Failed to init RTP listener"); diff --git a/submod.sh b/submod.sh index 6ef767a..32408ef 100755 --- a/submod.sh +++ b/submod.sh @@ -23,5 +23,5 @@ cd - # Use fixed master branch of Synth_Dexed cd Synth_Dexed/ git reset --hard -git checkout 65d8383ad5 -f +git checkout 2ad9e43095 -f cd -