00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef NEOVISIONII_NV2_LABEL_SERVER_C_DEFINED
00039 #define NEOVISIONII_NV2_LABEL_SERVER_C_DEFINED
00040
00041 #include "NeovisionII/nv2_label_server.h"
00042
00043 #include "NeovisionII/nv2_common.h"
00044
00045
00046 #include <sys/types.h>
00047 #include <sys/socket.h>
00048 #include <netinet/in.h>
00049 #include <arpa/inet.h>
00050
00051 #include <errno.h>
00052 #include <pthread.h>
00053 #include <stdio.h>
00054 #include <stdlib.h>
00055 #include <string.h>
00056 #include <unistd.h>
00057
00058 struct nv2_label_server
00059 {
00060 pthread_mutex_t m_patch_lock;
00061 struct nv2_image_patch m_patch;
00062 int m_should_quit;
00063
00064 int m_patch_reader_port;
00065 struct in_addr m_remote_label_reader_in_addr;
00066 int m_remote_label_reader_port;
00067
00068 int m_verbosity;
00069
00070 volatile int socket_fd;
00071
00072 pthread_t m_patch_reader_thread;
00073 };
00074
00075 static void* run_patch_reader(void* vq)
00076 {
00077 struct nv2_label_server* const q = (struct nv2_label_server*) vq;
00078
00079 q->socket_fd = socket(PF_INET, SOCK_STREAM, 0);
00080 if (q->socket_fd == -1)
00081 nv2_fatal("socket() failed");
00082
00083 {
00084 const int set_on = 1;
00085 if (setsockopt(q->socket_fd,
00086 SOL_SOCKET, SO_REUSEADDR,
00087 &set_on, sizeof(set_on)) == -1)
00088 nv2_warn("setsockopt() failed");
00089 }
00090
00091 struct sockaddr_in name;
00092 name.sin_family = AF_INET;
00093 name.sin_addr.s_addr = htonl(INADDR_ANY);
00094 name.sin_port = htons(q->m_patch_reader_port);
00095 if (bind(q->socket_fd, (struct sockaddr*)(&name), sizeof(name)) == -1)
00096 nv2_fatal("bind() failed");
00097
00098 listen(q->socket_fd, 5);
00099
00100 int client_socket_fd = -1;
00101
00102
00103 while (q->socket_fd > 0)
00104 {
00105 struct sockaddr_in client_name;
00106 socklen_t client_name_len = sizeof(client_name);
00107
00108 client_socket_fd =
00109 accept(q->socket_fd,
00110 (struct sockaddr*)(&client_name),
00111 &client_name_len);
00112
00113 if (client_socket_fd < 0)
00114 {
00115
00116
00117
00118
00119
00120 if (q->socket_fd < 0)
00121 break;
00122
00123 if (q->m_verbosity >= 1)
00124 fprintf(stderr, "accept() failed "
00125 "(strerror=%s)\n",
00126 strerror(errno));
00127 continue;
00128 }
00129
00130 struct nv2_image_patch p;
00131 nv2_image_patch_init_empty(&p);
00132
00133 if (nv2_robust_read(client_socket_fd, &p,
00134 NV2_IMAGE_PATCH_HEADER_SIZE, NULL)
00135 != NV2_IMAGE_PATCH_HEADER_SIZE)
00136 {
00137 if (q->m_verbosity >= 1)
00138 fprintf(stderr, "read(header) failed\n");
00139 break;
00140 }
00141
00142 p.protocol_version = ntohl(p.protocol_version);
00143 p.width = ntohl(p.width);
00144 p.height = ntohl(p.height);
00145 p.id = ntohl(p.id);
00146 p.is_training_image= ntohl(p.is_training_image);
00147 p.type = ntohl(p.type);
00148 p.training_label[sizeof(p.training_label)-1] = '\0';
00149 p.remote_command[sizeof(p.remote_command)-1] = '\0';
00150
00151 const uint32_t npixbytes =
00152 p.width * p.height * nv2_pixel_type_bytes_per_pixel(p.type);
00153
00154
00155
00156
00157 const uint32_t maxbytes = 4096*4096;
00158
00159 int doquit = 0;
00160
00161 if (npixbytes > maxbytes)
00162 {
00163 if (q->m_verbosity >= 1)
00164 fprintf(stderr,
00165 "image patch was %ux%u%u=%u bytes, "
00166 "but the maximum allowable size "
00167 "is %u bytes\n",
00168 (unsigned int) p.width,
00169 (unsigned int) p.height,
00170 (unsigned int) nv2_pixel_type_bytes_per_pixel(p.type),
00171 (unsigned int) npixbytes,
00172 (unsigned int) maxbytes);
00173
00174 doquit = 1;
00175 }
00176 else if (p.protocol_version == 0)
00177 {
00178
00179
00180 doquit = 1;
00181 }
00182 else if (p.protocol_version != NV2_PATCH_PROTOCOL_VERSION)
00183 {
00184 if (q->m_verbosity >= 1)
00185 fprintf(stderr,
00186 "wrong patch protocol version "
00187 "(got %u, expected %u)",
00188 (unsigned int) p.protocol_version,
00189 (unsigned int) NV2_PATCH_PROTOCOL_VERSION);
00190
00191 doquit = 1;
00192 }
00193 else
00194 {
00195 p.data = (unsigned char*) malloc(npixbytes);
00196
00197 int nchunks_read = 0;
00198
00199 const size_t n =
00200 nv2_robust_read(client_socket_fd,
00201 p.data, npixbytes,
00202 &nchunks_read);
00203
00204 if (n != npixbytes)
00205 {
00206 doquit = 1;
00207 if (q->m_verbosity >= 1)
00208 nv2_warn("read(pixels) failed");
00209 }
00210
00211 if (q->m_verbosity >= 2)
00212 fprintf(stderr,
00213 "got patch = { .protocol_version=%u, "
00214 ".width=%u, .height=%u, .id=%u, "
00215 ".is_training=%u, "
00216 ".label='%s', .cmd='%s', "
00217 ".data=[%d bytes in %d chunks] }\n",
00218 (unsigned int) p.protocol_version,
00219 (unsigned int) p.width,
00220 (unsigned int) p.height,
00221 (unsigned int) p.id,
00222 (unsigned int) p.is_training_image,
00223 &p.training_label[0],
00224 &p.remote_command[0],
00225 (int) n, (int) nchunks_read);
00226 }
00227
00228 close(client_socket_fd);
00229 client_socket_fd = -1;
00230
00231 if (doquit)
00232 break;
00233
00234 pthread_mutex_lock(&q->m_patch_lock);
00235 nv2_image_patch_destroy(&q->m_patch);
00236 q->m_patch = p;
00237 pthread_mutex_unlock(&q->m_patch_lock);
00238 }
00239
00240 pthread_mutex_lock(&q->m_patch_lock);
00241 q->m_should_quit = 1;
00242 pthread_mutex_unlock(&q->m_patch_lock);
00243
00244 if (client_socket_fd >= 0)
00245 close(client_socket_fd);
00246
00247 close(q->socket_fd);
00248
00249 return (void*) 0;
00250 }
00251
00252 struct nv2_label_server* nv2_label_server_create(
00253 const int patch_reader_port,
00254 const char* remote_label_reader_addr,
00255 const int remote_label_reader_port)
00256 {
00257 struct nv2_label_server* p =
00258 (struct nv2_label_server*)
00259 malloc(sizeof(struct nv2_label_server));
00260
00261 if (p == 0)
00262 nv2_fatal("malloc() failed");
00263
00264 pthread_mutex_init(&p->m_patch_lock, 0);
00265 nv2_image_patch_init_empty(&p->m_patch);
00266 p->m_should_quit = 0;
00267
00268 p->m_patch_reader_port = patch_reader_port;
00269
00270 if (inet_aton(remote_label_reader_addr,
00271 &p->m_remote_label_reader_in_addr) == 0)
00272 nv2_fatal("inet_aton() failed");
00273
00274 p->m_remote_label_reader_port = remote_label_reader_port;
00275
00276 p->socket_fd = -1;
00277
00278 p->m_verbosity = 2;
00279
00280 if (0 != pthread_create(&p->m_patch_reader_thread, 0,
00281 &run_patch_reader,
00282 (void*) p))
00283 nv2_fatal("pthread_create() failed");
00284
00285 return p;
00286 }
00287
00288
00289 void nv2_label_server_destroy(struct nv2_label_server* p)
00290 {
00291 if (p->socket_fd != -1)
00292 {
00293 const int oldfd = p->socket_fd;
00294 p->socket_fd = -1;
00295 close(oldfd);
00296 }
00297
00298 if (0 != pthread_join(p->m_patch_reader_thread, 0))
00299 nv2_fatal("pthread_join() failed");
00300 nv2_image_patch_destroy(&p->m_patch);
00301 pthread_mutex_destroy(&p->m_patch_lock);
00302 }
00303
00304 enum nv2_image_patch_result
00305 nv2_label_server_get_current_patch(struct nv2_label_server* p,
00306 struct nv2_image_patch* ret)
00307 {
00308 pthread_mutex_lock(&p->m_patch_lock);
00309 *ret = p->m_patch;
00310 const int doquit = p->m_should_quit;
00311 nv2_image_patch_init_empty(&p->m_patch);
00312 pthread_mutex_unlock(&p->m_patch_lock);
00313
00314 if (doquit) return NV2_IMAGE_PATCH_END;
00315 else if (ret->id > 0) return NV2_IMAGE_PATCH_VALID;
00316 else return NV2_IMAGE_PATCH_NONE;
00317 }
00318
00319 enum nv2_label_send_result
00320 nv2_label_server_send_label(struct nv2_label_server* p,
00321 const struct nv2_patch_label* l)
00322 {
00323 const int socket_fd = socket(PF_INET, SOCK_STREAM, 0);
00324
00325 if (socket_fd == -1)
00326 nv2_fatal("socket() failed");
00327
00328
00329 struct sockaddr_in name;
00330 name.sin_family = AF_INET;
00331 name.sin_addr = p->m_remote_label_reader_in_addr;
00332 name.sin_port = htons(p->m_remote_label_reader_port);
00333
00334 struct nv2_patch_label nl = *l;
00335 nl.protocol_version = htonl(l->protocol_version);
00336 nl.patch_id = htonl(l->patch_id);
00337 nl.confidence = htonl(l->confidence);
00338
00339 enum nv2_label_send_result retval = NV2_LABEL_SEND_OK;
00340
00341 errno = 0;
00342 if (connect(socket_fd, (struct sockaddr*)(&name), sizeof(name))
00343 == -1)
00344 {
00345 if (p->m_verbosity >= 1)
00346 nv2_warn("connect() failed");
00347 retval = NV2_LABEL_SEND_FAIL;
00348 }
00349 else if (nv2_robust_write(socket_fd, &nl, sizeof(nl))
00350 != sizeof(nl))
00351 {
00352 if (p->m_verbosity >= 1)
00353 nv2_warn("write(nv2_patch_label) failed");
00354 retval = NV2_LABEL_SEND_FAIL;
00355 }
00356
00357 close(socket_fd);
00358
00359 return retval;
00360 }
00361
00362 void nv2_label_server_set_verbosity(struct nv2_label_server* p,
00363 const int verbosity)
00364 {
00365 p->m_verbosity = verbosity;
00366 }
00367
00368
00369
00370
00371
00372
00373
00374
00375 #endif // NEOVISIONII_NV2_LABEL_SERVER_C_DEFINED