From 55d7c8dff12d9e9e3294ac62d5dd0ad68ea3dd16 Mon Sep 17 00:00:00 2001 From: zhangyanlu Date: Wed, 22 Jun 2016 10:53:09 +0800 Subject: [PATCH 1/9] fix identity,fix announce work with ios10 --- PHKAccessory.cpp | 3 ++- PHKNetworkIP.cpp | 12 ++++++++++++ main.cpp | 2 +- makefile | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/PHKAccessory.cpp b/PHKAccessory.cpp index 32f645a..34829ba 100755 --- a/PHKAccessory.cpp +++ b/PHKAccessory.cpp @@ -323,7 +323,8 @@ void *announce(void *info) { printf("%s\n", reply); #endif - broadcastMessage(sender, reply, len); + //broadcastMessage(sender, reply, len); + delete [] reply; delete [] desc; diff --git a/PHKNetworkIP.cpp b/PHKNetworkIP.cpp index 8668226..d56e550 100644 --- a/PHKNetworkIP.cpp +++ b/PHKNetworkIP.cpp @@ -80,6 +80,17 @@ deviceType currentDeviceType = deviceType_other; int currentConfigurationNum = 1; +void write204(int sock) { + char *reply = new char[1024]; + int len = + snprintf(reply, 1024, + "HTTP/1.1 204 No Content\r\nContent-Type: application/hap+json\r\nContent-Length: 0\r\n\r\n"); + + write(sock, reply, len); + delete[] reply; + +} + int is_big_endian(void) { union { @@ -269,6 +280,7 @@ void *connectionLoop(void *threadInfo) { info->handleAccessoryRequest(); } else if (!strcmp(msg.directory, "identify")){ + write204(subSocket); close(subSocket); } } diff --git a/main.cpp b/main.cpp index 867b49a..a84e856 100644 --- a/main.cpp +++ b/main.cpp @@ -69,7 +69,7 @@ int main(int argc, const char * argv[]) { } initAccessorySet(); - setupPort(); + //setupPort(); PHKNetworkIP networkIP; do { diff --git a/makefile b/makefile index f2cf028..f5e8086 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,5 @@ LINK = -lssl -lcrypto -ldl -lpthread -CFLAG = -Os -s +CFLAG = -Os -s -I/usr/local/ssl/include/ -I/usr/local/include/ -I/usr/local/include/avahi-compat-libdns_sd/ CC = gcc CPP = g++ PHK_LIBNAME=libphk From b48938c3e641d42f17ced022e6a63cdbe8b0d9f1 Mon Sep 17 00:00:00 2001 From: rti Date: Thu, 24 Nov 2016 06:01:50 +0900 Subject: [PATCH 2/9] Support Windows (Visual Studio 10) --- windows_support_include/pthread.h | 56 +++++++++++++++ windows_support_include/strings.h | 9 +++ windows_support_include/unistd.h | 115 ++++++++++++++++++++++++++++++ 3 files changed, 180 insertions(+) create mode 100755 windows_support_include/pthread.h create mode 100755 windows_support_include/strings.h create mode 100755 windows_support_include/unistd.h diff --git a/windows_support_include/pthread.h b/windows_support_include/pthread.h new file mode 100755 index 0000000..24cec99 --- /dev/null +++ b/windows_support_include/pthread.h @@ -0,0 +1,56 @@ +#pragma once +//simple pthread emulation by rti + +#include +#include + +typedef CRITICAL_SECTION pthread_mutex_t; + +static void pthread_mutex_init(pthread_mutex_t* mutex, void* nazo) +{ + InitializeCriticalSection(mutex); +} + +static void pthread_mutex_destroy(pthread_mutex_t* mutex) +{ + DeleteCriticalSection(mutex); +} + +static void pthread_mutex_lock(pthread_mutex_t* mutex) +{ + EnterCriticalSection(mutex); +} + +static void pthread_mutex_unlock(pthread_mutex_t* mutex) +{ + LeaveCriticalSection(mutex); +} + +struct _threadcallback{ + static unsigned int __stdcall call(void* arg){ + _threadcallback* _this = ((_threadcallback*)arg); + _this->start_routine(_this->arg); + + delete _this; + return 0; + } + + void *(*start_routine) (void *); + void *arg; +}; + +typedef HANDLE pthread_t; +typedef void* pthread_attr_t; +static void pthread_create(pthread_t* thread, const pthread_attr_t *attr_null,void *(*start_routine) (void *), void *arg) +{ + _threadcallback* c = new _threadcallback; + c->start_routine = start_routine; + c->arg = arg; + + *thread = (HANDLE)_beginthreadex(NULL , 0 , _threadcallback::call , (void*)c , 0 ,NULL ); +} + +static void pthread_join(pthread_t* thread,void * nazo) +{ + ::WaitForSingleObject( thread , INFINITE); +} diff --git a/windows_support_include/strings.h b/windows_support_include/strings.h new file mode 100755 index 0000000..6d73762 --- /dev/null +++ b/windows_support_include/strings.h @@ -0,0 +1,9 @@ +#pragma once + +#define bzero(b,len) (memset((b), '\0', (len)), (void) 0) +#define bcopy(b1,b2,len) (memmove((b2), (b1), (len)), (void) 0) +#define bcmp(b1,b2,len) (memcmp(b1,b2,len)) +#define snprintf _snprintf +#define strtok_r strtok_s + +#define __func__ __FUNCTION__ diff --git a/windows_support_include/unistd.h b/windows_support_include/unistd.h new file mode 100755 index 0000000..9c7725c --- /dev/null +++ b/windows_support_include/unistd.h @@ -0,0 +1,115 @@ +// in windows +//orignal soruce code: http://d.hatena.ne.jp/deraw/20070517/1179334643 +#ifndef _UNISTD_H_ +#define _UNISTD_H_ +#ifdef _WIN32 +#pragma once + +#include +/* +access +chmod +chsize +close +creat +dup +dup2 +eof +filelength +isatty +locking +lseek +mktemp +open +read +setmode +sopen +tell +umask +unlink +write +*/ +#include +/* +chdir +getcwd +mkdir +rmdir +*/ +#include +/* +cwait +execl +execle +execlp +execlpe +execv +execve +execvp +execvpe +spawnl +spawnle +spawnlp +spawnlpe +spawnv +spawnve +spawnvp +spawnvpe + +*/ +#pragma comment( lib, "ws2_32" ) +#include +/* +gethostname +*/ + +#include +/* +_getpid +*/ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int pid_t; /* process id type */ + +#ifndef _SSIZE_T_DEFINED +typedef int ssize_t; +#define _SSIZE_T_DEFINED +#endif + +#ifndef vsnprintf +#define vsnprintf _vsnprintf +#endif + +#ifndef snprintf +#define snprintf _snprintf +#endif + + +#define nice(incr) (SetPriorityClass(GetCurrentProcess(),incr))//TODO +#define sleep(seconds) (Sleep(seconds*1000)) +#define usleep(useconds) (Sleep(useconds)) + +#define stime(tp) UNISTD_stime(tp) +__forceinline int UNISTD_stime(const time_t *tp ){ + FILETIME ft; + SYSTEMTIME st; + LONGLONG ll = Int32x32To64(*tp, 10000000) + 116444736000000000; + ft.dwLowDateTime = (DWORD) ll; + ft.dwHighDateTime = (DWORD)(ll >>32); + FileTimeToSystemTime(&ft,&st); + return SetSystemTime(&st); +} + +// +#define fstat64(fildes, stat) (_fstati64(fildes, stat)) +#define stat64(path, buffer) (_stati64(path,buffer)) + +#ifdef __cplusplus +} +#endif +#endif /* _WIN32 */ +#endif /* _UNISTD_H_ */ From c4098d03eec330e93cbd883aff4c97f041b0d1e9 Mon Sep 17 00:00:00 2001 From: rti Date: Thu, 24 Nov 2016 06:19:22 +0900 Subject: [PATCH 3/9] Support Windows (visual studio) I forgot to add. --- Chacha20/chacha20_simple.c | 8 +- Configuration.h | 10 ++ PHKAccessory.cpp | 4 +- PHKAccessory.h | 67 ++++++--- PHKNetworkIP.cpp | 62 ++++++--- PHKNetworkIP.h | 55 ++++++-- Personal-HomeKit-HAP.vcxproj | 140 +++++++++++++++++++ Personal-HomeKit-HAP.vcxproj.filters | 201 +++++++++++++++++++++++++++ Personal-HomeKit-HAP.vcxproj.user | 3 + ed25519-donna/ed25519.c | 3 +- main.cpp | 19 ++- srp/srp.h | 80 +++++------ srp/srp6_server.c | 2 +- srp/t_defines.h | 15 +- srp/t_misc.c | 6 +- 15 files changed, 571 insertions(+), 104 deletions(-) mode change 100644 => 100755 Chacha20/chacha20_simple.c mode change 100644 => 100755 Configuration.h mode change 100644 => 100755 PHKNetworkIP.cpp mode change 100644 => 100755 PHKNetworkIP.h create mode 100755 Personal-HomeKit-HAP.vcxproj create mode 100755 Personal-HomeKit-HAP.vcxproj.filters create mode 100755 Personal-HomeKit-HAP.vcxproj.user mode change 100644 => 100755 main.cpp diff --git a/Chacha20/chacha20_simple.c b/Chacha20/chacha20_simple.c old mode 100644 new mode 100755 index dfe9471..c84569b --- a/Chacha20/chacha20_simple.c +++ b/Chacha20/chacha20_simple.c @@ -19,6 +19,12 @@ This implementation is intended to be simple, many optimizations can be performe #include #include "chacha20_simple.h" +#ifdef _WIN32 + #define INLINE +#else + #define INLINE inline +#endif + void chacha20_setup(chacha20_ctx *ctx, const uint8_t *key, size_t length, uint8_t nonce[8]) { const char *constants = (length == 32) ? "expand 32-byte k" : "expand 16-byte k"; @@ -123,7 +129,7 @@ void chacha20_encrypt(chacha20_ctx *ctx, const uint8_t *in, uint8_t *out, size_t } } -void chacha20_decrypt(chacha20_ctx *ctx, const uint8_t *in, uint8_t *out, size_t length) +void INLINE chacha20_decrypt(chacha20_ctx *ctx, const uint8_t *in, uint8_t *out, size_t length) { chacha20_encrypt(ctx, in, out, length); } diff --git a/Configuration.h b/Configuration.h old mode 100644 new mode 100755 index a59b45d..2bfe087 --- a/Configuration.h +++ b/Configuration.h @@ -17,7 +17,11 @@ #define _manufactuerName "ET Chan" //Manufactuer #define devicePassword "523-12-643" //Password #define deviceUUID "62F47751-8F26-46BF-9552-8F4238E67D60" //UUID, for pair verify +#ifdef _WIN32 +#define controllerRecordsAddress "PHK_controller" //Where to store the client keys +#else #define controllerRecordsAddress "/var/PHK_controller" //Where to store the client keys +#endif //Number of client /* @@ -38,6 +42,12 @@ #include #include + +#ifdef WIN32 +#include +#include +#else +#endif #include typedef SHA512_CTX SHACTX; diff --git a/PHKAccessory.cpp b/PHKAccessory.cpp index 2a510f5..a8c2b40 100755 --- a/PHKAccessory.cpp +++ b/PHKAccessory.cpp @@ -328,6 +328,8 @@ void *announce(void *info) { delete [] desc; delete [] info; + + return NULL; } void updateValueFromDeviceEnd(characteristics *c, int aid, int iid, string value) { @@ -378,7 +380,7 @@ void handleAccessory(const char *request, unsigned int requestLen, char **reply, char *replyData = NULL; unsigned short replyDataLen = 0; - int statusCode; + int statusCode = 0; const char *protocol = "HTTP/1.1"; const char *returnType = hapJsonType; diff --git a/PHKAccessory.h b/PHKAccessory.h index 6ef068c..07c2dde 100755 --- a/PHKAccessory.h +++ b/PHKAccessory.h @@ -93,7 +93,7 @@ typedef enum { charType_videoRotation = 0x3C, charType_videoValAttr = 0x3D, -#pragma - The following is only default by the device after iOS 9 +//#pragma - The following is only default by the device after iOS 9 charType_firmwareRevision = 0x52, charType_hardwareRevision = 0x53, @@ -140,7 +140,7 @@ typedef enum { charType_sensorChargingState= 0x8F, -#pragma - The following is service provide +//#pragma - The following is service provide serviceType_accessoryInfo = 0x3E, serviceType_camera = 0x3F, serviceType_fan = 0x40, @@ -177,13 +177,13 @@ typedef enum { serviceType_battery = 0x96, serviceType_carbonDioxideSensor= 0x97, -#pragma - The following is for bluetooth characteristic +//#pragma - The following is for bluetooth characteristic btCharType_pairSetup = 0x4C, btCharType_pairVerify = 0x4E, btCharType_pairingFeature = 0x4F, btCharType_pairings = 0x50, btCharType_serviceInstanceID = 0x51, -#pragma - The following is for bluetooth service +//#pragma - The following is for bluetooth service btServiceType_accessoryInformation = 0xFED3, btServiceType_camera = 0xFEC9, btServiceType_fan = 0xFECB, @@ -230,8 +230,12 @@ class characteristics { class boolCharacteristics: public characteristics { public: bool _value; - void (*valueChangeFunctionCall)(bool oldValue, bool newValue) = NULL; - boolCharacteristics(unsigned short _type, int _premission): characteristics(_type, _premission) {} + void (*valueChangeFunctionCall)(bool oldValue, bool newValue); + boolCharacteristics(unsigned short _type, int _premission) + : valueChangeFunctionCall(NULL) + , characteristics(_type, _premission) + { + } virtual string value() { if (_value) return "1"; @@ -251,15 +255,23 @@ class floatCharacteristics: public characteristics { float _value; const float _minVal, _maxVal, _step; const unit _unit; - void (*valueChangeFunctionCall)(float oldValue, float newValue) = NULL; - floatCharacteristics(unsigned short _type, int _premission, float minVal, float maxVal, float step, unit charUnit): characteristics(_type, _premission), _minVal(minVal), _maxVal(maxVal), _step(step), _unit(charUnit) {} + void (*valueChangeFunctionCall)(float oldValue, float newValue); + floatCharacteristics(unsigned short _type, int _premission, float minVal, float maxVal, float step, unit charUnit) + : valueChangeFunctionCall(NULL) + ,characteristics(_type, _premission) + , _minVal(minVal) + , _maxVal(maxVal) + , _step(step) + , _unit(charUnit) + { + } virtual string value() { char temp[16]; snprintf(temp, 16, "%f", _value); return temp; } virtual void setValue(string str) { - float temp = atof(str.c_str()); + float temp = (float) atof(str.c_str()); if (temp == temp) { if (valueChangeFunctionCall) valueChangeFunctionCall(_value, temp); @@ -274,9 +286,16 @@ class intCharacteristics: public characteristics { int _value; const int _minVal, _maxVal, _step; const unit _unit; - void (*valueChangeFunctionCall)(int oldValue, int newValue) = NULL; - intCharacteristics(unsigned short _type, int _premission, int minVal, int maxVal, int step, unit charUnit): characteristics(_type, _premission), _minVal(minVal), _maxVal(maxVal), _step(step), _unit(charUnit) { - _value = minVal; + void (*valueChangeFunctionCall)(int oldValue, int newValue); + intCharacteristics(unsigned short _type, int _premission, int minVal, int maxVal, int step, unit charUnit) + : valueChangeFunctionCall(NULL) + , characteristics(_type, _premission) + , _minVal(minVal) + , _maxVal(maxVal) + , _step(step) + , _unit(charUnit) + { + _value = minVal; } virtual string value() { char temp[16]; @@ -284,11 +303,11 @@ class intCharacteristics: public characteristics { return temp; } virtual void setValue(string str) { - float temp = atoi(str.c_str()); + float temp = (float)atoi(str.c_str()); if (temp == temp) { if (valueChangeFunctionCall) - valueChangeFunctionCall(_value, temp); - _value = temp; + valueChangeFunctionCall(_value, (int)temp); + _value = (int) temp; } } virtual string describe(); @@ -298,8 +317,13 @@ class stringCharacteristics: public characteristics { public: string _value; const unsigned short maxLen; - void (*valueChangeFunctionCall)(string oldValue, string newValue) = NULL; - stringCharacteristics(unsigned short _type, int _premission, unsigned short _maxLen): characteristics(_type, _premission), maxLen(_maxLen) {} + void (*valueChangeFunctionCall)(string oldValue, string newValue); + stringCharacteristics(unsigned short _type, int _premission, unsigned short _maxLen) + : valueChangeFunctionCall(NULL) + , characteristics(_type, _premission) + , maxLen(_maxLen) + { + } virtual string value() { return "\""+_value+"\""; } @@ -324,7 +348,7 @@ class Service { class Accessory { public: - int numberOfInstance = 0; + int numberOfInstance; int aid; vector_services; void addService(Service *ser) { @@ -357,7 +381,9 @@ class Accessory { } return exist; } - Accessory() {} + Accessory() : numberOfInstance (0) + { + } short numberOfService() { return _services.size(); } Service *serviceAtIndex(int index) { for (vector::iterator it = _services.begin(); it != _services.end(); it++) { @@ -383,8 +409,9 @@ class Accessory { class AccessorySet { private: vector _accessories; - int _aid = 0; + int _aid; AccessorySet() { + _aid = 0; pthread_mutex_init(&accessoryMutex, NULL); } AccessorySet(AccessorySet const&); diff --git a/PHKNetworkIP.cpp b/PHKNetworkIP.cpp old mode 100644 new mode 100755 index 8668226..e79d0fe --- a/PHKNetworkIP.cpp +++ b/PHKNetworkIP.cpp @@ -9,6 +9,8 @@ #include "PHKNetworkIP.h" #define PHKNetworkServiceType "_hap._tcp" + +#include #include #include #include @@ -73,8 +75,13 @@ char tempStr[3073]; const unsigned char accessorySecretKey[32] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74}; -int _socket_v4, _socket_v6; -DNSServiceRef netServiceV4, netServiceV6; +int _socket_v4; +DNSServiceRef netServiceV4; +#ifdef _WIN32 +#else +int _socket_v6; +DNSServiceRef netServiceV6; +#endif deviceType currentDeviceType = deviceType_other; @@ -97,13 +104,15 @@ int setupSocketV4(unsigned int maximumConnection) { addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_family = PF_INET; addr.sin_port = htons(portNumber); int optval = 1; socklen_t optlen = sizeof(optval); - setsockopt(_socket, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen); + setsockopt(_socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&optval, optlen); bind(_socket, (const struct sockaddr *)&addr, sizeof(addr)); listen(_socket, maximumConnection); return _socket; } +#ifdef _WIN32 +#else int setupSocketV6(unsigned int maximumConnection) { int _socket = socket(PF_INET6, SOCK_STREAM, 0); sockaddr_in6 addr; bzero(&addr, sizeof(addr)); @@ -112,6 +121,7 @@ int setupSocketV6(unsigned int maximumConnection) { listen(_socket, maximumConnection); return _socket; } +#endif unsigned short getSocketPortNumberV4(int _socket) { sockaddr_in addr; socklen_t len = sizeof(addr); @@ -119,11 +129,14 @@ unsigned short getSocketPortNumberV4(int _socket) { return ntohs(addr.sin_port); } +#ifdef _WIN32 +#else unsigned short getSocketPortNumberV6(int _socket) { sockaddr_in6 addr; socklen_t len = sizeof(addr); getsockname(_socket, (struct sockaddr *)&addr, &len); return ntohs(addr.sin6_port); } +#endif void registerFail(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, void *context ) { #if HomeKitLog == 1 @@ -227,7 +240,7 @@ void broadcastMessage(void *sender, char *resultData, size_t resultLen) { memcpy((unsigned char*)&reply[resultLen+2], verify, 16); #endif - write(socketNumber, reply, resultLen+18); + send(socketNumber, reply, resultLen+18,0); delete [] reply; pthread_mutex_unlock(&connection[i].mutex); } @@ -242,7 +255,7 @@ void *connectionLoop(void *threadInfo) { #endif do { - len = read(subSocket, info->buffer, 4096); + len = recv(subSocket, info->buffer, 4096,0); #if HomeKitLog == 1 printf("Return len %d for socket %d\n", len, subSocket); #endif @@ -269,13 +282,21 @@ void *connectionLoop(void *threadInfo) { info->handleAccessoryRequest(); } else if (!strcmp(msg.directory, "identify")){ - close(subSocket); +#ifdef _WIN32 + closesocket(subSocket); +#else + close(subSocket); +#endif } } } while (len > 0); - + +#ifdef _WIN32 + ::closesocket(subSocket); +#else close(subSocket); +#endif #if HomeKitLog == 1 printf("Stop Connect: %d\n", subSocket); #endif @@ -300,7 +321,14 @@ void PHKNetworkIP::handleConnection() const { } } - if (index < 0) close(subSocket); + if (index < 0) + { +#ifdef _WIN32 + closesocket(subSocket); +#else + close(subSocket); +#endif + } } @@ -613,7 +641,7 @@ void connectionInfo::handlePairSeup() { mResponse.data.addRecord(stateRecord); mResponse.getBinaryPtr(&responseBuffer, &responseLen); if (responseBuffer) { - write(subSocket, (const void *)responseBuffer, (size_t)responseLen); + send(subSocket, responseBuffer, (size_t)responseLen,0); delete [] responseBuffer; } @@ -629,7 +657,7 @@ void connectionInfo::handlePairSeup() { #if HomeKitLog == 1 printf("%s, %d, responseBuffer = %s, responseLen = %d\n", __func__, __LINE__, responseBuffer, responseLen); #endif - int len = write(subSocket, (const void *)responseBuffer, (size_t)responseLen); + int len = send(subSocket, responseBuffer, (size_t)responseLen,0); delete [] responseBuffer; #if HomeKitLog == 1 printf("Pair Setup Transfered length %d\n", len); @@ -640,7 +668,7 @@ void connectionInfo::handlePairSeup() { #endif } - } while (read(subSocket, (void *)buffer, 4096) > 0); + } while (recv(subSocket, buffer, 4096,0) > 0); SRP_free(srp); } @@ -818,10 +846,10 @@ void connectionInfo::handlePairVerify() { char *repBuffer = 0; int repLen = 0; response.getBinaryPtr(&repBuffer, &repLen); if (repBuffer) { - write(subSocket, repBuffer, repLen); + send(subSocket, repBuffer, repLen,0); delete [] repBuffer; } - } while (!end && read(subSocket, buffer, 4096) > 0); + } while (!end && recv(subSocket, buffer, 4096,0) > 0); } @@ -845,7 +873,7 @@ void connectionInfo::handleAccessoryRequest() { do { bzero(buffer, 4096); - len = read(subSocket, buffer, 4096); + len = recv(subSocket, buffer, 4096,0); //FIXME make sure buffer len > (2 + msgLen + 16)?? if (len > 0) { @@ -924,7 +952,7 @@ void connectionInfo::handleAccessoryRequest() { Poly1305_GenKey((const unsigned char *)temp2, (uint8_t *)reply, resultLen, Type_Data_With_Length, verify); memcpy((unsigned char*)&reply[resultLen+2], verify, 16); - write(subSocket, reply, resultLen+18); + send(subSocket, reply, resultLen+18,0); pthread_mutex_unlock(&mutex); @@ -1036,7 +1064,9 @@ PHKNetworkMessageData & PHKNetworkMessageData::operator=(const PHKNetworkMessage } PHKNetworkMessageData::PHKNetworkMessageData(const char *rawData, unsigned short len) { - unsigned short delta = 0; + this->count = 0; + + unsigned short delta = 0; while (delta < len) { int index = recordIndex(rawData[delta+0]); if (index < 0) { diff --git a/PHKNetworkIP.h b/PHKNetworkIP.h old mode 100644 new mode 100755 index 9f45870..56ca557 --- a/PHKNetworkIP.h +++ b/PHKNetworkIP.h @@ -7,10 +7,19 @@ // // -#include -#include -#include -#include +#ifdef _WIN32 + #include + #include + #include + #include + #include +#else + #include + #include + #include +#endif + +#include // linux->avahi windows->bonjoursdk #include #include @@ -79,19 +88,29 @@ class PHKNetworkIP { class PHKNetworkMessageDataRecord { public: - unsigned char index = 0; - char *data = 0; - unsigned int length = 0; - bool activate = false; + unsigned char index; + char *data; + unsigned int length; + bool activate; + PHKNetworkMessageDataRecord() + : index(0) + , data(0) + , length(0) + , activate(false) + { + } ~PHKNetworkMessageDataRecord(); PHKNetworkMessageDataRecord &operator=(const PHKNetworkMessageDataRecord&); }; class PHKNetworkMessageData { PHKNetworkMessageDataRecord records[10]; - unsigned char count = 0; + unsigned char count; public: - PHKNetworkMessageData() {} + PHKNetworkMessageData() + { + this->count = 0; + } PHKNetworkMessageData(const char *rawData, unsigned short len); PHKNetworkMessageData(const PHKNetworkMessageData &data); PHKNetworkMessageData &operator=(const PHKNetworkMessageData &); @@ -127,13 +146,13 @@ class connectionInfo { pthread_t thread; pthread_mutex_t mutex; - bool connected = false; + bool connected; uint8_t controllerToAccessoryKey[32]; uint8_t accessoryToControllerKey[32]; - unsigned long long numberOfMsgRec = 0; - unsigned long long numberOfMsgSend = 0; - int subSocket = -1; + unsigned long long numberOfMsgRec; + unsigned long long numberOfMsgSend; + int subSocket; char buffer[4096]; void *notificationList[numberOfNotifiableValue]; @@ -142,6 +161,14 @@ class connectionInfo { void handlePairVerify(); void handleAccessoryRequest(); + connectionInfo() + : subSocket(0) + , numberOfMsgRec(0) + , numberOfMsgSend(0) + , connected(false) + { + } + void Poly1305_GenKey(const unsigned char * key, uint8_t * buf, uint16_t len, Poly1305Type_t type, char* verify); void addNotify(void *target) { diff --git a/Personal-HomeKit-HAP.vcxproj b/Personal-HomeKit-HAP.vcxproj new file mode 100755 index 0000000..d7c60e0 --- /dev/null +++ b/Personal-HomeKit-HAP.vcxproj @@ -0,0 +1,140 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {89C81753-1AFE-4F3C-B0FB-159F9BC02693} + PersonalHomeKitHAP + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSdkDir)include;$(FrameworkSDKDir)\include + $(SolutionDir)$(Configuration)\;$(LibraryPath) + + + + Level3 + Disabled + HomeKitLog=1;OPENSSL_ENGINE;_CRT_SECURE_NO_DEPRECATE;STDC_HEADERS;WIN32;_MBCS;%(PreprocessorDefinitions) + ..\openssl\include;windows_support_include;$(BONJOUR_SDK_HOME)/Include + 4996 + + + true + openssl.lib;$(BONJOUR_SDK_HOME)/Lib/$(PlatformName)/dnssd.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Personal-HomeKit-HAP.vcxproj.filters b/Personal-HomeKit-HAP.vcxproj.filters new file mode 100755 index 0000000..0b357d3 --- /dev/null +++ b/Personal-HomeKit-HAP.vcxproj.filters @@ -0,0 +1,201 @@ + + + + + {f6cf986d-69f1-47dc-b0c8-1e6ddbd14868} + + + {bd079260-fcdd-4ac0-a261-86033f0cedb8} + + + {7bddeea4-8d42-4bda-9889-d3a654eac7ce} + + + {bae2b6a2-57ef-4b8d-b5a6-197d87ab0f76} + + + {a842e132-cea7-4d9a-a055-6ff3ebacd4f7} + + + {5146eaa5-edee-463b-98b7-3b5e2a5ef71f} + + + + + Chacha20 + + + curve25519 + + + ed25519-donna + + + ed25519-donna + + + ed25519-donna + + + ed25519-donna + + + ed25519-donna + + + ed25519-donna + + + ed25519-donna + + + ed25519-donna + + + ed25519-donna + + + ed25519-donna + + + ed25519-donna + + + ed25519-donna + + + ed25519-donna + + + poly1305-opt-master + + + rfc6234-master + + + rfc6234-master + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + + + + + + + Chacha20 + + + curve25519 + + + ed25519-donna + + + poly1305-opt-master + + + rfc6234-master + + + rfc6234-master + + + rfc6234-master + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + srp + + + + + + + + \ No newline at end of file diff --git a/Personal-HomeKit-HAP.vcxproj.user b/Personal-HomeKit-HAP.vcxproj.user new file mode 100755 index 0000000..695b5c7 --- /dev/null +++ b/Personal-HomeKit-HAP.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/ed25519-donna/ed25519.c b/ed25519-donna/ed25519.c index 58a755b..555e5e6 100755 --- a/ed25519-donna/ed25519.c +++ b/ed25519-donna/ed25519.c @@ -16,7 +16,6 @@ #include "ed25519-donna.h" #include "ed25519.h" -#include "ed25519-randombytes.h" #include "ed25519-hash.h" /* @@ -148,3 +147,5 @@ ED25519_FN(curved25519_scalarmult_basepoint) (curved25519_key pk, const curved25 curve25519_contract(pk, yplusz); } +//This does not work unless it is at the bottom because of the order of winsock used in windows openssl. +#include "ed25519-randombytes.h" diff --git a/main.cpp b/main.cpp old mode 100644 new mode 100755 index 867b49a..1f1f27c --- a/main.cpp +++ b/main.cpp @@ -60,7 +60,11 @@ int main(int argc, const char * argv[]) { #if PowerOnTest==1 printf("poweron: %d\n", poly1305_power_on_self_test()); #endif - + +#ifdef _WIN32 + WSADATA wsaData; + WSAStartup(2, &wsaData); +#endif // insert code here... if (argc > 1) { //If there's some argument @@ -69,11 +73,18 @@ int main(int argc, const char * argv[]) { } initAccessorySet(); - setupPort(); +#ifdef _WIN32 +#else + setupPort(); +#endif - PHKNetworkIP networkIP; + PHKNetworkIP networkIP; do { networkIP.handleConnection(); } while (true); - return 0; + +#ifdef _WIN32 + WSACleanup(); +#endif + return 0; } diff --git a/srp/srp.h b/srp/srp.h index 4f89f5b..a8648e1 100755 --- a/srp/srp.h +++ b/srp/srp.h @@ -51,8 +51,8 @@ typedef int SRP_RESULT; /* Set the minimum number of bits acceptable in an SRP modulus */ #define SRP_DEFAULT_MIN_BITS 512 -_TYPE( SRP_RESULT ) SRP_set_modulus_min_bits P((int minbits)); -_TYPE( int ) SRP_get_modulus_min_bits P((void)); +_TYPE( SRP_RESULT ) SRP_set_modulus_min_bits (int minbits); +_TYPE( int ) SRP_get_modulus_min_bits (void); /* * Sets the "secret size callback" function. @@ -61,8 +61,8 @@ _TYPE( int ) SRP_get_modulus_min_bits P((void)); * The default function always returns 256 bits. */ typedef int (_CDECL * SRP_SECRET_BITS_CB)(int modsize); -_TYPE( SRP_RESULT ) SRP_set_secret_bits_cb P((SRP_SECRET_BITS_CB cb)); -_TYPE( int ) SRP_get_secret_bits P((int modsize)); +_TYPE( SRP_RESULT ) SRP_set_secret_bits_cb (SRP_SECRET_BITS_CB cb); +_TYPE( int ) SRP_get_secret_bits (int modsize); typedef struct srp_st SRP; @@ -97,15 +97,15 @@ struct srp_server_lu_st { * called to do lookups. */ _TYPE( SRP_SERVER_LOOKUP * ) - SRP_SERVER_LOOKUP_new P((SRP_SERVER_LOOKUP_METHOD * meth)); -_TYPE( SRP_RESULT ) SRP_SERVER_LOOKUP_free P((SRP_SERVER_LOOKUP * slu)); -_TYPE( SRP_RESULT ) SRP_SERVER_do_lookup P((SRP_SERVER_LOOKUP * slu, - SRP * srp, cstr * username)); + SRP_SERVER_LOOKUP_new (SRP_SERVER_LOOKUP_METHOD * meth); +_TYPE( SRP_RESULT ) SRP_SERVER_LOOKUP_free (SRP_SERVER_LOOKUP * slu); +_TYPE( SRP_RESULT ) SRP_SERVER_do_lookup (SRP_SERVER_LOOKUP * slu, + SRP * srp, cstr * username); /* * SRP_SERVER_system_lookup supercedes SRP_server_init_user. */ -_TYPE( SRP_SERVER_LOOKUP * ) SRP_SERVER_system_lookup P((void)); +_TYPE( SRP_SERVER_LOOKUP * ) SRP_SERVER_system_lookup (void); /* * Client Parameter Verification API @@ -213,8 +213,8 @@ _TYPE( SRP_RESULT ) SRP_finalize_library(); * the object operates in. SRP_free() frees it. * (See RFC2945 method definitions below.) */ -_TYPE( SRP * ) SRP_new P((SRP_METHOD * meth)); -_TYPE( SRP_RESULT ) SRP_free P((SRP * srp)); +_TYPE( SRP * ) SRP_new (SRP_METHOD * meth); +_TYPE( SRP_RESULT ) SRP_free (SRP * srp); /* * Use the supplied lookup object to look up user parameters and @@ -224,16 +224,16 @@ _TYPE( SRP_RESULT ) SRP_free P((SRP * srp)); * SRP_set_authenticator, since the lookup function handles that * internally. */ -_TYPE( SRP_RESULT ) SRP_set_server_lookup P((SRP * srp, - SRP_SERVER_LOOKUP * lookup)); +_TYPE( SRP_RESULT ) SRP_set_server_lookup (SRP * srp, + SRP_SERVER_LOOKUP * lookup); /* * Use the supplied callback function to verify parameters * (modulus, generator) given to the client. */ _TYPE( SRP_RESULT ) - SRP_set_client_param_verify_cb P((SRP * srp, - SRP_CLIENT_PARAM_VERIFY_CB cb)); + SRP_set_client_param_verify_cb (SRP * srp, + SRP_CLIENT_PARAM_VERIFY_CB cb); /* * Both client and server must call both SRP_set_username and @@ -241,14 +241,14 @@ _TYPE( SRP_RESULT ) * SRP_set_user_raw is an alternative to SRP_set_username that * accepts an arbitrary length-bounded octet string as input. */ -_TYPE( SRP_RESULT ) SRP_set_username P((SRP * srp, const char * username)); -_TYPE( SRP_RESULT ) SRP_set_user_raw P((SRP * srp, const unsigned char * user, - int userlen)); +_TYPE( SRP_RESULT ) SRP_set_username (SRP * srp, const char * username); +_TYPE( SRP_RESULT ) SRP_set_user_raw (SRP * srp, const unsigned char * user, + int userlen); _TYPE( SRP_RESULT ) - SRP_set_params P((SRP * srp, + SRP_set_params (SRP * srp, const unsigned char * modulus, int modlen, const unsigned char * generator, int genlen, - const unsigned char * salt, int saltlen)); + const unsigned char * salt, int saltlen); /* * On the client, SRP_set_authenticator, SRP_gen_exp, and @@ -270,13 +270,13 @@ _TYPE( SRP_RESULT ) * SRP_set_authenticator (since it doesn't know the plaintext password). */ _TYPE( SRP_RESULT ) - SRP_set_authenticator P((SRP * srp, const unsigned char * a, int alen)); + SRP_set_authenticator (SRP * srp, const unsigned char * a, int alen); _TYPE( SRP_RESULT ) - SRP_set_auth_password P((SRP * srp, const char * password)); + SRP_set_auth_password (SRP * srp, const char * password); _TYPE( SRP_RESULT ) - SRP_set_auth_password_raw P((SRP * srp, + SRP_set_auth_password_raw (SRP * srp, const unsigned char * password, - int passlen)); + int passlen); /* * SRP_gen_pub generates the random exponential residue to send @@ -293,21 +293,21 @@ _TYPE( SRP_RESULT ) * although the big integer value will still be available * through srp->pubkey in the SRP struct. */ -_TYPE( SRP_RESULT ) SRP_gen_pub P((SRP * srp, cstr ** result)); +_TYPE( SRP_RESULT ) SRP_gen_pub (SRP * srp, cstr ** result); /* * Append the data to the extra data segment. Authentication will * not succeed unless both sides add precisely the same data in * the same order. */ -_TYPE( SRP_RESULT ) SRP_add_ex_data P((SRP * srp, const unsigned char * data, - int datalen)); +_TYPE( SRP_RESULT ) SRP_add_ex_data (SRP * srp, const unsigned char * data, + int datalen); /* * SRP_compute_key must be called after the previous three methods. */ -_TYPE( SRP_RESULT ) SRP_compute_key P((SRP * srp, cstr ** result, +_TYPE( SRP_RESULT ) SRP_compute_key (SRP * srp, cstr ** result, const unsigned char * pubkey, - int pubkeylen)); + int pubkeylen); /* * On the client, call SRP_respond first to get the response to send @@ -317,9 +317,9 @@ _TYPE( SRP_RESULT ) SRP_compute_key P((SRP * srp, cstr ** result, * * It is an error to call SRP_respond with a NULL pointer. */ -_TYPE( SRP_RESULT ) SRP_verify P((SRP * srp, - const unsigned char * proof, int prooflen)); -_TYPE( SRP_RESULT ) SRP_respond P((SRP * srp, cstr ** response)); +_TYPE( SRP_RESULT ) SRP_verify (SRP * srp, + const unsigned char * proof, int prooflen); +_TYPE( SRP_RESULT ) SRP_respond (SRP * srp, cstr ** response); /* RFC2945-style SRP authentication */ @@ -330,17 +330,17 @@ _TYPE( SRP_RESULT ) SRP_respond P((SRP * srp, cstr ** response)); * RFC2945-style SRP authentication methods. Use these like: * SRP * srp = SRP_new(SRP_RFC2945_client_method()); */ -_TYPE( SRP_METHOD * ) SRP_RFC2945_client_method P((void)); -_TYPE( SRP_METHOD * ) SRP_RFC2945_server_method P((void)); +_TYPE( SRP_METHOD * ) SRP_RFC2945_client_method (void); +_TYPE( SRP_METHOD * ) SRP_RFC2945_server_method (void); /* * SRP-6 and SRP-6a authentication methods. * SRP-6a is recommended for better resistance to 2-for-1 attacks. */ -_TYPE( SRP_METHOD * ) SRP6_client_method P((void)); -_TYPE( SRP_METHOD * ) SRP6_server_method P((void)); -_TYPE( SRP_METHOD * ) SRP6a_client_method P((void)); -_TYPE( SRP_METHOD * ) SRP6a_server_method P((void)); +_TYPE( SRP_METHOD * ) SRP6_client_method (void); +_TYPE( SRP_METHOD * ) SRP6_server_method (void); +_TYPE( SRP_METHOD * ) SRP6a_client_method (void); +_TYPE( SRP_METHOD * ) SRP6a_server_method (void); /* * Convenience function - SRP_server_init_user @@ -351,12 +351,12 @@ _TYPE( SRP_METHOD * ) SRP6a_server_method P((void)); * This is deprecated in favor of SRP_SERVER_system_lookup() and * the Server Lookup API. */ -_TYPE( SRP_RESULT ) SRP_server_init_user P((SRP * srp, const char * username)); +_TYPE( SRP_RESULT ) SRP_server_init_user (SRP * srp, const char * username); /* * Use the named engine for acceleration. */ -_TYPE( SRP_RESULT ) SRP_use_engine P((const char * engine)); +_TYPE( SRP_RESULT ) SRP_use_engine (const char * engine); #ifdef __cplusplus } diff --git a/srp/srp6_server.c b/srp/srp6_server.c index ea9ceef..dc95499 100755 --- a/srp/srp6_server.c +++ b/srp/srp6_server.c @@ -258,6 +258,7 @@ srp6_server_key(SRP * srp, cstr ** result, cstr * s; BigInteger t1, t2, t3; SHACTX ctxt; + SHACTX sctx; unsigned char dig[SHA_DIGESTSIZE]; int modlen; @@ -331,7 +332,6 @@ srp6_server_key(SRP * srp, cstr ** result, BigIntegerClearFree(t3); /* convert srp->key into session key, update hashes */ - SHACTX sctx; BigIntegerToCstr(srp->key, s); SHAInit(&sctx); SHAUpdate(&sctx, s->data, s->length); diff --git a/srp/t_defines.h b/srp/t_defines.h index fc5b5d5..e5032dd 100755 --- a/srp/t_defines.h +++ b/srp/t_defines.h @@ -90,6 +90,13 @@ char *strchr(), *strrchr(), *strtok(); #include +#ifdef WIN32 +#include +#include +#define USE_FTIME 1 +#define USE_RENAME 1 +#define NO_FCHMOD 1 +#else #if TIME_WITH_SYS_TIME #include #include @@ -121,12 +128,10 @@ char *strchr(), *strrchr(), *strtok(); #define TERMIO struct sgttyb #define USE_SGTTY #endif +#endif /* WIN32 */ + + -#ifdef WIN32 -#define USE_FTIME 1 -#define USE_RENAME 1 -#define NO_FCHMOD 1 -#endif #ifdef USE_FTIME #include diff --git a/srp/t_misc.c b/srp/t_misc.c index cbbe6ee..9d91416 100755 --- a/srp/t_misc.c +++ b/srp/t_misc.c @@ -37,11 +37,12 @@ #include #include #include -#include #ifdef WIN32 #include #include +#else +#include #endif #include "t_sha.h" @@ -78,7 +79,10 @@ SHACTX randctxt; * tricks with variable ordering and sometimes define quirky * environment variables like $WINDOWID or $_. */ +#ifdef _WIN32 +#else extern char ** environ; +#endif static void t_envhash(out) From 8e1c14c18df3f786fa23a8af6be4e06dffebf67e Mon Sep 17 00:00:00 2001 From: rti Date: Sat, 3 Dec 2016 03:33:53 +0900 Subject: [PATCH 4/9] 1. I changed to setting that does not depend on Configuration.h. This is to make it easier to reuse modules. Specifically, we made it possible to pass information in PHKNetwork IP class constructor. Example. PHKNetworkIP networkIP(deviceName,devicePassword,deviceIdentity,controllerRecordsAddress); do { networkIP.handleConnection(); } while (true); 2. I made PHKControllerRecord.cpp from a function to a class. This is to make it possible to pass the path saving vector from outside by changing (1). The PHKControllerRecord class delegates administration to the AccessorySet. This is because AccessorySet is singleton so it is easy to use. Originally, I want it under PHKNetworkIP, but since it is hard to modify, I delegated to AccessorySet for the time being. 3. I changed have taken measures against buffer overrun of scanf. Example. We changed it as char buf[10]; sccanf(a, "%s", buf); ---> char buf[10+1]; sccanf (a, "%10s", buf); 4. Changed it to a code that is harder to leak memory. Example. We changed it as char* a = new[100]; ---> vector a_vec(100); char* a = &a_vec[0]; If secured with vector, it is safe because you do not have to delete it. 5. I introduced AccessorySetAutoLock autolock; to avoid forgetting mutex lock release. When you leave the scope, it automatically releases the mutex. { lock .... unlock } ----> { AccessorySetAutoLock autolock .... } //auto unlock 6. I changed the method of initialization. I use this as C ++ will initialize. char a[100]; bzero(b,100); -----> char a[100] = {0}; (It is very easy because C ++ will initialize without permission.) 7. Fixed a problem that boolCharacteristics "1" can not be judged as true. 8. Added PHKNetworkIP::closeAcceptConnection command to end accept loop. Now you can stop with CTRL + C, and reusability as a module increases. For details,plasess see the end of main.cpp. PHKNetworkIP networkIP(deviceName,devicePassword,deviceIdentity,controllerRecordsAddress); do { networkIP.handleConnection(); } while (true); //if you running PHKNetworkIP new accept thread, //call PHKNetworkIP::closeAcceptConnection to stop. 9. To fix memory leak, we fixed to release memory when releasing Service and Characteristics. 10. Uint8 Characteristic support added. (However, perhaps, this may not be necessary ...?? ) 11. We have supported the number of digits up to 8 digits. (Question: Why are you making three digits, why do you have [3] a reason?) char buf[3]; snprintf(buf,3,"%d",intValue); ---> char buf[8]; snprintf(buf, 8, "%d", intValue); (I wrote this sentence using google translation. Sorry if we had funny English.) --- PHKAccessory.cpp | 156 +++--- PHKAccessory.h | 1011 +++++++++++++++++++----------------- PHKArduinoLightInterface.c | 0 PHKArduinoLightInterface.h | 0 PHKControllerRecord.cpp | 73 +-- PHKControllerRecord.h | 69 ++- PHKNetworkIP.cpp | 290 ++++++----- PHKNetworkIP.h | 30 +- main.cpp | 13 +- 9 files changed, 930 insertions(+), 712 deletions(-) mode change 100644 => 100755 PHKArduinoLightInterface.c mode change 100644 => 100755 PHKArduinoLightInterface.h mode change 100644 => 100755 PHKControllerRecord.cpp mode change 100644 => 100755 PHKControllerRecord.h diff --git a/PHKAccessory.cpp b/PHKAccessory.cpp index a8c2b40..03479d2 100755 --- a/PHKAccessory.cpp +++ b/PHKAccessory.cpp @@ -13,6 +13,10 @@ const char hapJsonType[] = "application/hap+json"; const char pairingTlv8Type[] = "application/pairing+tlv8"; +//The default logger is printf +//Personal_homekit_set_logger_function can be changed. +PERSONAL_LOGGER_FUNCTION g_homekit_logger = printf; + //Wrap to JSON inline string wrap(const char *str) { return (string)"\""+str+"\""; } @@ -47,7 +51,7 @@ inline string attribute(unsigned short type, unsigned short acclaim, int p, bool return "{"+result+"}"; } -inline string attribute(unsigned short type, unsigned short acclaim, int p, int value, int minVal, int maxVal, int step, unit valueUnit) { +inline string attribute(unsigned short type, unsigned short acclaim, int p, int value, int minVal, int maxVal, int step, unit valueUnit,const std::string& format ) { string result; char tempStr[4]; @@ -99,7 +103,7 @@ inline string attribute(unsigned short type, unsigned short acclaim, int p, int break; } - result += "\"format\":\"int\""; + result += "\"format\":\"" + format + "\""; return "{"+result+"}"; } @@ -234,7 +238,11 @@ string floatCharacteristics::describe() { } string intCharacteristics::describe() { - return attribute(type, iid, premission, _value, _minVal, _maxVal, _step, _unit); + return attribute(type, iid, premission, _value, _minVal, _maxVal, _step, _unit, "int"); +} + +string uint8Characteristics::describe() { + return attribute(type, iid, premission, _value, _minVal, _maxVal, _step, _unit, "uint8"); } string stringCharacteristics::describe() { @@ -273,7 +281,7 @@ string Accessory::describe() { { keys[0] = "aid"; char temp[8]; - sprintf(temp, "%d", aid); + snprintf(temp,8, "%d", aid); values[0] = temp; } @@ -293,19 +301,34 @@ string Accessory::describe() { return result; } + + +void AccessorySet::lock() +{ + pthread_mutex_lock(&this->accessoryMutex); +} + +void AccessorySet::unlock() +{ + pthread_mutex_unlock(&this->accessoryMutex); +} + + string AccessorySet::describe() { int numberOfAcc = numberOfAccessory(); - string *desc = new string[numberOfAcc]; + vector desc_vec(numberOfAcc); + string *desc = &desc_vec[0]; for (int i = 0; i < numberOfAcc; i++) { desc[i] = _accessories[i]->describe(); } string result = arrayWrap(desc, numberOfAcc); - delete [] desc; string key = "accessories"; result = dictionaryWrap(&key, &result, 1); return result; } + + struct broadcastInfo { void *sender; char *desc; @@ -315,16 +338,16 @@ void *announce(void *info) { broadcastInfo *_info = (broadcastInfo *)info; void *sender = _info->sender; char *desc = _info->desc; - - char *reply = new char[1024]; + + vector reply_vec(1024); + char *reply = &reply_vec[0]; int len = snprintf(reply, 1024, "EVENT/1.0 200 OK\r\nContent-Type: application/hap+json\r\nContent-Length: %lu\r\n\r\n%s", strlen(desc), desc); #if HomeKitLog == 1 && HomeKitReplyHeaderLog==1 - printf("%s\n", reply); + g_homekit_logger("%s\n", reply); #endif broadcastMessage(sender, reply, len); - delete [] reply; delete [] desc; delete [] info; @@ -334,8 +357,9 @@ void *announce(void *info) { void updateValueFromDeviceEnd(characteristics *c, int aid, int iid, string value) { c->setValue(value); + string newValue = c->value(); char *broadcastTemp = new char[1024]; - snprintf(broadcastTemp, 1024, "{\"characteristics\":[{\"aid\":%d,\"iid\":%d,\"value\":%s}]}", aid, iid, value.c_str()); + snprintf(broadcastTemp, 1024, "{\"characteristics\":[{\"aid\":%d,\"iid\":%d,\"value\":%s}]}", aid, iid, newValue.c_str()); broadcastInfo * info = new broadcastInfo; info->sender = c; info->desc = broadcastTemp; @@ -346,7 +370,7 @@ void updateValueFromDeviceEnd(characteristics *c, int aid, int iid, string value void handleAccessory(const char *request, unsigned int requestLen, char **reply, unsigned int *replyLen, connectionInfo *sender) { #if HomeKitLog == 1 - printf("Receive request: %s\n", request); + g_homekit_logger("Receive request: %s\n", request); #endif int index = 5; char method[5]; @@ -367,7 +391,7 @@ void handleAccessory(const char *request, unsigned int requestLen, char **reply, } path[i] = 0; #if HomeKitLog == 1 - printf("Path: %s\n", path); + g_homekit_logger("Path: %s\n", path); #endif const char *dataPtr = request; @@ -388,7 +412,7 @@ void handleAccessory(const char *request, unsigned int requestLen, char **reply, if (strcmp(path, "/accessories") == 0) { //Publish the characterists of the accessories #if HomeKitLog == 1 - printf("Ask for accessories info\n"); + g_homekit_logger("Ask for accessories info\n"); #endif statusCode = 200; string desc = AccessorySet::getInstance().describe(); @@ -399,16 +423,18 @@ void handleAccessory(const char *request, unsigned int requestLen, char **reply, } else if (strcmp(path, "/pairings") == 0) { PHKNetworkMessage msg(request); statusCode = 200; - printf("%d\n", *msg.data.dataPtrForIndex(0)); - if (*msg.data.dataPtrForIndex(0) == 3) { +#if HomeKitLog == 1 + g_homekit_logger("%d\n", *msg.data.dataPtrForIndex(0)); +#endif + if (*msg.data.dataPtrForIndex(0) == 3) { //Pairing with new user #if HomeKitLog == 1 - printf("Add new user\n"); + g_homekit_logger("Add new user\n"); #endif PHKKeyRecord controllerRec; bcopy(msg.data.dataPtrForIndex(3), controllerRec.publicKey, 32); bcopy(msg.data.dataPtrForIndex(1), controllerRec.controllerID, 36); - addControllerKey(controllerRec); + AccessorySet::getInstance().Controllers.addControllerKey(controllerRec); PHKNetworkMessageDataRecord drec; drec.activate = true; drec.data = new char[1]; *drec.data = 2; drec.index = 6; drec.length = 1; @@ -419,11 +445,11 @@ void handleAccessory(const char *request, unsigned int requestLen, char **reply, statusCode = 200; } else { #if HomeKitLog == 1 - printf("Delete user"); + g_homekit_logger("Delete user"); #endif PHKKeyRecord controllerRec; bcopy(msg.data.dataPtrForIndex(1), controllerRec.controllerID, 36); - removeControllerKey(controllerRec); + AccessorySet::getInstance().Controllers.removeControllerKey(controllerRec); PHKNetworkMessageDataRecord drec; drec.activate = true; drec.data = new char[1]; *drec.data = 2; drec.index = 6; drec.length = 1; @@ -434,32 +460,39 @@ void handleAccessory(const char *request, unsigned int requestLen, char **reply, statusCode = 200; } } else if (strncmp(path, "/characteristics", 16) == 0){ - pthread_mutex_lock(&AccessorySet::getInstance().accessoryMutex); - printf("Characteristics\n"); - if (strncmp(method, "GET", 3) == 0) { + AccessorySetAutoLock autolock; +#if HomeKitLog == 1 + g_homekit_logger("Characteristics\n"); +#endif + if (strncmp(method, "GET", 3) == 0) { //Read characteristics int aid = 0; int iid = 0; - char indexBuffer[1000]; - sscanf(path, "/characteristics?id=%[^\n]", indexBuffer); - printf("Get characteristics %s with len %d\n", indexBuffer, strlen(indexBuffer)); - + char indexBuffer[1000+1]={0}; + sscanf(path, "/characteristics?id=%1000[^\n]", indexBuffer); +#if HomeKitLog == 1 + g_homekit_logger("Get characteristics %s with len %d\n", indexBuffer, strlen(indexBuffer)); +#endif statusCode = 404; string result = "["; while (strlen(indexBuffer) > 0) { - printf("Get characteristics %s with len %d\n", indexBuffer, strlen(indexBuffer)); - - char temp[1000]; +#if HomeKitLog == 1 + g_homekit_logger("Get characteristics %s with len %d\n", indexBuffer, strlen(indexBuffer)); +#endif + char temp[1000+1]={0}; //Initial the temp - temp[0] = 0; - sscanf(indexBuffer, "%d.%d%[^\n]", &aid, &iid, temp); - printf("Get temp %s with len %d\n", temp, strlen(temp)); - strncpy(indexBuffer, temp, 1000); - printf("Get characteristics %s with len %d\n", indexBuffer, strlen(indexBuffer)); - //Trim comma + sscanf(indexBuffer, "%d.%d%1000[^\n]", &aid, &iid, temp); +#if HomeKitLog == 1 + g_homekit_logger("Get temp %s with len %d\n", temp, strlen(temp)); +#endif + strncpy(indexBuffer, temp, 1000); +#if HomeKitLog == 1 + g_homekit_logger("Get characteristics %s with len %d\n", indexBuffer, strlen(indexBuffer)); +#endif + //Trim comma if (indexBuffer[0] == ',') { indexBuffer[0] = '0'; } @@ -469,11 +502,11 @@ void handleAccessory(const char *request, unsigned int requestLen, char **reply, characteristics *c = a->characteristicsAtIndex(iid); if (c != NULL) { #if HomeKitLog == 1 - printf("Ask for one characteristics: %d . %d\n", aid, iid); + g_homekit_logger("Ask for one characteristics: %d . %d\n", aid, iid); #endif - char c1[3], c2[3]; - sprintf(c1, "%d", aid); - sprintf(c2, "%d", iid); + char c1[8], c2[8]; + snprintf(c1,8, "%d", aid); + snprintf(c2,8, "%d", iid); string s[3] = {string(c1), string(c2), c->value()}; string k[3] = {"aid", "iid", "value"}; if (result.length() != 1) { @@ -502,8 +535,8 @@ void handleAccessory(const char *request, unsigned int requestLen, char **reply, } else if (strncmp(method, "PUT", 3) == 0) { //Change characteristics - char characteristicsBuffer[1000]; - sscanf(dataPtr, "{\"characteristics\":[{%[^]]s}", characteristicsBuffer); + char characteristicsBuffer[1000+1]={0}; + sscanf(dataPtr, "{\"characteristics\":[{%1000[^]]}", characteristicsBuffer); char *buffer2 = characteristicsBuffer; while (strlen(buffer2) && statusCode != 400) { @@ -512,15 +545,15 @@ void handleAccessory(const char *request, unsigned int requestLen, char **reply, buffer1 = strtok_r(buffer2, "}", &buffer2); if (*buffer2 != 0) buffer2+=2; - int aid = 0; int iid = 0; char value[16]; - int result = sscanf(buffer1, "\"aid\":%d,\"iid\":%d,\"value\":%s", &aid, &iid, value); + int aid = 0; int iid = 0; char value[16+1]={0}; + int result = sscanf(buffer1, "\"aid\":%d,\"iid\":%d,\"value\":%16s", &aid, &iid, value); if (result == 2) { - sscanf(buffer1, "\"aid\":%d,\"iid\":%d,\"ev\":%s", &aid, &iid, value); + sscanf(buffer1, "\"aid\":%d,\"iid\":%d,\"ev\":%16s", &aid, &iid, value); updateNotify = true; } else if (result == 0) { - sscanf(buffer1, "\"remote\":true,\"value\":%[^,],\"aid\":%d,\"iid\":%d", value, &aid, &iid); + sscanf(buffer1, "\"remote\":true,\"value\":%16[^,],\"aid\":%d,\"iid\":%d", value, &aid, &iid); if (result == 2) { - sscanf(buffer1, "\"remote\":true,\"aid\":%d,\"iid\":%d,\"ev\":%s", &aid, &iid, value); + sscanf(buffer1, "\"remote\":true,\"aid\":%d,\"iid\":%d,\"ev\":%16s", &aid, &iid, value); updateNotify = true; } } @@ -533,7 +566,7 @@ void handleAccessory(const char *request, unsigned int requestLen, char **reply, if (updateNotify) { #if HomeKitLog == 1 - printf("Ask to notify one characteristics: %d . %d -> %s\n", aid, iid, value); + g_homekit_logger("Ask to notify one characteristics: %d . %d -> %s\n", aid, iid, value); #endif if (c==NULL) { statusCode = 400; @@ -548,7 +581,7 @@ void handleAccessory(const char *request, unsigned int requestLen, char **reply, } } else { #if HomeKitLog == 1 - printf("Ask to change one characteristics: %d . %d -> %s\n", aid, iid, value); + g_homekit_logger("Ask to change one characteristics: %d . %d -> %s\n", aid, iid, value); #endif if (c==NULL) { statusCode = 400; @@ -579,23 +612,23 @@ void handleAccessory(const char *request, unsigned int requestLen, char **reply, } else { return; } - pthread_mutex_unlock(&AccessorySet::getInstance().accessoryMutex); } else { //Error #if HomeKitLog == 1 - printf("Ask for something I don't know\n"); + g_homekit_logger("Ask for something I don't know\n"); + g_homekit_logger("%s\n", request); + g_homekit_logger("%s", path); #endif - printf("%s\n", request); - printf("%s", path); statusCode = 404; } //Calculate the length of header - char * tmp = new char[256]; - bzero(tmp, 256); - int len = snprintf(tmp, 256, "%s %d OK\r\nContent-Type: %s\r\nContent-Length: %u\r\n\r\n", protocol, statusCode, returnType, replyDataLen); - delete [] tmp; - + int len = 0; + { + char tmp[256]; + len = snprintf(tmp, 256, "%s %d OK\r\nContent-Type: %s\r\nContent-Length: %u\r\n\r\n", protocol, statusCode, returnType, replyDataLen); + } + //replyLen should omit the '\0'. (*replyLen) = len+replyDataLen; //reply should add '\0', or the printf is incorrect @@ -609,7 +642,7 @@ void handleAccessory(const char *request, unsigned int requestLen, char **reply, } #if HomeKitLog == 1 && HomeKitReplyHeaderLog==1 - printf("Reply: %s\n", *reply); + g_homekit_logger("Reply: %s\n", *reply); #endif } @@ -639,3 +672,8 @@ void addInfoServiceToAccessory(Accessory *acc, string accName, string manufactue identify->valueChangeFunctionCall = identifyCallback; acc->addCharacteristics(infoService, identify); } + +void Personal_homekit_set_logger_function(PERSONAL_LOGGER_FUNCTION func) +{ + g_homekit_logger = func; +} diff --git a/PHKAccessory.h b/PHKAccessory.h index 07c2dde..ca0c09b 100755 --- a/PHKAccessory.h +++ b/PHKAccessory.h @@ -1,464 +1,547 @@ -#pragma once -// -// PHKAccessory.h -// Workbench -// -// Created by Wai Man Chan on 9/27/14. -// -// - -#include -#include -#define __STDC_LIMIT_MACROS -#include -extern "C" { -#include -} - -#include "PHKNetworkIP.h" - -#include "PHKControllerRecord.h" - -extern "C" { -#include "PHKArduinoLightInterface.h" -} - -#include - -#if MCU -#else -#include -#endif - -using namespace std; - -typedef enum { - charType_adminOnlyAccess = 0x1, - charType_audioChannels = 0x2, - charType_audioCodexName = 0x3, - charType_audioCodexParameter= 0x4, - charType_audioFeedback = 0x5, - charType_audioPropAttr = 0x6, - charType_audioValAttr = 0x7, - charType_brightness = 0x8, - charType_cameraNightVision = 0x9, - charType_cameraPan = 0xA, - charType_cameraTilt = 0xB, - charType_cameraZoom = 0xC, - charType_coolingThreshold = 0xD, - charType_currentDoorState = 0xE, - charType_currentHeatCoolMode= 0xF, - charType_currentHumidity = 0x10, - charType_currentTemperature = 0x11, - charType_heatingThreshold = 0x12, - charType_hue = 0x13, - charType_identify = 0x14, - charType_inputVolume = 0x15, - charType_ipCameraStart = 0x16, - charType_ipCameraStop = 0x17, - charType_lockControlPoint = 0x19, - charType_lockAutoTimeout = 0x1A, - charType_lockLastAction = 0x1C, - charType_lockCurrentState = 0x1D, - charType_lockTargetState = 0x1E, - charType_logs = 0x1F, - charType_manufactuer = 0x20, - charType_modelName = 0x21, - charType_motionDetect = 0x22, - charType_serviceName = 0x23, - charType_obstruction = 0x24, - charType_on = 0x25, - charType_outletInUse = 0x26, - charType_outputVolume = 0x27, - charType_rotationDirection = 0x28, - charType_rotationSpeed = 0x29, - charType_rtcpExtProp = 0x2A, - charType_rtcpVideoPayload = 0x2B, - charType_rtcpAudioPayload = 0x2C, - charType_rtcpAudioClock = 0x2D, - charType_rtcpProtocol = 0x2E, - charType_saturation = 0x2F, - charType_serialNumber = 0x30, - charType_srtpCyptoSuite = 0x31, - charType_targetDoorState = 0x32, - charType_targetHeatCoolMode = 0x33, - charType_targetHumidity = 0x34, - charType_targetTemperature = 0x35, - charType_temperatureUnit = 0x36, - charType_version = 0x37, - charType_videoCodexName = 0x38, - charType_videoCodexPara = 0x39, - charType_videoMirror = 0x3A, - charType_videoPropAttr = 0x3B, - charType_videoRotation = 0x3C, - charType_videoValAttr = 0x3D, - -//#pragma - The following is only default by the device after iOS 9 - - charType_firmwareRevision = 0x52, - charType_hardwareRevision = 0x53, - charType_softwareRevision = 0x54, - - charType_reachable = 0x63, - - charType_airParticulateDensity = 0x64, - charType_airParticulateSize = 0x65, - charType_airQuality = 0x95, - charType_carbonDioxideDetected = 0x92, - charType_carbonMonoxideDetected = 0x69, - charType_carbonDioxideLevel = 0x93, - charType_carbonMonoxideLevel = 0x90, - charType_carbonDioxidePeakLevel = 0x94, - charType_carbonMonoxidePeakLevel = 0x91, - charType_smokeDetected = 0x76, - - charType_alarmCurrentState = 0x66, - charType_alarmTargetState = 0x67, - charType_batteryLevel = 0x68, - charType_contactSensorState = 0x6A, - charType_holdPosition = 0x6F, - charType_leakDetected = 0x70, - charType_occupancyDetected = 0x71, - - charType_currentAmbientLightLevel = 0x6B, - charType_currentHorizontalTiltAngle = 0x6C, - charType_targetHorizontalTiltAngle = 0x7B, - charType_currentPosition = 0x6D, - charType_targetPosition = 0x7C, - charType_currentVerticalTiltAngle = 0x6E, - charType_targetVerticalTiltAngle = 0x7D, - - charType_positionState = 0x72, - charType_programmableSwitchEvent = 0x73, - charType_programmableSwitchOutputState = 0x74, - - charType_sensorActive = 0x75, - charType_sensorFault = 0x77, - charType_sensorJammed = 0x78, - charType_sensorLowBattery = 0x79, - charType_sensorTampered = 0x7A, - charType_sensorChargingState= 0x8F, - - -//#pragma - The following is service provide - serviceType_accessoryInfo = 0x3E, - serviceType_camera = 0x3F, - serviceType_fan = 0x40, - serviceType_garageDoorOpener = 0x41, - serviceType_lightBulb = 0x43, - serviceType_lockManagement = 0x44, - serviceType_lockMechanism = 0x45, - serviceType_microphone = 0x46, - serviceType_outlet = 0x47, - serviceType_speaker = 0x48, - serviceType_switch = 0x49, - serviceType_thermostat = 0x4A, - - serviceType_alarmSystem = 0x7E, - serviceType_bridgingState = 0x62, - serviceType_carbonMonoxideSensor = 0x7F, - serviceType_contactSensor = 0x80, - serviceType_door = 0x81, - serviceType_humiditySensor = 0x82, - serviceType_leakSensor = 0x83, - serviceType_lightSensor = 0x84, - serviceType_motionSensor = 0x85, - serviceType_occupancySensor = 0x86, - serviceType_smokeSensor = 0x87, - serviceType_programmableSwitch_stateful = 0x88, - serviceType_programmableSwitch_stateless = 0x89, - serviceType_temperatureSensor = 0x8A, - serviceType_window = 0x8B, - serviceType_windowCover = 0x8C, - serviceType_airQualitySensor = 0x8C, - serviceType_securityAlarm = 0x8E, - serviceType_charging = 0x8F, - - serviceType_battery = 0x96, - serviceType_carbonDioxideSensor= 0x97, - -//#pragma - The following is for bluetooth characteristic - btCharType_pairSetup = 0x4C, - btCharType_pairVerify = 0x4E, - btCharType_pairingFeature = 0x4F, - btCharType_pairings = 0x50, - btCharType_serviceInstanceID = 0x51, -//#pragma - The following is for bluetooth service - btServiceType_accessoryInformation = 0xFED3, - btServiceType_camera = 0xFEC9, - btServiceType_fan = 0xFECB, - btServiceType_garageDoorOpener = 0xFECE, - btServiceType_lightBulb = 0xFED2, - btServiceType_lockManagement = 0xFECF, - btServiceType_lockMechanism = 0xFED0, - btServiceType_microphone = 0xFEC8, - btServiceType_outlet = 0xFECC, - btServiceType_speaker = 0xFEC7, - btServiceType_switch = 0xFECD, - -} charType; - -enum { - premission_read = 1, - premission_write = 1 << 1, - premission_notify = 1 << 2 //Notify = Accessory will notice the controller -}; - -typedef enum { - unit_none = 0, - unit_celsius, - unit_percentage, - unit_arcDegree -} unit; - - -class characteristics { -public: - - const unsigned short type; - const int premission; - int iid; - characteristics(unsigned short _type, int _premission): type(_type), premission(_premission) {} - virtual string value() = 0; - virtual void setValue(string str) = 0; - virtual string describe() = 0; - bool writable() { return premission&premission_write; } - bool notifiable() { return premission&premission_notify; } -}; - -//To store value of device state, subclass the following type -class boolCharacteristics: public characteristics { -public: - bool _value; - void (*valueChangeFunctionCall)(bool oldValue, bool newValue); - boolCharacteristics(unsigned short _type, int _premission) - : valueChangeFunctionCall(NULL) - , characteristics(_type, _premission) - { - } - virtual string value() { - if (_value) - return "1"; - return "0"; - } - virtual void setValue(string str) { - bool newValue = (strncmp("true", str.c_str(), 4)==0); - if (valueChangeFunctionCall) - valueChangeFunctionCall(_value, newValue); - _value = newValue; - } - virtual string describe(); -}; - -class floatCharacteristics: public characteristics { -public: - float _value; - const float _minVal, _maxVal, _step; - const unit _unit; - void (*valueChangeFunctionCall)(float oldValue, float newValue); - floatCharacteristics(unsigned short _type, int _premission, float minVal, float maxVal, float step, unit charUnit) - : valueChangeFunctionCall(NULL) - ,characteristics(_type, _premission) - , _minVal(minVal) - , _maxVal(maxVal) - , _step(step) - , _unit(charUnit) - { - } - virtual string value() { - char temp[16]; - snprintf(temp, 16, "%f", _value); - return temp; - } - virtual void setValue(string str) { - float temp = (float) atof(str.c_str()); - if (temp == temp) { - if (valueChangeFunctionCall) - valueChangeFunctionCall(_value, temp); - _value = temp; - } - } - virtual string describe(); -}; - -class intCharacteristics: public characteristics { -public: - int _value; - const int _minVal, _maxVal, _step; - const unit _unit; - void (*valueChangeFunctionCall)(int oldValue, int newValue); - intCharacteristics(unsigned short _type, int _premission, int minVal, int maxVal, int step, unit charUnit) - : valueChangeFunctionCall(NULL) - , characteristics(_type, _premission) - , _minVal(minVal) - , _maxVal(maxVal) - , _step(step) - , _unit(charUnit) - { - _value = minVal; - } - virtual string value() { - char temp[16]; - snprintf(temp, 16, "%d", _value); - return temp; - } - virtual void setValue(string str) { - float temp = (float)atoi(str.c_str()); - if (temp == temp) { - if (valueChangeFunctionCall) - valueChangeFunctionCall(_value, (int)temp); - _value = (int) temp; - } - } - virtual string describe(); -}; - -class stringCharacteristics: public characteristics { -public: - string _value; - const unsigned short maxLen; - void (*valueChangeFunctionCall)(string oldValue, string newValue); - stringCharacteristics(unsigned short _type, int _premission, unsigned short _maxLen) - : valueChangeFunctionCall(NULL) - , characteristics(_type, _premission) - , maxLen(_maxLen) - { - } - virtual string value() { - return "\""+_value+"\""; - } - virtual void setValue(string str) { - if (valueChangeFunctionCall) - valueChangeFunctionCall(_value, str); - _value = str; - } - virtual string describe(); -}; - -//Abstract Layer of object -class Service { -public: - int serviceID, uuid; - vector _characteristics; - Service(int _uuid): uuid(_uuid) {} - virtual short numberOfCharacteristics() { return _characteristics.size(); } - virtual characteristics *characteristicsAtIndex(int index) { return _characteristics[index]; } - string describe(); -}; - -class Accessory { -public: - int numberOfInstance; - int aid; - vector_services; - void addService(Service *ser) { - ser->serviceID = ++numberOfInstance; - _services.push_back(ser); - } - void addCharacteristics(Service *ser, characteristics *cha) { - cha->iid = ++numberOfInstance; - ser->_characteristics.push_back(cha); - } - bool removeService(Service *ser) { - bool exist = false; - for (vector::iterator it = _services.begin(); it != _services.end(); it++) { - if (*it == ser) { - _services.erase(it); - exist = true; - } - } - return exist; - } - bool removeCharacteristics(characteristics *cha) { - bool exist = false; - for (vector::iterator it = _services.begin(); it != _services.end(); it++) { - for (vector::iterator jt = (*it)->_characteristics.begin(); jt != (*it)->_characteristics.end(); jt++) { - if (*jt == cha) { - (*it)->_characteristics.erase(jt); - exist = true; - } - } - } - return exist; - } - Accessory() : numberOfInstance (0) - { - } - short numberOfService() { return _services.size(); } - Service *serviceAtIndex(int index) { - for (vector::iterator it = _services.begin(); it != _services.end(); it++) { - if ((*it)->serviceID == index) { - return *it; - } - } - return NULL; - } - characteristics *characteristicsAtIndex(int index) { - for (vector::iterator it = _services.begin(); it != _services.end(); it++) { - for (vector::iterator jt = (*it)->_characteristics.begin(); jt != (*it)->_characteristics.end(); jt++) { - if ((*jt)->iid == index) { - return *jt; - } - } - } - return NULL; - } - string describe(); -}; - -class AccessorySet { -private: - vector _accessories; - int _aid; - AccessorySet() { - _aid = 0; - pthread_mutex_init(&accessoryMutex, NULL); - } - AccessorySet(AccessorySet const&); - void operator=(AccessorySet const&); -public: - static AccessorySet& getInstance() { - static AccessorySet instance; - - return instance; - } - pthread_mutex_t accessoryMutex; - short numberOfAccessory() { - return _accessories.size(); - } - Accessory *accessoryAtIndex(int index) { - for (vector::iterator it = _accessories.begin(); it != _accessories.end(); it++) { - if ((*it)->aid == index) { - return *it; - } - } - return NULL; - } - void addAccessory(Accessory *acc) { - acc->aid = ++_aid; - _accessories.push_back(acc); - } - bool removeAccessory(Accessory *acc) { - bool exist = false; - for (vector::iterator it = _accessories.begin(); it != _accessories.end(); it++) { - if (*it == acc) { - _accessories.erase(it); - exist = true; - } - } - return exist; - } - ~AccessorySet() { - pthread_mutex_destroy(&accessoryMutex); - } - string describe(); -}; - -typedef void (*identifyFunction)(bool oldValue, bool newValue); - -//Since Info Service contains only constant, only add method will be provided -void addInfoServiceToAccessory(Accessory *acc, string accName, string manufactuerName, string modelName, string serialNumber, identifyFunction identifyCallback); - -void handleAccessory(const char *request, unsigned int requestLen, char **reply, unsigned int *replyLen, connectionInfo *sender); - -void updateValueFromDeviceEnd(characteristics *c, int aid, int iid, string value); \ No newline at end of file +#pragma once +// +// PHKAccessory.h +// Workbench +// +// Created by Wai Man Chan on 9/27/14. +// +// + +#include +#include +#define __STDC_LIMIT_MACROS +#include +extern "C" { +#include +} + +#include "PHKNetworkIP.h" + +#include "PHKControllerRecord.h" + +extern "C" { +#include "PHKArduinoLightInterface.h" +} + +#include + +#if MCU +#else +#include +#endif + +using namespace std; + +typedef enum { + charType_adminOnlyAccess = 0x1, + charType_audioChannels = 0x2, + charType_audioCodexName = 0x3, + charType_audioCodexParameter= 0x4, + charType_audioFeedback = 0x5, + charType_audioPropAttr = 0x6, + charType_audioValAttr = 0x7, + charType_brightness = 0x8, + charType_cameraNightVision = 0x9, + charType_cameraPan = 0xA, + charType_cameraTilt = 0xB, + charType_cameraZoom = 0xC, + charType_coolingThreshold = 0xD, + charType_currentDoorState = 0xE, + charType_currentHeatCoolMode= 0xF, + charType_currentHumidity = 0x10, + charType_currentTemperature = 0x11, + charType_heatingThreshold = 0x12, + charType_hue = 0x13, + charType_identify = 0x14, + charType_inputVolume = 0x15, + charType_ipCameraStart = 0x16, + charType_ipCameraStop = 0x17, + charType_lockControlPoint = 0x19, + charType_lockAutoTimeout = 0x1A, + charType_lockLastAction = 0x1C, + charType_lockCurrentState = 0x1D, + charType_lockTargetState = 0x1E, + charType_logs = 0x1F, + charType_manufactuer = 0x20, + charType_modelName = 0x21, + charType_motionDetect = 0x22, + charType_serviceName = 0x23, + charType_obstruction = 0x24, + charType_on = 0x25, + charType_outletInUse = 0x26, + charType_outputVolume = 0x27, + charType_rotationDirection = 0x28, + charType_rotationSpeed = 0x29, + charType_rtcpExtProp = 0x2A, + charType_rtcpVideoPayload = 0x2B, + charType_rtcpAudioPayload = 0x2C, + charType_rtcpAudioClock = 0x2D, + charType_rtcpProtocol = 0x2E, + charType_saturation = 0x2F, + charType_serialNumber = 0x30, + charType_srtpCyptoSuite = 0x31, + charType_targetDoorState = 0x32, + charType_targetHeatCoolMode = 0x33, + charType_targetHumidity = 0x34, + charType_targetTemperature = 0x35, + charType_temperatureUnit = 0x36, + charType_version = 0x37, + charType_videoCodexName = 0x38, + charType_videoCodexPara = 0x39, + charType_videoMirror = 0x3A, + charType_videoPropAttr = 0x3B, + charType_videoRotation = 0x3C, + charType_videoValAttr = 0x3D, + +//#pragma - The following is only default by the device after iOS 9 + + charType_firmwareRevision = 0x52, + charType_hardwareRevision = 0x53, + charType_softwareRevision = 0x54, + + charType_reachable = 0x63, + + charType_airParticulateDensity = 0x64, + charType_airParticulateSize = 0x65, + charType_airQuality = 0x95, + charType_carbonDioxideDetected = 0x92, + charType_carbonMonoxideDetected = 0x69, + charType_carbonDioxideLevel = 0x93, + charType_carbonMonoxideLevel = 0x90, + charType_carbonDioxidePeakLevel = 0x94, + charType_carbonMonoxidePeakLevel = 0x91, + charType_smokeDetected = 0x76, + + charType_alarmCurrentState = 0x66, + charType_alarmTargetState = 0x67, + charType_batteryLevel = 0x68, + charType_contactSensorState = 0x6A, + charType_holdPosition = 0x6F, + charType_leakDetected = 0x70, + charType_occupancyDetected = 0x71, + + charType_currentAmbientLightLevel = 0x6B, + charType_currentHorizontalTiltAngle = 0x6C, + charType_targetHorizontalTiltAngle = 0x7B, + charType_currentPosition = 0x6D, + charType_targetPosition = 0x7C, + charType_currentVerticalTiltAngle = 0x6E, + charType_targetVerticalTiltAngle = 0x7D, + + charType_positionState = 0x72, + charType_programmableSwitchEvent = 0x73, + charType_programmableSwitchOutputState = 0x74, + + charType_sensorActive = 0x75, + charType_sensorFault = 0x77, + charType_sensorJammed = 0x78, + charType_sensorLowBattery = 0x79, + charType_sensorTampered = 0x7A, + charType_sensorChargingState= 0x8F, + + +//#pragma - The following is service provide + serviceType_accessoryInfo = 0x3E, + serviceType_camera = 0x3F, + serviceType_fan = 0x40, + serviceType_garageDoorOpener = 0x41, + serviceType_lightBulb = 0x43, + serviceType_lockManagement = 0x44, + serviceType_lockMechanism = 0x45, + serviceType_microphone = 0x46, + serviceType_outlet = 0x47, + serviceType_speaker = 0x48, + serviceType_switch = 0x49, + serviceType_thermostat = 0x4A, + + serviceType_alarmSystem = 0x7E, + serviceType_bridgingState = 0x62, + serviceType_carbonMonoxideSensor = 0x7F, + serviceType_contactSensor = 0x80, + serviceType_door = 0x81, + serviceType_humiditySensor = 0x82, + serviceType_leakSensor = 0x83, + serviceType_lightSensor = 0x84, + serviceType_motionSensor = 0x85, + serviceType_occupancySensor = 0x86, + serviceType_smokeSensor = 0x87, + serviceType_programmableSwitch_stateful = 0x88, + serviceType_programmableSwitch_stateless = 0x89, + serviceType_temperatureSensor = 0x8A, + serviceType_window = 0x8B, + serviceType_windowCover = 0x8C, + serviceType_airQualitySensor = 0x8C, + serviceType_securityAlarm = 0x8E, + serviceType_charging = 0x8F, + + serviceType_battery = 0x96, + serviceType_carbonDioxideSensor= 0x97, + +//#pragma - The following is for bluetooth characteristic + btCharType_pairSetup = 0x4C, + btCharType_pairVerify = 0x4E, + btCharType_pairingFeature = 0x4F, + btCharType_pairings = 0x50, + btCharType_serviceInstanceID = 0x51, +//#pragma - The following is for bluetooth service + btServiceType_accessoryInformation = 0xFED3, + btServiceType_camera = 0xFEC9, + btServiceType_fan = 0xFECB, + btServiceType_garageDoorOpener = 0xFECE, + btServiceType_lightBulb = 0xFED2, + btServiceType_lockManagement = 0xFECF, + btServiceType_lockMechanism = 0xFED0, + btServiceType_microphone = 0xFEC8, + btServiceType_outlet = 0xFECC, + btServiceType_speaker = 0xFEC7, + btServiceType_switch = 0xFECD, + +} charType; + +enum { + premission_read = 1, + premission_write = 1 << 1, + premission_notify = 1 << 2 //Notify = Accessory will notice the controller +}; + +typedef enum { + unit_none = 0, + unit_celsius, + unit_percentage, + unit_arcDegree +} unit; + + +class characteristics { +public: + + const unsigned short type; + const int premission; + int iid; + characteristics(unsigned short _type, int _premission): type(_type), premission(_premission) {} + virtual string value() = 0; + virtual void setValue(string str) = 0; + virtual string describe() = 0; + bool writable() { return premission&premission_write ? true : false ; } + bool notifiable() { return premission&premission_notify ? true : false; } +}; + +//To store value of device state, subclass the following type +class boolCharacteristics: public characteristics { +public: + bool _value; + void (*valueChangeFunctionCall)(bool oldValue, bool newValue); + boolCharacteristics(unsigned short _type, int _premission) + : valueChangeFunctionCall(NULL) + , characteristics(_type, _premission) + { + } + virtual string value() { + if (_value) + return "1"; + return "0"; + } + virtual void setValue(string str) { + bool newValue = false; + if (strncmp("true", str.c_str(), 4)==0 || strncmp("1", str.c_str(), 1)==0 ) + { + newValue = true; + } + if (valueChangeFunctionCall) + valueChangeFunctionCall(_value, newValue); + _value = newValue; + } + virtual string describe(); +}; + +class floatCharacteristics: public characteristics { +public: + float _value; + const float _minVal, _maxVal, _step; + const unit _unit; + void (*valueChangeFunctionCall)(float oldValue, float newValue); + floatCharacteristics(unsigned short _type, int _premission, float minVal, float maxVal, float step, unit charUnit) + : valueChangeFunctionCall(NULL) + ,characteristics(_type, _premission) + , _minVal(minVal) + , _maxVal(maxVal) + , _step(step) + , _unit(charUnit) + { + } + virtual string value() { + char temp[16]; + snprintf(temp, 16, "%f", _value); + return temp; + } + virtual void setValue(string str) { + float temp = (float) atof(str.c_str()); + if (temp == temp) { + if (valueChangeFunctionCall) + valueChangeFunctionCall(_value, temp); + _value = temp; + } + } + virtual string describe(); +}; + +class intCharacteristics: public characteristics { +public: + int _value; + const int _minVal, _maxVal, _step; + const unit _unit; + void (*valueChangeFunctionCall)(int oldValue, int newValue); + intCharacteristics(unsigned short _type, int _premission, int minVal, int maxVal, int step, unit charUnit) + : valueChangeFunctionCall(NULL) + , characteristics(_type, _premission) + , _minVal(minVal) + , _maxVal(maxVal) + , _step(step) + , _unit(charUnit) + { + _value = minVal; + } + virtual string value() { + char temp[16]; + snprintf(temp, 16, "%d", _value); + return temp; + } + virtual void setValue(string str) { + int temp = (int)atoi(str.c_str()); + if (temp == temp) { + if (valueChangeFunctionCall) + valueChangeFunctionCall(_value, (int)temp); + _value = (int) temp; + } + } + virtual string describe(); +}; + +class uint8Characteristics: public characteristics { +public: + int _value; + const int _minVal, _maxVal, _step; + const unit _unit; + void (*valueChangeFunctionCall)(int oldValue, int newValue); + uint8Characteristics(unsigned short _type, int _premission, int minVal, int maxVal, int step, unit charUnit) + : valueChangeFunctionCall(NULL) + , characteristics(_type, _premission) + , _minVal(minVal) + , _maxVal(maxVal) + , _step(step) + , _unit(charUnit) + { + _value = minVal; + } + virtual string value() { + char temp[16]; + snprintf(temp, 16, "%d", _value); + return temp; + } + virtual void setValue(string str) { + int temp = (int)atoi(str.c_str()); + if (temp == temp) { + if (valueChangeFunctionCall) + valueChangeFunctionCall(_value, (int)temp); + _value = (int) temp; + } + } + virtual string describe(); +}; + +class stringCharacteristics: public characteristics { +public: + string _value; + const unsigned short maxLen; + void (*valueChangeFunctionCall)(string oldValue, string newValue); + stringCharacteristics(unsigned short _type, int _premission, unsigned short _maxLen) + : valueChangeFunctionCall(NULL) + , characteristics(_type, _premission) + , maxLen(_maxLen) + { + } + virtual string value() { + return "\""+_value+"\""; + } + virtual void setValue(string str) { + if (valueChangeFunctionCall) + valueChangeFunctionCall(_value, str); + _value = str; + } + virtual string describe(); +}; + +//Abstract Layer of object +class Service { +public: + int serviceID, uuid; + vector _characteristics; + Service(int _uuid): uuid(_uuid) {} + virtual short numberOfCharacteristics() { return _characteristics.size(); } + virtual characteristics *characteristicsAtIndex(int index) { return _characteristics[index]; } + string describe(); +}; + +class Accessory { + int numberOfInstance; + vector_services; +public: + int aid; + void addService(Service *ser) { + ser->serviceID = ++numberOfInstance; + _services.push_back(ser); + } + void addCharacteristics(Service *ser, characteristics *cha) { + cha->iid = ++numberOfInstance; + ser->_characteristics.push_back(cha); + } + bool removeService(Service *ser) { + bool exist = false; + for (vector::iterator it = _services.begin(); it != _services.end(); it++) { + if (*it == ser) { + _services.erase(it); + exist = true; + } + } + delete ser; + return exist; + } + bool removeCharacteristics(characteristics *cha) { + bool exist = false; + for (vector::iterator it = _services.begin(); it != _services.end(); it++) { + for (vector::iterator jt = (*it)->_characteristics.begin(); jt != (*it)->_characteristics.end(); jt++) { + if (*jt == cha) { + (*it)->_characteristics.erase(jt); + exist = true; + } + } + } + delete cha; + return exist; + } + Accessory() : numberOfInstance (0) + { + } + virtual ~Accessory() + { + RemoveALL(); + } + short numberOfService() { return _services.size(); } + Service *serviceAtIndex(int index) { + for (vector::iterator it = _services.begin(); it != _services.end(); it++) { + if ((*it)->serviceID == index) { + return *it; + } + } + return NULL; + } + characteristics *characteristicsAtIndex(int index) { + for (vector::iterator it = _services.begin(); it != _services.end(); it++) { + for (vector::iterator jt = (*it)->_characteristics.begin(); jt != (*it)->_characteristics.end(); jt++) { + if ((*jt)->iid == index) { + return *jt; + } + } + } + return NULL; + } + string describe(); + void RemoveALL() + { + for (vector::iterator it = _services.begin(); it != _services.end(); it++) { + for (vector::iterator jt = (*it)->_characteristics.begin(); jt != (*it)->_characteristics.end(); jt++) { + delete *jt; + } + delete *it; + } + _services.clear(); + numberOfInstance = 0; + } +}; + + +class AccessorySet { +private: + vector _accessories; + int _aid; + pthread_mutex_t accessoryMutex; + AccessorySet() { + _aid = 0; + pthread_mutex_init(&accessoryMutex, NULL); + } + AccessorySet(AccessorySet const&); + void operator=(AccessorySet const&); +public: + static AccessorySet& getInstance() { + static AccessorySet instance; + + return instance; + } + void lock(); + void unlock(); + short numberOfAccessory() { + return (short) _accessories.size(); + } + Accessory *accessoryAtIndex(int index) { + for (vector::iterator it = _accessories.begin(); it != _accessories.end(); it++) { + if ((*it)->aid == index) { + return *it; + } + } + return NULL; + } + void addAccessory(Accessory *acc) { + acc->aid = ++_aid; + _accessories.push_back(acc); + } + bool removeAccessory(Accessory *acc) { + bool exist = false; + for (vector::iterator it = _accessories.begin(); it != _accessories.end(); it++) { + if (*it == acc) { + _accessories.erase(it); + exist = true; + } + } + delete acc; + return exist; + } + void RemoveALL() { + for (vector::iterator it = _accessories.begin(); it != _accessories.end(); it++) { + delete *it; + } + _accessories.clear(); + _aid = 0; + } + ~AccessorySet() { + pthread_mutex_destroy(&accessoryMutex); + RemoveALL(); + } + string describe(); + + ControllerRecord Controllers; +}; + +class AccessorySetAutoLock { +public: + AccessorySetAutoLock(){ + AccessorySet::getInstance().lock(); + } + + virtual ~AccessorySetAutoLock(){ + AccessorySet::getInstance().unlock(); + } +}; + +typedef void (*identifyFunction)(bool oldValue, bool newValue); + +//Since Info Service contains only constant, only add method will be provided +void addInfoServiceToAccessory(Accessory *acc, string accName, string manufactuerName, string modelName, string serialNumber, identifyFunction identifyCallback); + +void handleAccessory(const char *request, unsigned int requestLen, char **reply, unsigned int *replyLen, connectionInfo *sender); + +void updateValueFromDeviceEnd(characteristics *c, int aid, int iid, string value); + +//logger +typedef int(*PERSONAL_LOGGER_FUNCTION)(const char* msg,...); +extern PERSONAL_LOGGER_FUNCTION g_homekit_logger; +void Personal_homekit_set_logger_function(PERSONAL_LOGGER_FUNCTION); diff --git a/PHKArduinoLightInterface.c b/PHKArduinoLightInterface.c old mode 100644 new mode 100755 diff --git a/PHKArduinoLightInterface.h b/PHKArduinoLightInterface.h old mode 100644 new mode 100755 diff --git a/PHKControllerRecord.cpp b/PHKControllerRecord.cpp old mode 100644 new mode 100755 index 0580a77..cb05c4c --- a/PHKControllerRecord.cpp +++ b/PHKControllerRecord.cpp @@ -6,12 +6,9 @@ // // -#include "PHKControllerRecord.h" -#include "Configuration.h" #include #include - #if MCU #else #include @@ -19,19 +16,22 @@ using namespace std; -vectorreadIn(); -vectorcontrollerRecords = readIn(); +#include "PHKControllerRecord.h" +#include "Configuration.h" + -vectorreadIn() { + + + +void ControllerRecord::loadController() { ifstream fs; #if MCU #else - fs.open(controllerRecordsAddress, std::ifstream::in); + fs.open(this->storeFilePath.c_str(), std::ifstream::in); #endif - char buffer[70]; - bzero(buffer, 70); + char buffer[70] = {0}; PHKKeyRecord record; vector results; @@ -50,62 +50,67 @@ vectorreadIn() { #else fs.close(); #endif - - return results; + this->controllerRecords = results; } -void resetControllerRecord() { - ofstream fs; - fs.open(controllerRecordsAddress, std::ofstream::out|std::ofstream::trunc); +void ControllerRecord::resetController() { + unlink(this->storeFilePath.c_str() ); + this->controllerRecords.clear(); } -bool hasController() { - return controllerRecords.size() > 0; +bool ControllerRecord::hasController() { + return this->controllerRecords.size() > 0; } -void addControllerKey(PHKKeyRecord record) { - if (doControllerKeyExist(record) == false) { - controllerRecords.push_back(record); - +void ControllerRecord::storeFiles() +{ #if MCU #else - ofstream fs; - fs.open(controllerRecordsAddress, std::ofstream::trunc); + ofstream fs; + fs.open(this->storeFilePath.c_str(), std::ofstream::trunc); #endif - for (vector::iterator it = controllerRecords.begin(); it != controllerRecords.end(); it++) { + for (vector::iterator it = this->controllerRecords.begin(); it != this->controllerRecords.end(); it++) { #if MCU #else - fs.write(it->controllerID, 36); - fs.write(it->publicKey, 32); + fs.write(it->controllerID, 36); + fs.write(it->publicKey, 32); #endif - } - fs.close(); + } + fs.close(); +} + +void ControllerRecord::addControllerKey(PHKKeyRecord record) { + if (doControllerKeyExist(record) == false) { + this->controllerRecords.push_back(record); + storeFiles(); } } -bool doControllerKeyExist(PHKKeyRecord record) { - for (vector::iterator it = controllerRecords.begin(); it != controllerRecords.end(); it++) { +bool ControllerRecord::doControllerKeyExist(PHKKeyRecord record) { + for (vector::iterator it = this->controllerRecords.begin(); it != this->controllerRecords.end(); it++) { if (bcmp((*it).controllerID, record.controllerID, 32) == 0) return true; } return false; } -void removeControllerKey(PHKKeyRecord record) { - for (vector::iterator it = controllerRecords.begin(); it != controllerRecords.end(); it++) { +void ControllerRecord::removeControllerKey(PHKKeyRecord record) { + for (vector::iterator it = this->controllerRecords.begin(); it != this->controllerRecords.end(); it++) { if (bcmp((*it).controllerID, record.controllerID, 32) == 0) { - controllerRecords.push_back(record); + this->controllerRecords.erase(it); + storeFiles(); return; } } } -PHKKeyRecord getControllerKey(char key[32]) { - for (vector::iterator it = controllerRecords.begin(); it != controllerRecords.end(); it++) { +PHKKeyRecord ControllerRecord::getControllerKey(char key[32]) { + for (vector::iterator it = this->controllerRecords.begin(); it != this->controllerRecords.end(); it++) { if (bcmp(key, it->controllerID, 32) == 0) return *it; } PHKKeyRecord emptyRecord; bzero(emptyRecord.controllerID, 32); return emptyRecord; } + diff --git a/PHKControllerRecord.h b/PHKControllerRecord.h old mode 100644 new mode 100755 index c868e17..dda6cb1 --- a/PHKControllerRecord.h +++ b/PHKControllerRecord.h @@ -1,24 +1,45 @@ -#pragma once -// -// PHKControllerRecord.h -// Workbench -// -// Created by Wai Man Chan on 9/23/14. -// -// - -#include -#include -using namespace std; - -struct PHKKeyRecord { - char controllerID[36]; - char publicKey[32]; -}; - -void resetControllerRecord(); -bool hasController(); -void addControllerKey(PHKKeyRecord record); -bool doControllerKeyExist(PHKKeyRecord record); -void removeControllerKey(PHKKeyRecord record); -PHKKeyRecord getControllerKey(char key[32]); +#pragma once +// +// PHKControllerRecord.h +// Workbench +// +// Created by Wai Man Chan on 9/23/14. +// +// + +#include +#include +using namespace std; + +struct PHKKeyRecord { + char controllerID[36]; + char publicKey[32]; +}; + +class ControllerRecord +{ + string storeFilePath; + vector controllerRecords; + + void storeFiles(); + void loadController() ; +public: + ControllerRecord() + { + } + virtual ~ControllerRecord() + { + } + void create(const std::string& storeFilePath) + { + this->storeFilePath = storeFilePath; + loadController(); + } + + void resetController() ; + bool hasController() ; + void addControllerKey(PHKKeyRecord record) ; + bool doControllerKeyExist(PHKKeyRecord record) ; + void removeControllerKey(PHKKeyRecord record) ; + PHKKeyRecord getControllerKey(char key[32]) ; +}; diff --git a/PHKNetworkIP.cpp b/PHKNetworkIP.cpp index e79d0fe..f85534f 100755 --- a/PHKNetworkIP.cpp +++ b/PHKNetworkIP.cpp @@ -61,31 +61,31 @@ using namespace std; #define portNumber 0 -#if MCU -#else connectionInfo connection[numberOfClient]; -#endif const unsigned char modulusStr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; const unsigned char curveBasePoint[] = { 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; const unsigned char generator[] = {0x05}; -char tempStr[3073]; const unsigned char accessorySecretKey[32] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74}; -int _socket_v4; -DNSServiceRef netServiceV4; +static std::string g_DeviceName; +static std::string g_PinCode; +static std::string g_DeviceIdentity; + +static int _socket_v4 = -1; +static DNSServiceRef netServiceV4; #ifdef _WIN32 #else -int _socket_v6; -DNSServiceRef netServiceV6; +static int _socket_v6 = -1; +static DNSServiceRef netServiceV6; #endif deviceType currentDeviceType = deviceType_other; -int currentConfigurationNum = 1; +static int g_currentConfigurationNum = 1; int is_big_endian(void) { @@ -108,7 +108,8 @@ int setupSocketV4(unsigned int maximumConnection) { bind(_socket, (const struct sockaddr *)&addr, sizeof(addr)); listen(_socket, maximumConnection); - return _socket; + + return _socket; } #ifdef _WIN32 @@ -140,7 +141,7 @@ unsigned short getSocketPortNumberV6(int _socket) { void registerFail(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, void *context ) { #if HomeKitLog == 1 - printf("Service can't register\n"); + g_homekit_logger("Service can't register\n"); #endif exit(0); } @@ -149,23 +150,27 @@ TXTRecordRef buildTXTRecord() { TXTRecordRef txtRecord; TXTRecordCreate(&txtRecord, 0, NULL); TXTRecordSetValue(&txtRecord, "pv", 3, "1.0"); //Version - TXTRecordSetValue(&txtRecord, "id", 17, deviceIdentity); //Device id - char buf[3]; - sprintf(buf, "%d", currentConfigurationNum); - TXTRecordSetValue(&txtRecord, "c#", 1, buf); //Configuration Number - TXTRecordSetValue(&txtRecord, "s#", 1, "4"); //Number of service - if (hasController()) buf[0] = '0'; + TXTRecordSetValue(&txtRecord, "id", 17, g_DeviceIdentity.c_str() ); //Device id + + char buf[10]; + snprintf(buf,10, "%d", g_currentConfigurationNum); + TXTRecordSetValue(&txtRecord, "c#", strlen(buf), buf); //Configuration Number + TXTRecordSetValue(&txtRecord, "s#", 1, "1"); //Number of service + + if (AccessorySet::getInstance().Controllers.hasController()) buf[0] = '0'; else buf[0] = '1'; TXTRecordSetValue(&txtRecord, "sf", 1, buf); //Discoverable: 0 if has been paired - TXTRecordSetValue(&txtRecord, "ff", 1, "0"); //1 for MFI product - TXTRecordSetValue(&txtRecord, "md", strlen(deviceName), deviceName); //Model Name - int len = sprintf(buf, "%d", currentDeviceType); + + TXTRecordSetValue(&txtRecord, "ff", 1, "0"); //1 for MFI product + TXTRecordSetValue(&txtRecord, "md", g_DeviceName.size(), g_DeviceName.c_str() ); //Model Name + + int len = sprintf(buf, "%d", currentDeviceType); TXTRecordSetValue(&txtRecord, "ci", len, buf); //1 for MFI product return txtRecord; } void updateConfiguration() { - currentConfigurationNum++; + g_currentConfigurationNum++; TXTRecordRef txtRecord = buildTXTRecord(); DNSServiceUpdateRecord(netServiceV4, NULL, 0, TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), 0); TXTRecordDeallocate(&txtRecord); @@ -174,16 +179,24 @@ void updateConfiguration() { void PHKNetworkIP::setupSocket() { TXTRecordRef txtRecord = buildTXTRecord(); _socket_v4 = setupSocketV4(5); - DNSServiceRegister(&netServiceV4, 0, 0, deviceName, PHKNetworkServiceType, "", NULL, htons(getSocketPortNumberV4(_socket_v4)), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), NULL, NULL); - TXTRecordDeallocate(&txtRecord); + + DNSServiceRegister(&netServiceV4, 0, 0, g_DeviceName.c_str() , PHKNetworkServiceType, "", NULL, htons(getSocketPortNumberV4(_socket_v4)), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), NULL, NULL); + + TXTRecordDeallocate(&txtRecord); } -PHKNetworkIP::PHKNetworkIP() { - SRP_initialize_library(); - srand((unsigned int)time(NULL)); - for (int i = 0; i < numberOfClient; i++) { - connection[i].subSocket = -1; - } +PHKNetworkIP::PHKNetworkIP(const string& name,const string& pinCode,const string& identity,const string& controllerRecordsPath) { + g_DeviceName = name; + g_PinCode = pinCode; + g_DeviceIdentity = identity; + AccessorySet::getInstance().Controllers.create(controllerRecordsPath); + + for(int i = 0 ; i < numberOfClient; i++ ) + { + connection[i].init(); + } + SRP_initialize_library(); + setupSocket(); } @@ -191,7 +204,7 @@ PHKNetworkIP::PHKNetworkIP() { void broadcastMessage(void *sender, char *resultData, size_t resultLen) { #if HomeKitLog == 1 - printf("Broadcast with sender\n"); + g_homekit_logger("Broadcast with sender\n"); #endif for (int i = 0; i < numberOfClient; i++) { @@ -200,11 +213,12 @@ void broadcastMessage(void *sender, char *resultData, size_t resultLen) { pthread_mutex_lock(&connection[i].mutex); - chacha20_ctx chacha20; bzero(&chacha20, sizeof(chacha20)); + chacha20_ctx chacha20 = {0}; - char temp[64]; bzero(temp, 64); char temp2[64]; bzero(temp2, 64); + char temp[64] = {0}; char temp2[64] = {0}; - char *reply = new char[resultLen+18]; + vector _reply_vec(resultLen+18); + char *reply = &_reply_vec[0]; reply[0] = resultLen%256; reply[1] = (resultLen-(uint8_t)reply[0])/256; @@ -218,8 +232,7 @@ void broadcastMessage(void *sender, char *resultData, size_t resultLen) { poly1305_context verifyContext; bzero(&verifyContext, sizeof(verifyContext)); poly1305_init(&verifyContext, (const unsigned char*)temp2); { - char waste[16]; - bzero(waste, 16); + char waste[16] = {0}; poly1305_update(&verifyContext, (const unsigned char *)reply, 2); poly1305_update(&verifyContext, (const unsigned char *)waste, 14); @@ -234,14 +247,12 @@ void broadcastMessage(void *sender, char *resultData, size_t resultLen) { } poly1305_finish(&verifyContext, (unsigned char*)&reply[resultLen+2]); #else - char verify[16]; - memset(verify, 0, 16); + char verify[16] = {0}; Poly1305_GenKey((const unsigned char *)temp2, (uint8_t *)reply, resultLen, Type_Data_With_Length, verify); memcpy((unsigned char*)&reply[resultLen+2], verify, 16); #endif send(socketNumber, reply, resultLen+18,0); - delete [] reply; pthread_mutex_unlock(&connection[i].mutex); } } @@ -251,17 +262,17 @@ void *connectionLoop(void *threadInfo) { int subSocket = info->subSocket; ssize_t len; if (subSocket >= 0) { #if HomeKitLog == 1 - printf("Start Connect: %d\n", subSocket); + g_homekit_logger("Start Connect: %d\n", subSocket); #endif do { len = recv(subSocket, info->buffer, 4096,0); #if HomeKitLog == 1 - printf("Return len %d for socket %d\n", len, subSocket); + g_homekit_logger("Return len %d for socket %d\n", len, subSocket); #endif #if HomeKitReplyHeaderLog == 1 - printf("Message: %s\n", info->buffer); + g_homekit_logger("Message: %s\n", info->buffer); #endif PHKNetworkMessage msg(info->buffer); @@ -298,7 +309,7 @@ void *connectionLoop(void *threadInfo) { close(subSocket); #endif #if HomeKitLog == 1 - printf("Stop Connect: %d\n", subSocket); + g_homekit_logger("Stop Connect: %d\n", subSocket); #endif info->subSocket = -1; @@ -307,8 +318,26 @@ void *connectionLoop(void *threadInfo) { return NULL; } +void PHKNetworkIP::closeAcceptConnection(){ + + if (_socket_v4 >= 0) + { +#ifdef _WIN32 + closesocket(_socket_v4); +#else + shutdown(_socket_v4,SHUT_RDWR); + close(_socket_v4); +#endif + _socket_v4 = -1; + } +} + void PHKNetworkIP::handleConnection() const { int subSocket = accept(_socket_v4, 0, NULL); + if (subSocket < 0) + { + return ; + } int index = -1; for (int i = 0; i < numberOfClient; i++) { @@ -339,7 +368,9 @@ void PHKNetworkIP::handleConnection() const { //Passed-in buf is len and data_buf void connectionInfo::Poly1305_GenKey(const unsigned char * key, uint8_t * buf, uint16_t len, Poly1305Type_t type, char* verify) { - printf("Length: %d\n", buf[0]); +#if HomeKitLog == 1 + g_homekit_logger("Length: %d\n", buf[0]); +#endif if (key == NULL || buf == NULL || len < 2 || verify == NULL) return; @@ -372,7 +403,7 @@ void connectionInfo::Poly1305_GenKey(const unsigned char * key, uint8_t * buf, u poly1305_update(&verifyContext, (const unsigned char *)&_len, 1); poly1305_update(&verifyContext, (const unsigned char *)&waste, 7); - _len = len; + _len = (unsigned char)len; poly1305_update(&verifyContext, (const unsigned char *)&_len, 1); _len = len/256; @@ -406,7 +437,7 @@ void connectionInfo::handlePairSeup() { switch (state) { case State_M1_SRPStartRequest: { #if HomeKitLog == 1 - printf("%s, %d: State_M1_SRPStartRequest\n", __func__, __LINE__); + g_homekit_logger("%s, %d: State_M1_SRPStartRequest\n", __func__, __LINE__); #endif PHKNetworkMessageDataRecord saltRec; PHKNetworkMessageDataRecord publicKeyRec; @@ -419,7 +450,7 @@ void connectionInfo::handlePairSeup() { SRP_RESULT result = SRP_set_username(srp, "Pair-Setup"); int modulusSize = sizeof(modulusStr) / sizeof(modulusStr[0]); result = SRP_set_params(srp, (const unsigned char *)modulusStr, modulusSize, (const unsigned char *)generator, 1, saltChar, 16); - result = SRP_set_auth_password(srp, devicePassword); + result = SRP_set_auth_password(srp, g_PinCode.c_str() ); result = SRP_gen_pub(srp, &publicKey); saltRec.index = 2; @@ -440,7 +471,7 @@ void connectionInfo::handlePairSeup() { break; case State_M3_SRPVerifyRequest: { #if HomeKitLog == 1 - printf("%s, %d: State_M3_SRPVerifyRequest\n", __func__, __LINE__); + g_homekit_logger("%s, %d: State_M3_SRPVerifyRequest\n", __func__, __LINE__); #endif const char *keyStr = 0; int keyLen = 0; @@ -466,7 +497,7 @@ void connectionInfo::handlePairSeup() { responseRecord.length = 1; mResponse.data.addRecord(responseRecord); #if HomeKitLog == 1 - printf("Oops at M3\n"); + g_homekit_logger("Oops at M3\n"); #endif } else { SRP_respond(srp, &response); @@ -478,7 +509,7 @@ void connectionInfo::handlePairSeup() { bcopy(response->data, responseRecord.data, responseRecord.length); mResponse.data.addRecord(responseRecord); #if HomeKitLog == 1 - printf("Password Correct\n"); + g_homekit_logger("Password Correct\n"); #endif } @@ -490,7 +521,7 @@ void connectionInfo::handlePairSeup() { break; case State_M5_ExchangeRequest: { #if HomeKitLog == 1 - printf("%s, %d: State_M5_ExchangeRequest\n", __func__, __LINE__); + g_homekit_logger("%s, %d: State_M5_ExchangeRequest\n", __func__, __LINE__); #endif const char *encryptedPackage = NULL;int packageLen = 0; @@ -526,20 +557,20 @@ void connectionInfo::handlePairSeup() { #if HomeKitLog == 1 for(int j = 0; j < packageLen-16; j++) - printf("%X ", decryptedData[j]); - printf("\n"); + g_homekit_logger("%X ", decryptedData[j]); + g_homekit_logger("\n"); - printf("verify: "); + g_homekit_logger("verify: "); for(int j = 0; j < 16; j++) - printf("%X ", verify[j]); - printf("\n"); + g_homekit_logger("%X ", verify[j]); + g_homekit_logger("\n"); - printf("mac: "); + g_homekit_logger("mac: "); for(int j = 0; j < 16; j++) - printf("%X ", mac[j]); - printf("\n"); + g_homekit_logger("%X ", mac[j]); + g_homekit_logger("\n"); - printf("Corrupt TLv8 at M5\n"); + g_homekit_logger("Corrupt TLv8 at M5\n"); #endif } else { /* @@ -554,7 +585,7 @@ void connectionInfo::handlePairSeup() { PHKKeyRecord newRecord; bcopy(controllerIdentifier, newRecord.controllerID, 36); bcopy(controllerPublicKey, newRecord.publicKey, 32); - addControllerKey(newRecord); + AccessorySet::getInstance().Controllers.addControllerKey(newRecord); const char salt[] = "Pair-Setup-Controller-Sign-Salt"; const char info[] = "Pair-Setup-Controller-Sign-Info"; @@ -573,7 +604,7 @@ void connectionInfo::handlePairSeup() { { PHKNetworkMessageDataRecord usernameRecord; - usernameRecord.activate = true; usernameRecord.index = 1; usernameRecord.length = strlen(deviceIdentity); usernameRecord.data = new char[usernameRecord.length]; bcopy(deviceIdentity, usernameRecord.data, usernameRecord.length); + usernameRecord.activate = true; usernameRecord.index = 1; usernameRecord.length = g_DeviceIdentity.size(); usernameRecord.data = new char[usernameRecord.length]; bcopy(g_DeviceIdentity.c_str(), usernameRecord.data, usernameRecord.length); returnTLV8->addRecord(usernameRecord); } @@ -586,7 +617,7 @@ void connectionInfo::handlePairSeup() { uint8_t output[150]; hkdf((const unsigned char*)salt, strlen(salt), (const unsigned char*)secretKey->data, secretKey->length, (const unsigned char*)info, strlen(info), output, 32); - bcopy(deviceIdentity, &output[32], strlen(deviceIdentity)); + bcopy(g_DeviceIdentity.c_str() , &output[32], g_DeviceIdentity.size() ); char *signature = new char[64]; ed25519_secret_key edSecret; @@ -594,8 +625,8 @@ void connectionInfo::handlePairSeup() { ed25519_public_key edPubKey; ed25519_publickey(edSecret, edPubKey); - bcopy(edPubKey, &output[32+strlen(deviceIdentity)], 32); - ed25519_sign(output, 64+strlen(deviceIdentity), (const unsigned char*)edSecret, (const unsigned char*)edPubKey, (unsigned char *)signature); + bcopy(edPubKey, &output[32+g_DeviceIdentity.size()], 32); + ed25519_sign(output, 64+g_DeviceIdentity.size(), (const unsigned char*)edSecret, (const unsigned char*)edPubKey, (unsigned char *)signature); PHKNetworkMessageDataRecord signatureRecord; signatureRecord.activate = true; signatureRecord.data = signature; signatureRecord.index = 10; signatureRecord.length = 64; returnTLV8->addRecord(signatureRecord); @@ -620,12 +651,11 @@ void connectionInfo::handlePairSeup() { chacha20_ctx ctx; bzero(&ctx, sizeof(ctx)); chacha20_setup(&ctx, (const uint8_t *)sessionKey, 32, (uint8_t *)"PS-Msg06"); - char buffer[64], key[64]; bzero(buffer, 64); + char buffer[64] = {0}, key[64]; chacha20_encrypt(&ctx, (const uint8_t *)buffer, (uint8_t *)key, 64); chacha20_encrypt(&ctx, (const uint8_t *)tlv8Data, (uint8_t *)tlv8Record.data, tlv8Len); - char verify[16]; - memset(verify, 0, 16); + char verify[16] = {0}; Poly1305_GenKey((const unsigned char *)key, (unsigned char*)tlv8Record.data, tlv8Len, Type_Data_Without_Length, verify); memcpy((unsigned char *)&tlv8Record.data[tlv8Len], verify, 16); } @@ -655,16 +685,16 @@ void connectionInfo::handlePairSeup() { mResponse.getBinaryPtr(&responseBuffer, &responseLen); if (responseBuffer) { #if HomeKitLog == 1 - printf("%s, %d, responseBuffer = %s, responseLen = %d\n", __func__, __LINE__, responseBuffer, responseLen); + g_homekit_logger("%s, %d, responseBuffer = %s, responseLen = %d\n", __func__, __LINE__, responseBuffer, responseLen); #endif int len = send(subSocket, responseBuffer, (size_t)responseLen,0); delete [] responseBuffer; #if HomeKitLog == 1 - printf("Pair Setup Transfered length %d\n", len); + g_homekit_logger("Pair Setup Transfered length %d\n", len); #endif } else { #if HomeKitLog == 1 - printf("Why empty response\n"); + g_homekit_logger("Why empty response\n"); #endif } @@ -683,7 +713,7 @@ void connectionInfo::handlePairVerify() { uint8_t enKey[32]; #if HomeKitLog == 1 - printf("Start Pair Verify\n"); + g_homekit_logger("Start Pair Verify\n"); #endif do { @@ -693,7 +723,7 @@ void connectionInfo::handlePairVerify() { switch (state) { case State_Pair_Verify_M1: { #if HomeKitLog == 1 - printf("Pair Verify M1\n"); + g_homekit_logger("Pair Verify M1\n"); #endif bcopy(msg.data.dataPtrForIndex(3), controllerPublicKey, 32); for (short i = 0; i < sizeof(secretKey); i++) { @@ -702,11 +732,12 @@ void connectionInfo::handlePairVerify() { curve25519_donna((u8*)publicKey, (const u8 *)secretKey, (const u8 *)curveBasePoint); curve25519_donna(sharedKey, secretKey, controllerPublicKey); - - char *temp = new char[100]; + + vector _temp_vec(100); + char *temp = &_temp_vec[0]; bcopy(publicKey, temp, 32); - bcopy(deviceIdentity, &temp[32], strlen(deviceIdentity)); - bcopy(controllerPublicKey, &temp[32+strlen(deviceIdentity)], 32); + bcopy(g_DeviceIdentity.c_str(), &temp[32], g_DeviceIdentity.size()); + bcopy(controllerPublicKey, &temp[32+g_DeviceIdentity.size()], 32); PHKNetworkMessageDataRecord signRecord; signRecord.activate = true; signRecord.data = new char[64]; signRecord.index = 10; signRecord.length = 64; @@ -716,13 +747,12 @@ void connectionInfo::handlePairVerify() { ed25519_public_key edPubKey; ed25519_publickey(edSecret, edPubKey); - ed25519_sign((const unsigned char *)temp, 64+strlen(deviceIdentity), edSecret, edPubKey, (unsigned char *)signRecord.data); - delete [] temp; + ed25519_sign((const unsigned char *)temp, 64+g_DeviceIdentity.size(), edSecret, edPubKey, (unsigned char *)signRecord.data); PHKNetworkMessageDataRecord idRecord; idRecord.activate = true; idRecord.data = new char[17]; - bcopy(deviceIdentity, idRecord.data, 17); + bcopy(g_DeviceIdentity.c_str() , idRecord.data, 17); idRecord.index = 1; idRecord.length = (unsigned int)17; @@ -745,10 +775,12 @@ void connectionInfo::handlePairVerify() { const char *plainMsg = 0; unsigned short msgLen = 0; data.rawData(&plainMsg, &msgLen); - char *encryptMsg = new char[msgLen+16]; - char *polyKey = new char[64]; bzero(polyKey, 64); + vector _encryptMsg_vec(msgLen+16); + vector _polyKey_vec(msgLen+16); + char *encryptMsg = &_encryptMsg_vec[0]; + char polyKey[64] = {0}; - char zero[64]; bzero(zero, 64); + char zero[64] = {0}; chacha20_ctx chacha; chacha20_setup(&chacha, enKey, 32, (uint8_t *)"PV-Msg02"); @@ -757,8 +789,7 @@ void connectionInfo::handlePairVerify() { delete [] plainMsg; - char verify[16]; - memset(verify, 0, 16); + char verify[16] = {0}; Poly1305_GenKey((const unsigned char *)polyKey, (uint8_t *)encryptMsg, msgLen, Type_Data_Without_Length, verify); memcpy((unsigned char *)&encryptMsg[msgLen], verify, 16); @@ -770,33 +801,32 @@ void connectionInfo::handlePairVerify() { bcopy(encryptMsg, encryptRecord.data, encryptRecord.length); response.data.addRecord(encryptRecord); - delete [] encryptMsg; - delete [] polyKey; } break; case State_Pair_Verify_M3: { #if HomeKitLog == 1 - printf("Pair Verify M3\n"); + g_homekit_logger("Pair Verify M3\n"); #endif char *encryptedData = msg.data.dataPtrForIndex(5); short packageLen = msg.data.lengthForIndex(5); - chacha20_ctx chacha20; bzero(&chacha20, sizeof(chacha20)); + chacha20_ctx chacha20 = {0}; chacha20_setup(&chacha20, (const uint8_t *)enKey, 32, (uint8_t *)"PV-Msg03"); //Ploy1305 key - char temp[64]; bzero(temp, 64); char temp2[64]; bzero(temp2, 64); + char temp[64] = {0}; char temp2[64] = {0}; chacha20_encrypt(&chacha20, (const uint8_t*)temp, (uint8_t *)temp2, 64); - char verify[16]; bzero(verify, 16); + char verify[16] = {0}; Poly1305_GenKey((const unsigned char *)temp2, (uint8_t *)encryptedData, packageLen - 16, Type_Data_Without_Length, verify); if (!bcmp(verify, &encryptedData[packageLen-16], 16)) { - char *decryptData = new char[packageLen-16]; + vector decryptData_vec(packageLen-16); + char *decryptData = &decryptData_vec[0]; chacha20_decrypt(&chacha20, (const uint8_t *)encryptedData, (uint8_t *)decryptData, packageLen-16); PHKNetworkMessageData data = PHKNetworkMessageData(decryptData, packageLen-16); - PHKKeyRecord rec = getControllerKey(data.dataPtrForIndex(1)); + PHKKeyRecord rec = AccessorySet::getInstance().Controllers.getControllerKey(data.dataPtrForIndex(1)); char tempMsg[100]; bcopy(controllerPublicKey, tempMsg, 32); @@ -813,7 +843,7 @@ void connectionInfo::handlePairVerify() { hkdf((uint8_t *)"Control-Salt", 12, sharedKey, 32, (uint8_t *)"Control-Write-Encryption-Key", 28, controllerToAccessoryKey, 32); #if HomeKitLog == 1 - printf("Verify success\n"); + g_homekit_logger("Verify success\n"); #endif } else { @@ -825,11 +855,10 @@ void connectionInfo::handlePairVerify() { error.length = 1; response.data.addRecord(error); #if HomeKitLog == 1 - printf("Verify failed\n"); + g_homekit_logger("Verify failed\n"); #endif } - delete [] decryptData; } } @@ -855,13 +884,14 @@ void connectionInfo::handlePairVerify() { void connectionInfo::handleAccessoryRequest() { connected = true; - - char *decryptData = new char[2048]; + + vector decryptData_vec(2048); + char *decryptData = &decryptData_vec[0]; int len; #if HomeKitLog == 1 - printf("Successfully Connect\n"); + g_homekit_logger("Successfully Connect\n"); #endif numberOfMsgRec = 0; @@ -881,50 +911,57 @@ void connectionInfo::handleAccessoryRequest() { chacha20_ctx chacha20; bzero(&chacha20, sizeof(chacha20)); - printf("send: %llx\n", numberOfMsgRec); - if (!is_big_endian()) numberOfMsgRec = bswap_64(numberOfMsgRec); - printf("send: %llx\n", numberOfMsgRec); - chacha20_setup(&chacha20, (const uint8_t *)controllerToAccessoryKey, 32, (uint8_t *)&numberOfMsgRec); +#if HomeKitLog == 1 + g_homekit_logger("send: %llx\n", numberOfMsgRec); +#endif + if (!is_big_endian()) numberOfMsgRec = bswap_64(numberOfMsgRec); +#if HomeKitLog == 1 + g_homekit_logger("send: %llx\n", numberOfMsgRec); +#endif + chacha20_setup(&chacha20, (const uint8_t *)controllerToAccessoryKey, 32, (uint8_t *)&numberOfMsgRec); if (!is_big_endian()) numberOfMsgRec = bswap_64(numberOfMsgRec); numberOfMsgRec++; - printf("send: %llx\n", numberOfMsgRec); - - char temp[64]; bzero(temp, 64); char temp2[64]; bzero(temp2, 64); +#if HomeKitLog == 1 + g_homekit_logger("send: %llx\n", numberOfMsgRec); +#endif + char temp[64] = {0}; char temp2[64] = {0}; chacha20_encrypt(&chacha20, (const uint8_t*)temp, (uint8_t *)temp2, 64); //Ploy1305 key - char verify[16]; bzero(verify, 16); + char verify[16] = {0}; Poly1305_GenKey((const unsigned char *)temp2, (uint8_t *)buffer, msgLen, Type_Data_With_Length, verify); bzero(decryptData, 2048); chacha20_encrypt(&chacha20, (const uint8_t *)&buffer[2], (uint8_t *)decryptData, msgLen); - printf("Request: %s\nPacketLen: %d\n, MessageLen: %d\n", decryptData, len, strlen(decryptData)); +#if HomeKitLog == 1 + g_homekit_logger("Request: %s\nPacketLen: %d\n, MessageLen: %d\n", decryptData, len, strlen(decryptData)); +#endif if(len >= (2 + msgLen + 16) && memcmp((void *)verify, (void *)&buffer[2 + msgLen], 16) == 0) { #if HomeKitLog == 1 - printf("Verify successfully!\n"); + g_homekit_logger("Verify successfully!\n"); #endif } else { #if HomeKitLog == 1 - printf("Passed-in data is no-verified!\n"); + g_homekit_logger("Passed-in data is no-verified!\n"); for (int i = 0; i < 16; i++) - printf("%ud ", verify[i]); - printf("\n"); + g_homekit_logger("%ud ", verify[i]); + g_homekit_logger("\n"); for (int i = 0; i < 16; i++) - printf("%ud ", buffer[2 + msgLen+i]); - printf("\n"); + g_homekit_logger("%ud ", buffer[2 + msgLen+i]); + g_homekit_logger("\n"); unsigned long long numberOfMsgRec_ = numberOfMsgRec-1; chacha20_setup(&chacha20, (const uint8_t *)controllerToAccessoryKey, 32, (uint8_t *)&numberOfMsgRec_); chacha20_encrypt(&chacha20, (const uint8_t*)temp, (uint8_t *)temp2, 64); Poly1305_GenKey((const unsigned char *)temp, (uint8_t *)buffer, msgLen, Type_Data_With_Length, verify); for (int i = 0; i < 16; i++) - printf("%ud ", verify[i]); - printf("\n"); + g_homekit_logger("%ud ", verify[i]); + g_homekit_logger("\n"); #endif continue; @@ -937,7 +974,8 @@ void connectionInfo::handleAccessoryRequest() { handleAccessory(decryptData, msgLen, &resultData, &resultLen, this); //18 = 2(resultLen) + 16(poly1305 verify key) - char *reply = new char[resultLen+18]; + vector reply_vec(resultLen+18); + char *reply = &reply_vec[0]; reply[0] = resultLen%256; reply[1] = (resultLen-(uint8_t)reply[0])/256; @@ -956,14 +994,12 @@ void connectionInfo::handleAccessoryRequest() { pthread_mutex_unlock(&mutex); - delete [] reply; delete [] resultData; } } while (len > 0); pthread_mutex_destroy(&mutex); - delete [] decryptData; connected = false; } @@ -971,6 +1007,15 @@ void connectionInfo::handleAccessoryRequest() { //Object Logic PHKNetworkIP::~PHKNetworkIP() { DNSServiceRefDeallocate(netServiceV4); + + for (int i = 0; i < numberOfClient; i++) { + if ( connection[i].connected ) + { + pthread_join(connection[i].thread,NULL); + } + } + + SRP_finalize_library(); } const char *copyLine(const char *rawData, char *destination) { @@ -1183,3 +1228,12 @@ PHKNetworkMessageDataRecord &PHKNetworkMessageDataRecord::operator=(const PHKNet PHKNetworkMessageDataRecord::~PHKNetworkMessageDataRecord() { if (length) delete [] data; } + +//remove all controller pairing +void resetControllerAll() +{ + AccessorySetAutoLock autolock; + + AccessorySet::getInstance().Controllers.resetController(); + g_currentConfigurationNum = 1; +} diff --git a/PHKNetworkIP.h b/PHKNetworkIP.h index 56ca557..84bd350 100755 --- a/PHKNetworkIP.h +++ b/PHKNetworkIP.h @@ -77,13 +77,20 @@ typedef enum void broadcastMessage(void *sender, char *resultData, size_t resultLen); class PHKNetworkIP { + void setupSocket(); void handlePairSeup(int subSocket, char *buffer) const; void handlePairVerify(int subSocket, char *buffer) const; + public: - PHKNetworkIP(); + PHKNetworkIP(const string& name + ,const string& pinCode + ,const string& identity + ,const string& controllerRecordsPath); void handleConnection() const; ~PHKNetworkIP(); + + void closeAcceptConnection(); }; class PHKNetworkMessageDataRecord { @@ -153,7 +160,7 @@ class connectionInfo { unsigned long long numberOfMsgRec; unsigned long long numberOfMsgSend; int subSocket; - char buffer[4096]; + char buffer[4096+1]; void *notificationList[numberOfNotifiableValue]; @@ -162,11 +169,19 @@ class connectionInfo { void handleAccessoryRequest(); connectionInfo() - : subSocket(0) - , numberOfMsgRec(0) - , numberOfMsgSend(0) - , connected(false) { + init(); + } + void init() + { + subSocket = (-1); + numberOfMsgRec = (0); + numberOfMsgSend = (0); + connected = (false); + memset(buffer,0,4096+1); + memset(notificationList,0,sizeof(void*)*numberOfNotifiableValue); + memset(controllerToAccessoryKey,0,sizeof(uint8_t)*32); + memset(accessoryToControllerKey,0,sizeof(uint8_t)*32); } void Poly1305_GenKey(const unsigned char * key, uint8_t * buf, uint16_t len, Poly1305Type_t type, char* verify); @@ -202,3 +217,6 @@ class connectionInfo { }; void updateConfiguration(); + +//remove all controller pairing +void resetControllerAll(); diff --git a/main.cpp b/main.cpp index 1f1f27c..78d636e 100755 --- a/main.cpp +++ b/main.cpp @@ -60,16 +60,12 @@ int main(int argc, const char * argv[]) { #if PowerOnTest==1 printf("poweron: %d\n", poly1305_power_on_self_test()); #endif - -#ifdef _WIN32 - WSADATA wsaData; - WSAStartup(2, &wsaData); -#endif + // insert code here... if (argc > 1) { //If there's some argument //Currently means reset - resetControllerRecord(); + resetControllerAll(); } initAccessorySet(); @@ -78,11 +74,14 @@ int main(int argc, const char * argv[]) { setupPort(); #endif - PHKNetworkIP networkIP; + PHKNetworkIP networkIP(deviceName,devicePassword,deviceIdentity,controllerRecordsAddress); do { networkIP.handleConnection(); } while (true); + //if you running PHKNetworkIP new accept thread, + //call PHKNetworkIP::closeAcceptConnection to stop. + #ifdef _WIN32 WSACleanup(); #endif From efa799f8e30427b60e0023dc0a55c24f4c22c5b1 Mon Sep 17 00:00:00 2001 From: rti Date: Sat, 3 Dec 2016 05:10:59 +0900 Subject: [PATCH 5/9] I forgot to fix conflict in main.cpp --- main.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/main.cpp b/main.cpp index b7226ce..cb6b38a 100755 --- a/main.cpp +++ b/main.cpp @@ -69,14 +69,11 @@ int main(int argc, const char * argv[]) { } initAccessorySet(); -<<<<<<< HEAD #ifdef _WIN32 #else setupPort(); #endif -======= //setupPort(); ->>>>>>> 55d7c8dff12d9e9e3294ac62d5dd0ad68ea3dd16 PHKNetworkIP networkIP(deviceName,devicePassword,deviceIdentity,controllerRecordsAddress); do { From 7ee2ba5958857d255f9f24221cdeefe0b78e169a Mon Sep 17 00:00:00 2001 From: rti Date: Sun, 4 Dec 2016 01:43:27 +0900 Subject: [PATCH 6/9] _snprintf has been changed to _snprintf_s. With VS 2010, this method was the same as snprintf's behavior and safe. --- PHKAccessory.cpp | 73 +++++++++++++------------------ windows_support_include/pthread.h | 2 +- windows_support_include/strings.h | 3 +- windows_support_include/unistd.h | 4 +- 4 files changed, 35 insertions(+), 47 deletions(-) diff --git a/PHKAccessory.cpp b/PHKAccessory.cpp index 6a38378..caebde6 100755 --- a/PHKAccessory.cpp +++ b/PHKAccessory.cpp @@ -38,12 +38,12 @@ inline string attribute(unsigned short type, unsigned short acclaim, int p, bool result += "]"; result += ","; - char tempStr[4]; - snprintf(tempStr, 4, "%X", type); + char tempStr[9]; + snprintf(tempStr, 9, "%X", type); result += wrap("type")+":"+wrap(tempStr); result += ","; - snprintf(tempStr, 4, "%hd", acclaim); + snprintf(tempStr, 9, "%hd", acclaim); result += wrap("iid")+":"+tempStr; result += ","; @@ -53,24 +53,24 @@ inline string attribute(unsigned short type, unsigned short acclaim, int p, bool } inline string attribute(unsigned short type, unsigned short acclaim, int p, int value, int minVal, int maxVal, int step, unit valueUnit,const std::string& format ) { string result; - char tempStr[4]; + char tempStr[9]; - snprintf(tempStr, 4, "%d", value); + snprintf(tempStr, 9, "%d", value); if (p & premission_read) { result += wrap("value")+":"+tempStr; result += ","; } - snprintf(tempStr, 4, "%d", minVal); + snprintf(tempStr, 9, "%d", minVal); if (minVal != INT32_MIN) result += wrap("minValue")+":"+tempStr+","; - snprintf(tempStr, 4, "%d", maxVal); + snprintf(tempStr, 9, "%d", maxVal); if (maxVal != INT32_MAX) result += wrap("maxValue")+":"+tempStr+","; - snprintf(tempStr, 4, "%d", step); + snprintf(tempStr, 9, "%d", step); if (step > 0) result += wrap("minStep")+":"+tempStr+","; @@ -83,11 +83,11 @@ inline string attribute(unsigned short type, unsigned short acclaim, int p, int result += "]"; result += ","; - snprintf(tempStr, 4, "%X", type); + snprintf(tempStr, 9, "%X", type); result += wrap("type")+":"+wrap(tempStr); result += ","; - snprintf(tempStr, 4, "%hd", acclaim); + snprintf(tempStr, 9, "%hd", acclaim); result += wrap("iid")+":"+tempStr; result += ","; @@ -109,24 +109,24 @@ inline string attribute(unsigned short type, unsigned short acclaim, int p, int } inline string attribute(unsigned short type, unsigned short acclaim, int p, float value, float minVal, float maxVal, float step, unit valueUnit) { string result; - char tempStr[4]; + char tempStr[9]; - snprintf(tempStr, 4, "%f", value); + snprintf(tempStr, 9, "%f", value); if (p & premission_read) { result += wrap("value")+":"+tempStr; result += ","; } - snprintf(tempStr, 4, "%f", minVal); + snprintf(tempStr, 9, "%f", minVal); if (minVal != INT32_MIN) result += wrap("minValue")+":"+tempStr+","; - snprintf(tempStr, 4, "%f", maxVal); + snprintf(tempStr, 9, "%f", maxVal); if (maxVal != INT32_MAX) result += wrap("maxValue")+":"+tempStr+","; - snprintf(tempStr, 4, "%f", step); + snprintf(tempStr, 9, "%f", step); if (step > 0) result += wrap("minStep")+":"+tempStr+","; @@ -139,11 +139,11 @@ inline string attribute(unsigned short type, unsigned short acclaim, int p, floa result += "]"; result += ","; - snprintf(tempStr, 4, "%X", type); + snprintf(tempStr, 9, "%X", type); result += wrap("type")+":"+wrap(tempStr); result += ","; - snprintf(tempStr, 4, "%hd", acclaim); + snprintf(tempStr, 9, "%hd", acclaim); result += wrap("iid")+":"+tempStr; result += ","; @@ -165,7 +165,7 @@ inline string attribute(unsigned short type, unsigned short acclaim, int p, floa } inline string attribute(unsigned short type, unsigned short acclaim, int p, string value, unsigned short len) { string result; - char tempStr[4]; + char tempStr[9]; if (p & premission_read) { result += wrap("value")+":"+wrap(value.c_str()); @@ -181,16 +181,16 @@ inline string attribute(unsigned short type, unsigned short acclaim, int p, stri result += "]"; result += ","; - snprintf(tempStr, 4, "%X", type); + snprintf(tempStr, 9, "%X", type); result += wrap("type")+":"+wrap(tempStr); result += ","; - snprintf(tempStr, 4, "%hd", acclaim); + snprintf(tempStr, 9, "%hd", acclaim); result += wrap("iid")+":"+tempStr; result += ","; if (len > 0) { - snprintf(tempStr, 4, "%hd", len); + snprintf(tempStr, 9, "%hd", len); result += wrap("maxLen")+":"+tempStr; result += ","; } @@ -253,13 +253,13 @@ string Service::describe() { string keys[3] = {"iid", "type", "characteristics"}; string values[3]; { - char temp[8]; - snprintf(temp, 8, "%d", serviceID); + char temp[9]; + snprintf(temp, 9, "%d", serviceID); values[0] = temp; } { - char temp[8]; - snprintf(temp, 8, "\"%X\"", uuid); + char temp[9]; + snprintf(temp, 9, "\"%X\"", uuid); values[1] = temp; } { @@ -280,8 +280,8 @@ string Accessory::describe() { { keys[0] = "aid"; - char temp[8]; - snprintf(temp,8, "%d", aid); + char temp[9]; + snprintf(temp,9, "%d", aid); values[0] = temp; } @@ -361,19 +361,6 @@ void *announce(void *info) { return NULL; } -void updateValueFromDeviceEnd(characteristics *c, int aid, int iid, string value) { - c->setValue(value); - string newValue = c->value(); - char *broadcastTemp = new char[1024]; - snprintf(broadcastTemp, 1024, "{\"characteristics\":[{\"aid\":%d,\"iid\":%d,\"value\":%s}]}", aid, iid, newValue.c_str()); - broadcastInfo * info = new broadcastInfo; - info->sender = c; - info->desc = broadcastTemp; - pthread_t thread; - pthread_create(&thread, NULL, announce, info); - -} - void handleAccessory(const char *request, unsigned int requestLen, char **reply, unsigned int *replyLen, connectionInfo *sender) { #if HomeKitLog == 1 g_homekit_logger("Receive request: %s\n", request); @@ -510,9 +497,9 @@ void handleAccessory(const char *request, unsigned int requestLen, char **reply, #if HomeKitLog == 1 g_homekit_logger("Ask for one characteristics: %d . %d\n", aid, iid); #endif - char c1[8], c2[8]; - snprintf(c1,8, "%d", aid); - snprintf(c2,8, "%d", iid); + char c1[9], c2[9]; + snprintf(c1,9, "%d", aid); + snprintf(c2,9, "%d", iid); string s[3] = {string(c1), string(c2), c->value()}; string k[3] = {"aid", "iid", "value"}; if (result.length() != 1) { diff --git a/windows_support_include/pthread.h b/windows_support_include/pthread.h index 24cec99..927d1d9 100755 --- a/windows_support_include/pthread.h +++ b/windows_support_include/pthread.h @@ -50,7 +50,7 @@ static void pthread_create(pthread_t* thread, const pthread_attr_t *attr_null,vo *thread = (HANDLE)_beginthreadex(NULL , 0 , _threadcallback::call , (void*)c , 0 ,NULL ); } -static void pthread_join(pthread_t* thread,void * nazo) +static void pthread_join(pthread_t thread,void * nazo) { ::WaitForSingleObject( thread , INFINITE); } diff --git a/windows_support_include/strings.h b/windows_support_include/strings.h index 6d73762..dbab1ab 100755 --- a/windows_support_include/strings.h +++ b/windows_support_include/strings.h @@ -3,7 +3,8 @@ #define bzero(b,len) (memset((b), '\0', (len)), (void) 0) #define bcopy(b1,b2,len) (memmove((b2), (b1), (len)), (void) 0) #define bcmp(b1,b2,len) (memcmp(b1,b2,len)) -#define snprintf _snprintf #define strtok_r strtok_s #define __func__ __FUNCTION__ + + diff --git a/windows_support_include/unistd.h b/windows_support_include/unistd.h index 9c7725c..40259b3 100755 --- a/windows_support_include/unistd.h +++ b/windows_support_include/unistd.h @@ -81,11 +81,11 @@ typedef int ssize_t; #endif #ifndef vsnprintf -#define vsnprintf _vsnprintf +#define vsnprintf(s, n, format, ...) _vsnprintf_s(s, n, _TRUNCATE, format, __VA_ARGS__) #endif #ifndef snprintf -#define snprintf _snprintf +#define snprintf(s, n, format, ...) _snprintf_s(s, n, _TRUNCATE, format, __VA_ARGS__) #endif From 5f367b8e4e8cccf2f2008f6bb3057524f25be64e Mon Sep 17 00:00:00 2001 From: rti Date: Sun, 4 Dec 2016 12:24:23 +0900 Subject: [PATCH 7/9] Fixed Memory Leak. Fixed Windows WinsockStartup --- PHKNetworkIP.cpp | 12 +++++++++--- main.cpp | 5 +++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/PHKNetworkIP.cpp b/PHKNetworkIP.cpp index 139116d..3d60058 100755 --- a/PHKNetworkIP.cpp +++ b/PHKNetworkIP.cpp @@ -548,13 +548,14 @@ void connectionInfo::handlePairSeup() { chacha20_setup(&chacha20, (const uint8_t *)sessionKey, 32, (uint8_t *)"PS-Msg05"); //Ploy1305 key - char temp[64]; bzero(temp, 64); char temp2[64]; bzero(temp2, 64); + char temp[64] = {0}; char temp2[64] = {0}; chacha20_encrypt(&chacha20, (const uint8_t*)temp, (uint8_t *)temp2, 64); - char verify[16]; bzero(verify, 16); + char verify[16] = {0}; Poly1305_GenKey((const unsigned char*)temp2, (unsigned char *)encryptedData, packageLen - 16, Type_Data_Without_Length, verify); - char *decryptedData = new char[packageLen-16]; + vector decryptedData_vec(packageLen-16); + char *decryptedData = &decryptedData_vec[0]; bzero(decryptedData, packageLen-16); chacha20_decrypt(&chacha20, (const uint8_t *)encryptedData, (uint8_t *)decryptedData, packageLen-16); @@ -1113,6 +1114,11 @@ PHKNetworkMessageData & PHKNetworkMessageData::operator=(const PHKNetworkMessage for (int i = 0; i < 10; i++) { if (data.records[i].length) { records[i] = data.records[i]; + + if(records[i].length) + { + delete [] records[i].data; + } records[i].data = new char[records[i].length]; bcopy(data.records[i].data, records[i].data, data.records[i].length); } diff --git a/main.cpp b/main.cpp index cb6b38a..6a1dece 100755 --- a/main.cpp +++ b/main.cpp @@ -60,6 +60,11 @@ int main(int argc, const char * argv[]) { #if PowerOnTest==1 printf("poweron: %d\n", poly1305_power_on_self_test()); #endif + +#ifdef _WIN32 + WSADATA wsaData; + WSAStartup(2 , &wsaData); +#endif // insert code here... if (argc > 1) { From 3dffb614d39234516249804eb09f6478c10c2fe4 Mon Sep 17 00:00:00 2001 From: rti Date: Mon, 5 Dec 2016 21:31:25 +0900 Subject: [PATCH 8/9] Fixed Memory Leak. - Adding pthread_detach - Fix srp_free leak --- PHKAccessory.cpp | 34 ------------------ PHKAccessory.h | 2 +- PHKNetworkIP.cpp | 57 ++++++++++++++++++++++++------- PHKNetworkIP.h | 1 + main.cpp | 20 +++++------ windows_support_include/pthread.h | 13 +++++-- 6 files changed, 67 insertions(+), 60 deletions(-) diff --git a/PHKAccessory.cpp b/PHKAccessory.cpp index caebde6..d5efcc2 100755 --- a/PHKAccessory.cpp +++ b/PHKAccessory.cpp @@ -7,7 +7,6 @@ // #include "PHKAccessory.h" -#include "Configuration.h" const char hapJsonType[] = "application/hap+json"; @@ -334,32 +333,7 @@ struct broadcastInfo { char *desc; }; -void *announce(void *info) { - broadcastInfo *_info = (broadcastInfo *)info; - void *sender = _info->sender; - char *desc = _info->desc; - - vector reply_vec(1024); - char *reply = &reply_vec[0]; - int len = snprintf(reply, 1024, "EVENT/1.0 200 OK\r\nContent-Type: application/hap+json\r\nContent-Length: %lu\r\n\r\n%s", strlen(desc), desc); - -#if HomeKitLog == 1 && HomeKitReplyHeaderLog==1 - g_homekit_logger("%s\n", reply); -#endif - - //Use the /identify message. - // /Identify - -> write 204 (subSocket) - //I will use the fix of zyanlu. Thank you. - // - //broadcastMessage(sender, reply, len); - // - - delete [] desc; - delete [] info; - - return NULL; -} void handleAccessory(const char *request, unsigned int requestLen, char **reply, unsigned int *replyLen, connectionInfo *sender) { #if HomeKitLog == 1 @@ -582,14 +556,6 @@ void handleAccessory(const char *request, unsigned int requestLen, char **reply, if (c->writable()) { c->setValue(value); - char *broadcastTemp = new char[1024]; - snprintf(broadcastTemp, 1024, "{\"characteristics\":[{%s}]}", buffer1); - broadcastInfo * info = new broadcastInfo; - info->sender = c; - info->desc = broadcastTemp; - pthread_t thread; - pthread_create(&thread, NULL, announce, info); - statusCode = 204; } else { diff --git a/PHKAccessory.h b/PHKAccessory.h index ca0c09b..9c18a55 100755 --- a/PHKAccessory.h +++ b/PHKAccessory.h @@ -518,7 +518,7 @@ class AccessorySet { } string describe(); - ControllerRecord Controllers; + ControllerRecord Controllers; }; class AccessorySetAutoLock { diff --git a/PHKNetworkIP.cpp b/PHKNetworkIP.cpp index 3d60058..c80038e 100755 --- a/PHKNetworkIP.cpp +++ b/PHKNetworkIP.cpp @@ -188,6 +188,9 @@ void updateConfiguration() { } void PHKNetworkIP::setupSocket() { +#if HomeKitLog == 1 + g_homekit_logger("PHKNetworkIP::setupSocket\n"); +#endif TXTRecordRef txtRecord = buildTXTRecord(); _socket_v4 = setupSocketV4(5); @@ -327,7 +330,9 @@ void *connectionLoop(void *threadInfo) { info->subSocket = -1; } - return NULL; + + pthread_detach(info->thread); + return NULL; } void PHKNetworkIP::closeAcceptConnection(){ @@ -528,7 +533,14 @@ void connectionInfo::handlePairSeup() { const char salt[] = "Pair-Setup-Encrypt-Salt"; const char info[] = "Pair-Setup-Encrypt-Info"; int i = hkdf((const unsigned char*)salt, strlen(salt), (const unsigned char*)secretKey->data, secretKey->length, (const unsigned char*)info, strlen(info), (uint8_t*)sessionKey, 32); - if (i != 0) return; + if (i != 0) + { +#if HomeKitLog == 1 + g_homekit_logger("hkdf result zero\n"); +#endif + SRP_free(srp); + return; + } } break; case State_M5_ExchangeRequest: { @@ -548,13 +560,13 @@ void connectionInfo::handlePairSeup() { chacha20_setup(&chacha20, (const uint8_t *)sessionKey, 32, (uint8_t *)"PS-Msg05"); //Ploy1305 key - char temp[64] = {0}; char temp2[64] = {0}; + char temp[64] = {0}; char temp2[64] = {0}; chacha20_encrypt(&chacha20, (const uint8_t*)temp, (uint8_t *)temp2, 64); - char verify[16] = {0}; + char verify[16] = {0}; Poly1305_GenKey((const unsigned char*)temp2, (unsigned char *)encryptedData, packageLen - 16, Type_Data_Without_Length, verify); - vector decryptedData_vec(packageLen-16); + vector decryptedData_vec(packageLen-16); char *decryptedData = &decryptedData_vec[0]; bzero(decryptedData, packageLen-16); chacha20_decrypt(&chacha20, (const uint8_t *)encryptedData, (uint8_t *)decryptedData, packageLen-16); @@ -603,7 +615,15 @@ void connectionInfo::handlePairSeup() { const char salt[] = "Pair-Setup-Controller-Sign-Salt"; const char info[] = "Pair-Setup-Controller-Sign-Info"; int i = hkdf((const unsigned char*)salt, strlen(salt), (const unsigned char*)secretKey->data, secretKey->length, (const unsigned char*)info, strlen(info), (uint8_t*)controllerHash, 32); - if (i != 0) return; + if (i != 0) + { +#if HomeKitLog == 1 + g_homekit_logger("hkdf result zero (2)\n"); +#endif + delete subTLV8; + SRP_free(srp); + return; + } bcopy(controllerIdentifier, &controllerHash[32], 36); bcopy(controllerPublicKey, &controllerHash[68], 32); @@ -611,7 +631,14 @@ void connectionInfo::handlePairSeup() { int ed25519_err = ed25519_sign_open((const unsigned char*)controllerHash, 100, (const unsigned char*)controllerPublicKey, (const unsigned char*)controllerSignature); delete subTLV8; - if (ed25519_err) return; + if (ed25519_err) + { +#if HomeKitLog == 1 + g_homekit_logger("ed25519_sign_open error %d\n",ed25519_err); +#endif + SRP_free(srp); + return; + } else { PHKNetworkMessageData *returnTLV8 = new PHKNetworkMessageData(); @@ -667,10 +694,12 @@ void connectionInfo::handlePairSeup() { char buffer[64] = {0}, key[64]; chacha20_encrypt(&ctx, (const uint8_t *)buffer, (uint8_t *)key, 64); chacha20_encrypt(&ctx, (const uint8_t *)tlv8Data, (uint8_t *)tlv8Record.data, tlv8Len); + delete [] tlv8Data; char verify[16] = {0}; Poly1305_GenKey((const unsigned char *)key, (unsigned char*)tlv8Record.data, tlv8Len, Type_Data_Without_Length, verify); memcpy((unsigned char *)&tlv8Record.data[tlv8Len], verify, 16); + } tlv8Record.activate = true; tlv8Record.index = 5; @@ -689,6 +718,7 @@ void connectionInfo::handlePairSeup() { } delete []encryptedData; + SRP_free(srp); return; } @@ -1019,10 +1049,11 @@ void connectionInfo::handleAccessoryRequest() { //Object Logic PHKNetworkIP::~PHKNetworkIP() { - DNSServiceRefDeallocate(netServiceV4); + closeAcceptConnection(); + DNSServiceRefDeallocate(netServiceV4); for (int i = 0; i < numberOfClient; i++) { - if ( connection[i].connected ) + if ( connection[i].subSocket >= 0 ) { pthread_join(connection[i].thread,NULL); } @@ -1115,10 +1146,10 @@ PHKNetworkMessageData & PHKNetworkMessageData::operator=(const PHKNetworkMessage if (data.records[i].length) { records[i] = data.records[i]; - if(records[i].length) - { - delete [] records[i].data; - } + if(records[i].length) + { + delete [] records[i].data; + } records[i].data = new char[records[i].length]; bcopy(data.records[i].data, records[i].data, data.records[i].length); } diff --git a/PHKNetworkIP.h b/PHKNetworkIP.h index 84bd350..3aee13f 100755 --- a/PHKNetworkIP.h +++ b/PHKNetworkIP.h @@ -118,6 +118,7 @@ class PHKNetworkMessageData { { this->count = 0; } + PHKNetworkMessageData(const char *rawData, unsigned short len); PHKNetworkMessageData(const PHKNetworkMessageData &data); PHKNetworkMessageData &operator=(const PHKNetworkMessageData &); diff --git a/main.cpp b/main.cpp index 6a1dece..bbc0270 100755 --- a/main.cpp +++ b/main.cpp @@ -60,27 +60,27 @@ int main(int argc, const char * argv[]) { #if PowerOnTest==1 printf("poweron: %d\n", poly1305_power_on_self_test()); #endif - + #ifdef _WIN32 WSADATA wsaData; WSAStartup(2 , &wsaData); #endif - - // insert code here... - if (argc > 1) { - //If there's some argument - //Currently means reset - resetControllerAll(); - } + // + PHKNetworkIP networkIP(deviceName,devicePassword,deviceIdentity,controllerRecordsAddress); + + // insert code here... + if (argc > 1) { + //If there's some argument + //Currently means reset + resetControllerAll(); + } initAccessorySet(); #ifdef _WIN32 #else setupPort(); #endif - //setupPort(); - PHKNetworkIP networkIP(deviceName,devicePassword,deviceIdentity,controllerRecordsAddress); do { networkIP.handleConnection(); } while (true); diff --git a/windows_support_include/pthread.h b/windows_support_include/pthread.h index 927d1d9..3bad688 100755 --- a/windows_support_include/pthread.h +++ b/windows_support_include/pthread.h @@ -41,16 +41,25 @@ struct _threadcallback{ typedef HANDLE pthread_t; typedef void* pthread_attr_t; -static void pthread_create(pthread_t* thread, const pthread_attr_t *attr_null,void *(*start_routine) (void *), void *arg) +static int pthread_create(pthread_t* thread, const pthread_attr_t *attr_null,void *(*start_routine) (void *), void *arg) { _threadcallback* c = new _threadcallback; c->start_routine = start_routine; c->arg = arg; *thread = (HANDLE)_beginthreadex(NULL , 0 , _threadcallback::call , (void*)c , 0 ,NULL ); + return 1; } -static void pthread_join(pthread_t thread,void * nazo) +static int pthread_join(pthread_t thread,void * nazo) { ::WaitForSingleObject( thread , INFINITE); + ::CloseHandle(thread); + return 1; +} + +static int pthread_detach(pthread_t thread) +{ + ::CloseHandle(thread); + return 1; } From e8a294571f1f15c84d8789da008f4516203ec2f8 Mon Sep 17 00:00:00 2001 From: rti7743 Date: Mon, 6 Feb 2017 21:07:50 +0900 Subject: [PATCH 9/9] Revived broadcastMessage() --- .gitignore | 1 + PHKAccessory.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/.gitignore b/.gitignore index 0def275..958706c 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ *.exe *.out *.app +*.sdf diff --git a/PHKAccessory.cpp b/PHKAccessory.cpp index d5efcc2..1be2129 100755 --- a/PHKAccessory.cpp +++ b/PHKAccessory.cpp @@ -329,11 +329,44 @@ string AccessorySet::describe() { struct broadcastInfo { + pthread_t thread; void *sender; char *desc; }; +void *announce(void *info) { + broadcastInfo *_info = (broadcastInfo *)info; + void *sender = _info->sender; + char *desc = _info->desc; + + char *reply = new char[1024]; + int len = snprintf(reply, 1024, "EVENT/1.0 200 OK\r\nContent-Type: application/hap+json\r\nContent-Length: %lu\r\n\r\n%s", strlen(desc), desc); + +#if HomeKitLog == 1 && HomeKitReplyHeaderLog==1 + g_homekit_logger("%s\n", reply); +#endif + pthread_t currentthread = _info->thread; + + broadcastMessage(sender, reply, len); + delete [] reply; + + delete [] desc; + delete [] info; + pthread_detach(currentthread); + return NULL; +} + +void updateValueFromDeviceEnd(characteristics *c, int aid, int iid, string value) { + c->setValue(value); + char *broadcastTemp = new char[1024]; + snprintf(broadcastTemp, 1024, "{\"characteristics\":[{\"aid\":%d,\"iid\":%d,\"value\":%s}]}", aid, iid, value.c_str()); + broadcastInfo * info = new broadcastInfo; + info->sender = c; + info->desc = broadcastTemp; + pthread_create(&info->thread, NULL, announce, info); + +} void handleAccessory(const char *request, unsigned int requestLen, char **reply, unsigned int *replyLen, connectionInfo *sender) { #if HomeKitLog == 1 @@ -556,6 +589,13 @@ void handleAccessory(const char *request, unsigned int requestLen, char **reply, if (c->writable()) { c->setValue(value); + char *broadcastTemp = new char[1024]; + snprintf(broadcastTemp, 1024, "{\"characteristics\":[{%s}]}", buffer1); + broadcastInfo * info = new broadcastInfo; + info->sender = c; + info->desc = broadcastTemp; + pthread_create(&info->thread, NULL, announce, info); + statusCode = 204; } else {