#include <iostream>
#include <string>
+#include <thread>
+
+#include <pthread.h>
+
#include "LifxLightBulb.hpp"
#include "IoTSet.hpp"
#include "IoTDeviceAddress.hpp"
using namespace std;
+void run(LifxLightBulb *llb) {
+
+ llb->init();
+}
+
+
+void *prun(void *llb) {
+
+ ((LifxLightBulb*)llb)->init();
+}
+
+
+void onOff(LifxLightBulb *llb) {
+
+ for (int i = 0; i < 5; i++) {
+ llb->turnOff();
+ cout << "Turning off!" << endl;
+ this_thread::sleep_for (chrono::milliseconds(1000));
+ llb->turnOn();
+ cout << "Turning on!" << endl;
+ this_thread::sleep_for (chrono::milliseconds(1000));
+ }
+}
+
+
+void adjustTemp(LifxLightBulb *llb) {
+
+ for (int i = 2500; i < 9000; i += 100) {
+ cout << "Adjusting Temp: " << i << endl;
+ llb->setTemperature(i);
+ this_thread::sleep_for (chrono::milliseconds(100));
+ }
+ cout << "Adjusted temperature to 9000!" << endl;
+ for (int i = 9000; i > 2500; i -= 100) {
+ cout << "Adjusting Temp: " << i << endl;
+ llb->setTemperature(i);
+ this_thread::sleep_for (chrono::milliseconds(100));
+ }
+ cout << "Adjusted temperature to 2500!" << endl;
+}
+
+
+void adjustBright(LifxLightBulb *llb) {
+ for (int i = 100; i > 0; i -= 10) {
+ cout << "Adjusting Brightness: " << i << endl;
+ llb->setColor(llb->getHue(), llb->getSaturation(), i);
+ this_thread::sleep_for (chrono::milliseconds(100));
+ }
+ cout << "Adjusted brightness to 0!" << endl;
+ for (int i = 0; i < 100; i += 10) {
+ cout << "Adjusting Brightness: " << i << endl;
+ llb->setColor(llb->getHue(), llb->getSaturation(), i);
+ this_thread::sleep_for (chrono::milliseconds(100));
+ }
+ cout << "Adjusting brightness to 100!" << endl;
+}
+
+
int main(int argc, char *argv[])
{
string macAddress = "D073D5128E300000";
+ //string macAddress = "D073D50241DA0000";
string devIPAddress = "192.168.2.126";
- IoTDeviceAddress devAddress(devIPAddress, 12345, 56700, false, false);
- unordered_set<IoTDeviceAddress> myset = { devAddress };
+ //string devIPAddress = "192.168.2.232";
+ //IoTDeviceAddress devAddress(devIPAddress, 12345, 56700, false, false);
+ IoTDeviceAddress* devAddress = new IoTDeviceAddress(devIPAddress, 12345, 56700, false, false);
+ unordered_set<IoTDeviceAddress*> myset = { devAddress };
- IoTSet<IoTDeviceAddress> setDevAddress(myset);
+ IoTSet<IoTDeviceAddress*> setDevAddress(myset);
LifxLightBulb *llb = new LifxLightBulb(setDevAddress, macAddress);
llb->init();
-
+ llb->turnOn();
cout << "Generated LifxLightBulb object!" << endl;
+ onOff(llb);
+ adjustTemp(llb);
+ adjustBright(llb);
+ llb->turnOff();
+ delete devAddress;
delete llb;
return 0;
#include <mutex>
#include <thread>
#include <chrono>
+#include <future>
#include <string.h>
#include <time.h>
+#include <pthread.h>
#include "LightBulb.hpp"
#include "Socket.hpp"
//TODO:
//static Semaphore socketMutex = new Semaphore(1);
bool sendSocketFlag = false;
- int64_t lastSentGetBulbVersionRequest = 0; // time last request sent
// Current Bulb Values
int currentHue = 0;
bool stateDidChange = false;
// Device address
- IoTSet<IoTDeviceAddress> lb_addresses;
+ IoTSet<IoTDeviceAddress*> lb_addresses;
public:
}
- LifxLightBulb(IoTSet<IoTDeviceAddress> _devAddress, string macAddress) {
+ LifxLightBulb(IoTSet<IoTDeviceAddress*> _devAddress, string macAddress) {
// Initialize macAddress
char tmpMacAddress[16];
if (didAlreadyInit.exchange(true))
return;
- unordered_set<IoTDeviceAddress>::const_iterator itr = lb_addresses.begin();
- IoTDeviceAddress deviceAddress = *itr;
- cout << "Address: " << deviceAddress.getAddress() << endl;
+ unordered_set<IoTDeviceAddress*>::const_iterator itr = lb_addresses.begin();
+ IoTDeviceAddress* deviceAddress = *itr;
+ cout << "Address: " << deviceAddress->getAddress() << endl;
// 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.
- thread th1 (&LifxLightBulb::workerFunction, this);
- th1.join();
+ // 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();
+
+ cout << "Initialized LifxLightBulb!" << endl;
}
void turnOff() {
- lock_guard<mutex> guard(bulbStateMutex);
+ //lock_guard<mutex> guard(bulbStateMutex);
+ bulbStateMutex.lock();
bulbIsOn = false;
sendSetLightPowerPacket(0, 0);
stateDidChange = true;
- cout << "Turning off lightbulb!" << endl;
+ bulbStateMutex.unlock();
}
void turnOn() {
- lock_guard<mutex> guard(bulbStateMutex);
+ //lock_guard<mutex> guard(bulbStateMutex);
+ bulbStateMutex.lock();
bulbIsOn = true;
sendSetLightPowerPacket(65535, 0);
stateDidChange = true;
+ bulbStateMutex.unlock();
}
recHeader.setFromBytes(headerBytes);
// load the payload bytes (strip away the header)
- char payloadBytes[recHeader.getSize()];
+ //char payloadBytes[recHeader.getSize()];
+ 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;
+ cout << "Received: " << type << endl;
DeviceStateService* dat = NULL;
switch (type) {
default:
cout << "unknown packet Type" << endl;
}
-
+ // Avoid memory leaks
+ delete payloadBytes;
}
// Worker function which runs the while loop for receiving data from the bulb.
// Is blocking.
- void workerFunction() {
- LifxHeader h;
+ void 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
- // TODO: Check if we can do this here!
- //communicationSocket.setSoTimeout(50);
+ llb->communicationSocket->setTimeOut(50000); // In milliseconds
- turnOff();
+ llb->turnOff();
- while (true) {
+ 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 (!didGetBulbVersion) {
+ if (!llb->didGetBulbVersion) {
int64_t currentTime = (int64_t) time(NULL);
- if ((currentTime - lastSentGetBulbVersionRequest) > GET_BULB_VERSION_RESEND_WAIT_SECONDS) {
+ if ((currentTime - lastSentGetBulbVersionRequest) > llb->GET_BULB_VERSION_RESEND_WAIT_SECONDS) {
// Get the bulb version so we know what type of bulb this is.
- sendGetVersionPacket();
+ cout << "Sending version packet! " << endl;
+ llb->sendGetVersionPacket();
lastSentGetBulbVersionRequest = currentTime;
}
}
// Communication resource is busy so try again later
- if (sendSocketFlag) {
+ if (llb->sendSocketFlag) {
continue;
}
- socketMutex.lock();
-
- char dat[1024];
- int ret = communicationSocket->receiveData(dat, 1024);
-
+ llb->socketMutex.lock();
+ int ret = llb->communicationSocket->receiveData(dat, 1024);
// Never forget to release!
- socketMutex.unlock();
+ llb->socketMutex.unlock();
// A packed arrived
if (ret != -1) {
- receivedPacket(dat);
+ 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 (stateDidChange) {
- sendGetLightStatePacket();
+ if (llb->stateDidChange) {
+ llb->sendGetLightStatePacket();
}
// Wait a bit as to not tie up system resources
this_thread::sleep_for (chrono::milliseconds(100));
+ //cout << endl << "Sleep and wake up!" << endl;
}
}
for (int i = 0; i < 8; i++) {
colorData[i] = payloadData[i];
}
- BulbColor color(colorData);
+ //BulbColor color(colorData);
+ BulbColor* color = new BulbColor(colorData);
int power = ((payloadData[11] & 0xFF) << 8);
power |= (payloadData[10] & 0xFF);
labelArray[i] = payloadData[12 + i];
}
- return new LightState(&color, power, label);
+ return new LightState(color, power, label);
}
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);
if (bulbWrongColor) {
BulbColor* newColor = new BulbColor(currentHue, currentSaturation, currentBrightness, currentTemperature);
sendSetLightColorPacket(newColor, 250);
- // System.out.println("Failed Check 1");
+ //cout << "Failed Check 1" << endl;
}
bulbStateMutex.lock();
if ((!bulbIsOnTmp) && (power != 0)) {
turnOff();
- // System.out.println("Failed Check 2: " + Integer.toString(power));
+ //cout << "Failed Check 2: " << endl;
}
if (bulbIsOnTmp && (power < 65530)) {
turnOn();
- // System.out.println("Failed Check 3: " + Integer.toString(power));
+ //cout << "Failed Check 3: " << endl;
}
// Avoid memory leak - delete object
{
// IoTUDP class properties
private:
+ UDPSocket *socket;
string strHostAddress;
int iSrcPort;
int iDstPort;
- UDPSocket *socket;
bool didClose;
+ int timeOut;
public:
// Constructor
- IoTUDP(IoTDeviceAddress iotDevAdd) {
+ IoTUDP(IoTDeviceAddress* iotDevAdd) {
- strHostAddress = iotDevAdd.getAddress();
- iSrcPort = iotDevAdd.getSourcePortNumber();
- iDstPort = iotDevAdd.getDestinationPortNumber();
+ strHostAddress = iotDevAdd->getAddress();
+ iSrcPort = iotDevAdd->getSourcePortNumber();
+ iDstPort = iotDevAdd->getDestinationPortNumber();
+ timeOut = 0;
socket = new UDPSocket(iSrcPort);
if (socket == NULL) {
}
+ string getHostAddress() {
+ return strHostAddress;
+ }
+
+
+ int getSourcePort() {
+ return iSrcPort;
+ }
+
+
+ int getDestinationPort() {
+ return iDstPort;
+ }
+
+
+ void setTimeOut(int interval) {
+
+ timeOut = interval;
+ }
+
+
// Send data packet
void sendData(const void* buffer, int bufferLen) {
-
- unsigned short destinationPort = (unsigned short) iDstPort;
+ unsigned short destinationPort = (unsigned short) iDstPort;
socket->sendTo(buffer, bufferLen, strHostAddress, destinationPort);
}
// Receive data packet
int receiveData(void* buffer, int iMaxDataLength) {
-
unsigned short destinationPort = (unsigned short) iDstPort;
- return socket->recvFrom(buffer, iMaxDataLength, strHostAddress, destinationPort);
+ //return socket->recvFrom(buffer, iMaxDataLength, strHostAddress, destinationPort);
+ return socket->recvFrom(buffer, iMaxDataLength, strHostAddress, destinationPort, timeOut);
}
};
#endif
typedef char raw_type; // Type used for raw data on this platform
#else
#include <sys/types.h> // For data types
+ #include <sys/select.h> // For select() - non-blocking socket
#include <sys/socket.h> // For socket(), connect(), send(), and recv()
#include <netdb.h> // For gethostbyname()
#include <arpa/inet.h> // For inet_addr()
#include <errno.h> // For errno
#include <string.h> // For memset
+#include <fcntl.h> // For fcntl
using namespace std;
return rtn;
}
+int UDPSocket::recvFrom(void *buffer, int bufferLen, string &sourceAddress,
+ unsigned short &sourcePort, int timeOut) throw(SocketException) {
+
+ if(!(fcntl(sockDesc, F_GETFL) & O_NONBLOCK)) {
+ // If not non-blocking then put it into non-blocking
+ if(fcntl(sockDesc, F_SETFL, fcntl(sockDesc, F_GETFL) | O_NONBLOCK) < 0) {
+ throw SocketException("Set non-blocking failed (recvfrom())", true);
+ }
+ }
+ fd_set readFds; // FD
+ FD_ZERO(&readFds);
+ FD_SET(sockDesc, &readFds);
+ struct timeval to; // timeout
+ to.tv_sec = 0;
+ to.tv_usec = timeOut;
+ sockaddr_in clntAddr;
+ socklen_t addrLen = sizeof(clntAddr);
+
+ int rv = select(sockDesc+1 ,&readFds, NULL, NULL, &to);
+ int rtn = -1; // Assuming receive failure
+ if (rv == 1) {
+ if ((rtn = recvfrom(sockDesc, (raw_type *) buffer, bufferLen, 0,
+ (sockaddr *) &clntAddr, (socklen_t *) &addrLen)) < 0) {
+ throw SocketException("Receive failed (recvfrom())", true);
+ }
+ sourceAddress = inet_ntoa(clntAddr.sin_addr);
+ sourcePort = ntohs(clntAddr.sin_port);
+ }
+
+ return rtn;
+}
+
void UDPSocket::setMulticastTTL(unsigned char multicastTTL) throw(SocketException) {
if (setsockopt(sockDesc, IPPROTO_IP, IP_MULTICAST_TTL,
(raw_type *) &multicastTTL, sizeof(multicastTTL)) < 0) {
throw SocketException("Multicast group leave failed (setsockopt())", true);
}
}
+
+void UDPSocket::setTimeOut(int interval) throw(SocketException) {
+
+ struct timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = interval;
+ if (setsockopt(sockDesc, SOL_SOCKET, SO_RCVTIMEO, &timeout,
+ sizeof(timeout)) < 0) {
+ throw SocketException("Multicast group join failed (setsockopt())", true);
+ }
+}
*/
void setLocalPort(unsigned short localPort) throw(SocketException);
- /**
+ /** ADDED BY: Rahmadi Trimananda (rtrimana@uci.edu)
* Set the local port to the specified port and the local address
* to the specified address. If you omit the port, a random port
* will be selected.
/**
* Read read up to bufferLen bytes data from this socket. The given buffer
- * is where the data will be placed
+ * is where the data will be placed (this is a non-blocking version)
* @param buffer buffer to receive data
* @param bufferLen maximum number of bytes to receive
* @param sourceAddress address of datagram source
int recvFrom(void *buffer, int bufferLen, string &sourceAddress,
unsigned short &sourcePort) throw(SocketException);
+ /**
+ * Read read up to bufferLen bytes data from this socket. The given buffer
+ * is where the data will be placed
+ * @param buffer buffer to receive data
+ * @param bufferLen maximum number of bytes to receive
+ * @param sourceAddress address of datagram source
+ * @param sourcePort port of data source
+ * @param timeout interval
+ * @return number of bytes received and -1 for error
+ * @exception SocketException thrown if unable to receive datagram
+ */
+ int recvFrom(void *buffer, int bufferLen, string &sourceAddress,
+ unsigned short &sourcePort, int timeout) throw(SocketException);
+
/**
* Set the multicast TTL
* @param multicastTTL multicast TTL
*/
void leaveGroup(const string &multicastGroup) throw(SocketException);
+ /** ADDED BY: Rahmadi Trimananda (rtrimana@uci.edu)
+ * Set timeout for socket
+ * @param timeout interval (in milliseconds)
+ * @exception SocketException thrown if unable to set timeout
+ */
+ void setTimeOut(int interval) throw(SocketException);
+
private:
void setBroadcast();
};
// TODO: DEBUG
System.out.println("\n\nDEBUG: GET ZIGBEE DEVICE IOT SET OBJECT!!!");
- System.out.println("DEBUG: sMessage host address: " + sMessage.getHostAddress());
- System.out.println("DEBUG: sMessage source port: " + sMessage.getSourceDeviceDriverPort());
- System.out.println("DEBUG: sMessage destination port: " + sMessage.getDestinationDeviceDriverPort());
- System.out.println("DEBUG: sMessage source wild card: " + sMessage.isSourcePortWildCard());
- System.out.println("DEBUG: sMessage desination wild card: " + sMessage.isDestinationPortWildCard() + "\n\n");
+ System.out.println("DEBUG: sMessage host address: " + sMessage.getHostAddress() + "\n\n");
// Get IoTSet objects for IP address set on device driver/controller
IoTZigbeeAddress objZBDevAddress = new IoTZigbeeAddress(sMessage.getHostAddress());
// TODO: DEBUG
System.out.println("\n\nDEBUG: GET ADD IOT SET OBJECT!!!");
- System.out.println("DEBUG: sMessage host address: " + sMessage.getHostAddress() +);
+ System.out.println("DEBUG: sMessage host address: " + sMessage.getHostAddress() + "\n\n");
// Get IoTSet objects for IP address set on device driver/controller
IoTAddress objAddress = new IoTAddress(sMessage.getHostAddress());
private void invokeInitMethod() throws IOException {
// TODO: DEBUG
- System.out.println("\n\nDEBUG: INVOKE INIT METHOD!!!");
+ System.out.println("\n\nDEBUG: INVOKE INIT METHOD!!!\n\n");
new Thread() {
public void run() {