Commit 2780404a7309841b24fdff2ec8cab74c321f2f0d

Authored by Moritz Wirger
1 parent d218d9d3

Fix entertainment mode support

- Add mbedtls as submodule
- Add bin folder to gitignore
.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
  1 +[submodule "lib/mbedtls"]
  2 + path = lib/mbedtls
  3 + url = https://github.com/ARMmbed/mbedtls.git
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&lt;char&gt; HexToBytes(const std::string&amp; hex) @@ -28,26 +52,25 @@ std::vector&lt;char&gt; HexToBytes(const std::string&amp; 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&amp; bridge, Group&amp; group):bridge(bridge @@ -74,8 +97,8 @@ EntertainmentMode::EntertainmentMode(Bridge&amp; bridge, Group&amp; 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&amp; bridge, Group&amp; group):bridge(bridge @@ -87,22 +110,33 @@ EntertainmentMode::EntertainmentMode(Bridge&amp; bridge, Group&amp; 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