├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── SerialLog.txt ├── examples └── HomeKit_IDF │ ├── HomeKit_IDF.ino │ ├── homekit_main.c │ └── wifi_info.h └── src ├── _esp_hap_config.h ├── base36.h ├── byte_convert.c ├── byte_convert.h ├── esp_hap_acc.c ├── esp_hap_acc.h ├── esp_hap_bct.c ├── esp_hap_bct_priv.h ├── esp_hap_char.c ├── esp_hap_char.h ├── esp_hap_controllers.c ├── esp_hap_controllers.h ├── esp_hap_database.c ├── esp_hap_database.h ├── esp_hap_ip_services.c ├── esp_hap_ip_services.h ├── esp_hap_keystore.c ├── esp_hap_keystore.h ├── esp_hap_main.c ├── esp_hap_main.h ├── esp_hap_mdns.c ├── esp_hap_mdns.h ├── esp_hap_network_io.c ├── esp_hap_network_io.h ├── esp_hap_pair_common.c ├── esp_hap_pair_common.h ├── esp_hap_pair_setup.c ├── esp_hap_pair_setup.h ├── esp_hap_pair_verify.c ├── esp_hap_pair_verify.h ├── esp_hap_pairings.c ├── esp_hap_pairings.h ├── esp_hap_secure_message.h ├── esp_hap_serv.c ├── esp_hap_serv.h ├── esp_hap_setup_payload.c ├── esp_hap_wac.h ├── esp_hap_wifi.c ├── esp_hap_wifi.h ├── esp_mfi_aes.c ├── esp_mfi_aes.h ├── esp_mfi_base64.c ├── esp_mfi_base64.h ├── esp_mfi_debug.c ├── esp_mfi_debug.h ├── esp_mfi_dummy.c ├── esp_mfi_i2c.c.0 ├── esp_mfi_i2c.h.0 ├── esp_mfi_rand.c ├── esp_mfi_rand.h ├── esp_mfi_sha.c ├── esp_mfi_sha.h ├── hap.h ├── hap_apple_chars.c ├── hap_apple_chars.h ├── hap_apple_servs.c ├── hap_apple_servs.h ├── hap_bct.h ├── hap_platform_httpd.c ├── hap_platform_httpd.h ├── hap_platform_keystore.c ├── hap_platform_keystore.h ├── hap_platform_memory.c ├── hap_platform_memory.h ├── hap_platform_os.c ├── hap_platform_os.h ├── hap_wac.h ├── hexbin.c ├── hexbin.h ├── hexdump.c ├── hexdump.h ├── hkdf-sha.h ├── hkdf.c ├── hmac.c ├── jsmn └── jsmn.h ├── json_generator.c ├── json_generator.h ├── json_parser.c ├── json_parser.h ├── mu_bignum.h ├── mu_srp.c ├── mu_srp.h ├── port ├── bignum.c ├── bignum.h ├── bignum_impl.h └── esp_bignum.c ├── sha-private.h ├── sha.h ├── sha1.c ├── sha224-256.c ├── sha384-512.c ├── shatest.c └── usha.c /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Mixiaoxiao (Wang Bin) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arduino-HomeKit-ESP 2 | Arduino library version of espressif's official [esp-homekit-sdk](https://github.com/espressif/esp-homekit-sdk). 3 | 4 | Currently, only for ESP32 with hardware acceleration. ESP32-S2, ESP32-C3 and future IDF based chips are all on the way. 5 | 6 | Tested on my ESP32 board, works fine. 7 | 8 | The performance is awesome!!! 9 | 10 | The serial log is [here](https://raw.github.com/Mixiaoxiao/Arduino-HomeKit-ESP/master/extras/SerialLog.txt) 11 | 12 | ## Setup code 13 | 14 | ``111-11-111`` 15 | 16 | ## Manual Installation 17 | 18 | Refer to the official guide: [Manual installation](https://www.arduino.cc/en/guide/libraries#toc5) 19 | Note: this library will not publish the release version for Arduino IDE. 20 | 21 | 22 | #### Manual Installation for Windows 23 | 24 | 1. Click on _"Clone or Download"_ button, then click _"[Download ZIP](https://github.com/Mixiaoxiao/Arduino-HomeKit-ESP/archive/master.zip)"_ on the page. 25 | 1. Extract the contents of the downloaded zip file. 26 | 1. Rename the extracted folder to _"Arduino-HomeKit-ESP"_. 27 | 1. Move this folder to your libraries directory. (under windows: `C:\Users\\Documents\Arduino\libraries\`) 28 | 1. Restart your Arduino IDE. 29 | 1. Check out the examples. 30 | 31 | 32 | -------------------------------------------------------------------------------- /SerialLog.txt: -------------------------------------------------------------------------------- 1 | Boot OK 2 | WiFi connecting... 3 | ............... 4 | WiFi connected, IP: 192.168.6.134 5 | [ 1657] Keystore initialised 6 | [ 1662] Accessory is not Paired with any controller 7 | [ 1664] Database initialised. Accessory Device ID: 90:60:09:AB:F0:1D 8 | [ 1664] HAP Initialization succeeded. Version : 4.0 9 | [ 1670] MFi auth not supported. Falling back to HAP_MFI_AUTH_NONE 10 | [ 1675] Setup ID: ES32 11 | [ 1681] HAP Main Loop Started 12 | [ 1684] mDNS initialised 13 | [ 1684] Registering HomeKit web handlers 14 | [ 1687] Announcing _hap._tcp mDNS service 15 | [ 10032] ######## Starting Pair Setup ######## 16 | [ 10032] Pair Setup M1 Received 17 | [ 12073] Pair Setup M2 Successful 18 | [ 12501] Pair Setup M3 Received 19 | [ 14540] Using pair-setup without MFi. 20 | [ 14540] Pair Setup M4 Successful 21 | [ 14929] Pair Setup M5 Received 22 | [ 15023] Pair Setup Successful for CF87DA6B-7078-44BB-AC04-27B6F2B26D37 23 | [ 15027] Updated state number to 11 24 | [ 15028] Cleaning Pair Setup Context 25 | [ 15032] Re-announcing _hap._tcp mDNS service 26 | [ 16205] ######## Starting Pair Verify ######## 27 | [ 16205] Pair Verify M1 Received 28 | [ 16327] Pair Verify M2 Successful 29 | [ 16385] Pair Verify M3 Received 30 | [ 16444] HomeKit Session active 31 | [ 16445] Pair Verify Successful for CF87DA6B-7078-44BB-AC04-27B6F2B26D37 32 | [ 16781] Events Enabled for aid=1 iid=12 33 | [ 16781] Events Enabled for aid=1 iid=13 34 | [ 17080] Events Enabled for aid=1 iid=12 35 | [ 17080] Events Enabled for aid=1 iid=13 36 | [ 22311] ######## Starting Pair Verify ######## 37 | [ 22311] Pair Verify M1 Received 38 | [ 22435] Pair Verify M2 Successful 39 | [ 22470] Pair Verify M3 Received 40 | [ 22528] HomeKit Session active 41 | [ 22528] Pair Verify Successful for CF87DA6B-7078-44BB-AC04-27B6F2B26D37 42 | [ 25069] Value Changed 43 | [ 26605] Value Changed -------------------------------------------------------------------------------- /examples/HomeKit_IDF/HomeKit_IDF.ino: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "wifi_info.h" 3 | #include "hap.h" 4 | 5 | extern "C" void homekit_main(); 6 | 7 | void setup() { 8 | Serial.begin(115200); 9 | Serial.println("Boot OK"); 10 | wifi_connect(); 11 | // Useful apis: (see hap.h) 12 | // hap_reset_to_factory(); 13 | // hap_reset_homekit_data(); 14 | // hap_reset_pairings(); 15 | homekit_main(); 16 | vTaskDelete(NULL); 17 | } 18 | 19 | void loop() { 20 | } 21 | -------------------------------------------------------------------------------- /examples/HomeKit_IDF/wifi_info.h: -------------------------------------------------------------------------------- 1 | /* 2 | * wifi_info.h 3 | * 4 | * Created on: 2020-05-15 5 | * Author: Mixiaoxiao (Wang Bin) 6 | */ 7 | 8 | #ifndef WIFI_INFO_H_ 9 | #define WIFI_INFO_H_ 10 | 11 | #if defined(ESP8266) 12 | #include 13 | #elif defined(ESP32) 14 | #include 15 | #endif 16 | 17 | const char *ssid = "your-ssid"; 18 | const char *password = "your-password"; 19 | 20 | void wifi_connect() { 21 | WiFi.persistent(false); 22 | WiFi.mode(WIFI_STA); 23 | WiFi.setAutoReconnect(true); 24 | WiFi.begin(ssid, password); 25 | Serial.println("WiFi connecting..."); 26 | while (!WiFi.isConnected()) { 27 | delay(100); 28 | Serial.print("."); 29 | } 30 | Serial.print("\n"); 31 | Serial.printf("WiFi connected, IP: %s\n", WiFi.localIP().toString().c_str()); 32 | } 33 | 34 | #endif /* WIFI_INFO_H_ */ 35 | -------------------------------------------------------------------------------- /src/_esp_hap_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * _esp_hap_config.h 3 | * 4 | * Created on: 2020-11-23 5 | * Author: Mixiaoxiao 6 | */ 7 | 8 | #ifndef ESP_HAP_CONFIG_H_ 9 | #define ESP_HAP_CONFIG_H_ 10 | 11 | #define HAP_SDK_VER "4.0" 12 | #define MFI_VER HAP_SDK_VER 13 | 14 | #define CONFIG_HAP_HTTP_STACK_SIZE 12288 15 | #define CONFIG_HAP_HTTP_SERVER_PORT 5556 // 80 for normal webserver 16 | #define CONFIG_HAP_HTTP_CONTROL_PORT 32859 17 | #define CONFIG_HAP_HTTP_MAX_OPEN_SOCKETS 6 18 | #define CONFIG_HAP_HTTP_MAX_URI_HANDLERS 16 19 | 20 | #endif /* ESP_HAP_CONFIG_H_ */ 21 | -------------------------------------------------------------------------------- /src/base36.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Base36 PostgreSQL input/output function for bigint 3 | * 4 | * Author: Dimitri Fontaine 5 | * 6 | * Taken from https://github.com/dimitri/base36/blob/master/base36.c 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #define BASE36_LENGTH 13 13 | 14 | typedef long long int base36; 15 | 16 | static int base36_digits[36] = 17 | {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 18 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 19 | 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 20 | 'U', 'V', 'W', 'X', 'Y', 'Z' 21 | }; 22 | 23 | static base36 base36_powers[BASE36_LENGTH] = 24 | { 25 | 1ULL, 26 | 36ULL, 27 | 1296ULL, 28 | 46656ULL, 29 | 1679616ULL, 30 | 60466176ULL, 31 | 2176782336ULL, 32 | 78364164096ULL, 33 | 2821109907456ULL, 34 | 101559956668416ULL, 35 | 3656158440062976ULL, 36 | 131621703842267136ULL, 37 | 4738381338321616896ULL 38 | }; 39 | 40 | static inline 41 | char *base36_to_str(base36 c) 42 | { 43 | int i, d, p = 0; 44 | base36 m = c; 45 | bool discard = true; 46 | char *str = calloc((BASE36_LENGTH + 1), sizeof(char)); 47 | 48 | for(i=BASE36_LENGTH-1; i>=0; i--) 49 | { 50 | d = m / base36_powers[i]; 51 | m = m - base36_powers[i] * d; 52 | 53 | discard = discard && (d == 0 && i >0); 54 | 55 | if( !discard ) 56 | str[p++] = base36_digits[d]; 57 | } 58 | 59 | return str; 60 | } 61 | -------------------------------------------------------------------------------- /src/byte_convert.c: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #include 15 | #include 16 | 17 | /* Functions to convert Little Endian byte stream to 18 | * uint16, uint32 and uint64 19 | */ 20 | uint16_t get_u16_le(const void *val_ptr) 21 | { 22 | const uint8_t *p = (const uint8_t *)val_ptr; 23 | uint16_t val; 24 | 25 | val = (uint16_t)p[0]; 26 | val |= (uint16_t)p[1] << 8; 27 | 28 | return val; 29 | } 30 | 31 | uint32_t get_u32_le(const void *val_ptr) 32 | { 33 | const uint8_t *p = (const uint8_t *)val_ptr; 34 | uint32_t val; 35 | 36 | val = (uint32_t)p[0]; 37 | val |= (uint32_t)p[1] << 8; 38 | val |= (uint32_t)p[2] << 16; 39 | val |= (uint32_t)p[3] << 24; 40 | 41 | return val; 42 | } 43 | 44 | uint64_t get_u64_le(const void *val_ptr) 45 | { 46 | const uint8_t *p = (const uint8_t *)val_ptr; 47 | uint64_t val; 48 | 49 | val = (uint64_t)p[0]; 50 | val |= (uint64_t)p[1] << 8; 51 | val |= (uint64_t)p[2] << 16; 52 | val |= (uint64_t)p[3] << 24; 53 | val |= (uint64_t)p[4] << 32; 54 | val |= (uint64_t)p[5] << 40; 55 | val |= (uint64_t)p[6] << 48; 56 | val |= (uint64_t)p[7] << 56; 57 | 58 | return val; 59 | } 60 | 61 | /* Functions to convert Big Endian byte stream to 62 | * uint16, uint32 and uint64 63 | */ 64 | uint16_t get_u16_be(const void *val_ptr) 65 | { 66 | const uint8_t *p = (const uint8_t *)val_ptr; 67 | uint16_t val; 68 | 69 | val = (uint16_t)p[0] << 8; 70 | val |= (uint16_t)p[1]; 71 | 72 | return val; 73 | } 74 | 75 | uint32_t get_u32_be(const void *val_ptr) 76 | { 77 | const uint8_t *p = (const uint8_t *)val_ptr; 78 | uint32_t val; 79 | 80 | val = (uint32_t)p[0] << 24; 81 | val |= (uint32_t)p[1] << 16; 82 | val |= (uint32_t)p[2] << 8; 83 | val |= (uint32_t)p[3]; 84 | 85 | return val; 86 | } 87 | 88 | uint64_t get_u64_be(const void *val_ptr) 89 | { 90 | const uint8_t *p = (const uint8_t *)val_ptr; 91 | uint64_t val; 92 | 93 | val = (uint64_t)p[0] << 56; 94 | val |= (uint64_t)p[1] << 48; 95 | val |= (uint64_t)p[2] << 40; 96 | val |= (uint64_t)p[3] << 32; 97 | val |= (uint64_t)p[4] << 24; 98 | val |= (uint64_t)p[5] << 16; 99 | val |= (uint64_t)p[6] << 8; 100 | val |= (uint64_t)p[7]; 101 | 102 | return val; 103 | } 104 | 105 | /* Functions to convert uint16, uint32 and uint64 106 | * to Little Endian 107 | */ 108 | void put_u16_le(void *val_ptr, const uint16_t val) 109 | { 110 | uint8_t *p = (uint8_t *)val_ptr; 111 | 112 | p[0] = (uint8_t)val & 0xff; 113 | p[1] = (uint8_t)(val >> 8) & 0xff; 114 | } 115 | 116 | void put_u32_le(void *val_ptr, const uint32_t val) 117 | { 118 | uint8_t *p = (uint8_t *)val_ptr; 119 | 120 | p[0] = (uint8_t)val & 0xff; 121 | p[1] = (uint8_t)(val >> 8) & 0xff; 122 | p[2] = (uint8_t)(val >> 16) & 0xff; 123 | p[3] = (uint8_t)(val >> 24) & 0xff; 124 | } 125 | 126 | void put_u64_le(void *val_ptr, const uint64_t val) 127 | { 128 | uint8_t *p = (uint8_t *)val_ptr; 129 | 130 | p[0] = (uint8_t)val & 0xff; 131 | p[1] = (uint8_t)(val >> 8) & 0xff; 132 | p[2] = (uint8_t)(val >> 16) & 0xff; 133 | p[3] = (uint8_t)(val >> 24) & 0xff; 134 | p[4] = (uint8_t)(val >> 32) & 0xff; 135 | p[5] = (uint8_t)(val >> 40) & 0xff; 136 | p[6] = (uint8_t)(val >> 48) & 0xff; 137 | p[7] = (uint8_t)(val >> 56) & 0xff; 138 | } 139 | 140 | /* Functions to convert uint16, uint32 and uint64 141 | * to Big Endian 142 | */ 143 | void put_u16_be(void *val_ptr, const uint16_t val) 144 | { 145 | uint8_t *p = (uint8_t *)val_ptr; 146 | 147 | p[0] = (uint8_t)(val >> 8) & 0xff; 148 | p[1] = (uint8_t)val & 0xff; 149 | } 150 | 151 | void put_u32_be(void *val_ptr, const uint32_t val) 152 | { 153 | uint8_t *p = (uint8_t *)val_ptr; 154 | 155 | p[0] = (uint8_t)((val >> 24) & 0xff); 156 | p[1] = (uint8_t)((val >> 16) & 0xff); 157 | p[2] = (uint8_t)((val >> 8) & 0xff); 158 | p[3] = (uint8_t)(val & 0xff); 159 | } 160 | 161 | void put_u64_be(void *val_ptr, const uint64_t val) 162 | { 163 | uint8_t *p = (uint8_t *)val_ptr; 164 | 165 | p[0] = (uint8_t)(val >> 56) & 0xff; 166 | p[1] = (uint8_t)(val >> 48) & 0xff; 167 | p[2] = (uint8_t)(val >> 40) & 0xff; 168 | p[3] = (uint8_t)(val >> 32) & 0xff; 169 | p[4] = (uint8_t)(val >> 24) & 0xff; 170 | p[5] = (uint8_t)(val >> 16) & 0xff; 171 | p[6] = (uint8_t)(val >> 8) & 0xff; 172 | p[7] = (uint8_t)val & 0xff; 173 | } 174 | -------------------------------------------------------------------------------- /src/byte_convert.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | /** 15 | * \file byte_convert.h 16 | * \brief Conversion between integers and byte streams 17 | * 18 | * This module offers APIs to convert 16bit, 32bit and 64 bit unsigned integers 19 | * into Little/Big Endian byte streams 20 | */ 21 | #ifndef _BYTE_CONVERT_H 22 | #define _BYTE_CONVERT_H 23 | 24 | #include 25 | 26 | /** Little Endian to uint16 Conversion 27 | * Get a uint16 integer from a little Endian byte stream 28 | * 29 | * \param[in] val_ptr Pointer to the 2 byte stream 30 | * 31 | * \return The converted uint16 integer 32 | */ 33 | uint16_t get_u16_le(const void *val_ptr); 34 | 35 | /** Little Endian to uint32 Conversion 36 | * Get a uint32 integer from a little Endian byte stream 37 | * 38 | * \param[in] val_ptr Pointer to the 4 byte stream 39 | * 40 | * \return The converted uint32 integer 41 | */ 42 | uint32_t get_u32_le(const void *val_ptr); 43 | 44 | /** Little Endian to uint64 Conversion 45 | * Get a uint64 integer from a little Endian byte stream 46 | * 47 | * \param[in] val_ptr Pointer to the 8 byte stream 48 | * 49 | * \return The converted uint32 integer 50 | */ 51 | uint64_t get_u64_le(const void *val_ptr); 52 | 53 | /** Big Endian to uint16 Conversion 54 | * Get a uint16 integer from a Big Endian byte stream 55 | * 56 | * \param[in] val_ptr Pointer to the 2 byte stream 57 | * 58 | * \return The converted uint16 integer 59 | */ 60 | uint16_t get_u16_be(const void *val_ptr); 61 | 62 | /** Big Endian to uint32 Conversion 63 | * Get a uint32 integer from a Big Endian byte stream 64 | * 65 | * \param[in] val_ptr Pointer to the 4 byte stream 66 | * 67 | * \return The converted uint32 integer 68 | */ 69 | uint32_t get_u32_be(const void *val_ptr); 70 | 71 | /** Big Endian to uint64 Conversion 72 | * Get a uint64 integer from a Big Endian byte stream 73 | * 74 | * \param[in] val_ptr Pointer to the 8 byte stream 75 | * 76 | * \return The converted uint16 integer 77 | */ 78 | uint64_t get_u64_be(const void *val_ptr); 79 | 80 | /** Uint16 to Little Endian Conversion 81 | * 82 | * Put a uint16 integer into a Little Endian byte stream 83 | * 84 | * \param[out] Pointer to a 2 byte stream that will be filled with the value 85 | * 86 | * \param[in] The uint16 integer 87 | */ 88 | void put_u16_le(void *val_ptr, const uint16_t val); 89 | 90 | /** Uint32 to Little Endian Conversion 91 | * 92 | * Put a uint32 integer into a Little Endian byte stream 93 | * 94 | * \param[out] Pointer to a 4 byte stream that will be filled with the value 95 | * 96 | * \param[in] The uint32 integer 97 | */ 98 | void put_u32_le(void *val_ptr, const uint32_t val); 99 | 100 | /** Uint64 to Little Endian Conversion 101 | * 102 | * Put a uint64 integer into a Little Endian byte stream 103 | * 104 | * \param[out] Pointer to a 8 byte stream that will be filled with the value 105 | * 106 | * \param[in] The uint64 integer 107 | */ 108 | void put_u64_le(void *val_ptr, const uint64_t val); 109 | 110 | /** Uint16 to Big Endian Conversion 111 | * 112 | * Put a uint16 integer into a Big Endian byte stream 113 | * 114 | * \param[out] Pointer to a 2 byte stream that will be filled with the value 115 | * 116 | * \param[in] The uint16 integer 117 | */ 118 | void put_u16_be(void *val_ptr, const uint16_t val); 119 | 120 | /** Uint32 to Big Endian Conversion 121 | * 122 | * Put a uint32 integer into a Big Endian byte stream 123 | * 124 | * \param[out] Pointer to a 4 byte stream that will be filled with the value 125 | * 126 | * \param[in] The uint32 integer 127 | */ 128 | void put_u32_be(void *val_ptr, const uint32_t val); 129 | 130 | /** Uint64 to Big Endian Conversion 131 | * 132 | * Put a uint64 integer into a Big Endian byte stream 133 | * 134 | * \param[out] Pointer to a 8 byte stream that will be filled with the value 135 | * 136 | * \param[in] The uint64 integer 137 | */ 138 | void put_u64_be(void *val_ptr, const uint64_t val); 139 | #endif /* _BYTE_CONVERT_H */ 140 | -------------------------------------------------------------------------------- /src/esp_hap_acc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #ifndef _HAP_ACC_H_ 26 | #define _HAP_ACC_H_ 27 | 28 | #include 29 | #include 30 | 31 | #ifdef __cplusplus 32 | extern "C"{ 33 | #endif 34 | 35 | typedef struct esp_mfi_accessory { 36 | struct esp_mfi_accessory *next; 37 | uint32_t aid; /* accessory AID */ 38 | hap_serv_t *servs; /* service list */ 39 | bool power_off; 40 | uint32_t next_iid; 41 | hap_identify_routine_t identify_routine; 42 | } __hap_acc_t; 43 | hap_char_t *hap_acc_get_char_by_iid(hap_acc_t *ha, int32_t iid); 44 | hap_acc_t *hap_acc_get_by_aid(int32_t aid); 45 | int hap_acc_get_info(hap_acc_cfg_t *acc_cfg); 46 | const hap_val_t *hap_get_product_data(); 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | #endif /* _HAP_ACC_H_ */ 52 | -------------------------------------------------------------------------------- /src/esp_hap_bct.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | static char *new_name; 35 | 36 | void hap_bct_change_name(const char *name) 37 | { 38 | if (new_name) { 39 | hap_platform_memory_free(new_name); 40 | } 41 | new_name = strdup(name); 42 | hap_send_event(HAP_INTERNAL_EVENT_BCT_CHANGE_NAME); 43 | } 44 | 45 | void hap_bct_hot_plug() 46 | { 47 | hap_send_event(HAP_INTERNAL_EVENT_BCT_HOT_PLUG); 48 | } 49 | 50 | void hap_handle_bct_change_name() 51 | { 52 | if (!new_name) { 53 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_ERR, "No BCT name specified"); 54 | return; 55 | } else { 56 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_INFO, "Changing BCT Name to %s", new_name); 57 | } 58 | if (hap_mdns_serv_name_change(&hap_priv.hap_mdns_handle, new_name) != HAP_SUCCESS) { 59 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_ERR, "Failed to change BCT name"); 60 | } 61 | hap_platform_memory_free(new_name); 62 | new_name = NULL; 63 | } 64 | 65 | void hap_handle_hot_plug() 66 | { 67 | esp_wifi_stop(); 68 | vTaskDelay((10 * 1000) / portTICK_PERIOD_MS); /* Wait for 10 seconds */ 69 | esp_wifi_start(); 70 | esp_wifi_connect(); 71 | } 72 | -------------------------------------------------------------------------------- /src/esp_hap_bct_priv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef _HAP_BCT_PRIV_H_ 25 | #define _HAP_BCT_PRIV_H_ 26 | void hap_handle_bct_change_name(); 27 | void hap_handle_hot_plug(); 28 | #endif /* _HAP_BCT_PRIV_H_ */ 29 | -------------------------------------------------------------------------------- /src/esp_hap_char.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #ifndef _HAP_CHAR_H_ 26 | #define _HAP_CHAR_H_ 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | #define HAP_CHAR_MIN_FLAG (1 << 0) 39 | #define HAP_CHAR_MAX_FLAG (1 << 1) 40 | #define HAP_CHAR_STEP_FLAG (1 << 2) 41 | #define HAP_CHAR_MAXLEN_FLAG (1 << 3) 42 | #define HAP_CHAR_MAXDATALEN_FLAG (1 << 4) 43 | 44 | /** 45 | * @brief characteristics object information 46 | */ 47 | typedef struct { 48 | uint32_t iid; /* Characteristic instance ID */ 49 | const char *type_uuid; /* Apple's characteristic UUID */ 50 | uint16_t permission; /* Characteristic permission */ 51 | hap_char_format_t format; /* data type of the value */ 52 | hap_val_t val; 53 | bool ev; /* check if characteristics supports event */ 54 | char *description; /* characteristics's description */ 55 | char *unit; 56 | 57 | /* Characteristics's father subsystem */ 58 | hap_serv_t *parent; 59 | 60 | uint8_t constraint_flags; 61 | 62 | hap_val_t max; /* maximum value, maxlen, max data len*/ 63 | hap_val_t min; /* minimum value */ 64 | hap_val_t step; /* step value */ 65 | 66 | hap_char_t *next_char; 67 | /* Bitmap to indicate which controllers have enabled notifications 68 | */ 69 | uint16_t ev_ctrls; 70 | 71 | /* Bitmap indicating the last controller that modified the value. 72 | * No notification should be sent to the owner 73 | */ 74 | uint16_t owner_ctrl; 75 | 76 | /* Pointer to a valid values range. It will be a 2 byte array, if set from application */ 77 | uint8_t *valid_vals_range; 78 | /* Since a list of valid values can have any length, using a pointer here, 79 | * which will be allocated if valid values are set for a characteristic 80 | */ 81 | uint8_t *valid_vals; 82 | size_t valid_vals_cnt; 83 | bool update_called; 84 | } __hap_char_t; 85 | 86 | void hap_char_manage_notification(hap_char_t *hc, int index, bool ev); 87 | bool hap_char_is_ctrl_subscribed(hap_char_t *hc, int index); 88 | void hap_char_set_owner_ctrl(hap_char_t *hc, int index); 89 | bool hap_char_is_ctrl_owner(hap_char_t *hc, int index); 90 | void hap_disable_all_char_notif(int index); 91 | int hap_char_check_val_constraints(__hap_char_t *_hc, hap_val_t *val); 92 | int hap_event_queue_init(); 93 | hap_char_t * hap_get_pending_notif_char(); 94 | #ifdef __cplusplus 95 | } 96 | #endif 97 | 98 | #endif /* _HAP_CHAR_H_ */ 99 | -------------------------------------------------------------------------------- /src/esp_hap_controllers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #define HAP_KEYSTORE_NAMESPACE_CTRL "hap_ctrl" 35 | 36 | int hap_controllers_init() 37 | { 38 | memset(hap_priv.controllers, 0, sizeof(hap_priv.controllers)); 39 | char index_str[4]; 40 | uint8_t i; 41 | size_t info_size; 42 | bool acc_paired = false; 43 | for (i = 0; i < HAP_MAX_CONTROLLERS; i++) { 44 | snprintf(index_str, sizeof(index_str), "%d", i); 45 | info_size = sizeof(hap_ctrl_info_t); 46 | if (hap_keystore_get(HAP_KEYSTORE_NAMESPACE_CTRL, index_str, 47 | (uint8_t *)&hap_priv.controllers[i].info, &info_size) == HAP_SUCCESS) { 48 | if (info_size == sizeof(hap_ctrl_info_t)) { 49 | hap_priv.controllers[i].index = i; 50 | hap_priv.controllers[i].valid = true; 51 | acc_paired = true; 52 | } 53 | } 54 | } 55 | if (acc_paired) { 56 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_INFO, "Accessory is Paired with atleast one controller"); 57 | } else { 58 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_INFO, "Accessory is not Paired with any controller"); 59 | } 60 | return HAP_SUCCESS; 61 | } 62 | 63 | hap_ctrl_data_t *hap_controller_get_empty_loc() 64 | { 65 | int i; 66 | for (i = 0; i < HAP_MAX_CONTROLLERS; i++) { 67 | if (!hap_priv.controllers[i].valid) { 68 | hap_priv.controllers[i].index = i; 69 | return &hap_priv.controllers[i]; 70 | } 71 | } 72 | return NULL; 73 | } 74 | 75 | int hap_get_paired_controller_count() 76 | { 77 | int i, cnt = 0; 78 | for (i = 0; i < HAP_MAX_CONTROLLERS; i++) { 79 | if (hap_priv.controllers[i].valid) { 80 | cnt++; 81 | } 82 | } 83 | return cnt; 84 | } 85 | 86 | bool is_accessory_paired() 87 | { 88 | int i; 89 | for (i = 0; i < HAP_MAX_CONTROLLERS; i++) { 90 | if (hap_priv.controllers[i].valid) 91 | return true; 92 | } 93 | return false; 94 | } 95 | 96 | bool is_admin_paired() 97 | { 98 | int i; 99 | for (i = 0; i < HAP_MAX_CONTROLLERS; i++) { 100 | if (hap_priv.controllers[i].valid && hap_priv.controllers[i].info.perms) 101 | return true; 102 | } 103 | return false; 104 | } 105 | 106 | int hap_controller_save(hap_ctrl_data_t *ctrl_data) 107 | { 108 | ctrl_data->valid = true; 109 | char index_str[4]; 110 | snprintf(index_str, sizeof(index_str), "%d", ctrl_data->index); 111 | int ret = hap_keystore_set(HAP_KEYSTORE_NAMESPACE_CTRL, index_str, 112 | (const uint8_t *)&ctrl_data->info, (size_t)sizeof(hap_ctrl_info_t)); 113 | 114 | if (ret != HAP_SUCCESS) { 115 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_ERR, "Failed to store controller %d", ctrl_data->index); 116 | return HAP_FAIL; 117 | } 118 | hap_report_event(HAP_EVENT_CTRL_PAIRED, ctrl_data->info.id, sizeof(ctrl_data->info.id)); 119 | return HAP_SUCCESS; 120 | } 121 | 122 | void hap_controller_remove(hap_ctrl_data_t *ctrl_data) 123 | { 124 | if (!ctrl_data) 125 | return; 126 | char index_str[4]; 127 | snprintf(index_str, sizeof(index_str), "%d", ctrl_data->index); 128 | char id[HAP_CTRL_ID_LEN]; 129 | strncpy(id, ctrl_data->info.id, sizeof(id)); 130 | hap_keystore_delete(HAP_KEYSTORE_NAMESPACE_CTRL, index_str); 131 | memset(ctrl_data, 0, sizeof(hap_ctrl_data_t)); 132 | hap_report_event(HAP_EVENT_CTRL_UNPAIRED, id, sizeof(id)); 133 | } 134 | 135 | hap_ctrl_data_t *hap_get_controller(char *ctrl_id) 136 | { 137 | int i; 138 | for (i = 0; i < HAP_MAX_CONTROLLERS; i++) { 139 | if (hap_priv.controllers[i].valid 140 | && (!strcmp(hap_priv.controllers[i].info.id, ctrl_id))) 141 | return &hap_priv.controllers[i]; 142 | } 143 | return NULL; 144 | } 145 | 146 | void hap_erase_controller_info() 147 | { 148 | hap_keystore_delete_namespace(HAP_KEYSTORE_NAMESPACE_CTRL); 149 | } 150 | -------------------------------------------------------------------------------- /src/esp_hap_controllers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef _HAP_CONTROLLERS_H_ 25 | #define _HAP_CONTROLLERS_H_ 26 | 27 | #include 28 | #include 29 | 30 | #define HAP_MAX_CONTROLLERS 16 31 | #define HAP_CTRL_ID_LEN 64 32 | #define ED_KEY_LEN 32 33 | 34 | 35 | typedef struct { 36 | char id[HAP_CTRL_ID_LEN]; 37 | uint8_t ltpk[ED_KEY_LEN]; 38 | uint8_t perms; 39 | } __attribute__((packed)) hap_ctrl_info_t; 40 | 41 | typedef struct { 42 | hap_ctrl_info_t info; 43 | /* If "valid" is false, it means that the entry is invalid, 44 | * irrespective of the values of other members, and can be 45 | * used to store new controller info 46 | */ 47 | bool valid; 48 | /* Index is used just for better managing the keystore data */ 49 | uint8_t index; 50 | } hap_ctrl_data_t; 51 | 52 | int hap_controllers_init(); 53 | bool is_accessory_paired(); 54 | bool is_admin_paired(); 55 | hap_ctrl_data_t *hap_controller_get_empty_loc(); 56 | int hap_controller_save(hap_ctrl_data_t *ctrl_data); 57 | void hap_controller_remove(hap_ctrl_data_t *ctrl_data); 58 | hap_ctrl_data_t *hap_get_controller(char *ctrl_id); 59 | void hap_erase_controller_info(); 60 | 61 | #endif /* _HAP_CONTROLLERS_H_ */ 62 | -------------------------------------------------------------------------------- /src/esp_hap_database.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef _HAP_DATABASE_H_ 25 | #define _HAP_DATABASE_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #define HAP_KEYSTORE_NAMESPACE_HAPMAIN "hap_main" 35 | #define HAP_FACTORY_NAMESPACE_HAP_SETUP "hap_setup" 36 | 37 | #define HAP_MAX_SESSIONS 8 38 | #define SETUP_ID_LEN 4 39 | #define SETUP_HASH_LEN 4 40 | 41 | #define HAP_ACC_ID_LEN 18 /* AA:BB:CC:XX:YY:ZZ\0 */ 42 | #define ED_KEY_LEN 32 43 | #define HAP_SW_TOKEN_MAX_LEN 1200 44 | 45 | 46 | typedef struct { 47 | hap_acc_cfg_t primary_acc; 48 | uint32_t config_num; 49 | uint32_t cur_aid; 50 | uint8_t raw_acc_id[6]; 51 | char acc_id[HAP_ACC_ID_LEN]; 52 | char setup_id[SETUP_ID_LEN + 1]; 53 | uint8_t setup_hash[SETUP_HASH_LEN]; 54 | char setup_hash_str[SETUP_HASH_LEN * 2 + 1]; 55 | uint8_t ltska[ED_KEY_LEN]; 56 | uint8_t ltpka[ED_KEY_LEN]; 57 | hap_cid_t cid; 58 | hap_ctrl_data_t controllers[HAP_MAX_CONTROLLERS]; 59 | hap_secure_session_t *sessions[HAP_MAX_SESSIONS]; 60 | uint8_t pair_attempts; 61 | hap_mdns_handle_t wac_mdns_handle; 62 | hap_mdns_handle_t hap_mdns_handle; 63 | hap_setup_info_t *setup_info; 64 | char *setup_code; 65 | char *ssid; 66 | char *password; 67 | hap_software_token_info_t *token_info; 68 | uint8_t features; 69 | hap_event_handler_t hap_event_handler; 70 | char *softap_ssid; 71 | void (*ext_nw_prov_start)(void *data, const char *name); 72 | void (*ext_nw_prov_stop)(void *data); 73 | void *ext_nw_prov_data; 74 | hap_cfg_t cfg; 75 | hap_transport_t transport; 76 | uint32_t pairing_flags; 77 | httpd_handle_t server; 78 | uint8_t *product_data; 79 | uint16_t state_num; 80 | bool disconnected_event_sent; 81 | hap_mfi_auth_type_t auth_type; 82 | } hap_priv_t; 83 | 84 | extern hap_priv_t hap_priv; 85 | int hap_database_init(void); 86 | char *hap_get_acc_id(); 87 | int hap_get_next_aid(); 88 | int hap_acc_setup_init(); 89 | void hap_erase_accessory_info(); 90 | void hap_increment_and_save_config_num(); 91 | void hap_increment_and_save_state_num(); 92 | #endif /* _HAP_DATABASE_H_ */ 93 | -------------------------------------------------------------------------------- /src/esp_hap_ip_services.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef _HAP_IP_SERVICES_H_ 25 | #define _HAP_IP_SERVICES_H_ 26 | #include 27 | #include 28 | int hap_http_session_not_authorized(httpd_req_t *req); 29 | int hap_httpd_get_data(httpd_req_t *req, char *buffer, int len); 30 | int hap_httpd_start(); 31 | int hap_ip_services_start(); 32 | int hap_mdns_announce(bool first); 33 | int hap_mdns_deannounce(); 34 | void hap_http_send_notif(); 35 | #endif /* _HAP_IP_SERVICES_H_ */ 36 | -------------------------------------------------------------------------------- /src/esp_hap_keystore.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #include 25 | #include 26 | #include 27 | 28 | static bool keystore_init_done; 29 | static char *hap_platform_nvs_partition; 30 | static char *hap_platform_factory_nvs_partition; 31 | 32 | int hap_keystore_init() 33 | { 34 | if (keystore_init_done) { 35 | return HAP_SUCCESS; 36 | } 37 | 38 | hap_platform_nvs_partition = hap_platform_keystore_get_nvs_partition_name(); 39 | int err = hap_platform_keystore_init_partition(hap_platform_nvs_partition, false); 40 | if (err != 0) { 41 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_ERR, "Error (%d) NVS init failed", err); 42 | return HAP_FAIL; 43 | } 44 | /* Not cheking the return value, as this partition may be absent */ 45 | hap_platform_factory_nvs_partition = hap_platform_keystore_get_factory_nvs_partition_name(); 46 | hap_platform_keystore_init_partition(hap_platform_factory_nvs_partition, true); 47 | 48 | keystore_init_done = true; 49 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_INFO, "Keystore initialised"); 50 | return HAP_SUCCESS; 51 | } 52 | 53 | int __hap_keystore_get(const char *part_name, const char *name_space, const char *key, uint8_t *val, size_t *val_size) 54 | { 55 | if (!keystore_init_done) { 56 | return HAP_FAIL; 57 | } 58 | 59 | int err = hap_platform_keystore_get(part_name, name_space, key, val, val_size); 60 | if (err != 0) { 61 | return HAP_FAIL; 62 | } 63 | return HAP_SUCCESS; 64 | } 65 | int hap_keystore_get(const char *name_space, const char *key, uint8_t *val, size_t *val_size) 66 | { 67 | 68 | return __hap_keystore_get(hap_platform_nvs_partition, name_space, key, val, val_size); 69 | } 70 | int hap_factory_keystore_get(const char *name_space, const char *key, uint8_t *val, size_t *val_size) 71 | { 72 | return __hap_keystore_get(hap_platform_factory_nvs_partition, name_space, key, val, val_size); 73 | } 74 | 75 | int __hap_keystore_set(const char *part_name, const char *name_space, const char *key, const uint8_t *val, const size_t val_len) 76 | 77 | { 78 | if (!keystore_init_done) { 79 | return HAP_FAIL; 80 | } 81 | 82 | int err = hap_platform_keystore_set(part_name, name_space, key, val, val_len); 83 | if (err != 0) { 84 | return HAP_FAIL; 85 | } 86 | return HAP_SUCCESS; 87 | } 88 | 89 | int hap_keystore_set(const char *name_space, const char *key, const uint8_t *val, const size_t val_len) 90 | { 91 | return __hap_keystore_set(hap_platform_nvs_partition, name_space, key, val, val_len); 92 | } 93 | 94 | int hap_factory_keystore_set(const char *name_space, const char *key, const uint8_t *val, const size_t val_len) 95 | { 96 | return __hap_keystore_set(hap_platform_factory_nvs_partition, name_space, key, val, val_len); 97 | } 98 | 99 | int hap_keystore_delete(const char *name_space, const char *key) 100 | { 101 | if (!keystore_init_done) { 102 | return HAP_FAIL; 103 | } 104 | 105 | int err = hap_platform_keystore_delete(hap_platform_nvs_partition, name_space, key); 106 | if (err != 0) { 107 | return HAP_FAIL; 108 | } 109 | return HAP_SUCCESS; 110 | } 111 | 112 | int hap_keystore_delete_namespace(const char *name_space) 113 | { 114 | if (!keystore_init_done) { 115 | return HAP_FAIL; 116 | } 117 | 118 | int err = hap_platform_keystore_delete_namespace(hap_platform_nvs_partition, name_space); 119 | if (err != 0) { 120 | return HAP_FAIL; 121 | } 122 | return HAP_SUCCESS; 123 | } 124 | 125 | void hap_keystore_erase_all_data() 126 | { 127 | hap_platfrom_keystore_erase_partition(hap_platform_nvs_partition); 128 | } 129 | -------------------------------------------------------------------------------- /src/esp_hap_keystore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef _HAP_KEYSTORE_H_ 25 | #define _HAP_KEYSTORE_H_ 26 | #include 27 | int hap_keystore_init(); 28 | int hap_keystore_get(const char *name_space, const char *key, uint8_t *val, size_t *val_size); 29 | int hap_keystore_set(const char *name_space, const char *key, const uint8_t *val, const size_t val_len); 30 | int hap_keystore_delete(const char *name_space, const char *key); 31 | int hap_keystore_delete_namespace(const char *name_space); 32 | int hap_factory_keystore_set(const char *name_space, const char *key, const uint8_t *val, const size_t val_len); 33 | void hap_keystore_erase_all_data(); 34 | #endif /* _HAP_KEYSTORE_H_ */ 35 | -------------------------------------------------------------------------------- /src/esp_hap_main.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #ifndef _HAP_MAIN_LOOP_H_ 26 | #define _HAP_MAIN_LOOP_H_ 27 | #include 28 | #include 29 | 30 | #define HAP_FF_HARDWARE_AUTH 0x01 31 | #define HAP_FF_SW_TOKEN_AUTH 0x02 32 | 33 | 34 | #define HAP_SF_ACC_UNPAIRED 0x01 35 | #define HAP_SF_ACC_UNCONFIGURED 0x02 36 | #define HAP_SF_PROBLEM_DETECTED 0x04 37 | 38 | typedef enum { 39 | HAP_INTERNAL_EVENT_LOOP_STOP = 1, 40 | HAP_INTERNAL_EVENT_ACC_PAIRED, 41 | HAP_INTERNAL_EVENT_ACC_UNPAIRED, 42 | HAP_INTERNAL_EVENT_CONFIG_NUM_UPDATED, 43 | HAP_INTERNAL_EVENT_BCT_CHANGE_NAME, 44 | HAP_INTERNAL_EVENT_BCT_HOT_PLUG, 45 | HAP_INTERNAL_EVENT_RESET_PAIRINGS, 46 | HAP_INTERNAL_EVENT_RESET_TO_FACTORY, 47 | HAP_INTERNAL_EVENT_REBOOT, 48 | HAP_INTERNAL_EVENT_RESET_NETWORK, 49 | HAP_INTERNAL_EVENT_TRIGGER_NOTIF, 50 | HAP_INTERNAL_EVENT_RESET_HOMEKIT_DATA, 51 | } hap_internal_event_t; 52 | 53 | typedef struct { 54 | hap_internal_event_t event; 55 | } hap_event_ctx_t; 56 | 57 | typedef enum { 58 | HAP_STATE_NONE = 0, 59 | HAP_STATE_NW_UNCONFIGURED, 60 | HAP_STATE_NW_CONFIGURED, 61 | } hap_state_t; 62 | 63 | int hap_loop_start(); 64 | int hap_loop_stop(); 65 | int hap_send_event(hap_internal_event_t event); 66 | int hap_update_config_number(); 67 | bool is_hap_loop_started(); 68 | void hap_report_event(hap_event_t event, void *data, size_t data_size); 69 | int hap_enable_hw_auth(void); 70 | int hap_enable_sw_auth(void); 71 | 72 | #endif /* _HAP_MAIN_LOOP_H_ */ 73 | -------------------------------------------------------------------------------- /src/esp_hap_mdns.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #include 25 | #include 26 | #include 27 | 28 | static bool mdns_init_done; 29 | 30 | int hap_mdns_serv_start(hap_mdns_handle_t *handle, const char *name, const char *type, 31 | const char *protocol, int port, mdns_txt_item_t *txt_records, size_t num_txt) 32 | { 33 | strcpy(handle->type, type); 34 | strcpy(handle->proto, protocol); 35 | if (mdns_service_add(name, type, protocol, port, txt_records, num_txt) != 0) { 36 | return HAP_FAIL; 37 | } 38 | return HAP_SUCCESS; 39 | } 40 | 41 | int hap_mdns_serv_update_txt(hap_mdns_handle_t *handle, mdns_txt_item_t *txt_records, size_t num_txt) 42 | { 43 | if (mdns_service_txt_set(handle->type, handle->proto, txt_records, num_txt) != 0) { 44 | return HAP_FAIL; 45 | } 46 | return HAP_SUCCESS; 47 | } 48 | 49 | int hap_mdns_serv_name_change(hap_mdns_handle_t *handle, const char * instance_name) 50 | { 51 | if (mdns_service_instance_name_set(handle->type, handle->proto, instance_name) == ESP_OK) { 52 | return HAP_SUCCESS; 53 | } 54 | return HAP_FAIL; 55 | } 56 | 57 | int hap_mdns_serv_stop(hap_mdns_handle_t *handle) 58 | { 59 | if (mdns_service_remove(handle->type, handle->proto) == ESP_OK) { 60 | return HAP_SUCCESS; 61 | } 62 | return HAP_FAIL; 63 | } 64 | 65 | int hap_mdns_init() 66 | { 67 | int ret = HAP_SUCCESS; 68 | if (!mdns_init_done) { 69 | ret = mdns_init(); 70 | if (ret == ESP_OK) { 71 | mdns_hostname_set("MyHost"); 72 | mdns_init_done = true; 73 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_INFO, "mDNS initialised"); 74 | return HAP_SUCCESS; 75 | } 76 | } 77 | return HAP_FAIL; 78 | } 79 | 80 | int hap_mdns_deinit() 81 | { 82 | mdns_free(); 83 | mdns_init_done = false; 84 | return HAP_SUCCESS; 85 | } 86 | -------------------------------------------------------------------------------- /src/esp_hap_mdns.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef _HAP_MDNS_H_ 25 | #define _HAP_MDNS_H_ 26 | 27 | #include 28 | #include 29 | 30 | typedef struct { 31 | char type[32]; 32 | char proto[32]; 33 | } hap_mdns_handle_t; 34 | 35 | int hap_mdns_serv_start(hap_mdns_handle_t *handle, const char *name, const char *type, 36 | const char *protocol, int port, mdns_txt_item_t *txt_records, size_t num_txt); 37 | int hap_mdns_serv_update_txt(hap_mdns_handle_t *handle, mdns_txt_item_t *txt_records, size_t num_txt); 38 | int hap_mdns_serv_name_change(hap_mdns_handle_t *handle, const char * instance_name); 39 | int hap_mdns_serv_stop(hap_mdns_handle_t *handle); 40 | int hap_mdns_init(); 41 | int hap_mdns_deinit(); 42 | 43 | #endif /* _HAP_MDNS_H_ */ 44 | -------------------------------------------------------------------------------- /src/esp_hap_network_io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef _HAP_NETWORK_IO_H_ 25 | #define _HAP_NETWORK_IO_H_ 26 | #include 27 | #include 28 | int hap_httpd_send(httpd_handle_t hd, int sockfd, const char *buf, unsigned buf_len, int flags); 29 | int hap_httpd_recv(httpd_handle_t hd, int sockfd, char *buf, unsigned buf_len, int flags); 30 | 31 | #endif /* _HAP_NETWORK_IO_H_ */ 32 | -------------------------------------------------------------------------------- /src/esp_hap_pair_common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | void hap_tlv_data_init(hap_tlv_data_t *tlv_data, uint8_t *buf, int buf_size) 30 | { 31 | tlv_data->bufptr = buf; 32 | tlv_data->bufsize = buf_size; 33 | tlv_data->curlen = 0; 34 | } 35 | 36 | int get_tlv_length(uint8_t *buf, int buflen, uint8_t type) 37 | { 38 | if (!buf ) 39 | return -1; 40 | int curlen = 0; 41 | int val_len = 0; 42 | bool found = false; 43 | while (buflen > 0) { 44 | if (buf[curlen] == type) { 45 | uint8_t len = buf[curlen + 1]; 46 | if ((buflen - len) < 2) 47 | return -1; 48 | val_len += len; 49 | if (len < 255) 50 | return val_len; 51 | else 52 | found = true; 53 | 54 | } else if (found) 55 | return val_len; 56 | 57 | /* buf[curlen +1] will give the Length */ 58 | buflen -= (2 + buf[curlen + 1]); 59 | curlen += (2 + buf[curlen + 1]); 60 | } 61 | return -1; 62 | } 63 | int get_value_from_tlv(uint8_t *buf, int buflen, uint8_t type, void *val, int val_size) 64 | { 65 | if (!buf || !val) 66 | return -1; 67 | int curlen = 0; 68 | int val_len = 0; 69 | bool found = false; 70 | while (buflen > 0) { 71 | if (buf[curlen] == type) { 72 | uint8_t len = buf[curlen + 1]; 73 | if ((val_size < len) || ((buflen - len) < 2)) 74 | return -1; 75 | memcpy(val + val_len, &buf[curlen + 2], len); 76 | val_len += len; 77 | val_size -= len; 78 | if (len < 255) 79 | return val_len; 80 | else 81 | found = true; 82 | 83 | } else if (found) 84 | return val_len; 85 | 86 | /* buf[curlen +1] will give the Length */ 87 | buflen -= (2 + buf[curlen + 1]); 88 | curlen += (2 + buf[curlen + 1]); 89 | } 90 | return -1; 91 | } 92 | 93 | int add_tlv(hap_tlv_data_t *tlv_data, uint8_t type, int len, void *val) 94 | { 95 | if(!tlv_data->bufptr || ((len + 2) > (tlv_data->bufsize - tlv_data->curlen))) 96 | return -1; 97 | uint8_t *buf_ptr = (uint8_t *)val; 98 | int orig_len = tlv_data->curlen; 99 | do { 100 | tlv_data->bufptr[tlv_data->curlen++] = type; 101 | int tmp_len; 102 | if (len > 255) 103 | tmp_len = 255; 104 | else 105 | tmp_len = len; 106 | tlv_data->bufptr[tlv_data->curlen++] = tmp_len; 107 | memcpy(&tlv_data->bufptr[tlv_data->curlen], buf_ptr, tmp_len); 108 | tlv_data->curlen += tmp_len; 109 | buf_ptr += tmp_len; 110 | len -= tmp_len; 111 | } while (len); 112 | return tlv_data->curlen - orig_len; 113 | } 114 | void hap_prepare_error_tlv(uint8_t state, uint8_t error, void *buf, int bufsize, int *outlen) 115 | { 116 | hap_tlv_data_t tlv_data; 117 | tlv_data.bufptr = buf; 118 | tlv_data.bufsize = bufsize; 119 | tlv_data.curlen = 0; 120 | /* Not doing any error handling because the size required for "state" and "error" will 121 | * be too small to cause any error, and we anyways dont have any specific action to 122 | * do in case if error in add_tlv() 123 | */ 124 | add_tlv(&tlv_data, kTLVType_State, sizeof(state), &state); 125 | add_tlv(&tlv_data, kTLVType_Error, sizeof(error), &error); 126 | *outlen = tlv_data.curlen; 127 | } 128 | -------------------------------------------------------------------------------- /src/esp_hap_pair_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef _HAP_PAIR_COMMON_H_ 25 | #define _HAP_PAIR_COMMON_H_ 26 | 27 | #include 28 | #include 29 | #define ENCRYPT_KEY_LEN 32 30 | #define POLY_AUTHTAG_LEN 16 31 | #define CURVE_KEY_LEN 32 32 | #define ED_SIGN_LEN 64 33 | #define NONCE_LEN 8 34 | 35 | #define STATE_M0 0 36 | #define STATE_M1 1 37 | #define STATE_M2 2 38 | #define STATE_M3 3 39 | #define STATE_M4 4 40 | #define STATE_M5 5 41 | #define STATE_M6 6 42 | #define STATE_VERIFIED 0x55 43 | #define STATE_INVALID 0xaa 44 | 45 | typedef enum { 46 | HAP_METHOD_RESERVED = 0, 47 | HAP_METHOD_PAIR_SETUP = 1, 48 | HAP_METHOD_PAIR_VERIFY = 2, 49 | HAP_METHOD_ADD_PAIRING = 3, 50 | HAP_METHOD_REMOVE_PAIRING = 4, 51 | HAP_METHOD_LIST_PAIRINGS = 5, 52 | } hap_pairing_methods_t; 53 | 54 | 55 | typedef enum { 56 | kTLVError_Unknown = 0x01, 57 | kTLVError_Authentication = 0x02, 58 | kTLVError_Backoff = 0x03, 59 | kTLVError_MaxPeers = 0x04, 60 | kTLVError_MaxTries = 0x05, 61 | kTLVError_Unavailable = 0x06, 62 | kTLVError_Busy = 0x07, 63 | } hap_tlv_error_t; 64 | 65 | typedef enum { 66 | kTLVType_Method = 0x00, 67 | kTLVType_Identifier = 0x01, 68 | kTLVType_Salt = 0x02, 69 | kTLVType_PublicKey = 0x03, 70 | kTLVType_Proof = 0x04, 71 | kTLVType_EncryptedData = 0x05, 72 | kTLVType_State = 0x06, 73 | kTLVType_Error = 0x07, 74 | kTLVType_RetryDelay = 0x08, 75 | kTLVType_Certificate = 0x09, 76 | kTLVType_Signature = 0x0a, 77 | kTLVType_Permissions = 0x0b, 78 | kTLVType_FragmentedData = 0x0c, 79 | kTLVType_FragmentLast = 0x0d, 80 | kTLVType_Flags = 0x13, 81 | kTLVType_OwnershipProofToken = 0x1A, 82 | kTLVType_ProductData = 0x1C, 83 | kTLVType_Separator = 0xff, 84 | } hap_tlv_type_t; 85 | 86 | typedef struct { 87 | uint8_t *bufptr; 88 | int bufsize; 89 | int curlen; 90 | } hap_tlv_data_t; 91 | 92 | typedef struct { 93 | uint8_t state; 94 | uint8_t encrypt_key[ENCRYPT_KEY_LEN]; 95 | uint8_t decrypt_key[ENCRYPT_KEY_LEN]; 96 | uint8_t encrypt_nonce[NONCE_LEN]; 97 | uint8_t decrypt_nonce[NONCE_LEN]; 98 | hap_ctrl_data_t *ctrl; 99 | uint64_t pid; 100 | int64_t ttl; 101 | int64_t prepare_time; 102 | /* TODO: As of now, this identifier will be the socket 103 | * number, since only http is supported. 104 | * Need to make this generic later. 105 | */ 106 | int conn_identifier; 107 | } hap_secure_session_t; 108 | 109 | void hap_tlv_data_init(hap_tlv_data_t *tlv_data, uint8_t *buf, int buf_size); 110 | int get_value_from_tlv(uint8_t *buf, int buf_len, uint8_t type, void *val, int val_size); 111 | int get_tlv_length(uint8_t *buf, int buflen, uint8_t type); 112 | int add_tlv(hap_tlv_data_t *tlv_data, uint8_t type, int len, void *val); 113 | void hap_prepare_error_tlv(uint8_t state, uint8_t error, void *buf, int buf_size, int *out_len); 114 | #endif /* _HAP_PAIR_COMMON_H_ */ 115 | -------------------------------------------------------------------------------- /src/esp_hap_pair_setup.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef _HAP_PAIR_SETUP_H_ 25 | #define _HAP_PAIR_SETUP_H_ 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #define PS_NONCE1 "PS-Msg04" 33 | #define PS_NONCE2 "PS-Msg05" 34 | #define PS_NONCE3 "PS-Msg06" 35 | 36 | #define PAIR_FLAG_TRANSIENT 0x00000010 37 | #define PAIR_FLAG_SPLIT 0x01000000 38 | 39 | 40 | typedef struct { 41 | uint8_t state; 42 | uint8_t method; 43 | uint32_t pairing_flags; 44 | int8_t pairing_flags_len; 45 | int len_s; 46 | char *bytes_s; 47 | int secret_len; 48 | char *shared_secret; 49 | mu_srp_handle_t srp_hd; 50 | hap_ctrl_data_t *ctrl; 51 | uint8_t session_key[32]; 52 | TimerHandle_t timer; 53 | hap_secure_session_t *session; 54 | int sock_fd; 55 | } pair_setup_ctx_t; 56 | int hap_pair_setup_context_init(int sock_fd, void **ctx, uint8_t *buf, int bufsize, int *outlen); 57 | int hap_pair_setup_process(void **ctx, uint8_t *buf, int inlen, int bufsize, int *outlen); 58 | void hap_pair_setup_ctx_clean(void *sess_ctx); 59 | int hap_pair_setup_manage_mfi_auth(pair_setup_ctx_t *ps_ctx, hap_tlv_data_t *tlv_data, hap_tlv_error_t *tlv_error); 60 | #endif /* _HAP_PAIR_SETUP_H_ */ 61 | -------------------------------------------------------------------------------- /src/esp_hap_pair_verify.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef _HAP_PAIR_VERIFY_H_ 25 | #define _HAP_PAIR_VERIFY_H_ 26 | #include 27 | #include 28 | int hap_pair_verify_context_init(void **ctx, uint8_t *buf, int bufsize, int *outlen); 29 | int hap_pair_verify_process(void **ctx, uint8_t *buf, int inlen, int bufsize, int *outlen); 30 | uint8_t hap_pair_verify_get_state(void *ctx); 31 | void hap_free_session(void *session); 32 | int hap_get_ctrl_session_index(hap_secure_session_t *session); 33 | void hap_close_ctrl_sessions(hap_ctrl_data_t *ctrl); 34 | void hap_close_all_sessions(); 35 | #endif /* _HAP_PAIR_VERIFY_H_ */ 36 | -------------------------------------------------------------------------------- /src/esp_hap_pairings.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef _HAP_PAIRINGS_H_ 25 | #define _HAP_PAIRINGS_H_ 26 | #include 27 | int hap_pairings_process(void *ctx, uint8_t *buf, int inlen, int bufsize, int *outlen); 28 | bool hap_is_req_secure(hap_secure_session_t *session); 29 | #endif /* _HAP_PAIRINGS_H_ */ 30 | -------------------------------------------------------------------------------- /src/esp_hap_secure_message.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef _HAP_SECURE_MESSAGE_H_ 25 | #define _HAP_SECURE_MESSAGE_H_ 26 | #include 27 | #include 28 | /** Information for Software Token based authentication. 29 | * To be used only if MFi chip is not present on the accessory 30 | */ 31 | typedef struct { 32 | /** UUID for the accessory */ 33 | uint8_t uuid[16]; 34 | /** Token associated with the UUID */ 35 | uint8_t *token; 36 | /* Length of the above token */ 37 | size_t token_len; 38 | } hap_software_token_info_t; 39 | 40 | int hap_register_secure_message_handler(httpd_handle_t handle); 41 | int hap_unregister_secure_message_handler(httpd_handle_t handle); 42 | #endif /* _HAP_SECURE_MESSAGE_H_ */ 43 | -------------------------------------------------------------------------------- /src/esp_hap_serv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #ifndef _HAP_SERV_H_ 26 | #define _HAP_SERV_H_ 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | typedef struct hap_linked_serv { 37 | hap_serv_t *hs; 38 | struct hap_linked_serv *next; 39 | } hap_linked_serv_t; 40 | 41 | typedef struct hap_linked_serv hap_linked_serv_t; 42 | 43 | /** 44 | * HAP service information 45 | */ 46 | typedef struct { 47 | char *type_uuid; /* String that defines the type of the service. */ 48 | 49 | uint32_t iid; /* service instance ID */ 50 | 51 | bool hidden; /* If set it to be True, the service is not visible to user. */ 52 | bool primary; /* If set it to be True, this is the primary service of the accessory. */ 53 | 54 | /** 55 | * List of Characteristic objects. Must not be empty. The maximum number of characteristics 56 | * allowed is 100, and each characteristic in the array must have a unique type. 57 | */ 58 | hap_char_t *chars; 59 | hap_acc_t *parent; 60 | hap_serv_t *next_serv; 61 | 62 | hap_serv_write_t write_cb; 63 | hap_serv_read_t read_cb; 64 | hap_serv_bulk_read_t bulk_read; 65 | hap_linked_serv_t *linked_servs; 66 | void *priv; 67 | } __hap_serv_t; 68 | 69 | bool hap_serv_get_hidden(hap_serv_t *hs); 70 | bool hap_serv_get_primary(hap_serv_t *hs); 71 | hap_char_t *hap_serv_get_char_by_iid(hap_serv_t *hs, int32_t iid); 72 | char *hap_serv_get_uuid(hap_serv_t *hs); 73 | hap_serv_t *hap_serv_create(char *type_uuid); 74 | void hap_serv_delete(hap_serv_t *hs); 75 | int hap_serv_add_char(hap_serv_t *hs, hap_char_t *hc); 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif /* _HAP_SERV_H_ */ 81 | -------------------------------------------------------------------------------- /src/esp_hap_setup_payload.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | static const char *TAG = "esp_hap_setup_payload"; 33 | 34 | #define SETUP_CODE_MASK 0x0000000007ffffff 35 | #define HAP_OVER_IP_MASK 0x0000000010000000 36 | #define WAC_MASK 0x0000000040000000 37 | #define SETUP_PAYLOAD_PREFIX "X-HM://00" 38 | 39 | static void remove_chars(char *str, char c) 40 | { 41 | int i = 0, j = 0; 42 | while(str[i]) { 43 | if (str[i] != c) { 44 | str[j] = str[i]; 45 | j++; 46 | } 47 | i++; 48 | } 49 | str[j] = 0; 50 | } 51 | 52 | char *esp_hap_get_setup_payload(char *setup_code, char *setup_id, bool wac_support, hap_cid_t cid) 53 | { 54 | if (!setup_code || !setup_id) { 55 | ESP_LOGE(TAG, "Setup code or Setup ID cannot be NULL"); 56 | return NULL; 57 | } 58 | uint64_t payload = 0; 59 | if (strlen(setup_code) != 10 || strlen(setup_id) != 4) { 60 | ESP_LOGE(TAG, "Setup code or Setup ID not correct. Eg. 111-22-333, ES32"); 61 | return NULL; 62 | } 63 | char setup_code_copy[11]; 64 | strcpy(setup_code_copy, setup_code); 65 | remove_chars(setup_code_copy, '-'); 66 | int64_t code = atoi(setup_code_copy); 67 | int64_t category = cid; 68 | category <<= 31; 69 | 70 | payload |= code; 71 | payload |= category; 72 | payload |= HAP_OVER_IP_MASK; 73 | if (wac_support) { 74 | payload |= WAC_MASK; 75 | } 76 | char *base36_str = base36_to_str(payload); 77 | char setup_payload[24]; 78 | snprintf(setup_payload, sizeof(setup_payload), "%s%s%s", SETUP_PAYLOAD_PREFIX, base36_str, setup_id); 79 | free(base36_str); 80 | return strdup(setup_payload); 81 | } 82 | -------------------------------------------------------------------------------- /src/esp_hap_wac.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #ifndef _HAP_WAC_H_ 26 | #define _HAP_WAC_H_ 27 | int hap_wac_start(void); 28 | int hap_wac2_network_switch(void); 29 | int hap_wac2_finish(void); 30 | int hap_wac2_stop(void); 31 | bool hap_is_mfi_auth_enabled(); 32 | #endif /* _HAP_WAC_H_ */ 33 | -------------------------------------------------------------------------------- /src/esp_hap_wifi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | esp_err_t hap_wifi_is_provisioned(bool *provisioned) 31 | { 32 | if (!provisioned) { 33 | return ESP_ERR_INVALID_ARG; 34 | } 35 | 36 | *provisioned = false; 37 | 38 | /* Get Wi-Fi Station configuration */ 39 | wifi_config_t wifi_cfg; 40 | if (esp_wifi_get_config(ESP_IF_WIFI_STA, &wifi_cfg) != ESP_OK) { 41 | return ESP_FAIL; 42 | } 43 | 44 | if (strlen((const char *) wifi_cfg.sta.ssid)) { 45 | *provisioned = true; 46 | } 47 | return ESP_OK; 48 | } 49 | bool hap_is_network_configured(void) 50 | { 51 | /* If only the Ethernet is enabled, return true */ 52 | if (hap_priv.transport == HAP_TRANSPORT_ETHERNET) { 53 | return true; 54 | } 55 | 56 | bool provisioned = false; 57 | hap_wifi_is_provisioned(&provisioned); 58 | return provisioned; 59 | } 60 | 61 | void hap_erase_network_info(void) 62 | { 63 | esp_wifi_restore(); 64 | } 65 | 66 | esp_err_t hap_wifi_softap_start(char *ssid) 67 | { 68 | if (!ssid) { 69 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_ERR, "SSID cannot be NULL"); 70 | } 71 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_INFO, "Starting SoftAP with SSID: %s", ssid); 72 | wifi_config_t wifi_config = { 73 | .ap = { 74 | .ssid = "", 75 | .ssid_len = 0, 76 | .max_connection = 4, 77 | .password = "", 78 | .authmode = WIFI_AUTH_OPEN 79 | }, 80 | }; 81 | size_t ssid_len = strnlen(ssid, sizeof(wifi_config.ap.ssid)); 82 | memcpy(wifi_config.ap.ssid, ssid, ssid_len); 83 | wifi_mode_t mode; 84 | esp_wifi_get_mode(&mode); 85 | if (mode == WIFI_MODE_STA) { 86 | esp_wifi_set_mode(WIFI_MODE_APSTA); 87 | } else { 88 | esp_wifi_set_mode(WIFI_MODE_AP); 89 | } 90 | esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config); 91 | esp_wifi_start(); 92 | return ESP_OK; 93 | } 94 | 95 | esp_err_t hap_wifi_softap_stop(void) 96 | { 97 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_INFO, "Stopping SoftAP."); 98 | wifi_mode_t mode; 99 | esp_wifi_get_mode(&mode); 100 | if (mode == WIFI_MODE_AP) { 101 | esp_wifi_stop(); 102 | } 103 | esp_wifi_set_mode(WIFI_MODE_STA); 104 | return ESP_OK; 105 | } 106 | 107 | esp_err_t hap_wifi_sta_connect(wifi_config_t *config) 108 | { 109 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_INFO, "Connecting to Wi-Fi."); 110 | wifi_mode_t mode; 111 | esp_wifi_get_mode(&mode); 112 | if (mode == WIFI_MODE_AP || mode == WIFI_MODE_APSTA) { 113 | esp_wifi_set_mode(WIFI_MODE_APSTA); 114 | } else { 115 | esp_wifi_set_mode(WIFI_MODE_STA); 116 | } 117 | esp_wifi_set_config(ESP_IF_WIFI_STA, config); 118 | esp_wifi_start(); 119 | esp_wifi_connect(); 120 | return ESP_OK; 121 | } 122 | -------------------------------------------------------------------------------- /src/esp_hap_wifi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef _HAP_WIFI_H_ 25 | #define _HAP_WIFI_H_ 26 | #include 27 | bool hap_is_network_configured(); 28 | void hap_wifi_restart(); 29 | void hap_erase_network_info(); 30 | #endif /* _HAP_WIFI_H_ */ 31 | -------------------------------------------------------------------------------- /src/esp_mfi_aes.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include "mbedtls/aes.h" 30 | #include "esp_log.h" 31 | 32 | #include "esp_mfi_aes.h" 33 | 34 | static const char* TAG = "mfi_aes_adapter"; 35 | 36 | /*! 37 | * @group AES 128-bit Counter Mode API 38 | 39 | * @abstract API to encrypt or decrypt using AES-128 in counter mode. 40 | * 41 | * Call esp_mfi_aes_ctr_init to initialize the context. Don't use the context until it has been initialized. 42 | * Call esp_mfi_aes_ctr_update to encrypt or decrypt N bytes of input and generate N bytes of output. 43 | * Call esp_mfi_aes_ctr_final to finalize the context. After finalizing, you must call AES_CTR_Init to use it again. 44 | */ 45 | 46 | typedef struct { 47 | uint8_t key[MFI_AES_CTR_SIZE]; 48 | uint8_t nonce[MFI_AES_CTR_SIZE]; 49 | } aes_ctr_context_t; 50 | 51 | /** 52 | * @bref Create AES context 53 | * 54 | * @param none 55 | * 56 | * @return the AES context point 57 | */ 58 | esp_mfi_aes_ctr_t esp_mfi_aes_ctr_new(void) 59 | { 60 | aes_ctr_context_t *context = NULL; 61 | context = (aes_ctr_context_t *) malloc(sizeof(aes_ctr_context_t)); 62 | return context; 63 | } 64 | 65 | /** 66 | * @bref Initialize AES context, include initialize the key and nonce 67 | * 68 | * @param incontext AES context point 69 | * inkey AES key 70 | * innonce AES nonce 71 | * 72 | * @return the result 73 | * 0 : sucessful 74 | * others : failed 75 | */ 76 | int esp_mfi_aes_ctr_init(esp_mfi_aes_ctr_t incontext, const uint8_t inkey[MFI_AES_CTR_SIZE], const uint8_t innonce[MFI_AES_CTR_SIZE]) 77 | { 78 | int ret = 0; 79 | 80 | if (incontext == NULL) 81 | return -EINVAL; 82 | 83 | aes_ctr_context_t *context = incontext; 84 | 85 | memcpy(context->key, inkey, MFI_AES_CTR_SIZE); 86 | memcpy(context->nonce, innonce, MFI_AES_CTR_SIZE); 87 | 88 | return ret; 89 | } 90 | 91 | /** 92 | * @bref Update AES context 93 | * 94 | * @param incontext AES context point 95 | * insrc the data point of update 96 | * insrclen the data length 97 | * indst the data pint of output 98 | * 99 | * @return the result 100 | * 0 : sucessful 101 | * others : failed 102 | */ 103 | int esp_mfi_aes_ctr_update(esp_mfi_aes_ctr_t incontext, const void *insrc, uint16_t insrclen, void *indst) 104 | { 105 | int ret = 0; 106 | 107 | if (incontext == NULL) 108 | return -EINVAL; 109 | 110 | aes_ctr_context_t *context = incontext; 111 | size_t offset = 0; 112 | uint8_t stream_block[MFI_AES_CTR_SIZE]; 113 | mbedtls_aes_context ctx; 114 | mbedtls_aes_init(&ctx); 115 | 116 | ret = mbedtls_aes_setkey_enc( &ctx, context->key, 128); 117 | 118 | if (ret != 0) { 119 | ESP_LOGE(TAG, "mfi aes setkey[%d]", ret); 120 | ret = -EINVAL; 121 | } else { 122 | ret = mbedtls_aes_crypt_ctr(&ctx, insrclen, &offset, context->nonce, stream_block, (uint8_t *) insrc, indst); 123 | if (ret != 0) { 124 | ESP_LOGE(TAG, "mfi aes crypt[%d]", ret); 125 | ret = -EINVAL; 126 | } 127 | } 128 | 129 | return ret; 130 | } 131 | 132 | /** 133 | * @bref Destory AES context point 134 | * 135 | * @param incontext AES context point 136 | * 137 | * @return none 138 | */ 139 | void esp_mfi_aes_ctr_final(esp_mfi_aes_ctr_t incontext) 140 | { 141 | if (incontext) { 142 | memset((aes_ctr_context_t *) incontext, 0, sizeof(aes_ctr_context_t)); 143 | free(incontext); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/esp_mfi_aes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef ESP_MFI_AES_H_ 25 | #define ESP_MFI_AES_H_ 26 | 27 | #include 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | #define MFI_AES_CTR_SIZE 16 34 | 35 | typedef void* esp_mfi_aes_ctr_t; 36 | 37 | /** 38 | * @brief Create AES context 39 | * 40 | * @return pointer of the AES context 41 | */ 42 | esp_mfi_aes_ctr_t esp_mfi_aes_ctr_new(void); 43 | 44 | /** 45 | * @brief Initialize AES context, including the key and nonce 46 | * 47 | * @param incontext pointer of the AES context 48 | * @param inkey AES key 49 | * @param innonce AES nonce 50 | * 51 | * @return 52 | * - 0 : succeed 53 | * - others : fail 54 | */ 55 | int esp_mfi_aes_ctr_init(esp_mfi_aes_ctr_t incontext, const uint8_t inkey[MFI_AES_CTR_SIZE], const uint8_t innonce[MFI_AES_CTR_SIZE]); 56 | 57 | /** 58 | * @brief Update AES context 59 | * 60 | * @param incontext AES context point 61 | * @param insrc pointer of the source data to be updated 62 | * @param insrclen source data length 63 | * @param indst pointer of the updated data 64 | * 65 | * @return 66 | * - 0 : succeed 67 | * - others : fail 68 | */ 69 | int esp_mfi_aes_ctr_update(esp_mfi_aes_ctr_t incontext, const void *insrc, uint16_t insrclen, void *indst); 70 | 71 | /** 72 | * @brief Destroy AES context pointer 73 | * 74 | * @param incontext pointer of the AES context 75 | */ 76 | void esp_mfi_aes_ctr_final(esp_mfi_aes_ctr_t incontext); 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | 82 | #endif /* ESP_MFI_AES_H_ */ 83 | -------------------------------------------------------------------------------- /src/esp_mfi_base64.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #include 26 | 27 | #include "mbedtls/base64.h" 28 | 29 | /** 30 | * @brief transform bin data to base64 data 31 | */ 32 | int esp_mfi_base64_encode(const char *src, int len, char *dest, int dest_len, int *out_len) 33 | { 34 | int ret = mbedtls_base64_encode((unsigned char *)dest, dest_len, (size_t *)out_len, (unsigned char *)src, len); 35 | if (ret != 0){ 36 | return -EINVAL; 37 | } else{ 38 | return 0; 39 | } 40 | } 41 | 42 | /** 43 | * @brief transform base64 data to bin data 44 | */ 45 | int esp_mfi_base64_decode(const char *src, int len, char *dest, int dest_len, int *out_len) 46 | { 47 | int ret = 0; 48 | ret = mbedtls_base64_decode((unsigned char *)dest, dest_len, (size_t *)out_len, (unsigned char *)src, len); 49 | if (ret != 0) { 50 | return -EINVAL; 51 | } else { 52 | return 0; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/esp_mfi_base64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef ESP_MFI_BASE64_H_ 25 | #define ESP_MFI_BASE64_H_ 26 | 27 | #include 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /** 34 | * @brief transform bin data to base64 data 35 | * 36 | * @param src input data point 37 | * @param len input data length 38 | * @param dest output data point 39 | * @param dest_len output data buffer length 40 | * @param out_len output data length 41 | * 42 | * @return 43 | * - 0 : succeed 44 | * - others : fail 45 | */ 46 | int esp_mfi_base64_encode(const char *src, int len, char *dest, int dest_len, int *out_len); 47 | 48 | /** 49 | * @brief transform base64 data to bin data 50 | * 51 | * @param src input data point 52 | * @param len input data length 53 | * @param dest output data point 54 | * @param dest_len output data buffer length 55 | * @param out_len output data length 56 | * 57 | * @return 58 | * - 0 : succeed 59 | * - others : fail 60 | */ 61 | int esp_mfi_base64_decode(const char *src, int len, char *dest, int dest_len, int *out_len); 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | #endif /* ESP_MFI_BASE64_H_ */ 68 | -------------------------------------------------------------------------------- /src/esp_mfi_debug.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #define RED_CHAR 31 30 | #define GREEN_CHAR 32 31 | #define YELLOW_CHAR 33 32 | #define BLUE_CHAR 34 33 | #define CYAN_CHAR 36 34 | #define WHITE_CHAR 37 35 | 36 | #ifdef CONFIG_MFI_DEBUG_LEVEL_INIT 37 | #define MFI_DEBUG_LEVEL_INIT CONFIG_MFI_DEBUG_LEVEL_INIT 38 | #else /* CONFIG_MFI_DEBUG_LEVEL_INIT */ 39 | #define MFI_DEBUG_LEVEL_INIT 0 40 | #endif /* CONFIG_MFI_DEBUG_LEVEL_INIT */ 41 | 42 | static uint32_t mfi_debug_level = MFI_DEBUG_LEVEL_INIT; 43 | 44 | /** 45 | * @bref set the MFI debugging level 46 | */ 47 | int esp_mfi_set_debug_level(uint32_t level) 48 | { 49 | mfi_debug_level = level; 50 | return 0; 51 | } 52 | 53 | /** 54 | * @bref get the MFI debugging level and output data color 55 | */ 56 | uint32_t esp_mfi_get_debug_level(uint32_t level, uint32_t *color) 57 | { 58 | const uint32_t prospect_table[] = { 59 | 0, /* no */ 60 | WHITE_CHAR, /* information: 1, color(37: white) */ 61 | GREEN_CHAR, /* warn : 3, color(32: green) */ 62 | RED_CHAR, /* error : 3, color(31: red) */ 63 | YELLOW_CHAR, /* assert : 4, color(33: yellow) */ 64 | CYAN_CHAR /* block : 5, color(36: cyan) */ 65 | /* others : n, color(34: blue) */ 66 | }; 67 | const uint32_t prospect_table_size = sizeof(prospect_table) / sizeof(prospect_table[0]); 68 | 69 | if (level < prospect_table_size) 70 | *color = prospect_table[level]; 71 | else 72 | *color = BLUE_CHAR; 73 | 74 | return mfi_debug_level; 75 | } 76 | 77 | void hap_set_debug_level(hap_debug_level_t level) 78 | { 79 | esp_mfi_set_debug_level(level); 80 | } 81 | -------------------------------------------------------------------------------- /src/esp_mfi_debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #ifndef ESP_MFI_DEBUG_H_ 26 | #define ESP_MFI_DEBUG_H_ 27 | 28 | #include 29 | #include 30 | 31 | #ifdef __cplusplus 32 | extern "C"{ 33 | #endif 34 | 35 | #define ESP_MFI_DEBUG_FL "\n" 36 | #define CONFIG_ESP_MFI_DEBUG_ENABLE 37 | #ifdef CONFIG_ESP_MFI_DEBUG_ENABLE 38 | #define ESP_MFI_DEBUG_ENABLE 39 | #endif /* CONFIG_ESP_MFI_DEBUG_ENABLE */ 40 | 41 | #define CONFIG_ESP_MFI_ASSERT 42 | #ifdef CONFIG_ESP_MFI_ASSERT 43 | #define ESP_MFI_ASSERT_ENABLE 44 | #endif /* CONFIG_ESP_MFI_ASSERT */ 45 | 46 | #define CONFIG_MFI_DEBUG_LEVEL_INIT 0 47 | #define CONFIG_ESP_MFI_ASSERT_BLOCK 48 | #ifdef CONFIG_ESP_MFI_ASSERT_BLOCK 49 | #define ESP_MFI_ASSERT_BLOCK() while (1) 50 | #else /* CONFIG_ESP_MFI_ASSERT_BLOCK */ 51 | #define ESP_MFI_ASSERT_BLOCK() 52 | #endif /* CONFIG_ESP_MFI_ASSERT_BLOCK */ 53 | 54 | /* debug level with different color */ 55 | #define ESP_MFI_DEBUG_INFO 1 56 | #define ESP_MFI_DEBUG_WARN 2 57 | #define ESP_MFI_DEBUG_ERR 3 58 | #define ESP_MFI_DEBUG_ASSERT 4 59 | #define ESP_MFI_DEBUG_BLOCK 5 60 | 61 | /** 62 | * @bref set the MFI debugging level 63 | * 64 | * @param level debugging level 65 | * 66 | * @return the result 67 | * = 0 : OK 68 | * others : failed 69 | */ 70 | int esp_mfi_set_debug_level(uint32_t level); 71 | 72 | /** 73 | * @bref get the MFI debugging level and output data color 74 | * 75 | * @param level input debug level 76 | * @param color data color 77 | * 78 | * @return MFI debugging level 79 | */ 80 | uint32_t esp_mfi_get_debug_level(uint32_t level, uint32_t *color); 81 | 82 | /** 83 | * @bref format the string and data, then output it 84 | * 85 | * @param level if level > MFI_DEBUG_LEVEL then output it 86 | * @param fmt format string 87 | * @param ... parameters of format string 88 | * 89 | * @return none 90 | * 91 | * void ESP_MFI_DEBUG(unsigned int level, const char *fmt, ...); 92 | */ 93 | #ifdef ESP_MFI_DEBUG_ENABLE 94 | /* 95 | #define ESP_MFI_DEBUG(l, fmt, ...) \ 96 | { \ 97 | uint32_t __color_LINE; \ 98 | if (l > esp_mfi_get_debug_level(l, &__color_LINE)) { \ 99 | printf("\e[1;%dm" fmt "\e[0m" ESP_MFI_DEBUG_FL, \ 100 | __color_LINE, ##__VA_ARGS__); \ 101 | } \ 102 | } 103 | #define ESP_MFI_DEBUG_INTR(l, fmt, ...) \ 104 | { \ 105 | uint32_t __color_LINE; \ 106 | if (l > esp_mfi_get_debug_level(l, &__color_LINE)) { \ 107 | ets_printf("\e[1;%dm" fmt "\e[0m" ESP_MFI_DEBUG_FL, \ 108 | __color_LINE, ##__VA_ARGS__); \ 109 | } \ 110 | } 111 | 112 | #define ESP_MFI_DEBUG(l, fmt, ...) \ 113 | { \ 114 | uint32_t __color_LINE; \ 115 | if (l > esp_mfi_get_debug_level(l, &__color_LINE)) { \ 116 | printf("[%7lu] " fmt "\n", ((unsigned long) (esp_timer_get_time() / 1000ULL)), ##__VA_ARGS__); \ 117 | } \ 118 | } 119 | #define ESP_MFI_DEBUG_INTR(l, fmt, ...) \ 120 | { \ 121 | uint32_t __color_LINE; \ 122 | if (l > esp_mfi_get_debug_level(l, &__color_LINE)) { \ 123 | printf("[%7lu] " fmt "\n", ((unsigned long) (esp_timer_get_time() / 1000ULL)), ##__VA_ARGS__); \ 124 | } \ 125 | }*/ 126 | 127 | #define ESP_MFI_DEBUG(l, fmt, ...) \ 128 | { \ 129 | printf("[%7lu] " fmt "\n", ((unsigned long) (esp_timer_get_time() / 1000ULL)), ##__VA_ARGS__); \ 130 | } 131 | #define ESP_MFI_DEBUG_INTR(l, fmt, ...) \ 132 | { \ 133 | printf("[%7lu] " fmt "\n", ((unsigned long) (esp_timer_get_time() / 1000ULL)), ##__VA_ARGS__); \ 134 | } 135 | #else /* ESP_MFI_DEBUG_ENABLE */ 136 | #define ESP_MFI_DEBUG(l, fmt, ...) 137 | #define ESP_MFI_DEBUG_INTR(l, fmt, ...) 138 | #endif /* ESP_MFI_DEBUG_ENABLE */ 139 | 140 | /** 141 | * @bref if the signal is false(0) do something depended on configuration 142 | * 143 | * @param conditions checking conditions 144 | * 145 | * @return none 146 | * 147 | * void ESP_MFI_ASSERT(int conditions); 148 | */ 149 | #ifdef ESP_MFI_ASSERT_ENABLE 150 | #define ESP_MFI_ASSERT(cond) \ 151 | { \ 152 | if (!(cond)) { \ 153 | printf("\e[1;33m" "ESP_MFI assert file %s line %d" ESP_MFI_DEBUG_FL, \ 154 | __FILE__, __LINE__); \ 155 | ESP_MFI_ASSERT_BLOCK(); \ 156 | } \ 157 | } 158 | #else 159 | #define ESP_MFI_ASSERT(cond) 160 | #endif 161 | 162 | /** 163 | * @bref check if data length matches given length 164 | * 165 | * @param optlen data length 166 | * @param opttype data 167 | * 168 | * @return none 169 | * 170 | * void ESP_MFI_CHECK_OPTLEN(int conditions, (all type) data); 171 | */ 172 | #define ESP_MFI_CHECK_OPTLEN(optlen, opttype) \ 173 | do { \ 174 | if ((optlen) > sizeof(opttype)) { \ 175 | return -1; \ 176 | } \ 177 | } while(0) \ 178 | 179 | #ifdef __cplusplus 180 | } 181 | #endif 182 | 183 | #endif /* ESP_MFI_DEBUG_H_ */ 184 | -------------------------------------------------------------------------------- /src/esp_mfi_dummy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | ESP_EVENT_DEFINE_BASE(HAP_WAC_EVENT); 33 | 34 | int hap_pair_setup_manage_mfi_auth(pair_setup_ctx_t *ps_ctx, hap_tlv_data_t *tlv_data, hap_tlv_error_t *tlv_error) 35 | { 36 | 37 | if (ps_ctx->method == HAP_METHOD_PAIR_SETUP) { 38 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_ERR, "Secure pair setup not supported. Please use MFi variant of the SDK."); 39 | *tlv_error = kTLVError_Unknown; 40 | return HAP_FAIL; 41 | } 42 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_WARN, "Using pair-setup without MFi."); 43 | return ESP_OK; 44 | } 45 | 46 | int hap_enable_mfi_auth(hap_mfi_auth_type_t auth_type) 47 | { 48 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_WARN, "MFi auth not supported. Falling back to HAP_MFI_AUTH_NONE"); 49 | hap_priv.auth_type = HAP_MFI_AUTH_NONE; 50 | return 0; 51 | } 52 | 53 | int hap_wac_start(void) 54 | { 55 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_ERR, "WAC not supported. Please use MFi variant of the SDK."); 56 | return ESP_FAIL; 57 | } 58 | 59 | int hap_wac_stop(void) 60 | { 61 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_ERR, "WAC not supported. Please use MFi variant of the SDK."); 62 | return ESP_FAIL; 63 | } 64 | int hap_enable_hw_auth(void) 65 | { 66 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_ERR, "MFi HW Auth not supported. Please use MFi variant of the SDK."); 67 | return ESP_FAIL; 68 | 69 | } 70 | int hap_enable_sw_auth(void) 71 | { 72 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_ERR, "MFi SW Auth not supported. Please use MFi variant of the SDK."); 73 | return ESP_FAIL; 74 | } 75 | int hap_register_secure_message_handler(httpd_handle_t handle) 76 | { 77 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_ERR, "MFi SW Auth not supported. Please use MFi variant of the SDK."); 78 | return ESP_FAIL; 79 | } 80 | int hap_unregister_secure_message_handler(httpd_handle_t handle) 81 | { 82 | ESP_MFI_DEBUG(ESP_MFI_DEBUG_ERR, "MFi SW Auth not supported. Please use MFi variant of the SDK."); 83 | return ESP_FAIL; 84 | } 85 | -------------------------------------------------------------------------------- /src/esp_mfi_i2c.h.0: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #ifndef ESP_MFI_I2C_H_ 26 | #define ESP_MFI_I2C_H_ 27 | 28 | #include 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /** 35 | * @brief Initialize I2C 36 | * 37 | * @return 38 | * - 0 : succeed 39 | * - others : fail 40 | */ 41 | int esp_mfi_i2c_init(void); 42 | 43 | /** 44 | * @brief I2C operation end 45 | * 46 | * @return 47 | * - 0 : succeed 48 | * - others : fail 49 | */ 50 | int esp_mfi_i2c_end(void); 51 | 52 | /** 53 | * @brief Write data to I2C slave 54 | * 55 | * @param slvaddr address of slave 56 | * @param regaddr address of register 57 | * @param buff pointer of data to write 58 | * @param len the data length 59 | * 60 | * @return 61 | * - 0 : succeed 62 | * - others : fail 63 | */ 64 | int esp_mfi_i2c_write(uint8_t slvaddr, uint8_t regaddr, uint8_t *buff, uint32_t len); 65 | 66 | /** 67 | * @brief Read data from I2C slave 68 | * 69 | * @param slvaddr address of slave 70 | * @param regaddr address of register 71 | * @param buff pointer of data read 72 | * @param len the data length 73 | * 74 | * @return 75 | * - 0 : succeed 76 | * - others : fail 77 | */ 78 | int esp_mfi_i2c_read(uint8_t slvaddr, uint8_t regaddr, uint8_t *buff, uint32_t len); 79 | 80 | #ifdef __cplusplus 81 | } 82 | #endif 83 | 84 | #endif /* ESP_MFI_I2C_H_ */ 85 | -------------------------------------------------------------------------------- /src/esp_mfi_rand.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | /** 29 | * @bref Obtain a series of random bytes 30 | * 31 | * @param buf the random bytes were copied point 32 | * len the number of bytes requested 33 | * 34 | * @return the result 35 | * > 0 : the number of bytes that were copied to the buffer 36 | * others : failed 37 | */ 38 | int esp_mfi_get_random(uint8_t *buf, uint16_t len) 39 | { 40 | int i, j; 41 | unsigned long tmp; 42 | 43 | for (i = 0; i < ((len + 3) & ~3) / 4; i++) { 44 | tmp = esp_random(); 45 | 46 | for (j = 0; j < 4; j++) { 47 | if ((i * 4 + j) < len) { 48 | buf[i * 4 + j] = (uint8_t) (tmp >> (j * 8)); 49 | } else { 50 | break; 51 | } 52 | } 53 | } 54 | 55 | return len; 56 | } 57 | -------------------------------------------------------------------------------- /src/esp_mfi_rand.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #ifndef ESP_MFI_RAND_H_ 26 | #define ESP_MFI_RAND_H_ 27 | 28 | #include 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /** 35 | * @brief Get a random number of bytes specified. 36 | * 37 | * @param buf pointer of the random number it gets 38 | * @param len specified bytes of the random number 39 | * 40 | * @return 41 | * - > 0 : the actual length(bytes) of the random number 42 | * - others : failure 43 | */ 44 | int esp_mfi_get_random(uint8_t *buf, uint16_t len); 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif /* ESP_MFI_RAND_H_ */ 51 | -------------------------------------------------------------------------------- /src/esp_mfi_sha.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #include 26 | 27 | #include "mbedtls/sha1.h" 28 | #include "mbedtls/sha256.h" 29 | #include "mbedtls/sha512.h" 30 | 31 | #include "esp_mfi_sha.h" 32 | 33 | #ifdef CONFIG_IDF_TARGET_ESP8266 34 | #define mbedtls_sha512_starts mbedtls_sha512_starts_ret 35 | #define mbedtls_sha512_update mbedtls_sha512_update_ret 36 | #define mbedtls_sha512_finish mbedtls_sha512_finish_ret 37 | #endif 38 | 39 | /** 40 | * @bref Create SHA1 context 41 | * 42 | * @param none 43 | * 44 | * @return the SHA1 context point 45 | */ 46 | esp_mfi_sha_ctx_t esp_mfi_sha1_new(void) 47 | { 48 | mbedtls_sha1_context *context = NULL; 49 | context = (mbedtls_sha1_context *) malloc(sizeof(mbedtls_sha1_context)); 50 | mbedtls_sha1_init(context); 51 | return context; 52 | } 53 | 54 | /** 55 | * @bref Free SHA1 context 56 | * 57 | * @param ctx the SHA1 context point 58 | * 59 | * @return none 60 | */ 61 | void esp_mfi_sha1_free(esp_mfi_sha_ctx_t ctx) 62 | { 63 | if (ctx) { 64 | mbedtls_sha1_free( (mbedtls_sha1_context *)ctx); 65 | free(ctx); 66 | } 67 | } 68 | 69 | /** 70 | * @bref Init SHA1 context 71 | * 72 | * @param ctx the SHA1 context point 73 | * 74 | * @return none 75 | */ 76 | void esp_mfi_sha1_init(esp_mfi_sha_ctx_t ctx) 77 | { 78 | if (ctx == NULL) 79 | return; 80 | 81 | mbedtls_sha1_starts((mbedtls_sha1_context *) ctx); 82 | } 83 | 84 | /** 85 | * @bref Update SHA1 context 86 | * 87 | * @param ctx the SHA1 context point 88 | * msg input data point 89 | * len input data length 90 | * 91 | * @return none 92 | */ 93 | void esp_mfi_sha1_update(esp_mfi_sha_ctx_t ctx, const uint8_t * msg, int len) 94 | { 95 | if (ctx == NULL || msg == NULL) 96 | return; 97 | 98 | mbedtls_sha1_update((mbedtls_sha1_context *) ctx, msg, len); 99 | } 100 | 101 | /** 102 | * @bref Final SHA1 context 103 | * 104 | * @param digest output data point 105 | * ctx the SHA1 context point 106 | * 107 | * @return none 108 | */ 109 | void esp_mfi_sha1_final(esp_mfi_sha_ctx_t ctx, uint8_t *digest) 110 | { 111 | if (ctx == NULL || digest == NULL) 112 | return; 113 | 114 | mbedtls_sha1_finish((mbedtls_sha1_context *) ctx, digest); 115 | } 116 | 117 | /* 118 | * SHA256 declarations 119 | */ 120 | 121 | /** 122 | * @bref Create SHA256 context 123 | * 124 | * @param none 125 | * 126 | * @return the SHA256 context point 127 | */ 128 | esp_mfi_sha_ctx_t esp_mfi_sha256_new(void) 129 | { 130 | mbedtls_sha256_context *context = NULL; 131 | context = (mbedtls_sha256_context *) malloc(sizeof(mbedtls_sha256_context)); 132 | mbedtls_sha256_init(context); 133 | return context; 134 | } 135 | 136 | /** 137 | * @bref Free SHA256 context 138 | * 139 | * @param ctx the SHA256 context point 140 | * 141 | * @return none 142 | */ 143 | void esp_mfi_sha256_free(esp_mfi_sha_ctx_t ctx) 144 | { 145 | if (ctx) { 146 | mbedtls_sha256_free((mbedtls_sha256_context *)ctx); 147 | free(ctx); 148 | } 149 | } 150 | 151 | /** 152 | * @bref Init SHA256 context 153 | * 154 | * @param ctx the SHA256 context point 155 | * 156 | * @return none 157 | */ 158 | void esp_mfi_sha256_init(esp_mfi_sha_ctx_t ctx) 159 | { 160 | if (ctx == NULL) 161 | return; 162 | 163 | mbedtls_sha256_starts((mbedtls_sha256_context *) ctx, 0); 164 | } 165 | 166 | /** 167 | * @bref Update SHA256 context 168 | * 169 | * @param ctx the SHA256 context point 170 | * msg input data point 171 | * len input data length 172 | * 173 | * @return none 174 | */ 175 | void esp_mfi_sha256_update(esp_mfi_sha_ctx_t ctx, const uint8_t *input, int len) 176 | { 177 | if (ctx == NULL || input == NULL) 178 | return; 179 | 180 | mbedtls_sha256_update((mbedtls_sha256_context *) ctx, input, len); 181 | } 182 | 183 | /** 184 | * @bref Final SHA256 context 185 | * 186 | * @param digest output data point 187 | * ctx the SHA256 context point 188 | * 189 | * @return none 190 | */ 191 | void esp_mfi_sha256_final(esp_mfi_sha_ctx_t ctx, uint8_t *digest) 192 | { 193 | if (ctx == NULL || digest == NULL) 194 | return; 195 | 196 | mbedtls_sha256_finish((mbedtls_sha256_context *) ctx, digest); 197 | } 198 | 199 | /* 200 | * SHA512 declarations 201 | */ 202 | 203 | /** 204 | * @bref Create SHA512 context 205 | * 206 | * @param none 207 | * 208 | * @return the SHA512 context point 209 | */ 210 | esp_mfi_sha_ctx_t esp_mfi_sha512_new(void) 211 | { 212 | mbedtls_sha512_context *context = NULL; 213 | context = (mbedtls_sha512_context *) malloc(sizeof(mbedtls_sha512_context)); 214 | mbedtls_sha512_init(context); 215 | return context; 216 | } 217 | 218 | /** 219 | * @bref Free SHA512 context 220 | * 221 | * @param ctx the SHA512 context point 222 | * 223 | * @return none 224 | */ 225 | void esp_mfi_sha512_free(esp_mfi_sha_ctx_t ctx) 226 | { 227 | if (ctx) { 228 | mbedtls_sha512_free((mbedtls_sha512_context *)ctx); 229 | free(ctx); 230 | } 231 | } 232 | 233 | /** 234 | * @bref Init SHA512 context 235 | * 236 | * @param ctx the SHA512 context point 237 | * 238 | * @return none 239 | */ 240 | void esp_mfi_sha512_init(esp_mfi_sha_ctx_t ctx) 241 | { 242 | if (ctx == NULL) 243 | return; 244 | 245 | mbedtls_sha512_starts((mbedtls_sha512_context *) ctx, 0); 246 | } 247 | 248 | /** 249 | * @bref Update SHA512 context 250 | * 251 | * @param ctx the SHA512 context point 252 | * msg input data point 253 | * len input data length 254 | * 255 | * @return none 256 | */ 257 | void esp_mfi_sha512_update(esp_mfi_sha_ctx_t ctx, const uint8_t *input, int len) 258 | { 259 | if (ctx == NULL || input == NULL) 260 | return; 261 | 262 | mbedtls_sha512_update((mbedtls_sha512_context *) ctx, input, len); 263 | } 264 | 265 | /** 266 | * @bref Final SHA512 context 267 | * 268 | * @param digest output data point 269 | * ctx the SHA512 context point 270 | * 271 | * @return none 272 | */ 273 | void esp_mfi_sha512_final(esp_mfi_sha_ctx_t ctx, uint8_t *digest) 274 | { 275 | if (ctx == NULL || digest == NULL) 276 | return; 277 | 278 | mbedtls_sha512_finish((mbedtls_sha512_context *) ctx, digest); 279 | } 280 | -------------------------------------------------------------------------------- /src/esp_mfi_sha.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #ifndef ESP_MFI_SHA_H_ 26 | #define ESP_MFI_SHA_H_ 27 | 28 | #include 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | typedef void* esp_mfi_sha_ctx_t; 35 | 36 | /* 37 | * SHA1 declarations 38 | */ 39 | 40 | #define MFI_SHA1_SIZE 20 41 | 42 | /** 43 | * @brief Create SHA1 context 44 | * 45 | * @return pointer of the SHA1 context 46 | */ 47 | esp_mfi_sha_ctx_t esp_mfi_sha1_new(void); 48 | 49 | /** 50 | * @brief Init SHA1 context 51 | * 52 | * @param ctx pointer of the SHA1 context 53 | */ 54 | void esp_mfi_sha1_init(esp_mfi_sha_ctx_t ctx); 55 | 56 | /** 57 | * @brief Update SHA1 context 58 | * 59 | * @param ctx pointer of the SHA1 context 60 | * @param msg pointer of the input data 61 | * @param len input data length 62 | */ 63 | void esp_mfi_sha1_update(esp_mfi_sha_ctx_t ctx, const uint8_t *msg, int len); 64 | 65 | /** 66 | * @brief Final SHA1 context 67 | * 68 | * @param digest pointer of output data 69 | * @param ctx pointer of the SHA1 context 70 | */ 71 | void esp_mfi_sha1_final(esp_mfi_sha_ctx_t ctx, uint8_t *digest); 72 | 73 | /** 74 | * @brief Free SHA1 context 75 | * 76 | * @param ctx pointer of the SHA1 context 77 | */ 78 | void esp_mfi_sha1_free(esp_mfi_sha_ctx_t ctx); 79 | 80 | /* 81 | * SHA256 declarations 82 | */ 83 | 84 | #define MFI_SHA256_SIZE 32 85 | 86 | /** 87 | * @brief Create SHA256 context 88 | * 89 | * @return pointer of the SHA256 context 90 | */ 91 | esp_mfi_sha_ctx_t esp_mfi_sha256_new(void); 92 | 93 | /** 94 | * @brief Init SHA256 context 95 | * 96 | * @param ctx pointer of the SHA256 context 97 | */ 98 | void esp_mfi_sha256_init(esp_mfi_sha_ctx_t ctx); 99 | 100 | /** 101 | * @brief Update SHA256 context 102 | * 103 | * @param ctx pointer of the SHA256 context 104 | * @param msg pointer of input data 105 | * @param len input data length 106 | */ 107 | void esp_mfi_sha256_update(esp_mfi_sha_ctx_t ctx, const uint8_t *input, int len); 108 | 109 | /** 110 | * @brief Final SHA256 context 111 | * 112 | * @param digest pointer of output data 113 | * @param ctx pointer of the SHA256 context 114 | */ 115 | void esp_mfi_sha256_final(esp_mfi_sha_ctx_t ctx, uint8_t *digest); 116 | 117 | /** 118 | * @brief Free SHA256 context 119 | * 120 | * @param ctx pointer of the SHA256 context 121 | */ 122 | void esp_mfi_sha256_free(esp_mfi_sha_ctx_t ctx); 123 | 124 | /* 125 | * SHA512 declarations 126 | */ 127 | 128 | #define MFI_SHA512_SIZE 64 129 | 130 | /** 131 | * @brief Create SHA512 context 132 | * 133 | * @return pointer of the SHA512 context 134 | */ 135 | esp_mfi_sha_ctx_t esp_mfi_sha512_new(void); 136 | 137 | /** 138 | * @brief Init SHA512 context 139 | * 140 | * @param ctx pointer of the SHA512 context 141 | */ 142 | void esp_mfi_sha512_init(esp_mfi_sha_ctx_t ctx); 143 | 144 | /** 145 | * @brief Update SHA512 context 146 | * 147 | * @param ctx pointer of the SHA512 context 148 | * @param msg pointer of input data 149 | * @param len input data length 150 | */ 151 | void esp_mfi_sha512_update(esp_mfi_sha_ctx_t ctx, const uint8_t *input, int len); 152 | 153 | /** 154 | * @brief Final SHA512 context 155 | * 156 | * @param digest pointer of output data 157 | * @param ctx pointer of the SHA512 context 158 | */ 159 | void esp_mfi_sha512_final(esp_mfi_sha_ctx_t ctx, uint8_t *digest); 160 | 161 | /** 162 | * @brief Free SHA512 context 163 | * 164 | * @param ctx pointer of the SHA512 context 165 | */ 166 | void esp_mfi_sha512_free(esp_mfi_sha_ctx_t ctx); 167 | 168 | #ifdef __cplusplus 169 | } 170 | #endif 171 | 172 | #endif /* ESP_MFI_SHA_H_ */ 173 | -------------------------------------------------------------------------------- /src/hap_bct.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef _HAP_BCT_H_ 25 | #define _HAP_BCT_H_ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | /** 32 | * @brief Change the name of the Bonjour Service for BCT 33 | * 34 | * This is required as per the "Manual Name Change" step of "Tester Interaction" 35 | * section of Bonjour Conformance Test. 36 | * 37 | * @param[in] name The desired new name for the service. For BCT 1.4 or earlier: "New - Bonjour Service Name". 38 | * For BCT 1.5 or later: "New-BCT" 39 | */ 40 | void hap_bct_change_name(const char *name); 41 | 42 | /** 43 | * @brief Trigger a Hot plug of the network interface for BCT 44 | * 45 | * This is required as per the "Cable Change Handling" and "Hot Plugging" steps 46 | * of "Tester Interaction" section of Bonjout Conformance Test 47 | */ 48 | void hap_bct_hot_plug(); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif /* _HAP_BCT_H_ */ 55 | -------------------------------------------------------------------------------- /src/hap_platform_httpd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2019 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #include 25 | #include <_esp_hap_config.h> 26 | 27 | httpd_handle_t *int_handle; 28 | int hap_platform_httpd_start(httpd_handle_t *handle) 29 | { 30 | httpd_config_t config = { 31 | .task_priority = tskIDLE_PRIORITY+5, 32 | .stack_size = CONFIG_HAP_HTTP_STACK_SIZE, 33 | .server_port = CONFIG_HAP_HTTP_SERVER_PORT, 34 | .ctrl_port = CONFIG_HAP_HTTP_CONTROL_PORT, 35 | .max_open_sockets = CONFIG_HAP_HTTP_MAX_OPEN_SOCKETS, 36 | .max_uri_handlers = CONFIG_HAP_HTTP_MAX_URI_HANDLERS, 37 | .max_resp_headers = 8, 38 | .backlog_conn = 5, 39 | .lru_purge_enable = true, 40 | .recv_wait_timeout = 5, 41 | .send_wait_timeout = 5, 42 | }; 43 | esp_err_t err = httpd_start(handle, &config); 44 | if (err == ESP_OK) { 45 | int_handle = handle; 46 | } 47 | return err; 48 | } 49 | 50 | int hap_platform_httpd_stop(httpd_handle_t *handle) 51 | { 52 | esp_err_t err = httpd_stop(*handle); 53 | if (err == ESP_OK) { 54 | int_handle = NULL; 55 | } 56 | return err; 57 | } 58 | 59 | int hap_platform_httpd_get_port() 60 | { 61 | return CONFIG_HAP_HTTP_SERVER_PORT; 62 | } 63 | 64 | void * hap_platform_httpd_get_sess_ctx(httpd_req_t *req) 65 | { 66 | if (req) { 67 | return req->sess_ctx; 68 | } 69 | return NULL; 70 | } 71 | 72 | esp_err_t hap_platform_httpd_set_sess_ctx(httpd_req_t *req, void *ctx, httpd_free_ctx_fn_t free_ctx, bool ignore_ctx_changes) 73 | { 74 | if (req) { 75 | req->sess_ctx = ctx; 76 | req->free_ctx = free_ctx; 77 | #ifndef CONFIG_IDF_TARGET_ESP8266 78 | req->ignore_sess_ctx_changes = ignore_ctx_changes; 79 | #endif 80 | return ESP_OK; 81 | } 82 | return ESP_FAIL; 83 | } 84 | 85 | static char * hap_platform_httpd_rqtype_to_string(int method) 86 | { 87 | switch (method) { 88 | case HTTP_GET: 89 | return "GET"; 90 | case HTTP_POST: 91 | return "POST"; 92 | case HTTP_PUT: 93 | return "PUT"; 94 | default: 95 | return "INVALID"; 96 | } 97 | } 98 | 99 | const char *hap_platform_httpd_get_req_method(httpd_req_t *req) 100 | { 101 | if (req) { 102 | return hap_platform_httpd_rqtype_to_string(req->method); 103 | } 104 | return NULL; 105 | } 106 | 107 | const char *hap_platform_httpd_get_req_uri(httpd_req_t *req) 108 | { 109 | if (req) { 110 | return req->uri; 111 | } 112 | return NULL; 113 | } 114 | 115 | int hap_platform_httpd_get_content_len(httpd_req_t *req) 116 | { 117 | if (req) { 118 | return req->content_len; 119 | } 120 | return -1; 121 | } 122 | 123 | httpd_handle_t *hap_platform_httpd_get_handle() 124 | { 125 | return int_handle; 126 | } 127 | -------------------------------------------------------------------------------- /src/hap_platform_httpd.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * ESPRESSIF MIT License 4 | * 5 | * Copyright (c) 2019 6 | * 7 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 8 | * it is free of charge, to any person obtaining a copy of this software and associated 9 | * documentation files (the "Software"), to deal in the Software without restriction, including 10 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 12 | * to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | * 24 | */ 25 | #ifndef _HAP_PLATFORM_HTTPD_H_ 26 | #define _HAP_PLATFORM_HTTPD_H_ 27 | #include 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | /** Start the webserver 33 | * 34 | * This API will be called by the HAP Core to start the webserver. 35 | * 36 | * @param[out] handle Pointer to the handle that should be populated by this 37 | * function on a success. 38 | * 39 | * @return ESP_OK on success 40 | * @return error code otherwise 41 | */ 42 | int hap_platform_httpd_start(httpd_handle_t *handle); 43 | 44 | /** Stop the webserver 45 | * 46 | * This API will be called by the HAP Core to stop the webserver. 47 | * 48 | * @param[in] handle Pointer to the handle created in hap_platform_httpd_start 49 | * 50 | * @return ESP_OK on success 51 | * @return error code otherwise 52 | */ 53 | int hap_platform_httpd_stop(httpd_handle_t *handle); 54 | 55 | /** Get the current HTTP Port 56 | * 57 | * This API will be called by the HAP Core to get the HTTP Port being used. This will 58 | * be used for the mDNS announcement 59 | * 60 | * @return Configured HTTP Port 61 | */ 62 | int hap_platform_httpd_get_port(); 63 | 64 | /** Get the HTTPD session context 65 | * 66 | * This API will be called by the HAP Core to get the context associated with a given 67 | * session. It is generally used to maintain pairing information. 68 | * 69 | * @param[in] req HTTPD Request structure. 70 | * 71 | * @return pointer to the session context. 72 | */ 73 | void * hap_platform_httpd_get_sess_ctx(httpd_req_t *req); 74 | 75 | /** Set the HTTPD session context 76 | * 77 | * This API will be called by the HAP Core to set the context associated with a given 78 | * session. It is generally used to maintain pairing information. 79 | * 80 | * @param[in] req HTTPD Request structure. 81 | * @param[in] ctx The context to be set for the given session. 82 | * @param[in] free_fn Pointer to a function that will be used by the HTTP Server to clear the context when the session closes 83 | * @param[in] ignore_ctx_changes Flag to indicate if the HTTP Server should ignore changes to the context across different requests. 84 | * If set to false, the server will try clearing the old context, if it detects any change. 85 | * 86 | * @return ESP_OK in success 87 | * @return ESP_FAIL if req is nULL 88 | */ 89 | esp_err_t hap_platform_httpd_set_sess_ctx(httpd_req_t *req, void *ctx, httpd_free_ctx_fn_t free_ctx, bool ignore_ctx_changes); 90 | 91 | /** Get the HTTP request method 92 | * 93 | * This API will be called by the HAP Core to get the HTTP request method 94 | * in string format (Eg. GET, POST, etc.) 95 | * 96 | * @param[in] HTTPD Request structure. 97 | * 98 | * @return Pointer to a string indicating the HTTP method. 99 | */ 100 | const char *hap_platform_httpd_get_req_method(httpd_req_t *req); 101 | 102 | /** Get the HTTP request URI 103 | * 104 | * This API will be called by the HAP Core to get the request URI string. 105 | * 106 | * @param[in] HTTPD Request structure. 107 | * 108 | * @return Pointer to the URI string. 109 | */ 110 | const char *hap_platform_httpd_get_req_uri(httpd_req_t *req); 111 | 112 | /** Get the HTTP request content length 113 | * 114 | * This API will be called by the HAP Core to get the content length of the request. 115 | * 116 | * @param[in] HTTPD Request structure. 117 | * 118 | * @return Content length. 119 | */ 120 | int hap_platform_httpd_get_content_len(httpd_req_t *req); 121 | 122 | /** 123 | * Get the HAP HTTPD Handle 124 | * 125 | * If an application wants to register additional HTTPD endpoints on the same server 126 | * instance being used by HomeKit, this API can be used to get the handle. This 127 | * should be used only after hap_start(). 128 | * 129 | * @return HomeKit HTTPD Handle 130 | */ 131 | httpd_handle_t *hap_platform_httpd_get_handle(); 132 | 133 | #ifdef __cplusplus 134 | } 135 | #endif 136 | #endif /* _HAP_PLATFORM_HTTPD_H_ */ 137 | -------------------------------------------------------------------------------- /src/hap_platform_keystore.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #include 25 | #include 26 | #include 27 | 28 | #define HAP_PLATFORM_DEF_NVS_PARTITION "nvs" 29 | #define HAP_PLATFORM_DEF_FACTORY_NVS_PARTITION "factory_nvs" 30 | 31 | static const char *TAG = "hap_platform_keystore"; 32 | 33 | char * hap_platform_keystore_get_nvs_partition_name() 34 | { 35 | return HAP_PLATFORM_DEF_NVS_PARTITION; 36 | } 37 | 38 | char * hap_platform_keystore_get_factory_nvs_partition_name() 39 | { 40 | return HAP_PLATFORM_DEF_FACTORY_NVS_PARTITION; 41 | } 42 | 43 | #ifdef CONFIG_NVS_ENCRYPTION 44 | int hap_platform_keystore_init_partition(const char *part_name, bool read_only) 45 | { 46 | esp_err_t err; 47 | nvs_sec_cfg_t *cfg = NULL; 48 | nvs_sec_cfg_t sec_cfg; 49 | esp_partition_iterator_t iterator = esp_partition_find(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS_KEYS, NULL); 50 | if (iterator) { 51 | const esp_partition_t *partition = esp_partition_get(iterator); 52 | err = nvs_flash_read_security_cfg(partition, &sec_cfg); 53 | if (err == ESP_OK) { 54 | cfg = &sec_cfg; 55 | } else { 56 | ESP_LOGE(TAG, "No NVS keys found"); 57 | } 58 | } else { 59 | ESP_LOGE(TAG, "No NVS keys partition found"); 60 | } 61 | if (!cfg) { 62 | ESP_LOGE(TAG, "NVS partition '%s' not encrypted", part_name); 63 | } else { 64 | ESP_LOGI(TAG, "NVS partition '%s' is encrypted", part_name); 65 | } 66 | if (read_only) { 67 | err = nvs_flash_secure_init_partition(part_name, cfg); 68 | } else { 69 | err = nvs_flash_secure_init_partition(part_name, cfg); 70 | if (err == ESP_ERR_NVS_NO_FREE_PAGES) { 71 | ESP_ERROR_CHECK(nvs_flash_erase_partition(part_name)); 72 | err = nvs_flash_secure_init_partition(part_name, cfg); 73 | } 74 | } 75 | if (err == ESP_OK) { 76 | return 0; 77 | } 78 | return -1; 79 | } 80 | #else 81 | int hap_platform_keystore_init_partition(const char *part_name, bool read_only) 82 | { 83 | esp_err_t err; 84 | if (read_only) { 85 | err = nvs_flash_init_partition(part_name); 86 | } else { 87 | err = nvs_flash_init_partition(part_name); 88 | if (err == ESP_ERR_NVS_NO_FREE_PAGES) { 89 | ESP_ERROR_CHECK(nvs_flash_erase_partition(part_name)); 90 | err = nvs_flash_init_partition(part_name); 91 | } 92 | } 93 | if (err == ESP_OK) { 94 | return 0; 95 | } 96 | return -1; 97 | } 98 | #endif /* CONFIG_NVS_ENCRYPTION */ 99 | 100 | int hap_platform_keystore_get(const char *part_name, const char *name_space, const char *key, uint8_t *val, size_t *val_size) 101 | { 102 | nvs_handle handle; 103 | esp_err_t err = nvs_open_from_partition(part_name, name_space, NVS_READONLY, &handle); 104 | if (err != ESP_OK) { 105 | return -1; 106 | } else { 107 | err = nvs_get_blob(handle, key, val, val_size); 108 | nvs_close(handle); 109 | } 110 | if (err == ESP_OK) { 111 | return 0; 112 | } 113 | return -1; 114 | } 115 | 116 | int hap_platform_keystore_set(const char *part_name, const char *name_space, const char *key, const uint8_t *val, const size_t val_len) 117 | 118 | { 119 | nvs_handle handle; 120 | esp_err_t err = nvs_open_from_partition(part_name, name_space, NVS_READWRITE, &handle); 121 | if (err != ESP_OK) { 122 | ESP_LOGE(TAG, "Error (%d) opening NVS handle!", err); 123 | } else { 124 | err = nvs_set_blob(handle, key, val, val_len); 125 | if (err != ESP_OK) { 126 | ESP_LOGE(TAG, "Failed to write %s", key); 127 | } else { 128 | nvs_commit(handle); 129 | } 130 | nvs_close(handle); 131 | } 132 | if (err == ESP_OK) { 133 | return 0; 134 | } 135 | return -1; 136 | } 137 | 138 | int hap_platform_keystore_delete(const char *part_name, const char *name_space, const char *key) 139 | { 140 | nvs_handle handle; 141 | esp_err_t err = nvs_open_from_partition(part_name, name_space, NVS_READWRITE, &handle); 142 | if (err != ESP_OK) { 143 | ESP_LOGE(TAG, "Error (%d) opening NVS handle!", err); 144 | } else { 145 | err = nvs_erase_key(handle, key); 146 | if (err != ESP_OK) { 147 | ESP_LOGE(TAG, "Failed to delete %s", key); 148 | } else { 149 | nvs_commit(handle); 150 | } 151 | nvs_close(handle); 152 | } 153 | if (err == ESP_OK) { 154 | return 0; 155 | } 156 | return -1; 157 | } 158 | 159 | int hap_platform_keystore_delete_namespace(const char *part_name, const char *name_space) 160 | { 161 | nvs_handle handle; 162 | esp_err_t err = nvs_open_from_partition(part_name, name_space, NVS_READWRITE, &handle); 163 | if (err != ESP_OK) { 164 | ESP_LOGE(TAG, "Error (%d) opening NVS handle!", err); 165 | } else { 166 | err = nvs_erase_all(handle); 167 | if (err != ESP_OK) { 168 | ESP_LOGE(TAG, "Failed to delete %s", name_space); 169 | } else { 170 | nvs_commit(handle); 171 | } 172 | nvs_close(handle); 173 | } 174 | if (err == ESP_OK) { 175 | return 0; 176 | } 177 | return -1; 178 | } 179 | 180 | int hap_platfrom_keystore_erase_partition(const char *part_name) 181 | { 182 | esp_err_t err = nvs_flash_erase_partition(part_name); 183 | if (err == ESP_OK) { 184 | return 0; 185 | } 186 | return -1; 187 | } 188 | -------------------------------------------------------------------------------- /src/hap_platform_keystore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #ifndef _HAP_PLATFORM_KEYSTORE_H_ 26 | #define _HAP_PLATFORM_KEYSTORE_H_ 27 | 28 | #include 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /** Get NVS Partition Name 35 | * 36 | * @return pointer to an allocated string indicating NVS partition Name 37 | */ 38 | char * hap_platform_keystore_get_nvs_partition_name(); 39 | 40 | 41 | /** Get Factory NVS Partition Name 42 | * 43 | * @return pointer to an allocated string indicating Factory NVS partition Name 44 | */ 45 | char * hap_platform_keystore_get_factory_nvs_partition_name(); 46 | 47 | /** Initialise Key Store Partition 48 | * 49 | * @param[in] part_name Name of Partition 50 | * @param[in] read_only True for Read-Only, False for Read-Write 51 | * 52 | * @return 0 on success 53 | * @return -1 on error 54 | */ 55 | int hap_platform_keystore_init_partition(const char *part_name, bool read_only); 56 | 57 | /** Get Value from Key Store 58 | * 59 | * @param[in] part_name Name of Partition 60 | * @param[in] name_space Name space for the key 61 | * @param[in] key Name of the key 62 | * @param[out] val Allocated buffer into which the value will be read 63 | * @param[in,out] val_size Size of the allocated value buffer. Will hold the size of value read on success 64 | * 65 | * @return 0 on success 66 | * @return -1 on error 67 | */ 68 | int hap_platform_keystore_get(const char *part_name, const char *name_space, const char *key, uint8_t *val, size_t *val_size); 69 | 70 | /** Set Value in Key Store 71 | * 72 | * @param[in] part_name Name of Partition 73 | * @param[in] name_space Name space for the key 74 | * @param[in] key Name of the key 75 | * @param[in] val Pointer to the value buffer 76 | * @param[in] val_len Length of the value buffer 77 | * 78 | * @return 0 on success 79 | * @return -1 on error 80 | */ 81 | int hap_platform_keystore_set(const char *part_name, const char *name_space, const char *key, const uint8_t *val, const size_t val_len); 82 | 83 | /** Delete Entry from Key Store 84 | * 85 | * @param[in] part_name Name of Partition 86 | * @param[in] name_space Name space for the key 87 | * @param[in] key Name of the key 88 | * 89 | * @return 0 on success 90 | * @return -1 on error 91 | */ 92 | int hap_platform_keystore_delete(const char *part_name, const char *name_space, const char *key); 93 | 94 | /** Delete Name space from Key Store 95 | * 96 | * @param[in] part_name Name of Partition 97 | * @param[in] name_space Name space for the key 98 | * 99 | * @return 0 on success 100 | * @return -1 on error 101 | */ 102 | int hap_platform_keystore_delete_namespace(const char *part_name, const char *name_space); 103 | 104 | /** Erase a Key Store partition 105 | * 106 | * @param[in] part_name Name of Partition 107 | * 108 | * @return 0 on success 109 | * @return -1 on error 110 | */ 111 | int hap_platfrom_keystore_erase_partition(const char *part_name); 112 | #ifdef __cplusplus 113 | } 114 | #endif 115 | #endif /* _HAP_PLATFORM_KEYSTORE_H_ */ 116 | -------------------------------------------------------------------------------- /src/hap_platform_memory.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2019 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #include 25 | 26 | void * hap_platform_memory_malloc(size_t size) 27 | { 28 | return malloc(size); 29 | } 30 | 31 | void * hap_platform_memory_calloc(size_t count, size_t size) 32 | { 33 | return calloc(count, size); 34 | } 35 | 36 | void hap_platform_memory_free(void *ptr) 37 | { 38 | free(ptr); 39 | } 40 | -------------------------------------------------------------------------------- /src/hap_platform_memory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2019 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef _HAP_PLATFORM_MEMORY_H_ 25 | #define _HAP_PLATFORM_MEMORY_H_ 26 | #include 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | 32 | /** Allocate memory 33 | * 34 | * This API allocates "size" bytes of memory and returns a pointer to the allocated memory. 35 | * 36 | * @param[in] size Number of bytes to be allocated 37 | * 38 | * @return pointer to the allocated memory 39 | * @return NULL on failure 40 | */ 41 | void * hap_platform_memory_malloc(size_t size); 42 | 43 | /** Allocate contiguous memory for items 44 | * 45 | * This API contiguously allocates enough space for "count" objects that are "size" bytes of memory each 46 | * and returns a pointer to the allocated memory. The allocated memory is filled with bytes of value zero. 47 | * 48 | * @param[in] count Number of items 49 | * @param[in] size Size of each item 50 | * 51 | * @return pointer to the allocated memory 52 | * @return NULL on failure 53 | */ 54 | void * hap_platform_memory_calloc(size_t count, size_t size); 55 | 56 | /** Free allocate memory 57 | * 58 | * This API frees the memory allocated by hap_platform_memory_malloc() or hap_platform_memory_calloc() 59 | * 60 | * @param[in] ptr Pointer to the allocated memory 61 | */ 62 | void hap_platform_memory_free(void *ptr); 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | #endif /* _HAP_PLATFORM_MEMORY_H_ */ 68 | -------------------------------------------------------------------------------- /src/hap_platform_os.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2019 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | uint16_t hap_platform_os_get_msec_per_tick() 30 | { 31 | return portTICK_PERIOD_MS; 32 | } 33 | -------------------------------------------------------------------------------- /src/hap_platform_os.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2019 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | #ifndef _HAP_PLATFORM_OS_H_ 25 | #define _HAP_PLATFORM_OS_H_ 26 | #include 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | 32 | /** Return the OS tick period in milliseconds 33 | * 34 | * @return the milliseconds per tick as configured for the OS 35 | */ 36 | uint16_t hap_platform_os_get_msec_per_tick(); 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | #endif /* _HAP_PLATFORM_OS_H_ */ 42 | -------------------------------------------------------------------------------- /src/hap_wac.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ESPRESSIF MIT License 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, 7 | * it is free of charge, to any person obtaining a copy of this software and associated 8 | * documentation files (the "Software"), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the Software is furnished 11 | * to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or 14 | * substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #ifndef _HAP_WAC_H_ 26 | #define _HAP_WAC_H_ 27 | #include 28 | #include 29 | #include 30 | #include 31 | /** HomeKit Event Base */ 32 | ESP_EVENT_DECLARE_BASE(HAP_WAC_EVENT); 33 | /** HomeKit Events */ 34 | typedef enum { 35 | /* WAC has started. Associated data is NULL */ 36 | HAP_WAC_EVENT_STARTED, 37 | /** WAC has timed out because of inactivity. Associated data is NULL. 38 | * Appropriate indications should be given to the user, so that the accessory can be rebooted 39 | * for restarting WAC. 40 | */ 41 | HAP_WAC_EVENT_TIMEOUT, 42 | /** WAC was successful and will stop after some time. Associated data is NULL. 43 | */ 44 | HAP_WAC_EVENT_SUCCESS, 45 | /** WAC is requesting to start SoftAP. Associated data is a pointer to a NULL terminated SSID. 46 | * Using this SSID isn't required, but recommended. The network security should be "Open" for 47 | * WAC to work. If SoftAP has already been started, nothing needs to be done for this event. 48 | * The helper function hap_wifi_softap_start() can be used for this. 49 | */ 50 | HAP_WAC_EVENT_REQ_SOFTAP_START, 51 | /** WAC is requesting to stop SoftAP. Associated data is NULL. 52 | * The helper function hap_wifi_softap_stop() can be used for this. 53 | */ 54 | HAP_WAC_EVENT_REQ_SOFTAP_STOP, 55 | /** WAC has received the Wi-Fi credentials. Associated data is a pointer to wifi_config_t 56 | * structure. This should be used to connect to the Wi-Fi network. 57 | * The helper function hap_wifi_sta_connect() can be used for this. 58 | */ 59 | HAP_WAC_EVENT_RECV_CRED, 60 | /** WAC has stopped */ 61 | HAP_WAC_EVENT_STOPPED 62 | } hap_wac_event_t; 63 | 64 | /** Start WAC Provisioning. 65 | * 66 | * This should be called when the accessory boots up in an unprovisioned mode. 67 | * The helper function hap_wifi_is_provisioned() function can be used to find 68 | * if the accessory is provisioned or not. 69 | * 70 | * @return 0 on success. 71 | * @return -1 on failure. 72 | */ 73 | int hap_wac_start(void); 74 | 75 | /** Stop WAC Provisioning. 76 | * 77 | * This should be used only if WAC needs to be stopped explicitly (say, after 78 | * provisioning was done using some other means). Else, WAC stops automatically, 79 | * either after the timeout or after successful provisioning. 80 | * 81 | * @return 0 on success. 82 | * @return -1 on failure. 83 | */ 84 | int hap_wac_stop(void); 85 | 86 | /** Check is accessory is provisioned 87 | * 88 | * @param[out] provisioned Pointer to an allocated boolean variable. Will 89 | * be set to true if accessory is provisioned, else false. 90 | * 91 | * @return ESP_OK on success. 92 | * @return error on failure. 93 | */ 94 | esp_err_t hap_wifi_is_provisioned(bool *provisioned); 95 | 96 | /** Start SoftAP 97 | * 98 | * @param[in] ssid NULL terminated ssid string. 99 | * 100 | * @return ESP_OK on success. 101 | * @return error on failure. 102 | */ 103 | esp_err_t hap_wifi_softap_start(char *ssid); 104 | 105 | /** Stop Soft AP 106 | * 107 | * @return ESP_OK on success. 108 | * @return error on failure. 109 | */ 110 | esp_err_t hap_wifi_softap_stop(void); 111 | 112 | /** Connect to Wi-Fi network with given configuration 113 | * 114 | * @param[in] config Pointer to \ref wifi_config_t structure. 115 | * 116 | * @return ESP_OK on success. 117 | * @return error on failure. 118 | */ 119 | esp_err_t hap_wifi_sta_connect(wifi_config_t *config); 120 | 121 | #endif /* _HAP_WAC_H_ */ 122 | -------------------------------------------------------------------------------- /src/hexbin.c: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #include 15 | static int hex2bin_byte(uint8_t *byte) 16 | { 17 | if (*byte >= '0' && *byte <= '9') 18 | *byte -= '0'; 19 | else if (*byte >= 'a' && *byte <= 'f') 20 | *byte -= ('a' - 0x0a); 21 | else if (*byte >= 'A' && *byte <= 'F') 22 | *byte -= ('A' - 0x0a); 23 | else 24 | return -1; 25 | return 0; 26 | } 27 | 28 | int hex2bin(const char *ihex, size_t ilen, uint8_t *obin, size_t *olen) 29 | { 30 | if (ilen > (2 * (*olen))) { 31 | return -1; 32 | } else if (ilen % 2) { 33 | return -1; 34 | } 35 | int i, j; 36 | uint8_t byte; 37 | for (i = 0, j = 0; i < ilen / 2; i++) { 38 | byte = ihex[j++]; 39 | if (hex2bin_byte(&byte) < 0) { 40 | return -1; 41 | } 42 | obin[i] = (byte << 4); 43 | byte = ihex[j++]; 44 | if (hex2bin_byte(&byte) < 0) { 45 | return -1; 46 | } 47 | obin[i] |= byte; 48 | } 49 | *olen = i; 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /src/hexbin.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #ifndef _HEXBIN_H_ 15 | #define _HEXBIN_H_ 16 | #include 17 | #include 18 | int hex2bin(const char *ihex, size_t ilen, uint8_t *obin, size_t *olen); 19 | #endif /* _HEXBIN_H_ */ 20 | -------------------------------------------------------------------------------- /src/hexdump.c: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #include 15 | 16 | //#define HEX_DBG_ENABLE 17 | 18 | #ifdef HEX_DBG_ENABLE 19 | void hex_dbg_with_name(char *name, unsigned char *buf, int buf_len) 20 | { 21 | int i; 22 | printf("%s: ", name); 23 | for (i = 0; i < buf_len; i++) { 24 | if (i % 16 == 0) 25 | printf("\r\n"); 26 | printf("%02x ", buf[i]); 27 | } 28 | printf("\r\n"); 29 | } 30 | #else 31 | void hex_dbg_with_name(char *name, unsigned char *buf, int buf_len) 32 | { 33 | } 34 | #endif /* HEX_DBG_ENABLED */ 35 | -------------------------------------------------------------------------------- /src/hexdump.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #ifndef _HEXDUMP_H_ 15 | #define _HEXDUMP_H_ 16 | void hex_dbg_with_name(char *name, unsigned char *buf, int buf_len); 17 | 18 | #endif /* _HEXDUMP_H_ */ 19 | -------------------------------------------------------------------------------- /src/hmac.c: -------------------------------------------------------------------------------- 1 | /**************************** hmac.c ***************************/ 2 | /***************** See RFC 6234 for details. *******************/ 3 | /* Copyright (c) 2011 IETF Trust and the persons identified as */ 4 | /* authors of the code. All rights reserved. */ 5 | /* See sha.h for terms of use and redistribution. */ 6 | 7 | /* 8 | * Description: 9 | * This file implements the HMAC algorithm (Keyed-Hashing for 10 | * Message Authentication, [RFC 2104]), expressed in terms of 11 | * the various SHA algorithms. 12 | */ 13 | 14 | #include "sha.h" 15 | 16 | /* 17 | * hmac 18 | * 19 | * Description: 20 | * This function will compute an HMAC message digest. 21 | * 22 | * Parameters: 23 | * whichSha: [in] 24 | * One of SHA1, SHA224, SHA256, SHA384, SHA512 25 | * message_array[ ]: [in] 26 | * An array of octets representing the message. 27 | * Note: in RFC 2104, this parameter is known 28 | * as 'text'. 29 | * length: [in] 30 | * The length of the message in message_array. 31 | * key[ ]: [in] 32 | * The secret shared key. 33 | * key_len: [in] 34 | * The length of the secret shared key. 35 | * digest[ ]: [out] 36 | * Where the digest is to be returned. 37 | * NOTE: The length of the digest is determined by 38 | * the value of whichSha. 39 | * 40 | * Returns: 41 | * sha Error Code. 42 | * 43 | */ 44 | 45 | int hmac(SHAversion whichSha, 46 | const unsigned char *message_array, int length, 47 | const unsigned char *key, int key_len, 48 | uint8_t digest[USHAMaxHashSize]) 49 | { 50 | HMACContext context; 51 | return hmacReset(&context, whichSha, key, key_len) || 52 | hmacInput(&context, message_array, length) || 53 | hmacResult(&context, digest); 54 | } 55 | 56 | /* 57 | * hmacReset 58 | * 59 | * Description: 60 | * This function will initialize the hmacContext in preparation 61 | * for computing a new HMAC message digest. 62 | * 63 | * Parameters: 64 | * context: [in/out] 65 | * The context to reset. 66 | * whichSha: [in] 67 | * One of SHA1, SHA224, SHA256, SHA384, SHA512 68 | * key[ ]: [in] 69 | * The secret shared key. 70 | * key_len: [in] 71 | * The length of the secret shared key. 72 | * 73 | * Returns: 74 | * sha Error Code. 75 | * 76 | */ 77 | int hmacReset(HMACContext *context, enum SHAversion whichSha, 78 | const unsigned char *key, int key_len) 79 | { 80 | int i, blocksize, hashsize, ret; 81 | 82 | /* inner padding - key XORd with ipad */ 83 | unsigned char k_ipad[USHA_Max_Message_Block_Size]; 84 | 85 | /* temporary buffer when keylen > blocksize */ 86 | unsigned char tempkey[USHAMaxHashSize]; 87 | 88 | if (!context) return shaNull; 89 | context->Computed = 0; 90 | context->Corrupted = shaSuccess; 91 | 92 | blocksize = context->blockSize = USHABlockSize(whichSha); 93 | hashsize = context->hashSize = USHAHashSize(whichSha); 94 | context->whichSha = whichSha; 95 | 96 | /* 97 | * If key is longer than the hash blocksize, 98 | * reset it to key = HASH(key). 99 | */ 100 | if (key_len > blocksize) { 101 | USHAContext tcontext; 102 | int err = USHAReset(&tcontext, whichSha) || 103 | USHAInput(&tcontext, key, key_len) || 104 | USHAResult(&tcontext, tempkey); 105 | if (err != shaSuccess) return err; 106 | 107 | key = tempkey; 108 | key_len = hashsize; 109 | } 110 | 111 | /* 112 | * The HMAC transform looks like: 113 | * 114 | * SHA(K XOR opad, SHA(K XOR ipad, text)) 115 | * 116 | * where K is an n byte key, 0-padded to a total of blocksize bytes, 117 | * ipad is the byte 0x36 repeated blocksize times, 118 | * opad is the byte 0x5c repeated blocksize times, 119 | * and text is the data being protected. 120 | */ 121 | 122 | /* store key into the pads, XOR'd with ipad and opad values */ 123 | for (i = 0; i < key_len; i++) { 124 | k_ipad[i] = key[i] ^ 0x36; 125 | context->k_opad[i] = key[i] ^ 0x5c; 126 | } 127 | /* remaining pad bytes are '\0' XOR'd with ipad and opad values */ 128 | for ( ; i < blocksize; i++) { 129 | k_ipad[i] = 0x36; 130 | context->k_opad[i] = 0x5c; 131 | } 132 | 133 | /* perform inner hash */ 134 | /* init context for 1st pass */ 135 | ret = USHAReset(&context->shaContext, whichSha) || 136 | /* and start with inner pad */ 137 | USHAInput(&context->shaContext, k_ipad, blocksize); 138 | return context->Corrupted = ret; 139 | } 140 | 141 | /* 142 | * hmacInput 143 | * 144 | * Description: 145 | * This function accepts an array of octets as the next portion 146 | * of the message. It may be called multiple times. 147 | * 148 | * Parameters: 149 | * context: [in/out] 150 | * The HMAC context to update. 151 | * text[ ]: [in] 152 | * An array of octets representing the next portion of 153 | * the message. 154 | * text_len: [in] 155 | * The length of the message in text. 156 | * 157 | * Returns: 158 | * sha Error Code. 159 | * 160 | */ 161 | int hmacInput(HMACContext *context, const unsigned char *text, 162 | int text_len) 163 | { 164 | if (!context) return shaNull; 165 | if (context->Corrupted) return context->Corrupted; 166 | if (context->Computed) return context->Corrupted = shaStateError; 167 | /* then text of datagram */ 168 | return context->Corrupted = 169 | USHAInput(&context->shaContext, text, text_len); 170 | } 171 | 172 | /* 173 | * hmacFinalBits 174 | * 175 | * Description: 176 | * This function will add in any final bits of the message. 177 | * 178 | * Parameters: 179 | * context: [in/out] 180 | * The HMAC context to update. 181 | * message_bits: [in] 182 | * The final bits of the message, in the upper portion of the 183 | * byte. (Use 0b###00000 instead of 0b00000### to input the 184 | * three bits ###.) 185 | * length: [in] 186 | * The number of bits in message_bits, between 1 and 7. 187 | * 188 | * Returns: 189 | * sha Error Code. 190 | */ 191 | int hmacFinalBits(HMACContext *context, 192 | uint8_t bits, unsigned int bit_count) 193 | { 194 | if (!context) return shaNull; 195 | if (context->Corrupted) return context->Corrupted; 196 | if (context->Computed) return context->Corrupted = shaStateError; 197 | /* then final bits of datagram */ 198 | return context->Corrupted = 199 | USHAFinalBits(&context->shaContext, bits, bit_count); 200 | } 201 | 202 | /* 203 | * hmacResult 204 | * 205 | * Description: 206 | * This function will return the N-byte message digest into the 207 | * Message_Digest array provided by the caller. 208 | * 209 | * Parameters: 210 | * context: [in/out] 211 | * The context to use to calculate the HMAC hash. 212 | * digest[ ]: [out] 213 | * Where the digest is returned. 214 | * NOTE 2: The length of the hash is determined by the value of 215 | * whichSha that was passed to hmacReset(). 216 | * 217 | * Returns: 218 | * sha Error Code. 219 | * 220 | */ 221 | int hmacResult(HMACContext *context, uint8_t *digest) 222 | { 223 | int ret; 224 | if (!context) return shaNull; 225 | if (context->Corrupted) return context->Corrupted; 226 | if (context->Computed) return context->Corrupted = shaStateError; 227 | 228 | /* finish up 1st pass */ 229 | /* (Use digest here as a temporary buffer.) */ 230 | ret = 231 | USHAResult(&context->shaContext, digest) || 232 | 233 | /* perform outer SHA */ 234 | /* init context for 2nd pass */ 235 | USHAReset(&context->shaContext, context->whichSha) || 236 | 237 | /* start with outer pad */ 238 | USHAInput(&context->shaContext, context->k_opad, 239 | context->blockSize) || 240 | 241 | /* then results of 1st hash */ 242 | USHAInput(&context->shaContext, digest, context->hashSize) || 243 | /* finish up 2nd pass */ 244 | USHAResult(&context->shaContext, digest); 245 | 246 | context->Computed = 1; 247 | return context->Corrupted = ret; 248 | } 249 | 250 | -------------------------------------------------------------------------------- /src/json_generator.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Piyush Shah 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | #define MAX_INT_IN_STR 24 25 | #define MAX_FLOAT_IN_STR 30 26 | 27 | static inline int json_gen_get_empty_len(json_gen_str_t *jstr) 28 | { 29 | return (jstr->buf_size - (jstr->free_ptr - jstr->buf) - 1); 30 | } 31 | 32 | /* This will add the incoming string to the JSON string buffer 33 | * and flush it out if the buffer is full. Note that the data being 34 | * flushed out will always be equal to the size of the buffer unless 35 | * this is the last chunk being flushed out on json_gen_end_str() 36 | */ 37 | static int json_gen_add_to_str(json_gen_str_t *jstr, char *str) 38 | { 39 | if (!str) { 40 | return 0; 41 | } 42 | int len = strlen(str); 43 | char *cur_ptr = str; 44 | while (1) { 45 | int len_remaining = json_gen_get_empty_len(jstr); 46 | int copy_len = len_remaining > len ? len : len_remaining; 47 | memmove(jstr->free_ptr, cur_ptr, copy_len); 48 | cur_ptr += copy_len; 49 | jstr->free_ptr += copy_len; 50 | len -= copy_len; 51 | if (len) { 52 | *jstr->free_ptr = '\0'; 53 | /* Report error if the buffer is full and no flush callback 54 | * is registered 55 | */ 56 | if (!jstr->flush_cb) { 57 | return -1; 58 | } 59 | jstr->flush_cb(jstr->buf, jstr->priv); 60 | jstr->free_ptr = jstr->buf; 61 | } else 62 | break; 63 | } 64 | return 0; 65 | } 66 | 67 | 68 | void json_gen_str_start(json_gen_str_t *jstr, char *buf, int buf_size, 69 | json_gen_flush_cb_t flush_cb, void *priv) 70 | { 71 | memset(jstr, 0, sizeof(json_gen_str_t)); 72 | jstr->buf = buf; 73 | jstr->buf_size = buf_size; 74 | jstr->flush_cb = flush_cb; 75 | jstr->free_ptr = buf; 76 | jstr->priv = priv; 77 | } 78 | 79 | void json_gen_str_end(json_gen_str_t *jstr) 80 | { 81 | *jstr->free_ptr = '\0'; 82 | if (jstr->flush_cb) 83 | jstr->flush_cb(jstr->buf, jstr->priv); 84 | memset(jstr, 0, sizeof(json_gen_str_t)); 85 | } 86 | 87 | static inline void json_gen_handle_comma(json_gen_str_t *jstr) 88 | { 89 | if (jstr->comma_req) 90 | json_gen_add_to_str(jstr, ","); 91 | } 92 | 93 | 94 | static int json_gen_handle_name(json_gen_str_t *jstr, char *name) 95 | { 96 | json_gen_add_to_str(jstr, "\""); 97 | json_gen_add_to_str(jstr, name); 98 | return json_gen_add_to_str(jstr, "\":"); 99 | } 100 | 101 | 102 | int json_gen_start_object(json_gen_str_t *jstr) 103 | { 104 | json_gen_handle_comma(jstr); 105 | jstr->comma_req = false; 106 | return json_gen_add_to_str(jstr, "{"); 107 | } 108 | 109 | int json_gen_end_object(json_gen_str_t *jstr) 110 | { 111 | jstr->comma_req = true; 112 | return json_gen_add_to_str(jstr, "}"); 113 | } 114 | 115 | 116 | int json_gen_start_array(json_gen_str_t *jstr) 117 | { 118 | json_gen_handle_comma(jstr); 119 | jstr->comma_req = false; 120 | return json_gen_add_to_str(jstr, "["); 121 | } 122 | 123 | int json_gen_end_array(json_gen_str_t *jstr) 124 | { 125 | jstr->comma_req = true; 126 | return json_gen_add_to_str(jstr, "]"); 127 | } 128 | 129 | int json_gen_push_object(json_gen_str_t *jstr, char *name) 130 | { 131 | json_gen_handle_comma(jstr); 132 | json_gen_handle_name(jstr, name); 133 | jstr->comma_req = false; 134 | return json_gen_add_to_str(jstr, "{"); 135 | } 136 | 137 | int json_gen_pop_object(json_gen_str_t *jstr) 138 | { 139 | jstr->comma_req = true; 140 | return json_gen_add_to_str(jstr, "}"); 141 | } 142 | 143 | int json_gen_push_object_str(json_gen_str_t *jstr, char *name, char *object_str) 144 | { 145 | json_gen_handle_comma(jstr); 146 | json_gen_handle_name(jstr, name); 147 | jstr->comma_req = true; 148 | return json_gen_add_to_str(jstr, object_str); 149 | } 150 | 151 | int json_gen_push_array(json_gen_str_t *jstr, char *name) 152 | { 153 | json_gen_handle_comma(jstr); 154 | json_gen_handle_name(jstr, name); 155 | jstr->comma_req = false; 156 | return json_gen_add_to_str(jstr, "["); 157 | } 158 | int json_gen_pop_array(json_gen_str_t *jstr) 159 | { 160 | jstr->comma_req = true; 161 | return json_gen_add_to_str(jstr, "]"); 162 | } 163 | 164 | int json_gen_push_array_str(json_gen_str_t *jstr, char *name, char *array_str) 165 | { 166 | json_gen_handle_comma(jstr); 167 | json_gen_handle_name(jstr, name); 168 | jstr->comma_req = true; 169 | return json_gen_add_to_str(jstr, array_str); 170 | } 171 | 172 | static int json_gen_set_bool(json_gen_str_t *jstr, bool val) 173 | { 174 | jstr->comma_req = true; 175 | if (val) 176 | return json_gen_add_to_str(jstr, "true"); 177 | else 178 | return json_gen_add_to_str(jstr, "false"); 179 | } 180 | int json_gen_obj_set_bool(json_gen_str_t *jstr, char *name, bool val) 181 | { 182 | json_gen_handle_comma(jstr); 183 | json_gen_handle_name(jstr, name); 184 | return json_gen_set_bool(jstr, val); 185 | } 186 | 187 | int json_gen_arr_set_bool(json_gen_str_t *jstr, bool val) 188 | { 189 | json_gen_handle_comma(jstr); 190 | return json_gen_set_bool(jstr, val); 191 | } 192 | 193 | static int json_gen_set_int(json_gen_str_t *jstr, int val) 194 | { 195 | jstr->comma_req = true; 196 | char str[MAX_INT_IN_STR]; 197 | snprintf(str, MAX_INT_IN_STR, "%d", val); 198 | return json_gen_add_to_str(jstr, str); 199 | } 200 | 201 | int json_gen_obj_set_int(json_gen_str_t *jstr, char *name, int val) 202 | { 203 | json_gen_handle_comma(jstr); 204 | json_gen_handle_name(jstr, name); 205 | return json_gen_set_int(jstr, val); 206 | } 207 | 208 | int json_gen_arr_set_int(json_gen_str_t *jstr, int val) 209 | { 210 | json_gen_handle_comma(jstr); 211 | return json_gen_set_int(jstr, val); 212 | } 213 | 214 | 215 | static int json_gen_set_float(json_gen_str_t *jstr, float val) 216 | { 217 | jstr->comma_req = true; 218 | char str[MAX_FLOAT_IN_STR]; 219 | snprintf(str, MAX_FLOAT_IN_STR, "%.*f", JSON_FLOAT_PRECISION, val); 220 | return json_gen_add_to_str(jstr, str); 221 | } 222 | int json_gen_obj_set_float(json_gen_str_t *jstr, char *name, float val) 223 | { 224 | json_gen_handle_comma(jstr); 225 | json_gen_handle_name(jstr, name); 226 | return json_gen_set_float(jstr, val); 227 | } 228 | int json_gen_arr_set_float(json_gen_str_t *jstr, float val) 229 | { 230 | json_gen_handle_comma(jstr); 231 | return json_gen_set_float(jstr, val); 232 | } 233 | 234 | static int json_gen_set_string(json_gen_str_t *jstr, char *val) 235 | { 236 | jstr->comma_req = true; 237 | json_gen_add_to_str(jstr, "\""); 238 | json_gen_add_to_str(jstr, val); 239 | return json_gen_add_to_str(jstr, "\""); 240 | } 241 | 242 | int json_gen_obj_set_string(json_gen_str_t *jstr, char *name, char *val) 243 | { 244 | json_gen_handle_comma(jstr); 245 | json_gen_handle_name(jstr, name); 246 | return json_gen_set_string(jstr, val); 247 | } 248 | 249 | int json_gen_arr_set_string(json_gen_str_t *jstr, char *val) 250 | { 251 | json_gen_handle_comma(jstr); 252 | return json_gen_set_string(jstr, val); 253 | } 254 | 255 | static int json_gen_set_long_string(json_gen_str_t *jstr, char *val) 256 | { 257 | jstr->comma_req = true; 258 | json_gen_add_to_str(jstr, "\""); 259 | return json_gen_add_to_str(jstr, val); 260 | } 261 | 262 | int json_gen_obj_start_long_string(json_gen_str_t *jstr, char *name, char *val) 263 | { 264 | json_gen_handle_comma(jstr); 265 | json_gen_handle_name(jstr, name); 266 | return json_gen_set_long_string(jstr, val); 267 | } 268 | 269 | int json_gen_arr_start_long_string(json_gen_str_t *jstr, char *val) 270 | { 271 | json_gen_handle_comma(jstr); 272 | return json_gen_set_long_string(jstr, val); 273 | } 274 | 275 | int json_gen_add_to_long_string(json_gen_str_t *jstr, char *val) 276 | { 277 | return json_gen_add_to_str(jstr, val); 278 | } 279 | 280 | int json_gen_end_long_string(json_gen_str_t *jstr) 281 | { 282 | return json_gen_add_to_str(jstr, "\""); 283 | } 284 | static int json_gen_set_null(json_gen_str_t *jstr) 285 | { 286 | jstr->comma_req = true; 287 | return json_gen_add_to_str(jstr, "null"); 288 | } 289 | int json_gen_obj_set_null(json_gen_str_t *jstr, char *name) 290 | { 291 | json_gen_handle_comma(jstr); 292 | json_gen_handle_name(jstr, name); 293 | return json_gen_set_null(jstr); 294 | } 295 | 296 | int json_gen_arr_set_null(json_gen_str_t *jstr) 297 | { 298 | json_gen_handle_comma(jstr); 299 | return json_gen_set_null(jstr); 300 | } 301 | -------------------------------------------------------------------------------- /src/json_parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Piyush Shah 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef _JSON_PARSER_H_ 17 | #define _JSON_PARSER_H_ 18 | 19 | #define JSMN_HEADER 20 | #include 21 | #include 22 | #include 23 | 24 | #ifdef __cplusplus 25 | extern "C" 26 | { 27 | #endif 28 | 29 | #define OS_SUCCESS 0 30 | #define OS_FAIL -1 31 | 32 | typedef jsmn_parser json_parser_t; 33 | typedef jsmntok_t json_tok_t; 34 | 35 | typedef struct { 36 | json_parser_t parser; 37 | char *js; 38 | json_tok_t *tokens; 39 | json_tok_t *cur; 40 | int num_tokens; 41 | } jparse_ctx_t; 42 | 43 | int json_parse_start(jparse_ctx_t *jctx, char *js, int len); 44 | int json_parse_end(jparse_ctx_t *jctx); 45 | 46 | int json_obj_get_array(jparse_ctx_t *jctx, char *name, int *num_elem); 47 | int json_obj_leave_array(jparse_ctx_t *jctx); 48 | int json_obj_get_object(jparse_ctx_t *jctx, char *name); 49 | int json_obj_leave_object(jparse_ctx_t *jctx); 50 | int json_obj_get_bool(jparse_ctx_t *jctx, char *name, bool *val); 51 | int json_obj_get_int(jparse_ctx_t *jctx, char *name, int *val); 52 | int json_obj_get_int64(jparse_ctx_t *jctx, char *name, int64_t *val); 53 | int json_obj_get_float(jparse_ctx_t *jctx, char *name, float *val); 54 | int json_obj_get_string(jparse_ctx_t *jctx, char *name, char *val, int size); 55 | int json_obj_get_strlen(jparse_ctx_t *jctx, char *name, int *strlen); 56 | int json_obj_get_object_str(jparse_ctx_t *jctx, char *name, char *val, int size); 57 | int json_obj_get_object_strlen(jparse_ctx_t *jctx, char *name, int *strlen); 58 | int json_obj_get_array_str(jparse_ctx_t *jctx, char *name, char *val, int size); 59 | int json_obj_get_array_strlen(jparse_ctx_t *jctx, char *name, int *strlen); 60 | 61 | int json_arr_get_array(jparse_ctx_t *jctx, uint32_t index); 62 | int json_arr_leave_array(jparse_ctx_t *jctx); 63 | int json_arr_get_object(jparse_ctx_t *jctx, uint32_t index); 64 | int json_arr_leave_object(jparse_ctx_t *jctx); 65 | int json_arr_get_bool(jparse_ctx_t *jctx, uint32_t index, bool *val); 66 | int json_arr_get_int(jparse_ctx_t *jctx, uint32_t index, int *val); 67 | int json_arr_get_int64(jparse_ctx_t *jctx, uint32_t index, int64_t *val); 68 | int json_arr_get_float(jparse_ctx_t *jctx, uint32_t index, float *val); 69 | int json_arr_get_string(jparse_ctx_t *jctx, uint32_t index, char *val, int size); 70 | int json_arr_get_strlen(jparse_ctx_t *jctx, uint32_t index, int *strlen); 71 | 72 | #ifdef __cplusplus 73 | } 74 | #endif 75 | 76 | #endif /* _JSON_PARSER_H_ */ 77 | -------------------------------------------------------------------------------- /src/mu_bignum.h: -------------------------------------------------------------------------------- 1 | #ifndef _MU_BIGNUM_H_ 2 | #define _MU_BIGNUM_H_ 3 | 4 | #define BIGNUM_MBEDTLS 5 | 6 | #ifdef BIGNUM_OPENSSL 7 | #include 8 | 9 | 10 | typedef BIGNUM mu_bn_t; 11 | typedef BN_CTX mu_bn_ctx_t; 12 | 13 | 14 | static inline mu_bn_t *mu_bn_new_from_hex(const char *hex) 15 | { 16 | mu_bn_t *a = BN_new(); 17 | if (a) 18 | BN_hex2bn(&a, hex); 19 | return a; 20 | } 21 | 22 | static inline mu_bn_t *mu_bn_new_from_bin(const char *str, int str_len) 23 | { 24 | return BN_bin2bn((unsigned char *)str, str_len, NULL); 25 | } 26 | 27 | static inline mu_bn_t *mu_bn_new() 28 | { 29 | return BN_new(); 30 | } 31 | 32 | static inline void mu_bn_free(mu_bn_t *bn) 33 | { 34 | return BN_free(bn); 35 | } 36 | 37 | static inline mu_bn_ctx_t *mu_bn_ctx_new() 38 | { 39 | return BN_CTX_new(); 40 | } 41 | 42 | static inline void mu_bn_ctx_free(mu_bn_ctx_t *ctx) 43 | { 44 | return BN_CTX_free(ctx); 45 | } 46 | 47 | static inline unsigned int mu_bn_sizeof(mu_bn_t *bn) 48 | { 49 | return BN_num_bytes(bn); 50 | } 51 | 52 | 53 | static inline char *mu_bn_to_bin(mu_bn_t *bn, int *len) 54 | { 55 | *len = mu_bn_sizeof(bn); 56 | char *p = malloc(*len); 57 | if (p) { 58 | BN_bn2bin(bn, (unsigned char *)p); 59 | } 60 | return p; 61 | } 62 | 63 | static inline int mu_bn_get_rand(mu_bn_t *bn, int bits, int top, int bottom) 64 | { 65 | return BN_rand(bn, bits, top, bottom); 66 | } 67 | 68 | static inline int mu_bn_a_exp_b_mod_c(mu_bn_t *result, mu_bn_t *a, mu_bn_t *b, mu_bn_t *c, mu_bn_ctx_t *ctx) 69 | { 70 | return BN_mod_exp(result, a, b, c, ctx); 71 | } 72 | 73 | static inline int mu_bn_a_mul_b_mod_c(mu_bn_t *result, mu_bn_t *a, mu_bn_t *b, mu_bn_t *c, mu_bn_ctx_t *ctx) 74 | { 75 | return BN_mod_mul(result, a, b, c, ctx); 76 | } 77 | 78 | static inline int mu_bn_a_add_b_mod_c(mu_bn_t *result, mu_bn_t *a, mu_bn_t *b, mu_bn_t *c, mu_bn_ctx_t *ctx) 79 | { 80 | if (BN_add(result, a, b) != 1) 81 | return 1; 82 | return BN_mod(result, result, c, ctx); 83 | } 84 | #endif /* BIGNUM_OPENSSL */ 85 | 86 | 87 | #ifdef BIGNUM_MBEDTLS 88 | #include 89 | #include 90 | #ifdef CONFIG_IDF_TARGET_ESP8266 91 | #include 92 | #endif 93 | typedef mbedtls_mpi mu_bn_t; 94 | typedef mu_bn_t mu_bn_ctx_t; 95 | 96 | static inline mu_bn_t *mu_bn_new() 97 | { 98 | mu_bn_t *a = malloc(sizeof (mu_bn_t)); 99 | if (!a) 100 | return NULL; 101 | mbedtls_mpi_init(a); 102 | return a; 103 | } 104 | static inline mu_bn_t *mu_bn_new_from_hex(const char *hex) 105 | { 106 | mu_bn_t *a = mu_bn_new(); 107 | if (!a) 108 | return NULL; 109 | 110 | mbedtls_mpi_read_string(a, 16, hex); 111 | return a; 112 | } 113 | 114 | static inline mu_bn_t *mu_bn_new_from_bin(const char *str, int str_len) 115 | { 116 | 117 | mu_bn_t *a = mu_bn_new(); 118 | if (!a) { 119 | return NULL; 120 | } 121 | mbedtls_mpi_read_binary(a, (unsigned char *)str, str_len); 122 | return a; 123 | } 124 | 125 | 126 | static inline void mu_bn_free(mu_bn_t *bn) 127 | { 128 | if (bn) { 129 | mbedtls_mpi_free(bn); 130 | free(bn); 131 | } 132 | } 133 | 134 | static inline mu_bn_ctx_t *mu_bn_ctx_new() 135 | { 136 | mu_bn_t *bn = mu_bn_new(); 137 | return ( mu_bn_ctx_t *)bn; 138 | } 139 | 140 | static inline void mu_bn_ctx_free(mu_bn_ctx_t *ctx) 141 | { 142 | mu_bn_free((mu_bn_t *)ctx); 143 | } 144 | 145 | static inline unsigned int mu_bn_sizeof(mu_bn_t *bn) 146 | { 147 | return mbedtls_mpi_size(bn); 148 | } 149 | 150 | 151 | static inline char *mu_bn_to_bin(mu_bn_t *bn, int *len) 152 | { 153 | *len = mu_bn_sizeof(bn); 154 | char *p = malloc(*len); 155 | if (p) { 156 | mbedtls_mpi_write_binary(bn, (unsigned char *)p, *len); 157 | } 158 | return p; 159 | } 160 | 161 | static inline int mu_get_random(void *ctx, unsigned char *data, size_t len) 162 | { 163 | esp_fill_random(data, len); 164 | return 0; 165 | } 166 | static inline int mu_bn_get_rand(mu_bn_t *bn, int bits, int top, int bottom) 167 | { 168 | 169 | return mbedtls_mpi_fill_random(bn, bits / 8, mu_get_random, NULL); 170 | } 171 | 172 | #ifdef CONFIG_IDF_TARGET_ESP8266 173 | static inline int mu_bn_a_exp_b_mod_c(mu_bn_t *result, mu_bn_t *a, mu_bn_t *b, mu_bn_t *c, mu_bn_ctx_t *ctx) 174 | { 175 | int ret; 176 | rtc_clk_cpu_freq_set(RTC_CPU_FREQ_160M); 177 | ret = mbedtls_mpi_exp_mod(result, a, b, c, (mu_bn_t *) ctx); 178 | rtc_clk_cpu_freq_set(RTC_CPU_FREQ_80M); 179 | return ret; 180 | } 181 | static inline int mu_bn_a_mul_b_mod_c(mu_bn_t *result, mu_bn_t *a, mu_bn_t *b, mu_bn_t *c, mu_bn_ctx_t *ctx) 182 | { 183 | mbedtls_mpi tmp_result; 184 | rtc_clk_cpu_freq_set(RTC_CPU_FREQ_160M); 185 | mbedtls_mpi_init(&tmp_result); 186 | mbedtls_mpi_mul_mpi(&tmp_result, a, b); 187 | mbedtls_mpi_mod_mpi(result, &tmp_result, c); 188 | mbedtls_mpi_free(&tmp_result); 189 | rtc_clk_cpu_freq_set(RTC_CPU_FREQ_80M); 190 | return 0; 191 | } 192 | #else 193 | 194 | #include "port/bignum.h" 195 | #include "port/bignum_impl.h" 196 | 197 | static inline int mu_bn_a_exp_b_mod_c(mu_bn_t *result, mu_bn_t *a, mu_bn_t *b, mu_bn_t *c, mu_bn_ctx_t *ctx) 198 | { 199 | //return mbedtls_mpi_exp_mod(result, a, b, c, (mu_bn_t *) ctx); 200 | // wangbin changed 201 | printf("esp_mpi_exp_mod\n"); 202 | return esp_mpi_exp_mod(result, a, b, c, (mu_bn_t *) ctx); 203 | } 204 | 205 | 206 | static inline int mu_bn_a_mul_b_mod_c(mu_bn_t *result, mu_bn_t *a, mu_bn_t *b, mu_bn_t *c, mu_bn_ctx_t *ctx) 207 | { 208 | printf("esp_mpi_mul_mpi_mod\n"); 209 | return esp_mpi_mul_mpi_mod(result, a, b, c); 210 | } 211 | #endif /* !CONFIG_IDF_TARGET_ESP8266 */ 212 | 213 | static inline int mu_bn_a_add_b_mod_c(mu_bn_t *result, mu_bn_t *a, mu_bn_t *b, mu_bn_t *c, mu_bn_ctx_t *ctx) 214 | { 215 | int res; 216 | mbedtls_mpi t; 217 | #ifdef CONFIG_IDF_TARGET_ESP8266 218 | rtc_clk_cpu_freq_set(RTC_CPU_FREQ_160M); 219 | #endif 220 | mbedtls_mpi_init(&t); 221 | res = mbedtls_mpi_add_mpi(&t, a, b); 222 | if (res == 0) { 223 | res = mbedtls_mpi_mod_mpi(result, &t, c); 224 | } 225 | mbedtls_mpi_free(&t); 226 | #ifdef CONFIG_IDF_TARGET_ESP8266 227 | rtc_clk_cpu_freq_set(RTC_CPU_FREQ_80M); 228 | #endif 229 | return res; 230 | } 231 | #endif /* BIGNUM_MBEDTLS */ 232 | #endif /* ! _MU_BIGNUM_H_ */ 233 | -------------------------------------------------------------------------------- /src/mu_srp.h: -------------------------------------------------------------------------------- 1 | #ifndef _MU_SRP_H_ 2 | #define _MU_SRP_H_ 3 | 4 | #include 5 | #include "mu_bignum.h" 6 | 7 | typedef enum { 8 | MU_NG_3072 = 0, 9 | } mu_ng_type_t; 10 | 11 | typedef struct mu_srp_handle { 12 | int allocated; 13 | mu_ng_type_t type; 14 | mu_bn_ctx_t *ctx; 15 | 16 | /* N 17 | * the bytes_n simply points to the static array 18 | */ 19 | mu_bn_t *n; 20 | char *bytes_n; 21 | int len_n; 22 | 23 | /* g 24 | * the bytes_g simply points to the static array 25 | */ 26 | mu_bn_t *g; 27 | char *bytes_g; 28 | int len_g; 29 | 30 | /* Salt */ 31 | mu_bn_t *s; 32 | char *bytes_s; 33 | int len_s; 34 | /* Verifier */ 35 | mu_bn_t *v; 36 | /* B */ 37 | mu_bn_t *B; 38 | char *bytes_B; 39 | int len_B; 40 | /* b */ 41 | mu_bn_t *b; 42 | /* A */ 43 | mu_bn_t *A; 44 | char *bytes_A; 45 | int len_A; 46 | /* K - session key*/ 47 | char *session_key; 48 | } mu_srp_handle_t; 49 | 50 | int mu_srp_init(mu_srp_handle_t *hd, mu_ng_type_t ng); 51 | 52 | void mu_srp_free(mu_srp_handle_t *hd); 53 | /* Returns B (pub key) and salt 54 | * 55 | * *bytes_B MUST NOT BE FREED BY THE CALLER 56 | * *bytes_salt MUST NOT BE FREE BY THE CALLER 57 | * 58 | */ 59 | int mu_srp_srv_pubkey(mu_srp_handle_t *hd, const char *username, const char *pass, int pass_len, int salt_len, 60 | char **bytes_B, int *len_B, char **bytes_salt); 61 | 62 | /* Set the Salt and Verifier pre-generated for a given password. 63 | * This should be used only if the actual password is not available. 64 | * The public key can then be generated using mu_srp_srv_pubkey_from_salt_verifier() 65 | * and not mu_srp_srv_pubkey() 66 | */ 67 | int mu_srp_set_salt_verifier(mu_srp_handle_t *hd, const char *salt, int salt_len, 68 | const char *verifier, int verifier_len); 69 | 70 | /* Returns B (pub key) when the salt and verifier are set using mu_srp_set_salt_verifier() 71 | * 72 | * *bytes_B MUST NOT BE FREED BY THE CALLER 73 | */ 74 | int mu_srp_srv_pubkey_from_salt_verifier(mu_srp_handle_t *hd, char **bytes_B, int *len_B); 75 | 76 | /* Returns bytes_key 77 | * *bytes_key MUST NOT BE FREED BY THE CALLER 78 | */ 79 | int mu_srp_get_session_key(mu_srp_handle_t *hd, char *bytes_A, int len_A, char **bytes_key, int *len_key); 80 | 81 | /* Exchange proofs 82 | * Returns 1 if user's proof is ok. Also 1 when is returned, bytes_host_proof contains our proof. 83 | * 84 | * bytes_user_proof is parameter in 85 | * bytes_host_proof is parameter out (should be SHA512_DIGEST_LENGTH) bytes in size 86 | */ 87 | int mu_srp_exchange_proofs(mu_srp_handle_t *hd, char *username, char *bytes_user_proof, char *bytes_host_proof); 88 | 89 | 90 | 91 | #endif /* ! _MU_SRP_H_ */ 92 | -------------------------------------------------------------------------------- /src/port/bignum.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #pragma once 15 | 16 | #include_next "mbedtls/bignum.h" 17 | #include "sdkconfig.h" 18 | 19 | /** 20 | * This is a wrapper for the main mbedtls/bignum.h. This wrapper 21 | * provides a few additional ESP32-only functions. 22 | * 23 | * This is because we don't set MBEDTLS_BIGNUM_ALT in the same way we 24 | * do for AES, SHA, etc. Because we still use most of the bignum.h 25 | * implementation and just replace a few hardware accelerated 26 | * functions (see MBEDTLS_MPI_EXP_MOD_ALT & MBEDTLS_MPI_MUL_MPI_ALT in 27 | * esp_config.h). 28 | * 29 | * @note Unlike the other hardware accelerator support functions in esp32/hwcrypto, there is no 30 | * generic "hwcrypto/bignum.h" header for using these functions without mbedTLS. The reason for this 31 | * is that all of the function implementations depend strongly upon the mbedTLS MPI implementation. 32 | */ 33 | 34 | /** 35 | * @brief Lock access to RSA Accelerator (MPI/bignum operations) 36 | * 37 | * RSA Accelerator hardware unit can only be used by one 38 | * consumer at a time. 39 | * 40 | * @note This function is non-recursive (do not call it twice from the 41 | * same task.) 42 | * 43 | * @note You do not need to call this if you are using the mbedTLS bignum.h 44 | * API or esp_mpi_xxx functions. This function is only needed if you 45 | * want to call ROM RSA functions or access the registers directly. 46 | * 47 | */ 48 | void esp_mpi_acquire_hardware(void); 49 | 50 | /** 51 | * @brief Unlock access to RSA Accelerator (MPI/bignum operations) 52 | * 53 | * Has to be called once for each call to esp_mpi_acquire_hardware(). 54 | * 55 | * @note You do not need to call this if you are using the mbedTLS bignum.h 56 | * API or esp_mpi_xxx functions. This function is only needed if you 57 | * want to call ROM RSA functions or access the registers directly. 58 | */ 59 | void esp_mpi_release_hardware(void); 60 | 61 | //#if CONFIG_MBEDTLS_HARDWARE_MPI 62 | 63 | /* @brief MPI modular mupltiplication function 64 | * 65 | * Calculates Z = (X * Y) mod M using MPI hardware acceleration. 66 | * 67 | * This is not part of the standard mbedTLS bignum API. 68 | * 69 | * @note All of X, Y & Z should be less than 4096 bit long or an error is returned. 70 | * 71 | * @param Z Result bignum, should be pre-initialised with mbedtls_mpi_init(). 72 | * @param X First multiplication argument. 73 | * @param Y Second multiplication argument. 74 | * @param M Modulus value for result. 75 | * 76 | * @return 0 on success, mbedTLS MPI error codes on failure. 77 | */ 78 | int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M); 79 | 80 | //#endif // CONFIG_MBEDTLS_HARDWARE_MPI 81 | -------------------------------------------------------------------------------- /src/port/bignum_impl.h: -------------------------------------------------------------------------------- 1 | #ifndef _ESP_BIGNUM_H_ 2 | #define _ESP_BIGNUM_H_ 3 | 4 | #include 5 | #include 6 | 7 | /* Use montgomery exponentiation (HAC 14.94) for calculating X ^ Y mod M, 8 | this may be faster for some targets. The hardware acceleration support for modular 9 | exponentiation on the ESP32 is slow for public key operations, so use montgomery 10 | exponentiation instead. 11 | */ 12 | 13 | #define CONFIG_IDF_TARGET_ESP32 1 14 | 15 | #if CONFIG_IDF_TARGET_ESP32 16 | #define ESP_MPI_USE_MONT_EXP 17 | 18 | #define MBEDTLS_MPI_EXP_MOD_ALT 19 | //#define MBEDTLS_MPI_MUL_MPI_ALT 20 | #endif 21 | 22 | 23 | int esp_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, mbedtls_mpi *_Rinv ); 24 | 25 | /** 26 | * @brief Enable the MPI hardware and acquire the lock 27 | * 28 | */ 29 | void esp_mpi_enable_hardware_hw_op( void ); 30 | 31 | /** 32 | * @brief Disable the MPI hardware and release the lock 33 | * 34 | */ 35 | void esp_mpi_disable_hardware_hw_op( void ); 36 | 37 | /** 38 | * @brief Calculate the number of words needed to represent the input word in hardware 39 | * 40 | * @param words The number of words to be represented 41 | * 42 | * @return size_t Number of words required 43 | */ 44 | size_t esp_mpi_hardware_words(size_t words); 45 | 46 | /** 47 | * @brief Starts a (X * Y) Mod M calculation in hardware. Rinv and M_prime needs to be precalculated in software. 48 | * 49 | */ 50 | void esp_mpi_mul_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t hw_words); 51 | 52 | /** 53 | * @brief Starts a (X * Y) calculation in hardware. 54 | * 55 | */ 56 | void esp_mpi_mul_mpi_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words); 57 | 58 | /** 59 | * @brief Special-case of (X * Y), where we use hardware montgomery mod 60 | multiplication to calculate result where either A or B are >2048 bits so 61 | can't use the standard multiplication method. 62 | * 63 | */ 64 | void esp_mpi_mult_mpi_failover_mod_mult_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words); 65 | 66 | /** 67 | * @brief Read out the result from the previous calculation. 68 | * 69 | */ 70 | void esp_mpi_read_result_hw_op(mbedtls_mpi *Z, size_t z_words); 71 | 72 | #ifdef ESP_MPI_USE_MONT_EXP 73 | /** 74 | * @brief Starts a montgomery multiplication calculation in hardware 75 | * 76 | */ 77 | int esp_mont_hw_op(mbedtls_mpi* Z, const mbedtls_mpi* X, const mbedtls_mpi* Y, const mbedtls_mpi* M, 78 | mbedtls_mpi_uint Mprime, 79 | size_t hw_words, 80 | bool again); 81 | 82 | #else 83 | 84 | /** 85 | * @brief Starts a (X ^ Y) Mod M calculation in hardware. Rinv and M_prime needs to be precalculated in software. 86 | * 87 | */ 88 | void esp_mpi_exp_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t hw_words); 89 | 90 | #endif //ESP_MPI_USE_MONT_EXP 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /src/sha-private.h: -------------------------------------------------------------------------------- 1 | /************************ sha-private.h ************************/ 2 | /***************** See RFC 6234 for details. *******************/ 3 | #ifndef _SHA_PRIVATE__H 4 | #define _SHA_PRIVATE__H 5 | /* 6 | * These definitions are defined in FIPS 180-3, section 4.1. 7 | * Ch() and Maj() are defined identically in sections 4.1.1, 8 | * 4.1.2, and 4.1.3. 9 | * 10 | * The definitions used in FIPS 180-3 are as follows: 11 | */ 12 | 13 | #ifndef USE_MODIFIED_MACROS 14 | #define SHA_Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) 15 | #define SHA_Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 16 | #else /* USE_MODIFIED_MACROS */ 17 | /* 18 | * The following definitions are equivalent and potentially faster. 19 | */ 20 | 21 | #define SHA_Ch(x, y, z) (((x) & ((y) ^ (z))) ^ (z)) 22 | #define SHA_Maj(x, y, z) (((x) & ((y) | (z))) | ((y) & (z))) 23 | 24 | #endif /* USE_MODIFIED_MACROS */ 25 | 26 | #define SHA_Parity(x, y, z) ((x) ^ (y) ^ (z)) 27 | 28 | #endif /* _SHA_PRIVATE__H */ 29 | 30 | -------------------------------------------------------------------------------- /src/usha.c: -------------------------------------------------------------------------------- 1 | /**************************** usha.c ***************************/ 2 | /***************** See RFC 6234 for details. *******************/ 3 | /* Copyright (c) 2011 IETF Trust and the persons identified as */ 4 | /* authors of the code. All rights reserved. */ 5 | /* See sha.h for terms of use and redistribution. */ 6 | 7 | /* 8 | * Description: 9 | * This file implements a unified interface to the SHA algorithms. 10 | */ 11 | 12 | #include "sha.h" 13 | 14 | /* 15 | * USHAReset 16 | * 17 | * Description: 18 | * This function will initialize the SHA Context in preparation 19 | * for computing a new SHA message digest. 20 | * 21 | * Parameters: 22 | * context: [in/out] 23 | * The context to reset. 24 | * whichSha: [in] 25 | * Selects which SHA reset to call 26 | * 27 | * Returns: 28 | * sha Error Code. 29 | * 30 | */ 31 | int USHAReset(USHAContext *context, enum SHAversion whichSha) 32 | { 33 | if (!context) return shaNull; 34 | context->whichSha = whichSha; 35 | switch (whichSha) { 36 | case SHA1: return SHA1Reset((SHA1Context*)&context->ctx); 37 | case SHA224: return SHA224Reset((SHA224Context*)&context->ctx); 38 | case SHA256: return SHA256Reset((SHA256Context*)&context->ctx); 39 | case SHA384: return SHA384Reset((SHA384Context*)&context->ctx); 40 | case SHA512: return SHA512Reset((SHA512Context*)&context->ctx); 41 | default: return shaBadParam; 42 | } 43 | } 44 | 45 | /* 46 | * USHAInput 47 | * 48 | * Description: 49 | * This function accepts an array of octets as the next portion 50 | * of the message. 51 | * 52 | * Parameters: 53 | * context: [in/out] 54 | * The SHA context to update. 55 | * message_array: [in] 56 | * An array of octets representing the next portion of 57 | * the message. 58 | * length: [in] 59 | * The length of the message in message_array. 60 | * 61 | * Returns: 62 | * sha Error Code. 63 | * 64 | */ 65 | int USHAInput(USHAContext *context, 66 | const uint8_t *bytes, unsigned int bytecount) 67 | { 68 | if (!context) return shaNull; 69 | switch (context->whichSha) { 70 | case SHA1: 71 | return SHA1Input((SHA1Context*)&context->ctx, bytes, 72 | bytecount); 73 | case SHA224: 74 | return SHA224Input((SHA224Context*)&context->ctx, bytes, 75 | bytecount); 76 | case SHA256: 77 | return SHA256Input((SHA256Context*)&context->ctx, bytes, 78 | bytecount); 79 | case SHA384: 80 | return SHA384Input((SHA384Context*)&context->ctx, bytes, 81 | bytecount); 82 | case SHA512: 83 | return SHA512Input((SHA512Context*)&context->ctx, bytes, 84 | bytecount); 85 | default: return shaBadParam; 86 | } 87 | } 88 | 89 | /* 90 | * USHAFinalBits 91 | * 92 | * Description: 93 | * This function will add in any final bits of the message. 94 | * 95 | * Parameters: 96 | * context: [in/out] 97 | * The SHA context to update. 98 | * message_bits: [in] 99 | * The final bits of the message, in the upper portion of the 100 | * byte. (Use 0b###00000 instead of 0b00000### to input the 101 | * three bits ###.) 102 | * length: [in] 103 | * The number of bits in message_bits, between 1 and 7. 104 | * 105 | * Returns: 106 | * sha Error Code. 107 | */ 108 | int USHAFinalBits(USHAContext *context, 109 | uint8_t bits, unsigned int bit_count) 110 | { 111 | if (!context) return shaNull; 112 | switch (context->whichSha) { 113 | case SHA1: 114 | return SHA1FinalBits((SHA1Context*)&context->ctx, bits, 115 | bit_count); 116 | case SHA224: 117 | return SHA224FinalBits((SHA224Context*)&context->ctx, bits, 118 | bit_count); 119 | case SHA256: 120 | return SHA256FinalBits((SHA256Context*)&context->ctx, bits, 121 | bit_count); 122 | case SHA384: 123 | return SHA384FinalBits((SHA384Context*)&context->ctx, bits, 124 | bit_count); 125 | case SHA512: 126 | return SHA512FinalBits((SHA512Context*)&context->ctx, bits, 127 | bit_count); 128 | default: return shaBadParam; 129 | } 130 | } 131 | 132 | /* 133 | * USHAResult 134 | * 135 | * Description: 136 | * This function will return the message digest of the appropriate 137 | * bit size, as returned by USHAHashSizeBits(whichSHA) for the 138 | * 'whichSHA' value used in the preceeding call to USHAReset, 139 | * into the Message_Digest array provided by the caller. 140 | * 141 | * Parameters: 142 | * context: [in/out] 143 | * The context to use to calculate the SHA-1 hash. 144 | * Message_Digest: [out] 145 | * Where the digest is returned. 146 | * 147 | * Returns: 148 | * sha Error Code. 149 | * 150 | */ 151 | int USHAResult(USHAContext *context, 152 | uint8_t Message_Digest[USHAMaxHashSize]) 153 | { 154 | if (!context) return shaNull; 155 | switch (context->whichSha) { 156 | case SHA1: 157 | return SHA1Result((SHA1Context*)&context->ctx, Message_Digest); 158 | case SHA224: 159 | return SHA224Result((SHA224Context*)&context->ctx, 160 | Message_Digest); 161 | case SHA256: 162 | return SHA256Result((SHA256Context*)&context->ctx, 163 | Message_Digest); 164 | case SHA384: 165 | return SHA384Result((SHA384Context*)&context->ctx, 166 | Message_Digest); 167 | case SHA512: 168 | return SHA512Result((SHA512Context*)&context->ctx, 169 | Message_Digest); 170 | default: return shaBadParam; 171 | } 172 | } 173 | 174 | /* 175 | * USHABlockSize 176 | * 177 | * Description: 178 | * This function will return the blocksize for the given SHA 179 | * algorithm. 180 | * 181 | * Parameters: 182 | * whichSha: 183 | * which SHA algorithm to query 184 | * 185 | * Returns: 186 | * block size 187 | * 188 | */ 189 | int USHABlockSize(enum SHAversion whichSha) 190 | { 191 | switch (whichSha) { 192 | case SHA1: return SHA1_Message_Block_Size; 193 | case SHA224: return SHA224_Message_Block_Size; 194 | case SHA256: return SHA256_Message_Block_Size; 195 | case SHA384: return SHA384_Message_Block_Size; 196 | default: 197 | case SHA512: return SHA512_Message_Block_Size; 198 | } 199 | } 200 | 201 | /* 202 | * USHAHashSize 203 | * 204 | * Description: 205 | * This function will return the hashsize for the given SHA 206 | * algorithm. 207 | * 208 | * Parameters: 209 | * whichSha: 210 | * which SHA algorithm to query 211 | * 212 | * Returns: 213 | * hash size 214 | * 215 | */ 216 | int USHAHashSize(enum SHAversion whichSha) 217 | { 218 | switch (whichSha) { 219 | case SHA1: return SHA1HashSize; 220 | case SHA224: return SHA224HashSize; 221 | case SHA256: return SHA256HashSize; 222 | case SHA384: return SHA384HashSize; 223 | default: 224 | case SHA512: return SHA512HashSize; 225 | } 226 | } 227 | 228 | /* 229 | * USHAHashSizeBits 230 | * 231 | * Description: 232 | * This function will return the hashsize for the given SHA 233 | * algorithm, expressed in bits. 234 | * 235 | * Parameters: 236 | * whichSha: 237 | * which SHA algorithm to query 238 | * 239 | * Returns: 240 | * hash size in bits 241 | * 242 | */ 243 | int USHAHashSizeBits(enum SHAversion whichSha) 244 | { 245 | switch (whichSha) { 246 | case SHA1: return SHA1HashSizeBits; 247 | case SHA224: return SHA224HashSizeBits; 248 | case SHA256: return SHA256HashSizeBits; 249 | case SHA384: return SHA384HashSizeBits; 250 | default: 251 | case SHA512: return SHA512HashSizeBits; 252 | } 253 | } 254 | 255 | /* 256 | * USHAHashName 257 | * 258 | * Description: 259 | * This function will return the name of the given SHA algorithm 260 | * as a string. 261 | * 262 | * Parameters: 263 | * whichSha: 264 | * which SHA algorithm to query 265 | * 266 | * Returns: 267 | * character string with the name in it 268 | * 269 | */ 270 | const char *USHAHashName(enum SHAversion whichSha) 271 | { 272 | switch (whichSha) { 273 | case SHA1: return "SHA1"; 274 | case SHA224: return "SHA224"; 275 | case SHA256: return "SHA256"; 276 | case SHA384: return "SHA384"; 277 | default: 278 | case SHA512: return "SHA512"; 279 | } 280 | } 281 | 282 | --------------------------------------------------------------------------------