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