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 */
57 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
58                           uint8_t reg_flag);
59 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
60                               mm_camera_event_t *event);
61 extern 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  *==========================================================================*/
mm_camera_util_get_channel_by_handler(mm_camera_obj_t * cam_obj,uint32_t handler)76 mm_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  *==========================================================================*/
mm_camera_util_chip_is_a_family(void)101 uint8_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  *==========================================================================*/
mm_camera_dispatch_app_event(mm_camera_cmdcb_t * cmd_cb,void * user_data)121 static 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  *==========================================================================*/
mm_camera_event_notify(void * user_data)153 static 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  *==========================================================================*/
mm_camera_enqueue_evt(mm_camera_obj_t * my_obj,mm_camera_event_t * event)222 int32_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  *==========================================================================*/
mm_camera_open(mm_camera_obj_t * my_obj)258 int32_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 
372 on_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  *==========================================================================*/
mm_camera_close(mm_camera_obj_t * my_obj)415 int32_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  *==========================================================================*/
mm_camera_register_event_notify_internal(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)465 int32_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  *==========================================================================*/
mm_camera_register_event_notify(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)517 int32_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  *==========================================================================*/
mm_camera_qbuf(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_buf_def_t * buf)543 int32_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  *==========================================================================*/
mm_camera_cancel_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,uint32_t buf_idx)578 int32_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  *==========================================================================*/
mm_camera_get_queued_buf_count(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id)607 int32_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  *==========================================================================*/
mm_camera_query_capability(mm_camera_obj_t * my_obj)642 int32_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  *==========================================================================*/
mm_camera_set_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)687 int32_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  *==========================================================================*/
mm_camera_get_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)718 int32_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  *==========================================================================*/
mm_camera_do_auto_focus(mm_camera_obj_t * my_obj)744 int32_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  *==========================================================================*/
mm_camera_cancel_auto_focus(mm_camera_obj_t * my_obj)765 int32_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  *==========================================================================*/
mm_camera_prepare_snapshot(mm_camera_obj_t * my_obj,int32_t do_af_flag)787 int32_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  *==========================================================================*/
mm_camera_start_zsl_snapshot(mm_camera_obj_t * my_obj)809 int32_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  *==========================================================================*/
mm_camera_stop_zsl_snapshot(mm_camera_obj_t * my_obj)831 int32_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  *==========================================================================*/
mm_camera_flush(mm_camera_obj_t * my_obj)852 int32_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  *==========================================================================*/
mm_camera_add_channel(mm_camera_obj_t * my_obj,mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t channel_cb,void * userdata)881 uint32_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  *==========================================================================*/
mm_camera_del_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)929 int32_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  *==========================================================================*/
mm_camera_get_bundle_info(mm_camera_obj_t * my_obj,uint32_t ch_id,cam_bundle_config_t * bundle_info)969 int32_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  *==========================================================================*/
mm_camera_link_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,uint32_t linked_ch_id)1006 uint32_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  *==========================================================================*/
mm_camera_add_stream(mm_camera_obj_t * my_obj,uint32_t ch_id)1049 uint32_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  *==========================================================================*/
mm_camera_del_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id)1086 int32_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  *==========================================================================*/
mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t * my_obj,uint32_t ch_id)1122 int32_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  *==========================================================================*/
mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t * my_obj,uint32_t ch_id)1157 int32_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  *==========================================================================*/
mm_camera_config_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,mm_camera_stream_config_t * config)1194 int32_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  *==========================================================================*/
mm_camera_start_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)1235 int32_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  *==========================================================================*/
mm_camera_stop_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)1269 int32_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  *==========================================================================*/
mm_camera_request_super_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_req_buf_t * buf)1305 int32_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  *==========================================================================*/
mm_camera_cancel_super_buf_request(mm_camera_obj_t * my_obj,uint32_t ch_id)1339 int32_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  *==========================================================================*/
mm_camera_flush_super_buf_queue(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t frame_idx)1373 int32_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  *==========================================================================*/
mm_camera_config_channel_notify(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_super_buf_notify_mode_t notify_mode)1409 int32_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  *==========================================================================*/
mm_camera_set_stream_parms(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t s_id,cam_stream_parm_buffer_t * parms)1450 int32_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  *==========================================================================*/
mm_camera_get_stream_parms(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t s_id,cam_stream_parm_buffer_t * parms)1499 int32_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  *==========================================================================*/
mm_camera_do_stream_action(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,void * actions)1547 int32_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  *==========================================================================*/
mm_camera_map_stream_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx,int fd,size_t size,void * buffer)1602 int32_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  *==========================================================================*/
mm_camera_map_stream_bufs(mm_camera_obj_t * my_obj,uint32_t ch_id,const cam_buf_map_type_list * buf_map_list)1654 int32_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  *==========================================================================*/
mm_camera_unmap_stream_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx)1703 int32_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  *==========================================================================*/
mm_camera_evt_sub(mm_camera_obj_t * my_obj,uint8_t reg_flag)1748 int32_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  *==========================================================================*/
mm_camera_util_wait_for_event(mm_camera_obj_t * my_obj,uint32_t evt_mask,uint32_t * status)1800 void 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  *==========================================================================*/
mm_camera_util_bundled_sendmsg(mm_camera_obj_t * my_obj,void * msg,size_t buf_size,int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM],int numfds)1844 int32_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  *==========================================================================*/
mm_camera_util_sendmsg(mm_camera_obj_t * my_obj,void * msg,size_t buf_size,int sendfd)1881 int32_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  *==========================================================================*/
mm_camera_map_buf(mm_camera_obj_t * my_obj,uint8_t buf_type,int fd,size_t size,void * buffer)1920 int32_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  *==========================================================================*/
mm_camera_map_bufs(mm_camera_obj_t * my_obj,const cam_buf_map_type_list * buf_map_list)1961 int32_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  *==========================================================================*/
mm_camera_unmap_buf(mm_camera_obj_t * my_obj,uint8_t buf_type)2017 int32_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  *==========================================================================*/
mm_camera_util_s_ctrl(__unused mm_camera_obj_t * my_obj,__unused int stream_id,int32_t fd,uint32_t id,int32_t * value)2057 int32_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  *==========================================================================*/
mm_camera_util_g_ctrl(__unused mm_camera_obj_t * my_obj,__unused int stream_id,int32_t fd,uint32_t id,int32_t * value)2112 int32_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  *==========================================================================*/
mm_camera_create_shim_cmd_packet(cam_shim_cmd_type type,uint32_t sessionID,void * data)2161 cam_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  *==========================================================================*/
mm_camera_destroy_shim_cmd_packet(cam_shim_packet_t * cmd)2213 int32_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  *==========================================================================*/
mm_camera_channel_advanced_capture(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_advanced_capture_t type,uint32_t trigger,void * in_value)2268 int32_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  *==========================================================================*/
mm_camera_get_session_id(mm_camera_obj_t * my_obj,uint32_t * sessionid)2337 int32_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  *==========================================================================*/
mm_camera_sync_related_sensors(mm_camera_obj_t * my_obj,cam_sync_related_sensors_event_info_t * parms)2374 int32_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  *==========================================================================*/
mm_camera_reg_stream_buf_cb(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,mm_camera_buf_notify_t stream_cb,mm_camera_stream_cb_type cb_type,void * userdata)2404 int32_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  *==========================================================================*/
2442 pthread_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} */
2451 int 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 */
2459 static 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 */
2470 typedef struct {
2471    cam_global_debug_level_t  level;
2472    int                       initialized;
2473    const char               *name;
2474    const char               *prop;
2475 } module_debug_t;
2476 
2477 static 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
cam_get_dbg_level(const char * module,char * pValue)2498 static 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  **/
cam_vsnprintf(char * pdst,unsigned int size,const char * pfmt,va_list argptr)2536 static 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  **/
mm_camera_debug_log(const cam_modules_t module,const cam_global_debug_level_t level,const char * func,const int line,const char * fmt,...)2562 void 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  **/
mm_camera_set_dbg_log_properties(void)2600 void 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