Skip to content

Commit

Permalink
lib: boostrap WebService SSDPP and /location route
Browse files Browse the repository at this point in the history
  • Loading branch information
alanlivio committed Mar 15, 2021
1 parent 3852b7e commit 5b31068
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 5 deletions.
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ else()
add_definitions (-DWITH_CEF=0)
endif()

PKG_CHECK_MODULES(GSSDP gssdp-1.2 REQUIRED)

set (LIBGINGA_SOURCES
./lib/ginga.h
./lib/aux-ginga.cpp
Expand All @@ -148,6 +150,8 @@ set (LIBGINGA_SOURCES
./lib/PlayerSigGen.cpp
./lib/PlayerText.cpp
./lib/PlayerVideo.cpp

./lib/WebServices.cpp

#if WITH_LIBRSVG
./lib/PlayerSvg.cpp
Expand All @@ -172,6 +176,9 @@ set (LIBGINGA_INCLUDE_DIRS
${GSTREAMER_INCLUDE_DIRS}
${GSTREAMER_BASE_INCLUDE_DIRS}

${LIBSOUP_INCLUDE_DIRS}
${GSSDP_INCLUDE_DIRS}

${NCLUA_INCLUDE_DIRS}
${LUA_INCLUDE_DIR}
)
Expand All @@ -194,6 +201,9 @@ set (LIBGINGA_LIBS
${GSTREAMER_APP_LIBRARIES}
${GSTREAMER_VIDEO_LIBRARIES}

${LIBSOUP_LIBRARIES}
${GSSDP_LIBRARIES}

${NCLUA_LIBRARIES}
${LUA_LIBRARIES}
)
Expand Down
9 changes: 9 additions & 0 deletions lib/Formatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ Formatter::getState ()
return _state;
}

bool
Formatter::startWebServices (){
return _webservices->start();
}

bool
Formatter::start (const string &file, string *errmsg)
{
Expand All @@ -129,6 +134,9 @@ Formatter::start (const string &file, string *errmsg)
if (_state != GINGA_STATE_STOPPED)
return false;

if (!_webservices->isStarted())
this->startWebServices();

// Parse document.
g_assert_null (_doc);
w = _opts.width;
Expand Down Expand Up @@ -449,6 +457,7 @@ Formatter::Formatter (const GingaOptions *opts) : Ginga (opts)
= (s = g_getenv ("G_MESSAGES_DEBUG")) ? string (s) : "";

_doc = nullptr;
_webservices = new WebServices(this);
_docPath = "";
_eos = false;

Expand Down
6 changes: 6 additions & 0 deletions lib/Formatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ along with Ginga. If not, see <https://www.gnu.org/licenses/>. */
#include "aux-ginga.h"

#include "Document.h"
#include "WebServices.h"

GINGA_NAMESPACE_BEGIN

Expand All @@ -42,6 +43,7 @@ class Formatter : public Ginga

bool start (const std::string &, std::string *);
bool stop ();
bool startWebServices ();

void resize (int, int);
void redraw (cairo_t *);
Expand All @@ -61,6 +63,7 @@ class Formatter : public Ginga
explicit Formatter (const GingaOptions *);
~Formatter ();

WebServices *getWebService ();
Document *getDocument ();
bool getEOS ();
void setEOS (bool);
Expand Down Expand Up @@ -93,6 +96,9 @@ class Formatter : public Ginga
/// @brief The saved value of environment variable G_MESSAGES_DEBUG.
string _saved_G_MESSAGES_DEBUG;

/// @brief Current WebServices.
WebServices *_webservices;

/// @brief Current document tree.
Document *_doc;

Expand Down
124 changes: 124 additions & 0 deletions lib/WebServices.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#include <WebServices.h>
#include <stdio.h>
#include <Formatter.h>
#include <gio/gio.h>
#include <stdlib.h>

// routes
#define WS_PORT 44642
#define SSDP_UUID "uuid:b16f8e7e-8050-11eb-8036-00155dfe4f40"
#define SSDP_DEVICE "upnp:rootdevice"
#define SSDP_NAME "TeleMidia GingaCCWebServices"
#define SSDP_USN "urn:schemas-sbtvd-org:service:GingaCCWebServices:1"

/**
* @brief Creates a new WebServices.
* @return New #WebServices.
*/
WebServices::WebServices (Formatter *fmt)
{
_formatter = fmt;
_started = false;
}

WebServices::~WebServices ()
{
g_object_unref (_resource_group);
g_object_unref (_client);
}

bool WebServices::isStarted ()
{
return _started;
}

static void
ws_null_callback (SoupServer *server, SoupMessage *msg, const char *path,
GHashTable *query, SoupClientContext *client,
gpointer user_data)
{
soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
soup_message_set_response (msg, "text/plan", SOUP_MEMORY_COPY,
"route not implemented", 0);
}

static void
ws_loc_callback (SoupServer *server, SoupMessage *msg, const char *path,
GHashTable *query, SoupClientContext *client,
gpointer user_data)
{
WebServices *ws;
char *value;

ws = (WebServices *) user_data;
soup_message_set_status (msg, SOUP_STATUS_OK);
soup_message_set_response (msg, "text/plan", SOUP_MEMORY_COPY, NULL, 0);

// Add GingaCC-WS headers
value = g_strdup_printf ("http://%s:%d", ws->_host_addr, WS_PORT);
soup_message_headers_append (msg->response_headers,
"GingaCC-Server-BaseURL", value);

value = g_strdup_printf ("https://%s:%d", ws->_host_addr, WS_PORT);
soup_message_headers_append (msg->response_headers,
"GingaCC-Server-SecureBaseURL", value);
g_free (value);

soup_message_headers_append (
msg->response_headers, "GingaCC-Server-PairingMethods", "qcode,kex");
}

bool
WebServices::start ()
{
GError *error = NULL;
int ret = 0;
char *location;

// create ssdpclient
_client = gssdp_client_new (NULL, &error);
if (error)
{
g_printerr ("Error creating the GSSDP client: %s\n", error->message);
g_error_free (error);
return false;
}
_resource_group = gssdp_resource_group_new (_client);
g_assert (_resource_group);
_host_addr = gssdp_client_get_host_ip (_client);

// ssdp avaliable
location = g_strdup_printf ("http://%s:%d/location", _host_addr, WS_PORT);
gssdp_resource_group_add_resource_simple (_resource_group, SSDP_USN,
SSDP_USN, location);
g_free (location);
gssdp_resource_group_set_available (_resource_group, TRUE);
g_assert (gssdp_resource_group_get_available (_resource_group));

// create server
_ws = soup_server_new (SOUP_SERVER_SERVER_HEADER, SSDP_NAME, nullptr);
g_assert_nonnull (_ws);
// set server to handle both /location and other routes in WS_PORT
ret = soup_server_listen_all (_ws, WS_PORT, SoupServerListenOptions (0),
&error);
if (!ret)
{
g_printerr ("could not start webservices listen: %s\n",
error->message);
goto fail;
}

// add route /location ()
soup_server_add_handler (_ws, "/location", ws_loc_callback, this,
nullptr);

// add route NULL
soup_server_add_handler (_ws, nullptr, ws_null_callback, this, nullptr);

// all done
_started = true;
return true;
fail:
g_error_free (error);
return false;
}
48 changes: 48 additions & 0 deletions lib/WebServices.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* Copyright (C) 2006-2018 PUC-Rio/Laboratorio TeleMidia
This file is part of Ginga (Ginga-NCL).
Ginga 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 2 of the License, or
(at your option) any later version.
Ginga 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 Ginga. If not, see <https://www.gnu.org/licenses/>. */

#ifndef WEBSERVICES_H
#define WEBSERVICES_H

#include "aux-ginga.h"
#include <libgssdp/gssdp.h>
#include <gio/gio.h>
#include <libsoup/soup.h>

GINGA_NAMESPACE_BEGIN
class Formatter;

class WebServices
{
public:
explicit WebServices (Formatter*);
~WebServices ();
bool start ();
bool isStarted ();
const char *_host_addr;

private:
Formatter* _formatter;
bool _started;
GSSDPClient *_client;
SoupServer *_ws;
GSSDPResourceGroup *_resource_group;
};

GINGA_NAMESPACE_END

#endif // WebServices_H
1 change: 1 addition & 0 deletions lib/ginga.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class Ginga
virtual GingaState getState () = 0;
virtual bool start (const std::string &path, std::string *errmsg) = 0;
virtual bool stop () = 0;
virtual bool startWebServices () = 0;

virtual void resize (int width, int height) = 0;
virtual void redraw (cairo_t *cr) = 0;
Expand Down
25 changes: 20 additions & 5 deletions src/ginga.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ PRAGMA_DIAG_IGNORE (-Wunused-macros)
// clang-format on

#include "ginga.h"
#include "aux-ginga.h"
using namespace ::std;

// Global formatter.
Expand All @@ -42,6 +43,7 @@ static Ginga *GINGA = nullptr;
static gboolean opt_debug = FALSE; // toggle debug
static gboolean opt_experimental = FALSE; // toggle experimental stuff
static gboolean opt_fullscreen = FALSE; // toggle fullscreen-mode
static gboolean opt_wsonly = FALSE; // toggle webservices-only-mode
static gboolean opt_opengl = FALSE; // toggle OpenGL backend
static string opt_background = ""; // background color
static gint opt_width = 800; // initial window width
Expand Down Expand Up @@ -99,6 +101,8 @@ static GOptionEntry options[]
"Enable debugging", NULL },
{ "fullscreen", 'f', 0, G_OPTION_ARG_NONE, &opt_fullscreen,
"Enable full-screen mode", NULL },
{ "wsonly", 'w', 0, G_OPTION_ARG_NONE, &opt_wsonly,
"Enable WebServices-only mode that start WS and ignore file arguments", NULL },
{ "opengl", 'g', 0, G_OPTION_ARG_NONE, &opt_opengl,
"Use OpenGL backend", NULL },
{ "size", 's', 0, G_OPTION_ARG_CALLBACK, pointerof (opt_size_cb),
Expand Down Expand Up @@ -141,8 +145,8 @@ static G_GNUC_PRINTF (3, 4) void _error (gboolean try_help, int die,
// Callbacks.

#if GTK_CHECK_VERSION(3, 16, 0)
static gboolean
render_gl_callback (unused (GtkGLArea *area), unused (GdkGLContext *ctx))
static gboolean render_gl_callback (unused (GtkGLArea *area),
unused (GdkGLContext *ctx))
{
GINGA->redraw (nullptr);
return TRUE;
Expand Down Expand Up @@ -339,7 +343,7 @@ main (int argc, char **argv)
_exit (0);
}

if (saved_argc < 2)
if (!opt_wsonly && saved_argc < 2)
{
usage_error ("Missing file operand");
_exit (0);
Expand Down Expand Up @@ -407,9 +411,19 @@ main (int argc, char **argv)
opts.background = string (opt_background);
GINGA = Ginga::create (&opts);
g_assert_nonnull (GINGA);
int fail_count = 0;

// Run only GingaCC-WebServices
if (opt_wsonly && saved_argc < 2)
{
GINGA->startWebServices ();
GMainLoop * main_loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (main_loop);
g_main_loop_unref (main_loop);
goto done;
}

// Run each NCL file, one after another.
int fail_count = 0;
for (int i = 1; i < saved_argc; i++)
{
string errmsg;
Expand All @@ -427,7 +441,8 @@ main (int argc, char **argv)
GINGA->stop ();
}

// Done.
// Done.
done:
delete GINGA;
g_strfreev (saved_argv);

Expand Down

0 comments on commit 5b31068

Please sign in to comment.