thermferm/server.c

changeset 44
f37d73940699
parent 43
24e731bb2e08
child 45
053c4657105f
equal deleted inserted replaced
43:24e731bb2e08 44:f37d73940699
42 42
43 #define SS_BUFSIZE 1024 43 #define SS_BUFSIZE 1024
44 #define SS_TIMEOUT 300 44 #define SS_TIMEOUT 300
45 45
46 46
47 char *exe_cmd(char *);
48
49
50 char *exe_cmd(char *cmd)
51 {
52 static char obuf[1024];
53 int i;
54
55 if (strncmp(cmd, "lcd", 3) == 0) {
56 for (i = 0; i < 20; i++) {
57 obuf[i] = lcdbuf[lcdHandle][i][0];
58 obuf[i+20] = lcdbuf[lcdHandle][i][1];
59 obuf[i+40] = lcdbuf[lcdHandle][i][2];
60 obuf[i+60] = lcdbuf[lcdHandle][i][3];
61 }
62 obuf[80] = '\0';
63 return obuf;
64 }
65
66 return (char *)"ERROR";
67 }
68
69
70
71 int server_init(void)
72 {
73 int optval = 1;
74
75 memset((char *)&myaddr_in, 0, sizeof(struct sockaddr_in));
76 memset((char *)&peeraddr_in, 0, sizeof(struct sockaddr_in));
77 myaddr_in.sin_family = AF_INET;
78 myaddr_in.sin_addr.s_addr = INADDR_ANY;
79 myaddr_in.sin_port = htons(Config.my_port);
80
81 ls = socket(AF_INET, SOCK_STREAM, 0);
82 if (ls == -1) {
83 syslog(LOG_NOTICE, "Can't create listen socket: %s", strerror(errno));
84 fprintf(stderr, "Can't create listen socket: %s\n", strerror(errno));
85 return 1;
86 }
87
88 if (setsockopt(ls, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) == -1) {
89 syslog(LOG_NOTICE, "Can't setsockopt SO_KEEPALIVE socket: %s", strerror(errno));
90 close(ls);
91 return 1;
92 }
93
94 if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) {
95 syslog(LOG_NOTICE, "Can't setsockopt SO_REUSEADDR socket: %s", strerror(errno));
96 close(ls);
97 return 1;
98 }
99
100 if (bind(ls, (struct sockaddr *)&myaddr_in, sizeof(struct sockaddr_in)) == -1) {
101 syslog(LOG_NOTICE, "Can't bind to listen socket: %s", strerror(errno));
102 close(ls);
103 return 1;
104 }
105
106 syslog(LOG_NOTICE, "listen socket created %d", ls);
107 if (debug)
108 fprintf(stdout, "listen socket created %d\n", ls);
109
110
111 return 0;
112 }
113
114
115
116 /* 47 /*
117 * Send message to client 48 * Send message to client
118 */ 49 */
119 int srv_send(const char *format, ...) 50 int srv_send(const char *format, ...)
120 { 51 {
126 57
127 va_start(va_ptr, format); 58 va_start(va_ptr, format);
128 vsnprintf(out, SS_BUFSIZE-1, format, va_ptr); 59 vsnprintf(out, SS_BUFSIZE-1, format, va_ptr);
129 va_end(va_ptr); 60 va_end(va_ptr);
130 61
62 syslog(LOG_NOTICE, "send: \"%s\"", out);
63
131 if (send(s, out, strlen(out), 0) != strlen(out)) { 64 if (send(s, out, strlen(out), 0) != strlen(out)) {
132 syslog(LOG_NOTICE, "srv_send failed"); 65 syslog(LOG_NOTICE, "srv_send failed");
133 return -1; 66 return -1;
134 } 67 }
135 68
136 if (send(s, (char *)"\r\n", 2, 0) != 2) { 69 if (send(s, (char *)"\r\n", 2, 0) != 2) {
137 syslog(LOG_NOTICE, "srv_send failed"); 70 syslog(LOG_NOTICE, "srv_send failed");
138 return -1; 71 return -1;
139 } 72 }
140 73
141 syslog(LOG_NOTICE, "send: \"%s\"", out);
142 return 0; 74 return 0;
143 } 75 }
144 76
145 77
146 78
153 85
154 86
155 87
156 void cmd_server(void) 88 void cmd_server(void)
157 { 89 {
158 char *hostname, buf[SS_BUFSIZE]; 90 char *hostname, buf[SS_BUFSIZE], obuf[SS_BUFSIZE];
159 int i, rc, rlen, timer; 91 int i, rc, rlen, timer;
160 socklen_t fromlen; 92 socklen_t fromlen;
161 struct pollfd pfd[1]; 93 struct pollfd pfd[1];
162 94
163 /* 95 /*
181 hostname = hp->h_name; 113 hostname = hp->h_name;
182 } 114 }
183 115
184 clients++; 116 clients++;
185 syslog(LOG_NOTICE, "Start new client connection (%d) from %s port %u", clients, hostname, ntohs(peeraddr_in.sin_port)); 117 syslog(LOG_NOTICE, "Start new client connection (%d) from %s port %u", clients, hostname, ntohs(peeraddr_in.sin_port));
118 if (debug)
119 fprintf(stdout, "Start new client connection (%d) from %s port %u\n", clients, hostname, ntohs(peeraddr_in.sin_port));
186 timer = SS_TIMEOUT * 4; 120 timer = SS_TIMEOUT * 4;
187 121
188 /* 122 /*
189 * Receive loop 123 * Receive loop
190 */ 124 */
221 timer = SS_TIMEOUT * 4; 155 timer = SS_TIMEOUT * 4;
222 if (strlen(buf)) { 156 if (strlen(buf)) {
223 syslog(LOG_NOTICE, "recv: \"%s\"", buf); 157 syslog(LOG_NOTICE, "recv: \"%s\"", buf);
224 158
225 /* 159 /*
226 * Process command from the client 160 * Process commands from the client
227 */ 161 */
228 srv_send(exe_cmd(buf)); 162 if (strncmp(buf, "ack", 3) == 0) {
163 srv_send((char *)"ack");
164 } else if (strncmp(buf, "lcd", 3) == 0) {
165 for (i = 0; i < 20; i++) {
166 obuf[i] = lcdbuf[lcdHandle][i][0];
167 obuf[i+21] = lcdbuf[lcdHandle][i][1];
168 obuf[i+42] = lcdbuf[lcdHandle][i][2];
169 obuf[i+63] = lcdbuf[lcdHandle][i][3];
170 }
171 obuf[20] = obuf[41] = obuf[62] = ',';
172 obuf[83] = '\0';
173 srv_send(obuf);
174 } else if (strncmp(buf, "getMode", 7) == 0) {
175 srv_send("b");
176 } else if (strncmp(buf, "getControlSettings", 18) == 0) {
177 srv_send("mode='b', beerSet=20.0, fridgeSet=20.0, heatEstimator=0.2, coolEstimator=5");
178 } else {
179 if (debug)
180 fprintf(stdout, "unknown command \"%s\"\n", buf);
181 srv_send((char *)"ERR");
182 }
183 break;
229 } 184 }
230 } 185 }
231 } else { 186 } else {
232 syslog(LOG_NOTICE, "poll other event"); 187 syslog(LOG_NOTICE, "poll other event");
233 } 188 }
245 if (my_shutdown) { 200 if (my_shutdown) {
246 break; 201 break;
247 } 202 }
248 } 203 }
249 } 204 }
205
206 if (clients)
207 clients--;
208 syslog(LOG_NOTICE, "End connection from %s port %u", hostname, ntohs(peeraddr_in.sin_port));
209 if (debug)
210 fprintf(stdout, "End connection from %s port %u\n", hostname, ntohs(peeraddr_in.sin_port));
211 close(s);
250 } 212 }
251 213
252 214
253 215
254 PI_THREAD (my_server_loop) 216 PI_THREAD (my_server_loop)
255 { 217 {
256 socklen_t addrlen; 218 socklen_t addrlen;
219 int optval = 1;
257 220
258 syslog(LOG_NOTICE, "Thread my_server_loop started"); 221 syslog(LOG_NOTICE, "Thread my_server_loop started");
259 if (debug) 222 if (debug)
260 fprintf(stdout, "Thread my_server_loop started\n"); 223 fprintf(stdout, "Thread my_server_loop started\n");
224
225 memset((char *)&myaddr_in, 0, sizeof(struct sockaddr_in));
226 memset((char *)&peeraddr_in, 0, sizeof(struct sockaddr_in));
227 myaddr_in.sin_family = AF_INET;
228 myaddr_in.sin_addr.s_addr = INADDR_ANY;
229 myaddr_in.sin_port = htons(Config.my_port);
230
231 ls = socket(AF_INET, SOCK_STREAM, 0);
232 if (ls == -1) {
233 syslog(LOG_NOTICE, "Can't create listen socket: %s", strerror(errno));
234 fprintf(stderr, "Can't create listen socket: %s\n", strerror(errno));
235 return 0;
236 }
237
238 if (setsockopt(ls, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) == -1) {
239 syslog(LOG_NOTICE, "Can't setsockopt SO_KEEPALIVE socket: %s", strerror(errno));
240 close(ls);
241 return 0;
242 }
243
244 if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) {
245 syslog(LOG_NOTICE, "Can't setsockopt SO_REUSEADDR socket: %s", strerror(errno));
246 close(ls);
247 return NULL;
248 }
249
250 if (bind(ls, (struct sockaddr *)&myaddr_in, sizeof(struct sockaddr_in)) == -1) {
251 syslog(LOG_NOTICE, "Can't bind to listen socket: %s", strerror(errno));
252 close(ls);
253 return NULL;
254 }
255
256 if (listen(ls, 5) == -1) {
257 syslog(LOG_NOTICE, "Can't listen on listen socket: %s", strerror(errno));
258 close(ls);
259 return NULL;
260 }
261
262 syslog(LOG_NOTICE, "listen socket created %d", ls);
263 if (debug)
264 fprintf(stdout, "listen socket created %d\n", ls);
265
261 266
262 /* 267 /*
263 * Loop forever until the external shutdown variable is set. 268 * Loop forever until the external shutdown variable is set.
264 */ 269 */
265 for (;;) { 270 for (;;) {
274 s = accept(ls, (struct sockaddr *)&peeraddr_in, &addrlen); 279 s = accept(ls, (struct sockaddr *)&peeraddr_in, &addrlen);
275 if (s == -1) { 280 if (s == -1) {
276 syslog(LOG_NOTICE, "my_server_loop accept failed %s", strerror(errno)); 281 syslog(LOG_NOTICE, "my_server_loop accept failed %s", strerror(errno));
277 if (debug) 282 if (debug)
278 fprintf(stdout, "my_server_loop accept failed %s\n", strerror(errno)); 283 fprintf(stdout, "my_server_loop accept failed %s\n", strerror(errno));
279 return 1; 284 return 0;
280 } 285 }
281 286
282 switch (fork()) { 287 switch (fork()) {
283 case -1: /* 288 case -1: /*
284 * Can't fork, just continue. 289 * Can't fork, just continue.
285 */ 290 */
286 return 1; 291 return 0;
287 case 0: /* 292 case 0: /*
288 * Child process, the commandline server. 293 * Child process, the commandline server.
289 */ 294 */
290 cmd_server(); 295 cmd_server();
291 return 0; 296 return 0;

mercurial