Add basic support for Roku HTTP protocol

This commit is contained in:
Tobias Hieta authored and Tobias Hieta committed 2016-02-22 09:01:47 +01:00
1 parent c2842aa430
commit 732498a8d8
8 files changed
+203 -28

No files matched your search

+21
View File
@@ -0,0 +1,21 @@
{
"name": "Roku HTTP input",
"idmatcher": "roku",
"mapping": {
"Up": "up",
"Down": "down",
"Left": "left",
"Right": "right",
"Select": "enter",
"Play": "play_pause",
"Home": "home",
"Back": "back",
"Fwd": "seek_forward",
"Rev": "seek_backward",
"Info": "host:toggleDebug",
"Backspace": "back",
"Enter": "enter",
"Lit_([0-9])": "%1",
"Lit_([A-Za-z])": "jump+%1"
}
}
-2
View File
@@ -13,7 +13,6 @@
#include "system/UpdaterComponent.h"
#include "settings/SettingsComponent.h"
#include "remote/RemoteComponent.h"
#include "remote/RokuRemoteComponent.h"
#include "server/HTTPServer.h"
@@ -70,7 +69,6 @@ void ComponentManager::initialize()
registerComponent(&RemoteComponent::Get());
registerComponent(&PlayerComponent::Get());
registerComponent(&PowerComponent::Get());
registerComponent(&RokuRemoteComponent::Get());
#if KONVERGO_OPENELEC
registerComponent(&OESystemComponent::Get());
+2
View File
@@ -6,6 +6,8 @@ set(INPUT_SRCS
InputKeyboard.h
InputSocket.h
InputSocket.cpp
InputRoku.cpp
InputRoku.h
)
if(APPLE)
+2
View File
@@ -6,6 +6,7 @@
#include "power/PowerComponent.h"
#include "InputKeyboard.h"
#include "InputSocket.h"
#include "InputRoku.h"
#ifdef Q_OS_MAC
#include "apple/InputAppleRemote.h"
@@ -58,6 +59,7 @@ bool InputComponent::componentInitialize()
addInput(&InputKeyboard::Get());
addInput(new InputSocket(this));
addInput(new InputRoku(this));
#ifdef Q_OS_MAC
addInput(new InputAppleRemote(this));
+149
View File
@@ -0,0 +1,149 @@
//
// Created by Tobias Hieta on 02/02/16.
//
#include "InputRoku.h"
#include "QsLog.h"
#include "qhttpserverresponse.hpp"
#include "qhttpserverrequest.hpp"
#include <QUrl>
#include <QXmlStreamWriter>
using namespace qhttp::server;
/////////////////////////////////////////////////////////////////////////////////////////
bool InputRoku::initInput()
{
m_server = new QHttpServer(this);
if (!m_server->listen(QHostAddress::Any, 8060))
{
QLOG_WARN() << "Failed to start roku component on port 8060";
return false;
}
connect(m_server, &QHttpServer::newRequest, this, &InputRoku::handleRequest);
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////
void InputRoku::handleRequest(QHttpRequest* request, QHttpResponse* response)
{
if (request->url().path() == "/query/apps")
{
handleQueryApps(request, response);
}
else if (request->url().path() == "/query/device-info")
{
handleQueryDeviceInfo(request, response);
}
else if (request->url().path().startsWith("/keypress/"))
{
handleKeyPress(request, response);
}
else
{
response->setStatusCode(qhttp::ESTATUS_NOT_FOUND);
response->end();
}
}
/////////////////////////////////////////////////////////////////////////////////////////
void InputRoku::handleQueryApps(QHttpRequest* request, QHttpResponse* response)
{
if (request->method() != qhttp::EHTTP_GET)
{
response->setStatusCode(qhttp::ESTATUS_METHOD_NOT_ALLOWED);
response->end();
return;
}
QByteArray data;
QXmlStreamWriter writer(&data);
writer.setAutoFormatting(true);
writer.writeStartDocument();
writer.writeStartElement("apps");
writer.writeStartElement("app");
writer.writeAttribute("id", "1");
writer.writeCharacters("Plex Media Player");
writer.writeEndElement(); // app
writer.writeEndElement(); // apps
writer.writeEndDocument();
response->setStatusCode(qhttp::ESTATUS_OK);
response->write(data);
response->end();
}
/////////////////////////////////////////////////////////////////////////////////////////
void InputRoku::handleQueryDeviceInfo(QHttpRequest* request, QHttpResponse* response)
{
QByteArray data;
QXmlStreamWriter writer(&data);
writer.setAutoFormatting(true);
writer.writeStartDocument();
writer.writeStartElement("device-info");
writer.writeEndElement(); // device-info
writer.writeEndDocument();
response->setStatusCode(qhttp::ESTATUS_OK);
response->write(data);
response->end();
/*
<device-info>
<udn>015e5108-9000-1046-8035-b0a737964dfb</udn>
<serial-number>1GU48T017973</serial-number>
<device-id>1GU48T017973</device-id>
<vendor-name>Roku</vendor-name>
<model-number>4200X</model-number>
<model-name>Roku 3</model-name>
<wifi-mac>b0:a7:37:96:4d:fb</wifi-mac>
<ethernet-mac>b0:a7:37:96:4d:fa</ethernet-mac>
<network-type>ethernet</network-type>
<user-device-name/>
<software-version>7.00</software-version>
<software-build>09021</software-build>
<secure-device>true</secure-device>
<language>en</language>
<country>US</country>
<locale>en_US</locale>
<time-zone>US/Pacific</time-zone>
<time-zone-offset>-480</time-zone-offset>
<power-mode>PowerOn</power-mode>
<developer-enabled>true</developer-enabled>
<keyed-developer-id>70f6ed9c90cf60718a26f3a7c3e5af1c3ec29558</keyed-developer-id>
<search-enabled>true</search-enabled>
<voice-search-enabled>true</voice-search-enabled>
<notifications-enabled>true</notifications-enabled>
<notifications-first-use>false</notifications-first-use>
<headphones-connected>false</headphones-connected>
</device-info>
*/
}
/////////////////////////////////////////////////////////////////////////////////////////
void InputRoku::handleKeyPress(QHttpRequest* request, QHttpResponse* response)
{
QString path = request->url().path();
QStringList pathsplit = path.split("/");
if (pathsplit.count() != 3)
{
response->setStatusCode(qhttp::ESTATUS_BAD_REQUEST);
response->end();
return;
}
QLOG_DEBUG() << "We got roku input:" << pathsplit.value(2);
emit receivedInput("roku", pathsplit.value(2));
response->setStatusCode(qhttp::ESTATUS_OK);
response->end();
return;
}
+29
View File
@@ -0,0 +1,29 @@
//
// Created by Tobias Hieta on 02/02/16.
//
#ifndef PLEXMEDIAPLAYER_ROKUREMOTECOMPONENT_H
#define PLEXMEDIAPLAYER_ROKUREMOTECOMPONENT_H
#include "input/InputComponent.h"
#include "qhttpserver.hpp"
class InputRoku : public InputBase
{
Q_OBJECT
public:
explicit InputRoku(QObject* parent = 0) : InputBase(parent) { }
virtual bool initInput() override;
virtual const char* inputName() override { return "roku"; };
private:
void handleRequest(qhttp::server::QHttpRequest* request, qhttp::server::QHttpResponse* response);
void handleQueryApps(qhttp::server::QHttpRequest* request, qhttp::server::QHttpResponse* response);
void handleKeyPress(qhttp::server::QHttpRequest* request, qhttp::server::QHttpResponse* response);
void handleQueryDeviceInfo(qhttp::server::QHttpRequest* request, qhttp::server::QHttpResponse* response);
qhttp::server::QHttpServer* m_server;
};
#endif //PLEXMEDIAPLAYER_ROKUREMOTECOMPONENT_H
-5
View File
@@ -1,5 +0,0 @@
//
// Created by Tobias Hieta on 02/02/16.
//
#include "RokuRemoteComponent.h"
-21
View File
@@ -1,21 +0,0 @@
//
// Created by Tobias Hieta on 02/02/16.
//
#ifndef PLEXMEDIAPLAYER_ROKUREMOTECOMPONENT_H
#define PLEXMEDIAPLAYER_ROKUREMOTECOMPONENT_H
#include "ComponentManager.h"
class RokuRemoteComponent : public ComponentBase
{
Q_OBJECT
DEFINE_SINGLETON(RokuRemoteComponent);
public:
virtual bool componentInitialize() override { return true; };
virtual const char* componentName() override { return "rokuremote"; };
virtual bool componentExport() override { return false; };
};
#endif //PLEXMEDIAPLAYER_ROKUREMOTECOMPONENT_H