#include <stdio.h> #include <string.h> //strlen #include <stdlib.h> #include <errno.h> #include <unistd.h> //close #include <arpa/inet.h> //close #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <sys/time.h> //FD_SET, FD_ISSET, FD_ZERO macros #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <time.h> #define TRUE 1 #define FALSE 0 #define PORT 8888 #define IN 0 #define OUT 1 #define LOW 0 #define HIGH 1 #define POUT 17 #define PIN1 24 #define POUT1 23 #define BTNOUT 21 #define BTN 20 #define VALUE_MAX 45 #define BUFFER_MAX 45 #define DIRECTION_MAX 45 #define LED 0 static int PWMExport(int pwmnum) { char buffer[BUFFER_MAX]; int bytes_written; int fd; fd = open("/sys/class/pwm/pwmchip0/unexport", O_WRONLY); if (-1 == fd) { fprintf(stderr, "Failed to open in unexport!\n"); return -1; } bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pwmnum); write(fd, buffer, bytes_written); close(fd); sleep(1); fd = open("/sys/class/pwm/pwmchip0/export", O_WRONLY); if (-1 == fd) { fprintf(stderr, "Failed to open in export!\n"); return -1; } bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pwmnum); write(fd, buffer, bytes_written); close(fd); sleep(1); return 0; } static int PWMEnable(int pwmnum) { static const char s_unenable_str[] = "0"; static const char s_enable_str[] = "1"; char path[DIRECTION_MAX]; int fd; snprintf(path, DIRECTION_MAX, "/sys/class/pwm/pwmchip0/pwm%d/enable", pwmnum); fd = open(path, O_WRONLY); if (-1 == fd) { fprintf(stderr, "Failed to open in enable!\n"); return -1; } write(fd, s_unenable_str, strlen(s_unenable_str)); close(fd); fd = open(path, O_WRONLY); if (-1 == fd) { fprintf(stderr, "Failed to open in enable!\n"); return -1; } write(fd, s_enable_str, strlen(s_enable_str)); close(fd); return 0; } static int PWMWritePeriod(int pwmnum, int value) { char s_values_str[VALUE_MAX]; char path[VALUE_MAX]; int fd, byte; snprintf(path, VALUE_MAX, "/sys/class/pwm/pwmchip0/pwm%d/period", pwmnum); fd = open(path, O_WRONLY); if (-1 == fd) { fprintf(stderr, "Faild to open in period!\n"); return -1; } byte = snprintf(s_values_str, VALUE_MAX, "%d", value); //fprintf(stderr, "byte: %s\n", s_values_str); if (-1 == write(fd, s_values_str, byte)) { fprintf(stderr, "Failed to write value in period\n"); close(fd); return -1; } close(fd); return 0; } static int PWMWriteDutyCycle(int pwmnum, int value) { char s_values_str[VALUE_MAX]; char path[VALUE_MAX]; int fd, byte; #define VALUE_MAX 45 snprintf(path, VALUE_MAX, "/sys/class/pwm/pwmchip0/pwm%d/duty_cycle", pwmnum); fd = open(path, O_WRONLY); if (-1 == fd) { fprintf(stderr, "Faild to open in duty_cycle!\n"); return -1; } byte = snprintf(s_values_str, VALUE_MAX, "%d", value); //fprintf(stderr, "byte: %s\n", s_values_str); if (-1 == write(fd, s_values_str, byte)) { fprintf(stderr, "Failed to write value in duty_cycle\n"); close(fd); return -1; } close(fd); return 0; } static int GPIOExport(int pin) { char buffer[BUFFER_MAX]; ssize_t bytes_written; int fd; fd = open("/sys/class/gpio/export", O_WRONLY); if (-1 == fd) { fprintf(stderr, "Failed to open export for writing!\n"); return(-1); } bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pin); write(fd, buffer, bytes_written); close(fd); return(0); } static int GPIODirection(int pin, int dir) { static const char s_directions_str[] = "in\0out"; char path[DIRECTION_MAX] = "/sys/class/gpio/gpio%d/direction"; int fd; snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction", pin); fd = open(path, O_WRONLY); if (-1 == fd) { //fprintf(stderr, "failed to open gpio direction for writing!, pin: %d\n", pin); return(-1); } if (-1 == write(fd, &s_directions_str[IN == dir ? 0 : 3], IN == dir ? 2 : 3)) { fprintf(stderr, "Failed to set direction!\n"); close(fd); return(-1); } close(fd); return 0; } static int GPIOWrite(int pin, int value) { static const char s_values_str[] = "01"; char path[VALUE_MAX]; int fd; snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin); fd = open(path, O_WRONLY); if (-1 == fd) { fprintf(stderr, "Failed to open gpio value for writing!\n"); return(-1); } if (1 != write(fd, &s_values_str[LOW == value ? 0 : 1], 1)) { fprintf(stderr, "Failed to write value!\n"); close(fd); return(-1); } close(fd); return(0); } static int GPIORead(int pin) { char path[VALUE_MAX]; char value_str[3]; int fd; snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin); //fprintf(stderr,path); fd = open(path, O_RDONLY); if (-1 == fd) { fprintf(stderr, "Failed to open gpio value for reading!\n"); return(-1); } if (-1 == read(fd, value_str, 3)) { fprintf(stderr, "Failed to read value!\n"); close(fd); return(-1); } close(fd); return(atoi(value_str)); } static int GPIOUnexport(int pin) { char buffer[BUFFER_MAX]; ssize_t bytes_written; int fd; fd = open("/sys/class/gpio/unexport", O_WRONLY); if (-1 == fd) { fprintf(stderr, "Failed to open unexport for writing!\n"); return (-1); } bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pin); write(fd, buffer, bytes_written); close(fd); return (0); } void error_handling( char *message){ fputs(message,stderr); fputc( '\n',stderr); exit(1); } static void initLED(int pwmnum) { PWMExport(pwmnum); PWMWritePeriod(pwmnum,20000000); PWMWriteDutyCycle(pwmnum,0); PWMEnable(pwmnum); } static void TurnOnLed(int pwmbtnnum, int bright) { PWMWriteDutyCycle(pwmbtnnum, bright); } int opt = TRUE; int master_socket , addrlen , new_socket , client_socket[30] , max_clients = 30 , activity, i , valread , sd; int max_sd; struct sockaddr_in address; char buffer[1025]; //data buffer of 1K int bright; void setLED() { if(sizeof(buffer) > 1 && buffer[1] >= '0') bright = (buffer[1] - '0') * 750000; if(bright > 1400000) bright = 0; TurnOnLed(LED, bright); printf("led bright: %d\n",bright); } void broadcast(char* buffer, int valread) { for (i = 0; i < max_clients; i++){ sd = client_socket[i]; buffer[valread] = '\0'; send(sd , buffer , strlen(buffer) , 0 ); } } void receiveCallback(int sd, char* buffer, int valread) { if(buffer[0] == '1'){ printf("broadcast: %s\n",buffer); broadcast(buffer,valread); setLED(); } if(buffer[0] == '4'){ char disStr[15] = {0,}; for(int i = 1; i < 15; i++) disStr[i-1] = buffer[i]; int dis = atoi(disStr); printf("distance: %d\n",dis); if(dis > 5) { TurnOnLed(LED, 1300000); broadcast(buffer,valread); } else{ TurnOnLed(LED, 0); } } if(buffer[0] == '5'){ broadcast(buffer,valread); setLED(); } } int main(int argc , char *argv[]) { initLED(LED); GPIOExport(5); GPIODirection(5,OUT); GPIOWrite(5,1); //set of socket descriptors fd_set readfds; //a message char *message = "ECHO Daemon v1.0 \r\n"; //initialise all client_socket[] to 0 so not checked for (i = 0; i < max_clients; i++) { client_socket[i] = 0; } //create a master socket if( (master_socket = socket(AF_INET , SOCK_STREAM , 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } //set master socket to allow multiple connections , //this is just a good habit, it will work without this if( setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 ) { perror("setsockopt"); exit(EXIT_FAILURE); } //type of socket created address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons( PORT ); //bind the socket to localhost port 8888 if (bind(master_socket, (struct sockaddr *)&address, sizeof(address))<0) { perror("bind failed"); exit(EXIT_FAILURE); } printf("Listener on port %d \n", PORT); //try to specify maximum of 3 pending connections for the master socket if (listen(master_socket, 3) < 0) { perror("listen"); exit(EXIT_FAILURE); } //accept the incoming connection addrlen = sizeof(address); puts("Waiting for connections ..."); while(TRUE) { //clear the socket set FD_ZERO(&readfds); //add master socket to set FD_SET(master_socket, &readfds); max_sd = master_socket; //add child sockets to set for ( i = 0 ; i < max_clients ; i++) { //socket descriptor sd = client_socket[i]; //if valid socket descriptor then add to read list if(sd > 0) FD_SET( sd , &readfds); //highest file descriptor number, need it for the select function if(sd > max_sd) max_sd = sd; } //wait for an activity on one of the sockets , timeout is NULL , //so wait indefinitely activity = select( max_sd + 1 , &readfds , NULL , NULL , NULL); if ((activity < 0) && (errno!=EINTR)) { printf("select error"); } //If something happened on the master socket , //then its an incoming connection if (FD_ISSET(master_socket, &readfds)) { if ((new_socket = accept(master_socket, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) { perror("accept"); exit(EXIT_FAILURE); } //inform user of socket number - used in send and receive commands printf("New connection , socket fd is %d , ip is : %s , port : %d\n" , new_socket , inet_ntoa(address.sin_addr) , ntohs(address.sin_port)); //send new connection greeting message if( send(new_socket, message, strlen(message), 0) != strlen(message) ) { perror("send"); } puts("Welcome message sent successfully"); //add new socket to array of sockets for (i = 0; i < max_clients; i++) { //if position is empty if( client_socket[i] == 0 ) { client_socket[i] = new_socket; printf("Adding to list of sockets as %d\n" , i); break; } } } //else its some IO operation on some other socket for (i = 0; i < max_clients; i++) { sd = client_socket[i]; if (FD_ISSET( sd , &readfds)) { //Check if it was for closing , and also read the //incoming message if ((valread = read( sd , buffer, 1024)) == 0) { getpeername(sd , (struct sockaddr*)&address , \ (socklen_t*)&addrlen); printf("Host disconnected , ip %s , port %d \n" , inet_ntoa(address.sin_addr) , ntohs(address.sin_port)); close( sd ); client_socket[i] = 0; } else { receiveCallback(sd, buffer, valread); } } } } return 0; }