// Copyright 2017 Paul Nettle.
//
// This file is part of Gobbledegook.
//
// Gobbledegook 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.
//
// Gobbledegook 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 Gobbledegook. If not, see .
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// >>
// >>> INSIDE THIS FILE
// >>
//
// This is an example single-file stand-alone application that runs a Gobbledegook server.
//
// >>
// >>> DISCUSSION
// >>
//
// Very little is required ("MUST") by a stand-alone application to instantiate a valid Gobbledegook server. There are also some
// things that are reocommended ("SHOULD").
//
// * A stand-alone application MUST:
//
// * Start the server via a call to `ggkStart()`.
//
// Once started the server will run on its own thread.
//
// Two of the parameters to `ggkStart()` are delegates responsible for providing data accessors for the server, a
// `GGKServerDataGetter` delegate and a 'GGKServerDataSetter' delegate. The getter method simply receives a string name (for
// example, "battery/level") and returns a void pointer to that data (for example: `(void *)&batteryLevel`). The setter does
// the same only in reverse.
//
// While the server is running, you will likely need to update the data being served. This is done by calling
// `ggkNofifyUpdatedCharacteristic()` or `ggkNofifyUpdatedDescriptor()` with the full path to the characteristic or delegate
// whose data has been updated. This will trigger your server's `onUpdatedValue()` method, which can perform whatever
// actions are needed such as sending out a change notification (or in BlueZ parlance, a "PropertiesChanged" signal.)
//
// * A stand-alone application SHOULD:
//
// * Shutdown the server before termination
//
// Triggering the server to begin shutting down is done via a call to `ggkTriggerShutdown()`. This is a non-blocking method
// that begins the asynchronous shutdown process.
//
// Before your application terminates, it should wait for the server to be completely stopped. This is done via a call to
// `ggkWait()`. If the server has not yet reached the `EStopped` state when `ggkWait()` is called, it will block until the
// server has done so.
//
// To avoid the blocking behavior of `ggkWait()`, ensure that the server has stopped before calling it. This can be done
// by ensuring `ggkGetServerRunState() == EStopped`. Even if the server has stopped, it is recommended to call `ggkWait()`
// to ensure the server has cleaned up all threads and other internals.
//
// If you want to keep things simple, there is a method `ggkShutdownAndWait()` which will trigger the shutdown and then
// block until the server has stopped.
//
// * Implement signal handling to provide a clean shut-down
//
// This is done by calling `ggkTriggerShutdown()` from any signal received that can terminate your application. For an
// example of this, search for all occurrences of the string "signalHandler" in the code below.
//
// * Register a custom logging mechanism with the server
//
// This is done by calling each of the log registeration methods:
//
// `ggkLogRegisterDebug()`
// `ggkLogRegisterInfo()`
// `ggkLogRegisterStatus()`
// `ggkLogRegisterWarn()`
// `ggkLogRegisterError()`
// `ggkLogRegisterFatal()`
// `ggkLogRegisterAlways()`
// `ggkLogRegisterTrace()`
//
// Each registration method manages a different log level. For a full description of these levels, see the header comment
// in Logger.cpp.
//
// The code below includes a simple logging mechanism that logs to stdout and filters logs based on a few command-line
// options to specify the level of verbosity.
//
// >>
// >>> Building with GOBBLEDEGOOK
// >>
//
// The Gobbledegook distribution includes this file as part of the Gobbledegook files with everything compiling to a single, stand-
// alone binary. It is built this way because Gobbledegook is not intended to be a generic library. You will need to make your
// custom modifications to it. Don't worry, a lot of work went into Gobbledegook to make it almost trivial to customize
// (see Server.cpp).
//
// If it is important to you or your build process that Gobbledegook exist as a library, you are welcome to do so. Just configure
// your build process to build the Gobbledegook files (minus this file) as a library and link against that instead. All that is
// required by applications linking to a Gobbledegook library is to include `include/Gobbledegook.h`.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include
#include
#include
#include
#include