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