Commit 3321666f2f0e58d15448a92ea90b3a5007d1f623
Committed by
Moritz Wirger
1 parent
5212c084
Add initial files for Entertainment Mode support
Showing
2 changed files
with
245 additions
and
0 deletions
include/hueplusplus/EntertainmentMode.h
0 → 100644
| 1 | +/** | |
| 2 | + \file EntertainmentMode.h | |
| 3 | + Copyright Notice\n | |
| 4 | + Copyright (C) 2020 Adam Honse - developer\n | |
| 5 | + | |
| 6 | + This file is part of hueplusplus. | |
| 7 | + | |
| 8 | + hueplusplus is free software: you can redistribute it and/or modify | |
| 9 | + it under the terms of the GNU Lesser General Public License as published by | |
| 10 | + the Free Software Foundation, either version 3 of the License, or | |
| 11 | + (at your option) any later version. | |
| 12 | + | |
| 13 | + hueplusplus is distributed in the hope that it will be useful, | |
| 14 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 16 | + GNU Lesser General Public License for more details. | |
| 17 | + | |
| 18 | + You should have received a copy of the GNU Lesser General Public License | |
| 19 | + along with hueplusplus. If not, see <http://www.gnu.org/licenses/>. | |
| 20 | +**/ | |
| 21 | + | |
| 22 | +#ifndef INCLUDE_HUEPLUSPLUS_HUE_ENTERTAINMENT_MODE_H | |
| 23 | +#define INCLUDE_HUEPLUSPLUS_HUE_ENTERTAINMENT_MODE_H | |
| 24 | + | |
| 25 | +#include "Bridge.h" | |
| 26 | +#include "Group.h" | |
| 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 | |
| 41 | +{ | |
| 42 | +//! \brief Class for Hue Entertainment Mode | |
| 43 | +//! | |
| 44 | +//! Provides methods to initialize and control Entertainment groups. | |
| 45 | +class EntertainmentMode | |
| 46 | +{ | |
| 47 | +public: | |
| 48 | + EntertainmentMode(Bridge& bridge, Group& group); | |
| 49 | + | |
| 50 | + bool Connect(); | |
| 51 | + bool Disconnect(); | |
| 52 | + | |
| 53 | + bool SetColorRGB(unsigned int light_index, unsigned char red, unsigned char green, unsigned char blue); | |
| 54 | + | |
| 55 | + void Update(); | |
| 56 | + | |
| 57 | +protected: | |
| 58 | + Bridge& bridge; | |
| 59 | + Group& group; | |
| 60 | + | |
| 61 | + unsigned char* entertainment_msg; //!< buffer containing the entertainment mode packet data | |
| 62 | + unsigned int entertainment_msg_size; //!< size of the entertainment mode buffer | |
| 63 | + unsigned int entertainment_num_lights; //!< number of lights in entertainment mode group | |
| 64 | + | |
| 65 | + mbedtls_ssl_context ssl; | |
| 66 | + mbedtls_net_context server_fd; | |
| 67 | + mbedtls_entropy_context entropy; | |
| 68 | + mbedtls_ctr_drbg_context ctr_drbg; | |
| 69 | + mbedtls_ssl_config conf; | |
| 70 | + mbedtls_x509_crt cacert; | |
| 71 | + mbedtls_timing_delay_context timer; | |
| 72 | +}; | |
| 73 | +} // namespace hueplusplus | |
| 74 | + | |
| 75 | +#endif | ... | ... |
src/EntertainmentMode.cpp
0 → 100644
| 1 | +/** | |
| 2 | + \file EntertainmentMode.cpp | |
| 3 | + Copyright Notice\n | |
| 4 | + Copyright (C) 2020 Adam Honse - developer\n | |
| 5 | + | |
| 6 | + This file is part of hueplusplus. | |
| 7 | + | |
| 8 | + hueplusplus is free software: you can redistribute it and/or modify | |
| 9 | + it under the terms of the GNU Lesser General Public License as published by | |
| 10 | + the Free Software Foundation, either version 3 of the License, or | |
| 11 | + (at your option) any later version. | |
| 12 | + | |
| 13 | + hueplusplus is distributed in the hope that it will be useful, | |
| 14 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 16 | + GNU Lesser General Public License for more details. | |
| 17 | + | |
| 18 | + You should have received a copy of the GNU Lesser General Public License | |
| 19 | + along with hueplusplus. If not, see <http://www.gnu.org/licenses/>. | |
| 20 | +**/ | |
| 21 | + | |
| 22 | +#include "hueplusplus/EntertainmentMode.h" | |
| 23 | + | |
| 24 | +std::vector<char> HexToBytes(const std::string& hex) | |
| 25 | +{ | |
| 26 | + std::vector<char> bytes; | |
| 27 | + | |
| 28 | + for (unsigned int i = 0; i < hex.length(); i += 2) | |
| 29 | + { | |
| 30 | + std::string byteString = hex.substr(i, 2); | |
| 31 | + char byte = (char) strtol(byteString.c_str(), NULL, 16); | |
| 32 | + bytes.push_back(byte); | |
| 33 | + } | |
| 34 | + | |
| 35 | + return bytes; | |
| 36 | +} | |
| 37 | + | |
| 38 | +namespace hueplusplus | |
| 39 | +{ | |
| 40 | +EntertainmentMode::EntertainmentMode(Bridge& bridge, Group& group):bridge(bridge),group(group) | |
| 41 | +{ | |
| 42 | + /*-------------------------------------------------*\ | |
| 43 | + | Signal the bridge to start streaming | | |
| 44 | + \*-------------------------------------------------*/ | |
| 45 | + bridge.StartStreaming(std::to_string(group.getId())); | |
| 46 | + | |
| 47 | + /*-------------------------------------------------*\ | |
| 48 | + | Get the number of lights from the group | | |
| 49 | + \*-------------------------------------------------*/ | |
| 50 | + entertainment_num_lights = group.getLightIds().size(); | |
| 51 | + | |
| 52 | + /*-------------------------------------------------*\ | |
| 53 | + | Create Entertainment Mode message buffer | | |
| 54 | + \*-------------------------------------------------*/ | |
| 55 | + entertainment_msg_size = HUE_ENTERTAINMENT_HEADER_SIZE + (entertainment_num_lights * HUE_ENTERTAINMENT_LIGHT_SIZE); | |
| 56 | + entertainment_msg = new unsigned char[entertainment_msg_size]; | |
| 57 | + | |
| 58 | + /*-------------------------------------------------*\ | |
| 59 | + | Fill in Entertainment Mode message header | | |
| 60 | + \*-------------------------------------------------*/ | |
| 61 | + memcpy(entertainment_msg, "HueStream", 9); | |
| 62 | + entertainment_msg[9] = 0x01; // Version Major (1) | |
| 63 | + entertainment_msg[10] = 0x00; // Version Minor (0) | |
| 64 | + entertainment_msg[11] = 0x00; // Sequence ID | |
| 65 | + entertainment_msg[12] = 0x00; // Reserved | |
| 66 | + entertainment_msg[13] = 0x00; // Reserved | |
| 67 | + entertainment_msg[14] = 0x00; // Color Space (RGB) | |
| 68 | + entertainment_msg[15] = 0x00; // Reserved | |
| 69 | + | |
| 70 | + /*-------------------------------------------------*\ | |
| 71 | + | Fill in Entertainment Mode light data | | |
| 72 | + \*-------------------------------------------------*/ | |
| 73 | + for (unsigned int light_idx = 0; light_idx < entertainment_num_lights; light_idx++) | |
| 74 | + { | |
| 75 | + unsigned int msg_idx = HUE_ENTERTAINMENT_HEADER_SIZE + (light_idx * HUE_ENTERTAINMENT_LIGHT_SIZE); | |
| 76 | + | |
| 77 | + entertainment_msg[msg_idx + 0] = 0x00; // Type (Light) | |
| 78 | + entertainment_msg[msg_idx + 1] = group.getLightIds()[light_idx] >> 8; // ID MSB | |
| 79 | + entertainment_msg[msg_idx + 2] = group.getLightIds()[light_idx] & 0xFF; // ID LSB | |
| 80 | + entertainment_msg[msg_idx + 3] = 0x00; // Red MSB | |
| 81 | + entertainment_msg[msg_idx + 4] = 0x00; // Red LSB; | |
| 82 | + entertainment_msg[msg_idx + 5] = 0x00; // Green MSB; | |
| 83 | + entertainment_msg[msg_idx + 6] = 0x00; // Green LSB; | |
| 84 | + entertainment_msg[msg_idx + 7] = 0x00; // Blue MSB; | |
| 85 | + entertainment_msg[msg_idx + 8] = 0x00; // Blue LSB; | |
| 86 | + } | |
| 87 | + | |
| 88 | + /*-------------------------------------------------*\ | |
| 89 | + | Initialize mbedtls contexts | | |
| 90 | + \*-------------------------------------------------*/ | |
| 91 | + mbedtls_net_init(&server_fd); | |
| 92 | + mbedtls_ssl_init(&ssl); | |
| 93 | + mbedtls_ssl_config_init(&conf); | |
| 94 | + mbedtls_x509_crt_init(&cacert); | |
| 95 | + mbedtls_ctr_drbg_init(&ctr_drbg); | |
| 96 | + mbedtls_entropy_init(&entropy); | |
| 97 | + | |
| 98 | + /*-------------------------------------------------*\ | |
| 99 | + | Seed the Deterministic Random Bit Generator (RNG) | | |
| 100 | + \*-------------------------------------------------*/ | |
| 101 | + int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0); | |
| 102 | + | |
| 103 | + /*-------------------------------------------------*\ | |
| 104 | + | Parse certificate | | |
| 105 | + \*-------------------------------------------------*/ | |
| 106 | + ret = mbedtls_x509_crt_parse(&cacert, (const unsigned char*)mbedtls_test_cas_pem, mbedtls_test_cas_pem_len); | |
| 107 | + | |
| 108 | + /*-------------------------------------------------*\ | |
| 109 | + | Connect to the Hue bridge UDP server | | |
| 110 | + \*-------------------------------------------------*/ | |
| 111 | + ret = mbedtls_net_connect(&server_fd, bridge.getBridgeIP().c_str(), "2100", MBEDTLS_NET_PROTO_UDP); | |
| 112 | + | |
| 113 | + /*-------------------------------------------------*\ | |
| 114 | + | Configure defaults | | |
| 115 | + \*-------------------------------------------------*/ | |
| 116 | + ret = mbedtls_ssl_config_defaults( | |
| 117 | + &conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT); | |
| 118 | + | |
| 119 | + mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL); | |
| 120 | + mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL); | |
| 121 | + mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); | |
| 122 | + | |
| 123 | + /*-------------------------------------------------*\ | |
| 124 | + | Convert client key to binary array | | |
| 125 | + \*-------------------------------------------------*/ | |
| 126 | + std::vector<char> psk_binary = HexToBytes(bridge.getClientKey()); | |
| 127 | + | |
| 128 | + /*-------------------------------------------------*\ | |
| 129 | + | Configure SSL pre-shared key and identity | | |
| 130 | + | PSK - binary array from client key | | |
| 131 | + | Identity - username (ASCII) | | |
| 132 | + \*-------------------------------------------------*/ | |
| 133 | + ret = mbedtls_ssl_conf_psk(&conf, (const unsigned char*)&psk_binary[0], psk_binary.size(), | |
| 134 | + (const unsigned char*)bridge.getUsername().c_str(), bridge.getUsername().length()); | |
| 135 | + | |
| 136 | + /*-------------------------------------------------*\ | |
| 137 | + | Set up the SSL | | |
| 138 | + \*-------------------------------------------------*/ | |
| 139 | + ret = mbedtls_ssl_setup(&ssl, &conf); | |
| 140 | + | |
| 141 | + ret = mbedtls_ssl_set_hostname(&ssl, "localhost"); | |
| 142 | + | |
| 143 | + mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout); | |
| 144 | + mbedtls_ssl_set_timer_cb(&ssl, &timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay); | |
| 145 | + | |
| 146 | + do | |
| 147 | + { | |
| 148 | + ret = mbedtls_ssl_handshake(&ssl); | |
| 149 | + } while (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE); | |
| 150 | +} | |
| 151 | + | |
| 152 | +bool EntertainmentMode::SetColorRGB(unsigned int light_index, unsigned char red, unsigned char green, unsigned char blue) | |
| 153 | +{ | |
| 154 | + unsigned int msg_idx = HUE_ENTERTAINMENT_HEADER_SIZE + (light_index * HUE_ENTERTAINMENT_LIGHT_SIZE); | |
| 155 | + | |
| 156 | + entertainment_msg[msg_idx + 3] = red; // Red MSB | |
| 157 | + entertainment_msg[msg_idx + 4] = red; // Red LSB; | |
| 158 | + entertainment_msg[msg_idx + 5] = green; // Green MSB; | |
| 159 | + entertainment_msg[msg_idx + 6] = green; // Green LSB; | |
| 160 | + entertainment_msg[msg_idx + 7] = blue; // Blue MSB; | |
| 161 | + entertainment_msg[msg_idx + 8] = blue; // Blue LSB; | |
| 162 | + | |
| 163 | + return false; | |
| 164 | +} | |
| 165 | + | |
| 166 | +void EntertainmentMode::Update() | |
| 167 | +{ | |
| 168 | + mbedtls_ssl_write(&ssl, (const unsigned char*)entertainment_msg, entertainment_msg_size); | |
| 169 | +} | |
| 170 | +} // namespace hueplusplus | ... | ... |