diff --git a/client/Makefile b/client/Makefile index 779ec5cc..970162ff 100644 --- a/client/Makefile +++ b/client/Makefile @@ -9,6 +9,14 @@ else TARGET_DIR ?= /usr endif +# MIPS +# export STAGING_DIR=/home/johannes/Develop/openwrt/staging_dir +# TOOLCHAIN_DIR=$(STAGING_DIR)/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2 +# LDCFLAGS=$(TOOLCHAIN_DIR)/usr/lib +# LD_LIBRARY_PATH=$(TOOLCHAIN_DIR)/usr/lib +# PATH=$(TOOLCHAIN_DIR)/bin:$PATH +# CXX = $(TOOLCHAIN_DIR)/bin/mips-openwrt-linux-g++ + ifdef ANDROID # Android NDK setup: (http://developer.android.com/ndk/guides/standalone_toolchain.html) # 1. Download NDK: http://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin diff --git a/message/message.h b/message/message.h index d4691732..5ab28aec 100644 --- a/message/message.h +++ b/message/message.h @@ -19,6 +19,7 @@ #ifndef MESSAGE_H #define MESSAGE_H +#include #include #include #include diff --git a/server/Makefile b/server/Makefile index ee496d6b..612049d2 100644 --- a/server/Makefile +++ b/server/Makefile @@ -13,7 +13,7 @@ CXX = /usr/bin/g++ CFLAGS = -std=c++0x -Wall -Wno-unused-function -O3 -pthread -DASIO_STANDALONE -DVERSION=\"$(VERSION)\" -I.. -I../externals/asio/asio/include -I../externals/popl/include LDFLAGS = -lrt -lvorbis -lvorbisenc -logg -lFLAC -lavahi-client -lavahi-common -OBJ = snapServer.o config.o controlServer.o controlSession.o streamServer.o streamSession.o json/jsonrpc.o pcmreader/streamManager.o pcmreader/pcmReader.o pcmreader/pipeReader.o encoder/encoderFactory.o encoder/flacEncoder.o encoder/pcmEncoder.o encoder/oggEncoder.o publishAvahi.o ../common/log.o ../message/pcmChunk.o ../message/sampleFormat.o +OBJ = snapServer.o config.o controlServer.o controlSession.o streamServer.o streamSession.o json/jsonrpc.o pcmreader/readerUri.o pcmreader/streamManager.o pcmreader/pcmReader.o pcmreader/pipeReader.o encoder/encoderFactory.o encoder/flacEncoder.o encoder/pcmEncoder.o encoder/oggEncoder.o publishAvahi.o ../common/log.o ../message/pcmChunk.o ../message/sampleFormat.o BIN = snapserver all: $(TARGET) diff --git a/server/config.h b/server/config.h index ac12e24b..015073e2 100644 --- a/server/config.h +++ b/server/config.h @@ -66,34 +66,6 @@ struct Volume }; -struct Stream -{ -//TODO - Stream() : id("TODO_ID"), name("TODO_NAME"), uri("file:///tmp/snapfifo") - { - } - - void fromJson(const json& j) - { - id = jGet(j, "id", "TODO_ID"); - name = jGet(j, "name", "TODO_NAME"); - uri = jGet(j, "uri", "file:///tmp/snapfifo"); - } - - json toJson() - { - json j; - j["id"] = id; - j["name"] = name; - j["uri"] = uri; - return j; - } - - std::string id; - std::string name; - std::string uri; -}; - struct ClientInfo { diff --git a/server/pcmreader/pcmReader.cpp b/server/pcmreader/pcmReader.cpp index adf069e1..3b1fc155 100644 --- a/server/pcmreader/pcmReader.cpp +++ b/server/pcmreader/pcmReader.cpp @@ -21,75 +21,16 @@ #include #include -#include "pcmReader.h" #include "../encoder/encoderFactory.h" -#include "common/utils.h" -#include "common/compat.h" #include "common/snapException.h" +#include "common/compat.h" +#include "pcmReader.h" #include "common/log.h" using namespace std; -ReaderUri::ReaderUri(const std::string& uri) -{ -// https://en.wikipedia.org/wiki/Uniform_Resource_Identifier -// scheme:[//[user:password@]host[:port]][/]path[?query][#fragment] -// would be more elegant with regex. Not yet supported on my dev machine's gcc 4.8 :( - size_t pos; - this->uri = uri; - string tmp(uri); - - pos = tmp.find(':'); - if (pos == string::npos) - throw invalid_argument("missing ':'"); - scheme = tmp.substr(0, pos); - tmp = tmp.substr(pos + 1); - logE << "scheme: '" << scheme << "' tmp: '" << tmp << "'\n"; - - if (tmp.find("//") != 0) - throw invalid_argument("missing host separator: '//'"); - tmp = tmp.substr(2); - - pos = tmp.find('/'); - if (pos == string::npos) - throw invalid_argument("missing path separator: '/'"); - host = tmp.substr(0, pos); - tmp = tmp.substr(pos); - path = tmp; - logE << "host: '" << host << "' tmp: '" << tmp << "' path: '" << path << "'\n"; - - pos = tmp.find('?'); - if (pos == string::npos) - return; - - path = tmp.substr(0, pos); - tmp = tmp.substr(pos + 1); - string queryStr = tmp; - logE << "path: '" << path << "' tmp: '" << tmp << "' query: '" << queryStr << "'\n"; - - pos = tmp.find('#'); - if (pos != string::npos) - { - queryStr = tmp.substr(0, pos); - tmp = tmp.substr(pos + 1); - fragment = tmp; - logE << "query: '" << queryStr << "' fragment: '" << fragment << "' tmp: '" << tmp << "'\n"; - } - - vector keyValueList = split(queryStr, '&'); - for (auto& kv: keyValueList) - { - pos = kv.find('='); - if (pos != string::npos) - query[kv.substr(0, pos)] = kv.substr(pos+1); - } - -// for (auto& kv: query) -// logD << "key: '" << kv.first << "' value: '" << kv.second << "'\n"; -} - PcmReader::PcmReader(PcmListener* pcmListener, const ReaderUri& uri) : pcmListener_(pcmListener), uri_(uri), pcmReadMs_(20) { diff --git a/server/pcmreader/pcmReader.h b/server/pcmreader/pcmReader.h index 25243c69..d21ba448 100644 --- a/server/pcmreader/pcmReader.h +++ b/server/pcmreader/pcmReader.h @@ -23,6 +23,7 @@ #include #include #include +#include "readerUri.h" #include "../encoder/encoder.h" #include "message/sampleFormat.h" #include "message/header.h" @@ -43,27 +44,6 @@ public: }; -struct ReaderUri -{ - ReaderUri(const std::string& uri); - std::string uri; - std::string scheme; -/* struct Authority - { - std::string username; - std::string password; - std::string host; - size_t port; - }; - Authority authority; -*/ - std::string host; - std::string path; - std::map query; - std::string fragment; -}; - - /// Reads and decodes PCM data /** * Reads PCM and passes the data to an encoder. diff --git a/server/pcmreader/readerUri.cpp b/server/pcmreader/readerUri.cpp new file mode 100644 index 00000000..712c6b00 --- /dev/null +++ b/server/pcmreader/readerUri.cpp @@ -0,0 +1,96 @@ +/*** + This file is part of snapcast + Copyright (C) 2014-2016 Johannes Pohl + + 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +***/ + + +#include +#include +#include +#include "readerUri.h" + + +using namespace std; + + +ReaderUri::ReaderUri(const std::string& uri) +{ +// https://en.wikipedia.org/wiki/Uniform_Resource_Identifier +// scheme:[//[user:password@]host[:port]][/]path[?query][#fragment] +// would be more elegant with regex. Not yet supported on my dev machine's gcc 4.8 :( + size_t pos; + this->uri = uri; + string tmp(uri); + + pos = tmp.find(':'); + if (pos == string::npos) + throw invalid_argument("missing ':'"); + scheme = tmp.substr(0, pos); + tmp = tmp.substr(pos + 1); + logE << "scheme: '" << scheme << "' tmp: '" << tmp << "'\n"; + + if (tmp.find("//") != 0) + throw invalid_argument("missing host separator: '//'"); + tmp = tmp.substr(2); + + pos = tmp.find('/'); + if (pos == string::npos) + throw invalid_argument("missing path separator: '/'"); + host = tmp.substr(0, pos); + tmp = tmp.substr(pos); + path = tmp; + logE << "host: '" << host << "' tmp: '" << tmp << "' path: '" << path << "'\n"; + + pos = tmp.find('?'); + if (pos == string::npos) + return; + + path = tmp.substr(0, pos); + tmp = tmp.substr(pos + 1); + string queryStr = tmp; + logE << "path: '" << path << "' tmp: '" << tmp << "' query: '" << queryStr << "'\n"; + + pos = tmp.find('#'); + if (pos != string::npos) + { + queryStr = tmp.substr(0, pos); + tmp = tmp.substr(pos + 1); + fragment = tmp; + logE << "query: '" << queryStr << "' fragment: '" << fragment << "' tmp: '" << tmp << "'\n"; + } + + vector keyValueList = split(queryStr, '&'); + for (auto& kv: keyValueList) + { + pos = kv.find('='); + if (pos != string::npos) + query[kv.substr(0, pos)] = kv.substr(pos+1); + } +} + + +json ReaderUri::toJson() const +{ + json j; + j["uri"] = uri; + j["scheme"] = scheme; + j["host"] = host; + j["path"] = path; + j["fragment"] = fragment; + j["query"] = json(query); + return j; +} + diff --git a/server/pcmreader/readerUri.h b/server/pcmreader/readerUri.h new file mode 100644 index 00000000..6edf5c58 --- /dev/null +++ b/server/pcmreader/readerUri.h @@ -0,0 +1,52 @@ +/*** + This file is part of snapcast + Copyright (C) 2014-2016 Johannes Pohl + + 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +***/ + +#ifndef READER_URI_H +#define READER_URI_H + +#include +#include +#include "../json/json.hpp" + +using json = nlohmann::json; + + +struct ReaderUri +{ + ReaderUri(const std::string& uri); + std::string uri; + std::string scheme; +/* struct Authority + { + std::string username; + std::string password; + std::string host; + size_t port; + }; + Authority authority; +*/ + std::string host; + std::string path; + std::map query; + std::string fragment; + + json toJson() const; +}; + + +#endif diff --git a/server/pcmreader/streamManager.cpp b/server/pcmreader/streamManager.cpp index 049ce47c..d7dfe558 100644 --- a/server/pcmreader/streamManager.cpp +++ b/server/pcmreader/streamManager.cpp @@ -88,4 +88,12 @@ void StreamManager::stop() } +json StreamManager::toJson() const +{ + json result = json::array(); + for (auto stream: streams_) + result.push_back(stream->getUri().toJson()); + return result; +} + diff --git a/server/pcmreader/streamManager.h b/server/pcmreader/streamManager.h index 6fb7276a..9ac83c67 100644 --- a/server/pcmreader/streamManager.h +++ b/server/pcmreader/streamManager.h @@ -18,6 +18,7 @@ public: void stop(); const std::vector& getStreams(); const PcmReaderPtr getDefaultStream(); + json toJson() const; private: std::vector streams_; diff --git a/server/streamServer.cpp b/server/streamServer.cpp index 215a1e05..19bf67dd 100644 --- a/server/streamServer.cpp +++ b/server/streamServer.cpp @@ -164,7 +164,7 @@ void StreamServer::onMessageReceived(ControlSession* controlSession, const std:: {"version", VERSION} }}, {"clients", jClient}, - {"streams", "TODO"} + {"streams", streamManager_->toJson()} }; } else if (request.method == "Server.DeleteClient") @@ -342,7 +342,7 @@ void StreamServer::start() streamManager_.reset(new StreamManager(this, settings_.sampleFormat, settings_.codec, settings_.streamReadMs)); for (auto& streamUri: settings_.pcmStreams) - streamManager_->addStream(streamUri); + logE << "Stream: " << streamManager_->addStream(streamUri)->getUri().toJson() << "\n"; streamManager_->start();