#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <poll.h> #include <telldus-core.h> int quiet=0; int tcp_listen_socket; #define MAX_LISTENERS 200 struct listener { int fd; } listeners[MAX_LISTENERS]={{0}}; void listeners_read(struct listener *listener) { char buf[200]; int n=read(listener->fd,buf,200); if (n<=0) { close(listener->fd); listener->fd=0; fprintf(stderr,"listener %p read %d = close\n",listener,n); } else fprintf(stderr,"listener %p read %d\n",listener,n); } void WINAPI sensorEvent(const char *protocol, const char *model, int sensorId, \ int dataType, const char *value, int ts, int callbackId, void *context) { char buf[200]=""; int n= snprintf(buf,199, "{\"type\":\"sensor-data\"," "\"sensorid\":%d," "\"protocol\":\"%s\"," "\"sensormodel\":\"%s\"," "\"datatype\":%d," "\"datatype_s\":\"%s\"," "\"value\":\"%s\"," "\"timestamp\":%d" "}\r\n", sensorId, protocol, model, dataType, (dataType==TELLSTICK_TEMPERATURE)?"Temperature": (dataType==TELLSTICK_HUMIDITY)?"Humidity": (dataType==TELLSTICK_RAINRATE)?"Rainrate": (dataType==TELLSTICK_RAINTOTAL)?"Raintotal": (dataType==TELLSTICK_WINDDIRECTION)?"Winddirection": (dataType==TELLSTICK_WINDAVERAGE)?"Windaverage": (dataType==TELLSTICK_WINDGUST)?"Windgust": "Unknown", value, ts); for (int i=0; i<MAX_LISTENERS; i++) if (listeners[i].fd) write(listeners[i].fd,buf,n); printf("%s",buf); } int main(int ac,char **am) { int tcpport; if (ac<2) { fprintf(stderr,"USAGE: %s <listen port>\n",am[0]); return 0; } tcpport=atoi(am[1]); /* bind local TCP port */ if ((tcp_listen_socket=socket(AF_INET, SOCK_STREAM, 0))<0) { perror("failed to open socket"); exit(1); } int one=1; if (setsockopt(tcp_listen_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(int))==-1) { perror("failed to set socket reuseable"); exit(1); } struct sockaddr_in sa; sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_ANY); sa.sin_port = htons(tcpport); if (bind(tcp_listen_socket,(struct sockaddr *)&sa,sizeof(sa))<0) { fprintf(stderr,"trying to bind to local port %d",tcpport); perror(""); exit(1); } if (listen(tcp_listen_socket,4711)) { fprintf(stderr,"trying to listen to local port %d",tcpport); perror(""); exit(1); } /* telldus */ tdInit(); //Register for callback int callbackId = 0; callbackId = tdRegisterSensorEvent( (TDSensorEvent)&sensorEvent, 0 ); /* main loop */ for (;;) { struct pollfd pfd[MAX_LISTENERS+1]; pfd[0].fd=tcp_listen_socket; pfd[0].events=POLLIN; pfd[0].revents=0; int pfds=1; for (int i=0; i<MAX_LISTENERS; i++) if (listeners[i].fd) { pfd[pfds].fd=listeners[i].fd; pfd[pfds].events=POLLIN|POLLERR|POLLHUP; pfds++; } poll(pfd,pfds,-1); if ((pfd[0].revents&POLLIN)) { struct sockaddr_in sa; socklen_t sz=sizeof(struct sockaddr_in); int fd=accept(tcp_listen_socket,(struct sockaddr*)&sa,&sz); if (fd==-1) { perror("new connection failed"); } else { int i; for (i=0; i<MAX_LISTENERS; i++) if (!listeners[i].fd) { char buf[32]="\0"; inet_ntop(AF_INET, &(sa.sin_addr), buf, 32); listeners[i].fd=fd; fprintf(stderr,"new listener %p fd %d\n",listeners+i,fd); break; } if (i==MAX_LISTENERS) close(fd); // no space } } for (int i=1; i<pfds; i++) { if ((pfd[i].revents&POLLIN)) { for (int j=0; j<MAX_LISTENERS; j++) if (listeners[j].fd==pfd[i].fd) { listeners_read(listeners+j); } } else if ((pfd[i].revents&(POLLHUP|POLLERR))) { for (int j=0; j<MAX_LISTENERS; j++) if (listeners[j].fd==pfd[i].fd) { listeners[j].fd=0; close(pfd[i].fd); fprintf(stderr,"listener %p close\n",listeners+j); } } } } tdUnregisterCallback( callbackId ); tdClose(); }