1 /* Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 // System dependencies
31 #include <errno.h>
32
33 // Camera dependencies
34 #include "mm_qcamera_socket.h"
35 #include "mm_qcamera_commands.h"
36 #include "mm_qcamera_dbg.h"
37
38 #define IP_ADDR "127.0.0.1"
39 #define TUNING_CHROMATIX_PORT 55555
40 #define TUNING_PREVIEW_PORT 55556
41
42 #define CURRENT_COMMAND_ACK_SUCCESS 1
43 #define CURRENT_COMMAND_ACK_FAILURE 2
44
45 pthread_t eztune_thread_id;
46
tuneserver_send_command_rsp(tuningserver_t * tsctrl,char * send_buf,uint32_t send_len)47 static ssize_t tuneserver_send_command_rsp(tuningserver_t *tsctrl,
48 char *send_buf, uint32_t send_len)
49 {
50 ssize_t rc;
51
52 /* send ack back to client upon req */
53 if (send_len <= 0) {
54 LOGE("Invalid send len \n");
55 return -1;
56 }
57 if (send_buf == NULL) {
58 LOGE("Invalid send buf \n");
59 return -1;
60 }
61
62 rc = send(tsctrl->clientsocket_id, send_buf, send_len, 0);
63 if (rc < 0) {
64 LOGE("RSP send returns error %s\n", strerror(errno));
65 } else {
66 rc = 0;
67 }
68
69 if (send_buf != NULL) {
70 free(send_buf);
71 send_buf = NULL;
72 }
73 return rc;
74 }
75
release_eztune_prevcmd_rsp(eztune_prevcmd_rsp * pHead)76 static void release_eztune_prevcmd_rsp(eztune_prevcmd_rsp *pHead)
77 {
78 if (pHead != NULL ) {
79 release_eztune_prevcmd_rsp((eztune_prevcmd_rsp *)pHead->next);
80 free(pHead);
81 }
82 }
83
tuneserver_ack(uint16_t a,uint32_t b,tuningserver_t * tsctrl)84 static ssize_t tuneserver_ack(uint16_t a, uint32_t b, tuningserver_t *tsctrl)
85 {
86 ssize_t rc;
87 char ack_1[6];
88 /*Ack the command here*/
89 memcpy(ack_1, &a, 2);
90 memcpy(ack_1+2, &b, 4);
91 /* send echo back to client upon accept */
92 rc = send(tsctrl->clientsocket_id, &ack_1, sizeof(ack_1), 0);
93 if (rc < 0) {
94 LOGE(" eztune_server_run: send returns error %s\n",
95 strerror(errno));
96 return rc;
97 } else if (rc < (int32_t)sizeof(ack_1)) {
98 /*Shouldn't hit this for packets <1K; need to re-send if we do*/
99 }
100 return 0;
101 }
102
tuneserver_send_command_ack(uint8_t ack,tuningserver_t * tsctrl)103 static ssize_t tuneserver_send_command_ack( uint8_t ack,
104 tuningserver_t *tsctrl)
105 {
106 ssize_t rc;
107 /* send ack back to client upon req */
108 rc = send(tsctrl->clientsocket_id, &ack, sizeof(ack), 0);
109 if (rc < 0) {
110 LOGE("ACK send returns error %s\n", strerror(errno));
111 return rc;
112 }
113 return 0;
114 }
115
116 /** tuneserver_process_command
117 * @tsctrl: the server control object
118 *
119 * Processes the command that the client sent
120 *
121 * Return: >=0 on success, -1 on failure.
122 **/
tuneserver_process_command(tuningserver_t * tsctrl,char * send_buf,uint32_t send_len)123 static int32_t tuneserver_process_command(tuningserver_t *tsctrl,
124 char *send_buf, uint32_t send_len)
125 {
126 tuneserver_protocol_t *p = tsctrl->proto;
127 int result = 0;
128
129 LOGD(" Current command is %d\n", p->current_cmd);
130 switch (p->current_cmd) {
131 case TUNESERVER_GET_LIST:
132 if(tuneserver_send_command_ack(CURRENT_COMMAND_ACK_SUCCESS, tsctrl)) {
133 LOGE(" Ack Failed for cmd %d\n", p->current_cmd);
134 return -1;
135 }
136 result = tuneserver_process_get_list_cmd(tsctrl, p->recv_buf,
137 send_buf, send_len);
138 if (result < 0) {
139 LOGE(" RSP processing Failed for cmd %d\n", p->current_cmd);
140 return -1;
141 }
142 if(tuneserver_send_command_rsp(tsctrl, send_buf, send_len)) {
143 LOGE(" RSP Failed for cmd %d\n", p->current_cmd);
144 return -1;
145 }
146 break;
147
148 case TUNESERVER_GET_PARMS:
149 if(tuneserver_send_command_ack(CURRENT_COMMAND_ACK_SUCCESS, tsctrl)) {
150 LOGE(" Ack Failed for cmd %d\n", p->current_cmd);
151 return -1;
152 }
153 result = tuneserver_process_get_params_cmd(tsctrl, p->recv_buf,
154 send_buf, send_len);
155 if (result < 0) {
156 LOGE(" RSP processing Failed for cmd %d\n", p->current_cmd);
157 return -1;
158 }
159 if(tuneserver_send_command_rsp(tsctrl, send_buf, send_len)) {
160 LOGE(" RSP Failed for cmd %d\n", p->current_cmd);
161 return -1;
162 }
163 break;
164
165 case TUNESERVER_SET_PARMS:
166 if(tuneserver_send_command_ack(CURRENT_COMMAND_ACK_SUCCESS, tsctrl)) {
167 LOGE(" Ack Failed for cmd %d\n", p->current_cmd);
168 return -1;
169 }
170 result = tuneserver_process_set_params_cmd(tsctrl, p->recv_buf,
171 send_buf, send_len);
172 if (result < 0) {
173 LOGE(" RSP processing Failed for cmd %d\n", p->current_cmd);
174 return -1;
175 }
176 if(tuneserver_send_command_rsp(tsctrl, send_buf, send_len)) {
177 LOGE(" RSP Failed for cmd %d\n", p->current_cmd);
178 return -1;
179 }
180 break;
181
182 case TUNESERVER_MISC_CMDS: {
183 if(tuneserver_send_command_ack(CURRENT_COMMAND_ACK_SUCCESS, tsctrl)) {
184 LOGE(" Ack Failed for cmd %d\n", p->current_cmd);
185 return -1;
186 }
187 result = tuneserver_process_misc_cmd(tsctrl, p->recv_buf,
188 send_buf, send_len);
189 if (result < 0) {
190 LOGE(" RSP processing Failed for cmd %d\n", p->current_cmd);
191 return -1;
192 }
193 if(tuneserver_send_command_rsp(tsctrl, send_buf, send_len)) {
194 LOGE(" RSP Failed for cmd %d\n", p->current_cmd);
195 return -1;
196 }
197 break;
198 }
199
200 default:
201 if(tuneserver_send_command_ack(CURRENT_COMMAND_ACK_SUCCESS, tsctrl)) {
202 LOGE(" Ack Failed for cmd %d\n", p->current_cmd);
203 return -1;
204 }
205 LOGE(" p->current_cmd: default\n");
206 result = -1;
207 break;
208 }
209
210 return result;
211 }
212
213 /** tuneserver_process_client_message
214 * @recv_buffer: received message from the client
215 * @tsctrl: the server control object
216 *
217 * Processes the message from client and prepares for next
218 * message.
219 *
220 * Return: >=0 on success, -1 on failure.
221 **/
tuneserver_process_client_message(void * recv_buffer,tuningserver_t * tsctrl)222 static int32_t tuneserver_process_client_message(void *recv_buffer,
223 tuningserver_t *tsctrl)
224 {
225 int rc = 0;
226 tuneserver_protocol_t *p = tsctrl->proto;
227
228 switch (tsctrl->proto->next_recv_code) {
229 case TUNESERVER_RECV_COMMAND:
230 p->current_cmd = *(uint16_t *)recv_buffer;
231 p->next_recv_code = TUNESERVER_RECV_PAYLOAD_SIZE;
232 p->next_recv_len = sizeof(uint32_t);
233 break;
234
235 case TUNESERVER_RECV_PAYLOAD_SIZE:
236 p->next_recv_code = TUNESERVER_RECV_PAYLOAD;
237 p->next_recv_len = *(uint32_t *)recv_buffer;
238 p->recv_len = p->next_recv_len;
239 if (p->next_recv_len > TUNESERVER_MAX_RECV)
240 return -1;
241 if (p->next_recv_len == 0) {
242 p->next_recv_code = TUNESERVER_RECV_RESPONSE;
243 p->next_recv_len = sizeof(uint32_t);
244 }
245 break;
246
247 case TUNESERVER_RECV_PAYLOAD:
248 p->recv_buf = malloc(p->next_recv_len);
249 if (!p->recv_buf) {
250 LOGE("Error allocating memory for recv_buf %s\n",
251 strerror(errno));
252 return -1;
253 }
254 memcpy(p->recv_buf, recv_buffer, p->next_recv_len);
255 p->next_recv_code = TUNESERVER_RECV_RESPONSE;
256 p->next_recv_len = sizeof(uint32_t);
257 /*Process current command at this point*/
258 break;
259
260 case TUNESERVER_RECV_RESPONSE:
261 p->next_recv_code = TUNESERVER_RECV_COMMAND;
262 p->next_recv_len = 2;
263 p->send_len = *(uint32_t *)recv_buffer;
264 p->send_buf = (char *)calloc(p->send_len, sizeof(char *));
265 if (!p->send_buf) {
266 LOGE("Error allocating memory for send_buf %s\n",
267 strerror(errno));
268 return -1;
269 }
270 rc = tuneserver_process_command(tsctrl, p->send_buf, p->send_len);
271 free(p->recv_buf);
272 p->recv_buf = NULL;
273 p->recv_len = 0;
274 break;
275
276 default:
277 LOGE(" p->next_recv_code: default\n");
278 rc = -1;
279 break;
280 }
281
282 return rc;
283 }
284
285 /** tuneserver_ack_onaccept_initprotocol
286 * @tsctrl: the server control object
287 *
288 * Acks a connection from the cient and sets up the
289 * protocol object to start receiving commands.
290 *
291 * Return: >=0 on success, -1 on failure.
292 **/
tuneserver_ack_onaccept_initprotocol(tuningserver_t * tsctrl)293 static ssize_t tuneserver_ack_onaccept_initprotocol(tuningserver_t *tsctrl)
294 {
295 ssize_t rc = 0;
296 uint32_t ack_status;
297
298 LOGE("starts\n");
299 /*
300 if(tsctrl->camera_running) {
301 ack_status = 1;
302 } else {
303 ack_status = 2;
304 }
305 */
306 ack_status = 1;
307
308 rc = tuneserver_ack(1, ack_status, tsctrl);
309
310 tsctrl->proto = malloc(sizeof(tuneserver_protocol_t));
311 if (!tsctrl->proto) {
312 LOGE(" malloc returns NULL with error %s\n", strerror(errno));
313 return -1;
314 }
315
316 tsctrl->proto->current_cmd = 0xFFFF;
317 tsctrl->proto->next_recv_code = TUNESERVER_RECV_COMMAND;
318 tsctrl->proto->next_recv_len = 2;
319 tsctrl->proto->recv_buf = NULL;
320 tsctrl->proto->send_buf = NULL;
321
322 LOGD("X\n");
323
324 return rc;
325 }
326
327 /** tuneserver_check_status
328 * @tsctrl: the server control object
329 *
330 * Checks if camera is running and stops it.
331 *
332 * Return: >=0 on success, -1 on failure.
333 **/
334 #if 0
335 static void tuneserver_check_status(tuningserver_t *tsctrl)
336 {
337 if (tsctrl->camera_running == 1) {
338 /*TODO: Stop camera here*/
339 tuneserver_stop_cam(&tsctrl->lib_handle);
340 }
341 tsctrl->camera_running = 0;
342
343 tuneserver_close_cam(&tsctrl->lib_handle);
344 }
345 #endif
346
prevserver_send_command_rsp(tuningserver_t * tsctrl,char * send_buf,uint32_t send_len)347 static ssize_t prevserver_send_command_rsp(tuningserver_t *tsctrl,
348 char *send_buf, uint32_t send_len)
349 {
350 ssize_t rc;
351
352 /* send ack back to client upon req */
353 if (send_len <= 0) {
354 LOGE("Invalid send len \n");
355 return -1;
356 }
357 if (send_buf == NULL) {
358 LOGE("Invalid send buf \n");
359 return -1;
360 }
361
362 rc = send(tsctrl->pr_clientsocket_id, send_buf, send_len, 0);
363 if (rc < 0) {
364 LOGE("RSP send returns error %s\n", strerror(errno));
365 } else {
366 rc = 0;
367 }
368 if (send_buf != NULL) {
369 free(send_buf);
370 send_buf = NULL;
371 }
372 return rc;
373 }
374
prevserver_init_protocol(tuningserver_t * tsctrl)375 static void prevserver_init_protocol(tuningserver_t *tsctrl)
376 {
377 tsctrl->pr_proto = malloc(sizeof(prserver_protocol_t));
378 if (!tsctrl->pr_proto) {
379 LOGE(" malloc returns NULL with error %s\n",
380 strerror(errno));
381 return;
382 }
383
384 tsctrl->pr_proto->current_cmd = 0xFFFF;
385 tsctrl->pr_proto->next_recv_code = TUNE_PREV_RECV_COMMAND;
386 tsctrl->pr_proto->next_recv_len = 2;
387 }
388
prevserver_process_command(tuningserver_t * tsctrl,char ** send_buf,uint32_t * send_len)389 static int32_t prevserver_process_command(
390 tuningserver_t *tsctrl, char **send_buf, uint32_t *send_len)
391 {
392 prserver_protocol_t *p = tsctrl->pr_proto;
393 int result = 0;
394 eztune_prevcmd_rsp *rsp_ptr=NULL, *rspn_ptr=NULL, *head_ptr=NULL;
395
396 LOGD(" Current command is %d\n", p->current_cmd);
397 switch (p->current_cmd) {
398 case TUNE_PREV_GET_INFO:
399 result = tuneserver_preview_getinfo(tsctrl, send_buf, send_len);
400 if (result < 0) {
401 LOGE(" RSP processing Failed for cmd %d\n",
402 p->current_cmd);
403 return -1;
404 }
405 rsp_ptr = (eztune_prevcmd_rsp *)*send_buf;
406 if ((!rsp_ptr) || (!rsp_ptr->send_buf)) {
407 LOGE(" RSP ptr is NULL %d\n", p->current_cmd);
408 return -1;
409 }
410 if (prevserver_send_command_rsp(tsctrl,
411 rsp_ptr->send_buf, rsp_ptr->send_len)) {
412 LOGE(" RSP Failed for TUNE_PREV_GET_INFO ver cmd %d\n",
413 p->current_cmd);
414 return -1;
415 }
416 rspn_ptr = (eztune_prevcmd_rsp *)rsp_ptr->next;
417 if ((!rspn_ptr) || (!rspn_ptr->send_buf)) {
418 LOGE(" RSP1 ptr is NULL %d\n", p->current_cmd);
419 return -1;
420 }
421 if (prevserver_send_command_rsp(tsctrl,
422 rspn_ptr->send_buf, rspn_ptr->send_len)) {
423 LOGE(" RSP Failed for TUNE_PREV_GET_INFO caps cmd %d\n",
424 p->current_cmd);
425 return -1;
426 }
427 free(rspn_ptr);
428 free(rsp_ptr);
429 break;
430
431 case TUNE_PREV_CH_CNK_SIZE:
432 result = tuneserver_preview_getchunksize(tsctrl, send_buf, send_len);
433 if (result < 0) {
434 LOGE(" RSP processing Failed for cmd %d\n", p->current_cmd);
435 return -1;
436 }
437 if (prevserver_send_command_rsp(tsctrl, *send_buf, *send_len)) {
438 LOGE(" RSP Failed for TUNE_PREV_CH_CNK_SIZE cmd %d\n",
439 p->current_cmd);
440 return -1;
441 }
442 break;
443
444 case TUNE_PREV_GET_PREV_FRAME:
445 result = tuneserver_preview_getframe(tsctrl, send_buf, send_len);
446 if (result < 0) {
447 LOGE(" RSP processing Failed for cmd %d\n", p->current_cmd);
448 return -1;
449 }
450 rsp_ptr = (eztune_prevcmd_rsp *)*send_buf;
451 if ((!rsp_ptr) || (!rsp_ptr->send_buf)) {
452 LOGE(" RSP ptr is NULL %d\n", p->current_cmd);
453 return -1;
454 }
455 head_ptr = rsp_ptr;
456
457 while (rsp_ptr != NULL) {
458 if ((!rsp_ptr) || (!rsp_ptr->send_buf)) {
459 LOGE(" RSP ptr is NULL %d\n", p->current_cmd);
460 return -1;
461 }
462 if (prevserver_send_command_rsp(tsctrl,
463 rsp_ptr->send_buf, rsp_ptr->send_len)) {
464 LOGE(" RSP Failed for TUNE_PREV_GET_INFO ver cmd %d\n",
465 p->current_cmd);
466 return -1;
467 }
468 rsp_ptr = (eztune_prevcmd_rsp *)rsp_ptr->next;
469 }
470 release_eztune_prevcmd_rsp(head_ptr);
471 break;
472
473 case TUNE_PREV_GET_JPG_SNAP:
474 case TUNE_PREV_GET_RAW_SNAP:
475 case TUNE_PREV_GET_RAW_PREV:
476 result = tuneserver_preview_unsupported(tsctrl, send_buf, send_len);
477 if (result < 0) {
478 LOGE("RSP processing Failed for cmd %d\n", p->current_cmd);
479 return -1;
480 }
481 if (prevserver_send_command_rsp(tsctrl, *send_buf, *send_len)) {
482 LOGE("RSP Failed for UNSUPPORTED cmd %d\n", p->current_cmd);
483 return -1;
484 }
485 break;
486
487 default:
488 LOGE(" p->current_cmd: default\n");
489 result = -1;
490 break;
491 }
492
493 return result;
494 }
495
496 /** previewserver_process_client_message
497 * @recv_buffer: received message from the client
498 * @tsctrl: the server control object
499 *
500 * Processes the message from client and prepares for next
501 * message.
502 *
503 * Return: >=0 on success, -1 on failure.
504 **/
prevserver_process_client_message(void * recv_buffer,tuningserver_t * tsctrl)505 static int32_t prevserver_process_client_message(void *recv_buffer,
506 tuningserver_t *tsctrl)
507 {
508 int rc = 0;
509 prserver_protocol_t *p = tsctrl->pr_proto;
510
511 LOGD("command = %d", p->next_recv_code);
512
513 switch (p->next_recv_code) {
514 case TUNE_PREV_RECV_COMMAND:
515 p->current_cmd = *(uint16_t *)recv_buffer;
516 if(p->current_cmd != TUNE_PREV_CH_CNK_SIZE) {
517 rc = prevserver_process_command(tsctrl,
518 &p->send_buf, (uint32_t *)&p->send_len);
519 break;
520 }
521 p->next_recv_code = TUNE_PREV_RECV_NEWCNKSIZE;
522 p->next_recv_len = sizeof(uint32_t);
523 LOGD("TUNE_PREV_COMMAND X\n");
524 break;
525 case TUNE_PREV_RECV_NEWCNKSIZE:
526 p->new_cnk_size = *(uint32_t *)recv_buffer;
527 p->next_recv_code = TUNE_PREV_RECV_COMMAND;
528 p->next_recv_len = 2;
529 rc = prevserver_process_command(tsctrl,
530 &p->send_buf, (uint32_t *)&p->send_len);
531 break;
532 default:
533 LOGE("prev_proc->next_recv_code: default\n");
534 rc = -1;
535 break;
536 }
537
538 return rc;
539 }
540
541 /** tunning_server_socket_listen
542 * @ip_addr: the ip addr to listen
543 * @port: the port to listen
544 *
545 * Setup a listen socket for eztune.
546 *
547 * Return: >0 on success, <=0 on failure.
548 **/
tunning_server_socket_listen(const char * ip_addr,uint16_t port)549 int tunning_server_socket_listen(const char* ip_addr, uint16_t port)
550 {
551 int sock_fd = -1;
552 mm_qcamera_sock_addr_t server_addr;
553 int result;
554 int option;
555 int socket_flag;
556
557 memset(&server_addr, 0, sizeof(server_addr));
558 server_addr.addr_in.sin_family = AF_INET;
559 server_addr.addr_in.sin_port = (__be16) htons(port);
560 server_addr.addr_in.sin_addr.s_addr = inet_addr(ip_addr);
561
562 if (server_addr.addr_in.sin_addr.s_addr == INADDR_NONE) {
563 LOGE(" invalid address.\n");
564 return -1;
565 }
566
567 /* Create an AF_INET stream socket to receive incoming connection ON */
568 sock_fd = socket(AF_INET, SOCK_STREAM, 0);
569 if (sock_fd < 0) {
570 LOGE(" socket failed\n");
571 return sock_fd;
572 }
573
574 // set listen socket to non-block, but why??
575 socket_flag = fcntl(sock_fd, F_GETFL, 0);
576 fcntl(sock_fd, F_SETFL, socket_flag | O_NONBLOCK);
577
578 /* reuse in case it is in timeout */
579 option = 1;
580 result = setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR,
581 &option, sizeof(option));
582
583 if (result < 0) {
584 LOGE("eztune setsockopt failed");
585 close(sock_fd);
586 sock_fd = -1;
587 return sock_fd;
588 }
589
590 result = bind(sock_fd, &server_addr.addr, sizeof(server_addr.addr_in));
591 if (result < 0) {
592 LOGE("eztune socket bind failed");
593 close(sock_fd);
594 sock_fd = -1;
595 return sock_fd;
596 }
597
598 result = listen(sock_fd, 1);
599 if (result < 0) {
600 LOGE("eztune socket listen failed");
601 close(sock_fd);
602 sock_fd = -1;
603 return sock_fd;
604 }
605
606 LOGH("sock_fd: %d, listen at port: %d\n", sock_fd, port);
607
608 return sock_fd;
609 }
610
611 /** main
612 *
613 * Creates the server, and starts waiting for
614 * connections/messages from a prospective
615 * client
616 *
617 **/
eztune_proc(void * data)618 void *eztune_proc(void *data)
619 {
620 int server_socket = -1, client_socket = -1;
621 int prev_server_socket = -1, prev_client_socket = -1;
622
623 mm_qcamera_sock_addr_t addr_client_inet;
624 socklen_t addr_client_len = sizeof(addr_client_inet.addr_in);
625 int result;
626 fd_set tsfds;
627 int num_fds = 0;
628 ssize_t recv_bytes;
629 char buf[TUNESERVER_MAX_RECV];
630
631 mm_camera_lib_handle *lib_handle = (mm_camera_lib_handle *)data;
632
633 LOGE(">>> Starting tune server <<< \n");
634
635 // for eztune chromatix params
636 server_socket = tunning_server_socket_listen(IP_ADDR, TUNING_CHROMATIX_PORT);
637 if (server_socket <= 0) {
638 LOGE("[ERR] fail to setup listen socket for eztune chromatix parms...");
639 return NULL;
640 }
641 prev_server_socket = tunning_server_socket_listen(IP_ADDR, TUNING_PREVIEW_PORT);
642 if (prev_server_socket <= 0) {
643 LOGE("[ERR] fail to setup listen socket for eztune preview...\n");
644 return NULL;
645 }
646 num_fds = TUNESERVER_MAX(server_socket, prev_server_socket);
647 LOGH("num_fds = %d\n", num_fds);
648
649 do {
650 FD_ZERO(&tsfds);
651 FD_SET(server_socket, &tsfds);
652 FD_SET(prev_server_socket, &tsfds);
653 if (client_socket > 0) {
654 FD_SET(client_socket, &tsfds);
655 }
656 if (prev_client_socket > 0) {
657 FD_SET( prev_client_socket, &tsfds);
658 }
659
660 /* no timeout */
661 result = select(num_fds + 1, &tsfds, NULL, NULL, NULL);
662 if (result < 0) {
663 LOGE("select failed: %s\n", strerror(errno));
664 continue;
665 }
666
667 /*
668 ** (1) CHROMATIX SERVER
669 */
670 if (FD_ISSET(server_socket, &tsfds)) {
671 LOGD("Receiving New client connection\n");
672
673 client_socket = accept(server_socket,
674 &addr_client_inet.addr, &addr_client_len);
675 if (client_socket == -1) {
676 LOGE("accept failed %s", strerror(errno));
677 continue;
678 }
679
680 if (client_socket >= FD_SETSIZE) {
681 LOGE("client_socket is out of range. client_socket=%d",client_socket);
682 continue;
683 }
684
685 LOGE("accept a new connect on 55555, sd(%d)\n", client_socket);
686 num_fds = TUNESERVER_MAX(num_fds, client_socket);
687
688 // open camera and get handle - this is needed to
689 // be able to set parameters without starting
690 // preview stream
691 /*if (!tsctrl.camera_running) {
692 result = tuneserver_open_cam(&tsctrl.lib_handle, &tsctrl);
693 if(result) {
694 printf("\n Camera Open Fail !!! \n");
695 close(server_socket);
696 return EXIT_FAILURE;
697 }
698 }*/
699 result = tuneserver_open_cam(lib_handle);
700 if(result) {
701 LOGE("\n Tuning Library open failed!!!\n");
702 close(server_socket);
703 return NULL;
704 }
705 lib_handle->tsctrl.clientsocket_id = client_socket;
706 if (tuneserver_ack_onaccept_initprotocol(&lib_handle->tsctrl) < 0) {
707 LOGE(" Error while acking\n");
708 close(client_socket);
709 continue;
710 }
711 tuneserver_initialize_tuningp(lib_handle, client_socket,
712 lib_handle->tsctrl.proto->send_buf, lib_handle->tsctrl.proto->send_len);
713 }
714
715 if ((client_socket < FD_SETSIZE) && (FD_ISSET(client_socket, &tsfds))) {
716 if (lib_handle->tsctrl.proto == NULL) {
717 LOGE(" Cannot receive msg without connect\n");
718 continue;
719 }
720
721 /*Receive message and process it*/
722 recv_bytes = recv(client_socket, (void *)buf,
723 lib_handle->tsctrl.proto->next_recv_len, 0);
724 LOGD("Receive %lld bytes \n", (long long int) recv_bytes);
725
726 if (recv_bytes == -1) {
727 LOGE(" Receive failed with error %s\n", strerror(errno));
728 //tuneserver_check_status(&tsctrl);
729 continue;
730 } else if (recv_bytes == 0) {
731 LOGE("connection has been terminated\n");
732
733 tuneserver_deinitialize_tuningp(&lib_handle->tsctrl, client_socket,
734 lib_handle->tsctrl.proto->send_buf,
735 lib_handle->tsctrl.proto->send_len);
736 free(lib_handle->tsctrl.proto);
737 lib_handle->tsctrl.proto = NULL;
738
739 close(client_socket);
740 client_socket = -1;
741 //tuneserver_check_status(&tsctrl);
742 } else {
743 LOGD(" Processing socket command\n");
744
745 result = tuneserver_process_client_message(buf, &lib_handle->tsctrl);
746
747 if (result < 0) {
748 LOGE("Protocol violated\n");
749
750 free(lib_handle->tsctrl.proto);
751 lib_handle->tsctrl.proto = NULL;
752
753 close(client_socket);
754 client_socket = -1;
755 //tuneserver_check_status(&tsctrl);
756 continue;
757 }
758 }
759 }
760
761 /*
762 ** (2) PREVIEW SERVER
763 */
764 if (FD_ISSET(prev_server_socket, &tsfds)) {
765 LOGD("Receiving New Preview client connection\n");
766
767 prev_client_socket = accept(prev_server_socket,
768 &addr_client_inet.addr, &addr_client_len);
769 if (prev_client_socket == -1) {
770 LOGE("accept failed %s", strerror(errno));
771 continue;
772 }
773 if (prev_client_socket >= FD_SETSIZE) {
774 LOGE("prev_client_socket is out of range. prev_client_socket=%d",prev_client_socket);
775 continue;
776 }
777
778 lib_handle->tsctrl.pr_clientsocket_id = prev_client_socket;
779
780 LOGD("Accepted a new connection, fd(%d)\n", prev_client_socket);
781 num_fds = TUNESERVER_MAX(num_fds, prev_client_socket);
782
783 // start camera
784 /*if (!tsctrl.camera_running) {
785 result = 0;
786 result = tuneserver_open_cam(&tsctrl.lib_handle, &tsctrl);
787 if(result) {
788 printf("\n Camera Open Fail !!! \n");
789 return EXIT_FAILURE;
790 }
791 }*/
792 cam_dimension_t dim;
793 //dim.width = lib_handle->test_obj.buffer_width;
794 //dim.height = lib_handle->test_obj.buffer_height;
795 dim.width = DEFAULT_PREVIEW_WIDTH;
796 dim.height = DEFAULT_PREVIEW_HEIGHT;
797
798 LOGD("preview dimension info: w(%d), h(%d)\n", dim.width, dim.height);
799 // we have to make sure that camera is running, before init connection,
800 // because we need to know the frame size for allocating the memory.
801 prevserver_init_protocol(&lib_handle->tsctrl);
802
803 result = tuneserver_initialize_prevtuningp(lib_handle, prev_client_socket,
804 dim, (char **)&lib_handle->tsctrl.proto->send_buf,
805 &lib_handle->tsctrl.proto->send_len);
806 if (result < 0) {
807 LOGE("tuneserver_initialize_prevtuningp error!");
808 close(prev_client_socket);
809 prev_client_socket = -1;
810 }
811 }
812
813 if ((prev_client_socket < FD_SETSIZE) && (FD_ISSET(prev_client_socket, &tsfds))) {
814 recv_bytes = recv(prev_client_socket, (void *)buf,
815 lib_handle->tsctrl.pr_proto->next_recv_len, 0);
816
817 LOGD("prev_client_socket=%d\n", prev_client_socket);
818 LOGD("next_recv_len=%d\n", buf[0]+buf[1]*256);
819
820 if (recv_bytes <= 0) {
821 if (recv_bytes == 0) {
822 LOGE("client close the connection.\n");
823 } else {
824 LOGE("receive error: %s\n", strerror(errno));
825 }
826
827 //tuneserver_check_status(&tsctrl);
828 // if recv error, we should close the connection, free the proto data,
829 // AND wait for a new connecton..
830 // close_connection();
831 // stop_camera()
832 // cleanup_proto_data();
833 tuneserver_deinitialize_prevtuningp(&lib_handle->tsctrl,
834 (char **)&lib_handle->tsctrl.proto->send_buf,
835 &lib_handle->tsctrl.proto->send_len);
836 close(prev_client_socket);
837 prev_client_socket = -1;
838 } else {
839 result = prevserver_process_client_message((void *)buf,
840 &lib_handle->tsctrl);
841 if (result < 0) {
842 LOGE("Protocol violated\n");
843
844 //free(tsctrl->preivew_proto);
845 //free(tsctrl);
846 //max_fd = ezt_parms_listen_sd + 1;
847 tuneserver_deinitialize_prevtuningp(&lib_handle->tsctrl,
848 (char **)&lib_handle->tsctrl.proto->send_buf,
849 &lib_handle->tsctrl.proto->send_len);
850 close(prev_client_socket);
851 prev_client_socket = -1;
852 //tuneserver_check_status(&tsctrl);
853 }
854 //sleep(1);
855 }
856 }
857 } while (1);
858
859 if (server_socket >= 0) {
860 close(server_socket);
861 }
862 if (client_socket >= 0) {
863 close(client_socket);
864 }
865 if (prev_server_socket >= 0) {
866 close(prev_server_socket);
867 }
868 if (prev_client_socket >= 0) {
869 close(prev_client_socket);
870 }
871
872 return EXIT_SUCCESS;
873 }
874
eztune_server_start(void * lib_handle)875 int eztune_server_start (void *lib_handle)
876 {
877 return pthread_create(&eztune_thread_id, NULL, eztune_proc, lib_handle);
878 }
879
880