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