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