Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move REST API common code to rest_api.cpp/h #7674

Merged
merged 1 commit into from Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Expand Up @@ -91,6 +91,7 @@ set(PLUGIN_INCLUDE_FILES
resource.h
resourcelinks.h
rest_alarmsystems.h
rest_api.h
rest_devices.h
rest_node_base.h
rule.h
Expand Down Expand Up @@ -187,6 +188,7 @@ add_library(${PROJECT_NAME} SHARED
resource.cpp
resourcelinks.cpp
rest_alarmsystems.cpp
rest_api.cpp
rest_capabilities.cpp
rest_configuration.cpp
rest_devices.cpp
Expand Down
38 changes: 1 addition & 37 deletions de_web_plugin.cpp
Expand Up @@ -51,6 +51,7 @@
#include "rest_devices.h"
#include "rest_alarmsystems.h"
#include "read_files.h"
#include "tuya.h"
#include "utils/utils.h"
#include "xiaomi.h"
#include "zcl/zcl.h"
Expand All @@ -65,23 +66,6 @@

DeRestPluginPrivate *plugin = nullptr;

const char *HttpStatusOk = "200 OK"; // OK
const char *HttpStatusAccepted = "202 Accepted"; // Accepted but not complete
const char *HttpStatusNotModified = "304 Not Modified"; // For ETag / If-None-Match
const char *HttpStatusBadRequest = "400 Bad Request"; // Malformed request
const char *HttpStatusUnauthorized = "401 Unauthorized"; // Unauthorized
const char *HttpStatusForbidden = "403 Forbidden"; // Understand request but no permission
const char *HttpStatusNotFound = "404 Not Found"; // Requested uri not found
const char *HttpStatusServiceUnavailable = "503 Service Unavailable";
const char *HttpStatusNotImplemented = "501 Not Implemented";
const char *HttpContentHtml = "text/html; charset=utf-8";
const char *HttpContentCss = "text/css";
const char *HttpContentJson = "application/json; charset=utf-8";
const char *HttpContentJS = "text/javascript";
const char *HttpContentPNG = "image/png";
const char *HttpContentJPG = "image/jpg";
const char *HttpContentSVG = "image/svg+xml";

static int checkZclAttributesDelay = 750;
static uint MaxGroupTasks = 4;

Expand Down Expand Up @@ -2243,26 +2227,6 @@ bool DeRestPluginPrivate::isInNetwork()
return false;
}

/*! Creates a error map used in JSON response.
\param id - error id
\param ressource example: "/lights/2"
\param description example: "resource, /lights/2, not available"
\return the map
*/
QVariantMap errorToMap(int id, const QString &ressource, const QString &description)
{
QVariantMap map;
QVariantMap error;
error["type"] = (double)id;
error["address"] = ressource.toHtmlEscaped();
error["description"] = description.toHtmlEscaped();
map["error"] = error;

DBG_Printf(DBG_INFO_L2, "API error %d, %s, %s\n", id, qPrintable(ressource), qPrintable(description));

return map;
}

/*! Creates a new unique ETag for a resource.
*/
void DeRestPluginPrivate::updateEtag(QString &etag)
Expand Down
122 changes: 1 addition & 121 deletions de_web_plugin_private.h
Expand Up @@ -18,9 +18,6 @@
#include <stdint.h>
#include <queue>
#include <memory>
#if QT_VERSION < 0x050000
#include <QHttpRequestHeader>
#endif
#include <sqlite3.h>
#include <deconz.h>
#include "device.h"
Expand All @@ -31,19 +28,17 @@
#include "event_emitter.h"
#include "green_power.h"
#include "resource.h"
#include "rest_api.h"
#include "rest_node_base.h"
#include "light_node.h"
#include "group.h"
#include "group_info.h"
#include "ias_zone.h"
#include "scene.h"
#include "sensor.h"
#include "resourcelinks.h"
#include "rule.h"
#include "bindings.h"
#include <math.h>
#include "websocket_server.h"
#include "tuya.h"

// enable domain specific string literals
using namespace deCONZ::literals;
Expand All @@ -53,35 +48,6 @@ using namespace deCONZ::literals;
#define ARCH_ARM
#endif

/*! JSON generic error message codes */
#define ERR_UNAUTHORIZED_USER 1
#define ERR_INVALID_JSON 2
#define ERR_RESOURCE_NOT_AVAILABLE 3
#define ERR_METHOD_NOT_AVAILABLE 4
#define ERR_MISSING_PARAMETER 5
#define ERR_PARAMETER_NOT_AVAILABLE 6
#define ERR_INVALID_VALUE 7
#define ERR_PARAMETER_NOT_MODIFIABLE 8
#define ERR_TOO_MANY_ITEMS 11
#define ERR_DUPLICATE_EXIST 100 // de extension
#define ERR_NOT_ALLOWED_SENSOR_TYPE 501
#define ERR_SENSOR_LIST_FULL 502
#define ERR_RULE_ENGINE_FULL 601
#define ERR_CONDITION_ERROR 607
#define ERR_ACTION_ERROR 608
#define ERR_INTERNAL_ERROR 901

#define ERR_NOT_CONNECTED 950 // de extension
#define ERR_BRIDGE_BUSY 951 // de extension

#define ERR_LINK_BUTTON_NOT_PRESSED 101
#define ERR_DEVICE_OFF 201
#define ERR_DEVICE_NOT_REACHABLE 202
#define ERR_BRIDGE_GROUP_TABLE_FULL 301
#define ERR_DEVICE_GROUP_TABLE_FULL 302

#define ERR_DEVICE_SCENES_TABLE_FULL 402 // de extension

#define IDLE_TIMER_INTERVAL 1000
#define IDLE_LIMIT 30
#define IDLE_READ_LIMIT 120
Expand Down Expand Up @@ -428,10 +394,6 @@ using namespace deCONZ::literals;
#define MAX_RULE_NAME_LENGTH 64
#define MAX_SENSOR_NAME_LENGTH 32

// REST API return codes
#define REQ_READY_SEND 0
#define REQ_NOT_HANDLED -1

// Special application return codes
#define APP_RET_UPDATE 40
#define APP_RET_RESTART_APP 41
Expand Down Expand Up @@ -489,9 +451,6 @@ void getTime(quint32 *time, qint32 *tz, quint32 *dstStart, quint32 *dstEnd, qint
int getFreeSensorId(); // TODO needs to be part of a Database class
int getFreeLightId(); // TODO needs to be part of a Database class

// REST API common
QVariantMap errorToMap(int id, const QString &ressource, const QString &description);

extern const quint64 macPrefixMask;

extern const quint64 celMacPrefix;
Expand Down Expand Up @@ -704,24 +663,6 @@ inline bool checkMacAndVendor(const deCONZ::Node *node, quint16 vendor)
quint8 zclNextSequenceNumber();
const deCONZ::Node *getCoreNode(uint64_t extAddress);

// HTTP status codes
extern const char *HttpStatusOk;
extern const char *HttpStatusAccepted;
extern const char *HttpStatusNotModified;
extern const char *HttpStatusUnauthorized;
extern const char *HttpStatusBadRequest;
extern const char *HttpStatusForbidden;
extern const char *HttpStatusNotFound;
extern const char *HttpStatusNotImplemented;
extern const char *HttpStatusServiceUnavailable;
extern const char *HttpContentHtml;
extern const char *HttpContentCss;
extern const char *HttpContentJson;
extern const char *HttpContentJS;
extern const char *HttpContentPNG;
extern const char *HttpContentJPG;
extern const char *HttpContentSVG;

// Forward declarations
class DeviceDescriptions;
class DeviceWidget;
Expand Down Expand Up @@ -981,67 +922,6 @@ class ApiAuth
QString useragent;
};

enum ApiVersion
{
ApiVersion_1, //!< common version 1.0
ApiVersion_1_DDEL, //!< version 1.0, "Accept: application/vnd.ddel.v1"
ApiVersion_1_1_DDEL, //!< version 1.1, "Accept: application/vnd.ddel.v1.1"
ApiVersion_2_DDEL, //!< version 2.0, "Accept: application/vnd.ddel.v2"
ApiVersion_3_DDEL //!< version 3.0, "Accept: application/vnd.ddel.v3"
};

enum ApiAuthorisation
{
ApiAuthNone,
ApiAuthLocal,
ApiAuthInternal,
ApiAuthFull
};

enum ApiMode
{
ApiModeNormal,
ApiModeStrict,
ApiModeEcho,
ApiModeHue
};

/*! \class ApiRequest

Helper to simplify HTTP REST request handling.
*/
class ApiRequest
{
public:
ApiRequest(const QHttpRequestHeader &h, const QStringList &p, QTcpSocket *s, const QString &c);
QString apikey() const;
ApiVersion apiVersion() const { return version; }

const QHttpRequestHeader &hdr;
const QStringList &path;
QTcpSocket *sock;
QString content;
ApiVersion version;
ApiAuthorisation auth;
ApiMode mode;
};

/*! \class ApiResponse

Helper to simplify HTTP REST request handling.
*/
class ApiResponse
{
public:
QString etag;
const char *httpStatus;
const char *contentType;
QList<QPair<QString, QString> > hdrFields; // extra header fields
QVariantMap map; // json content
QVariantList list; // json content
QString str; // json string
};

/*! \class ApiConfig

Provide config to the resource system.
Expand Down
1 change: 1 addition & 0 deletions electrical_measurement.cpp
@@ -1,3 +1,4 @@
#include <math.h>
#include "de_web_plugin.h"
#include "de_web_plugin_private.h"
#include "device.h"
Expand Down
1 change: 1 addition & 0 deletions hue.cpp
Expand Up @@ -3,6 +3,7 @@
*/

#include <QString>
#include <math.h>
#include "de_web_plugin.h"
#include "de_web_plugin_private.h"

Expand Down
49 changes: 49 additions & 0 deletions rest_api.cpp
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2024 dresden elektronik ingenieurtechnik gmbh.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
* style license a copy of which has been included with this distribution in
* the LICENSE.txt file.
*
*/

#include <deconz/dbg_trace.h>
#include "rest_api.h"

const char *HttpStatusOk = "200 OK"; // OK
const char *HttpStatusAccepted = "202 Accepted"; // Accepted but not complete
const char *HttpStatusNotModified = "304 Not Modified"; // For ETag / If-None-Match
const char *HttpStatusBadRequest = "400 Bad Request"; // Malformed request
const char *HttpStatusUnauthorized = "401 Unauthorized"; // Unauthorized
const char *HttpStatusForbidden = "403 Forbidden"; // Understand request but no permission
const char *HttpStatusNotFound = "404 Not Found"; // Requested uri not found
const char *HttpStatusServiceUnavailable = "503 Service Unavailable";
const char *HttpStatusNotImplemented = "501 Not Implemented";
const char *HttpContentHtml = "text/html; charset=utf-8";
const char *HttpContentCss = "text/css";
const char *HttpContentJson = "application/json; charset=utf-8";
const char *HttpContentJS = "text/javascript";
const char *HttpContentPNG = "image/png";
const char *HttpContentJPG = "image/jpg";
const char *HttpContentSVG = "image/svg+xml";

/*! Creates a error map used in JSON response.
\param id - error id
\param ressource example: "/lights/2"
\param description example: "resource, /lights/2, not available"
\return the map
*/
QVariantMap errorToMap(int id, const QString &ressource, const QString &description)
{
QVariantMap map;
QVariantMap error;
error["type"] = (double)id;
error["address"] = ressource.toHtmlEscaped();
error["description"] = description.toHtmlEscaped();
map["error"] = error;

DBG_Printf(DBG_INFO_L2, "API error %d, %s, %s\n", id, qPrintable(ressource), qPrintable(description));

return map;
}