1 /*
2 * Copyright (C) 2013 SAMSUNG S.LSI
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 *
17 */
18
19 #include <ctype.h>
20 #include <limits.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "util.h"
26
27 /* START [H17080801] HAL config file path */
28 #define CFG_FILE_1 "/vendor/etc/libnfc-sec-vendor.conf"
29 #define CFG_FILE_2 "/etc/libnfc-sec-vendor.conf"
30 /* END [H17080801] HAL config file path */
31
32 #define isToken(x) (x == ':' || x == '=' || x == ' ' || x == '\t')
33 #define skipToken(x) \
34 while (isToken(*x)) x++
35 #define skipSpace(x) \
36 while (isspace(*x)) x++
37
willBeContinuous(char * buffer,size_t maxlen)38 bool willBeContinuous(char* buffer, size_t maxlen) {
39 char* p;
40 size_t len;
41 if (!buffer) return false;
42
43 len = strnlen(buffer, maxlen);
44 if (len == maxlen && buffer[len - 2] != '\n') return true;
45
46 p = buffer + len - 1;
47 while (isspace(*p) && p > buffer) p--;
48 if (*p == '\\') return true;
49 return false;
50 }
51
find_by_name_from_current(FILE * file,const char * field)52 bool find_by_name_from_current(FILE* file, const char* field) {
53 char *p, buffer[256] = {
54 '\0',
55 };
56 size_t len;
57 int fp;
58 bool skip = false;
59
60 if (!file || !field) return false;
61
62 len = strlen(field);
63 while (!feof(file) && fgets(buffer, sizeof(buffer) - 1, file)) {
64 if (skip) {
65 skip = willBeContinuous(buffer, sizeof(buffer));
66 continue;
67 }
68 skip = willBeContinuous(buffer, sizeof(buffer));
69
70 p = buffer;
71 skipSpace(p);
72 if (*p == '#') continue;
73
74 if (!strncmp((char const*)field, (char const*)p, len)) {
75 fp = -strlen(p);
76 fp += len;
77 return (fseek(file, fp, SEEK_CUR) == 0) ? true : false;
78 }
79 }
80 return false;
81 }
82
find_by_name(FILE * file,const char * field)83 bool find_by_name(FILE* file, const char* field) {
84 fseek(file, 0x00, SEEK_SET);
85 return find_by_name_from_current(file, field);
86 }
87
__get_config_int(char * file_path,const char * field,int * data,int option)88 bool __get_config_int(__attribute__((unused)) char* file_path,
89 const char* field, int* data, int option) {
90 FILE* file;
91 char buffer[10], *p, *endp;
92 size_t len;
93 long int val;
94
95 if (!field || !data) return false;
96
97 /* START [H17080801] HAL config file path */
98 if ((file = fopen(CFG_FILE_1, "rb")) == NULL) {
99 OSI_loge("Cannot open config file %s", CFG_FILE_1);
100 if ((file = fopen(CFG_FILE_2, "rb")) == NULL) {
101 OSI_loge("Cannot open config file %s", CFG_FILE_2);
102 return 0;
103 }
104 }
105 /* END [H17080801] HAL config file path */
106
107 if (!find_by_name(file, field)) {
108 OSI_loge("Cannot find the field name [%s]", field);
109 goto fail;
110 }
111
112 if (!fgets(buffer, sizeof(buffer) - 1, file)) {
113 OSI_loge("Read failed");
114 goto fail;
115 }
116
117 if (willBeContinuous(buffer, sizeof(buffer))) // not supported multi line
118 goto fail;
119
120 if ((len = strlen(buffer)) == sizeof(buffer) - 1) {
121 OSI_loge("It is too long data [%s~]; max", buffer);
122 goto fail;
123 }
124
125 p = buffer;
126 skipToken(p);
127 if (*p == '\0') {
128 OSI_loge("It is empty data");
129 goto fail;
130 }
131
132 if (((*p == '0') && (*(p + 1) == 'x')) || option == HAL_UTIL_GET_INT_16)
133 val = strtol(p, &endp, 0x10);
134 else
135 val = strtol(p, &endp, 10);
136
137 if (p == endp) {
138 OSI_loge("Read failed [%s]", buffer);
139 goto fail;
140 }
141
142 OSI_logd("Get config %s: %ld(0x%lx)", field, val, val);
143
144 fclose(file);
145
146 *data = val;
147 return true;
148
149 fail:
150 fclose(file);
151 return false;
152 }
153
get_config_int(const char * field,int * data)154 bool get_config_int(const char* field, int* data) {
155 /* START [17080801] HAL config file path */
156 return __get_config_int((char*)CFG_FILE_1, field, data, 0);
157 /* END [17080801] HAL config file path */
158 }
159
get_config_string(const char * field,char * strBuffer,size_t bufferSize)160 int get_config_string(const char* field, char* strBuffer, size_t bufferSize) {
161 FILE* file;
162 char data[256], *buffer, *p;
163 bool readmore = true;
164 size_t count = 0;
165
166 if (!field || !strBuffer || bufferSize < 1) return 0;
167
168 /* START [H17080801] HAL config file path */
169 if ((file = fopen(CFG_FILE_1, "rb")) == NULL) {
170 OSI_loge("Cannot open config file %s", CFG_FILE_1);
171 if ((file = fopen(CFG_FILE_2, "rb")) == NULL) {
172 OSI_loge("Cannot open config file %s", CFG_FILE_2);
173 return 0;
174 }
175 }
176 /* END [H17080801] HAL config file path */
177
178 if (!find_by_name(file, field)) {
179 OSI_logd("Cannot find the field name [%s]", field);
180 goto fail;
181 }
182
183 if ((buffer = (char*)malloc(bufferSize)) == NULL) {
184 OSI_logd("Cannot allocate temporary buffer for [%s]", field);
185 goto fail;
186 }
187
188 while (count < bufferSize - 1 && readmore) {
189 if (!fgets(data, sizeof(data) - 1, file)) {
190 OSI_loge("Read failed");
191 goto fail_free;
192 }
193
194 readmore = willBeContinuous(data, sizeof(data));
195 p = data;
196 while ((p = strchr(p, '"')) != NULL) // start string
197 {
198 for (p++; *p != '"'; p++) // end string
199 {
200 if (*p == '\n' || *p == '\0' || *p == '\\') {
201 OSI_loge("Cannot find ending point of string");
202 goto fail_free;
203 }
204 buffer[count++] = *p;
205 }
206 p++;
207 }
208 }
209 buffer[count] = '\0';
210
211 OSI_logd("Get config %s: %s", field, buffer);
212 if (count == bufferSize) {
213 if (p == NULL)
214 goto fail_free;
215 else if (*p != '\n')
216 OSI_loge("Overflower!, remained data is [%s]", p);
217 else if (readmore)
218 OSI_loge("Overflower!, data is remained! (multi line)");
219 }
220
221 count++;
222 memcpy(strBuffer, buffer, count);
223 free(buffer);
224
225 fclose(file);
226 return count;
227
228 fail_free:
229 free(buffer);
230 fail:
231 fclose(file);
232 return 0;
233 }
234
get_config_count(const char * field)235 int get_config_count(const char* field) {
236 FILE* file;
237 int count = 0;
238
239 /* START [H17080801] HAL config file path */
240 if ((file = fopen(CFG_FILE_1, "rb")) == NULL) {
241 OSI_loge("Cannot open config file %s", CFG_FILE_1);
242 if ((file = fopen(CFG_FILE_2, "rb")) == NULL) {
243 OSI_loge("Cannot open config file %s", CFG_FILE_2);
244 return 0;
245 }
246 }
247 /* END [H17080801] HAL config file path */
248
249 while (find_by_name_from_current(file, field)) count++;
250
251 fclose(file);
252 return count;
253 }
254
get_hw_rev()255 int get_hw_rev() {
256 char* info_file = (char*)"/proc/cpuinfo";
257 char* field = (char*)"Revision";
258 int rev = -1;
259
260 OSI_logd("%s enter;", __func__);
261 __get_config_int(info_file, field, &rev, HAL_UTIL_GET_INT_16);
262 OSI_logd("%s exit; rev = %d", __func__, rev);
263
264 return rev;
265 }
266