1/* Copyright (c) 2012-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// To remove
31#include <cutils/properties.h>
32
33// System dependencies
34#include <pthread.h>
35#include <errno.h>
36#include <fcntl.h>
37#include <stdlib.h>
38#include <dlfcn.h>
39#define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h>
40#include IOCTL_H
41
42// Camera dependencies
43#include "cam_semaphore.h"
44#include "mm_camera_dbg.h"
45#include "mm_camera_sock.h"
46#include "mm_camera_interface.h"
47#include "mm_camera.h"
48#include "cam_cond.h"
49
50#define SET_PARM_BIT32(parm, parm_arr) \
51    (parm_arr[parm/32] |= (1<<(parm%32)))
52
53#define GET_PARM_BIT32(parm, parm_arr) \
54    ((parm_arr[parm/32]>>(parm%32))& 0x1)
55
56/* internal function declare */
57int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
58                          uint8_t reg_flag);
59int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
60                              mm_camera_event_t *event);
61extern mm_camera_obj_t* mm_camera_util_get_camera_by_session_id
62        (uint32_t session_id);
63
64/*===========================================================================
65 * FUNCTION   : mm_camera_util_get_channel_by_handler
66 *
67 * DESCRIPTION: utility function to get a channel object from its handle
68 *
69 * PARAMETERS :
70 *   @cam_obj: ptr to a camera object
71 *   @handler: channel handle
72 *
73 * RETURN     : ptr to a channel object.
74 *              NULL if failed.
75 *==========================================================================*/
76mm_channel_t * mm_camera_util_get_channel_by_handler(
77                                    mm_camera_obj_t * cam_obj,
78                                    uint32_t handler)
79{
80    int i;
81    mm_channel_t *ch_obj = NULL;
82    for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) {
83        if (handler == cam_obj->ch[i].my_hdl) {
84            ch_obj = &cam_obj->ch[i];
85            break;
86        }
87    }
88    return ch_obj;
89}
90
91/*===========================================================================
92 * FUNCTION   : mm_camera_util_chip_is_a_family
93 *
94 * DESCRIPTION: utility function to check if the host is A family chip
95 *
96 * PARAMETERS :
97 *
98 * RETURN     : TRUE if A family.
99 *              FALSE otherwise.
100 *==========================================================================*/
101uint8_t mm_camera_util_chip_is_a_family(void)
102{
103#ifdef USE_A_FAMILY
104    return TRUE;
105#else
106    return FALSE;
107#endif
108}
109
110/*===========================================================================
111 * FUNCTION   : mm_camera_dispatch_app_event
112 *
113 * DESCRIPTION: dispatch event to apps who regitster for event notify
114 *
115 * PARAMETERS :
116 *   @cmd_cb: ptr to a struct storing event info
117 *   @user_data: user data ptr (camera object)
118 *
119 * RETURN     : none
120 *==========================================================================*/
121static void mm_camera_dispatch_app_event(mm_camera_cmdcb_t *cmd_cb,
122                                         void* user_data)
123{
124    int i;
125    mm_camera_event_t *event = &cmd_cb->u.evt;
126    mm_camera_obj_t * my_obj = (mm_camera_obj_t *)user_data;
127    if (NULL != my_obj) {
128        mm_camera_cmd_thread_name(my_obj->evt_thread.threadName);
129        pthread_mutex_lock(&my_obj->cb_lock);
130        for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
131            if(my_obj->evt.evt[i].evt_cb) {
132                my_obj->evt.evt[i].evt_cb(
133                    my_obj->my_hdl,
134                    event,
135                    my_obj->evt.evt[i].user_data);
136            }
137        }
138        pthread_mutex_unlock(&my_obj->cb_lock);
139    }
140}
141
142/*===========================================================================
143 * FUNCTION   : mm_camera_event_notify
144 *
145 * DESCRIPTION: callback to handle event notify from kernel. This call will
146 *              dequeue event from kernel.
147 *
148 * PARAMETERS :
149 *   @user_data: user data ptr (camera object)
150 *
151 * RETURN     : none
152 *==========================================================================*/
153static void mm_camera_event_notify(void* user_data)
154{
155    struct v4l2_event ev;
156    struct msm_v4l2_event_data *msm_evt = NULL;
157    int rc;
158    mm_camera_event_t evt;
159    memset(&evt, 0, sizeof(mm_camera_event_t));
160
161    mm_camera_obj_t *my_obj = (mm_camera_obj_t*)user_data;
162    if (NULL != my_obj) {
163        /* read evt */
164        memset(&ev, 0, sizeof(ev));
165        rc = ioctl(my_obj->ctrl_fd, VIDIOC_DQEVENT, &ev);
166
167        if (rc >= 0 && ev.id == MSM_CAMERA_MSM_NOTIFY) {
168            msm_evt = (struct msm_v4l2_event_data *)ev.u.data;
169            switch (msm_evt->command) {
170            case CAM_EVENT_TYPE_DAEMON_PULL_REQ:
171                evt.server_event_type = CAM_EVENT_TYPE_DAEMON_PULL_REQ;
172                mm_camera_enqueue_evt(my_obj, &evt);
173                break;
174            case CAM_EVENT_TYPE_MAP_UNMAP_DONE:
175                pthread_mutex_lock(&my_obj->evt_lock);
176                my_obj->evt_rcvd.server_event_type = msm_evt->command;
177                my_obj->evt_rcvd.status = msm_evt->status;
178                pthread_cond_signal(&my_obj->evt_cond);
179                pthread_mutex_unlock(&my_obj->evt_lock);
180                break;
181            case CAM_EVENT_TYPE_INT_TAKE_JPEG:
182            case CAM_EVENT_TYPE_INT_TAKE_RAW:
183                {
184                    evt.server_event_type = msm_evt->command;
185                    mm_camera_enqueue_evt(my_obj, &evt);
186                }
187                break;
188            case MSM_CAMERA_PRIV_SHUTDOWN:
189                {
190                    LOGE("Camera Event DAEMON DIED received");
191                    evt.server_event_type = CAM_EVENT_TYPE_DAEMON_DIED;
192                    mm_camera_enqueue_evt(my_obj, &evt);
193                }
194                break;
195            case CAM_EVENT_TYPE_CAC_DONE:
196                {
197                    evt.server_event_type = CAM_EVENT_TYPE_CAC_DONE;
198                    mm_camera_enqueue_evt(my_obj, &evt);
199                }
200                break;
201            default:
202                break;
203            }
204        }
205    }
206}
207
208/*===========================================================================
209 * FUNCTION   : mm_camera_enqueue_evt
210 *
211 * DESCRIPTION: enqueue received event into event queue to be processed by
212 *              event thread.
213 *
214 * PARAMETERS :
215 *   @my_obj   : ptr to a camera object
216 *   @event    : event to be queued
217 *
218 * RETURN     : int32_t type of status
219 *              0  -- success
220 *              -1 -- failure
221 *==========================================================================*/
222int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
223                              mm_camera_event_t *event)
224{
225    int32_t rc = 0;
226    mm_camera_cmdcb_t *node = NULL;
227
228    node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
229    if (NULL != node) {
230        memset(node, 0, sizeof(mm_camera_cmdcb_t));
231        node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB;
232        node->u.evt = *event;
233
234        /* enqueue to evt cmd thread */
235        cam_queue_enq(&(my_obj->evt_thread.cmd_queue), node);
236        /* wake up evt cmd thread */
237        cam_sem_post(&(my_obj->evt_thread.cmd_sem));
238    } else {
239        LOGE("No memory for mm_camera_node_t");
240        rc = -1;
241    }
242
243    return rc;
244}
245
246/*===========================================================================
247 * FUNCTION   : mm_camera_open
248 *
249 * DESCRIPTION: open a camera
250 *
251 * PARAMETERS :
252 *   @my_obj   : ptr to a camera object
253 *
254 * RETURN     : int32_t type of status
255 *              0  -- success
256 *              -1 -- failure
257 *==========================================================================*/
258int32_t mm_camera_open(mm_camera_obj_t *my_obj)
259{
260    char dev_name[MM_CAMERA_DEV_NAME_LEN];
261    int32_t rc = 0;
262    int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES;
263    uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP;
264    int cam_idx = 0;
265    const char *dev_name_value = NULL;
266    int l_errno = 0;
267
268    LOGD("begin\n");
269
270    if (NULL == my_obj) {
271        goto on_error;
272    }
273    dev_name_value = mm_camera_util_get_dev_name(my_obj->my_hdl);
274    if (NULL == dev_name_value) {
275        goto on_error;
276    }
277    snprintf(dev_name, sizeof(dev_name), "/dev/%s",
278             dev_name_value);
279    sscanf(dev_name, "/dev/video%d", &cam_idx);
280    LOGD("dev name = %s, cam_idx = %d", dev_name, cam_idx);
281
282    do{
283        n_try--;
284        errno = 0;
285        my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);
286        l_errno = errno;
287        LOGD("ctrl_fd = %d, errno == %d", my_obj->ctrl_fd, l_errno);
288        if((my_obj->ctrl_fd >= 0) || (errno != EIO && errno != ETIMEDOUT) || (n_try <= 0 )) {
289            break;
290        }
291        LOGE("Failed with %s error, retrying after %d milli-seconds",
292              strerror(errno), sleep_msec);
293        usleep(sleep_msec * 1000U);
294    }while (n_try > 0);
295
296    if (my_obj->ctrl_fd < 0) {
297        LOGE("cannot open control fd of '%s' (%s)\n",
298                  dev_name, strerror(l_errno));
299        if (l_errno == EBUSY)
300            rc = -EUSERS;
301        else
302            rc = -1;
303        goto on_error;
304    } else {
305        mm_camera_get_session_id(my_obj, &my_obj->sessionid);
306        LOGH("Camera Opened id = %d sessionid = %d", cam_idx, my_obj->sessionid);
307    }
308
309#ifdef DAEMON_PRESENT
310    /* open domain socket*/
311    n_try = MM_CAMERA_DEV_OPEN_TRIES;
312    do {
313        n_try--;
314        my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP);
315        l_errno = errno;
316        LOGD("ds_fd = %d, errno = %d", my_obj->ds_fd, l_errno);
317        if((my_obj->ds_fd >= 0) || (n_try <= 0 )) {
318            LOGD("opened, break out while loop");
319            break;
320        }
321        LOGD("failed with I/O error retrying after %d milli-seconds",
322              sleep_msec);
323        usleep(sleep_msec * 1000U);
324    } while (n_try > 0);
325
326    if (my_obj->ds_fd < 0) {
327        LOGE("cannot open domain socket fd of '%s'(%s)\n",
328                  dev_name, strerror(l_errno));
329        rc = -1;
330        goto on_error;
331    }
332#else /* DAEMON_PRESENT */
333    cam_status_t cam_status;
334    cam_status = mm_camera_module_open_session(my_obj->sessionid,
335            mm_camera_module_event_handler);
336    if (cam_status < 0) {
337        LOGE("Failed to open session");
338        if (cam_status == CAM_STATUS_BUSY) {
339            rc = -EUSERS;
340        } else {
341            rc = -1;
342        }
343        goto on_error;
344    }
345#endif /* DAEMON_PRESENT */
346
347    pthread_mutex_init(&my_obj->msg_lock, NULL);
348    pthread_mutex_init(&my_obj->cb_lock, NULL);
349    pthread_mutex_init(&my_obj->evt_lock, NULL);
350    PTHREAD_COND_INIT(&my_obj->evt_cond);
351
352    LOGD("Launch evt Thread in Cam Open");
353    snprintf(my_obj->evt_thread.threadName, THREAD_NAME_SIZE, "CAM_Dispatch");
354    mm_camera_cmd_thread_launch(&my_obj->evt_thread,
355                                mm_camera_dispatch_app_event,
356                                (void *)my_obj);
357
358    /* launch event poll thread
359     * we will add evt fd into event poll thread upon user first register for evt */
360    LOGD("Launch evt Poll Thread in Cam Open");
361    snprintf(my_obj->evt_poll_thread.threadName, THREAD_NAME_SIZE, "CAM_evntPoll");
362    mm_camera_poll_thread_launch(&my_obj->evt_poll_thread,
363                                 MM_CAMERA_POLL_TYPE_EVT);
364    mm_camera_evt_sub(my_obj, TRUE);
365
366    /* unlock cam_lock, we need release global intf_lock in camera_open(),
367     * in order not block operation of other Camera in dual camera use case.*/
368    pthread_mutex_unlock(&my_obj->cam_lock);
369    LOGD("end (rc = %d)\n", rc);
370    return rc;
371
372on_error:
373
374    if (NULL == dev_name_value) {
375        LOGE("Invalid device name\n");
376        rc = -1;
377    }
378
379    if (NULL == my_obj) {
380        LOGE("Invalid camera object\n");
381        rc = -1;
382    } else {
383        if (my_obj->ctrl_fd >= 0) {
384            close(my_obj->ctrl_fd);
385            my_obj->ctrl_fd = -1;
386        }
387#ifdef DAEMON_PRESENT
388        if (my_obj->ds_fd >= 0) {
389            mm_camera_socket_close(my_obj->ds_fd);
390            my_obj->ds_fd = -1;
391        }
392#endif
393    }
394
395    /* unlock cam_lock, we need release global intf_lock in camera_open(),
396     * in order not block operation of other Camera in dual camera use case.*/
397    pthread_mutex_unlock(&my_obj->cam_lock);
398    return rc;
399}
400
401/*===========================================================================
402 * FUNCTION   : mm_camera_close
403 *
404 * DESCRIPTION: enqueue received event into event queue to be processed by
405 *              event thread.
406 *
407 * PARAMETERS :
408 *   @my_obj   : ptr to a camera object
409 *   @event    : event to be queued
410 *
411 * RETURN     : int32_t type of status
412 *              0  -- success
413 *              -1 -- failure
414 *==========================================================================*/
415int32_t mm_camera_close(mm_camera_obj_t *my_obj)
416{
417    LOGD("unsubscribe evt");
418
419#ifndef DAEMON_PRESENT
420    mm_camera_module_close_session(my_obj->sessionid);
421#endif /* DAEMON_PRESENT */
422
423    mm_camera_evt_sub(my_obj, FALSE);
424
425    LOGD("Close evt Poll Thread in Cam Close");
426    mm_camera_poll_thread_release(&my_obj->evt_poll_thread);
427
428    LOGD("Close evt cmd Thread in Cam Close");
429    mm_camera_cmd_thread_release(&my_obj->evt_thread);
430
431    if(my_obj->ctrl_fd >= 0) {
432        close(my_obj->ctrl_fd);
433        my_obj->ctrl_fd = -1;
434    }
435
436#ifdef DAEMON_PRESENT
437    if(my_obj->ds_fd >= 0) {
438        mm_camera_socket_close(my_obj->ds_fd);
439        my_obj->ds_fd = -1;
440    }
441#endif
442
443    pthread_mutex_destroy(&my_obj->msg_lock);
444    pthread_mutex_destroy(&my_obj->cb_lock);
445    pthread_mutex_destroy(&my_obj->evt_lock);
446    pthread_cond_destroy(&my_obj->evt_cond);
447    pthread_mutex_unlock(&my_obj->cam_lock);
448    return 0;
449}
450
451/*===========================================================================
452 * FUNCTION   : mm_camera_register_event_notify_internal
453 *
454 * DESCRIPTION: internal implementation for registering callback for event notify.
455 *
456 * PARAMETERS :
457 *   @my_obj   : ptr to a camera object
458 *   @evt_cb   : callback to be registered to handle event notify
459 *   @user_data: user data ptr
460 *
461 * RETURN     : int32_t type of status
462 *              0  -- success
463 *              -1 -- failure
464 *==========================================================================*/
465int32_t mm_camera_register_event_notify_internal(mm_camera_obj_t *my_obj,
466                                                 mm_camera_event_notify_t evt_cb,
467                                                 void * user_data)
468{
469    int i;
470    int rc = -1;
471    mm_camera_evt_obj_t *evt_array = NULL;
472
473    pthread_mutex_lock(&my_obj->cb_lock);
474    evt_array = &my_obj->evt;
475    if(evt_cb) {
476        /* this is reg case */
477        for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
478            if(evt_array->evt[i].user_data == NULL) {
479                evt_array->evt[i].evt_cb = evt_cb;
480                evt_array->evt[i].user_data = user_data;
481                evt_array->reg_count++;
482                rc = 0;
483                break;
484            }
485        }
486    } else {
487        /* this is unreg case */
488        for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
489            if(evt_array->evt[i].user_data == user_data) {
490                evt_array->evt[i].evt_cb = NULL;
491                evt_array->evt[i].user_data = NULL;
492                evt_array->reg_count--;
493                rc = 0;
494                break;
495            }
496        }
497    }
498
499    pthread_mutex_unlock(&my_obj->cb_lock);
500    return rc;
501}
502
503/*===========================================================================
504 * FUNCTION   : mm_camera_register_event_notify
505 *
506 * DESCRIPTION: registering a callback for event notify.
507 *
508 * PARAMETERS :
509 *   @my_obj   : ptr to a camera object
510 *   @evt_cb   : callback to be registered to handle event notify
511 *   @user_data: user data ptr
512 *
513 * RETURN     : int32_t type of status
514 *              0  -- success
515 *              -1 -- failure
516 *==========================================================================*/
517int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj,
518                                        mm_camera_event_notify_t evt_cb,
519                                        void * user_data)
520{
521    int rc = -1;
522    rc = mm_camera_register_event_notify_internal(my_obj,
523                                                  evt_cb,
524                                                  user_data);
525    pthread_mutex_unlock(&my_obj->cam_lock);
526    return rc;
527}
528
529/*===========================================================================
530 * FUNCTION   : mm_camera_qbuf
531 *
532 * DESCRIPTION: enqueue buffer back to kernel
533 *
534 * PARAMETERS :
535 *   @my_obj       : camera object
536 *   @ch_id        : channel handle
537 *   @buf          : buf ptr to be enqueued
538 *
539 * RETURN     : int32_t type of status
540 *              0  -- success
541 *              -1 -- failure
542 *==========================================================================*/
543int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj,
544                       uint32_t ch_id,
545                       mm_camera_buf_def_t *buf)
546{
547    int rc = -1;
548    mm_channel_t * ch_obj = NULL;
549    ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
550
551    pthread_mutex_unlock(&my_obj->cam_lock);
552
553    /* we always assume qbuf will be done before channel/stream is fully stopped
554     * because qbuf is done within dataCB context
555     * in order to avoid deadlock, we are not locking ch_lock for qbuf */
556    if (NULL != ch_obj) {
557        rc = mm_channel_qbuf(ch_obj, buf);
558    }
559
560    return rc;
561}
562
563/*===========================================================================
564 * FUNCTION   : mm_camera_cancel_buf
565 *
566 * DESCRIPTION: Cancel an already queued buffer
567 *
568 * PARAMETERS :
569 *   @my_obj       : camera object
570 *   @ch_id        : channel handle
571 *
572 *   @buf          : buf ptr to be enqueued
573 *
574 * RETURN     : int32_t type of status
575 *              0  -- success
576 *              -1 -- failure
577 *==========================================================================*/
578int32_t mm_camera_cancel_buf(mm_camera_obj_t *my_obj,
579                       uint32_t ch_id,
580                       uint32_t stream_id,
581                       uint32_t buf_idx)
582{
583    int rc = -1;
584    mm_channel_t * ch_obj = NULL;
585    ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
586
587    if (NULL != ch_obj) {
588        pthread_mutex_unlock(&my_obj->cam_lock);
589        rc = mm_channel_cancel_buf(ch_obj,stream_id,buf_idx);
590    }
591
592    return rc;
593}
594
595/*===========================================================================
596 * FUNCTION   : mm_camera_get_queued_buf_count
597 *
598 * DESCRIPTION: return queued buffer count
599 *
600 * PARAMETERS :
601 *   @my_obj       : camera object
602 *   @ch_id        : channel handle
603 *   @stream_id : stream id
604 *
605 * RETURN     : queued buffer count
606 *==========================================================================*/
607int32_t mm_camera_get_queued_buf_count(mm_camera_obj_t *my_obj,
608        uint32_t ch_id, uint32_t stream_id)
609{
610    int rc = -1;
611    mm_channel_t * ch_obj = NULL;
612    uint32_t payload;
613    ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
614    payload = stream_id;
615
616    if (NULL != ch_obj) {
617        pthread_mutex_lock(&ch_obj->ch_lock);
618        pthread_mutex_unlock(&my_obj->cam_lock);
619        rc = mm_channel_fsm_fn(ch_obj,
620                MM_CHANNEL_EVT_GET_STREAM_QUEUED_BUF_COUNT,
621                (void *)&payload,
622                NULL);
623    } else {
624        pthread_mutex_unlock(&my_obj->cam_lock);
625    }
626
627    return rc;
628}
629
630/*===========================================================================
631 * FUNCTION   : mm_camera_query_capability
632 *
633 * DESCRIPTION: query camera capability
634 *
635 * PARAMETERS :
636 *   @my_obj: camera object
637 *
638 * RETURN     : int32_t type of status
639 *              0  -- success
640 *              -1 -- failure
641 *==========================================================================*/
642int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj)
643{
644    int32_t rc = 0;
645
646#ifdef DAEMON_PRESENT
647    struct v4l2_capability cap;
648    /* get camera capabilities */
649    memset(&cap, 0, sizeof(cap));
650    rc = ioctl(my_obj->ctrl_fd, VIDIOC_QUERYCAP, &cap);
651#else /* DAEMON_PRESENT */
652    cam_shim_packet_t *shim_cmd;
653    cam_shim_cmd_data shim_cmd_data;
654    memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
655    shim_cmd_data.command = MSM_CAMERA_PRIV_QUERY_CAP;
656    shim_cmd_data.stream_id = 0;
657    shim_cmd_data.value = NULL;
658    shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_GET_PARM,
659            my_obj->sessionid,&shim_cmd_data);
660    rc = mm_camera_module_send_cmd(shim_cmd);
661    mm_camera_destroy_shim_cmd_packet(shim_cmd);
662#endif /* DAEMON_PRESENT */
663    if (rc != 0) {
664        LOGE("cannot get camera capabilities, rc = %d, errno %d",
665                rc, errno);
666    }
667    pthread_mutex_unlock(&my_obj->cam_lock);
668    return rc;
669}
670
671/*===========================================================================
672 * FUNCTION   : mm_camera_set_parms
673 *
674 * DESCRIPTION: set parameters per camera
675 *
676 * PARAMETERS :
677 *   @my_obj       : camera object
678 *   @parms        : ptr to a param struct to be set to server
679 *
680 * RETURN     : int32_t type of status
681 *              0  -- success
682 *              -1 -- failure
683 * NOTE       : Assume the parms struct buf is already mapped to server via
684 *              domain socket. Corresponding fields of parameters to be set
685 *              are already filled in by upper layer caller.
686 *==========================================================================*/
687int32_t mm_camera_set_parms(mm_camera_obj_t *my_obj,
688                            parm_buffer_t *parms)
689{
690    int32_t rc = -1;
691    int32_t value = 0;
692    if (parms !=  NULL) {
693        rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
694            CAM_PRIV_PARM, &value);
695    }
696    pthread_mutex_unlock(&my_obj->cam_lock);
697    return rc;
698}
699
700/*===========================================================================
701 * FUNCTION   : mm_camera_get_parms
702 *
703 * DESCRIPTION: get parameters per camera
704 *
705 * PARAMETERS :
706 *   @my_obj       : camera object
707 *   @parms        : ptr to a param struct to be get from server
708 *
709 * RETURN     : int32_t type of status
710 *              0  -- success
711 *              -1 -- failure
712 * NOTE       : Assume the parms struct buf is already mapped to server via
713 *              domain socket. Parameters to be get from server are already
714 *              filled in by upper layer caller. After this call, corresponding
715 *              fields of requested parameters will be filled in by server with
716 *              detailed information.
717 *==========================================================================*/
718int32_t mm_camera_get_parms(mm_camera_obj_t *my_obj,
719                            parm_buffer_t *parms)
720{
721    int32_t rc = -1;
722    int32_t value = 0;
723    if (parms != NULL) {
724        rc = mm_camera_util_g_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
725    }
726    pthread_mutex_unlock(&my_obj->cam_lock);
727    return rc;
728}
729
730/*===========================================================================
731 * FUNCTION   : mm_camera_do_auto_focus
732 *
733 * DESCRIPTION: performing auto focus
734 *
735 * PARAMETERS :
736 *   @camera_handle: camera handle
737 *
738 * RETURN     : int32_t type of status
739 *              0  -- success
740 *              -1 -- failure
741 * NOTE       : if this call success, we will always assume there will
742 *              be an auto_focus event following up.
743 *==========================================================================*/
744int32_t mm_camera_do_auto_focus(mm_camera_obj_t *my_obj)
745{
746    int32_t rc = -1;
747    int32_t value = 0;
748    rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_DO_AUTO_FOCUS, &value);
749    pthread_mutex_unlock(&my_obj->cam_lock);
750    return rc;
751}
752
753/*===========================================================================
754 * FUNCTION   : mm_camera_cancel_auto_focus
755 *
756 * DESCRIPTION: cancel auto focus
757 *
758 * PARAMETERS :
759 *   @camera_handle: camera handle
760 *
761 * RETURN     : int32_t type of status
762 *              0  -- success
763 *              -1 -- failure
764 *==========================================================================*/
765int32_t mm_camera_cancel_auto_focus(mm_camera_obj_t *my_obj)
766{
767    int32_t rc = -1;
768    int32_t value = 0;
769    rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_CANCEL_AUTO_FOCUS, &value);
770    pthread_mutex_unlock(&my_obj->cam_lock);
771    return rc;
772}
773
774/*===========================================================================
775 * FUNCTION   : mm_camera_prepare_snapshot
776 *
777 * DESCRIPTION: prepare hardware for snapshot
778 *
779 * PARAMETERS :
780 *   @my_obj       : camera object
781 *   @do_af_flag   : flag indicating if AF is needed
782 *
783 * RETURN     : int32_t type of status
784 *              0  -- success
785 *              -1 -- failure
786 *==========================================================================*/
787int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
788                                   int32_t do_af_flag)
789{
790    int32_t rc = -1;
791    int32_t value = do_af_flag;
792    rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_PREPARE_SNAPSHOT, &value);
793    pthread_mutex_unlock(&my_obj->cam_lock);
794    return rc;
795}
796
797/*===========================================================================
798 * FUNCTION   : mm_camera_start_zsl_snapshot
799 *
800 * DESCRIPTION: start zsl snapshot
801 *
802 * PARAMETERS :
803 *   @my_obj       : camera object
804 *
805 * RETURN     : int32_t type of status
806 *              0  -- success
807 *              -1 -- failure
808 *==========================================================================*/
809int32_t mm_camera_start_zsl_snapshot(mm_camera_obj_t *my_obj)
810{
811    int32_t rc = -1;
812    int32_t value = 0;
813
814    rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
815             CAM_PRIV_START_ZSL_SNAPSHOT, &value);
816    return rc;
817}
818
819/*===========================================================================
820 * FUNCTION   : mm_camera_stop_zsl_snapshot
821 *
822 * DESCRIPTION: stop zsl capture
823 *
824 * PARAMETERS :
825 *   @my_obj       : camera object
826 *
827 * RETURN     : int32_t type of status
828 *              0  -- success
829 *              -1 -- failure
830 *==========================================================================*/
831int32_t mm_camera_stop_zsl_snapshot(mm_camera_obj_t *my_obj)
832{
833    int32_t rc = -1;
834    int32_t value;
835    rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
836             CAM_PRIV_STOP_ZSL_SNAPSHOT, &value);
837    return rc;
838}
839
840/*===========================================================================
841 * FUNCTION   : mm_camera_flush
842 *
843 * DESCRIPTION: flush the current camera state and buffers
844 *
845 * PARAMETERS :
846 *   @my_obj       : camera object
847 *
848 * RETURN     : int32_t type of status
849 *              0  -- success
850 *              -1 -- failure
851 *==========================================================================*/
852int32_t mm_camera_flush(mm_camera_obj_t *my_obj)
853{
854    int32_t rc = -1;
855    int32_t value;
856    rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
857            CAM_PRIV_FLUSH, &value);
858    pthread_mutex_unlock(&my_obj->cam_lock);
859    return rc;
860}
861
862/*===========================================================================
863 * FUNCTION   : mm_camera_add_channel
864 *
865 * DESCRIPTION: add a channel
866 *
867 * PARAMETERS :
868 *   @my_obj       : camera object
869 *   @attr         : bundle attribute of the channel if needed
870 *   @channel_cb   : callback function for bundle data notify
871 *   @userdata     : user data ptr
872 *
873 * RETURN     : uint32_t type of channel handle
874 *              0  -- invalid channel handle, meaning the op failed
875 *              >0 -- successfully added a channel with a valid handle
876 * NOTE       : if no bundle data notify is needed, meaning each stream in the
877 *              channel will have its own stream data notify callback, then
878 *              attr, channel_cb, and userdata can be NULL. In this case,
879 *              no matching logic will be performed in channel for the bundling.
880 *==========================================================================*/
881uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj,
882                               mm_camera_channel_attr_t *attr,
883                               mm_camera_buf_notify_t channel_cb,
884                               void *userdata)
885{
886    mm_channel_t *ch_obj = NULL;
887    uint8_t ch_idx = 0;
888    uint32_t ch_hdl = 0;
889
890    for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) {
891        if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) {
892            ch_obj = &my_obj->ch[ch_idx];
893            break;
894        }
895    }
896
897    if (NULL != ch_obj) {
898        /* initialize channel obj */
899        memset(ch_obj, 0, sizeof(mm_channel_t));
900        ch_hdl = mm_camera_util_generate_handler(ch_idx);
901        ch_obj->my_hdl = ch_hdl;
902        ch_obj->state = MM_CHANNEL_STATE_STOPPED;
903        ch_obj->cam_obj = my_obj;
904        pthread_mutex_init(&ch_obj->ch_lock, NULL);
905        ch_obj->sessionid = my_obj->sessionid;
906        mm_channel_init(ch_obj, attr, channel_cb, userdata);
907    }
908
909    pthread_mutex_unlock(&my_obj->cam_lock);
910
911    return ch_hdl;
912}
913
914/*===========================================================================
915 * FUNCTION   : mm_camera_del_channel
916 *
917 * DESCRIPTION: delete a channel by its handle
918 *
919 * PARAMETERS :
920 *   @my_obj       : camera object
921 *   @ch_id        : channel handle
922 *
923 * RETURN     : int32_t type of status
924 *              0  -- success
925 *              -1 -- failure
926 * NOTE       : all streams in the channel should be stopped already before
927 *              this channel can be deleted.
928 *==========================================================================*/
929int32_t mm_camera_del_channel(mm_camera_obj_t *my_obj,
930                              uint32_t ch_id)
931{
932    int32_t rc = -1;
933    mm_channel_t * ch_obj =
934        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
935
936    if (NULL != ch_obj) {
937        pthread_mutex_lock(&ch_obj->ch_lock);
938        pthread_mutex_unlock(&my_obj->cam_lock);
939
940        rc = mm_channel_fsm_fn(ch_obj,
941                               MM_CHANNEL_EVT_DELETE,
942                               NULL,
943                               NULL);
944
945        pthread_mutex_destroy(&ch_obj->ch_lock);
946        memset(ch_obj, 0, sizeof(mm_channel_t));
947    } else {
948        pthread_mutex_unlock(&my_obj->cam_lock);
949    }
950    return rc;
951}
952
953/*===========================================================================
954 * FUNCTION   : mm_camera_get_bundle_info
955 *
956 * DESCRIPTION: query bundle info of the channel
957 *
958 * PARAMETERS :
959 *   @my_obj       : camera object
960 *   @ch_id        : channel handle
961 *   @bundle_info  : bundle info to be filled in
962 *
963 * RETURN     : int32_t type of status
964 *              0  -- success
965 *              -1 -- failure
966 * NOTE       : all streams in the channel should be stopped already before
967 *              this channel can be deleted.
968 *==========================================================================*/
969int32_t mm_camera_get_bundle_info(mm_camera_obj_t *my_obj,
970                                  uint32_t ch_id,
971                                  cam_bundle_config_t *bundle_info)
972{
973    int32_t rc = -1;
974    mm_channel_t * ch_obj =
975        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
976
977    if (NULL != ch_obj) {
978        pthread_mutex_lock(&ch_obj->ch_lock);
979        pthread_mutex_unlock(&my_obj->cam_lock);
980
981        rc = mm_channel_fsm_fn(ch_obj,
982                               MM_CHANNEL_EVT_GET_BUNDLE_INFO,
983                               (void *)bundle_info,
984                               NULL);
985    } else {
986        pthread_mutex_unlock(&my_obj->cam_lock);
987    }
988    return rc;
989}
990
991/*===========================================================================
992 * FUNCTION   : mm_camera_link_stream
993 *
994 * DESCRIPTION: link a stream into a channel
995 *
996 * PARAMETERS :
997 *   @my_obj       : camera object
998 *   @ch_id        : channel handle
999 *   @stream_id    : stream that will be linked
1000 *   @linked_ch_id : channel in which the stream will be linked
1001 *
1002 * RETURN     : uint32_t type of stream handle
1003 *              0  -- invalid stream handle, meaning the op failed
1004 *              >0 -- successfully linked a stream with a valid handle
1005 *==========================================================================*/
1006uint32_t mm_camera_link_stream(mm_camera_obj_t *my_obj,
1007        uint32_t ch_id,
1008        uint32_t stream_id,
1009        uint32_t linked_ch_id)
1010{
1011    uint32_t s_hdl = 0;
1012    mm_channel_t * ch_obj =
1013            mm_camera_util_get_channel_by_handler(my_obj, linked_ch_id);
1014    mm_channel_t * owner_obj =
1015            mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1016
1017    if ((NULL != ch_obj) && (NULL != owner_obj)) {
1018        pthread_mutex_lock(&ch_obj->ch_lock);
1019        pthread_mutex_unlock(&my_obj->cam_lock);
1020
1021        mm_camera_stream_link_t stream_link;
1022        memset(&stream_link, 0, sizeof(mm_camera_stream_link_t));
1023        stream_link.ch = owner_obj;
1024        stream_link.stream_id = stream_id;
1025        mm_channel_fsm_fn(ch_obj,
1026                          MM_CHANNEL_EVT_LINK_STREAM,
1027                          (void*)&stream_link,
1028                          (void*)&s_hdl);
1029    } else {
1030        pthread_mutex_unlock(&my_obj->cam_lock);
1031    }
1032
1033    return s_hdl;
1034}
1035
1036/*===========================================================================
1037 * FUNCTION   : mm_camera_add_stream
1038 *
1039 * DESCRIPTION: add a stream into a channel
1040 *
1041 * PARAMETERS :
1042 *   @my_obj       : camera object
1043 *   @ch_id        : channel handle
1044 *
1045 * RETURN     : uint32_t type of stream handle
1046 *              0  -- invalid stream handle, meaning the op failed
1047 *              >0 -- successfully added a stream with a valid handle
1048 *==========================================================================*/
1049uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
1050                              uint32_t ch_id)
1051{
1052    uint32_t s_hdl = 0;
1053    mm_channel_t * ch_obj =
1054        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1055
1056    if (NULL != ch_obj) {
1057        pthread_mutex_lock(&ch_obj->ch_lock);
1058        pthread_mutex_unlock(&my_obj->cam_lock);
1059
1060        mm_channel_fsm_fn(ch_obj,
1061                          MM_CHANNEL_EVT_ADD_STREAM,
1062                          NULL,
1063                          (void *)&s_hdl);
1064    } else {
1065        pthread_mutex_unlock(&my_obj->cam_lock);
1066    }
1067
1068    return s_hdl;
1069}
1070
1071/*===========================================================================
1072 * FUNCTION   : mm_camera_del_stream
1073 *
1074 * DESCRIPTION: delete a stream by its handle
1075 *
1076 * PARAMETERS :
1077 *   @my_obj       : camera object
1078 *   @ch_id        : channel handle
1079 *   @stream_id    : stream handle
1080 *
1081 * RETURN     : int32_t type of status
1082 *              0  -- success
1083 *              -1 -- failure
1084 * NOTE       : stream should be stopped already before it can be deleted.
1085 *==========================================================================*/
1086int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
1087                             uint32_t ch_id,
1088                             uint32_t stream_id)
1089{
1090    int32_t rc = -1;
1091    mm_channel_t * ch_obj =
1092        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1093
1094    if (NULL != ch_obj) {
1095        pthread_mutex_lock(&ch_obj->ch_lock);
1096        pthread_mutex_unlock(&my_obj->cam_lock);
1097
1098        rc = mm_channel_fsm_fn(ch_obj,
1099                               MM_CHANNEL_EVT_DEL_STREAM,
1100                               (void *)&stream_id,
1101                               NULL);
1102    } else {
1103        pthread_mutex_unlock(&my_obj->cam_lock);
1104    }
1105
1106    return rc;
1107}
1108
1109/*===========================================================================
1110 * FUNCTION   : mm_camera_start_zsl_snapshot_ch
1111 *
1112 * DESCRIPTION: starts zsl snapshot for specific channel
1113 *
1114 * PARAMETERS :
1115 *   @my_obj       : camera object
1116 *   @ch_id        : channel handle
1117 *
1118 * RETURN     : int32_t type of status
1119 *              0  -- success
1120 *              -1 -- failure
1121 *==========================================================================*/
1122int32_t mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
1123        uint32_t ch_id)
1124{
1125    int32_t rc = -1;
1126    mm_channel_t * ch_obj =
1127        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1128
1129    if (NULL != ch_obj) {
1130        pthread_mutex_lock(&ch_obj->ch_lock);
1131        pthread_mutex_unlock(&my_obj->cam_lock);
1132
1133        rc = mm_channel_fsm_fn(ch_obj,
1134                               MM_CHANNEL_EVT_START_ZSL_SNAPSHOT,
1135                               NULL,
1136                               NULL);
1137    } else {
1138        pthread_mutex_unlock(&my_obj->cam_lock);
1139    }
1140
1141    return rc;
1142}
1143
1144/*===========================================================================
1145 * FUNCTION   : mm_camera_stop_zsl_snapshot_ch
1146 *
1147 * DESCRIPTION: stops zsl snapshot for specific channel
1148 *
1149 * PARAMETERS :
1150 *   @my_obj       : camera object
1151 *   @ch_id        : channel handle
1152 *
1153 * RETURN     : int32_t type of status
1154 *              0  -- success
1155 *              -1 -- failure
1156 *==========================================================================*/
1157int32_t mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
1158        uint32_t ch_id)
1159{
1160    int32_t rc = -1;
1161    mm_channel_t * ch_obj =
1162        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1163
1164    if (NULL != ch_obj) {
1165        pthread_mutex_lock(&ch_obj->ch_lock);
1166        pthread_mutex_unlock(&my_obj->cam_lock);
1167
1168        rc = mm_channel_fsm_fn(ch_obj,
1169                               MM_CHANNEL_EVT_STOP_ZSL_SNAPSHOT,
1170                               NULL,
1171                               NULL);
1172    } else {
1173        pthread_mutex_unlock(&my_obj->cam_lock);
1174    }
1175
1176    return rc;
1177}
1178
1179/*===========================================================================
1180 * FUNCTION   : mm_camera_config_stream
1181 *
1182 * DESCRIPTION: configure a stream
1183 *
1184 * PARAMETERS :
1185 *   @my_obj       : camera object
1186 *   @ch_id        : channel handle
1187 *   @stream_id    : stream handle
1188 *   @config       : stream configuration
1189 *
1190 * RETURN     : int32_t type of status
1191 *              0  -- success
1192 *              -1 -- failure
1193 *==========================================================================*/
1194int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
1195                                uint32_t ch_id,
1196                                uint32_t stream_id,
1197                                mm_camera_stream_config_t *config)
1198{
1199    int32_t rc = -1;
1200    mm_channel_t * ch_obj =
1201        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1202    mm_evt_paylod_config_stream_t payload;
1203
1204    if (NULL != ch_obj) {
1205        pthread_mutex_lock(&ch_obj->ch_lock);
1206        pthread_mutex_unlock(&my_obj->cam_lock);
1207
1208        memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t));
1209        payload.stream_id = stream_id;
1210        payload.config = config;
1211        rc = mm_channel_fsm_fn(ch_obj,
1212                               MM_CHANNEL_EVT_CONFIG_STREAM,
1213                               (void *)&payload,
1214                               NULL);
1215    } else {
1216        pthread_mutex_unlock(&my_obj->cam_lock);
1217    }
1218
1219    return rc;
1220}
1221
1222/*===========================================================================
1223 * FUNCTION   : mm_camera_start_channel
1224 *
1225 * DESCRIPTION: start a channel, which will start all streams in the channel
1226 *
1227 * PARAMETERS :
1228 *   @my_obj       : camera object
1229 *   @ch_id        : channel handle
1230 *
1231 * RETURN     : int32_t type of status
1232 *              0  -- success
1233 *              -1 -- failure
1234 *==========================================================================*/
1235int32_t mm_camera_start_channel(mm_camera_obj_t *my_obj, uint32_t ch_id)
1236{
1237    int32_t rc = -1;
1238    mm_channel_t * ch_obj =
1239        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1240
1241    if (NULL != ch_obj) {
1242        pthread_mutex_lock(&ch_obj->ch_lock);
1243        pthread_mutex_unlock(&my_obj->cam_lock);
1244
1245        rc = mm_channel_fsm_fn(ch_obj,
1246                               MM_CHANNEL_EVT_START,
1247                               NULL,
1248                               NULL);
1249    } else {
1250        pthread_mutex_unlock(&my_obj->cam_lock);
1251    }
1252
1253    return rc;
1254}
1255
1256/*===========================================================================
1257 * FUNCTION   : mm_camera_stop_channel
1258 *
1259 * DESCRIPTION: stop a channel, which will stop all streams in the channel
1260 *
1261 * PARAMETERS :
1262 *   @my_obj       : camera object
1263 *   @ch_id        : channel handle
1264 *
1265 * RETURN     : int32_t type of status
1266 *              0  -- success
1267 *              -1 -- failure
1268 *==========================================================================*/
1269int32_t mm_camera_stop_channel(mm_camera_obj_t *my_obj,
1270                               uint32_t ch_id)
1271{
1272    int32_t rc = 0;
1273    mm_channel_t * ch_obj =
1274        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1275
1276    if (NULL != ch_obj) {
1277        pthread_mutex_lock(&ch_obj->ch_lock);
1278        pthread_mutex_unlock(&my_obj->cam_lock);
1279
1280        rc = mm_channel_fsm_fn(ch_obj,
1281                               MM_CHANNEL_EVT_STOP,
1282                               NULL,
1283                               NULL);
1284    } else {
1285        pthread_mutex_unlock(&my_obj->cam_lock);
1286    }
1287    return rc;
1288}
1289
1290/*===========================================================================
1291 * FUNCTION   : mm_camera_request_super_buf
1292 *
1293 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
1294 *              frames from superbuf queue
1295 *
1296 * PARAMETERS :
1297 *   @my_obj       : camera object
1298 *   @ch_id        : channel handle
1299 *   @num_buf_requested : number of matched frames needed
1300 *
1301 * RETURN     : int32_t type of status
1302 *              0  -- success
1303 *              -1 -- failure
1304 *==========================================================================*/
1305int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj,
1306        uint32_t ch_id, mm_camera_req_buf_t *buf)
1307{
1308    int32_t rc = -1;
1309    mm_channel_t * ch_obj =
1310        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1311
1312    if ((NULL != ch_obj) && (buf != NULL)) {
1313        pthread_mutex_lock(&ch_obj->ch_lock);
1314        pthread_mutex_unlock(&my_obj->cam_lock);
1315
1316        rc = mm_channel_fsm_fn(ch_obj, MM_CHANNEL_EVT_REQUEST_SUPER_BUF,
1317                (void *)buf, NULL);
1318    } else {
1319        pthread_mutex_unlock(&my_obj->cam_lock);
1320    }
1321
1322    return rc;
1323}
1324
1325/*===========================================================================
1326 * FUNCTION   : mm_camera_cancel_super_buf_request
1327 *
1328 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
1329 *              of matched frames from superbuf queue
1330 *
1331 * PARAMETERS :
1332 *   @my_obj       : camera object
1333 *   @ch_id        : channel handle
1334 *
1335 * RETURN     : int32_t type of status
1336 *              0  -- success
1337 *              -1 -- failure
1338 *==========================================================================*/
1339int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id)
1340{
1341    int32_t rc = -1;
1342    mm_channel_t * ch_obj =
1343        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1344
1345    if (NULL != ch_obj) {
1346        pthread_mutex_lock(&ch_obj->ch_lock);
1347        pthread_mutex_unlock(&my_obj->cam_lock);
1348
1349        rc = mm_channel_fsm_fn(ch_obj,
1350                               MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF,
1351                               NULL,
1352                               NULL);
1353    } else {
1354        pthread_mutex_unlock(&my_obj->cam_lock);
1355    }
1356
1357    return rc;
1358}
1359
1360/*===========================================================================
1361 * FUNCTION   : mm_camera_flush_super_buf_queue
1362 *
1363 * DESCRIPTION: flush out all frames in the superbuf queue
1364 *
1365 * PARAMETERS :
1366 *   @my_obj       : camera object
1367 *   @ch_id        : channel handle
1368 *
1369 * RETURN     : int32_t type of status
1370 *              0  -- success
1371 *              -1 -- failure
1372 *==========================================================================*/
1373int32_t mm_camera_flush_super_buf_queue(mm_camera_obj_t *my_obj, uint32_t ch_id,
1374                                                             uint32_t frame_idx)
1375{
1376    int32_t rc = -1;
1377    mm_channel_t * ch_obj =
1378        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1379
1380    if (NULL != ch_obj) {
1381        pthread_mutex_lock(&ch_obj->ch_lock);
1382        pthread_mutex_unlock(&my_obj->cam_lock);
1383
1384        rc = mm_channel_fsm_fn(ch_obj,
1385                               MM_CHANNEL_EVT_FLUSH_SUPER_BUF_QUEUE,
1386                               (void *)&frame_idx,
1387                               NULL);
1388    } else {
1389        pthread_mutex_unlock(&my_obj->cam_lock);
1390    }
1391
1392    return rc;
1393}
1394
1395/*===========================================================================
1396 * FUNCTION   : mm_camera_config_channel_notify
1397 *
1398 * DESCRIPTION: configures the channel notification mode
1399 *
1400 * PARAMETERS :
1401 *   @my_obj       : camera object
1402 *   @ch_id        : channel handle
1403 *   @notify_mode  : notification mode
1404 *
1405 * RETURN     : int32_t type of status
1406 *              0  -- success
1407 *              -1 -- failure
1408 *==========================================================================*/
1409int32_t mm_camera_config_channel_notify(mm_camera_obj_t *my_obj,
1410                                        uint32_t ch_id,
1411                                        mm_camera_super_buf_notify_mode_t notify_mode)
1412{
1413    int32_t rc = -1;
1414    mm_channel_t * ch_obj =
1415        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1416
1417    if (NULL != ch_obj) {
1418        pthread_mutex_lock(&ch_obj->ch_lock);
1419        pthread_mutex_unlock(&my_obj->cam_lock);
1420
1421        rc = mm_channel_fsm_fn(ch_obj,
1422                               MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE,
1423                               (void *)&notify_mode,
1424                               NULL);
1425    } else {
1426        pthread_mutex_unlock(&my_obj->cam_lock);
1427    }
1428
1429    return rc;
1430}
1431
1432/*===========================================================================
1433 * FUNCTION   : mm_camera_set_stream_parms
1434 *
1435 * DESCRIPTION: set parameters per stream
1436 *
1437 * PARAMETERS :
1438 *   @my_obj       : camera object
1439 *   @ch_id        : channel handle
1440 *   @s_id         : stream handle
1441 *   @parms        : ptr to a param struct to be set to server
1442 *
1443 * RETURN     : int32_t type of status
1444 *              0  -- success
1445 *              -1 -- failure
1446 * NOTE       : Assume the parms struct buf is already mapped to server via
1447 *              domain socket. Corresponding fields of parameters to be set
1448 *              are already filled in by upper layer caller.
1449 *==========================================================================*/
1450int32_t mm_camera_set_stream_parms(mm_camera_obj_t *my_obj,
1451                                   uint32_t ch_id,
1452                                   uint32_t s_id,
1453                                   cam_stream_parm_buffer_t *parms)
1454{
1455    int32_t rc = -1;
1456    mm_evt_paylod_set_get_stream_parms_t payload;
1457    mm_channel_t * ch_obj =
1458        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1459
1460    if (NULL != ch_obj) {
1461        pthread_mutex_lock(&ch_obj->ch_lock);
1462        pthread_mutex_unlock(&my_obj->cam_lock);
1463
1464        memset(&payload, 0, sizeof(payload));
1465        payload.stream_id = s_id;
1466        payload.parms = parms;
1467
1468        rc = mm_channel_fsm_fn(ch_obj,
1469                               MM_CHANNEL_EVT_SET_STREAM_PARM,
1470                               (void *)&payload,
1471                               NULL);
1472    } else {
1473        pthread_mutex_unlock(&my_obj->cam_lock);
1474    }
1475
1476    return rc;
1477}
1478
1479/*===========================================================================
1480 * FUNCTION   : mm_camera_get_stream_parms
1481 *
1482 * DESCRIPTION: get parameters per stream
1483 *
1484 * PARAMETERS :
1485 *   @my_obj       : camera object
1486 *   @ch_id        : channel handle
1487 *   @s_id         : stream handle
1488 *   @parms        : ptr to a param struct to be get from server
1489 *
1490 * RETURN     : int32_t type of status
1491 *              0  -- success
1492 *              -1 -- failure
1493 * NOTE       : Assume the parms struct buf is already mapped to server via
1494 *              domain socket. Parameters to be get from server are already
1495 *              filled in by upper layer caller. After this call, corresponding
1496 *              fields of requested parameters will be filled in by server with
1497 *              detailed information.
1498 *==========================================================================*/
1499int32_t mm_camera_get_stream_parms(mm_camera_obj_t *my_obj,
1500                                   uint32_t ch_id,
1501                                   uint32_t s_id,
1502                                   cam_stream_parm_buffer_t *parms)
1503{
1504    int32_t rc = -1;
1505    mm_evt_paylod_set_get_stream_parms_t payload;
1506    mm_channel_t * ch_obj =
1507        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1508
1509    if (NULL != ch_obj) {
1510        pthread_mutex_lock(&ch_obj->ch_lock);
1511        pthread_mutex_unlock(&my_obj->cam_lock);
1512
1513        memset(&payload, 0, sizeof(payload));
1514        payload.stream_id = s_id;
1515        payload.parms = parms;
1516
1517        rc = mm_channel_fsm_fn(ch_obj,
1518                               MM_CHANNEL_EVT_GET_STREAM_PARM,
1519                               (void *)&payload,
1520                               NULL);
1521    } else {
1522        pthread_mutex_unlock(&my_obj->cam_lock);
1523    }
1524
1525    return rc;
1526}
1527
1528/*===========================================================================
1529 * FUNCTION   : mm_camera_do_stream_action
1530 *
1531 * DESCRIPTION: request server to perform stream based action. Maybe removed later
1532 *              if the functionality is included in mm_camera_set_parms
1533 *
1534 * PARAMETERS :
1535 *   @my_obj       : camera object
1536 *   @ch_id        : channel handle
1537 *   @s_id         : stream handle
1538 *   @actions      : ptr to an action struct buf to be performed by server
1539 *
1540 * RETURN     : int32_t type of status
1541 *              0  -- success
1542 *              -1 -- failure
1543 * NOTE       : Assume the action struct buf is already mapped to server via
1544 *              domain socket. Actions to be performed by server are already
1545 *              filled in by upper layer caller.
1546 *==========================================================================*/
1547int32_t mm_camera_do_stream_action(mm_camera_obj_t *my_obj,
1548                                   uint32_t ch_id,
1549                                   uint32_t stream_id,
1550                                   void *actions)
1551{
1552    int32_t rc = -1;
1553    mm_evt_paylod_do_stream_action_t payload;
1554    mm_channel_t * ch_obj =
1555        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1556
1557    if (NULL != ch_obj) {
1558        pthread_mutex_lock(&ch_obj->ch_lock);
1559        pthread_mutex_unlock(&my_obj->cam_lock);
1560
1561        memset(&payload, 0, sizeof(payload));
1562        payload.stream_id = stream_id;
1563        payload.actions = actions;
1564
1565        rc = mm_channel_fsm_fn(ch_obj,
1566                               MM_CHANNEL_EVT_DO_STREAM_ACTION,
1567                               (void*)&payload,
1568                               NULL);
1569    } else {
1570        pthread_mutex_unlock(&my_obj->cam_lock);
1571    }
1572
1573    return rc;
1574}
1575
1576/*===========================================================================
1577 * FUNCTION   : mm_camera_map_stream_buf
1578 *
1579 * DESCRIPTION: mapping stream buffer via domain socket to server
1580 *
1581 * PARAMETERS :
1582 *   @my_obj       : camera object
1583 *   @ch_id        : channel handle
1584 *   @s_id         : stream handle
1585 *   @buf_type     : type of buffer to be mapped. could be following values:
1586 *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
1587 *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
1588 *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1589 *   @buf_idx      : index of buffer within the stream buffers, only valid if
1590 *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1591 *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1592 *   @plane_idx    : plane index. If all planes share the same fd,
1593 *                   plane_idx = -1; otherwise, plean_idx is the
1594 *                   index to plane (0..num_of_planes)
1595 *   @fd           : file descriptor of the buffer
1596 *   @size         : size of the buffer
1597 *
1598 * RETURN     : int32_t type of status
1599 *              0  -- success
1600 *              -1 -- failure
1601 *==========================================================================*/
1602int32_t mm_camera_map_stream_buf(mm_camera_obj_t *my_obj,
1603                                 uint32_t ch_id,
1604                                 uint32_t stream_id,
1605                                 uint8_t buf_type,
1606                                 uint32_t buf_idx,
1607                                 int32_t plane_idx,
1608                                 int fd,
1609                                 size_t size,
1610                                 void *buffer)
1611{
1612    int32_t rc = -1;
1613    cam_buf_map_type payload;
1614    mm_channel_t * ch_obj =
1615        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1616
1617    if (NULL != ch_obj) {
1618        pthread_mutex_lock(&ch_obj->ch_lock);
1619        pthread_mutex_unlock(&my_obj->cam_lock);
1620
1621        memset(&payload, 0, sizeof(payload));
1622        payload.stream_id = stream_id;
1623        payload.type = buf_type;
1624        payload.frame_idx = buf_idx;
1625        payload.plane_idx = plane_idx;
1626        payload.fd = fd;
1627        payload.size = size;
1628        payload.buffer = buffer;
1629        rc = mm_channel_fsm_fn(ch_obj,
1630                               MM_CHANNEL_EVT_MAP_STREAM_BUF,
1631                               (void*)&payload,
1632                               NULL);
1633    } else {
1634        pthread_mutex_unlock(&my_obj->cam_lock);
1635    }
1636
1637    return rc;
1638}
1639
1640/*===========================================================================
1641 * FUNCTION   : mm_camera_map_stream_bufs
1642 *
1643 * DESCRIPTION: mapping stream buffers via domain socket to server
1644 *
1645 * PARAMETERS :
1646 *   @my_obj       : camera object
1647 *   @ch_id        : channel handle
1648 *   @buf_map_list : list of buffers to be mapped
1649 *
1650 * RETURN     : int32_t type of status
1651 *              0  -- success
1652 *              -1 -- failure
1653 *==========================================================================*/
1654int32_t mm_camera_map_stream_bufs(mm_camera_obj_t *my_obj,
1655                                  uint32_t ch_id,
1656                                  const cam_buf_map_type_list *buf_map_list)
1657{
1658    int32_t rc = -1;
1659    cam_buf_map_type_list payload;
1660    mm_channel_t * ch_obj =
1661        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1662
1663    if (NULL != ch_obj) {
1664        pthread_mutex_lock(&ch_obj->ch_lock);
1665        pthread_mutex_unlock(&my_obj->cam_lock);
1666
1667        memcpy(&payload, buf_map_list, sizeof(payload));
1668        rc = mm_channel_fsm_fn(ch_obj,
1669                               MM_CHANNEL_EVT_MAP_STREAM_BUFS,
1670                               (void*)&payload,
1671                               NULL);
1672    } else {
1673        pthread_mutex_unlock(&my_obj->cam_lock);
1674    }
1675
1676    return rc;
1677}
1678
1679/*===========================================================================
1680 * FUNCTION   : mm_camera_unmap_stream_buf
1681 *
1682 * DESCRIPTION: unmapping stream buffer via domain socket to server
1683 *
1684 * PARAMETERS :
1685 *   @my_obj       : camera object
1686 *   @ch_id        : channel handle
1687 *   @s_id         : stream handle
1688 *   @buf_type     : type of buffer to be mapped. could be following values:
1689 *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
1690 *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
1691 *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1692 *   @buf_idx      : index of buffer within the stream buffers, only valid if
1693 *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1694 *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1695 *   @plane_idx    : plane index. If all planes share the same fd,
1696 *                   plane_idx = -1; otherwise, plean_idx is the
1697 *                   index to plane (0..num_of_planes)
1698 *
1699 * RETURN     : int32_t type of status
1700 *              0  -- success
1701 *              -1 -- failure
1702 *==========================================================================*/
1703int32_t mm_camera_unmap_stream_buf(mm_camera_obj_t *my_obj,
1704                                   uint32_t ch_id,
1705                                   uint32_t stream_id,
1706                                   uint8_t buf_type,
1707                                   uint32_t buf_idx,
1708                                   int32_t plane_idx)
1709{
1710    int32_t rc = -1;
1711    cam_buf_unmap_type payload;
1712    mm_channel_t * ch_obj =
1713        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1714
1715    if (NULL != ch_obj) {
1716        pthread_mutex_lock(&ch_obj->ch_lock);
1717        pthread_mutex_unlock(&my_obj->cam_lock);
1718
1719        memset(&payload, 0, sizeof(payload));
1720        payload.stream_id = stream_id;
1721        payload.type = buf_type;
1722        payload.frame_idx = buf_idx;
1723        payload.plane_idx = plane_idx;
1724        rc = mm_channel_fsm_fn(ch_obj,
1725                               MM_CHANNEL_EVT_UNMAP_STREAM_BUF,
1726                               (void*)&payload,
1727                               NULL);
1728    } else {
1729        pthread_mutex_unlock(&my_obj->cam_lock);
1730    }
1731
1732    return rc;
1733}
1734
1735/*===========================================================================
1736 * FUNCTION   : mm_camera_evt_sub
1737 *
1738 * DESCRIPTION: subscribe/unsubscribe event notify from kernel
1739 *
1740 * PARAMETERS :
1741 *   @my_obj       : camera object
1742 *   @reg_flag     : 1 -- subscribe ; 0 -- unsubscribe
1743 *
1744 * RETURN     : int32_t type of status
1745 *              0  -- success
1746 *              -1 -- failure
1747 *==========================================================================*/
1748int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
1749                          uint8_t reg_flag)
1750{
1751    int32_t rc = 0;
1752    struct v4l2_event_subscription sub;
1753
1754    memset(&sub, 0, sizeof(sub));
1755    sub.type = MSM_CAMERA_V4L2_EVENT_TYPE;
1756    sub.id = MSM_CAMERA_MSM_NOTIFY;
1757    if(FALSE == reg_flag) {
1758        /* unsubscribe */
1759        rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1760        if (rc < 0) {
1761            LOGE("unsubscribe event rc = %d, errno %d",
1762                     rc, errno);
1763            return rc;
1764        }
1765        /* remove evt fd from the polling thraed when unreg the last event */
1766        rc = mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread,
1767                                               my_obj->my_hdl,
1768                                               mm_camera_sync_call);
1769    } else {
1770        rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
1771        if (rc < 0) {
1772            LOGE("subscribe event rc = %d, errno %d",
1773             rc, errno);
1774            return rc;
1775        }
1776        /* add evt fd to polling thread when subscribe the first event */
1777        rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
1778                                               my_obj->my_hdl,
1779                                               my_obj->ctrl_fd,
1780                                               mm_camera_event_notify,
1781                                               (void*)my_obj,
1782                                               mm_camera_sync_call);
1783    }
1784    return rc;
1785}
1786
1787/*===========================================================================
1788 * FUNCTION   : mm_camera_util_wait_for_event
1789 *
1790 * DESCRIPTION: utility function to wait for certain events
1791 *
1792 * PARAMETERS :
1793 *   @my_obj       : camera object
1794 *   @evt_mask     : mask for events to be waited. Any of event in the mask would
1795 *                   trigger the wait to end
1796 *   @status       : status of the event
1797 *
1798 * RETURN     : none
1799 *==========================================================================*/
1800void mm_camera_util_wait_for_event(mm_camera_obj_t *my_obj,
1801                                   uint32_t evt_mask,
1802                                   uint32_t *status)
1803{
1804    int32_t rc = 0;
1805    struct timespec ts;
1806
1807    pthread_mutex_lock(&my_obj->evt_lock);
1808    while (!(my_obj->evt_rcvd.server_event_type & evt_mask)) {
1809        clock_gettime(CLOCK_MONOTONIC, &ts);
1810        ts.tv_sec += WAIT_TIMEOUT;
1811        rc = pthread_cond_timedwait(&my_obj->evt_cond, &my_obj->evt_lock, &ts);
1812        if (rc) {
1813            LOGE("pthread_cond_timedwait of evt_mask 0x%x failed %d",
1814                     evt_mask, rc);
1815            break;
1816        }
1817    }
1818    if (!rc) {
1819        *status = my_obj->evt_rcvd.status;
1820    } else {
1821        *status = MSM_CAMERA_STATUS_FAIL;
1822    }
1823    /* reset local storage for recieved event for next event */
1824    memset(&my_obj->evt_rcvd, 0, sizeof(mm_camera_event_t));
1825    pthread_mutex_unlock(&my_obj->evt_lock);
1826}
1827
1828/*===========================================================================
1829 * FUNCTION   : mm_camera_util_bundled_sendmsg
1830 *
1831 * DESCRIPTION: utility function to send bundled msg via domain socket
1832 *
1833 * PARAMETERS :
1834 *   @my_obj       : camera object
1835 *   @msg          : message to be sent
1836 *   @buf_size     : size of the message to be sent
1837 *   @sendfds      : array of file descriptors to be sent
1838 *   @numfds       : number of file descriptors to be sent
1839 *
1840 * RETURN     : int32_t type of status
1841 *              0  -- success
1842 *              -1 -- failure
1843 *==========================================================================*/
1844int32_t mm_camera_util_bundled_sendmsg(mm_camera_obj_t *my_obj,
1845                                       void *msg,
1846                                       size_t buf_size,
1847                                       int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM],
1848                                       int numfds)
1849{
1850    int32_t rc = -1;
1851    uint32_t status;
1852
1853    /* need to lock msg_lock, since sendmsg until response back is deemed as one operation*/
1854    pthread_mutex_lock(&my_obj->msg_lock);
1855    if(mm_camera_socket_bundle_sendmsg(my_obj->ds_fd, msg, buf_size, sendfds, numfds) > 0) {
1856        /* wait for event that mapping/unmapping is done */
1857        mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);
1858        if (MSM_CAMERA_STATUS_SUCCESS == status) {
1859            rc = 0;
1860        }
1861    }
1862    pthread_mutex_unlock(&my_obj->msg_lock);
1863    return rc;
1864}
1865
1866/*===========================================================================
1867 * FUNCTION   : mm_camera_util_sendmsg
1868 *
1869 * DESCRIPTION: utility function to send msg via domain socket
1870 *
1871 * PARAMETERS :
1872 *   @my_obj       : camera object
1873 *   @msg          : message to be sent
1874 *   @buf_size     : size of the message to be sent
1875 *   @sendfd       : >0 if any file descriptor need to be passed across process
1876 *
1877 * RETURN     : int32_t type of status
1878 *              0  -- success
1879 *              -1 -- failure
1880 *==========================================================================*/
1881int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj,
1882                               void *msg,
1883                               size_t buf_size,
1884                               int sendfd)
1885{
1886    int32_t rc = -1;
1887    uint32_t status;
1888
1889    /* need to lock msg_lock, since sendmsg until reposonse back is deemed as one operation*/
1890    pthread_mutex_lock(&my_obj->msg_lock);
1891    if(mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd) > 0) {
1892        /* wait for event that mapping/unmapping is done */
1893        mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);
1894        if (MSM_CAMERA_STATUS_SUCCESS == status) {
1895            rc = 0;
1896        }
1897    }
1898    pthread_mutex_unlock(&my_obj->msg_lock);
1899    return rc;
1900}
1901
1902/*===========================================================================
1903 * FUNCTIOa   : mm_camera_map_buf
1904 *
1905 * DESCRIPTION: mapping camera buffer via domain socket to server
1906 *
1907 * PARAMETERS :
1908 *   @my_obj       : camera object
1909 *   @buf_type     : type of buffer to be mapped. could be following values:
1910 *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
1911 *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1912 *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1913 *   @fd           : file descriptor of the buffer
1914 *   @size         : size of the buffer
1915 *
1916 * RETURN     : int32_t type of status
1917 *              0  -- success
1918 *              -1 -- failure
1919 *==========================================================================*/
1920int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
1921        uint8_t buf_type, int fd, size_t size, void *buffer)
1922{
1923    int32_t rc = 0;
1924
1925    cam_sock_packet_t packet;
1926    memset(&packet, 0, sizeof(cam_sock_packet_t));
1927    packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING;
1928    packet.payload.buf_map.type = buf_type;
1929    packet.payload.buf_map.fd = fd;
1930    packet.payload.buf_map.size = size;
1931    packet.payload.buf_map.buffer = buffer;
1932#ifdef DAEMON_PRESENT
1933    rc = mm_camera_util_sendmsg(my_obj,
1934                                &packet,
1935                                sizeof(cam_sock_packet_t),
1936                                fd);
1937#else
1938    cam_shim_packet_t *shim_cmd;
1939    shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF,
1940            my_obj->sessionid, &packet);
1941    rc = mm_camera_module_send_cmd(shim_cmd);
1942    mm_camera_destroy_shim_cmd_packet(shim_cmd);
1943#endif
1944    pthread_mutex_unlock(&my_obj->cam_lock);
1945    return rc;
1946}
1947
1948/*===========================================================================
1949 * FUNCTION   : mm_camera_map_bufs
1950 *
1951 * DESCRIPTION: mapping camera buffers via domain socket to server
1952 *
1953 * PARAMETERS :
1954 *   @my_obj       : camera object
1955 *   @buf_map_list : list of buffers to be mapped
1956 *
1957 * RETURN     : int32_t type of status
1958 *              0  -- success
1959 *              -1 -- failure
1960 *==========================================================================*/
1961int32_t mm_camera_map_bufs(mm_camera_obj_t *my_obj,
1962                           const cam_buf_map_type_list* buf_map_list)
1963{
1964    int32_t rc = 0;
1965    cam_sock_packet_t packet;
1966    memset(&packet, 0, sizeof(cam_sock_packet_t));
1967    packet.msg_type = CAM_MAPPING_TYPE_FD_BUNDLED_MAPPING;
1968
1969    memcpy(&packet.payload.buf_map_list, buf_map_list,
1970           sizeof(packet.payload.buf_map_list));
1971
1972    int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM];
1973    uint32_t numbufs = packet.payload.buf_map_list.length;
1974    uint32_t i;
1975    for (i = 0; i < numbufs; i++) {
1976        sendfds[i] = packet.payload.buf_map_list.buf_maps[i].fd;
1977        packet.payload.buf_map_list.buf_maps[i].buffer =
1978                buf_map_list->buf_maps[i].buffer;
1979    }
1980    for (i = numbufs; i < CAM_MAX_NUM_BUFS_PER_STREAM; i++) {
1981        packet.payload.buf_map_list.buf_maps[i].fd = -1;
1982        sendfds[i] = -1;
1983    }
1984
1985#ifdef DAEMON_PRESENT
1986    rc = mm_camera_util_bundled_sendmsg(my_obj,
1987            &packet, sizeof(cam_sock_packet_t),
1988            sendfds, numbufs);
1989#else
1990    cam_shim_packet_t *shim_cmd;
1991    shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF,
1992            my_obj->sessionid, &packet);
1993    rc = mm_camera_module_send_cmd(shim_cmd);
1994    mm_camera_destroy_shim_cmd_packet(shim_cmd);
1995#endif
1996
1997    pthread_mutex_unlock(&my_obj->cam_lock);
1998    return rc;
1999}
2000
2001/*===========================================================================
2002 * FUNCTION   : mm_camera_unmap_buf
2003 *
2004 * DESCRIPTION: unmapping camera buffer via domain socket to server
2005 *
2006 * PARAMETERS :
2007 *   @my_obj       : camera object
2008 *   @buf_type     : type of buffer to be mapped. could be following values:
2009 *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
2010 *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
2011 *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
2012 *
2013 * RETURN     : int32_t type of status
2014 *              0  -- success
2015 *              -1 -- failure
2016 *==========================================================================*/
2017int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
2018                            uint8_t buf_type)
2019{
2020    int32_t rc = 0;
2021    cam_sock_packet_t packet;
2022    memset(&packet, 0, sizeof(cam_sock_packet_t));
2023    packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING;
2024    packet.payload.buf_unmap.type = buf_type;
2025#ifdef DAEMON_PRESENT
2026    rc = mm_camera_util_sendmsg(my_obj,
2027                                &packet,
2028                                sizeof(cam_sock_packet_t),
2029                                -1);
2030#else
2031    cam_shim_packet_t *shim_cmd;
2032    shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF,
2033            my_obj->sessionid, &packet);
2034    rc = mm_camera_module_send_cmd(shim_cmd);
2035    mm_camera_destroy_shim_cmd_packet(shim_cmd);
2036#endif
2037    pthread_mutex_unlock(&my_obj->cam_lock);
2038    return rc;
2039}
2040
2041/*===========================================================================
2042 * FUNCTION   : mm_camera_util_s_ctrl
2043 *
2044 * DESCRIPTION: utility function to send v4l2 ioctl for s_ctrl
2045 *
2046 * PARAMETERS :
2047 *   @my_obj     :Camera object
2048 *   @stream_id :streamID
2049 *   @fd      : file descritpor for sending ioctl
2050 *   @id      : control id
2051 *   @value   : value of the ioctl to be sent
2052 *
2053 * RETURN     : int32_t type of status
2054 *              0  -- success
2055 *              -1 -- failure
2056 *==========================================================================*/
2057int32_t mm_camera_util_s_ctrl(__unused mm_camera_obj_t *my_obj,
2058        __unused int stream_id, int32_t fd,
2059        uint32_t id, int32_t *value)
2060{
2061    int rc = 0;
2062
2063#ifdef DAEMON_PRESENT
2064    struct v4l2_control control;
2065    memset(&control, 0, sizeof(control));
2066    control.id = id;
2067    if (value != NULL) {
2068        control.value = *value;
2069    }
2070    rc = ioctl(fd, VIDIOC_S_CTRL, &control);
2071    LOGD("fd=%d, S_CTRL, id=0x%x, value = %p, rc = %d\n",
2072          fd, id, value, rc);
2073    if (rc < 0) {
2074        LOGE("ioctl failed %d, errno %d", rc, errno);
2075    } else if (value != NULL) {
2076        *value = control.value;
2077    }
2078#else /* DAEMON_PRESENT */
2079    cam_shim_packet_t *shim_cmd;
2080    cam_shim_cmd_data shim_cmd_data;
2081    (void)fd;
2082    (void)value;
2083    memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
2084
2085    shim_cmd_data.command = id;
2086    shim_cmd_data.stream_id = stream_id;
2087    shim_cmd_data.value = NULL;
2088    shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_SET_PARM,
2089            my_obj->sessionid,&shim_cmd_data);
2090    rc = mm_camera_module_send_cmd(shim_cmd);
2091    mm_camera_destroy_shim_cmd_packet(shim_cmd);
2092#endif /* DAEMON_PRESENT */
2093    return (rc >= 0)? 0 : -1;
2094}
2095
2096/*===========================================================================
2097 * FUNCTION   : mm_camera_util_g_ctrl
2098 *
2099 * DESCRIPTION: utility function to send v4l2 ioctl for g_ctrl
2100 *
2101 * PARAMETERS :
2102 *   @my_obj     :Camera object
2103 *   @stream_id :streamID
2104 *   @fd      : file descritpor for sending ioctl
2105 *   @id      : control id
2106 *   @value   : value of the ioctl to be sent
2107 *
2108 * RETURN     : int32_t type of status
2109 *              0  -- success
2110 *              -1 -- failure
2111 *==========================================================================*/
2112int32_t mm_camera_util_g_ctrl(__unused mm_camera_obj_t *my_obj,
2113        __unused int stream_id, int32_t fd, uint32_t id, int32_t *value)
2114{
2115    int rc = 0;
2116    struct v4l2_control control;
2117
2118    memset(&control, 0, sizeof(control));
2119    control.id = id;
2120    if (value != NULL) {
2121        control.value = *value;
2122    }
2123
2124#ifdef DAEMON_PRESENT
2125    rc = ioctl(fd, VIDIOC_G_CTRL, &control);
2126    LOGD("fd=%d, G_CTRL, id=0x%x, rc = %d\n", fd, id, rc);
2127    if (value != NULL) {
2128        *value = control.value;
2129    }
2130#else /* DAEMON_PRESENT */
2131    cam_shim_packet_t *shim_cmd;
2132    cam_shim_cmd_data shim_cmd_data;
2133    (void)fd;
2134    memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
2135
2136    shim_cmd_data.command = id;
2137    shim_cmd_data.stream_id = stream_id;
2138    shim_cmd_data.value = value;
2139    shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_GET_PARM,
2140            my_obj->sessionid, &shim_cmd_data);
2141
2142    rc = mm_camera_module_send_cmd(shim_cmd);
2143    mm_camera_destroy_shim_cmd_packet(shim_cmd);
2144#endif /* DAEMON_PRESENT */
2145    return (rc >= 0)? 0 : -1;
2146}
2147
2148/*===========================================================================
2149 * FUNCTION   : mm_camera_create_shim_cmd
2150 *
2151 * DESCRIPTION: Prepare comand packet to pass to back-end through shim layer
2152 *
2153 * PARAMETERS :
2154 *   @type                : type of command
2155 *   @sessionID        : camera sessionID
2156  *  @data                : command data
2157 *
2158 * RETURN     : NULL in case of failures
2159                      allocated pointer to shim packet
2160 *==========================================================================*/
2161cam_shim_packet_t *mm_camera_create_shim_cmd_packet(cam_shim_cmd_type type,
2162        uint32_t sessionID, void *data)
2163{
2164    cam_shim_packet_t *shim_pack = NULL;
2165    uint32_t i = 0;
2166
2167    shim_pack = (cam_shim_packet_t *)malloc(sizeof(cam_shim_packet_t));
2168    if (shim_pack == NULL) {
2169        LOGE("Cannot allocate a memory for shim packet");
2170        return NULL;
2171    }
2172    memset(shim_pack, 0, sizeof(cam_shim_packet_t));
2173    shim_pack->cmd_type = type;
2174    shim_pack->session_id = sessionID;
2175    switch (type) {
2176        case CAM_SHIM_SET_PARM:
2177        case CAM_SHIM_GET_PARM: {
2178            cam_shim_cmd_data *cmd_data = (cam_shim_cmd_data *)data;
2179            shim_pack->cmd_data = *cmd_data;
2180            break;
2181        }
2182        case CAM_SHIM_REG_BUF: {
2183            cam_reg_buf_t *cmd_data = (cam_reg_buf_t *)data;
2184            shim_pack->reg_buf = *cmd_data;
2185            break;
2186        }
2187        case CAM_SHIM_BUNDLE_CMD: {
2188            cam_shim_stream_cmd_packet_t *cmd_data = (cam_shim_stream_cmd_packet_t *)data;
2189            for (i = 0; i < cmd_data->stream_count; i++) {
2190                shim_pack->bundle_cmd.stream_event[i] = cmd_data->stream_event[i];
2191            }
2192            shim_pack->bundle_cmd.stream_count = cmd_data->stream_count;
2193            break;
2194        }
2195        default:
2196            LOGW("No Data for this command");
2197    }
2198    return shim_pack;
2199}
2200
2201/*===========================================================================
2202 * FUNCTION   : mm_camera_destroy_shim_cmd
2203 *
2204 * DESCRIPTION: destroy shim packet
2205 *
2206 * PARAMETERS :
2207 *   @cmd                : ptr to shim packet
2208
2209 * RETURN     : int32_t type of status
2210 *              0  -- success
2211 *              -1 -- failure
2212 *==========================================================================*/
2213int32_t mm_camera_destroy_shim_cmd_packet(cam_shim_packet_t *cmd)
2214{
2215    int32_t rc = 0;
2216    uint32_t i = 0, j = 0;
2217
2218    if (cmd == NULL) {
2219        LOGW("Command is NULL");
2220        return rc;
2221    }
2222
2223    switch (cmd->cmd_type) {
2224        case CAM_SHIM_SET_PARM:
2225        case CAM_SHIM_GET_PARM:
2226        case CAM_SHIM_REG_BUF:
2227            break;
2228        case CAM_SHIM_BUNDLE_CMD: {
2229            cam_shim_stream_cmd_packet_t *cmd_data = (cam_shim_stream_cmd_packet_t *)cmd;
2230            for (i = 0; i < cmd_data->stream_count; i++) {
2231                cam_shim_cmd_packet_t *stream_evt = &cmd_data->stream_event[i];
2232                for (j = 0; j < stream_evt->cmd_count; j++) {
2233                    if (stream_evt->cmd != NULL) {
2234                        if(stream_evt->cmd->cmd_type == CAM_SHIM_BUNDLE_CMD) {
2235                            mm_camera_destroy_shim_cmd_packet(stream_evt->cmd);
2236                        }
2237                        free(stream_evt->cmd);
2238                        stream_evt->cmd = NULL;
2239                    }
2240                }
2241            }
2242            break;
2243        }
2244        default:
2245            LOGW("No Data for this command");
2246    }
2247    free(cmd);
2248    cmd = NULL;
2249    return rc;
2250}
2251
2252/*===========================================================================
2253 * FUNCTION   : mm_camera_channel_advanced_capture
2254 *
2255 * DESCRIPTION: sets the channel advanced capture
2256 *
2257 * PARAMETERS :
2258 *   @my_obj       : camera object
2259 *   @ch_id        : channel handle
2260  *   @type : advanced capture type.
2261 *   @start_flag  : flag to indicate start/stop
2262  *   @in_value  : input configaration
2263 *
2264 * RETURN     : int32_t type of status
2265 *              0  -- success
2266 *              -1 -- failure
2267 *==========================================================================*/
2268int32_t mm_camera_channel_advanced_capture(mm_camera_obj_t *my_obj,
2269            uint32_t ch_id, mm_camera_advanced_capture_t type,
2270            uint32_t trigger, void *in_value)
2271{
2272    LOGD("E type = %d", type);
2273    int32_t rc = -1;
2274    mm_channel_t * ch_obj =
2275        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2276
2277    if (NULL != ch_obj) {
2278        pthread_mutex_lock(&ch_obj->ch_lock);
2279        pthread_mutex_unlock(&my_obj->cam_lock);
2280        switch (type) {
2281            case MM_CAMERA_AF_BRACKETING:
2282                rc = mm_channel_fsm_fn(ch_obj,
2283                                       MM_CHANNEL_EVT_AF_BRACKETING,
2284                                       (void *)&trigger,
2285                                       NULL);
2286                break;
2287            case MM_CAMERA_AE_BRACKETING:
2288                rc = mm_channel_fsm_fn(ch_obj,
2289                                       MM_CHANNEL_EVT_AE_BRACKETING,
2290                                       (void *)&trigger,
2291                                       NULL);
2292                break;
2293            case MM_CAMERA_FLASH_BRACKETING:
2294                rc = mm_channel_fsm_fn(ch_obj,
2295                                       MM_CHANNEL_EVT_FLASH_BRACKETING,
2296                                       (void *)&trigger,
2297                                       NULL);
2298                break;
2299            case MM_CAMERA_ZOOM_1X:
2300                rc = mm_channel_fsm_fn(ch_obj,
2301                                       MM_CHANNEL_EVT_ZOOM_1X,
2302                                       (void *)&trigger,
2303                                       NULL);
2304                break;
2305            case MM_CAMERA_FRAME_CAPTURE:
2306                rc = mm_channel_fsm_fn(ch_obj,
2307                                       MM_CAMERA_EVT_CAPTURE_SETTING,
2308                                       (void *)in_value,
2309                                       NULL);
2310                break;
2311            default:
2312                break;
2313        }
2314
2315    } else {
2316        pthread_mutex_unlock(&my_obj->cam_lock);
2317    }
2318
2319    LOGD("X");
2320    return rc;
2321}
2322
2323/*===========================================================================
2324 * FUNCTION   : mm_camera_get_session_id
2325 *
2326 * DESCRIPTION: get the session identity
2327 *
2328 * PARAMETERS :
2329 *   @my_obj       : camera object
2330 *   @sessionid: pointer to the output session id
2331 *
2332 * RETURN     : int32_t type of status
2333 *              0  -- success
2334 *              -1 -- failure
2335 * NOTE       : if this call succeeds, we will get a valid session id
2336 *==========================================================================*/
2337int32_t mm_camera_get_session_id(mm_camera_obj_t *my_obj,
2338        uint32_t* sessionid)
2339{
2340    int32_t rc = -1;
2341    int32_t value = 0;
2342    if(sessionid != NULL) {
2343        struct v4l2_control control;
2344        memset(&control, 0, sizeof(control));
2345        control.id = MSM_CAMERA_PRIV_G_SESSION_ID;
2346        control.value = value;
2347
2348        rc = ioctl(my_obj->ctrl_fd, VIDIOC_G_CTRL, &control);
2349        value = control.value;
2350        LOGD("fd=%d, get_session_id, id=0x%x, value = %d, rc = %d\n",
2351                 my_obj->ctrl_fd, MSM_CAMERA_PRIV_G_SESSION_ID,
2352                value, rc);
2353        *sessionid = value;
2354    }
2355    return rc;
2356}
2357
2358/*===========================================================================
2359 * FUNCTION   : mm_camera_sync_related_sensors
2360 *
2361 * DESCRIPTION: send sync cmd
2362 *
2363 * PARAMETERS :
2364 *   @my_obj       : camera object
2365 *   @parms        : ptr to the related cam info to be sent to server
2366 *
2367 * RETURN     : int32_t type of status
2368 *              0  -- success
2369 *              -1 -- failure
2370 * NOTE       : Assume the sync struct buf is already mapped to server via
2371 *              domain socket. Corresponding fields of parameters to be set
2372 *              are already filled in by upper layer caller.
2373 *==========================================================================*/
2374int32_t mm_camera_sync_related_sensors(mm_camera_obj_t *my_obj,
2375        cam_sync_related_sensors_event_info_t* parms)
2376{
2377    int32_t rc = -1;
2378    int32_t value = 0;
2379    if (parms !=  NULL) {
2380        rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
2381                CAM_PRIV_SYNC_RELATED_SENSORS, &value);
2382    }
2383    pthread_mutex_unlock(&my_obj->cam_lock);
2384    return rc;
2385}
2386
2387/*===========================================================================
2388 * FUNCTION   : mm_camera_reg_stream_buf_cb
2389 *
2390 * DESCRIPTION: Register callback for stream buffer
2391 *
2392 * PARAMETERS :
2393 *   @my_obj    : camera object
2394 *   @ch_id     : channel handle
2395 *   @stream_id : stream that will be linked
2396 *   @buf_cb    : special callback needs to be registered for stream buffer
2397 *   @cb_type   : Callback type SYNC/ASYNC
2398 *   @userdata  : user data pointer
2399 *
2400 * RETURN    : int32_t type of status
2401 *             0  -- success
2402 *             1 --  failure
2403 *==========================================================================*/
2404int32_t mm_camera_reg_stream_buf_cb(mm_camera_obj_t *my_obj,
2405        uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t stream_cb,
2406        mm_camera_stream_cb_type cb_type, void *userdata)
2407{
2408    int rc = 0;
2409    mm_stream_data_cb_t buf_cb;
2410    mm_channel_t * ch_obj =
2411            mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2412
2413    if (NULL != ch_obj) {
2414        pthread_mutex_lock(&ch_obj->ch_lock);
2415        pthread_mutex_unlock(&my_obj->cam_lock);
2416
2417        memset(&buf_cb, 0, sizeof(mm_stream_data_cb_t));
2418        buf_cb.cb = stream_cb;
2419        buf_cb.cb_count = -1;
2420        buf_cb.cb_type = cb_type;
2421        buf_cb.user_data = userdata;
2422
2423        mm_evt_paylod_reg_stream_buf_cb payload;
2424        memset(&payload, 0, sizeof(mm_evt_paylod_reg_stream_buf_cb));
2425        payload.buf_cb = buf_cb;
2426        payload.stream_id = stream_id;
2427        mm_channel_fsm_fn(ch_obj,
2428                MM_CHANNEL_EVT_REG_STREAM_BUF_CB,
2429                (void*)&payload, NULL);
2430    } else {
2431        pthread_mutex_unlock(&my_obj->cam_lock);
2432    }
2433    return rc;
2434}
2435
2436#ifdef QCAMERA_REDEFINE_LOG
2437
2438/*===========================================================================
2439 * DESCRIPTION: mm camera debug interface
2440 *
2441 *==========================================================================*/
2442pthread_mutex_t dbg_log_mutex;
2443
2444#undef LOG_TAG
2445#define LOG_TAG "QCamera"
2446#define CDBG_MAX_STR_LEN 1024
2447#define CDBG_MAX_LINE_LENGTH 256
2448
2449/* current trace loggin permissions
2450   * {NONE, ERR, WARN, HIGH, DEBUG, LOW, INFO} */
2451int g_cam_log[CAM_LAST_MODULE][CAM_GLBL_DBG_INFO + 1] = {
2452    {0, 1, 0, 0, 0, 0, 1}, /* CAM_NO_MODULE     */
2453    {0, 1, 0, 0, 0, 0, 1}, /* CAM_HAL_MODULE    */
2454    {0, 1, 0, 0, 0, 0, 1}, /* CAM_MCI_MODULE    */
2455    {0, 1, 0, 0, 0, 0, 1}, /* CAM_JPEG_MODULE   */
2456};
2457
2458/* string representation for logging level */
2459static const char *cam_dbg_level_to_str[] = {
2460     "",        /* CAM_GLBL_DBG_NONE  */
2461     "<ERROR>", /* CAM_GLBL_DBG_ERR   */
2462     "<WARN>", /* CAM_GLBL_DBG_WARN  */
2463     "<HIGH>", /* CAM_GLBL_DBG_HIGH  */
2464     "<DBG>", /* CAM_GLBL_DBG_DEBUG */
2465     "<LOW>", /* CAM_GLBL_DBG_LOW   */
2466     "<INFO>"  /* CAM_GLBL_DBG_INFO  */
2467};
2468
2469/* current trace logging configuration */
2470typedef struct {
2471   cam_global_debug_level_t  level;
2472   int                       initialized;
2473   const char               *name;
2474   const char               *prop;
2475} module_debug_t;
2476
2477static module_debug_t cam_loginfo[(int)CAM_LAST_MODULE] = {
2478  {CAM_GLBL_DBG_ERR, 1,
2479      "",         "persist.camera.global.debug"     }, /* CAM_NO_MODULE     */
2480  {CAM_GLBL_DBG_ERR, 1,
2481      "<HAL>", "persist.camera.hal.debug"        }, /* CAM_HAL_MODULE    */
2482  {CAM_GLBL_DBG_ERR, 1,
2483      "<MCI>", "persist.camera.mci.debug"        }, /* CAM_MCI_MODULE    */
2484  {CAM_GLBL_DBG_ERR, 1,
2485      "<JPEG>", "persist.camera.mmstill.logs"     }, /* CAM_JPEG_MODULE   */
2486};
2487
2488/** cam_get_dbg_level
2489 *
2490 *    @module: module name
2491 *    @level:  module debug logging level
2492 *
2493 *  Maps debug log string to value.
2494 *
2495 *  Return: logging level
2496 **/
2497__unused
2498static cam_global_debug_level_t cam_get_dbg_level(const char *module,
2499  char *pValue) {
2500
2501  cam_global_debug_level_t rc = CAM_GLBL_DBG_NONE;
2502
2503  if (!strcmp(pValue, "none")) {
2504    rc = CAM_GLBL_DBG_NONE;
2505  } else if (!strcmp(pValue, "warn")) {
2506    rc = CAM_GLBL_DBG_WARN;
2507  } else if (!strcmp(pValue, "debug")) {
2508    rc = CAM_GLBL_DBG_DEBUG;
2509  } else if (!strcmp(pValue, "error")) {
2510    rc = CAM_GLBL_DBG_ERR;
2511  } else if (!strcmp(pValue, "low")) {
2512    rc = CAM_GLBL_DBG_LOW;
2513  } else if (!strcmp(pValue, "high")) {
2514    rc = CAM_GLBL_DBG_HIGH;
2515  } else if (!strcmp(pValue, "info")) {
2516    rc = CAM_GLBL_DBG_INFO;
2517  } else {
2518    ALOGE("Invalid %s debug log level %s\n", module, pValue);
2519  }
2520
2521  ALOGD("%s debug log level: %s\n", module, cam_dbg_level_to_str[rc]);
2522
2523  return rc;
2524}
2525
2526/** cam_vsnprintf
2527 *    @pdst:   destination buffer pointer
2528 *    @size:   size of destination b uffer
2529 *    @pfmt:   string format
2530 *    @argptr: variabkle length argument list
2531 *
2532 *  Processes variable length argument list to a formatted string.
2533 *
2534 *  Return: n/a
2535 **/
2536static void cam_vsnprintf(char* pdst, unsigned int size,
2537                          const char* pfmt, va_list argptr) {
2538  int num_chars_written = 0;
2539
2540  pdst[0] = '\0';
2541  num_chars_written = vsnprintf(pdst, size, pfmt, argptr);
2542
2543  if ((num_chars_written >= (int)size) && (size > 0)) {
2544     /* Message length exceeds the buffer limit size */
2545     num_chars_written = size - 1;
2546     pdst[size - 1] = '\0';
2547  }
2548}
2549
2550/** mm_camera_debug_log
2551 *    @module: origin or log message
2552 *    @level:  logging level
2553 *    @func:   caller function name
2554 *    @line:   caller line number
2555 *    @fmt:    log message formatting string
2556 *    @...:    variable argument list
2557 *
2558 *  Generig logger method.
2559 *
2560 *  Return: N/A
2561 **/
2562void mm_camera_debug_log(const cam_modules_t module,
2563                   const cam_global_debug_level_t level,
2564                   const char *func, const int line, const char *fmt, ...) {
2565  char    str_buffer[CDBG_MAX_STR_LEN];
2566  va_list args;
2567
2568  va_start(args, fmt);
2569  cam_vsnprintf(str_buffer, CDBG_MAX_STR_LEN, fmt, args);
2570  va_end(args);
2571
2572  switch (level) {
2573  case CAM_GLBL_DBG_WARN:
2574    ALOGW("%s%s %s: %d: %s", cam_loginfo[module].name,
2575      cam_dbg_level_to_str[level], func, line, str_buffer);
2576    break;
2577  case CAM_GLBL_DBG_ERR:
2578    ALOGE("%s%s %s: %d: %s", cam_loginfo[module].name,
2579      cam_dbg_level_to_str[level], func, line, str_buffer);
2580    break;
2581  case CAM_GLBL_DBG_INFO:
2582    ALOGI("%s%s %s: %d: %s", cam_loginfo[module].name,
2583      cam_dbg_level_to_str[level], func, line, str_buffer);
2584    break;
2585  case CAM_GLBL_DBG_HIGH:
2586  case CAM_GLBL_DBG_DEBUG:
2587  case CAM_GLBL_DBG_LOW:
2588  default:
2589    ALOGD("%s%s %s: %d: %s", cam_loginfo[module].name,
2590      cam_dbg_level_to_str[level], func, line, str_buffer);
2591  }
2592}
2593
2594 /** mm_camera_set_dbg_log_properties
2595 *
2596 *  Set global and module log level properties.
2597 *
2598 *  Return: N/A
2599 **/
2600void mm_camera_set_dbg_log_properties(void) {
2601  int          i;
2602  unsigned int j;
2603  static int   boot_init = 1;
2604  char         property_value[PROPERTY_VALUE_MAX] = {0};
2605  char         default_value[PROPERTY_VALUE_MAX]  = {0};
2606
2607  if (boot_init) {
2608      boot_init = 0;
2609      pthread_mutex_init(&dbg_log_mutex, 0);
2610  }
2611
2612  /* set global and individual module logging levels */
2613  pthread_mutex_lock(&dbg_log_mutex);
2614  for (i = CAM_NO_MODULE; i < CAM_LAST_MODULE; i++) {
2615    cam_global_debug_level_t log_level;
2616    snprintf(default_value, PROPERTY_VALUE_MAX, "%d", (int)cam_loginfo[i].level);
2617    property_get(cam_loginfo[i].prop, property_value, default_value);
2618    log_level = (cam_global_debug_level_t)atoi(property_value);
2619
2620    /* fix KW warnings */
2621    if (log_level > CAM_GLBL_DBG_INFO) {
2622       log_level = CAM_GLBL_DBG_INFO;
2623    }
2624
2625    cam_loginfo[i].level = log_level;
2626
2627    /* The logging macros will produce a log message when logging level for
2628     * a module is less or equal to the level specified in the property for
2629     * the module, or less or equal the level specified by the global logging
2630     * property. Currently we don't allow INFO logging to be turned off */
2631    for (j = CAM_GLBL_DBG_ERR; j <= CAM_GLBL_DBG_LOW; j++) {
2632      g_cam_log[i][j] = (cam_loginfo[CAM_NO_MODULE].level != CAM_GLBL_DBG_NONE)     &&
2633                        (cam_loginfo[i].level             != CAM_GLBL_DBG_NONE)     &&
2634                        ((j                                <= cam_loginfo[i].level) ||
2635                         (j                                <= cam_loginfo[CAM_NO_MODULE].level));
2636    }
2637  }
2638  pthread_mutex_unlock(&dbg_log_mutex);
2639}
2640
2641#endif
2642