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
39volatile uint32_t kpi_camscope_flags = 0;
40volatile uint32_t kpi_camscope_frame_count = 0;
41
42static 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
48static FILE * camscope_fd[CAMSCOPE_SECTION_SIZE];
49static uint32_t camscope_num_bytes_stored[CAMSCOPE_SECTION_SIZE];
50static char * camscope_memstore[CAMSCOPE_SECTION_SIZE];
51static 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 */
61void 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 */
85static 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 */
103void 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 */
128uint32_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 */
154void 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 */
171void 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 */
183void camscope_mutex_unlock(camscope_section_type camscope_section) {
184    pthread_mutex_unlock(&(camscope_mutex[camscope_section]));
185}
186