diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d6691393c..ed8fc630d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 @@ -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 diff --git a/de_web_plugin.cpp b/de_web_plugin.cpp index 0b160b65cb..5e56ff58ce 100644 --- a/de_web_plugin.cpp +++ b/de_web_plugin.cpp @@ -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" @@ -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; @@ -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) diff --git a/de_web_plugin_private.h b/de_web_plugin_private.h index 94321e7723..6fc08db59c 100644 --- a/de_web_plugin_private.h +++ b/de_web_plugin_private.h @@ -18,9 +18,6 @@ #include #include #include -#if QT_VERSION < 0x050000 -#include -#endif #include #include #include "device.h" @@ -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 #include "websocket_server.h" -#include "tuya.h" // enable domain specific string literals using namespace deCONZ::literals; @@ -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 @@ -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 @@ -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; @@ -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; @@ -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 > hdrFields; // extra header fields - QVariantMap map; // json content - QVariantList list; // json content - QString str; // json string -}; - /*! \class ApiConfig Provide config to the resource system. diff --git a/electrical_measurement.cpp b/electrical_measurement.cpp index 4acf6e30dd..692952b2c4 100644 --- a/electrical_measurement.cpp +++ b/electrical_measurement.cpp @@ -1,3 +1,4 @@ +#include #include "de_web_plugin.h" #include "de_web_plugin_private.h" #include "device.h" diff --git a/hue.cpp b/hue.cpp index a66f2a1fa3..c33cba56b4 100644 --- a/hue.cpp +++ b/hue.cpp @@ -3,6 +3,7 @@ */ #include +#include #include "de_web_plugin.h" #include "de_web_plugin_private.h" diff --git a/rest_api.cpp b/rest_api.cpp new file mode 100644 index 0000000000..cbb10b20fa --- /dev/null +++ b/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 +#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; +} diff --git a/rest_api.h b/rest_api.h new file mode 100644 index 0000000000..737d02d70e --- /dev/null +++ b/rest_api.h @@ -0,0 +1,136 @@ +/* + * 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. + * + */ + +#ifndef REST_API_H +#define REST_API_H + +#include +#include +#include + +#include +#include + +/*! 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 + +// REST API return codes +#define REQ_READY_SEND 0 +#define REQ_NOT_HANDLED -1 + +// 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; + +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 > hdrFields; // extra header fields + QVariantMap map; // json content + QVariantList list; // json content + QString str; // json string +}; + +// REST API common +QVariantMap errorToMap(int id, const QString &ressource, const QString &description); + +#endif // REST_API_H diff --git a/rest_configuration.cpp b/rest_configuration.cpp index cb8f661eff..eb0d748948 100644 --- a/rest_configuration.cpp +++ b/rest_configuration.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "rest_alarmsystems.h" #include "daylight.h" #include "de_web_plugin.h" diff --git a/rest_lights.cpp b/rest_lights.cpp index 0024044bc6..d08407b120 100644 --- a/rest_lights.cpp +++ b/rest_lights.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include "database.h" #include "de_web_plugin.h" #include "de_web_plugin_private.h" @@ -20,6 +21,7 @@ #include "json.h" #include "colorspace.h" #include "product_match.h" +#include "tuya.h" /*! Lights REST API broker. \param req - request data diff --git a/rest_sensors.cpp b/rest_sensors.cpp index 50d2e4ffbf..d10007dbba 100644 --- a/rest_sensors.cpp +++ b/rest_sensors.cpp @@ -25,6 +25,7 @@ #include "simple_metering.h" #include "thermostat.h" #include "thermostat_ui_configuration.h" +#include "tuya.h" #include "utils/utils.h" /*! In a DDF a sub device can specify valid keyvalue pairs for a ResourceItem.suffix in the meta object. diff --git a/simple_metering.cpp b/simple_metering.cpp index 2baec01ef0..aea9867dc1 100644 --- a/simple_metering.cpp +++ b/simple_metering.cpp @@ -1,3 +1,4 @@ +#include #include "de_web_plugin.h" #include "de_web_plugin_private.h" #include "device_descriptions.h" diff --git a/xiaomi.cpp b/xiaomi.cpp index e24544c314..120aa5c885 100644 --- a/xiaomi.cpp +++ b/xiaomi.cpp @@ -1,3 +1,4 @@ +#include #include "de_web_plugin.h" #include "de_web_plugin_private.h" #include "utils/utils.h" diff --git a/xmas.cpp b/xmas.cpp index 31c9b8775e..ce41353be8 100644 --- a/xmas.cpp +++ b/xmas.cpp @@ -3,6 +3,7 @@ * Handle LIDL Melinera Smart LED lightstrip (for Xmas tree). */ +#include #include "de_web_plugin_private.h" #include "utils/utils.h" diff --git a/zcl_tasks.cpp b/zcl_tasks.cpp index 5463e1412c..00b4a4644e 100644 --- a/zcl_tasks.cpp +++ b/zcl_tasks.cpp @@ -10,6 +10,7 @@ #include #include +#include #include "de_web_plugin.h" #include "de_web_plugin_private.h" #include "colorspace.h"