Sun, 27 Jul 2014 21:04:57 +0200
Small fix
/***************************************************************************** * Copyright (C) 2008-2014 * * Michiel Broek <mbroek at mbse dot eu> * * This file is part of the mbsePi-apps * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * mbsePi-apps is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with EC-65K; see the file COPYING. If not, write to the Free * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *****************************************************************************/ #include "rdconfig.h" #include "thermferm.h" #include "server.h" #include "xutil.h" extern int my_shutdown; extern int debug; extern char *current_unit; #ifdef HAVE_WIRINGPI_H extern int lcdHandle; extern unsigned char lcdbuf[MAX_LCDS][20][4]; #endif extern sys_config Config; extern const char UNITMODE[5][8]; extern const char UNITmode[5]; extern const char TEMPSTATE[3][8]; int s; /* connected socket */ int ls; /* listen socket */ struct sockaddr_in myaddr_in; /* for local socket address */ struct sockaddr_in peeraddr_in; /* for peer socket address */ struct hostent *hp; #define SS_BUFSIZE 1024 #define SS_TIMEOUT 300 float cs_heatEstimator = 0.2; float cs_coolEstimator = 5; float cv_beerDiff = 0.0; /* * Send message to client */ int srv_send(const char *format, ...) { char out[SS_BUFSIZE]; va_list va_ptr; if (s == -1) return -1; va_start(va_ptr, format); vsnprintf(out, SS_BUFSIZE-1, format, va_ptr); va_end(va_ptr); if (debug) { syslog(LOG_NOTICE, "send: \"%s\"", out); fprintf(stdout, "send: \"%s\"\n", out); } if (send(s, out, strlen(out), 0) != strlen(out)) { syslog(LOG_NOTICE, "srv_send failed"); return -1; } if (send(s, (char *)"\r\n", 2, 0) != 2) { syslog(LOG_NOTICE, "srv_send failed"); return -1; } return 0; } /* * ADD PROFILE name * ADD UNIT name */ int unit_add(char *buf) { units_list *unit, *tmpu; profiles_list *profile, *tmpp; uuid_t uu; char *opt, *param; opt = strtok(buf, " \0"); opt = strtok(NULL, " \0"); if (opt == NULL) { srv_send((char *)"501 Subcommand missing"); return 1; } param = strtok(NULL, "\0"); if (param == NULL) { srv_send((char *)"501 Parameter missing"); return 1; } if (debug) fprintf(stdout, "opt: '%s' param: '%s'\n", MBSE_SS(opt), MBSE_SS(param)); if (strcmp(opt, (char *)"PROFILE") == 0) { profile = (profiles_list *)malloc(sizeof(profiles_list)); profile->next = NULL; profile->version = 1; profile->uuid = malloc(37); uuid_generate(uu); uuid_unparse(uu, profile->uuid); profile->name = xstrcpy(param); profile->busy = 0; profile->steps = NULL; if (Config.profiles == NULL) { Config.profiles = profile; } else { for (tmpp = Config.profiles; tmpp; tmpp = tmpp->next) { if (tmpp->next == NULL) { tmpp->next = profile; break; } } } syslog(LOG_NOTICE, "Profile \"%s\" with uuid %s added", param, profile->uuid); srv_send((char *)"211 Profile \"%s\" with uuid %s added", param, profile->uuid); return 0; } else if (strcmp(opt, (char *)"UNIT") == 0) { unit = (units_list *)malloc(sizeof(units_list)); unit->next = NULL; unit->version = 1; unit->uuid = malloc(37); uuid_generate(uu); uuid_unparse(uu, unit->uuid); if (current_unit) free(current_unit); current_unit = xstrcpy(unit->uuid); unit->name = xstrcpy(param); unit->air_address = unit->beer_address = unit->io1_address = unit->io2_address = unit->profile = NULL; unit->volume = 0.0; unit->air_state = unit->beer_state = 1; unit->heater_available = unit->cooler_available = unit->fan_available = FALSE; unit->air_temperature = unit->beer_temperature = 20000; unit->beer_set = unit->fridge_set = 20.0; unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = unit->mode = unit->prof_state = 0; unit->temp_set_min = 1.0; unit->temp_set_max = 30.0; unit->idle_rangeH = 1.0; unit->idle_rangeL = -1.0; unit->prof_started = (time_t)0; if (Config.units == NULL) { Config.units = unit; } else { for (tmpu = Config.units; tmpu; tmpu = tmpu->next) { if (tmpu->next == NULL) { tmpu->next = unit; break; } } } syslog(LOG_NOTICE, "Unit with uuid %s added", unit->uuid); srv_send((char *)"211 Unit with uuid %s added", unit->uuid); return 0; } srv_send((char *)"502 Unknown command option"); return 1; } void delete_Profile(char *uuid) { profiles_list *current = Config.profiles; profiles_list *previous = NULL; prof_step *step, *olds; while (current) { if (strcmp(current->uuid, uuid) == 0) { if (previous == NULL) { Config.profiles = current->next; free(current->uuid); current->uuid = NULL; free(current->name); current->name = NULL; if (current->steps) { for (step = current->steps; step; step = olds) { olds = step->next; free(step); } current->steps = NULL; } free(current); return; } else { free(current->uuid); current->uuid = NULL; free(current->name); current->name = NULL; if (current->steps) { for (step = current->steps; step; step = olds) { olds = step->next; free(step); } current->steps = NULL; } previous->next = current->next; free(current); current = previous->next; return; } } else { previous = current; current = current->next; } } } /* * DEL PROFILE */ int cmd_del(char *buf) { char *opt, *param; opt = strtok(buf, " \0"); opt = strtok(NULL, " \0"); if (opt == NULL) { srv_send((char *)"501 Subcommand missing"); return 1; } param = strtok(NULL, "\0"); if (param == NULL) { srv_send((char *)"501 Parameter missing"); return 1; } if (debug) fprintf(stdout, "opt: '%s' param: '%s'\n", MBSE_SS(opt), MBSE_SS(param)); if (strcmp(opt, (char *)"PROFILE") == 0) { delete_Profile(param); srv_send((char *)"211 Profile %s deleted", param); return 0; } srv_send((char *)"502 Unknown command option"); return 1; } /* * LIST * LIST BUS * LIST LOG * LIST PROFILES * LIST UNIT */ int cmd_list(char *buf) { char *opt, *filename, *p, q[2], buffer[256]; units_list *unit; profiles_list *profile; prof_step *step; int j, ref; DIR *fd; FILE *fp; struct dirent *de; opt = strtok(buf, " \0"); opt = strtok(NULL, "\0"); if (opt == NULL) { /* * Default, list available units */ srv_send((char *)"212 Fermenter list follows:"); for (unit = Config.units; unit; unit = unit->next) { srv_send((char *)"%s,%s,%s", unit->uuid, unit->name, UNITMODE[unit->mode]); } srv_send((char *)"."); return 0; } else if (strcmp(opt, (char *)"BUS") == 0) { /* * 1-wire bus */ if ((fd = opendir((char *)"/sys/bus/w1/devices"))) { srv_send((char *)"212 1-wire bus devices:"); while ((de = readdir(fd))) { if (de->d_name[0] != '.') { ref = 0; if (strncmp(de->d_name, (char *)"w1", 2) == 0) { srv_send((char *)"%s,0,NA,System device", de->d_name); } else if (strncmp(de->d_name, (char *)"10", 2) == 0) { if (Config.air_address && (strcmp(de->d_name, Config.air_address) == 0)) ref++; for (unit = Config.units; unit; unit = unit->next) { if (unit->air_address && (strcmp(de->d_name, unit->air_address) == 0)) ref++; if (unit->beer_address && (strcmp(de->d_name, unit->beer_address) == 0)) ref++; } srv_send((char *)"%s,%d,18S20,Digital thermometer", de->d_name, ref); } else if (strncmp(de->d_name, (char *)"28", 2) == 0) { if (Config.air_address && (strcmp(de->d_name, Config.air_address) == 0)) ref++; for (unit = Config.units; unit; unit = unit->next) { if (unit->air_address && (strcmp(de->d_name, unit->air_address) == 0)) ref++; if (unit->beer_address && (strcmp(de->d_name, unit->beer_address) == 0)) ref++; } srv_send((char *)"%s,%d,18B20,Digital thermometer", de->d_name, ref); } else if (strncmp(de->d_name, (char *)"29", 2) == 0) { for (unit = Config.units; unit; unit = unit->next) { if (unit->io1_address && (strncmp((char *)"29", unit->io1_address, 2) == 0)) ref++; if (unit->io2_address && (strncmp((char *)"29", unit->io2_address, 2) == 0)) ref++; } srv_send((char *)"%s,%d,2408,8 Channel addressable switch/LCD", de->d_name, ref); } else if (strncmp(de->d_name, (char *)"3a", 2) == 0) { for (unit = Config.units; unit; unit = unit->next) { if (unit->io1_address && (strncmp((char *)"3a", unit->io1_address, 2) == 0)) ref++; if (unit->io2_address && (strncmp((char *)"3a", unit->io2_address, 2) == 0)) ref++; } srv_send((char *)"%s,%d,2413,Dual channel addressable switchs", de->d_name, ref); } else { srv_send((char *)"%s,0,NA,Unknown device", de->d_name); } } } srv_send((char *)"."); closedir(fd); return 0; } else { srv_send((char *)"503 directory /sys/bus/w1/devices: %s", strerror(errno)); return 1; } } else if (strcmp(opt, (char *)"LOG") == 0) { /* * Get the logfile data and emit only one line per hour. */ if (current_unit == NULL) { srv_send((char *)"401 No fermenter unit selected"); return 1; } q[0] = q[1] = 'a'; for (unit = Config.units; unit; unit = unit->next) { if (strcmp(current_unit, unit->uuid) == 0) break; } srv_send((char *)"212 Logfile list follows:"); if (getenv((char *)"USER") == NULL) { filename = xstrcpy((char *)"/root"); } else { filename = xstrcpy(getenv((char *)"HOME")); } filename = xstrcat(filename, (char *)"/.thermferm/log/"); filename = xstrcat(filename, unit->name); filename = xstrcat(filename, (char *)".log"); if ((fp = fopen(filename, "r"))) { while (fgets(buffer, sizeof(buffer)-1, fp) != NULL) { buffer[strlen(buffer) -1] = '\0'; p = buffer + 17; if (strncmp(p, (char *)"Mode", 4)) { if ((q[0] != buffer[11]) || (q[1] != buffer[12])) { q[0] = buffer[11]; q[1] = buffer[12]; srv_send(buffer); } } } } free(filename); filename = NULL; srv_send((char *)"."); return 0; } else if (strcmp(opt, (char *)"PROFILES") == 0) { /* * Fermenting profiles */ srv_send((char *)"212 profiles:"); for (profile = Config.profiles; profile; profile = profile->next) { j = 0; for (step = profile->steps; step; step = step->next) j++; srv_send((char *)"%s,%s,%d,%d", profile->uuid, profile->name, j, profile->busy); } srv_send((char *)"."); return 0; } else if (strcmp(opt, (char *)"UNIT") == 0) { /* * List configured and selected fermenter unit */ if (current_unit == NULL) { srv_send((char *)"401 No fermenter unit selected"); return 1; } srv_send((char *)"213 Unit %s listing follows:", current_unit); for (unit = Config.units; unit; unit = unit->next) { if (strcmp(current_unit, unit->uuid) == 0) { srv_send((char *)"NAME,%s", unit->name); srv_send((char *)"UUID,%s", unit->uuid); if (unit->air_address) { srv_send((char *)"AIR_ADDRESS,%s", unit->air_address); srv_send((char *)"AIR_STATE,%s", TEMPSTATE[unit->air_state]); srv_send((char *)"AIR_TEMPERATURE,%.3f", unit->air_temperature / 1000.0); } if (unit->beer_address) { srv_send((char *)"BEER_ADDRESS,%s", unit->beer_address); srv_send((char *)"BEER_STATE,%s", TEMPSTATE[unit->beer_state]); srv_send((char *)"BEER_TEMPERATURE,%.3f", unit->beer_temperature / 1000.0); } if (unit->io1_address) { srv_send((char *)"IO1_ADDRESS,%s", unit->io1_address); } if (unit->io2_address) { srv_send((char *)"IO2_ADDRESS,%s", unit->io2_address); } if (unit->heater_available) { srv_send((char *)"HEATER_AVAILABLE,%s", unit->heater_available); } if (unit->cooler_available) { srv_send((char *)"COOLER_AVAILABLE,%s", unit->cooler_available); } if (unit->fan_available) { srv_send((char *)"FAN_AVAILABLE,%s", unit->fan_available); } srv_send((char *)"MODE,%s", UNITMODE[unit->mode]); srv_send((char *)"FRIDGE_SET,%.1f", unit->fridge_set); srv_send((char *)"BEER_SET,%.1f", unit->beer_set); if (unit->profile) { srv_send((char *)"PROFILE,%s", unit->profile); } srv_send((char *)"TEMP_SET_MIN,%.1f", unit->temp_set_min); srv_send((char *)"TEMP_SET_MAX,%.1f", unit->temp_set_max); srv_send((char *)"IDLE_RANGE_L,%.1f", unit->idle_rangeL); srv_send((char *)"IDLE_RANGE_H,%.1f", unit->idle_rangeH); } } srv_send((char *)"."); return 0; } srv_send((char *)"502 Unknown command option"); return 1; } /* * Set new operating mode * MODE OFF|NONE|BEER|FRIDGE|PROFILE */ int cmd_mode(char *buf) { return 1; } /* * PROFILE List profile status of current unit * PROFILE uuid,name Rename profile name * PROFILE GETS uuid Get profile steps list * PROFILE PUTS uuid Put profile steps list */ int cmd_profile(char *buf) { char ibuf[SS_BUFSIZE], *sstep, *rest, *targ; int i, rlen, istep, irest; float ftarg; socklen_t fromlen; char *opt, *uuid, *param; profiles_list *profile; prof_step *step, *olds; units_list *unit; opt = strtok(buf, " \0"); opt = strtok(NULL, " \0"); if (opt == NULL) { /* * Profile status of current unit */ if (current_unit == NULL) { srv_send((char *)"401 No fermenter unit selected"); return 1; } for (unit = Config.units; unit; unit = unit->next) { if (strcmp(current_unit, unit->uuid) == 0) break; } if (unit->profile == NULL) { srv_send((char *)"441 Unit has no profile"); return 1; } if (unit->mode != UNITMODE_PROFILE) { srv_send((char *)"442 Unit is not using a profile"); return 1; } srv_send((char *)"241 Profile status follows:"); srv_send((char *)"."); return 1; } else if (strcmp(opt, (char *)"GETS") == 0) { uuid = strtok(NULL, "\0\n\r"); if (uuid == NULL) { srv_send((char *)"502 Unknown command option"); return 1; } for (profile = Config.profiles; profile; profile = profile->next) { if (strcmp(profile->uuid, uuid) == 0) { srv_send((char *)"215 Profile steps follow:"); for (step = profile->steps; step; step = step->next) { srv_send((char *)"%d,%d,%.1f", step->steptime, step->resttime, step->target); } srv_send((char *)"."); return 1; } } srv_send((char *)"440 No such profile"); return 1; } else if (strcmp(opt, (char *)"PUTS") == 0) { uuid = strtok(NULL, "\0\n\r"); if (uuid == NULL) { srv_send((char *)"502 Unknown command option"); return 1; } for (profile = Config.profiles; profile; profile = profile->next) { if (strcmp(profile->uuid, uuid) == 0) { fprintf(stdout, "profile found\n"); if (profile->steps) { for (step = profile->steps; step; step = olds) { olds = step->next; free(step); } profile->steps = NULL; } fprintf(stdout, "profile cleared\n"); while (1) { memset((char *)&ibuf, 0, SS_BUFSIZE); fromlen = sizeof(peeraddr_in); rlen = recvfrom(s, ibuf, sizeof(ibuf) -1, 0, (struct sockaddr *)&peeraddr_in, &fromlen); if (rlen == -1) { syslog(LOG_NOTICE, "recvfrom(): %s", strerror(errno)); srv_send((char *)"518 recfrom(): %s", strerror(errno)); return 1; } else { for (i = 0; i < strlen(ibuf); i++) { if (ibuf[i] == '\n') ibuf[i] = '\0'; if (ibuf[i] == '\r') ibuf[i] = '\0'; } for (i = strlen(ibuf) -1; i > 0; i--) { if (ibuf[i] == ' ') ibuf[i] = '\0'; else break; } if (strlen(ibuf)) { if (debug) { syslog(LOG_NOTICE, "recv: \"%s\"", ibuf); fprintf(stdout, "recv: \"%s\"\n", ibuf); } if (strcmp(ibuf, (char *)".") == 0) { srv_send((char *)"219 Accepted profile steps"); return 0; } sstep = strtok(ibuf, ",\0"); rest = strtok(NULL, ",\0"); targ = strtok(NULL, "\0"); if ((sscanf(sstep, "%d", &istep) == 1) && (sscanf(rest, "%d", &irest) == 1) && (sscanf(targ, "%f", &ftarg) == 1)) { step = (prof_step *)malloc(sizeof(prof_step)); step->next = NULL; step->version = 1; step->steptime = istep; step->resttime = irest; step->target = ftarg; if (profile->steps == NULL) { profile->steps = step; } else { for (olds = profile->steps; olds; olds = olds->next) { if (olds->next == NULL) { olds->next = step; break; } } } } fprintf(stdout, "this was data\n"); } } } } } srv_send((char *)"440 No such profile"); return 1; } else { /* * uuid,name rename profile */ uuid = strtok(opt, ","); param = strtok(NULL, "\0"); fprintf(stdout, "uuid: '%s' param: '%s'\n", uuid, param); for (profile = Config.profiles; profile; profile = profile->next) { if (strcmp(profile->uuid, uuid) == 0) { syslog(LOG_NOTICE, "Profile %s rename from '%s' to '%s'", uuid, profile->name, param); if (profile->name) free(profile->name); profile->name = xstrcpy(param); srv_send((char *)"240 Profile updated"); return 0; } } srv_send((char *)"440 No such profile"); return 1; } srv_send((char *)"502 Unknown command option"); return 1; } /* * SET BEER float * SET FRIDGE float * SET VOLUME float * SET IDLE_LOW float * SET IDLE_HIGH float * SET TEMP_MIN float * SET TEMP_MAX float * SET NAME string * SET PROFILE string */ int cmd_set(char *buf) { char *opt, *param; units_list *unit; profiles_list *profile; int rc; float fval; opt = strtok(buf, " \0"); opt = strtok(NULL, " \0"); if (opt == NULL) { srv_send((char *)"501 Subcommand missing"); return 1; } param = strtok(NULL, "\0"); if (param == NULL) { srv_send((char *)"501 Parameter missing"); return 1; } rc = sscanf(param, "%f", &fval); if (debug) fprintf(stdout, "opt='%s' param='%s' rc=%d fval=%.1f\n", opt, param, rc, fval); /* * Commands below need a selected unit */ if (current_unit == NULL) { srv_send((char *)"401 No fermenter unit selected"); return 1; } for (unit = Config.units; unit; unit = unit->next) { if (strcmp(current_unit, unit->uuid) == 0) break; } /* * If a valid parameter float value */ if (rc == 1) { if (strcmp(opt, (char *)"BEER") == 0) { if ((fval >= unit->temp_set_min) && (fval <= unit->temp_set_max)) { unit->beer_set = fval; srv_send((char *)"214 Unit %s BEER set to %.1f", current_unit, fval); return 0; } else { srv_send((char *)"510 New temperature not between %.1f and %.1f", unit->temp_set_min, unit->temp_set_max); return 1; } } else if (strcmp(opt, (char *)"FRIDGE") == 0) { if ((fval >= unit->temp_set_min) && (fval <= unit->temp_set_max)) { unit->fridge_set = fval; srv_send((char *)"214 Unit %s BEER set to %.1f", current_unit, fval); return 0; } else { srv_send((char *)"510 New temperature not between %.1f and %.1f", unit->temp_set_min, unit->temp_set_max); return 1; } } else if (strcmp(opt, (char *)"VOLUME") == 0) { /* * Must fit in a 2 TEU container */ if ((fval >= 0.0) && (fval <= 77020.0)) { unit->volume = fval; srv_send((char *)"214 Unit %s VOLUME set to %.1f", current_unit, fval); return 0; } else { srv_send((char *)"510 New volume not between 0 and 77020"); return 1; } } else if (strcmp(opt, (char *)"IDLE_LOW") == 0) { if ((fval >= -5.0) && (fval <= -0.1)) { unit->idle_rangeL = fval; srv_send((char *)"214 Unit %s IDLE_LOW set to %.1f", current_unit, fval); return 0; } else { srv_send((char *)"510 New value not between -5.0 and -0.1"); return 1; } } else if (strcmp(opt, (char *)"IDLE_HIGH") == 0) { if ((fval >= 0.1) && (fval <= 5.0)) { unit->idle_rangeH = fval; srv_send((char *)"214 Unit %s IDLE_HIGH set to %.1f", current_unit, fval); return 0; } else { srv_send((char *)"510 New value not between -5.0 and -0.1"); return 1; } } else if (strcmp(opt, (char *)"TEMP_MIN") == 0) { if ((fval >= -2.0) && (fval <= 35.0) && (fval < unit->temp_set_max)) { unit->temp_set_min = fval; srv_send((char *)"214 Unit %s TEMP_MIN set to %.1f", current_unit, fval); return 0; } else { srv_send((char *)"510 New value not between -2.0 and 35.0 and lower then TEMP_MAX"); return 1; } } else if (strcmp(opt, (char *)"TEMP_MAX") == 0) { if ((fval >= -2.0) && (fval <= 35.0) && (fval > unit->temp_set_min)) { unit->temp_set_max = fval; srv_send((char *)"214 Unit %s TEMP_MAX set to %.1f", current_unit, fval); return 0; } else { srv_send((char *)"510 New value not between -2.0 and 35.0 and higher then TEMP_MIN"); return 1; } } } /* * Set new unit or beer name */ if (strcmp(opt, (char *)"NAME") == 0) { if (unit->name) free(unit->name); unit->name = xstrcpy(param); srv_send((char *)"214 Unit %s NAME set to '%s'", current_unit, param); // TODO: change logfile name return 0; } else if (strcmp(opt, (char *)"PROFILE") == 0) { /* * Check for active profile, already selected etc. */ if (unit->profile && (unit->mode == UNITMODE_PROFILE)) { srv_send((char *)"541 Cannot change profile while a profile is active"); return 1; } if (unit->profile && (strcmp(unit->profile, param) == 0)) { srv_send((char *)"542 Profile already set"); return 1; } for (profile = Config.profiles; profile; profile = profile->next) { if (strcmp(profile->uuid, param) == 0) { if (unit->profile) free(unit->profile); unit->profile = xstrcpy(param); srv_send((char *)"242 Unit profile changed to %s", param); return 0; } } srv_send((char *)"543 Invalid profile"); return 1; } srv_send((char *)"502 Unknown command option"); return 1; } /* * UNIT uuid */ int cmd_unit(char *buf) { char *opt; units_list *tmp; opt = strtok(buf, " \0"); opt = strtok(NULL, " \0"); if (opt == NULL) { srv_send((char *)"501 Parameter missing"); return 1; } if (strlen(opt) == 36) { /* * Search using uuid */ for (tmp = Config.units; tmp; tmp = tmp->next) { if (strcmp(opt, tmp->uuid) == 0) { srv_send((char *)"210 Unit %s selected", tmp->uuid); if (current_unit) free(current_unit); current_unit = xstrcpy(tmp->uuid);; return 0; } } srv_send((char *)"410 No such unit"); return 1; } srv_send((char *)"502 Unknown command option"); return 1; } void cmd_server(void) { char buf[SS_BUFSIZE]; int i, rlen; socklen_t fromlen; #ifdef HAVE_WIRINGPI_H int j; char obuf[SS_BUFSIZE]; #endif memset((char *)&buf, 0, SS_BUFSIZE); fromlen = sizeof(peeraddr_in); rlen = recvfrom(s, buf, sizeof(buf) -1, 0, (struct sockaddr *)&peeraddr_in, &fromlen); if (rlen == -1) { syslog(LOG_NOTICE, "recvfrom(): %s", strerror(errno)); } else { for (i = 0; i < strlen(buf); i++) { if (buf[i] == '\n') buf[i] = '\0'; if (buf[i] == '\r') buf[i] = '\0'; } for (i = strlen(buf) -1; i > 0; i--) { if (buf[i] == ' ') buf[i] = '\0'; else break; } if (strlen(buf)) { if (debug) { syslog(LOG_NOTICE, "recv: \"%s\"", buf); fprintf(stdout, "recv: \"%s\"\n", buf); } /* * Process commands from the client */ if (strncmp(buf, "ADD", 3) == 0) { if (unit_add(buf) == 0) wrconfig(); } else if (strncmp(buf, "DEL", 3) == 0) { if (cmd_del(buf) == 0) wrconfig(); } else if (strncmp(buf, "HELP", 4) == 0) { srv_send((char *)"100 Help text follows"); srv_send((char *)"Recognized commands:"); srv_send((char *)""); // 12345678901234567890123456789012345678901234567890123456789012345678901234567890 srv_send((char *)"ADD PROFILE name Add a new profile with \"name\""); srv_send((char *)"ADD UNIT name Add a new unit with \"name\""); srv_send((char *)"DEL PROFILE uuid Delete profile with uuid"); // srv_send((char *)"DEL UNIT uuid Delete unit with uuid"); srv_send((char *)"LCD Get LCD screen (allways 4 rows of 20 characters)"); srv_send((char *)"LIST List all fermenter units"); srv_send((char *)"LIST BUS List 1-wire bus"); srv_send((char *)"LIST LOG List logfile data in 1 hour lines"); srv_send((char *)"LIST PROFILES List available profiles"); srv_send((char *)"LIST UNIT List fermenter unit"); srv_send((char *)"MODE OFF|NONE|BEER|FRIDGE|PROFILE"); // srv_send((char *)"PROFILE Profile status of current unit"); srv_send((char *)"PROFILE uuid,name Profile rename"); srv_send((char *)"PROFILE GETS uuid Profile get steps list"); srv_send((char *)"PROFILE PUTS uuid Profile put steps list"); srv_send((char *)"SET BEER val Set beer temperature"); srv_send((char *)"SET FRIDGE val Set fridge temperature"); srv_send((char *)"SET IDLE_LOW val Set idle temperature low (-5.0 .. -0.1)"); srv_send((char *)"SET IDLE_HIGH val Set idle temperature high (0.1 .. 5.0)"); srv_send((char *)"SET NAME name Set name or beername for the unit"); srv_send((char *)"SET PROFILE uuid Set unit profile"); // srv_send((char *)"SET PROFILE start|stop|pause Profile start, stop or pause"); srv_send((char *)"SET TEMP_MIN val Set unit minimum temperature"); srv_send((char *)"SET TEMP_MAX val Set unit maximum temperature"); srv_send((char *)"SET VOLUME val Set unit volume"); srv_send((char *)"UNIT uuid Select unit by uuid"); srv_send((char *)"."); } else if (strncmp(buf, "LCD", 3) == 0) { #ifdef HAVE_WIRINGPI_H srv_send((char *)"201 information follows"); for (j = 0; j < 4; j++) { sprintf(obuf, " "); obuf[20] = '\0'; for (i = 0; i < 20; i++) obuf[i] = lcdbuf[lcdHandle][i][j]; srv_send(obuf); } srv_send((char *)"."); #else srv_send((char *)"403 LCD not available"); #endif } else if (strncmp(buf, "LIST", 4) == 0) { cmd_list(buf); } else if (strncmp(buf, "MODE", 4) == 0) { cmd_mode(buf); } else if (strncmp(buf, "PROFILE", 7) == 0) { if (cmd_profile(buf) == 0) wrconfig(); } else if (strncmp(buf, "SET", 3) == 0) { if (cmd_set(buf) == 0) wrconfig(); } else if (strncmp(buf, "UNIT", 4) == 0) { cmd_unit(buf); } else { if (debug) fprintf(stdout, "unknown command \"%s\"\n", buf); srv_send((char *)"500 Unknown command"); } } } close(s); } #ifdef HAVE_WIRINGPI_H PI_THREAD (my_server_loop) #else void *my_server_loop(void *threadid) #endif { socklen_t addrlen; int optval = 1; syslog(LOG_NOTICE, "Thread my_server_loop started"); if (debug) fprintf(stdout, "Thread my_server_loop started\n"); memset((char *)&myaddr_in, 0, sizeof(struct sockaddr_in)); memset((char *)&peeraddr_in, 0, sizeof(struct sockaddr_in)); myaddr_in.sin_family = AF_INET; myaddr_in.sin_addr.s_addr = INADDR_ANY; myaddr_in.sin_port = htons(Config.my_port); ls = socket(AF_INET, SOCK_STREAM, 0); if (ls == -1) { syslog(LOG_NOTICE, "Can't create listen socket: %s", strerror(errno)); fprintf(stderr, "Can't create listen socket: %s\n", strerror(errno)); return 0; } if (setsockopt(ls, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) == -1) { syslog(LOG_NOTICE, "Can't setsockopt SO_KEEPALIVE socket: %s", strerror(errno)); close(ls); return 0; } if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) { syslog(LOG_NOTICE, "Can't setsockopt SO_REUSEADDR socket: %s", strerror(errno)); close(ls); return 0; } if (bind(ls, (struct sockaddr *)&myaddr_in, sizeof(struct sockaddr_in)) == -1) { syslog(LOG_NOTICE, "Can't bind to listen socket: %s", strerror(errno)); close(ls); return 0; } if (listen(ls, 5) == -1) { syslog(LOG_NOTICE, "Can't listen on listen socket: %s", strerror(errno)); close(ls); return 0; } syslog(LOG_NOTICE, "listen socket created %d", ls); if (debug) fprintf(stdout, "listen socket created %d\n", ls); /* * Loop forever until the external shutdown variable is set. */ for (;;) { addrlen = sizeof(struct sockaddr_in); /* * This call will block until a new connection * arrives. Then it will return the address of * the connecting peer, and a new socket * descriptor, s, for that connection. */ s = accept(ls, (struct sockaddr *)&peeraddr_in, &addrlen); if (s == -1) { syslog(LOG_NOTICE, "my_server_loop accept failed %s", strerror(errno)); if (debug) fprintf(stdout, "my_server_loop accept failed %s\n", strerror(errno)); return 0; } cmd_server(); if (my_shutdown) { syslog(LOG_NOTICE, "Thread my_server_loop stopped"); if (debug) fprintf(stdout, "Thread my_server_loop stopped\n"); return 0; } } }