Skip to content

Commit

Permalink
Added basic option/implementation for a WiFi bridge
Browse files Browse the repository at this point in the history
  • Loading branch information
bakkerr committed Aug 23, 2015
1 parent 2255958 commit e19e62d
Showing 1 changed file with 280 additions and 9 deletions.
289 changes: 280 additions & 9 deletions openmilight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
#include <stdio.h>

#include <sys/time.h>
#include <sys/select.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;

Expand Down Expand Up @@ -132,7 +134,7 @@ void strobe(uint8_t prefix, uint8_t rem_p, uint8_t remote, uint8_t bright, uint8
}
}

void udp()
void udp_raw()
{
int sockfd;
struct sockaddr_in servaddr, cliaddr;
Expand All @@ -152,22 +154,281 @@ void udp()

mesg[n] = '\0';

if(n == 7){
if(n == 8){
if(debug){
printf("UDP --> Received hex value\n");
}
uint8_t data[7];
for(int i = 0; i < 7; i++){
uint8_t data[8];
for(int i = 0; i < 8; i++){
data[i] = (uint8_t)mesg[i];
}
send(data);
}
else {
fprintf(stderr, "Message has invalid size %d (expecting 7)!\n", n);
fprintf(stderr, "Message has invalid size %d (expecting 8)!\n", n);
}
}
}

void udp_milight(uint16_t remote)
{
fd_set socks;
int discover_fd, data_fd;
struct sockaddr_in discover_addr, data_addr, cliaddr;
char mesg[42];

int disco = -1;

uint8_t data[8];
data[0] = 0xB8;
data[1] = (remote >> 8) & 0xFF;
data[2] = remote & 0xFF;
data[3] = 0x00;
data[4] = 0x00;
data[5] = 0x00;
data[6] = 0x01;
data[7] = 0x09;

discover_fd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&discover_addr, sizeof(discover_addr));
discover_addr.sin_family = AF_INET;
discover_addr.sin_addr.s_addr = htonl(INADDR_ANY);
discover_addr.sin_port = htons(48899);
bind(discover_fd, (struct sockaddr *)&discover_addr, sizeof(discover_addr));

data_fd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&data_addr, sizeof(data_addr));
data_addr.sin_family = AF_INET;
data_addr.sin_addr.s_addr = htonl(INADDR_ANY);
data_addr.sin_port = htons(8899);
bind(data_fd, (struct sockaddr *)&data_addr, sizeof(data_addr));

printf("%d - %d (%d)\n", discover_fd, data_fd, FD_SETSIZE);

while(1){
socklen_t len = sizeof(cliaddr);

FD_ZERO(&socks);
FD_SET(discover_fd, &socks);
FD_SET(data_fd, &socks);

if(select(FD_SETSIZE, &socks, NULL, NULL, NULL) >= 0){

if(FD_ISSET(discover_fd, &socks)){
int n = recvfrom(discover_fd, mesg, 41, 0, (struct sockaddr *)&cliaddr, &len);
mesg[n] = '\0';

if(debug){
char str[INET_ADDRSTRLEN];
long ip = cliaddr.sin_addr.s_addr;
inet_ntop(AF_INET, &ip, str, INET_ADDRSTRLEN);
printf("UDP --> Received discovery request (%s) from %s\n", mesg, str);
}

char str[INET_ADDRSTRLEN];
long ip = discover_addr.sin_addr.s_addr;
inet_ntop(AF_INET, &ip, str, INET_ADDRSTRLEN);
printf("my ip : %s\n", str);


//if(!strncmp(mesg, "Link_Wi-Fi",)
}

if(FD_ISSET(data_fd, &socks)){
int n = recvfrom(data_fd, mesg, 41, 0, (struct sockaddr *)&cliaddr, &len);

mesg[n] = '\0';


if(n == 2 || n == 3){
if(debug){
printf("UDP --> Received hex value (%02x, %02x, %02x)\n", mesg[0], mesg[1], mesg[2]);
}

data[0] = 0xB8;

switch(mesg[0]){
/* Color */
case 0x40:
disco = -1;
data[5] = 0x0F;
data[3] = (0xC8 - mesg[1] + 0x100) & 0xFF;
data[0] = 0xB0;
break;
/* All Off */
case 0x41:
data[5] = 0x02;
if(disco > 0){
data[0] = 0xB0 + disco;
}
break;
/* All On */
case 0x42:
data[4] = (data[4] & 0xF8);
data[5] = 0x01;
if(disco > 0){
data[0] = 0xB0 + disco;
}
break;
/* Disco slower */
case 0x43:
data[5] = 0x0C;
if(disco > 0){
data[0] = 0xB0 + disco;
}
break;
/* Disco faster */
case 0x44:
data[5] = 0x0B;
if(disco > 0){
data[0] = 0xB0 + disco;
}
break;
/* Z1 On */
case 0x45:
data[4] = (data[4] & 0xF8) | 0x01;
data[5] = 0x03;
if(disco > 0){
data[0] = 0xB0 + disco;
}
break;
/* Z1 Off */
case 0x46:
data[5] = 0x04;
if(disco > 0){
data[0] = 0xB0 + disco;
}
break;
/* Z2 On */
case 0x47:
data[4] = (data[4] & 0xF8) | 0x02;
data[5] = 0x05;
if(disco > 0){
data[0] = 0xB0 + disco;
}
break;
/* Z2 Off */
case 0x48:
data[5] = 0x06;
if(disco > 0){
data[0] = 0xB0 + disco;
}
break;
/* Z3 On */
case 0x49:
data[4] = (data[4] & 0xF8) | 0x03;
data[5] = 0x07;
if(disco > 0){
data[0] = 0xB0 + disco;
}
break;
/* Z3 Off */
case 0x4A:
data[5] = 0x08;
if(disco > 0){
data[0] = 0xB0 + disco;
}
break;
/* Z4 On */
case 0x4B:
data[4] = (data[4] & 0xF8) | 0x04;
data[5] = 0x09;
if(disco > 0){
data[0] = 0xB0 + disco;
}
break;
/* Z4 Off */
case 0x4C:
data[5] = 0x0A;
if(disco > 0){
data[0] = 0xB0 + disco;
}
break;
/* Disco */
case 0x4D:
disco = (disco + 1) % 9;
data[0] = 0xB0 + disco;
data[5] = 0x0D;
break;
/* Brightness */
case 0x4E:
data[5] = 0x0E;
data[4] = ((0x90 - (mesg[1] * 8) + 0x100) & 0xFF) | (data[4] & 0x07);
if(disco > 0){
data[0] = 0xB0 + disco;
}
break;
/* All White */
case 0xC2:
disco = -1;
data[5] = 0x11;
break;
/* Z1 White. */
case 0xC5:
disco = -1;
data[5] = 0x13;
break;
/* Z2 White. */
case 0xC7:
disco = -1;
data[5] = 0x15;
break;
/* Z3 White. */
case 0xC9:
disco = -1;
data[5] = 0x17;
break;
/* Z4 White. */
case 0xCB:
disco = -1;
data[5] = 0x19;
break;
/* All Night */
case 0xC1:
disco = -1;
data[5] = 0x12;
break;
/* Z1 Night */
case 0xC6:
disco = -1;
data[5] = 0x14;
break;
/* Z2 Night */
case 0xC8:
disco = -1;
data[5] = 0x16;
break;
/* Z3 Night */
case 0xCA:
disco = -1;
data[5] = 0x18;
break;
/* Z4 Night */
case 0xCC:
disco = -1;
data[5] = 0x1A;
break;
default:
fprintf(stderr, "Unknown command %02x!\n", mesg[0]);
continue;
} /* End case command */

/* Send command */
send(data);
data[6]++;
}
else {
fprintf(stderr, "Message has invalid size %d (expecting 2 or 3)!\n", n);
} /* End message size check */

} /* End handling data */

} /* End select */

} /* While (1) */

}

void usage(const char *arg, const char *options){
printf("\n");
printf("Usage: sudo %s [%s]\n", arg, options);
Expand All @@ -177,7 +438,8 @@ void usage(const char *arg, const char *options){
printf(" -f Fade mode\n");
printf(" -s Strobe mode\n");
printf(" -l Listening (receiving) mode\n");
printf(" -u UDP mode\n");
printf(" -u UDP mode (raw)\n");
printf(" -m UDP mode (milight)\n");
printf(" -n NN<dec> Resends of the same message\n");
printf(" -p PP<hex> Prefix value (Disco Mode)\n");
printf(" -q RR<hex> First byte of the remote\n");
Expand All @@ -199,6 +461,7 @@ int main(int argc, char** argv)
{
int do_receive = 0;
int do_udp = 0;
int do_milight = 0;
int do_strobe = 0;
int do_fade = 0;
int do_command = 0;
Expand All @@ -218,7 +481,7 @@ int main(int argc, char** argv)

uint64_t tmp;

const char *options = "hdfslun:p:q:r:c:b:k:v:w:";
const char *options = "hdfslumn:p:q:r:c:b:k:v:w:";

while((c = getopt(argc, argv, options)) != -1){
switch(c){
Expand All @@ -241,6 +504,9 @@ int main(int argc, char** argv)
case 'u':
do_udp = 1;
break;
case 'm':
do_milight = 1;
break;
case 'n':
tmp = strtoll(optarg, NULL, 10);
resends = (uint8_t)tmp;
Expand Down Expand Up @@ -311,10 +577,15 @@ int main(int argc, char** argv)
}

if(do_udp){
printf("UDP mode, press Ctrl-C to end\n");
udp();
printf("UDP mode (raw), press Ctrl-C to end\n");
udp_raw();
}

if(do_milight){
printf("UDP mode (milight), press Ctrl-C to end\n");
udp_milight(0x0044);
}

if(do_fade){
printf("Fade mode, press Ctrl-C to end\n");
fade(prefix, rem_p, remote, color, bright, resends);
Expand Down

0 comments on commit e19e62d

Please sign in to comment.