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