Commit 2780404a7309841b24fdff2ec8cab74c321f2f0d
1 parent
d218d9d3
Fix entertainment mode support
- Add mbedtls as submodule - Add bin folder to gitignore
Showing
12 changed files
with
159 additions
and
104 deletions
.gitignore
| @@ -31,6 +31,7 @@ | @@ -31,6 +31,7 @@ | ||
| 31 | # build directory | 31 | # build directory |
| 32 | /build* | 32 | /build* |
| 33 | /out | 33 | /out |
| 34 | +/bin | ||
| 34 | 35 | ||
| 35 | # Generated documentation | 36 | # Generated documentation |
| 36 | /doc/html | 37 | /doc/html |
| @@ -44,7 +45,6 @@ | @@ -44,7 +45,6 @@ | ||
| 44 | # Icon must end with two \r | 45 | # Icon must end with two \r |
| 45 | Icon | 46 | Icon |
| 46 | 47 | ||
| 47 | - | ||
| 48 | # Thumbnails | 48 | # Thumbnails |
| 49 | ._* | 49 | ._* |
| 50 | 50 |
.gitmodules
0 → 100644
CMakeLists.txt
| @@ -69,6 +69,8 @@ if (1 AND APPLE) | @@ -69,6 +69,8 @@ if (1 AND APPLE) | ||
| 69 | set(CMAKE_MACOSX_RPATH 1) | 69 | set(CMAKE_MACOSX_RPATH 1) |
| 70 | endif() | 70 | endif() |
| 71 | 71 | ||
| 72 | +add_subdirectory("lib/mbedtls") | ||
| 73 | + | ||
| 72 | add_subdirectory(src) | 74 | add_subdirectory(src) |
| 73 | 75 | ||
| 74 | # if the user decided to use tests add the subdirectory | 76 | # if the user decided to use tests add the subdirectory |
include/hueplusplus/Bridge.h
| @@ -101,6 +101,7 @@ public: | @@ -101,6 +101,7 @@ public: | ||
| 101 | 101 | ||
| 102 | //! \brief Function that adds a client key to the clientkeys map | 102 | //! \brief Function that adds a client key to the clientkeys map |
| 103 | //! | 103 | //! |
| 104 | + //! The client key is only needed for entertainment mode, otherwise it is optional. | ||
| 104 | //! \param mac MAC address of Hue bridge | 105 | //! \param mac MAC address of Hue bridge |
| 105 | //! \param clientkey Client key that is used to control the Hue bridge in entertainment mode | 106 | //! \param clientkey Client key that is used to control the Hue bridge in entertainment mode |
| 106 | void AddClientKey(const std::string& mac, const std::string& clientkey); | 107 | void AddClientKey(const std::string& mac, const std::string& clientkey); |
include/hueplusplus/EntertainmentMode.h
| @@ -25,49 +25,61 @@ | @@ -25,49 +25,61 @@ | ||
| 25 | #include "Bridge.h" | 25 | #include "Bridge.h" |
| 26 | #include "Group.h" | 26 | #include "Group.h" |
| 27 | 27 | ||
| 28 | -#include "mbedtls/ssl.h" | ||
| 29 | -#include "mbedtls/net_sockets.h" | ||
| 30 | -#include "mbedtls/entropy.h" | ||
| 31 | -#include "mbedtls/ctr_drbg.h" | ||
| 32 | -#include "mbedtls/error.h" | ||
| 33 | -#include "mbedtls/certs.h" | ||
| 34 | -#include "mbedtls/debug.h" | ||
| 35 | -#include "mbedtls/timing.h" | ||
| 36 | - | ||
| 37 | -#define HUE_ENTERTAINMENT_HEADER_SIZE 16 | ||
| 38 | -#define HUE_ENTERTAINMENT_LIGHT_SIZE 9 | ||
| 39 | - | ||
| 40 | namespace hueplusplus | 28 | namespace hueplusplus |
| 41 | { | 29 | { |
| 30 | +struct TLSContext; | ||
| 31 | + | ||
| 42 | //! \brief Class for Hue Entertainment Mode | 32 | //! \brief Class for Hue Entertainment Mode |
| 43 | //! | 33 | //! |
| 44 | //! Provides methods to initialize and control Entertainment groups. | 34 | //! Provides methods to initialize and control Entertainment groups. |
| 45 | class EntertainmentMode | 35 | class EntertainmentMode |
| 46 | { | 36 | { |
| 47 | public: | 37 | public: |
| 48 | - EntertainmentMode(Bridge& bridge, Group& group); | 38 | + //! @brief Constructor |
| 39 | + //! | ||
| 40 | + //! @param b Bridge reference | ||
| 41 | + //! @param g Group to control in entertainment mode reference | ||
| 42 | + EntertainmentMode(Bridge& b, Group& g); | ||
| 43 | + | ||
| 44 | + //! @brief Destroy the Entertainment Mode object | ||
| 45 | + ~EntertainmentMode(); | ||
| 49 | 46 | ||
| 47 | + //! @brief Connect and start streaming | ||
| 48 | + //! | ||
| 49 | + //! @return true If conected and ready to receive commands | ||
| 50 | + //! @return false If an error occured | ||
| 50 | bool Connect(); | 51 | bool Connect(); |
| 52 | + | ||
| 53 | + //! @brief Disconnect and stop streaming | ||
| 54 | + //! | ||
| 55 | + //! @return true If disconnected successfully | ||
| 56 | + //! @return false If an error occurred | ||
| 51 | bool Disconnect(); | 57 | bool Disconnect(); |
| 52 | - | 58 | + |
| 59 | + //! @brief Set the color of the given light in RGB format | ||
| 60 | + //! | ||
| 61 | + //! @param light_index Light index inside the group | ||
| 62 | + //! @param red Red color value (0-255) | ||
| 63 | + //! @param green Green color value (0-255) | ||
| 64 | + //! @param blue Blue color value (0-255) | ||
| 65 | + //! @return true If light_index was valid | ||
| 66 | + //! @return false If light_index was invalid | ||
| 53 | bool SetColorRGB(uint8_t light_index, uint8_t red, uint8_t green, uint8_t blue); | 67 | bool SetColorRGB(uint8_t light_index, uint8_t red, uint8_t green, uint8_t blue); |
| 54 | 68 | ||
| 55 | - void Update(); | 69 | + //! @brief Update all set colors by @ref SetColorRGB |
| 70 | + //! | ||
| 71 | + //! @return true If all color values for all lights have ben written/sent | ||
| 72 | + //! @return false If there was an error while writing | ||
| 73 | + bool Update(); | ||
| 56 | 74 | ||
| 57 | protected: | 75 | protected: |
| 58 | - Bridge& bridge; | ||
| 59 | - Group& group; | 76 | + Bridge* bridge; //!< Associated bridge |
| 77 | + Group* group; //!< Associated group | ||
| 60 | 78 | ||
| 61 | std::vector<uint8_t> entertainment_msg; //!< buffer containing the entertainment mode packet data | 79 | std::vector<uint8_t> entertainment_msg; //!< buffer containing the entertainment mode packet data |
| 62 | uint8_t entertainment_num_lights; //!< number of lights in entertainment mode group | 80 | uint8_t entertainment_num_lights; //!< number of lights in entertainment mode group |
| 63 | 81 | ||
| 64 | - mbedtls_ssl_context ssl; | ||
| 65 | - mbedtls_net_context server_fd; | ||
| 66 | - mbedtls_entropy_context entropy; | ||
| 67 | - mbedtls_ctr_drbg_context ctr_drbg; | ||
| 68 | - mbedtls_ssl_config conf; | ||
| 69 | - mbedtls_x509_crt cacert; | ||
| 70 | - mbedtls_timing_delay_context timer; | 82 | + std::unique_ptr<TLSContext> tls_context; //!< tls context |
| 71 | }; | 83 | }; |
| 72 | } // namespace hueplusplus | 84 | } // namespace hueplusplus |
| 73 | 85 |
include/hueplusplus/LinHttpHandler.h
| @@ -44,7 +44,7 @@ public: | @@ -44,7 +44,7 @@ public: | ||
| 44 | //! decimal notation like "192.168.2.1" \param port Optional integer that | 44 | //! decimal notation like "192.168.2.1" \param port Optional integer that |
| 45 | //! specifies the port to which the request is sent to. Default is 80 \return | 45 | //! specifies the port to which the request is sent to. Default is 80 \return |
| 46 | //! String containing the response of the host | 46 | //! String containing the response of the host |
| 47 | - virtual std::string send(const std::string& msg, const std::string& adr, int port = 80) const; | 47 | + virtual std::string send(const std::string& msg, const std::string& adr, int port = 80) const override; |
| 48 | 48 | ||
| 49 | //! \brief Function that sends a multicast request with the specified message. | 49 | //! \brief Function that sends a multicast request with the specified message. |
| 50 | //! | 50 | //! |
| 1 | +Subproject commit fc86f3f147890a65ffa9b21eef6be96ce35371c5 |
src/Bridge.cpp
| @@ -250,6 +250,11 @@ std::string Bridge::requestUsername() | @@ -250,6 +250,11 @@ std::string Bridge::requestUsername() | ||
| 250 | 250 | ||
| 251 | bool Bridge::StartStreaming(std::string group_identifier) | 251 | bool Bridge::StartStreaming(std::string group_identifier) |
| 252 | { | 252 | { |
| 253 | + if (clientkey.empty()) | ||
| 254 | + { | ||
| 255 | + throw HueException(CURRENT_FILE_INFO, "Cannot stream without client key!"); | ||
| 256 | + } | ||
| 257 | + | ||
| 253 | nlohmann::json request; | 258 | nlohmann::json request; |
| 254 | 259 | ||
| 255 | request["stream"]["active"] = true; | 260 | request["stream"]["active"] = true; |
| @@ -260,20 +265,10 @@ bool Bridge::StartStreaming(std::string group_identifier) | @@ -260,20 +265,10 @@ bool Bridge::StartStreaming(std::string group_identifier) | ||
| 260 | 265 | ||
| 261 | answer = http_handler->PUTJson(uri, request, ip, port); | 266 | answer = http_handler->PUTJson(uri, request, ip, port); |
| 262 | 267 | ||
| 263 | - if(answer[0].contains("success")) | ||
| 264 | - { | ||
| 265 | - std::string key = "/groups/" + group_identifier + "/stream/active"; | 268 | + std::string key = "/groups/" + group_identifier + "/stream/active"; |
| 269 | + nlohmann::json success = utils::safeGetMember(answer, 0, "success", key); | ||
| 266 | 270 | ||
| 267 | - if(answer[0]["success"].contains(key)) | ||
| 268 | - { | ||
| 269 | - if(answer[0]["success"][key] == true) | ||
| 270 | - { | ||
| 271 | - return true; | ||
| 272 | - } | ||
| 273 | - } | ||
| 274 | - } | ||
| 275 | - | ||
| 276 | - return false; | 271 | + return success == true; |
| 277 | } | 272 | } |
| 278 | 273 | ||
| 279 | bool Bridge::StopStreaming(std::string group_identifier) | 274 | bool Bridge::StopStreaming(std::string group_identifier) |
| @@ -288,13 +283,13 @@ bool Bridge::StopStreaming(std::string group_identifier) | @@ -288,13 +283,13 @@ bool Bridge::StopStreaming(std::string group_identifier) | ||
| 288 | 283 | ||
| 289 | answer = http_handler->PUTJson(uri, request, ip, port); | 284 | answer = http_handler->PUTJson(uri, request, ip, port); |
| 290 | 285 | ||
| 291 | - if(answer[0].contains("success")) | 286 | + if (answer[0].contains("success")) |
| 292 | { | 287 | { |
| 293 | std::string key = "/groups/" + group_identifier + "/stream/active"; | 288 | std::string key = "/groups/" + group_identifier + "/stream/active"; |
| 294 | 289 | ||
| 295 | - if(answer[0]["success"].contains(key)) | 290 | + if (answer[0]["success"].contains(key)) |
| 296 | { | 291 | { |
| 297 | - if(answer[0]["success"][key] == false) | 292 | + if (answer[0]["success"][key] == false) |
| 298 | { | 293 | { |
| 299 | return true; | 294 | return true; |
| 300 | } | 295 | } |
src/CMakeLists.txt
| @@ -7,6 +7,7 @@ set(hueplusplus_SOURCES | @@ -7,6 +7,7 @@ set(hueplusplus_SOURCES | ||
| 7 | BridgeConfig.cpp | 7 | BridgeConfig.cpp |
| 8 | CLIPSensors.cpp | 8 | CLIPSensors.cpp |
| 9 | ColorUnits.cpp | 9 | ColorUnits.cpp |
| 10 | + EntertainmentMode.cpp | ||
| 10 | ExtendedColorHueStrategy.cpp | 11 | ExtendedColorHueStrategy.cpp |
| 11 | ExtendedColorTemperatureStrategy.cpp | 12 | ExtendedColorTemperatureStrategy.cpp |
| 12 | Group.cpp | 13 | Group.cpp |
| @@ -58,12 +59,14 @@ set(hueplusplus_SOURCES ${_srcList} PARENT_SCOPE) | @@ -58,12 +59,14 @@ set(hueplusplus_SOURCES ${_srcList} PARENT_SCOPE) | ||
| 58 | 59 | ||
| 59 | # hueplusplus shared library | 60 | # hueplusplus shared library |
| 60 | add_library(hueplusplusshared SHARED ${hueplusplus_SOURCES}) | 61 | add_library(hueplusplusshared SHARED ${hueplusplus_SOURCES}) |
| 62 | +target_link_libraries(hueplusplusshared PRIVATE mbedtls) | ||
| 61 | target_compile_features(hueplusplusshared PUBLIC cxx_std_14) | 63 | target_compile_features(hueplusplusshared PUBLIC cxx_std_14) |
| 62 | target_include_directories(hueplusplusshared PUBLIC $<BUILD_INTERFACE:${hueplusplus_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>) | 64 | target_include_directories(hueplusplusshared PUBLIC $<BUILD_INTERFACE:${hueplusplus_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>) |
| 63 | install(TARGETS hueplusplusshared DESTINATION lib) | 65 | install(TARGETS hueplusplusshared DESTINATION lib) |
| 64 | 66 | ||
| 65 | # hueplusplus static library | 67 | # hueplusplus static library |
| 66 | add_library(hueplusplusstatic STATIC ${hueplusplus_SOURCES}) | 68 | add_library(hueplusplusstatic STATIC ${hueplusplus_SOURCES}) |
| 69 | +target_link_libraries(hueplusplusstatic PRIVATE mbedtls) | ||
| 67 | target_compile_features(hueplusplusstatic PUBLIC cxx_std_14) | 70 | target_compile_features(hueplusplusstatic PUBLIC cxx_std_14) |
| 68 | install(TARGETS hueplusplusstatic DESTINATION lib) | 71 | install(TARGETS hueplusplusstatic DESTINATION lib) |
| 69 | target_include_directories(hueplusplusstatic PUBLIC $<BUILD_INTERFACE:${hueplusplus_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>) | 72 | target_include_directories(hueplusplusstatic PUBLIC $<BUILD_INTERFACE:${hueplusplus_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>) |
src/EntertainmentMode.cpp
| @@ -20,6 +20,30 @@ | @@ -20,6 +20,30 @@ | ||
| 20 | **/ | 20 | **/ |
| 21 | 21 | ||
| 22 | #include "hueplusplus/EntertainmentMode.h" | 22 | #include "hueplusplus/EntertainmentMode.h" |
| 23 | +#include "mbedtls/certs.h" | ||
| 24 | +#include "mbedtls/ctr_drbg.h" | ||
| 25 | +#include "mbedtls/debug.h" | ||
| 26 | +#include "mbedtls/entropy.h" | ||
| 27 | +#include "mbedtls/error.h" | ||
| 28 | +#include "mbedtls/net_sockets.h" | ||
| 29 | +#include "mbedtls/ssl.h" | ||
| 30 | +#include "mbedtls/timing.h" | ||
| 31 | + | ||
| 32 | +namespace hueplusplus | ||
| 33 | +{ | ||
| 34 | +constexpr uint8_t HUE_ENTERTAINMENT_HEADER_SIZE = 16; | ||
| 35 | +constexpr uint8_t HUE_ENTERTAINMENT_LIGHT_SIZE = 9; | ||
| 36 | + | ||
| 37 | +struct TLSContext | ||
| 38 | +{ | ||
| 39 | + mbedtls_ssl_context ssl; | ||
| 40 | + mbedtls_net_context server_fd; | ||
| 41 | + mbedtls_entropy_context entropy; | ||
| 42 | + mbedtls_ctr_drbg_context ctr_drbg; | ||
| 43 | + mbedtls_ssl_config conf; | ||
| 44 | + mbedtls_x509_crt cacert; | ||
| 45 | + mbedtls_timing_delay_context timer; | ||
| 46 | +}; | ||
| 23 | 47 | ||
| 24 | std::vector<char> HexToBytes(const std::string& hex) | 48 | std::vector<char> HexToBytes(const std::string& hex) |
| 25 | { | 49 | { |
| @@ -28,26 +52,25 @@ std::vector<char> HexToBytes(const std::string& hex) | @@ -28,26 +52,25 @@ std::vector<char> HexToBytes(const std::string& hex) | ||
| 28 | for (unsigned int i = 0; i < hex.length(); i += 2) | 52 | for (unsigned int i = 0; i < hex.length(); i += 2) |
| 29 | { | 53 | { |
| 30 | std::string byteString = hex.substr(i, 2); | 54 | std::string byteString = hex.substr(i, 2); |
| 31 | - char byte = (char) strtol(byteString.c_str(), NULL, 16); | 55 | + char byte = (char)strtol(byteString.c_str(), NULL, 16); |
| 32 | bytes.push_back(byte); | 56 | bytes.push_back(byte); |
| 33 | } | 57 | } |
| 34 | 58 | ||
| 35 | return bytes; | 59 | return bytes; |
| 36 | } | 60 | } |
| 37 | 61 | ||
| 38 | -namespace hueplusplus | ||
| 39 | -{ | ||
| 40 | -EntertainmentMode::EntertainmentMode(Bridge& bridge, Group& group):bridge(bridge),group(group) | 62 | +EntertainmentMode::EntertainmentMode(Bridge& b, Group& g) |
| 63 | + : bridge(&b), group(&g), tls_context(std::make_unique<TLSContext>(TLSContext {})) | ||
| 41 | { | 64 | { |
| 42 | /*-------------------------------------------------*\ | 65 | /*-------------------------------------------------*\ |
| 43 | | Signal the bridge to start streaming | | 66 | | Signal the bridge to start streaming | |
| 44 | \*-------------------------------------------------*/ | 67 | \*-------------------------------------------------*/ |
| 45 | - bridge.StartStreaming(std::to_string(group.getId())); | 68 | + bridge->StartStreaming(std::to_string(group->getId())); |
| 46 | 69 | ||
| 47 | /*-------------------------------------------------*\ | 70 | /*-------------------------------------------------*\ |
| 48 | | Get the number of lights from the group | | 71 | | Get the number of lights from the group | |
| 49 | \*-------------------------------------------------*/ | 72 | \*-------------------------------------------------*/ |
| 50 | - entertainment_num_lights = group.getLightIds().size(); | 73 | + entertainment_num_lights = group->getLightIds().size(); |
| 51 | 74 | ||
| 52 | /*-------------------------------------------------*\ | 75 | /*-------------------------------------------------*\ |
| 53 | | Resize Entertainment Mode message buffer | | 76 | | Resize Entertainment Mode message buffer | |
| @@ -74,8 +97,8 @@ EntertainmentMode::EntertainmentMode(Bridge& bridge, Group& group):bridge(bridge | @@ -74,8 +97,8 @@ EntertainmentMode::EntertainmentMode(Bridge& bridge, Group& group):bridge(bridge | ||
| 74 | unsigned int msg_idx = HUE_ENTERTAINMENT_HEADER_SIZE + (light_idx * HUE_ENTERTAINMENT_LIGHT_SIZE); | 97 | unsigned int msg_idx = HUE_ENTERTAINMENT_HEADER_SIZE + (light_idx * HUE_ENTERTAINMENT_LIGHT_SIZE); |
| 75 | 98 | ||
| 76 | entertainment_msg[msg_idx + 0] = 0x00; // Type (Light) | 99 | entertainment_msg[msg_idx + 0] = 0x00; // Type (Light) |
| 77 | - entertainment_msg[msg_idx + 1] = group.getLightIds()[light_idx] >> 8; // ID MSB | ||
| 78 | - entertainment_msg[msg_idx + 2] = group.getLightIds()[light_idx] & 0xFF; // ID LSB | 100 | + entertainment_msg[msg_idx + 1] = group->getLightIds()[light_idx] >> 8; // ID MSB |
| 101 | + entertainment_msg[msg_idx + 2] = group->getLightIds()[light_idx] & 0xFF; // ID LSB | ||
| 79 | entertainment_msg[msg_idx + 3] = 0x00; // Red MSB | 102 | entertainment_msg[msg_idx + 3] = 0x00; // Red MSB |
| 80 | entertainment_msg[msg_idx + 4] = 0x00; // Red LSB; | 103 | entertainment_msg[msg_idx + 4] = 0x00; // Red LSB; |
| 81 | entertainment_msg[msg_idx + 5] = 0x00; // Green MSB; | 104 | entertainment_msg[msg_idx + 5] = 0x00; // Green MSB; |
| @@ -87,22 +110,33 @@ EntertainmentMode::EntertainmentMode(Bridge& bridge, Group& group):bridge(bridge | @@ -87,22 +110,33 @@ EntertainmentMode::EntertainmentMode(Bridge& bridge, Group& group):bridge(bridge | ||
| 87 | /*-------------------------------------------------*\ | 110 | /*-------------------------------------------------*\ |
| 88 | | Initialize mbedtls contexts | | 111 | | Initialize mbedtls contexts | |
| 89 | \*-------------------------------------------------*/ | 112 | \*-------------------------------------------------*/ |
| 90 | - mbedtls_net_init(&server_fd); | ||
| 91 | - mbedtls_ssl_init(&ssl); | ||
| 92 | - mbedtls_ssl_config_init(&conf); | ||
| 93 | - mbedtls_x509_crt_init(&cacert); | ||
| 94 | - mbedtls_ctr_drbg_init(&ctr_drbg); | ||
| 95 | - mbedtls_entropy_init(&entropy); | 113 | + mbedtls_net_init(&tls_context->server_fd); |
| 114 | + mbedtls_ssl_init(&tls_context->ssl); | ||
| 115 | + mbedtls_ssl_config_init(&tls_context->conf); | ||
| 116 | + mbedtls_x509_crt_init(&tls_context->cacert); | ||
| 117 | + mbedtls_ctr_drbg_init(&tls_context->ctr_drbg); | ||
| 118 | + mbedtls_entropy_init(&tls_context->entropy); | ||
| 96 | 119 | ||
| 97 | /*-------------------------------------------------*\ | 120 | /*-------------------------------------------------*\ |
| 98 | | Seed the Deterministic Random Bit Generator (RNG) | | 121 | | Seed the Deterministic Random Bit Generator (RNG) | |
| 99 | \*-------------------------------------------------*/ | 122 | \*-------------------------------------------------*/ |
| 100 | - int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0); | 123 | + int ret = mbedtls_ctr_drbg_seed(&tls_context->ctr_drbg, mbedtls_entropy_func, &tls_context->entropy, NULL, 0); |
| 101 | 124 | ||
| 102 | /*-------------------------------------------------*\ | 125 | /*-------------------------------------------------*\ |
| 103 | | Parse certificate | | 126 | | Parse certificate | |
| 104 | \*-------------------------------------------------*/ | 127 | \*-------------------------------------------------*/ |
| 105 | - ret = mbedtls_x509_crt_parse(&cacert, (const unsigned char*)mbedtls_test_cas_pem, mbedtls_test_cas_pem_len); | 128 | + ret = mbedtls_x509_crt_parse( |
| 129 | + &tls_context->cacert, (const unsigned char*)mbedtls_test_cas_pem, mbedtls_test_cas_pem_len); | ||
| 130 | +} | ||
| 131 | + | ||
| 132 | +EntertainmentMode::~EntertainmentMode() | ||
| 133 | +{ | ||
| 134 | + mbedtls_entropy_free(&tls_context->entropy); | ||
| 135 | + mbedtls_ctr_drbg_free(&tls_context->ctr_drbg); | ||
| 136 | + mbedtls_x509_crt_free(&tls_context->cacert); | ||
| 137 | + mbedtls_ssl_config_free(&tls_context->conf); | ||
| 138 | + mbedtls_ssl_free(&tls_context->ssl); | ||
| 139 | + mbedtls_net_free(&tls_context->server_fd); | ||
| 106 | } | 140 | } |
| 107 | 141 | ||
| 108 | bool EntertainmentMode::Connect() | 142 | bool EntertainmentMode::Connect() |
| @@ -111,20 +145,21 @@ bool EntertainmentMode::Connect() | @@ -111,20 +145,21 @@ bool EntertainmentMode::Connect() | ||
| 111 | | Signal the bridge to start streaming | | 145 | | Signal the bridge to start streaming | |
| 112 | | If successful, connect to the UDP port | | 146 | | If successful, connect to the UDP port | |
| 113 | \*-------------------------------------------------*/ | 147 | \*-------------------------------------------------*/ |
| 114 | - if(bridge.StartStreaming(std::to_string(group.getId()))) | 148 | + if (bridge->StartStreaming(std::to_string(group->getId()))) |
| 115 | { | 149 | { |
| 116 | /*-------------------------------------------------*\ | 150 | /*-------------------------------------------------*\ |
| 117 | | Connect to the Hue bridge UDP server | | 151 | | Connect to the Hue bridge UDP server | |
| 118 | \*-------------------------------------------------*/ | 152 | \*-------------------------------------------------*/ |
| 119 | - int ret = mbedtls_net_connect(&server_fd, bridge.getBridgeIP().c_str(), "2100", MBEDTLS_NET_PROTO_UDP); | 153 | + int ret = mbedtls_net_connect( |
| 154 | + &tls_context->server_fd, bridge->getBridgeIP().c_str(), "2100", MBEDTLS_NET_PROTO_UDP); | ||
| 120 | 155 | ||
| 121 | /*-------------------------------------------------*\ | 156 | /*-------------------------------------------------*\ |
| 122 | | If connecting failed, close and return false | | 157 | | If connecting failed, close and return false | |
| 123 | \*-------------------------------------------------*/ | 158 | \*-------------------------------------------------*/ |
| 124 | - if(ret != 0) | 159 | + if (ret != 0) |
| 125 | { | 160 | { |
| 126 | - mbedtls_ssl_close_notify(&ssl); | ||
| 127 | - bridge.StopStreaming(std::to_string(group.getId())); | 161 | + mbedtls_ssl_close_notify(&tls_context->ssl); |
| 162 | + bridge->StopStreaming(std::to_string(group->getId())); | ||
| 128 | return false; | 163 | return false; |
| 129 | } | 164 | } |
| 130 | 165 | ||
| @@ -132,90 +167,92 @@ bool EntertainmentMode::Connect() | @@ -132,90 +167,92 @@ bool EntertainmentMode::Connect() | ||
| 132 | | Configure defaults | | 167 | | Configure defaults | |
| 133 | \*-------------------------------------------------*/ | 168 | \*-------------------------------------------------*/ |
| 134 | ret = mbedtls_ssl_config_defaults( | 169 | ret = mbedtls_ssl_config_defaults( |
| 135 | - &conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT); | 170 | + &tls_context->conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT); |
| 136 | 171 | ||
| 137 | /*-------------------------------------------------*\ | 172 | /*-------------------------------------------------*\ |
| 138 | | If configuring failed, close and return false | | 173 | | If configuring failed, close and return false | |
| 139 | \*-------------------------------------------------*/ | 174 | \*-------------------------------------------------*/ |
| 140 | - if(ret != 0) | 175 | + if (ret != 0) |
| 141 | { | 176 | { |
| 142 | - mbedtls_ssl_close_notify(&ssl); | ||
| 143 | - bridge.StopStreaming(std::to_string(group.getId())); | 177 | + mbedtls_ssl_close_notify(&tls_context->ssl); |
| 178 | + bridge->StopStreaming(std::to_string(group->getId())); | ||
| 144 | return false; | 179 | return false; |
| 145 | } | 180 | } |
| 146 | 181 | ||
| 147 | - mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL); | ||
| 148 | - mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL); | ||
| 149 | - mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); | 182 | + mbedtls_ssl_conf_authmode(&tls_context->conf, MBEDTLS_SSL_VERIFY_OPTIONAL); |
| 183 | + mbedtls_ssl_conf_ca_chain(&tls_context->conf, &tls_context->cacert, NULL); | ||
| 184 | + mbedtls_ssl_conf_rng(&tls_context->conf, mbedtls_ctr_drbg_random, &tls_context->ctr_drbg); | ||
| 150 | 185 | ||
| 151 | /*-------------------------------------------------*\ | 186 | /*-------------------------------------------------*\ |
| 152 | | Convert client key to binary array | | 187 | | Convert client key to binary array | |
| 153 | \*-------------------------------------------------*/ | 188 | \*-------------------------------------------------*/ |
| 154 | - std::vector<char> psk_binary = HexToBytes(bridge.getClientKey()); | 189 | + std::vector<char> psk_binary = HexToBytes(bridge->getClientKey()); |
| 155 | 190 | ||
| 156 | /*-------------------------------------------------*\ | 191 | /*-------------------------------------------------*\ |
| 157 | | Configure SSL pre-shared key and identity | | 192 | | Configure SSL pre-shared key and identity | |
| 158 | | PSK - binary array from client key | | 193 | | PSK - binary array from client key | |
| 159 | | Identity - username (ASCII) | | 194 | | Identity - username (ASCII) | |
| 160 | \*-------------------------------------------------*/ | 195 | \*-------------------------------------------------*/ |
| 161 | - ret = mbedtls_ssl_conf_psk(&conf, (const unsigned char*)&psk_binary[0], psk_binary.size(), | ||
| 162 | - (const unsigned char*)bridge.getUsername().c_str(), bridge.getUsername().length()); | 196 | + ret = mbedtls_ssl_conf_psk(&tls_context->conf, (const unsigned char*)&psk_binary[0], psk_binary.size(), |
| 197 | + (const unsigned char*)bridge->getUsername().c_str(), bridge->getUsername().length()); | ||
| 163 | 198 | ||
| 164 | /*-------------------------------------------------*\ | 199 | /*-------------------------------------------------*\ |
| 165 | | If configuring failed, close and return false | | 200 | | If configuring failed, close and return false | |
| 166 | \*-------------------------------------------------*/ | 201 | \*-------------------------------------------------*/ |
| 167 | - if(ret != 0) | 202 | + if (ret != 0) |
| 168 | { | 203 | { |
| 169 | - mbedtls_ssl_close_notify(&ssl); | ||
| 170 | - bridge.StopStreaming(std::to_string(group.getId())); | 204 | + mbedtls_ssl_close_notify(&tls_context->ssl); |
| 205 | + bridge->StopStreaming(std::to_string(group->getId())); | ||
| 171 | return false; | 206 | return false; |
| 172 | } | 207 | } |
| 173 | 208 | ||
| 174 | /*-------------------------------------------------*\ | 209 | /*-------------------------------------------------*\ |
| 175 | | Set up the SSL | | 210 | | Set up the SSL | |
| 176 | \*-------------------------------------------------*/ | 211 | \*-------------------------------------------------*/ |
| 177 | - ret = mbedtls_ssl_setup(&ssl, &conf); | 212 | + ret = mbedtls_ssl_setup(&tls_context->ssl, &tls_context->conf); |
| 178 | 213 | ||
| 179 | /*-------------------------------------------------*\ | 214 | /*-------------------------------------------------*\ |
| 180 | | If setup failed, close and return false | | 215 | | If setup failed, close and return false | |
| 181 | \*-------------------------------------------------*/ | 216 | \*-------------------------------------------------*/ |
| 182 | - if(ret != 0) | 217 | + if (ret != 0) |
| 183 | { | 218 | { |
| 184 | - mbedtls_ssl_close_notify(&ssl); | ||
| 185 | - bridge.StopStreaming(std::to_string(group.getId())); | 219 | + mbedtls_ssl_close_notify(&tls_context->ssl); |
| 220 | + bridge->StopStreaming(std::to_string(group->getId())); | ||
| 186 | return false; | 221 | return false; |
| 187 | } | 222 | } |
| 188 | 223 | ||
| 189 | - ret = mbedtls_ssl_set_hostname(&ssl, "localhost"); | 224 | + ret = mbedtls_ssl_set_hostname(&tls_context->ssl, "localhost"); |
| 190 | 225 | ||
| 191 | /*-------------------------------------------------*\ | 226 | /*-------------------------------------------------*\ |
| 192 | | If set hostname failed, close and return false | | 227 | | If set hostname failed, close and return false | |
| 193 | \*-------------------------------------------------*/ | 228 | \*-------------------------------------------------*/ |
| 194 | - if(ret != 0) | 229 | + if (ret != 0) |
| 195 | { | 230 | { |
| 196 | - mbedtls_ssl_close_notify(&ssl); | ||
| 197 | - bridge.StopStreaming(std::to_string(group.getId())); | 231 | + mbedtls_ssl_close_notify(&tls_context->ssl); |
| 232 | + bridge->StopStreaming(std::to_string(group->getId())); | ||
| 198 | return false; | 233 | return false; |
| 199 | } | 234 | } |
| 200 | 235 | ||
| 201 | - mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout); | ||
| 202 | - mbedtls_ssl_set_timer_cb(&ssl, &timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay); | 236 | + mbedtls_ssl_set_bio( |
| 237 | + &tls_context->ssl, &tls_context->server_fd, mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout); | ||
| 238 | + mbedtls_ssl_set_timer_cb( | ||
| 239 | + &tls_context->ssl, &tls_context->timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay); | ||
| 203 | 240 | ||
| 204 | /*-------------------------------------------------*\ | 241 | /*-------------------------------------------------*\ |
| 205 | | Handshake | | 242 | | Handshake | |
| 206 | \*-------------------------------------------------*/ | 243 | \*-------------------------------------------------*/ |
| 207 | do | 244 | do |
| 208 | { | 245 | { |
| 209 | - ret = mbedtls_ssl_handshake(&ssl); | 246 | + ret = mbedtls_ssl_handshake(&tls_context->ssl); |
| 210 | } while (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE); | 247 | } while (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE); |
| 211 | 248 | ||
| 212 | /*-------------------------------------------------*\ | 249 | /*-------------------------------------------------*\ |
| 213 | | If set hostname failed, close and return false | | 250 | | If set hostname failed, close and return false | |
| 214 | \*-------------------------------------------------*/ | 251 | \*-------------------------------------------------*/ |
| 215 | - if(ret != 0) | 252 | + if (ret != 0) |
| 216 | { | 253 | { |
| 217 | - mbedtls_ssl_close_notify(&ssl); | ||
| 218 | - bridge.StopStreaming(std::to_string(group.getId())); | 254 | + mbedtls_ssl_close_notify(&tls_context->ssl); |
| 255 | + bridge->StopStreaming(std::to_string(group->getId())); | ||
| 219 | return false; | 256 | return false; |
| 220 | } | 257 | } |
| 221 | 258 | ||
| @@ -229,13 +266,13 @@ bool EntertainmentMode::Connect() | @@ -229,13 +266,13 @@ bool EntertainmentMode::Connect() | ||
| 229 | 266 | ||
| 230 | bool EntertainmentMode::Disconnect() | 267 | bool EntertainmentMode::Disconnect() |
| 231 | { | 268 | { |
| 232 | - mbedtls_ssl_close_notify(&ssl); | ||
| 233 | - return bridge.StopStreaming(std::to_string(group.getId())); | 269 | + mbedtls_ssl_close_notify(&tls_context->ssl); |
| 270 | + return bridge->StopStreaming(std::to_string(group->getId())); | ||
| 234 | } | 271 | } |
| 235 | 272 | ||
| 236 | bool EntertainmentMode::SetColorRGB(uint8_t light_index, uint8_t red, uint8_t green, uint8_t blue) | 273 | bool EntertainmentMode::SetColorRGB(uint8_t light_index, uint8_t red, uint8_t green, uint8_t blue) |
| 237 | { | 274 | { |
| 238 | - if(light_index < entertainment_num_lights) | 275 | + if (light_index < entertainment_num_lights) |
| 239 | { | 276 | { |
| 240 | unsigned int msg_idx = HUE_ENTERTAINMENT_HEADER_SIZE + (light_index * HUE_ENTERTAINMENT_LIGHT_SIZE); | 277 | unsigned int msg_idx = HUE_ENTERTAINMENT_HEADER_SIZE + (light_index * HUE_ENTERTAINMENT_LIGHT_SIZE); |
| 241 | 278 | ||
| @@ -254,24 +291,26 @@ bool EntertainmentMode::SetColorRGB(uint8_t light_index, uint8_t red, uint8_t gr | @@ -254,24 +291,26 @@ bool EntertainmentMode::SetColorRGB(uint8_t light_index, uint8_t red, uint8_t gr | ||
| 254 | } | 291 | } |
| 255 | } | 292 | } |
| 256 | 293 | ||
| 257 | -void EntertainmentMode::Update() | 294 | +bool EntertainmentMode::Update() |
| 258 | { | 295 | { |
| 259 | int ret; | 296 | int ret; |
| 260 | unsigned int total = 0; | 297 | unsigned int total = 0; |
| 261 | 298 | ||
| 262 | - while(total < entertainment_msg.size()) | 299 | + while (total < entertainment_msg.size()) |
| 263 | { | 300 | { |
| 264 | - ret = mbedtls_ssl_write(&ssl, (const unsigned char*)&entertainment_msg[total], entertainment_msg.size()); | 301 | + ret = mbedtls_ssl_write( |
| 302 | + &tls_context->ssl, (const unsigned char*)&entertainment_msg[total], entertainment_msg.size()); | ||
| 265 | 303 | ||
| 266 | - if(ret < 0) | 304 | + if (ret < 0) |
| 267 | { | 305 | { |
| 268 | // Return if mbedtls_ssl_write errors | 306 | // Return if mbedtls_ssl_write errors |
| 269 | - return; | 307 | + return false; |
| 270 | } | 308 | } |
| 271 | else | 309 | else |
| 272 | { | 310 | { |
| 273 | total += ret; | 311 | total += ret; |
| 274 | } | 312 | } |
| 275 | } | 313 | } |
| 314 | + return true; | ||
| 276 | } | 315 | } |
| 277 | } // namespace hueplusplus | 316 | } // namespace hueplusplus |
src/StateTransaction.cpp
| @@ -25,14 +25,13 @@ | @@ -25,14 +25,13 @@ | ||
| 25 | #include <set> | 25 | #include <set> |
| 26 | 26 | ||
| 27 | #include "hueplusplus/HueExceptionMacro.h" | 27 | #include "hueplusplus/HueExceptionMacro.h" |
| 28 | -#include "hueplusplus/StateTransaction.h" | ||
| 29 | #include "hueplusplus/Utils.h" | 28 | #include "hueplusplus/Utils.h" |
| 30 | 29 | ||
| 31 | namespace hueplusplus | 30 | namespace hueplusplus |
| 32 | { | 31 | { |
| 33 | StateTransaction::StateTransaction(const HueCommandAPI& commands, const std::string& path, nlohmann::json* currentState) | 32 | StateTransaction::StateTransaction(const HueCommandAPI& commands, const std::string& path, nlohmann::json* currentState) |
| 34 | : commands(commands), path(path), state(currentState), request(nlohmann::json::object()) | 33 | : commands(commands), path(path), state(currentState), request(nlohmann::json::object()) |
| 35 | -{} | 34 | +{ } |
| 36 | 35 | ||
| 37 | bool StateTransaction::commit(bool trimRequest) | 36 | bool StateTransaction::commit(bool trimRequest) |
| 38 | { | 37 | { |
| @@ -41,8 +40,8 @@ bool StateTransaction::commit(bool trimRequest) | @@ -41,8 +40,8 @@ bool StateTransaction::commit(bool trimRequest) | ||
| 41 | if (!request.count("on")) | 40 | if (!request.count("on")) |
| 42 | { | 41 | { |
| 43 | if (!stateJson.value("on", false) | 42 | if (!stateJson.value("on", false) |
| 44 | - && (request.value("bri", 0) != 0 || request.count("effect") || request.count("hue") | ||
| 45 | - || request.count("sat") || request.count("xy") || request.count("ct"))) | 43 | + && (request.value("bri", 0) != 0 || request.count("effect") || request.count("hue") || request.count("sat") |
| 44 | + || request.count("xy") || request.count("ct"))) | ||
| 46 | { | 45 | { |
| 47 | // Turn on if it was turned off | 46 | // Turn on if it was turned off |
| 48 | request["on"] = true; | 47 | request["on"] = true; |
test/test_Bridge.cpp
| @@ -88,7 +88,7 @@ TEST_F(BridgeFinderTest, FindBridges) | @@ -88,7 +88,7 @@ TEST_F(BridgeFinderTest, FindBridges) | ||
| 88 | TEST_F(BridgeFinderTest, GetBridge) | 88 | TEST_F(BridgeFinderTest, GetBridge) |
| 89 | { | 89 | { |
| 90 | using namespace ::testing; | 90 | using namespace ::testing; |
| 91 | - nlohmann::json request {{"devicetype":"HuePlusPlus#User","generateclientkey":true}}; | 91 | + nlohmann::json request {{"devicetype", "HuePlusPlus#User"}, {"generateclientkey", true}}; |
| 92 | 92 | ||
| 93 | nlohmann::json errorResponse | 93 | nlohmann::json errorResponse |
| 94 | = {{{"error", {{"type", 101}, {"address", ""}, {"description", "link button not pressed"}}}}}; | 94 | = {{{"error", {{"type", 101}, {"address", ""}, {"description", "link button not pressed"}}}}}; |
| @@ -158,7 +158,7 @@ TEST(Bridge, requestUsername) | @@ -158,7 +158,7 @@ TEST(Bridge, requestUsername) | ||
| 158 | { | 158 | { |
| 159 | using namespace ::testing; | 159 | using namespace ::testing; |
| 160 | std::shared_ptr<MockHttpHandler> handler = std::make_shared<MockHttpHandler>(); | 160 | std::shared_ptr<MockHttpHandler> handler = std::make_shared<MockHttpHandler>(); |
| 161 | - nlohmann::json request {{"devicetype":"HuePlusPlus#User","generateclientkey":true}}; | 161 | + nlohmann::json request {{"devicetype", "HuePlusPlus#User"}, {"generateclientkey", true}}; |
| 162 | 162 | ||
| 163 | { | 163 | { |
| 164 | nlohmann::json errorResponse | 164 | nlohmann::json errorResponse |