1 /* Copyright (c) 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 // Camera dependencies
31 #include <stdlib.h>
32 #include <string.h>
33 #include <pthread.h>
34 
35 #include "QCameraTrace.h"
36 
37 #define CAMSCOPE_MEMSTORE_SIZE 0x00100000 // 1MB
38 
39 volatile uint32_t kpi_camscope_flags = 0;
40 volatile uint32_t kpi_camscope_frame_count = 0;
41 
42 static const char * camscope_filenames[CAMSCOPE_SECTION_SIZE] = {
43     "/data/misc/camera/camscope_mmcamera.bin",
44     "/data/misc/camera/camscope_hal.bin",
45     "/data/misc/camera/camscope_jpeg.bin"
46 };
47 
48 static FILE * camscope_fd[CAMSCOPE_SECTION_SIZE];
49 static uint32_t camscope_num_bytes_stored[CAMSCOPE_SECTION_SIZE];
50 static char * camscope_memstore[CAMSCOPE_SECTION_SIZE];
51 static pthread_mutex_t camscope_mutex[CAMSCOPE_SECTION_SIZE];
52 
53 /* camscope_init:
54  *
55  *  @camscope_section: camscope section where this function is occurring
56  *
57  *  Initializes the CameraScope tool functionality
58  *
59  *  Return: N/A
60  */
camscope_init(camscope_section_type camscope_section)61 void camscope_init(camscope_section_type camscope_section) {
62     pthread_mutex_init(&(camscope_mutex[camscope_section]), NULL);
63     if (camscope_fd[camscope_section] == NULL) {
64         if(camscope_memstore[camscope_section] == NULL) {
65             camscope_memstore[camscope_section] =
66                 (char *)malloc(CAMSCOPE_MEMSTORE_SIZE);
67             if (camscope_memstore[camscope_section] == NULL) {
68               CLOGE(CAM_NO_MODULE, "Failed to allocate camscope memstore"
69                     "with size %d\n", CAMSCOPE_MEMSTORE_SIZE);
70             }
71         }
72         camscope_fd[camscope_section] =
73             fopen(camscope_filenames[camscope_section], "ab");
74     }
75 }
76 
77 /* camscope_flush:
78  *
79  *  @camscope_section: camscope section where this function is occurring
80  *
81  *  Flushes the camscope memstore to the file system
82  *
83  *  Return: N/A
84  */
camscope_flush(camscope_section_type camscope_section)85 static void camscope_flush(camscope_section_type camscope_section) {
86     if (camscope_fd[camscope_section] != NULL &&
87         camscope_memstore[camscope_section] != NULL) {
88         fwrite(camscope_memstore[camscope_section], sizeof(char),
89                camscope_num_bytes_stored[camscope_section],
90                camscope_fd[camscope_section]);
91         camscope_num_bytes_stored[camscope_section] = 0;
92     }
93 }
94 
95 /* camscope_destroy:
96  *
97  *  @camscope_section: camscope section where this function is occurring
98  *
99  *  Flushes any remaining data to the file system and cleans up CameraScope
100  *
101  *  Return: N/A
102  */
camscope_destroy(camscope_section_type camscope_section)103 void camscope_destroy(camscope_section_type camscope_section) {
104     if (camscope_fd[camscope_section] != NULL) {
105         pthread_mutex_lock(&(camscope_mutex[camscope_section]));
106         if(camscope_memstore[camscope_section] != NULL) {
107             camscope_flush(camscope_section);
108             free(camscope_memstore[camscope_section]);
109             camscope_memstore[camscope_section] = NULL;
110         }
111         fclose(camscope_fd[camscope_section]);
112         camscope_fd[camscope_section] = NULL;
113         pthread_mutex_unlock(&(camscope_mutex[camscope_section]));
114     }
115     pthread_mutex_destroy(&(camscope_mutex[camscope_section]));
116 }
117 
118 /* camscope_reserve:
119  *
120  *  @camscope_section:     camscope section where this function is occurring
121  *  @num_bytes_to_reserve: number in bytes to reserve on the memstore
122  *
123  *  Reserves a number of bytes on the memstore flushing to the
124  *  file system if remaining space is insufficient
125  *
126  *  Return: number of bytes successfully reserved on the memstore
127  */
camscope_reserve(camscope_section_type camscope_section,uint32_t num_bytes_to_reserve)128 uint32_t camscope_reserve(camscope_section_type camscope_section,
129                                  uint32_t num_bytes_to_reserve) {
130     uint32_t bytes_reserved = 0;
131     if (camscope_fd[camscope_section] != NULL &&
132         num_bytes_to_reserve <= CAMSCOPE_MEMSTORE_SIZE) {
133         int32_t size = CAMSCOPE_MEMSTORE_SIZE -
134                camscope_num_bytes_stored[camscope_section] -
135                num_bytes_to_reserve;
136         if (size < 0) {
137             camscope_flush(camscope_section);
138         }
139         bytes_reserved = num_bytes_to_reserve;
140     }
141     return bytes_reserved;
142 }
143 
144 /* camscope_store_data:
145  *
146  *  @camscope_section: camscope section where this function is occurring
147  *  @data:             data to be stored
148  *  @size:             size of data to be stored
149  *
150  *  Store the data to the memstore and calculate remaining space
151  *
152  *  Return: N/A
153  */
camscope_store_data(camscope_section_type camscope_section,void * data,uint32_t size)154 void camscope_store_data(camscope_section_type camscope_section,
155                        void* data, uint32_t size) {
156     if(camscope_memstore[camscope_section] != NULL) {
157         memcpy(camscope_memstore[camscope_section] +
158                camscope_num_bytes_stored[camscope_section], (char*)data, size);
159         camscope_num_bytes_stored[camscope_section] += size;
160     }
161 }
162 
163 /* camscope_mutex_lock:
164  *
165  *  @camscope_section: camscope section where this function is occurring
166  *
167  *  Lock the camscope mutex lock for the given camscope section
168  *
169  *  Return: N/A
170  */
camscope_mutex_lock(camscope_section_type camscope_section)171 void camscope_mutex_lock(camscope_section_type camscope_section) {
172     pthread_mutex_lock(&(camscope_mutex[camscope_section]));
173 }
174 
175 /* camscope_mutex_unlock:
176  *
177  *  @camscope_section: camscope section where this function is occurring
178  *
179  *  Unlock the camscope mutex lock for the given camscope section
180  *
181  *  Return: N/A
182  */
camscope_mutex_unlock(camscope_section_type camscope_section)183 void camscope_mutex_unlock(camscope_section_type camscope_section) {
184     pthread_mutex_unlock(&(camscope_mutex[camscope_section]));
185 }
186