blob: a8cfb5303954197505b56d8e279b73624df4f289 [file] [log] [blame]
Pengfei Liub4734232020-01-17 18:25:10 +08001#include <stdio.h>
2#include <unistd.h>
3#include <sys/types.h>
4#include <sys/stat.h>
5#include <fcntl.h>
6#include <string.h>
7#include <errno.h>
8#include <dvr_types.h>
9#include <dvr_utils.h>
Gong Ke2a0ebbe2021-05-25 15:22:50 +080010
11#ifdef __ANDROID_API__
hualing chena3f427d2021-03-24 15:30:00 +080012#include <cutils/properties.h>
Gong Ke2a0ebbe2021-05-25 15:22:50 +080013#endif
Pengfei Liub4734232020-01-17 18:25:10 +080014
wentao ma7d642782022-10-23 18:26:16 -070015#define _GNU_SOURCE
16#define __USE_GNU
17#include <search.h>
18
19static struct hsearch_data *prop_htab = NULL;
20
hualing chena540a7e2020-03-27 16:44:05 +080021/****************************************************************************
22 * Macro definitions
23 ***************************************************************************/
24
25/****************************************************************************
26 * Static functions
27 ***************************************************************************/
hualing chena540a7e2020-03-27 16:44:05 +080028
hualing chena540a7e2020-03-27 16:44:05 +080029/****************************************************************************
30 * API functions
31 ***************************************************************************/
32
hualing chena540a7e2020-03-27 16:44:05 +080033
34/**\brief Write a string cmd to a file
35 * \param[in] name, File name
36 * \param[in] cmd, String command
37 * \return DVR_SUCCESS On success
38 * \return Error code On failure
39 */
40
41int dvr_file_echo(const char *name, const char *cmd)
42{
43 int fd, len, ret;
44 if (name == NULL || cmd == NULL) {
45 return DVR_FAILURE;
46 }
47
hualing chena540a7e2020-03-27 16:44:05 +080048 fd = open(name, O_WRONLY);
49 if (fd == -1)
50 {
Wentao MA96f68962022-06-15 19:45:35 +080051 DVR_INFO("cannot open file \"%s\"", name);
hualing chena540a7e2020-03-27 16:44:05 +080052 return DVR_FAILURE;
53 }
54
55 len = strlen(cmd);
56
57 ret = write(fd, cmd, len);
58 if (ret != len)
59 {
Wentao MA96f68962022-06-15 19:45:35 +080060 DVR_INFO("write failed file:\"%s\" cmd:\"%s\" error:\"%s\"", name, cmd, strerror(errno));
hualing chena540a7e2020-03-27 16:44:05 +080061 close(fd);
62 return DVR_FAILURE;
63 }
64
65 close(fd);
66 return DVR_SUCCESS;
67}
68
69/**\brief read sysfs file
70 * \param[in] name, File name
71 * \param[out] buf, store sysfs node value
72 * \return DVR_SUCCESS On success
73 * \return Error code On failure
74 */
75
76int dvr_file_read(const char *name, char *buf, int len)
77{
78 FILE *fp;
79 char *ret;
80
81 if (name == NULL || buf == NULL) {
Wentao MA96f68962022-06-15 19:45:35 +080082 DVR_INFO("dvr_file_read error param is NULL");
hualing chena540a7e2020-03-27 16:44:05 +080083 return DVR_FAILURE;
84 }
85
hualing chena540a7e2020-03-27 16:44:05 +080086 fp = fopen(name, "r");
87 if (!fp)
88 {
Wentao MA96f68962022-06-15 19:45:35 +080089 DVR_INFO("cannot open file \"%s\"", name);
hualing chena540a7e2020-03-27 16:44:05 +080090 return DVR_FAILURE;
91 }
92
93 ret = fgets(buf, len, fp);
94 if (!ret)
95 {
Wentao MA96f68962022-06-15 19:45:35 +080096 DVR_INFO("read the file:\"%s\" error:\"%s\" failed", name, strerror(errno));
hualing chena540a7e2020-03-27 16:44:05 +080097 }
98
99 fclose(fp);
100 return ret ? DVR_SUCCESS : DVR_FAILURE;
101}
102
wentao ma7d642782022-10-23 18:26:16 -0700103/**\brief read property value
104 * \param[in] name, property name
105 * \param[out] buf, property value
hualing chena540a7e2020-03-27 16:44:05 +0800106 * \return DVR_SUCCESS On success
wentao ma7d642782022-10-23 18:26:16 -0700107 * \return DVR_FAILURE On failure
hualing chena540a7e2020-03-27 16:44:05 +0800108 */
hualing chena540a7e2020-03-27 16:44:05 +0800109int dvr_prop_read(const char *name, char *buf, int len)
110{
111 if (name == NULL || buf == NULL) {
wentao ma7d642782022-10-23 18:26:16 -0700112 DVR_ERROR("%s, property name or value buffer is NULL",__func__);
hualing chena540a7e2020-03-27 16:44:05 +0800113 return DVR_FAILURE;
114 }
115
wentao ma7d642782022-10-23 18:26:16 -0700116#ifdef __ANDROID_API__
117 memset(buf,0,len);
118 property_get(name, buf, "");
119 if (strlen(buf)>0) {
120 DVR_INFO("%s, Read property, name:%s, value:%s",__func__,name,buf);
hualing chena540a7e2020-03-27 16:44:05 +0800121 return DVR_SUCCESS;
122 }
wentao ma7d642782022-10-23 18:26:16 -0700123#endif
124
125 if (prop_htab == NULL) {
126 prop_htab = calloc(1,sizeof(struct hsearch_data));
127 if (prop_htab == NULL) {
128 DVR_ERROR("%s, Failed to allocate memory for prop_htab",__func__);
129 return DVR_FAILURE;
130 }
131 if (0 == hcreate_r(100,prop_htab))
132 {
133 DVR_ERROR("%s, Failed to create hash table with hcreate_r",__func__);
134 return DVR_FAILURE;
135 }
136 }
137
wentao.ma997da2f2022-11-14 16:31:59 +0800138 ENTRY e = {name,NULL}, *ep = NULL;
wentao ma7d642782022-10-23 18:26:16 -0700139 if (hsearch_r(e,FIND,&ep,prop_htab) == 0) {
140 DVR_ERROR("%s, Failed to read property %s",__func__,name);
141 return DVR_FAILURE;
142 }
143
144 strncpy(buf,ep->data,len);
145 DVR_INFO("%s, Read property from hash table, name:%s, value:%s",__func__,name,buf);
146 return DVR_SUCCESS;
147}
148
149/**\brief write property value
150 * \param[in] name, property name
151 * \param[in] value, property value
152 * \return DVR_SUCCESS On success
153 * \return DVR_FAILURE On failure
154 */
155int dvr_prop_write(const char *name, char *value)
156{
157 if (name == NULL || value == NULL) {
158 DVR_ERROR("%s: property name or value buffer is NULL",__func__);
159 return DVR_FAILURE;
160 }
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800161
162#ifdef __ANDROID_API__
wentao ma7d642782022-10-23 18:26:16 -0700163 property_set(name, value);
Gong Ke2a0ebbe2021-05-25 15:22:50 +0800164#endif
wentao ma7d642782022-10-23 18:26:16 -0700165
166 if (prop_htab == NULL) {
167 prop_htab = calloc(1,sizeof(struct hsearch_data));
168 if (prop_htab == NULL) {
169 DVR_ERROR("%s, Failed to allocate memory for prop_htab",__func__);
170 return DVR_FAILURE;
171 }
172 if (0 == hcreate_r(100,prop_htab))
173 {
174 DVR_ERROR("%s, Failed to create hash table with hcreate_r",__func__);
175 return DVR_FAILURE;
176 }
177 }
178
wentao.ma997da2f2022-11-14 16:31:59 +0800179 ENTRY e = {name,NULL}, *ep = NULL;
wentao ma7d642782022-10-23 18:26:16 -0700180 if (hsearch_r(e,FIND,&ep,prop_htab) != 0) {
181 // in case matched item is found
182 free(ep->data);
183 ep->data=strdup(value);
184 } else {
185 // in case no matched item, we need to add new one to hash table
186 e.key=strdup(name);
187 e.data=strdup(value);
188 if ( e.key != NULL && e.data != NULL ) {
189 if (hsearch_r(e,ENTER,&ep,prop_htab) == 0) {
190 DVR_ERROR("%s, Failed to add an entry to hash table %s:%s",__func__,name,value);
191 return DVR_FAILURE;
192 }
193 } else {
194 if (e.key != NULL) {
195 free(e.key);
196 }
197 if (e.data != NULL) {
198 free(e.data);
199 }
200 DVR_ERROR("%s, Failed to duplicate strings %s,%s",__func__,name,value);
201 return DVR_FAILURE;
202 }
203 }
204
205 DVR_INFO("%s, Wrote property to hash table, name:%s, value:%s",__func__,name,value);
206 return DVR_SUCCESS;
207}
208
209/**\brief read int type property value
210 * \param[in] name, property name
211 * \param[in] def, default property value in case any failure
212 * \return int type property value. If any failure default value will be returned instead
213 */
214int dvr_prop_read_int(const char *name, int def)
215{
216 char buf[16] = {0};
217 if (dvr_prop_read(name,buf,sizeof(buf)) == DVR_SUCCESS) {
218 return atoi(buf);
219 }
220 return def;
hualing chena540a7e2020-03-27 16:44:05 +0800221}
222
Wentao MA907b6432022-08-01 06:23:08 +0000223#define NSEC_PER_SEC 1000000000L
224void clock_timespec_subtract(struct timespec *ts1, struct timespec *ts2, struct timespec *ts3)
225{
226 time_t sec;
227 long nsec;
228 sec = ts1->tv_sec - ts2->tv_sec;
229 nsec = ts1->tv_nsec - ts2->tv_nsec;
230 if (ts1->tv_sec >= 0 && ts1->tv_nsec >=0) {
231 if ((sec < 0 && nsec > 0) || (sec > 0 && nsec >= NSEC_PER_SEC)) {
232 nsec -= NSEC_PER_SEC;
233 sec++;
234 }
235 if (sec > 0 && nsec < 0) {
236 nsec += NSEC_PER_SEC;
237 sec--;
238 }
239 } else {
240 if (nsec <= -NSEC_PER_SEC || nsec >= NSEC_PER_SEC) {
241 nsec += NSEC_PER_SEC;
242 sec--;
243 }
244 if ((sec < 0 && nsec > 0)) {
245 nsec -= NSEC_PER_SEC;
246 sec++;
247 }
248 }
249 ts3->tv_sec = sec;
250 ts3->tv_nsec = nsec;
251}
252