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 |
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; |