From: rtrimana Date: Wed, 9 May 2018 17:19:33 +0000 (-0700) Subject: Moving RPi folder. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b94c1a4dcb6e6876b39d3c8ee540840ad84c5ae4;p=iotcloud.git Moving RPi folder. --- diff --git a/version2/src/RPi/BulbColor.h b/version2/src/RPi/BulbColor.h deleted file mode 100644 index 329d060..0000000 --- a/version2/src/RPi/BulbColor.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef _BULBCOLOR_H__ -#define _BULBCOLOR_H__ -#include - -class BulbColor { - - private: - int hue; - int saturation; - int brightness; - int kelvin; - - public: - - BulbColor(int _hue, int _saturation, int _brightness, int _kelvin) { - - if ((_hue > 65535) || (_hue < 0)) { - cerr << "BulbColor: Invalid parameter value for _hue (0-65535)" << endl; - exit(1); - } - - if ((_saturation > 65535) || (_saturation < 0)) { - cerr << "BulbColor: Invalid parameter value for _saturation (0-65535)" << endl; - exit(1); - } - - if ((_brightness > 65535) || (_brightness < 0)) { - cerr << "BulbColor: Invalid parameter value for _brightness (0-65535)" << endl; - exit(1); - } - - if ((_kelvin > 65535) || (_kelvin < 0)) { - cerr << "BulbColor: Invalid parameter value for _kelvin (0-65535)" << endl; - exit(1); - } - - hue = _hue; - saturation = _saturation; - brightness = _brightness; - kelvin = _kelvin; - } - - - BulbColor(char* data) { - hue = ((data[1] & 0xFF) << 8); - hue |= (data[0] & 0xFF); - - saturation = ((data[3] & 0xFF) << 8); - saturation |= (data[2] & 0xFF); - - brightness = ((data[5] & 0xFF) << 8); - brightness |= (data[4] & 0xFF); - - kelvin = ((data[7] & 0xFF) << 8); - kelvin |= (data[6] & 0xFF); - } - - - ~BulbColor() { - } - - - int getHue() { - return hue; - } - - - int getSaturation() { - return saturation; - } - - - int getBrightness() { - return brightness; - } - - - int getKelvin() { - return kelvin; - } -}; -#endif diff --git a/version2/src/RPi/DeviceStateGroup.h b/version2/src/RPi/DeviceStateGroup.h deleted file mode 100644 index c54bce0..0000000 --- a/version2/src/RPi/DeviceStateGroup.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _DEVICESTATEGROUP_H__ -#define _DEVICESTATEGROUP_H__ -#include -#include - -class DeviceStateGroup { - - private: - char group[16]; - string label; - int64_t updatedAt; - - public: - - DeviceStateGroup(char _location[16], string _label, int64_t _updatedAt) { - - strcpy(group, _location); - label = _label; - updatedAt = _updatedAt; - } - - - ~DeviceStateGroup() { - } - - - char* getGroup() { - return group; - } - - - string getLabel() { - return label; - } - - - int64_t getUpdatedAt() { - return updatedAt; - } -}; -#endif diff --git a/version2/src/RPi/DeviceStateHostFirmware.h b/version2/src/RPi/DeviceStateHostFirmware.h deleted file mode 100644 index b2dd88a..0000000 --- a/version2/src/RPi/DeviceStateHostFirmware.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _DEVICESTATEHOSTFIRMWARE_H__ -#define _DEVICESTATEHOSTFIRMWARE_H__ -#include - -class DeviceStateHostFirmware { - // time of build in nanosecond accuracy - // after some tests - private: - int64_t build; - int64_t version; // firmware version - - public: - - DeviceStateHostFirmware(int64_t _build, int64_t _version) { - - build = _build; - version = _version; - } - - - ~DeviceStateHostFirmware() { - } - - - int64_t getBuild() { - return build; - } - - - int64_t getVersion() { - return version; - } - -}; -#endif diff --git a/version2/src/RPi/DeviceStateHostInfo.h b/version2/src/RPi/DeviceStateHostInfo.h deleted file mode 100644 index 081f6b9..0000000 --- a/version2/src/RPi/DeviceStateHostInfo.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _DEVICESTATEHOSTINFO_H__ -#define _DEVICESTATEHOSTINFO_H__ -#include - -class DeviceStateHostInfo { - private: - int64_t signal; - int64_t tx; - int64_t rx; - - public: - - DeviceStateHostInfo(int64_t _signal, int64_t _tx, int64_t _rx) { - - signal = _signal; - tx = _tx; - rx = _rx; - } - - - ~DeviceStateHostInfo() { - } - - - int64_t getSignal() { - return signal; - } - - - int64_t getTx() { - return tx; - } - - - int64_t getRx() { - return rx; - } -}; -#endif diff --git a/version2/src/RPi/DeviceStateInfo.h b/version2/src/RPi/DeviceStateInfo.h deleted file mode 100644 index 68d4bd5..0000000 --- a/version2/src/RPi/DeviceStateInfo.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _DEVICESTATEINFO_H__ -#define _DEVICESTATEINFO_H__ -#include - -class DeviceStateInfo { - private: - int64_t time; - int64_t upTime; - int64_t downTime; - - public: - - DeviceStateInfo(int64_t _time, int64_t _upTime, int64_t _downTime) { - - time = _time; - upTime = _upTime; - downTime = _downTime; - } - - - ~DeviceStateInfo() { - } - - - int64_t getTime() { - return time; - } - - - int64_t getUpTime() { - return upTime; - } - - - int64_t getDownTime() { - return downTime; - } -}; -#endif diff --git a/version2/src/RPi/DeviceStateLocation.h b/version2/src/RPi/DeviceStateLocation.h deleted file mode 100644 index 70f9bab..0000000 --- a/version2/src/RPi/DeviceStateLocation.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef _DEVICESTATELOCATION_H__ -#define _DEVICESTATELOCATION_H__ -#include -#include - -class DeviceStateLocation { - private: - char location[16]; - string label; - int64_t updatedAt; - - public: - - DeviceStateLocation(char _location[16], string _label, long _updatedAt) { - - strcpy(location, _location); - label = _label; - updatedAt = _updatedAt; - } - - - ~DeviceStateLocation() { - } - - - char* getLocation() { - return location; - } - - - string getLabel() { - return label; - } - - - int64_t getUpdatedAt() { - return updatedAt; - } -}; -#endif diff --git a/version2/src/RPi/DeviceStateService.h b/version2/src/RPi/DeviceStateService.h deleted file mode 100644 index 784cc3f..0000000 --- a/version2/src/RPi/DeviceStateService.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _DEVICESTATESERVICE_H__ -#define _DEVICESTATESERVICE_H__ -#include - -class DeviceStateService { - private: - int service; - int64_t port; - - public: - - DeviceStateService(int _service, long _port) { - - service = _service; - port = _port; - } - - - ~DeviceStateService() { - } - - - int getService() { - return service; - } - - - int64_t getPort() { - return port; - } -}; -#endif diff --git a/version2/src/RPi/DeviceStateVersion.h b/version2/src/RPi/DeviceStateVersion.h deleted file mode 100644 index 2e40d03..0000000 --- a/version2/src/RPi/DeviceStateVersion.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _DEVICESTATEVERSION_H__ -#define _DEVICESTATEVERSION_H__ -#include - -class DeviceStateVersion { - private: - int64_t vender; - int64_t product; - int64_t version; - - public: - - DeviceStateVersion(int64_t _vender, int64_t _product, int64_t _version) { - - vender = _vender; - product = _product; - version = _version; - } - - - ~DeviceStateVersion() { - } - - - int64_t getVender() { - return vender; - } - - - int64_t getProduct() { - return product; - } - - - int64_t getVersion() { - return version; - } -}; -#endif diff --git a/version2/src/RPi/DeviceStateWifiFirmware.h b/version2/src/RPi/DeviceStateWifiFirmware.h deleted file mode 100644 index 28c1d26..0000000 --- a/version2/src/RPi/DeviceStateWifiFirmware.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef _DEVICESTATEWIFIFIRMWARE_H__ -#define _DEVICESTATEWIFIFIRMWARE_H__ -#include - -class DeviceStateWifiFirmware { - // time of build in nanosecond accuracy - // after some tests - private: - int64_t build; - int64_t version; // firmware version - - public: - - DeviceStateWifiFirmware(int64_t _build, int64_t _version) { - - build = _build; - version = _version; - } - - - ~DeviceStateWifiFirmware() { - } - - - int64_t getBuild() { - return build; - } - - - int64_t getVersion() { - return version; - } -}; -#endif diff --git a/version2/src/RPi/DeviceStateWifiInfo.h b/version2/src/RPi/DeviceStateWifiInfo.h deleted file mode 100644 index 7bbc83b..0000000 --- a/version2/src/RPi/DeviceStateWifiInfo.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _DEVICESTATEWIFIINFO_H__ -#define _DEVICESTATEWIFIINFO_H__ -#include - -class DeviceStateWifiInfo { - private: - int64_t signal; - int64_t tx; - int64_t rx; - - public: - - DeviceStateWifiInfo(int64_t _signal, int64_t _tx, int64_t _rx) { - - signal = _signal; - tx = _tx; - rx = _rx; - } - - - ~DeviceStateWifiInfo() { - } - - - int64_t getSignal() { - return signal; - } - - - int64_t getTx() { - return tx; - } - - - int64_t getRx() { - return rx; - } -}; -#endif diff --git a/version2/src/RPi/IoTAddress.h b/version2/src/RPi/IoTAddress.h deleted file mode 100644 index 360caed..0000000 --- a/version2/src/RPi/IoTAddress.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _IOTADDRESS_HPP__ -#define _IOTADDRESS_HPP__ -#include - -#include "application.h" - -using namespace std; - - -// IoTAddress class for iotruntime -// Implemented based on IoTAddress.java that is used to wrap address -// -// @author Rahmadi Trimananda -// @version 1.0 -// @since 2017-01-09 - -class IoTAddress -{ - public: - - // Constructor - IoTAddress(IPAddress _sAddress) { - - inetAddress = _sAddress; - } - - - // Constructor - IoTAddress() { - } - - - ~IoTAddress() { - } - - - IPAddress getAddress() { - - return inetAddress; - } - - // IoTAddress class properties - protected: - IPAddress inetAddress; -}; -#endif diff --git a/version2/src/RPi/IoTDeviceAddress.h b/version2/src/RPi/IoTDeviceAddress.h deleted file mode 100644 index d6f1f27..0000000 --- a/version2/src/RPi/IoTDeviceAddress.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef _IOTDEVICEADDRESS_H__ -#define _IOTDEVICEADDRESS_H__ -#include - -#include "IoTAddress.h" - -using namespace std; - -// IoTDeviceAddress class for iotruntime -// Implemented based on IoTDeviceAddress.java that is used to wrap device address -// -// @author Rahmadi Trimananda -// @version 1.0 -// @since 2017-01-09 - - -class IoTDeviceAddress final : public IoTAddress -{ - - public: - - // Constructor - IoTDeviceAddress(IPAddress _sAddress, int _iSrcPort, int _iDstPort, bool _isSrcPortWildCard, bool _isDstPortWildCard) : IoTAddress(_sAddress) { - - iSrcPort = _iSrcPort; - iDstPort = _iDstPort; - isSrcPortWildCard = _isSrcPortWildCard; - isDstPortWildCard = _isDstPortWildCard; - } - - - // Constructor - IoTDeviceAddress() { - } - - - ~IoTDeviceAddress() { - } - - - // Getter methods - int getSourcePortNumber() { - - return iSrcPort; - } - - - int getDestinationPortNumber() { - - return iDstPort; - } - - - bool getIsSrcPortWildcard() { - - return isSrcPortWildCard; - } - - - bool getIsDstPortWildcard() { - - return isDstPortWildCard; - } - - - // Setter methods - void setSrcPort(int port) { - - if (isDstPortWildCard) { - iDstPort = port; - } - } - - - void setDstPort(int port) { - - if (isSrcPortWildCard) { - iSrcPort = port; - } - } - - - // IoTDeviceAddress class properties - private: - int iSrcPort; - int iDstPort; - - bool isSrcPortWildCard; - bool isDstPortWildCard; -}; -#endif diff --git a/version2/src/RPi/IoTSet.h b/version2/src/RPi/IoTSet.h deleted file mode 100644 index 0104809..0000000 --- a/version2/src/RPi/IoTSet.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef _IOTSET_H__ -#define _IOTSET_H__ -#include -#include -#include - -using namespace std; - -/** This is the IoTSet implementation for C++ - * - * @author Rahmadi Trimananda - * @version 1.0 - * @since 2016-09-06 - */ -template -class IoTSet final { - private: - const unordered_set* set; - public: - IoTSet(); - IoTSet(const unordered_set* s); - ~IoTSet(); - public: - typename unordered_set::const_iterator find(const T& k); // Find the object - bool empty(); // Test is empty? - typename unordered_set::const_iterator begin(); // Iterator - typename unordered_set::const_iterator end(); // Iterator - int size(); // Set size - unordered_set* values(); // Return set contents -}; - - -/** - * Default constructor - */ -template -IoTSet::IoTSet() { - -} - - -/** - * Useful constructor - */ -template -IoTSet::IoTSet(const unordered_set* s) { - - set = s; -} - - -/** - * Default destructor - */ -template -IoTSet::~IoTSet() { - -} - - -/** - * Find the object k in the set - */ -template -typename unordered_set::const_iterator IoTSet::find(const T& k) { - - return (new unordered_set(*set))->find(k); -} - - -/** - * Return the "begin" iterator - */ -template -typename unordered_set::const_iterator IoTSet::begin() { - - return (new unordered_set(*set))->begin(); -} - - -/** - * Return the "end" iterator - */ -template -typename unordered_set::const_iterator IoTSet::end() { - - return (new unordered_set(*set))->end(); -} - - -/** - * Return the size of the set - */ -template -int IoTSet::size() { - - return set->size(); -} - - -/** - * Return a new copy of the set - */ -template -unordered_set* IoTSet::values() { - - return new unordered_set(*set); -} -#endif - diff --git a/version2/src/RPi/IoTUDP.h b/version2/src/RPi/IoTUDP.h deleted file mode 100644 index f538553..0000000 --- a/version2/src/RPi/IoTUDP.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef _IOTUDP_H__ -#define _IOTUDP_H__ -#include - -#include "IoTDeviceAddress.h" - -using namespace std; - -// IoTUDP class for iotruntime -// Implemented based on IoTUDP.java that is used to wrap communication socket for UDP -// -// @author Rahmadi Trimananda -// @version 1.0 -// @since 2017-01-09 - -class IoTUDP final -{ - // IoTUDP class properties - private: - //UDPSocket *socket; - UDP socket; - IPAddress strHostAddress; - int iSrcPort; - int iDstPort; - bool didClose; - int timeOut; - - public: - - // Constructor - IoTUDP(IoTDeviceAddress* iotDevAdd) { - - strHostAddress = iotDevAdd->getAddress(); - iSrcPort = iotDevAdd->getSourcePortNumber(); - iDstPort = iotDevAdd->getDestinationPortNumber(); - timeOut = 0; - - socket.begin(iSrcPort); - didClose = false; - } - - - ~IoTUDP() { - } - - - IPAddress getHostAddress() { - return strHostAddress; - } - - - int getSourcePort() { - return iSrcPort; - } - - - int getDestinationPort() { - return iDstPort; - } - - - void setTimeOut(int interval) { - - timeOut = interval; - } - - - // Send data packet - void sendData(const char* buffer, int bufferLen) { - - unsigned short destinationPort = (unsigned short) iDstPort; - IPAddress ipFromBytes(strHostAddress); - socket.sendPacket(buffer, bufferLen, strHostAddress, destinationPort); - } - - - // Receive data packet - int receiveData(char* buffer, int iMaxDataLength) { - - return socket.receivePacket(buffer, iMaxDataLength); - } -}; -#endif diff --git a/version2/src/RPi/LifxHeader.h b/version2/src/RPi/LifxHeader.h deleted file mode 100644 index 6d4fbe5..0000000 --- a/version2/src/RPi/LifxHeader.h +++ /dev/null @@ -1,287 +0,0 @@ -#ifndef _LIFXHEADER_H__ -#define _LIFXHEADER_H__ -#include - -class LifxHeader { - - private: - // Frame variables - int size; - int origin; - bool tagged; - bool addressable; - int protocol; - int64_t source; - - // Frame address variables - char macAddress[8]; - bool ack_required; - bool res_required; - int sequence; - - // Protocol header - int type; - - public: - - LifxHeader() { - origin = 0; - addressable = true; - protocol =1024; - } - - - ~LifxHeader() { - } - - - void setSize(int _size) { - if (_size < 0) { - cerr << "Header: size cannot be less than 0" << endl; - exit(1); - } else if (_size > 65535) { - cerr << "Header: size too large" << endl; - exit(1); - } - size = _size; - } - - - void setOrigin(int _origin) { - if (_origin < 0) { - cerr << "Header: origin cannot be less than 0" << endl; - exit(1); - } else if (_origin > 3) { - cerr << "Header: origin too large" << endl; - exit(1); - } - origin = _origin; - } - - - void setTagged(bool _tagged) { - tagged = _tagged; - } - - - void setAddressable(bool _addressable) { - addressable = _addressable; - } - - - void setProtocol(int _protocol) { - if (_protocol < 0) { - cerr << "Header: protocol cannot be less than 0" << endl; - exit(1); - } else if (_protocol > 4095) { - cerr << "Header: protocol too large" << endl; - exit(1); - } - protocol = _protocol; - } - - - void setSource(int64_t _source) { - if (_source < 0) { - cerr << "Header: source cannot be less than 0" << endl; - exit(1); - } else if (_source > 4294967295) { - cerr << "Header: source too large" << endl; - exit(1); - } - source = _source; - } - - - void setSequence(int _sequence) { - if (_sequence < 0) { - cerr << "Header: sequence cannot be less than 0" << endl; - exit(1); - } else if (_sequence > 255) { - cerr << "Header: sequence too large" << endl; - exit(1); - } - sequence = _sequence; - } - - - void setType(int _type) { - if (_type < 0) { - cerr << "Header: type cannot be less than 0" << endl; - exit(1); - } else if (_type > 65535) { - cerr << "Header: type too large" << endl; - exit(1); - } - type = _type; - } - - - void setAck_required(bool _ack_required) { - ack_required = _ack_required; - } - - - void setRes_required(bool _res_required) { - res_required = _res_required; - } - - - void setMacAddress(char _macAddress[8]) { - strcpy(macAddress, _macAddress); - } - - - int getSize() { - return size; - } - - - int getOrigin() { - return origin; - } - - - bool getTagged() { - return tagged; - } - - - bool getAddressable() { - return addressable; - } - - - int getProtocol() { - return protocol; - } - - - int64_t getSource() { - return source; - } - - - int64_t getSequence() { - return sequence; - } - - - int getType() { - return type; - } - - - char* getHeaderBytes(char headerBytes[36]) { - - //char headerBytes[36]; - headerBytes[0] = (char)(size & 0xFF); - headerBytes[1] = (char)((size >> 8) & 0xFF); - - - headerBytes[2] = (char)(protocol & 0xFF); - headerBytes[3] = (char)((protocol >> 8) & 0x0F); - - headerBytes[3] |= (char)((origin & 0x03) << 6); - - if (tagged) { - headerBytes[3] |= (1 << 5); - } - - if (addressable) { - headerBytes[3] |= (1 << 4); - } - - headerBytes[4] = (char)((source >> 0) & 0xFF); - headerBytes[5] = (char)((source >> 8) & 0xFF); - headerBytes[6] = (char)((source >> 16) & 0xFF); - headerBytes[7] = (char)((source >> 24) & 0xFF); - - // fix in a bit - headerBytes[8] = macAddress[0]; - headerBytes[9] = macAddress[1]; - headerBytes[10] = macAddress[2]; - headerBytes[11] = macAddress[3]; - headerBytes[12] = macAddress[4]; - headerBytes[13] = macAddress[5]; - headerBytes[14] = macAddress[6]; - headerBytes[15] = macAddress[7]; - - // Reserved and set to 0 - headerBytes[16] = 0; - headerBytes[17] = 0; - headerBytes[18] = 0; - headerBytes[19] = 0; - headerBytes[20] = 0; - headerBytes[21] = 0; - - if (ack_required) { - headerBytes[22] = (1 << 1); - } - - if (res_required) { - headerBytes[22] |= (1); - } - - headerBytes[23] = (char)(sequence & 0xFF); - - // Reserved and set to 0 - headerBytes[24] = 0; - headerBytes[25] = 0; - headerBytes[26] = 0; - headerBytes[27] = 0; - headerBytes[28] = 0; - headerBytes[29] = 0; - headerBytes[30] = 0; - headerBytes[31] = 0; - - headerBytes[32] = (char)((type >> 0) & 0xFF); - headerBytes[33] = (char)((type >> 8) & 0xFF); - - // Reserved and set to 0 - headerBytes[34] = 0; - headerBytes[35] = 0; - - return headerBytes; - } - - - void setFromBytes(char dataBytes[36]) { - - size = dataBytes[0] & 0xFF; - size |= ((dataBytes[1] & 0xFF) << 8); - size &= 0xFFFF; - - origin = (dataBytes[3] >> 6) & 0x03; - tagged = ((dataBytes[3] >> 5) & 0x01) == 1; - addressable = ((dataBytes[3] >> 4) & 0x01) == 1; - - - protocol = (dataBytes[3] & 0x0F) << 8; - protocol |= dataBytes[2]; - protocol &= 0x0FFF; - - source = (dataBytes[7] & 0xFFl) << 24; - source |= ((dataBytes[6] & 0xFFl) << 16); - source |= ((dataBytes[5] & 0xFFl) << 8); - source |= ((dataBytes[4] & 0xFFl)); - - macAddress[0] = dataBytes[8]; - macAddress[1] = dataBytes[9]; - macAddress[2] = dataBytes[10]; - macAddress[3] = dataBytes[11]; - macAddress[4] = dataBytes[12]; - macAddress[5] = dataBytes[13]; - macAddress[6] = dataBytes[14]; - macAddress[7] = dataBytes[15]; - - ack_required = (dataBytes[22] & 0x02) == 0x02; - res_required = (dataBytes[22] & 0x01) == 0x01; - - sequence = (dataBytes[23] & 0xFF); - - type = ((dataBytes[33] & 0xFF) << 8); - type |= (dataBytes[32] & 0xFF); - } -}; -#endif diff --git a/version2/src/RPi/LifxLightBulb.cpp b/version2/src/RPi/LifxLightBulb.cpp deleted file mode 100644 index 247fb22..0000000 --- a/version2/src/RPi/LifxLightBulb.cpp +++ /dev/null @@ -1,1103 +0,0 @@ -#include -#include -#include - -#include - -#include "LifxLightBulb.h" -#include "IoTSet.h" -#include "IoTDeviceAddress.h" -#include "application.h" - -using namespace std; - - -// Default constructor -LifxLightBulb::LifxLightBulb() { - -} - - -// Constructor -LifxLightBulb::LifxLightBulb(IPAddress ipAddress, char* macAddress, int srcPort) { - - memcpy(bulbMacAddress, macAddress, 8); - - // Initialize device address - // Port 56700 is the default port for Lifx - IoTDeviceAddress* devAddress = new IoTDeviceAddress(ipAddress, srcPort, 56700, false, false); - unordered_set* myset1 = new unordered_set(); - myset1->insert(devAddress); - IoTSet* setDevAddress = new IoTSet(myset1); - lb_addresses = setDevAddress; -} - - -LifxLightBulb::~LifxLightBulb() { - - // Clean up - if (communicationSocket != NULL) { - - delete communicationSocket; - communicationSocket = NULL; - } - for(void* dev : *lb_addresses) { - IoTDeviceAddress* dv = (IoTDeviceAddress*) dev; - delete dv; - dv = NULL; - } - if (lb_addresses != NULL) { - - delete lb_addresses; - lb_addresses = NULL; - } -} - - -// PUBLIC METHODS -// Initialize the lightbulb -void LifxLightBulb::init() { - - if (didAlreadyInit) - return; - // Set to true if not yet - didAlreadyInit = true; - - unordered_set::const_iterator itr = lb_addresses->begin(); - IoTDeviceAddress* deviceAddress = (IoTDeviceAddress*) *itr; - - // Create IoTUDP socket - communicationSocket = new IoTUDP(deviceAddress); - - //cout << "Host address: " << communicationSocket->getHostAddress() << endl; - //cout << "Source port: " << communicationSocket->getSourcePort() << endl; - //cout << "Destination port: " << communicationSocket->getDestinationPort() << endl << endl; - - // Launch the worker function in a separate thread. - // NOTE: "this" pointer is passed into the detached thread because it does not belong - // to this object anymore so if it executes certain methods of "this" object, then it needs - // the correct references to stuff - thread th1 (&LifxLightBulb::workerFunction, this, this); - th1.detach(); -} - - -void LifxLightBulb::turnOff() { - - //lock_guard guard(bulbStateMutex); - bulbStateMutex.lock(); - bulbIsOn = false; - sendSetLightPowerPacket(0, 0); - stateDidChange = true; - bulbStateMutex.unlock(); -} - - -void LifxLightBulb::turnOn() { - - //lock_guard guard(bulbStateMutex); - bulbStateMutex.lock(); - bulbIsOn = true; - sendSetLightPowerPacket(65535, 0); - stateDidChange = true; - bulbStateMutex.unlock(); -} - - -double LifxLightBulb::getHue() { - double tmp = 0; - settingBulbColorMutex.lock(); - tmp = ((double)currentHue / 65535.0) * 360.0; - settingBulbColorMutex.unlock(); - - return tmp; -} - - -double LifxLightBulb::getSaturation() { - double tmp = 0; - settingBulbColorMutex.lock(); - tmp = ((double)currentSaturation / 65535.0) * 360.0; - settingBulbColorMutex.unlock(); - - return tmp; -} - - -double LifxLightBulb::getBrightness() { - double tmp = 0; - settingBulbColorMutex.lock(); - tmp = ((double)currentBrightness / 65535.0) * 360.0; - settingBulbColorMutex.unlock(); - - return tmp; -} - - -int LifxLightBulb::getTemperature() { - - int tmp = 0; - settingBulbTemperatureMutex.lock(); - tmp = currentTemperature; - settingBulbTemperatureMutex.unlock(); - - return tmp; -} - - -double LifxLightBulb::getHueRangeLowerBound() { - if (!didGetBulbVersion) { - return -1; - } - return ((double)hueLowerBound / 65535.0) * 360.0; -} - - -double LifxLightBulb::getHueRangeUpperBound() { - if (!didGetBulbVersion) { - return -1; - } - return ((double)hueUpperBound / 65535.0) * 360.0; -} - - -double LifxLightBulb::getSaturationRangeLowerBound() { - if (!didGetBulbVersion) { - return -1; - } - return ((double)saturationLowerBound / 65535.0) * 100.0; -} - - -double LifxLightBulb::getSaturationRangeUpperBound() { - if (!didGetBulbVersion) { - return -1; - } - return ((double)saturationUpperBound / 65535.0) * 100.0; -} - - -double LifxLightBulb::getBrightnessRangeLowerBound() { - if (!didGetBulbVersion) { - return -1; - } - return ((double)brightnessLowerBound / 65535.0) * 100.0; -} - - -double LifxLightBulb::getBrightnessRangeUpperBound() { - if (!didGetBulbVersion) { - return -1; - } - return ((double)brightnessUpperBound / 65535.0) * 100.0; -} - - -int LifxLightBulb::getTemperatureRangeLowerBound() { - if (!didGetBulbVersion) { - return -1; - } - return temperatureLowerBound; -} - - -int LifxLightBulb::getTemperatureRangeUpperBound() { - if (!didGetBulbVersion) { - return -1; - } - return temperatureUpperBound; -} - - -void LifxLightBulb::setTemperature(int _temperature) { - - settingBulbTemperatureMutex.lock(); - - BulbColor* newColor = new BulbColor(currentHue, currentSaturation, currentBrightness, _temperature); - sendSetLightColorPacket(newColor, 250); - - currentTemperature = _temperature; - stateDidChange = true; - - settingBulbTemperatureMutex.unlock(); -} - - -void LifxLightBulb::setColor(double _hue, double _saturation, double _brightness) { - - settingBulbColorMutex.lock(); - - _hue /= 360.0; - _saturation /= 100.0; - _brightness /= 100.0; - - - int newHue = (int)(_hue * 65535.0); - int newSaturation = (int)(_saturation * 65535.0); - int newBrightness = (int)(_brightness * 65535.0); - - BulbColor* newColor = new BulbColor(newHue, newSaturation, newBrightness, currentTemperature); - sendSetLightColorPacket(newColor, 250); - - currentHue = newHue; - currentSaturation = newSaturation; - currentBrightness = newBrightness; - stateDidChange = true; - - settingBulbColorMutex.unlock(); -} - - -bool LifxLightBulb::getState() { - - bool tmp = false; - - bulbStateMutex.lock(); - tmp = bulbIsOn; - bulbStateMutex.unlock(); - - return tmp; -} - - -// PRIVATE METHODS -// Communication helpers -void LifxLightBulb::receivedPacket(char* packetData) { - - char headerBytes[36]; - for (int i = 0; i < 36; i++) { - headerBytes[i] = packetData[i]; - } - - LifxHeader recHeader; - recHeader.setFromBytes(headerBytes); - - // load the payload bytes (strip away the header) - char* payloadBytes = new char[recHeader.getSize()]; - for (int i = 36; i < recHeader.getSize(); i++) { - payloadBytes[i - 36] = packetData[i]; - } - - int type = recHeader.getType(); - //cout << "Received: " << type << endl; - - DeviceStateService* dat = NULL; - switch (type) { - - case 3: - dat = parseDeviceStateServiceMessage(payloadBytes); - //cout << "Service: " << dat->getService(); - //cout << "Port : " << dat->getPort(); - // Avoid memory leak - delete this object - delete dat; - break; - - case 33: - handleStateVersionMessageReceived(payloadBytes); - break; - - case 35: - parseDeviceStateInfoMessage(payloadBytes); - break; - - - case 107: - handleLightStateMessageReceived(payloadBytes); - break; - - default: - break; - //cout << "unknown packet Type" << endl; - } - // Avoid memory leaks - delete payloadBytes; -} - - -void LifxLightBulb::sendPacket(char* packetData, int len) { - //cout << "sendPacket: About to send" << endl; - lock_guard guard(socketMutex); - sendSocketFlag = true; - communicationSocket->sendData(packetData, len); - sendSocketFlag = false; -} - - -// Worker function which runs the while loop for receiving data from the bulb. -// Is blocking. -void LifxLightBulb::workerFunction(LifxLightBulb* llb) { - - // Need timeout on receives since we are not sure if a packet will be available - // for processing so don't block waiting - llb->communicationSocket->setTimeOut(50000); // In milliseconds - llb->turnOff(); - - int64_t lastSentGetBulbVersionRequest = 0; // time last request sent - char dat[1024]; - - while (true) { - // Check if we got the bulb version yet - // could have requested it but message could have gotten lost (UDP) - if (!llb->didGetBulbVersion) { - int64_t currentTime = (int64_t) time(NULL); - if ((currentTime - lastSentGetBulbVersionRequest) > llb->GET_BULB_VERSION_RESEND_WAIT_SECONDS) { - // Get the bulb version so we know what type of bulb this is. - //cout << "Sending version packet! " << endl; - llb->sendGetVersionPacket(); - lastSentGetBulbVersionRequest = currentTime; - } - } - - // Communication resource is busy so try again later - if (llb->sendSocketFlag) { - continue; - } - - llb->socketMutex.lock(); - int ret = llb->communicationSocket->receiveData(dat, 1024); - // Never forget to release! - llb->socketMutex.unlock(); - - // A packed arrived - if (ret != -1) { - llb->receivedPacket(dat); - } - - // If a state change occurred then request the bulb state to ensure that the - // bulb did indeed change its state to the correct state - if (llb->stateDidChange) { - llb->sendGetLightStatePacket(); - } - - // Wait a bit as to not tie up system resources - //this_thread::sleep_for (chrono::milliseconds(100)); - delay(100); - //cout << endl << "Sleep and wake up!" << endl; - } -} - - -// Sending -// Device Messages -void LifxLightBulb::sendGetServicePacket() { - LifxHeader header; - header.setSize(36); - header.setTagged(true); - header.setMacAddress(bulbMacAddress); - header.setSource(0); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(2); - - char dataBytes[36]; - header.getHeaderBytes(dataBytes); - - sendPacket(dataBytes, 36); -} - - -void LifxLightBulb::sendGetHostInfoPacket() { - LifxHeader header; - header.setSize(36); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(12); - - char dataBytes[36]; - header.getHeaderBytes(dataBytes); - - sendPacket(dataBytes, 36); -} - - -void LifxLightBulb::sendGetHostFirmwarePacket() { - LifxHeader header; - header.setSize(36); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(14); - - char dataBytes[36]; - header.getHeaderBytes(dataBytes); - - sendPacket(dataBytes, 36); -} - - -void LifxLightBulb::sendGetWifiInfoPacket() { - LifxHeader header; - header.setSize(36); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(16); - - char dataBytes[36]; - header.getHeaderBytes(dataBytes); - - sendPacket(dataBytes, 36); -} - - -void LifxLightBulb::sendGetWifiFirmwarePacket() { - LifxHeader header; - header.setSize(36); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(18); - - char dataBytes[36]; - header.getHeaderBytes(dataBytes); - - sendPacket(dataBytes, 36); -} - - -void LifxLightBulb::sendGetPowerPacket() { - LifxHeader header; - header.setSize(36); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(20); - - char dataBytes[36]; - header.getHeaderBytes(dataBytes); - - sendPacket(dataBytes, 36); -} - - -void LifxLightBulb::sendSetPowerPacket(int level) { - // Currently only 0 and 65535 are supported - // This is a fix for now - if ((level != 65535) && (level != 0)) { - cerr << "Invalid parameter values" << endl; - exit(1); - } - - if ((level > 65535) || (level < 0)) { - cerr << "Invalid parameter values" << endl; - exit(1); - } - - char packetBytes[38]; - - LifxHeader header; - header.setSize(38); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(21); - char headerBytes[36]; - header.getHeaderBytes(headerBytes); - - for (int i = 0; i < 36; i++) { - packetBytes[i] = headerBytes[i]; - } - - packetBytes[36] = (char)(level & 0xFF); - packetBytes[37] = (char)((level >> 8) & 0xFF); - - sendPacket(packetBytes, 38); -} - - -void LifxLightBulb::sendGetLabelPacket() { - LifxHeader header; - header.setSize(36); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(23); - - char dataBytes[36]; - header.getHeaderBytes(dataBytes); - - sendPacket(dataBytes, 36); -} - - -void LifxLightBulb::sendSetLabelPacket(string label) { - // Currently only 0 and 65535 are supported - // This is a fix for now - if (label.length() != 32) { - cerr << "Invalid parameter values, label must be 32 bytes long" << endl; - exit(1); - } - - char packetBytes[68]; - - LifxHeader header; - header.setSize(68); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(24); - char headerBytes[36]; - header.getHeaderBytes(headerBytes); - - for (int i = 0; i < 36; i++) { - packetBytes[i] = headerBytes[i]; - } - - for (int i = 0; i < 32; i++) { - packetBytes[i + 36] = label.c_str()[i]; - } - - sendPacket(packetBytes, 68); -} - - -void LifxLightBulb::sendGetVersionPacket() { - LifxHeader header; - header.setSize(36); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(32); - - char dataBytes[36]; - header.getHeaderBytes(dataBytes); - - sendPacket(dataBytes, 36); -} - - -void LifxLightBulb::sendGetInfoPacket() { - LifxHeader header; - header.setSize(36); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(34); - - char dataBytes[36]; - header.getHeaderBytes(dataBytes); - - sendPacket(dataBytes, 36); -} - - -void LifxLightBulb::sendGetLocationPacket() { - LifxHeader header; - header.setSize(36); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(34); - - char dataBytes[36]; - header.getHeaderBytes(dataBytes); - - sendPacket(dataBytes, 36); -} - - -void LifxLightBulb::sendGetGroupPacket() { - LifxHeader header; - header.setSize(36); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(51); - - char dataBytes[36]; - header.getHeaderBytes(dataBytes); - - sendPacket(dataBytes, 36); -} - - -// Sending -// Light Messages -void LifxLightBulb::sendGetLightStatePacket() { - LifxHeader header; - header.setSize(36); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(101); - - char dataBytes[36]; - header.getHeaderBytes(dataBytes); - - sendPacket(dataBytes, 36); -} - - -void LifxLightBulb::sendSetLightColorPacket(BulbColor* bulbColor, long duration) { - - if ((duration > 4294967295l) || (duration < 0)) { - cerr << "Invalid parameter value, duration out of range (0 - 4294967295)" << endl; - exit(1); - } - - char packetBytes[49]; - - LifxHeader header; - header.setSize(49); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(102); - char headerBytes[36]; - header.getHeaderBytes(headerBytes); - - for (int i = 0; i < 36; i++) { - packetBytes[i] = headerBytes[i]; - } - - // 1 reserved packet - packetBytes[37] = (char)(bulbColor->getHue() & 0xFF); - packetBytes[38] = (char)((bulbColor->getHue() >> 8) & 0xFF); - - packetBytes[39] = (char)(bulbColor->getSaturation() & 0xFF); - packetBytes[40] = (char)((bulbColor->getSaturation() >> 8) & 0xFF); - - packetBytes[41] = (char)(bulbColor->getBrightness() & 0xFF); - packetBytes[42] = (char)((bulbColor->getBrightness() >> 8) & 0xFF); - - packetBytes[43] = (char)(bulbColor->getKelvin() & 0xFF); - packetBytes[44] = (char)((bulbColor->getKelvin() >> 8) & 0xFF); - - packetBytes[45] = (char)((duration >> 0) & 0xFF); - packetBytes[46] = (char)((duration >> 8) & 0xFF); - packetBytes[47] = (char)((duration >> 16) & 0xFF); - packetBytes[48] = (char)((duration >> 24) & 0xFF); - - sendPacket(packetBytes, 49); - // Avoid memory leak - delete object - delete bulbColor; -} - - -void LifxLightBulb::sendGetLightPowerPacket() { - LifxHeader header; - header.setSize(36); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(116); - - char dataBytes[36]; - header.getHeaderBytes(dataBytes); - - sendPacket(dataBytes, 36); -} - - -void LifxLightBulb::sendSetLightPowerPacket(int level, long duration) { - - if ((level > 65535) || (duration > 4294967295l) - || (level < 0) || (duration < 0)) { - cerr << "Invalid parameter values" << endl; - exit(1); - } - char packetBytes[42]; - - LifxHeader header; - header.setSize(42); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(117); - char headerBytes[36]; - header.getHeaderBytes(headerBytes); - - for (int i = 0; i < 36; i++) { - packetBytes[i] = headerBytes[i]; - } - - packetBytes[36] = (char)(level & 0xFF); - packetBytes[37] = (char)((level >> 8) & 0xFF); - - packetBytes[38] = (char)((duration >> 0) & 0xFF); - packetBytes[39] = (char)((duration >> 8) & 0xFF); - packetBytes[40] = (char)((duration >> 16) & 0xFF); - packetBytes[41] = (char)((duration >> 24) & 0xFF); - - sendPacket(packetBytes, 42); -} - - -void LifxLightBulb::sendEchoRequestPacket(char data[64]) { - - char packetBytes[100]; - - LifxHeader header; - header.setSize(100); - header.setTagged(false); - header.setMacAddress(bulbMacAddress); - header.setSource(10); // randomly picked - header.setAck_required(false); - header.setRes_required(false); - header.setSequence(0); - header.setType(58); - char headerBytes[36]; - header.getHeaderBytes(headerBytes); - - for (int i = 0; i < 36; i++) { - packetBytes[i] = headerBytes[i]; - } - - for (int i = 0; i < 64; i++) { - packetBytes[i + 36] = data[i]; - } - - sendPacket(packetBytes, 100); -} - - -// Receiving -// Device Messages -DeviceStateService* LifxLightBulb::parseDeviceStateServiceMessage(char* payloadData) { - int service = payloadData[0]; - int64_t port = ((payloadData[3] & 0xFF) << 24); - port |= ((payloadData[2] & 0xFF) << 16); - port |= ((payloadData[1] & 0xFF) << 8); - port |= (payloadData[0] & 0xFF); - - return new DeviceStateService(service, port); -} - - -DeviceStateHostInfo* LifxLightBulb::parseDeviceStateHostInfoMessage(char* payloadData) { - long signal = ((payloadData[3] & 0xFF) << 24); - signal |= ((payloadData[2] & 0xFF) << 16); - signal |= ((payloadData[1] & 0xFF) << 8); - signal |= (payloadData[0] & 0xFF); - - long tx = ((payloadData[7] & 0xFF) << 24); - tx |= ((payloadData[6] & 0xFF) << 16); - tx |= ((payloadData[5] & 0xFF) << 8); - tx |= (payloadData[4] & 0xFF); - - long rx = ((payloadData[11] & 0xFF) << 24); - rx |= ((payloadData[10] & 0xFF) << 16); - rx |= ((payloadData[9] & 0xFF) << 8); - rx |= (payloadData[8] & 0xFF); - - return new DeviceStateHostInfo(signal, tx, rx); -} - - -DeviceStateHostFirmware* LifxLightBulb::parseDeviceStateHostFirmwareMessage(char* payloadData) { - long build = 0; - for (int i = 0; i < 8; i++) { - build += ((int64_t) payloadData[i] & 0xffL) << (8 * i); - } - - // 8 reserved bytes - - int64_t version = ((payloadData[19] & 0xFF) << 24); - version |= ((payloadData[18] & 0xFF) << 16); - version |= ((payloadData[17] & 0xFF) << 8); - version |= (payloadData[16] & 0xFF); - - return new DeviceStateHostFirmware(build, version); -} - - -DeviceStateWifiInfo* LifxLightBulb::parseDeviceStateWifiInfoMessage(char* payloadData) { - int64_t signal = ((payloadData[3] & 0xFF) << 24); - signal |= ((payloadData[2] & 0xFF) << 16); - signal |= ((payloadData[1] & 0xFF) << 8); - signal |= (payloadData[0] & 0xFF); - - int64_t tx = ((payloadData[7] & 0xFF) << 24); - tx |= ((payloadData[6] & 0xFF) << 16); - tx |= ((payloadData[5] & 0xFF) << 8); - tx |= (payloadData[4] & 0xFF); - - int64_t rx = ((payloadData[11] & 0xFF) << 24); - rx |= ((payloadData[10] & 0xFF) << 16); - rx |= ((payloadData[9] & 0xFF) << 8); - rx |= (payloadData[8] & 0xFF); - - return new DeviceStateWifiInfo(signal, tx, rx); -} - - -DeviceStateWifiFirmware* LifxLightBulb::parseDeviceStateWifiFirmwareMessage(char* payloadData) { - long build = 0; - for (int i = 0; i < 8; i++) { - build += ((int64_t) payloadData[i] & 0xffL) << (8 * i); - } - - // 8 reserved bytes - - int64_t version = ((payloadData[19] & 0xFF) << 24); - version |= ((payloadData[18] & 0xFF) << 16); - version |= ((payloadData[17] & 0xFF) << 8); - version |= (payloadData[16] & 0xFF); - - return new DeviceStateWifiFirmware(build, version); -} - - -int LifxLightBulb::parseStatePowerMessage(char* payloadData) { - int level = ((payloadData[1] & 0xFF) << 8); - level |= (payloadData[0] & 0xFF); - return level; -} - - -DeviceStateVersion* LifxLightBulb::parseDeviceStateVersionMessage(char* payloadData) { - int64_t vender = ((payloadData[3] & 0xFF) << 24); - vender |= ((payloadData[2] & 0xFF) << 16); - vender |= ((payloadData[1] & 0xFF) << 8); - vender |= (payloadData[0] & 0xFF); - - int64_t product = ((payloadData[7] & 0xFF) << 24); - product |= ((payloadData[6] & 0xFF) << 16); - product |= ((payloadData[5] & 0xFF) << 8); - product |= (payloadData[4] & 0xFF); - - int64_t version = ((payloadData[11] & 0xFF) << 24); - version |= ((payloadData[10] & 0xFF) << 16); - version |= ((payloadData[9] & 0xFF) << 8); - version |= (payloadData[8] & 0xFF); - - return new DeviceStateVersion(vender, product, version); -} - - -DeviceStateInfo* LifxLightBulb::parseDeviceStateInfoMessage(char* payloadData) { - int64_t time = 0; - int64_t upTime = 0; - int64_t downTime = 0; - for (int i = 0; i < 8; i++) { - time += ((int64_t) payloadData[i] & 0xffL) << (8 * i); - upTime += ((int64_t) payloadData[i + 8] & 0xffL) << (8 * i); - downTime += ((int64_t) payloadData[i + 16] & 0xffL) << (8 * i); - } - - return new DeviceStateInfo(time, upTime, downTime); -} - - -DeviceStateLocation* LifxLightBulb::parseDeviceStateLocationMessage(char* payloadData) { - char location[16]; - for (int i = 0; i < 16; i++) { - location[i] = payloadData[i]; - } - - char labelBytes[32]; - for (int i = 0; i < 32; i++) { - labelBytes[i] = payloadData[i + 16]; - } - - int64_t updatedAt = 0; - for (int i = 0; i < 8; i++) { - updatedAt += ((int64_t) payloadData[48] & 0xffL) << (8 * i); - } - - string str(labelBytes); - return new DeviceStateLocation(location, str, updatedAt); -} - - -DeviceStateGroup* LifxLightBulb::parseDeviceStateGroupMessage(char* payloadData) { - char group[16]; - for (int i = 0; i < 16; i++) { - group[i] = payloadData[i]; - } - - char labelBytes[32]; - for (int i = 0; i < 32; i++) { - labelBytes[i] = payloadData[i + 16]; - } - - int64_t updatedAt = 0; - for (int i = 0; i < 8; i++) { - updatedAt += ((int64_t) payloadData[48] & 0xffL) << (8 * i); - } - - string str(labelBytes); - return new DeviceStateGroup(group, str, updatedAt); -} - - -// Receiving -// Light Messages -LightState* LifxLightBulb::parseLightStateMessage(char* payloadData) { - - char colorData[8]; - for (int i = 0; i < 8; i++) { - colorData[i] = payloadData[i]; - } - //BulbColor color(colorData); - BulbColor* color = new BulbColor(colorData); - - int power = ((payloadData[11] & 0xFF) << 8); - power |= (payloadData[10] & 0xFF); - - string label(payloadData); - - char labelArray[32]; - for (int i = 0; i < 32; i++) { - labelArray[i] = payloadData[12 + i]; - } - - return new LightState(color, power, label); -} - - -int LifxLightBulb::parseLightStatePowerMessage(char* payloadData) { - int level = ((payloadData[1] & 0xFF) << 8); - level |= (payloadData[0] & 0xFF); - return level; -} - - -// Private Handlers -void LifxLightBulb::handleStateVersionMessageReceived(char* payloadData) { - - DeviceStateVersion* deviceState = parseDeviceStateVersionMessage(payloadData); - int productNumber = (int)deviceState->getProduct(); - - bool isColor = false; - - if (productNumber == 1) {// Original 1000 - isColor = true; - } else if (productNumber == 3) {//Color 650 - isColor = true; - } else if (productNumber == 10) {// White 800 (Low Voltage) - isColor = false; - } else if (productNumber == 11) {// White 800 (High Voltage) - isColor = false; - } else if (productNumber == 18) {// White 900 BR30 (Low Voltage) - isColor = false; - } else if (productNumber == 20) {// Color 1000 BR30 - isColor = true; - } else if (productNumber == 22) {// Color 1000 - isColor = true; - } - - if (isColor) { - hueLowerBound = 0; - hueUpperBound = 65535; - saturationLowerBound = 0; - saturationUpperBound = 65535; - brightnessLowerBound = 0; - brightnessUpperBound = 65535; - temperatureLowerBound = 2500; - temperatureUpperBound = 9000; - } else { - hueLowerBound = 0; - hueUpperBound = 0; - saturationLowerBound = 0; - saturationUpperBound = 0; - brightnessLowerBound = 0; - brightnessUpperBound = 65535;// still can dim bulb - temperatureLowerBound = 2500; - temperatureUpperBound = 9000; - } - - //didGetBulbVersion.exchange(true); - didGetBulbVersion = true; - // Avoid memory leak - delete this object - delete deviceState; -} - - -void LifxLightBulb::handleLightStateMessageReceived(char* payloadData) { - LightState* lightState = parseLightStateMessage(payloadData); - - BulbColor* color = lightState->getColor(); - int power = lightState->getPower(); - - //cout << "color->getHue(): " << color->getHue() << " - currentHue: " << currentHue << endl; - //cout << "color->getSaturation(): " << color->getSaturation() << " - currentSaturation: " << currentSaturation << endl; - //cout << "color->getBrightness(): " << color->getBrightness() << " - currentBrightness: " << currentBrightness << endl; - //cout << "color->getKelvin(): " << color->getKelvin() << " - currentTemperature: " << currentTemperature << endl; - - bool bulbWrongColor = false; - bulbWrongColor = bulbWrongColor || (color->getHue() != currentHue); - bulbWrongColor = bulbWrongColor || (color->getSaturation() != currentSaturation); - bulbWrongColor = bulbWrongColor || (color->getBrightness() != currentBrightness); - bulbWrongColor = bulbWrongColor || (color->getKelvin() != currentTemperature); - - - // gets set to true if any of the below if statements are taken - stateDidChange = false; - - if (bulbWrongColor) { - BulbColor* newColor = new BulbColor(currentHue, currentSaturation, currentBrightness, currentTemperature); - sendSetLightColorPacket(newColor, 250); - //cout << "Failed Check 1" << endl; - } - - bulbStateMutex.lock(); - bool bulbIsOnTmp = bulbIsOn; - bulbStateMutex.unlock(); - - if ((!bulbIsOnTmp) && (power != 0)) { - turnOff(); - //cout << "Failed Check 2: " << endl; - - } - - if (bulbIsOnTmp && (power < 65530)) { - turnOn(); - //cout << "Failed Check 3: " << endl; - - } - // Avoid memory leak - delete object - delete lightState; - delete color; -} - diff --git a/version2/src/RPi/LifxLightBulb.h b/version2/src/RPi/LifxLightBulb.h deleted file mode 100644 index f2852b4..0000000 --- a/version2/src/RPi/LifxLightBulb.h +++ /dev/null @@ -1,163 +0,0 @@ -#ifndef _LIFXLIGHTBULB_H__ -#define _LIFXLIGHTBULB_H__ -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "LightBulb.h" -//#include "Socket.h" -#include "IoTSet.h" -#include "IoTUDP.h" -#include "IoTDeviceAddress.h" - -// Helper classes for LifxLightBulb -#include "LifxHeader.h" -#include "BulbColor.h" -#include "DeviceStateGroup.h" -#include "DeviceStateHostFirmware.h" -#include "DeviceStateHostInfo.h" -#include "DeviceStateInfo.h" -#include "DeviceStateLocation.h" -#include "DeviceStateService.h" -#include "DeviceStateVersion.h" -#include "DeviceStateWifiFirmware.h" -#include "DeviceStateWifiInfo.h" -#include "LightState.h" - - -using namespace std; - -// Driver LifxLightBulb -// Implemented based on LightBulb virtual class (interface) - -class LifxLightBulb : public LightBulb -{ - private: - // Constants - const static int64_t GET_BULB_VERSION_RESEND_WAIT_SECONDS = 10; - - // Variables - IoTUDP *communicationSocket; - char bulbMacAddress[8]; - //TODO: - bool sendSocketFlag = false; - - // Current Bulb Values - int currentHue = 0; - int currentSaturation = 0; - int currentBrightness = 65535; - int currentTemperature = 9000; - bool bulbIsOn = false; - - bool didAlreadyInit = false; - bool didGetBulbVersion = false; - - // Mutex locks - mutex socketMutex; - mutex settingBulbColorMutex; - mutex settingBulbTemperatureMutex; - mutex bulbStateMutex; - - // color and temperature ranges for the bulbs - int hueLowerBound = 0; - int hueUpperBound = 0; - int saturationLowerBound = 0; - int saturationUpperBound = 0; - int brightnessLowerBound = 0; - int brightnessUpperBound = 0; - int temperatureLowerBound = 2500; - int temperatureUpperBound = 9000; - - // Check if a state change was requested, used to poll the bulb for if the bulb did - // preform the requested state change - bool stateDidChange = false; - - // Device address - IoTSet* lb_addresses; // IoTSet* lb_addresses - - // Logging - ofstream log; - public: - - // Constructor - LifxLightBulb(); - LifxLightBulb(IPAddress ipAddress, char* macAddress, int srcPort); - ~LifxLightBulb(); - // Initialize the lightbulb - void init(); - void turnOff(); - void turnOn(); - double getHue(); - double getSaturation(); - double getBrightness(); - int getTemperature(); - double getHueRangeLowerBound(); - double getHueRangeUpperBound(); - double getSaturationRangeLowerBound(); - double getSaturationRangeUpperBound(); - double getBrightnessRangeLowerBound(); - double getBrightnessRangeUpperBound(); - int getTemperatureRangeLowerBound(); - int getTemperatureRangeUpperBound(); - void setTemperature(int _temperature); - void setColor(double _hue, double _saturation, double _brightness); - bool getState(); - - private: - // Private functions - // Communication helpers - void receivedPacket(char* packetData); - void sendPacket(char* packetData, int len); - // Worker function which runs the while loop for receiving data from the bulb. - // Is blocking. - void workerFunction(LifxLightBulb* llb); - // Sending - // Device Messages - void sendGetServicePacket(); - void sendGetHostInfoPacket(); - void sendGetHostFirmwarePacket(); - void sendGetWifiInfoPacket(); - void sendGetWifiFirmwarePacket(); - void sendGetPowerPacket(); - void sendSetPowerPacket(int level); - void sendGetLabelPacket(); - void sendSetLabelPacket(string label); - void sendGetVersionPacket(); - void sendGetInfoPacket(); - void sendGetLocationPacket(); - void sendGetGroupPacket(); - // Sending - // Light Messages - void sendGetLightStatePacket(); - void sendSetLightColorPacket(BulbColor* bulbColor, long duration); - void sendGetLightPowerPacket(); - void sendSetLightPowerPacket(int level, long duration); - void sendEchoRequestPacket(char data[64]); - // Receiving - // Device Messages - DeviceStateService* parseDeviceStateServiceMessage(char* payloadData); - DeviceStateHostInfo* parseDeviceStateHostInfoMessage(char* payloadData); - DeviceStateHostFirmware* parseDeviceStateHostFirmwareMessage(char* payloadData); - DeviceStateWifiInfo* parseDeviceStateWifiInfoMessage(char* payloadData); - DeviceStateWifiFirmware* parseDeviceStateWifiFirmwareMessage(char* payloadData); - int parseStatePowerMessage(char* payloadData); - DeviceStateVersion* parseDeviceStateVersionMessage(char* payloadData); - DeviceStateInfo* parseDeviceStateInfoMessage(char* payloadData); - DeviceStateLocation* parseDeviceStateLocationMessage(char* payloadData); - DeviceStateGroup* parseDeviceStateGroupMessage(char* payloadData); - // Receiving - // Light Messages - LightState* parseLightStateMessage(char* payloadData); - int parseLightStatePowerMessage(char* payloadData); - // Private Handlers - void handleStateVersionMessageReceived(char* payloadData); - void handleLightStateMessageReceived(char* payloadData); -}; - -#endif diff --git a/version2/src/RPi/LightBulb.h b/version2/src/RPi/LightBulb.h deleted file mode 100644 index 90f9df8..0000000 --- a/version2/src/RPi/LightBulb.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _LIGHTBULB_H__ -#define _LIGHTBULB_H__ -#include - -using namespace std; - -class LightBulb -{ - public: - virtual void init() = 0; - virtual void turnOff() = 0; - virtual void turnOn() = 0; - virtual bool getState() = 0; - virtual void setColor(double _hue, double _saturation, double _brightness) = 0; - virtual void setTemperature(int _temperature) = 0; - virtual double getBrightness() = 0; - virtual double getHue() = 0; - virtual double getSaturation() = 0; - virtual int getTemperature() = 0; - virtual double getBrightnessRangeLowerBound() = 0; - virtual double getBrightnessRangeUpperBound() = 0; - virtual double getHueRangeLowerBound() = 0; - virtual double getHueRangeUpperBound() = 0; - virtual double getSaturationRangeLowerBound() = 0; - virtual double getSaturationRangeUpperBound() = 0; - virtual int getTemperatureRangeLowerBound() = 0; - virtual int getTemperatureRangeUpperBound() = 0; -}; -#endif diff --git a/version2/src/RPi/LightState.h b/version2/src/RPi/LightState.h deleted file mode 100644 index ba350e3..0000000 --- a/version2/src/RPi/LightState.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _LIGHTSTATE_H__ -#define _LIGHTSTATE_H__ -#include - -#include "BulbColor.h" - -class LightState { - private: - BulbColor* color; - int power; - string label; - - public: - - LightState(BulbColor* _color, int _power, string _label) { - - color = _color; - power = _power; - label = _label; - } - - - ~LightState() { - } - - - BulbColor* getColor() { - return color; - } - - - int getPower() { - return power; - } - - - string getLabel() { - return label; - } -}; -#endif diff --git a/version2/src/RPi/LightsController.ino b/version2/src/RPi/LightsController.ino deleted file mode 100644 index b47d15d..0000000 --- a/version2/src/RPi/LightsController.ino +++ /dev/null @@ -1,86 +0,0 @@ -// ------------------------------------------------ -// Controlling LifxLightBulb through Particle Cloud -// @author Rahmadi Trimananda - UC Irvine -// ------------------------------------------------ - -#include "LifxLightBulb.h" - -LifxLightBulb *llb1; -LifxLightBulb *llb2; - -int led1 = D7; - -void setup() -{ - // Bulb 1 - char macAddress1[8]; - macAddress1[0] = 0xD0; - macAddress1[1] = 0x73; - macAddress1[2] = 0xD5; - macAddress1[3] = 0x12; - macAddress1[4] = 0x8E; - macAddress1[5] = 0x30; - macAddress1[6] = 0x00; - macAddress1[7] = 0x00; - IPAddress devIPAddress1(192, 168, 1, 126); - - llb1 = new LifxLightBulb(devIPAddress1, macAddress1, 12345); - llb1->init(); - - // Bulb 2 - char macAddress2[8]; - macAddress2[0] = 0xD0; - macAddress2[1] = 0x73; - macAddress2[2] = 0xD5; - macAddress2[3] = 0x02; - macAddress2[4] = 0x41; - macAddress2[5] = 0xDA; - macAddress2[6] = 0x00; - macAddress2[7] = 0x00; - IPAddress devIPAddress2(192, 168, 1, 232); - - llb2 = new LifxLightBulb(devIPAddress2, macAddress2, 12346); - llb2->init(); - - pinMode(led1, OUTPUT); - Particle.function("lifx1",lifx1Toggle); - Particle.function("lifx2",lifx2Toggle); -} - - -void loop() { - // Nothing to do here -} - - -// Toggling Lifx light bulb 1 -int lifx1Toggle(String command) { - - if (command=="on") { - llb1->turnOn(); - return 1; - } - else if (command=="off") { - llb1->turnOff(); - return 0; - } - else { - return -1; - } -} - -// Toggling Lifx light bulb 2 -int lifx2Toggle(String command) { - - if (command=="on") { - llb2->turnOn(); - return 1; - } - else if (command=="off") { - llb2->turnOff(); - return 0; - } - else { - return -1; - } -} diff --git a/version2/src/RPi/Makefile b/version2/src/RPi/Makefile deleted file mode 100644 index 948d8e1..0000000 --- a/version2/src/RPi/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -include common.mk - -all: compile - -# To run Particle, we need to install Particle CLI -# Please see: -# https://docs.particle.io/guide/getting-started/connect/photon/#install-the-particle-cli -monitor: - sudo chmod 666 /dev/ttyACM0 - particle serial monitor - -compile-c: - #g++ -c LifxLightBulb.cpp -o ./LifxLightBulb.o -Wall -O3 -g -I. -Wno-unused-variable -std=c++11 -pthread -pg - g++ ./LifxLightBulb.cpp ./socket/Socket.cpp -o ./LifxLightBulb.o -Wall -Wno-unused-variable --std=c++11 -pthread -pg -I. -I./socket - -compile: - rm -f *.bin - particle compile raspberry-pi - #particle compile photon - - -flash: - particle flash Pi-1 raspberry-pi*.bin - -PHONY += clean -clean: - rm -f *.bin - -PHONY += mrclean -mrclean: clean - rm -rf ../docs - -tabbing: - uncrustify -c C.cfg --no-backup *.cpp - uncrustify -c C.cfg --no-backup *.h - -wc: - wc *.cpp *.h - -.PHONY: $(PHONY) diff --git a/version2/src/RPi/README.txt b/version2/src/RPi/README.txt deleted file mode 100644 index b1ac1ff..0000000 --- a/version2/src/RPi/README.txt +++ /dev/null @@ -1,4 +0,0 @@ - -This is a RaspberryPi C++ implementation of Lifx light bulb controller. - -Created as a part of our testbed that will include smart home devices that will use Particle cloud. diff --git a/version2/src/RPi/common.mk b/version2/src/RPi/common.mk deleted file mode 100644 index 479a31c..0000000 --- a/version2/src/RPi/common.mk +++ /dev/null @@ -1,16 +0,0 @@ -# A few common Makefile items - -CC := gcc -CXX := g++ - -UNAME := $(shell uname) - -LIB_NAME := iotcloud -LIB_SO := lib_$(LIB_NAME).so - -CPPFLAGS += -Wall -g -O0 - -# Mac OSX options -ifeq ($(UNAME), Darwin) -CPPFLAGS += -D_XOPEN_SOURCE -DMAC -endif diff --git a/version2/src/RPi/gmon.out b/version2/src/RPi/gmon.out deleted file mode 100644 index 69b5434..0000000 Binary files a/version2/src/RPi/gmon.out and /dev/null differ diff --git a/version2/src/others/RPi/BulbColor.h b/version2/src/others/RPi/BulbColor.h new file mode 100644 index 0000000..329d060 --- /dev/null +++ b/version2/src/others/RPi/BulbColor.h @@ -0,0 +1,82 @@ +#ifndef _BULBCOLOR_H__ +#define _BULBCOLOR_H__ +#include + +class BulbColor { + + private: + int hue; + int saturation; + int brightness; + int kelvin; + + public: + + BulbColor(int _hue, int _saturation, int _brightness, int _kelvin) { + + if ((_hue > 65535) || (_hue < 0)) { + cerr << "BulbColor: Invalid parameter value for _hue (0-65535)" << endl; + exit(1); + } + + if ((_saturation > 65535) || (_saturation < 0)) { + cerr << "BulbColor: Invalid parameter value for _saturation (0-65535)" << endl; + exit(1); + } + + if ((_brightness > 65535) || (_brightness < 0)) { + cerr << "BulbColor: Invalid parameter value for _brightness (0-65535)" << endl; + exit(1); + } + + if ((_kelvin > 65535) || (_kelvin < 0)) { + cerr << "BulbColor: Invalid parameter value for _kelvin (0-65535)" << endl; + exit(1); + } + + hue = _hue; + saturation = _saturation; + brightness = _brightness; + kelvin = _kelvin; + } + + + BulbColor(char* data) { + hue = ((data[1] & 0xFF) << 8); + hue |= (data[0] & 0xFF); + + saturation = ((data[3] & 0xFF) << 8); + saturation |= (data[2] & 0xFF); + + brightness = ((data[5] & 0xFF) << 8); + brightness |= (data[4] & 0xFF); + + kelvin = ((data[7] & 0xFF) << 8); + kelvin |= (data[6] & 0xFF); + } + + + ~BulbColor() { + } + + + int getHue() { + return hue; + } + + + int getSaturation() { + return saturation; + } + + + int getBrightness() { + return brightness; + } + + + int getKelvin() { + return kelvin; + } +}; +#endif diff --git a/version2/src/others/RPi/DeviceStateGroup.h b/version2/src/others/RPi/DeviceStateGroup.h new file mode 100644 index 0000000..c54bce0 --- /dev/null +++ b/version2/src/others/RPi/DeviceStateGroup.h @@ -0,0 +1,41 @@ +#ifndef _DEVICESTATEGROUP_H__ +#define _DEVICESTATEGROUP_H__ +#include +#include + +class DeviceStateGroup { + + private: + char group[16]; + string label; + int64_t updatedAt; + + public: + + DeviceStateGroup(char _location[16], string _label, int64_t _updatedAt) { + + strcpy(group, _location); + label = _label; + updatedAt = _updatedAt; + } + + + ~DeviceStateGroup() { + } + + + char* getGroup() { + return group; + } + + + string getLabel() { + return label; + } + + + int64_t getUpdatedAt() { + return updatedAt; + } +}; +#endif diff --git a/version2/src/others/RPi/DeviceStateHostFirmware.h b/version2/src/others/RPi/DeviceStateHostFirmware.h new file mode 100644 index 0000000..b2dd88a --- /dev/null +++ b/version2/src/others/RPi/DeviceStateHostFirmware.h @@ -0,0 +1,35 @@ +#ifndef _DEVICESTATEHOSTFIRMWARE_H__ +#define _DEVICESTATEHOSTFIRMWARE_H__ +#include + +class DeviceStateHostFirmware { + // time of build in nanosecond accuracy + // after some tests + private: + int64_t build; + int64_t version; // firmware version + + public: + + DeviceStateHostFirmware(int64_t _build, int64_t _version) { + + build = _build; + version = _version; + } + + + ~DeviceStateHostFirmware() { + } + + + int64_t getBuild() { + return build; + } + + + int64_t getVersion() { + return version; + } + +}; +#endif diff --git a/version2/src/others/RPi/DeviceStateHostInfo.h b/version2/src/others/RPi/DeviceStateHostInfo.h new file mode 100644 index 0000000..081f6b9 --- /dev/null +++ b/version2/src/others/RPi/DeviceStateHostInfo.h @@ -0,0 +1,39 @@ +#ifndef _DEVICESTATEHOSTINFO_H__ +#define _DEVICESTATEHOSTINFO_H__ +#include + +class DeviceStateHostInfo { + private: + int64_t signal; + int64_t tx; + int64_t rx; + + public: + + DeviceStateHostInfo(int64_t _signal, int64_t _tx, int64_t _rx) { + + signal = _signal; + tx = _tx; + rx = _rx; + } + + + ~DeviceStateHostInfo() { + } + + + int64_t getSignal() { + return signal; + } + + + int64_t getTx() { + return tx; + } + + + int64_t getRx() { + return rx; + } +}; +#endif diff --git a/version2/src/others/RPi/DeviceStateInfo.h b/version2/src/others/RPi/DeviceStateInfo.h new file mode 100644 index 0000000..68d4bd5 --- /dev/null +++ b/version2/src/others/RPi/DeviceStateInfo.h @@ -0,0 +1,39 @@ +#ifndef _DEVICESTATEINFO_H__ +#define _DEVICESTATEINFO_H__ +#include + +class DeviceStateInfo { + private: + int64_t time; + int64_t upTime; + int64_t downTime; + + public: + + DeviceStateInfo(int64_t _time, int64_t _upTime, int64_t _downTime) { + + time = _time; + upTime = _upTime; + downTime = _downTime; + } + + + ~DeviceStateInfo() { + } + + + int64_t getTime() { + return time; + } + + + int64_t getUpTime() { + return upTime; + } + + + int64_t getDownTime() { + return downTime; + } +}; +#endif diff --git a/version2/src/others/RPi/DeviceStateLocation.h b/version2/src/others/RPi/DeviceStateLocation.h new file mode 100644 index 0000000..70f9bab --- /dev/null +++ b/version2/src/others/RPi/DeviceStateLocation.h @@ -0,0 +1,40 @@ +#ifndef _DEVICESTATELOCATION_H__ +#define _DEVICESTATELOCATION_H__ +#include +#include + +class DeviceStateLocation { + private: + char location[16]; + string label; + int64_t updatedAt; + + public: + + DeviceStateLocation(char _location[16], string _label, long _updatedAt) { + + strcpy(location, _location); + label = _label; + updatedAt = _updatedAt; + } + + + ~DeviceStateLocation() { + } + + + char* getLocation() { + return location; + } + + + string getLabel() { + return label; + } + + + int64_t getUpdatedAt() { + return updatedAt; + } +}; +#endif diff --git a/version2/src/others/RPi/DeviceStateService.h b/version2/src/others/RPi/DeviceStateService.h new file mode 100644 index 0000000..784cc3f --- /dev/null +++ b/version2/src/others/RPi/DeviceStateService.h @@ -0,0 +1,32 @@ +#ifndef _DEVICESTATESERVICE_H__ +#define _DEVICESTATESERVICE_H__ +#include + +class DeviceStateService { + private: + int service; + int64_t port; + + public: + + DeviceStateService(int _service, long _port) { + + service = _service; + port = _port; + } + + + ~DeviceStateService() { + } + + + int getService() { + return service; + } + + + int64_t getPort() { + return port; + } +}; +#endif diff --git a/version2/src/others/RPi/DeviceStateVersion.h b/version2/src/others/RPi/DeviceStateVersion.h new file mode 100644 index 0000000..2e40d03 --- /dev/null +++ b/version2/src/others/RPi/DeviceStateVersion.h @@ -0,0 +1,39 @@ +#ifndef _DEVICESTATEVERSION_H__ +#define _DEVICESTATEVERSION_H__ +#include + +class DeviceStateVersion { + private: + int64_t vender; + int64_t product; + int64_t version; + + public: + + DeviceStateVersion(int64_t _vender, int64_t _product, int64_t _version) { + + vender = _vender; + product = _product; + version = _version; + } + + + ~DeviceStateVersion() { + } + + + int64_t getVender() { + return vender; + } + + + int64_t getProduct() { + return product; + } + + + int64_t getVersion() { + return version; + } +}; +#endif diff --git a/version2/src/others/RPi/DeviceStateWifiFirmware.h b/version2/src/others/RPi/DeviceStateWifiFirmware.h new file mode 100644 index 0000000..28c1d26 --- /dev/null +++ b/version2/src/others/RPi/DeviceStateWifiFirmware.h @@ -0,0 +1,34 @@ +#ifndef _DEVICESTATEWIFIFIRMWARE_H__ +#define _DEVICESTATEWIFIFIRMWARE_H__ +#include + +class DeviceStateWifiFirmware { + // time of build in nanosecond accuracy + // after some tests + private: + int64_t build; + int64_t version; // firmware version + + public: + + DeviceStateWifiFirmware(int64_t _build, int64_t _version) { + + build = _build; + version = _version; + } + + + ~DeviceStateWifiFirmware() { + } + + + int64_t getBuild() { + return build; + } + + + int64_t getVersion() { + return version; + } +}; +#endif diff --git a/version2/src/others/RPi/DeviceStateWifiInfo.h b/version2/src/others/RPi/DeviceStateWifiInfo.h new file mode 100644 index 0000000..7bbc83b --- /dev/null +++ b/version2/src/others/RPi/DeviceStateWifiInfo.h @@ -0,0 +1,39 @@ +#ifndef _DEVICESTATEWIFIINFO_H__ +#define _DEVICESTATEWIFIINFO_H__ +#include + +class DeviceStateWifiInfo { + private: + int64_t signal; + int64_t tx; + int64_t rx; + + public: + + DeviceStateWifiInfo(int64_t _signal, int64_t _tx, int64_t _rx) { + + signal = _signal; + tx = _tx; + rx = _rx; + } + + + ~DeviceStateWifiInfo() { + } + + + int64_t getSignal() { + return signal; + } + + + int64_t getTx() { + return tx; + } + + + int64_t getRx() { + return rx; + } +}; +#endif diff --git a/version2/src/others/RPi/IoTAddress.h b/version2/src/others/RPi/IoTAddress.h new file mode 100644 index 0000000..360caed --- /dev/null +++ b/version2/src/others/RPi/IoTAddress.h @@ -0,0 +1,46 @@ +#ifndef _IOTADDRESS_HPP__ +#define _IOTADDRESS_HPP__ +#include + +#include "application.h" + +using namespace std; + + +// IoTAddress class for iotruntime +// Implemented based on IoTAddress.java that is used to wrap address +// +// @author Rahmadi Trimananda +// @version 1.0 +// @since 2017-01-09 + +class IoTAddress +{ + public: + + // Constructor + IoTAddress(IPAddress _sAddress) { + + inetAddress = _sAddress; + } + + + // Constructor + IoTAddress() { + } + + + ~IoTAddress() { + } + + + IPAddress getAddress() { + + return inetAddress; + } + + // IoTAddress class properties + protected: + IPAddress inetAddress; +}; +#endif diff --git a/version2/src/others/RPi/IoTDeviceAddress.h b/version2/src/others/RPi/IoTDeviceAddress.h new file mode 100644 index 0000000..d6f1f27 --- /dev/null +++ b/version2/src/others/RPi/IoTDeviceAddress.h @@ -0,0 +1,91 @@ +#ifndef _IOTDEVICEADDRESS_H__ +#define _IOTDEVICEADDRESS_H__ +#include + +#include "IoTAddress.h" + +using namespace std; + +// IoTDeviceAddress class for iotruntime +// Implemented based on IoTDeviceAddress.java that is used to wrap device address +// +// @author Rahmadi Trimananda +// @version 1.0 +// @since 2017-01-09 + + +class IoTDeviceAddress final : public IoTAddress +{ + + public: + + // Constructor + IoTDeviceAddress(IPAddress _sAddress, int _iSrcPort, int _iDstPort, bool _isSrcPortWildCard, bool _isDstPortWildCard) : IoTAddress(_sAddress) { + + iSrcPort = _iSrcPort; + iDstPort = _iDstPort; + isSrcPortWildCard = _isSrcPortWildCard; + isDstPortWildCard = _isDstPortWildCard; + } + + + // Constructor + IoTDeviceAddress() { + } + + + ~IoTDeviceAddress() { + } + + + // Getter methods + int getSourcePortNumber() { + + return iSrcPort; + } + + + int getDestinationPortNumber() { + + return iDstPort; + } + + + bool getIsSrcPortWildcard() { + + return isSrcPortWildCard; + } + + + bool getIsDstPortWildcard() { + + return isDstPortWildCard; + } + + + // Setter methods + void setSrcPort(int port) { + + if (isDstPortWildCard) { + iDstPort = port; + } + } + + + void setDstPort(int port) { + + if (isSrcPortWildCard) { + iSrcPort = port; + } + } + + + // IoTDeviceAddress class properties + private: + int iSrcPort; + int iDstPort; + + bool isSrcPortWildCard; + bool isDstPortWildCard; +}; +#endif diff --git a/version2/src/others/RPi/IoTSet.h b/version2/src/others/RPi/IoTSet.h new file mode 100644 index 0000000..0104809 --- /dev/null +++ b/version2/src/others/RPi/IoTSet.h @@ -0,0 +1,110 @@ +#ifndef _IOTSET_H__ +#define _IOTSET_H__ +#include +#include +#include + +using namespace std; + +/** This is the IoTSet implementation for C++ + * + * @author Rahmadi Trimananda + * @version 1.0 + * @since 2016-09-06 + */ +template +class IoTSet final { + private: + const unordered_set* set; + public: + IoTSet(); + IoTSet(const unordered_set* s); + ~IoTSet(); + public: + typename unordered_set::const_iterator find(const T& k); // Find the object + bool empty(); // Test is empty? + typename unordered_set::const_iterator begin(); // Iterator + typename unordered_set::const_iterator end(); // Iterator + int size(); // Set size + unordered_set* values(); // Return set contents +}; + + +/** + * Default constructor + */ +template +IoTSet::IoTSet() { + +} + + +/** + * Useful constructor + */ +template +IoTSet::IoTSet(const unordered_set* s) { + + set = s; +} + + +/** + * Default destructor + */ +template +IoTSet::~IoTSet() { + +} + + +/** + * Find the object k in the set + */ +template +typename unordered_set::const_iterator IoTSet::find(const T& k) { + + return (new unordered_set(*set))->find(k); +} + + +/** + * Return the "begin" iterator + */ +template +typename unordered_set::const_iterator IoTSet::begin() { + + return (new unordered_set(*set))->begin(); +} + + +/** + * Return the "end" iterator + */ +template +typename unordered_set::const_iterator IoTSet::end() { + + return (new unordered_set(*set))->end(); +} + + +/** + * Return the size of the set + */ +template +int IoTSet::size() { + + return set->size(); +} + + +/** + * Return a new copy of the set + */ +template +unordered_set* IoTSet::values() { + + return new unordered_set(*set); +} +#endif + diff --git a/version2/src/others/RPi/IoTUDP.h b/version2/src/others/RPi/IoTUDP.h new file mode 100644 index 0000000..f538553 --- /dev/null +++ b/version2/src/others/RPi/IoTUDP.h @@ -0,0 +1,83 @@ +#ifndef _IOTUDP_H__ +#define _IOTUDP_H__ +#include + +#include "IoTDeviceAddress.h" + +using namespace std; + +// IoTUDP class for iotruntime +// Implemented based on IoTUDP.java that is used to wrap communication socket for UDP +// +// @author Rahmadi Trimananda +// @version 1.0 +// @since 2017-01-09 + +class IoTUDP final +{ + // IoTUDP class properties + private: + //UDPSocket *socket; + UDP socket; + IPAddress strHostAddress; + int iSrcPort; + int iDstPort; + bool didClose; + int timeOut; + + public: + + // Constructor + IoTUDP(IoTDeviceAddress* iotDevAdd) { + + strHostAddress = iotDevAdd->getAddress(); + iSrcPort = iotDevAdd->getSourcePortNumber(); + iDstPort = iotDevAdd->getDestinationPortNumber(); + timeOut = 0; + + socket.begin(iSrcPort); + didClose = false; + } + + + ~IoTUDP() { + } + + + IPAddress getHostAddress() { + return strHostAddress; + } + + + int getSourcePort() { + return iSrcPort; + } + + + int getDestinationPort() { + return iDstPort; + } + + + void setTimeOut(int interval) { + + timeOut = interval; + } + + + // Send data packet + void sendData(const char* buffer, int bufferLen) { + + unsigned short destinationPort = (unsigned short) iDstPort; + IPAddress ipFromBytes(strHostAddress); + socket.sendPacket(buffer, bufferLen, strHostAddress, destinationPort); + } + + + // Receive data packet + int receiveData(char* buffer, int iMaxDataLength) { + + return socket.receivePacket(buffer, iMaxDataLength); + } +}; +#endif diff --git a/version2/src/others/RPi/LifxHeader.h b/version2/src/others/RPi/LifxHeader.h new file mode 100644 index 0000000..6d4fbe5 --- /dev/null +++ b/version2/src/others/RPi/LifxHeader.h @@ -0,0 +1,287 @@ +#ifndef _LIFXHEADER_H__ +#define _LIFXHEADER_H__ +#include + +class LifxHeader { + + private: + // Frame variables + int size; + int origin; + bool tagged; + bool addressable; + int protocol; + int64_t source; + + // Frame address variables + char macAddress[8]; + bool ack_required; + bool res_required; + int sequence; + + // Protocol header + int type; + + public: + + LifxHeader() { + origin = 0; + addressable = true; + protocol =1024; + } + + + ~LifxHeader() { + } + + + void setSize(int _size) { + if (_size < 0) { + cerr << "Header: size cannot be less than 0" << endl; + exit(1); + } else if (_size > 65535) { + cerr << "Header: size too large" << endl; + exit(1); + } + size = _size; + } + + + void setOrigin(int _origin) { + if (_origin < 0) { + cerr << "Header: origin cannot be less than 0" << endl; + exit(1); + } else if (_origin > 3) { + cerr << "Header: origin too large" << endl; + exit(1); + } + origin = _origin; + } + + + void setTagged(bool _tagged) { + tagged = _tagged; + } + + + void setAddressable(bool _addressable) { + addressable = _addressable; + } + + + void setProtocol(int _protocol) { + if (_protocol < 0) { + cerr << "Header: protocol cannot be less than 0" << endl; + exit(1); + } else if (_protocol > 4095) { + cerr << "Header: protocol too large" << endl; + exit(1); + } + protocol = _protocol; + } + + + void setSource(int64_t _source) { + if (_source < 0) { + cerr << "Header: source cannot be less than 0" << endl; + exit(1); + } else if (_source > 4294967295) { + cerr << "Header: source too large" << endl; + exit(1); + } + source = _source; + } + + + void setSequence(int _sequence) { + if (_sequence < 0) { + cerr << "Header: sequence cannot be less than 0" << endl; + exit(1); + } else if (_sequence > 255) { + cerr << "Header: sequence too large" << endl; + exit(1); + } + sequence = _sequence; + } + + + void setType(int _type) { + if (_type < 0) { + cerr << "Header: type cannot be less than 0" << endl; + exit(1); + } else if (_type > 65535) { + cerr << "Header: type too large" << endl; + exit(1); + } + type = _type; + } + + + void setAck_required(bool _ack_required) { + ack_required = _ack_required; + } + + + void setRes_required(bool _res_required) { + res_required = _res_required; + } + + + void setMacAddress(char _macAddress[8]) { + strcpy(macAddress, _macAddress); + } + + + int getSize() { + return size; + } + + + int getOrigin() { + return origin; + } + + + bool getTagged() { + return tagged; + } + + + bool getAddressable() { + return addressable; + } + + + int getProtocol() { + return protocol; + } + + + int64_t getSource() { + return source; + } + + + int64_t getSequence() { + return sequence; + } + + + int getType() { + return type; + } + + + char* getHeaderBytes(char headerBytes[36]) { + + //char headerBytes[36]; + headerBytes[0] = (char)(size & 0xFF); + headerBytes[1] = (char)((size >> 8) & 0xFF); + + + headerBytes[2] = (char)(protocol & 0xFF); + headerBytes[3] = (char)((protocol >> 8) & 0x0F); + + headerBytes[3] |= (char)((origin & 0x03) << 6); + + if (tagged) { + headerBytes[3] |= (1 << 5); + } + + if (addressable) { + headerBytes[3] |= (1 << 4); + } + + headerBytes[4] = (char)((source >> 0) & 0xFF); + headerBytes[5] = (char)((source >> 8) & 0xFF); + headerBytes[6] = (char)((source >> 16) & 0xFF); + headerBytes[7] = (char)((source >> 24) & 0xFF); + + // fix in a bit + headerBytes[8] = macAddress[0]; + headerBytes[9] = macAddress[1]; + headerBytes[10] = macAddress[2]; + headerBytes[11] = macAddress[3]; + headerBytes[12] = macAddress[4]; + headerBytes[13] = macAddress[5]; + headerBytes[14] = macAddress[6]; + headerBytes[15] = macAddress[7]; + + // Reserved and set to 0 + headerBytes[16] = 0; + headerBytes[17] = 0; + headerBytes[18] = 0; + headerBytes[19] = 0; + headerBytes[20] = 0; + headerBytes[21] = 0; + + if (ack_required) { + headerBytes[22] = (1 << 1); + } + + if (res_required) { + headerBytes[22] |= (1); + } + + headerBytes[23] = (char)(sequence & 0xFF); + + // Reserved and set to 0 + headerBytes[24] = 0; + headerBytes[25] = 0; + headerBytes[26] = 0; + headerBytes[27] = 0; + headerBytes[28] = 0; + headerBytes[29] = 0; + headerBytes[30] = 0; + headerBytes[31] = 0; + + headerBytes[32] = (char)((type >> 0) & 0xFF); + headerBytes[33] = (char)((type >> 8) & 0xFF); + + // Reserved and set to 0 + headerBytes[34] = 0; + headerBytes[35] = 0; + + return headerBytes; + } + + + void setFromBytes(char dataBytes[36]) { + + size = dataBytes[0] & 0xFF; + size |= ((dataBytes[1] & 0xFF) << 8); + size &= 0xFFFF; + + origin = (dataBytes[3] >> 6) & 0x03; + tagged = ((dataBytes[3] >> 5) & 0x01) == 1; + addressable = ((dataBytes[3] >> 4) & 0x01) == 1; + + + protocol = (dataBytes[3] & 0x0F) << 8; + protocol |= dataBytes[2]; + protocol &= 0x0FFF; + + source = (dataBytes[7] & 0xFFl) << 24; + source |= ((dataBytes[6] & 0xFFl) << 16); + source |= ((dataBytes[5] & 0xFFl) << 8); + source |= ((dataBytes[4] & 0xFFl)); + + macAddress[0] = dataBytes[8]; + macAddress[1] = dataBytes[9]; + macAddress[2] = dataBytes[10]; + macAddress[3] = dataBytes[11]; + macAddress[4] = dataBytes[12]; + macAddress[5] = dataBytes[13]; + macAddress[6] = dataBytes[14]; + macAddress[7] = dataBytes[15]; + + ack_required = (dataBytes[22] & 0x02) == 0x02; + res_required = (dataBytes[22] & 0x01) == 0x01; + + sequence = (dataBytes[23] & 0xFF); + + type = ((dataBytes[33] & 0xFF) << 8); + type |= (dataBytes[32] & 0xFF); + } +}; +#endif diff --git a/version2/src/others/RPi/LifxLightBulb.cpp b/version2/src/others/RPi/LifxLightBulb.cpp new file mode 100644 index 0000000..247fb22 --- /dev/null +++ b/version2/src/others/RPi/LifxLightBulb.cpp @@ -0,0 +1,1103 @@ +#include +#include +#include + +#include + +#include "LifxLightBulb.h" +#include "IoTSet.h" +#include "IoTDeviceAddress.h" +#include "application.h" + +using namespace std; + + +// Default constructor +LifxLightBulb::LifxLightBulb() { + +} + + +// Constructor +LifxLightBulb::LifxLightBulb(IPAddress ipAddress, char* macAddress, int srcPort) { + + memcpy(bulbMacAddress, macAddress, 8); + + // Initialize device address + // Port 56700 is the default port for Lifx + IoTDeviceAddress* devAddress = new IoTDeviceAddress(ipAddress, srcPort, 56700, false, false); + unordered_set* myset1 = new unordered_set(); + myset1->insert(devAddress); + IoTSet* setDevAddress = new IoTSet(myset1); + lb_addresses = setDevAddress; +} + + +LifxLightBulb::~LifxLightBulb() { + + // Clean up + if (communicationSocket != NULL) { + + delete communicationSocket; + communicationSocket = NULL; + } + for(void* dev : *lb_addresses) { + IoTDeviceAddress* dv = (IoTDeviceAddress*) dev; + delete dv; + dv = NULL; + } + if (lb_addresses != NULL) { + + delete lb_addresses; + lb_addresses = NULL; + } +} + + +// PUBLIC METHODS +// Initialize the lightbulb +void LifxLightBulb::init() { + + if (didAlreadyInit) + return; + // Set to true if not yet + didAlreadyInit = true; + + unordered_set::const_iterator itr = lb_addresses->begin(); + IoTDeviceAddress* deviceAddress = (IoTDeviceAddress*) *itr; + + // Create IoTUDP socket + communicationSocket = new IoTUDP(deviceAddress); + + //cout << "Host address: " << communicationSocket->getHostAddress() << endl; + //cout << "Source port: " << communicationSocket->getSourcePort() << endl; + //cout << "Destination port: " << communicationSocket->getDestinationPort() << endl << endl; + + // Launch the worker function in a separate thread. + // NOTE: "this" pointer is passed into the detached thread because it does not belong + // to this object anymore so if it executes certain methods of "this" object, then it needs + // the correct references to stuff + thread th1 (&LifxLightBulb::workerFunction, this, this); + th1.detach(); +} + + +void LifxLightBulb::turnOff() { + + //lock_guard guard(bulbStateMutex); + bulbStateMutex.lock(); + bulbIsOn = false; + sendSetLightPowerPacket(0, 0); + stateDidChange = true; + bulbStateMutex.unlock(); +} + + +void LifxLightBulb::turnOn() { + + //lock_guard guard(bulbStateMutex); + bulbStateMutex.lock(); + bulbIsOn = true; + sendSetLightPowerPacket(65535, 0); + stateDidChange = true; + bulbStateMutex.unlock(); +} + + +double LifxLightBulb::getHue() { + double tmp = 0; + settingBulbColorMutex.lock(); + tmp = ((double)currentHue / 65535.0) * 360.0; + settingBulbColorMutex.unlock(); + + return tmp; +} + + +double LifxLightBulb::getSaturation() { + double tmp = 0; + settingBulbColorMutex.lock(); + tmp = ((double)currentSaturation / 65535.0) * 360.0; + settingBulbColorMutex.unlock(); + + return tmp; +} + + +double LifxLightBulb::getBrightness() { + double tmp = 0; + settingBulbColorMutex.lock(); + tmp = ((double)currentBrightness / 65535.0) * 360.0; + settingBulbColorMutex.unlock(); + + return tmp; +} + + +int LifxLightBulb::getTemperature() { + + int tmp = 0; + settingBulbTemperatureMutex.lock(); + tmp = currentTemperature; + settingBulbTemperatureMutex.unlock(); + + return tmp; +} + + +double LifxLightBulb::getHueRangeLowerBound() { + if (!didGetBulbVersion) { + return -1; + } + return ((double)hueLowerBound / 65535.0) * 360.0; +} + + +double LifxLightBulb::getHueRangeUpperBound() { + if (!didGetBulbVersion) { + return -1; + } + return ((double)hueUpperBound / 65535.0) * 360.0; +} + + +double LifxLightBulb::getSaturationRangeLowerBound() { + if (!didGetBulbVersion) { + return -1; + } + return ((double)saturationLowerBound / 65535.0) * 100.0; +} + + +double LifxLightBulb::getSaturationRangeUpperBound() { + if (!didGetBulbVersion) { + return -1; + } + return ((double)saturationUpperBound / 65535.0) * 100.0; +} + + +double LifxLightBulb::getBrightnessRangeLowerBound() { + if (!didGetBulbVersion) { + return -1; + } + return ((double)brightnessLowerBound / 65535.0) * 100.0; +} + + +double LifxLightBulb::getBrightnessRangeUpperBound() { + if (!didGetBulbVersion) { + return -1; + } + return ((double)brightnessUpperBound / 65535.0) * 100.0; +} + + +int LifxLightBulb::getTemperatureRangeLowerBound() { + if (!didGetBulbVersion) { + return -1; + } + return temperatureLowerBound; +} + + +int LifxLightBulb::getTemperatureRangeUpperBound() { + if (!didGetBulbVersion) { + return -1; + } + return temperatureUpperBound; +} + + +void LifxLightBulb::setTemperature(int _temperature) { + + settingBulbTemperatureMutex.lock(); + + BulbColor* newColor = new BulbColor(currentHue, currentSaturation, currentBrightness, _temperature); + sendSetLightColorPacket(newColor, 250); + + currentTemperature = _temperature; + stateDidChange = true; + + settingBulbTemperatureMutex.unlock(); +} + + +void LifxLightBulb::setColor(double _hue, double _saturation, double _brightness) { + + settingBulbColorMutex.lock(); + + _hue /= 360.0; + _saturation /= 100.0; + _brightness /= 100.0; + + + int newHue = (int)(_hue * 65535.0); + int newSaturation = (int)(_saturation * 65535.0); + int newBrightness = (int)(_brightness * 65535.0); + + BulbColor* newColor = new BulbColor(newHue, newSaturation, newBrightness, currentTemperature); + sendSetLightColorPacket(newColor, 250); + + currentHue = newHue; + currentSaturation = newSaturation; + currentBrightness = newBrightness; + stateDidChange = true; + + settingBulbColorMutex.unlock(); +} + + +bool LifxLightBulb::getState() { + + bool tmp = false; + + bulbStateMutex.lock(); + tmp = bulbIsOn; + bulbStateMutex.unlock(); + + return tmp; +} + + +// PRIVATE METHODS +// Communication helpers +void LifxLightBulb::receivedPacket(char* packetData) { + + char headerBytes[36]; + for (int i = 0; i < 36; i++) { + headerBytes[i] = packetData[i]; + } + + LifxHeader recHeader; + recHeader.setFromBytes(headerBytes); + + // load the payload bytes (strip away the header) + char* payloadBytes = new char[recHeader.getSize()]; + for (int i = 36; i < recHeader.getSize(); i++) { + payloadBytes[i - 36] = packetData[i]; + } + + int type = recHeader.getType(); + //cout << "Received: " << type << endl; + + DeviceStateService* dat = NULL; + switch (type) { + + case 3: + dat = parseDeviceStateServiceMessage(payloadBytes); + //cout << "Service: " << dat->getService(); + //cout << "Port : " << dat->getPort(); + // Avoid memory leak - delete this object + delete dat; + break; + + case 33: + handleStateVersionMessageReceived(payloadBytes); + break; + + case 35: + parseDeviceStateInfoMessage(payloadBytes); + break; + + + case 107: + handleLightStateMessageReceived(payloadBytes); + break; + + default: + break; + //cout << "unknown packet Type" << endl; + } + // Avoid memory leaks + delete payloadBytes; +} + + +void LifxLightBulb::sendPacket(char* packetData, int len) { + //cout << "sendPacket: About to send" << endl; + lock_guard guard(socketMutex); + sendSocketFlag = true; + communicationSocket->sendData(packetData, len); + sendSocketFlag = false; +} + + +// Worker function which runs the while loop for receiving data from the bulb. +// Is blocking. +void LifxLightBulb::workerFunction(LifxLightBulb* llb) { + + // Need timeout on receives since we are not sure if a packet will be available + // for processing so don't block waiting + llb->communicationSocket->setTimeOut(50000); // In milliseconds + llb->turnOff(); + + int64_t lastSentGetBulbVersionRequest = 0; // time last request sent + char dat[1024]; + + while (true) { + // Check if we got the bulb version yet + // could have requested it but message could have gotten lost (UDP) + if (!llb->didGetBulbVersion) { + int64_t currentTime = (int64_t) time(NULL); + if ((currentTime - lastSentGetBulbVersionRequest) > llb->GET_BULB_VERSION_RESEND_WAIT_SECONDS) { + // Get the bulb version so we know what type of bulb this is. + //cout << "Sending version packet! " << endl; + llb->sendGetVersionPacket(); + lastSentGetBulbVersionRequest = currentTime; + } + } + + // Communication resource is busy so try again later + if (llb->sendSocketFlag) { + continue; + } + + llb->socketMutex.lock(); + int ret = llb->communicationSocket->receiveData(dat, 1024); + // Never forget to release! + llb->socketMutex.unlock(); + + // A packed arrived + if (ret != -1) { + llb->receivedPacket(dat); + } + + // If a state change occurred then request the bulb state to ensure that the + // bulb did indeed change its state to the correct state + if (llb->stateDidChange) { + llb->sendGetLightStatePacket(); + } + + // Wait a bit as to not tie up system resources + //this_thread::sleep_for (chrono::milliseconds(100)); + delay(100); + //cout << endl << "Sleep and wake up!" << endl; + } +} + + +// Sending +// Device Messages +void LifxLightBulb::sendGetServicePacket() { + LifxHeader header; + header.setSize(36); + header.setTagged(true); + header.setMacAddress(bulbMacAddress); + header.setSource(0); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(2); + + char dataBytes[36]; + header.getHeaderBytes(dataBytes); + + sendPacket(dataBytes, 36); +} + + +void LifxLightBulb::sendGetHostInfoPacket() { + LifxHeader header; + header.setSize(36); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(12); + + char dataBytes[36]; + header.getHeaderBytes(dataBytes); + + sendPacket(dataBytes, 36); +} + + +void LifxLightBulb::sendGetHostFirmwarePacket() { + LifxHeader header; + header.setSize(36); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(14); + + char dataBytes[36]; + header.getHeaderBytes(dataBytes); + + sendPacket(dataBytes, 36); +} + + +void LifxLightBulb::sendGetWifiInfoPacket() { + LifxHeader header; + header.setSize(36); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(16); + + char dataBytes[36]; + header.getHeaderBytes(dataBytes); + + sendPacket(dataBytes, 36); +} + + +void LifxLightBulb::sendGetWifiFirmwarePacket() { + LifxHeader header; + header.setSize(36); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(18); + + char dataBytes[36]; + header.getHeaderBytes(dataBytes); + + sendPacket(dataBytes, 36); +} + + +void LifxLightBulb::sendGetPowerPacket() { + LifxHeader header; + header.setSize(36); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(20); + + char dataBytes[36]; + header.getHeaderBytes(dataBytes); + + sendPacket(dataBytes, 36); +} + + +void LifxLightBulb::sendSetPowerPacket(int level) { + // Currently only 0 and 65535 are supported + // This is a fix for now + if ((level != 65535) && (level != 0)) { + cerr << "Invalid parameter values" << endl; + exit(1); + } + + if ((level > 65535) || (level < 0)) { + cerr << "Invalid parameter values" << endl; + exit(1); + } + + char packetBytes[38]; + + LifxHeader header; + header.setSize(38); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(21); + char headerBytes[36]; + header.getHeaderBytes(headerBytes); + + for (int i = 0; i < 36; i++) { + packetBytes[i] = headerBytes[i]; + } + + packetBytes[36] = (char)(level & 0xFF); + packetBytes[37] = (char)((level >> 8) & 0xFF); + + sendPacket(packetBytes, 38); +} + + +void LifxLightBulb::sendGetLabelPacket() { + LifxHeader header; + header.setSize(36); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(23); + + char dataBytes[36]; + header.getHeaderBytes(dataBytes); + + sendPacket(dataBytes, 36); +} + + +void LifxLightBulb::sendSetLabelPacket(string label) { + // Currently only 0 and 65535 are supported + // This is a fix for now + if (label.length() != 32) { + cerr << "Invalid parameter values, label must be 32 bytes long" << endl; + exit(1); + } + + char packetBytes[68]; + + LifxHeader header; + header.setSize(68); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(24); + char headerBytes[36]; + header.getHeaderBytes(headerBytes); + + for (int i = 0; i < 36; i++) { + packetBytes[i] = headerBytes[i]; + } + + for (int i = 0; i < 32; i++) { + packetBytes[i + 36] = label.c_str()[i]; + } + + sendPacket(packetBytes, 68); +} + + +void LifxLightBulb::sendGetVersionPacket() { + LifxHeader header; + header.setSize(36); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(32); + + char dataBytes[36]; + header.getHeaderBytes(dataBytes); + + sendPacket(dataBytes, 36); +} + + +void LifxLightBulb::sendGetInfoPacket() { + LifxHeader header; + header.setSize(36); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(34); + + char dataBytes[36]; + header.getHeaderBytes(dataBytes); + + sendPacket(dataBytes, 36); +} + + +void LifxLightBulb::sendGetLocationPacket() { + LifxHeader header; + header.setSize(36); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(34); + + char dataBytes[36]; + header.getHeaderBytes(dataBytes); + + sendPacket(dataBytes, 36); +} + + +void LifxLightBulb::sendGetGroupPacket() { + LifxHeader header; + header.setSize(36); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(51); + + char dataBytes[36]; + header.getHeaderBytes(dataBytes); + + sendPacket(dataBytes, 36); +} + + +// Sending +// Light Messages +void LifxLightBulb::sendGetLightStatePacket() { + LifxHeader header; + header.setSize(36); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(101); + + char dataBytes[36]; + header.getHeaderBytes(dataBytes); + + sendPacket(dataBytes, 36); +} + + +void LifxLightBulb::sendSetLightColorPacket(BulbColor* bulbColor, long duration) { + + if ((duration > 4294967295l) || (duration < 0)) { + cerr << "Invalid parameter value, duration out of range (0 - 4294967295)" << endl; + exit(1); + } + + char packetBytes[49]; + + LifxHeader header; + header.setSize(49); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(102); + char headerBytes[36]; + header.getHeaderBytes(headerBytes); + + for (int i = 0; i < 36; i++) { + packetBytes[i] = headerBytes[i]; + } + + // 1 reserved packet + packetBytes[37] = (char)(bulbColor->getHue() & 0xFF); + packetBytes[38] = (char)((bulbColor->getHue() >> 8) & 0xFF); + + packetBytes[39] = (char)(bulbColor->getSaturation() & 0xFF); + packetBytes[40] = (char)((bulbColor->getSaturation() >> 8) & 0xFF); + + packetBytes[41] = (char)(bulbColor->getBrightness() & 0xFF); + packetBytes[42] = (char)((bulbColor->getBrightness() >> 8) & 0xFF); + + packetBytes[43] = (char)(bulbColor->getKelvin() & 0xFF); + packetBytes[44] = (char)((bulbColor->getKelvin() >> 8) & 0xFF); + + packetBytes[45] = (char)((duration >> 0) & 0xFF); + packetBytes[46] = (char)((duration >> 8) & 0xFF); + packetBytes[47] = (char)((duration >> 16) & 0xFF); + packetBytes[48] = (char)((duration >> 24) & 0xFF); + + sendPacket(packetBytes, 49); + // Avoid memory leak - delete object + delete bulbColor; +} + + +void LifxLightBulb::sendGetLightPowerPacket() { + LifxHeader header; + header.setSize(36); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(116); + + char dataBytes[36]; + header.getHeaderBytes(dataBytes); + + sendPacket(dataBytes, 36); +} + + +void LifxLightBulb::sendSetLightPowerPacket(int level, long duration) { + + if ((level > 65535) || (duration > 4294967295l) + || (level < 0) || (duration < 0)) { + cerr << "Invalid parameter values" << endl; + exit(1); + } + char packetBytes[42]; + + LifxHeader header; + header.setSize(42); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(117); + char headerBytes[36]; + header.getHeaderBytes(headerBytes); + + for (int i = 0; i < 36; i++) { + packetBytes[i] = headerBytes[i]; + } + + packetBytes[36] = (char)(level & 0xFF); + packetBytes[37] = (char)((level >> 8) & 0xFF); + + packetBytes[38] = (char)((duration >> 0) & 0xFF); + packetBytes[39] = (char)((duration >> 8) & 0xFF); + packetBytes[40] = (char)((duration >> 16) & 0xFF); + packetBytes[41] = (char)((duration >> 24) & 0xFF); + + sendPacket(packetBytes, 42); +} + + +void LifxLightBulb::sendEchoRequestPacket(char data[64]) { + + char packetBytes[100]; + + LifxHeader header; + header.setSize(100); + header.setTagged(false); + header.setMacAddress(bulbMacAddress); + header.setSource(10); // randomly picked + header.setAck_required(false); + header.setRes_required(false); + header.setSequence(0); + header.setType(58); + char headerBytes[36]; + header.getHeaderBytes(headerBytes); + + for (int i = 0; i < 36; i++) { + packetBytes[i] = headerBytes[i]; + } + + for (int i = 0; i < 64; i++) { + packetBytes[i + 36] = data[i]; + } + + sendPacket(packetBytes, 100); +} + + +// Receiving +// Device Messages +DeviceStateService* LifxLightBulb::parseDeviceStateServiceMessage(char* payloadData) { + int service = payloadData[0]; + int64_t port = ((payloadData[3] & 0xFF) << 24); + port |= ((payloadData[2] & 0xFF) << 16); + port |= ((payloadData[1] & 0xFF) << 8); + port |= (payloadData[0] & 0xFF); + + return new DeviceStateService(service, port); +} + + +DeviceStateHostInfo* LifxLightBulb::parseDeviceStateHostInfoMessage(char* payloadData) { + long signal = ((payloadData[3] & 0xFF) << 24); + signal |= ((payloadData[2] & 0xFF) << 16); + signal |= ((payloadData[1] & 0xFF) << 8); + signal |= (payloadData[0] & 0xFF); + + long tx = ((payloadData[7] & 0xFF) << 24); + tx |= ((payloadData[6] & 0xFF) << 16); + tx |= ((payloadData[5] & 0xFF) << 8); + tx |= (payloadData[4] & 0xFF); + + long rx = ((payloadData[11] & 0xFF) << 24); + rx |= ((payloadData[10] & 0xFF) << 16); + rx |= ((payloadData[9] & 0xFF) << 8); + rx |= (payloadData[8] & 0xFF); + + return new DeviceStateHostInfo(signal, tx, rx); +} + + +DeviceStateHostFirmware* LifxLightBulb::parseDeviceStateHostFirmwareMessage(char* payloadData) { + long build = 0; + for (int i = 0; i < 8; i++) { + build += ((int64_t) payloadData[i] & 0xffL) << (8 * i); + } + + // 8 reserved bytes + + int64_t version = ((payloadData[19] & 0xFF) << 24); + version |= ((payloadData[18] & 0xFF) << 16); + version |= ((payloadData[17] & 0xFF) << 8); + version |= (payloadData[16] & 0xFF); + + return new DeviceStateHostFirmware(build, version); +} + + +DeviceStateWifiInfo* LifxLightBulb::parseDeviceStateWifiInfoMessage(char* payloadData) { + int64_t signal = ((payloadData[3] & 0xFF) << 24); + signal |= ((payloadData[2] & 0xFF) << 16); + signal |= ((payloadData[1] & 0xFF) << 8); + signal |= (payloadData[0] & 0xFF); + + int64_t tx = ((payloadData[7] & 0xFF) << 24); + tx |= ((payloadData[6] & 0xFF) << 16); + tx |= ((payloadData[5] & 0xFF) << 8); + tx |= (payloadData[4] & 0xFF); + + int64_t rx = ((payloadData[11] & 0xFF) << 24); + rx |= ((payloadData[10] & 0xFF) << 16); + rx |= ((payloadData[9] & 0xFF) << 8); + rx |= (payloadData[8] & 0xFF); + + return new DeviceStateWifiInfo(signal, tx, rx); +} + + +DeviceStateWifiFirmware* LifxLightBulb::parseDeviceStateWifiFirmwareMessage(char* payloadData) { + long build = 0; + for (int i = 0; i < 8; i++) { + build += ((int64_t) payloadData[i] & 0xffL) << (8 * i); + } + + // 8 reserved bytes + + int64_t version = ((payloadData[19] & 0xFF) << 24); + version |= ((payloadData[18] & 0xFF) << 16); + version |= ((payloadData[17] & 0xFF) << 8); + version |= (payloadData[16] & 0xFF); + + return new DeviceStateWifiFirmware(build, version); +} + + +int LifxLightBulb::parseStatePowerMessage(char* payloadData) { + int level = ((payloadData[1] & 0xFF) << 8); + level |= (payloadData[0] & 0xFF); + return level; +} + + +DeviceStateVersion* LifxLightBulb::parseDeviceStateVersionMessage(char* payloadData) { + int64_t vender = ((payloadData[3] & 0xFF) << 24); + vender |= ((payloadData[2] & 0xFF) << 16); + vender |= ((payloadData[1] & 0xFF) << 8); + vender |= (payloadData[0] & 0xFF); + + int64_t product = ((payloadData[7] & 0xFF) << 24); + product |= ((payloadData[6] & 0xFF) << 16); + product |= ((payloadData[5] & 0xFF) << 8); + product |= (payloadData[4] & 0xFF); + + int64_t version = ((payloadData[11] & 0xFF) << 24); + version |= ((payloadData[10] & 0xFF) << 16); + version |= ((payloadData[9] & 0xFF) << 8); + version |= (payloadData[8] & 0xFF); + + return new DeviceStateVersion(vender, product, version); +} + + +DeviceStateInfo* LifxLightBulb::parseDeviceStateInfoMessage(char* payloadData) { + int64_t time = 0; + int64_t upTime = 0; + int64_t downTime = 0; + for (int i = 0; i < 8; i++) { + time += ((int64_t) payloadData[i] & 0xffL) << (8 * i); + upTime += ((int64_t) payloadData[i + 8] & 0xffL) << (8 * i); + downTime += ((int64_t) payloadData[i + 16] & 0xffL) << (8 * i); + } + + return new DeviceStateInfo(time, upTime, downTime); +} + + +DeviceStateLocation* LifxLightBulb::parseDeviceStateLocationMessage(char* payloadData) { + char location[16]; + for (int i = 0; i < 16; i++) { + location[i] = payloadData[i]; + } + + char labelBytes[32]; + for (int i = 0; i < 32; i++) { + labelBytes[i] = payloadData[i + 16]; + } + + int64_t updatedAt = 0; + for (int i = 0; i < 8; i++) { + updatedAt += ((int64_t) payloadData[48] & 0xffL) << (8 * i); + } + + string str(labelBytes); + return new DeviceStateLocation(location, str, updatedAt); +} + + +DeviceStateGroup* LifxLightBulb::parseDeviceStateGroupMessage(char* payloadData) { + char group[16]; + for (int i = 0; i < 16; i++) { + group[i] = payloadData[i]; + } + + char labelBytes[32]; + for (int i = 0; i < 32; i++) { + labelBytes[i] = payloadData[i + 16]; + } + + int64_t updatedAt = 0; + for (int i = 0; i < 8; i++) { + updatedAt += ((int64_t) payloadData[48] & 0xffL) << (8 * i); + } + + string str(labelBytes); + return new DeviceStateGroup(group, str, updatedAt); +} + + +// Receiving +// Light Messages +LightState* LifxLightBulb::parseLightStateMessage(char* payloadData) { + + char colorData[8]; + for (int i = 0; i < 8; i++) { + colorData[i] = payloadData[i]; + } + //BulbColor color(colorData); + BulbColor* color = new BulbColor(colorData); + + int power = ((payloadData[11] & 0xFF) << 8); + power |= (payloadData[10] & 0xFF); + + string label(payloadData); + + char labelArray[32]; + for (int i = 0; i < 32; i++) { + labelArray[i] = payloadData[12 + i]; + } + + return new LightState(color, power, label); +} + + +int LifxLightBulb::parseLightStatePowerMessage(char* payloadData) { + int level = ((payloadData[1] & 0xFF) << 8); + level |= (payloadData[0] & 0xFF); + return level; +} + + +// Private Handlers +void LifxLightBulb::handleStateVersionMessageReceived(char* payloadData) { + + DeviceStateVersion* deviceState = parseDeviceStateVersionMessage(payloadData); + int productNumber = (int)deviceState->getProduct(); + + bool isColor = false; + + if (productNumber == 1) {// Original 1000 + isColor = true; + } else if (productNumber == 3) {//Color 650 + isColor = true; + } else if (productNumber == 10) {// White 800 (Low Voltage) + isColor = false; + } else if (productNumber == 11) {// White 800 (High Voltage) + isColor = false; + } else if (productNumber == 18) {// White 900 BR30 (Low Voltage) + isColor = false; + } else if (productNumber == 20) {// Color 1000 BR30 + isColor = true; + } else if (productNumber == 22) {// Color 1000 + isColor = true; + } + + if (isColor) { + hueLowerBound = 0; + hueUpperBound = 65535; + saturationLowerBound = 0; + saturationUpperBound = 65535; + brightnessLowerBound = 0; + brightnessUpperBound = 65535; + temperatureLowerBound = 2500; + temperatureUpperBound = 9000; + } else { + hueLowerBound = 0; + hueUpperBound = 0; + saturationLowerBound = 0; + saturationUpperBound = 0; + brightnessLowerBound = 0; + brightnessUpperBound = 65535;// still can dim bulb + temperatureLowerBound = 2500; + temperatureUpperBound = 9000; + } + + //didGetBulbVersion.exchange(true); + didGetBulbVersion = true; + // Avoid memory leak - delete this object + delete deviceState; +} + + +void LifxLightBulb::handleLightStateMessageReceived(char* payloadData) { + LightState* lightState = parseLightStateMessage(payloadData); + + BulbColor* color = lightState->getColor(); + int power = lightState->getPower(); + + //cout << "color->getHue(): " << color->getHue() << " - currentHue: " << currentHue << endl; + //cout << "color->getSaturation(): " << color->getSaturation() << " - currentSaturation: " << currentSaturation << endl; + //cout << "color->getBrightness(): " << color->getBrightness() << " - currentBrightness: " << currentBrightness << endl; + //cout << "color->getKelvin(): " << color->getKelvin() << " - currentTemperature: " << currentTemperature << endl; + + bool bulbWrongColor = false; + bulbWrongColor = bulbWrongColor || (color->getHue() != currentHue); + bulbWrongColor = bulbWrongColor || (color->getSaturation() != currentSaturation); + bulbWrongColor = bulbWrongColor || (color->getBrightness() != currentBrightness); + bulbWrongColor = bulbWrongColor || (color->getKelvin() != currentTemperature); + + + // gets set to true if any of the below if statements are taken + stateDidChange = false; + + if (bulbWrongColor) { + BulbColor* newColor = new BulbColor(currentHue, currentSaturation, currentBrightness, currentTemperature); + sendSetLightColorPacket(newColor, 250); + //cout << "Failed Check 1" << endl; + } + + bulbStateMutex.lock(); + bool bulbIsOnTmp = bulbIsOn; + bulbStateMutex.unlock(); + + if ((!bulbIsOnTmp) && (power != 0)) { + turnOff(); + //cout << "Failed Check 2: " << endl; + + } + + if (bulbIsOnTmp && (power < 65530)) { + turnOn(); + //cout << "Failed Check 3: " << endl; + + } + // Avoid memory leak - delete object + delete lightState; + delete color; +} + diff --git a/version2/src/others/RPi/LifxLightBulb.h b/version2/src/others/RPi/LifxLightBulb.h new file mode 100644 index 0000000..f2852b4 --- /dev/null +++ b/version2/src/others/RPi/LifxLightBulb.h @@ -0,0 +1,163 @@ +#ifndef _LIFXLIGHTBULB_H__ +#define _LIFXLIGHTBULB_H__ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "LightBulb.h" +//#include "Socket.h" +#include "IoTSet.h" +#include "IoTUDP.h" +#include "IoTDeviceAddress.h" + +// Helper classes for LifxLightBulb +#include "LifxHeader.h" +#include "BulbColor.h" +#include "DeviceStateGroup.h" +#include "DeviceStateHostFirmware.h" +#include "DeviceStateHostInfo.h" +#include "DeviceStateInfo.h" +#include "DeviceStateLocation.h" +#include "DeviceStateService.h" +#include "DeviceStateVersion.h" +#include "DeviceStateWifiFirmware.h" +#include "DeviceStateWifiInfo.h" +#include "LightState.h" + + +using namespace std; + +// Driver LifxLightBulb +// Implemented based on LightBulb virtual class (interface) + +class LifxLightBulb : public LightBulb +{ + private: + // Constants + const static int64_t GET_BULB_VERSION_RESEND_WAIT_SECONDS = 10; + + // Variables + IoTUDP *communicationSocket; + char bulbMacAddress[8]; + //TODO: + bool sendSocketFlag = false; + + // Current Bulb Values + int currentHue = 0; + int currentSaturation = 0; + int currentBrightness = 65535; + int currentTemperature = 9000; + bool bulbIsOn = false; + + bool didAlreadyInit = false; + bool didGetBulbVersion = false; + + // Mutex locks + mutex socketMutex; + mutex settingBulbColorMutex; + mutex settingBulbTemperatureMutex; + mutex bulbStateMutex; + + // color and temperature ranges for the bulbs + int hueLowerBound = 0; + int hueUpperBound = 0; + int saturationLowerBound = 0; + int saturationUpperBound = 0; + int brightnessLowerBound = 0; + int brightnessUpperBound = 0; + int temperatureLowerBound = 2500; + int temperatureUpperBound = 9000; + + // Check if a state change was requested, used to poll the bulb for if the bulb did + // preform the requested state change + bool stateDidChange = false; + + // Device address + IoTSet* lb_addresses; // IoTSet* lb_addresses + + // Logging + ofstream log; + public: + + // Constructor + LifxLightBulb(); + LifxLightBulb(IPAddress ipAddress, char* macAddress, int srcPort); + ~LifxLightBulb(); + // Initialize the lightbulb + void init(); + void turnOff(); + void turnOn(); + double getHue(); + double getSaturation(); + double getBrightness(); + int getTemperature(); + double getHueRangeLowerBound(); + double getHueRangeUpperBound(); + double getSaturationRangeLowerBound(); + double getSaturationRangeUpperBound(); + double getBrightnessRangeLowerBound(); + double getBrightnessRangeUpperBound(); + int getTemperatureRangeLowerBound(); + int getTemperatureRangeUpperBound(); + void setTemperature(int _temperature); + void setColor(double _hue, double _saturation, double _brightness); + bool getState(); + + private: + // Private functions + // Communication helpers + void receivedPacket(char* packetData); + void sendPacket(char* packetData, int len); + // Worker function which runs the while loop for receiving data from the bulb. + // Is blocking. + void workerFunction(LifxLightBulb* llb); + // Sending + // Device Messages + void sendGetServicePacket(); + void sendGetHostInfoPacket(); + void sendGetHostFirmwarePacket(); + void sendGetWifiInfoPacket(); + void sendGetWifiFirmwarePacket(); + void sendGetPowerPacket(); + void sendSetPowerPacket(int level); + void sendGetLabelPacket(); + void sendSetLabelPacket(string label); + void sendGetVersionPacket(); + void sendGetInfoPacket(); + void sendGetLocationPacket(); + void sendGetGroupPacket(); + // Sending + // Light Messages + void sendGetLightStatePacket(); + void sendSetLightColorPacket(BulbColor* bulbColor, long duration); + void sendGetLightPowerPacket(); + void sendSetLightPowerPacket(int level, long duration); + void sendEchoRequestPacket(char data[64]); + // Receiving + // Device Messages + DeviceStateService* parseDeviceStateServiceMessage(char* payloadData); + DeviceStateHostInfo* parseDeviceStateHostInfoMessage(char* payloadData); + DeviceStateHostFirmware* parseDeviceStateHostFirmwareMessage(char* payloadData); + DeviceStateWifiInfo* parseDeviceStateWifiInfoMessage(char* payloadData); + DeviceStateWifiFirmware* parseDeviceStateWifiFirmwareMessage(char* payloadData); + int parseStatePowerMessage(char* payloadData); + DeviceStateVersion* parseDeviceStateVersionMessage(char* payloadData); + DeviceStateInfo* parseDeviceStateInfoMessage(char* payloadData); + DeviceStateLocation* parseDeviceStateLocationMessage(char* payloadData); + DeviceStateGroup* parseDeviceStateGroupMessage(char* payloadData); + // Receiving + // Light Messages + LightState* parseLightStateMessage(char* payloadData); + int parseLightStatePowerMessage(char* payloadData); + // Private Handlers + void handleStateVersionMessageReceived(char* payloadData); + void handleLightStateMessageReceived(char* payloadData); +}; + +#endif diff --git a/version2/src/others/RPi/LightBulb.h b/version2/src/others/RPi/LightBulb.h new file mode 100644 index 0000000..90f9df8 --- /dev/null +++ b/version2/src/others/RPi/LightBulb.h @@ -0,0 +1,29 @@ +#ifndef _LIGHTBULB_H__ +#define _LIGHTBULB_H__ +#include + +using namespace std; + +class LightBulb +{ + public: + virtual void init() = 0; + virtual void turnOff() = 0; + virtual void turnOn() = 0; + virtual bool getState() = 0; + virtual void setColor(double _hue, double _saturation, double _brightness) = 0; + virtual void setTemperature(int _temperature) = 0; + virtual double getBrightness() = 0; + virtual double getHue() = 0; + virtual double getSaturation() = 0; + virtual int getTemperature() = 0; + virtual double getBrightnessRangeLowerBound() = 0; + virtual double getBrightnessRangeUpperBound() = 0; + virtual double getHueRangeLowerBound() = 0; + virtual double getHueRangeUpperBound() = 0; + virtual double getSaturationRangeLowerBound() = 0; + virtual double getSaturationRangeUpperBound() = 0; + virtual int getTemperatureRangeLowerBound() = 0; + virtual int getTemperatureRangeUpperBound() = 0; +}; +#endif diff --git a/version2/src/others/RPi/LightState.h b/version2/src/others/RPi/LightState.h new file mode 100644 index 0000000..ba350e3 --- /dev/null +++ b/version2/src/others/RPi/LightState.h @@ -0,0 +1,41 @@ +#ifndef _LIGHTSTATE_H__ +#define _LIGHTSTATE_H__ +#include + +#include "BulbColor.h" + +class LightState { + private: + BulbColor* color; + int power; + string label; + + public: + + LightState(BulbColor* _color, int _power, string _label) { + + color = _color; + power = _power; + label = _label; + } + + + ~LightState() { + } + + + BulbColor* getColor() { + return color; + } + + + int getPower() { + return power; + } + + + string getLabel() { + return label; + } +}; +#endif diff --git a/version2/src/others/RPi/LightsController.ino b/version2/src/others/RPi/LightsController.ino new file mode 100644 index 0000000..b47d15d --- /dev/null +++ b/version2/src/others/RPi/LightsController.ino @@ -0,0 +1,86 @@ +// ------------------------------------------------ +// Controlling LifxLightBulb through Particle Cloud +// @author Rahmadi Trimananda - UC Irvine +// ------------------------------------------------ + +#include "LifxLightBulb.h" + +LifxLightBulb *llb1; +LifxLightBulb *llb2; + +int led1 = D7; + +void setup() +{ + // Bulb 1 + char macAddress1[8]; + macAddress1[0] = 0xD0; + macAddress1[1] = 0x73; + macAddress1[2] = 0xD5; + macAddress1[3] = 0x12; + macAddress1[4] = 0x8E; + macAddress1[5] = 0x30; + macAddress1[6] = 0x00; + macAddress1[7] = 0x00; + IPAddress devIPAddress1(192, 168, 1, 126); + + llb1 = new LifxLightBulb(devIPAddress1, macAddress1, 12345); + llb1->init(); + + // Bulb 2 + char macAddress2[8]; + macAddress2[0] = 0xD0; + macAddress2[1] = 0x73; + macAddress2[2] = 0xD5; + macAddress2[3] = 0x02; + macAddress2[4] = 0x41; + macAddress2[5] = 0xDA; + macAddress2[6] = 0x00; + macAddress2[7] = 0x00; + IPAddress devIPAddress2(192, 168, 1, 232); + + llb2 = new LifxLightBulb(devIPAddress2, macAddress2, 12346); + llb2->init(); + + pinMode(led1, OUTPUT); + Particle.function("lifx1",lifx1Toggle); + Particle.function("lifx2",lifx2Toggle); +} + + +void loop() { + // Nothing to do here +} + + +// Toggling Lifx light bulb 1 +int lifx1Toggle(String command) { + + if (command=="on") { + llb1->turnOn(); + return 1; + } + else if (command=="off") { + llb1->turnOff(); + return 0; + } + else { + return -1; + } +} + +// Toggling Lifx light bulb 2 +int lifx2Toggle(String command) { + + if (command=="on") { + llb2->turnOn(); + return 1; + } + else if (command=="off") { + llb2->turnOff(); + return 0; + } + else { + return -1; + } +} diff --git a/version2/src/others/RPi/Makefile b/version2/src/others/RPi/Makefile new file mode 100644 index 0000000..948d8e1 --- /dev/null +++ b/version2/src/others/RPi/Makefile @@ -0,0 +1,40 @@ +include common.mk + +all: compile + +# To run Particle, we need to install Particle CLI +# Please see: +# https://docs.particle.io/guide/getting-started/connect/photon/#install-the-particle-cli +monitor: + sudo chmod 666 /dev/ttyACM0 + particle serial monitor + +compile-c: + #g++ -c LifxLightBulb.cpp -o ./LifxLightBulb.o -Wall -O3 -g -I. -Wno-unused-variable -std=c++11 -pthread -pg + g++ ./LifxLightBulb.cpp ./socket/Socket.cpp -o ./LifxLightBulb.o -Wall -Wno-unused-variable --std=c++11 -pthread -pg -I. -I./socket + +compile: + rm -f *.bin + particle compile raspberry-pi + #particle compile photon + + +flash: + particle flash Pi-1 raspberry-pi*.bin + +PHONY += clean +clean: + rm -f *.bin + +PHONY += mrclean +mrclean: clean + rm -rf ../docs + +tabbing: + uncrustify -c C.cfg --no-backup *.cpp + uncrustify -c C.cfg --no-backup *.h + +wc: + wc *.cpp *.h + +.PHONY: $(PHONY) diff --git a/version2/src/others/RPi/README.txt b/version2/src/others/RPi/README.txt new file mode 100644 index 0000000..b1ac1ff --- /dev/null +++ b/version2/src/others/RPi/README.txt @@ -0,0 +1,4 @@ + +This is a RaspberryPi C++ implementation of Lifx light bulb controller. + +Created as a part of our testbed that will include smart home devices that will use Particle cloud. diff --git a/version2/src/others/RPi/common.mk b/version2/src/others/RPi/common.mk new file mode 100644 index 0000000..479a31c --- /dev/null +++ b/version2/src/others/RPi/common.mk @@ -0,0 +1,16 @@ +# A few common Makefile items + +CC := gcc +CXX := g++ + +UNAME := $(shell uname) + +LIB_NAME := iotcloud +LIB_SO := lib_$(LIB_NAME).so + +CPPFLAGS += -Wall -g -O0 + +# Mac OSX options +ifeq ($(UNAME), Darwin) +CPPFLAGS += -D_XOPEN_SOURCE -DMAC +endif diff --git a/version2/src/others/RPi/gmon.out b/version2/src/others/RPi/gmon.out new file mode 100644 index 0000000..69b5434 Binary files /dev/null and b/version2/src/others/RPi/gmon.out differ