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