#ifndef MERCURY_MANAGER_H #define MERCURY_MANAGER_H #include #include #include #include #include #include "ShannonConnection.h" #include "MercuryResponse.h" #include "Packet.h" #include "Utils.h" #include "MercuryManager.h" #include "AudioChunk.h" #include "AudioChunkManager.h" #include #include "BellTask.h" #include "platform/WrappedSemaphore.h" #include "TimeProvider.h" #include "Session.h" #include #include "protobuf/mercury.pb.h" #include #include #define AUDIOCHUNK_TIMEOUT_MS 5 * 1000 #define RECONNECTION_RETRY_MS 5 * 1000 #define PING_TIMEOUT_MS 2 * 60 * 1000 + 5000 typedef std::function)> mercuryCallback; typedef std::function)> audioKeyCallback; typedef std::function voidCallback; #define AUDIO_CHUNK_SIZE 0x20000 enum class MercuryType : uint8_t { SUB = 0xb3, UNSUB = 0xb4, SUBRES = 0xb5, SEND = 0xb2, GET = 0xFF, // Shitty workaround, it's value is actually same as SEND PING = 0x04, PONG_ACK = 0x4a, AUDIO_CHUNK_REQUEST_COMMAND = 0x08, AUDIO_CHUNK_SUCCESS_RESPONSE = 0x09, AUDIO_CHUNK_FAILURE_RESPONSE = 0x0A, AUDIO_KEY_REQUEST_COMMAND = 0x0C, AUDIO_KEY_SUCCESS_RESPONSE = 0x0D, AUDIO_KEY_FAILURE_RESPONSE = 0x0E, COUNTRY_CODE_RESPONSE = 0x1B, }; extern std::map MercuryTypeMap; class MercuryManager : public bell::Task { private: Header tempMercuryHeader; std::map callbacks; std::mutex reconnectionMutex; std::mutex runningMutex; std::mutex stopMutex; std::map subscriptions; std::unique_ptr session; std::shared_ptr lastAuthBlob; std::unique_ptr audioChunkManager; std::vector> queue; std::unique_ptr queueSemaphore; unsigned long long lastRequestTimestamp = -1; unsigned long long lastPingTimestamp = -1; uint64_t sequenceId; uint32_t audioKeySequence; audioKeyCallback keyCallback; void runTask(); public: MercuryManager(std::unique_ptr session); ~MercuryManager(); std::atomic isRunning = false; voidCallback reconnectedCallback; uint16_t audioChunkSequence; std::shared_ptr timeProvider; char countryCode[2]; bool timeoutHandler(); uint64_t execute(MercuryType method, std::string uri, mercuryCallback &callback, mercuryCallback &subscription, mercuryParts &payload); uint64_t execute(MercuryType method, std::string uri, mercuryCallback &callback, mercuryCallback &subscription); uint64_t execute(MercuryType method, std::string uri, mercuryCallback &callback, mercuryParts &payload); uint64_t execute(MercuryType method, std::string uri, mercuryCallback &callback); void updateQueue(); void stop(); void handleQueue(); void requestAudioKey(std::vector trackId, std::vector fileId, audioKeyCallback &audioCallback); std::shared_ptr fetchAudioChunk(std::vector fileId, std::vector &audioKey, uint16_t index); std::shared_ptr fetchAudioChunk(std::vector fileId, std::vector &audioKey, uint32_t startPos, uint32_t endPos); void unregisterAudioCallback(uint16_t seqId); void unregisterMercuryCallback(uint64_t seqId); void freeAudioKeyCallback(); void reconnect(); }; #endif