blob: 6514cb3d7804d08922eb24fa0bc075d0b2ba7fac [file] [log] [blame]
Ben Romberger55886882014-01-10 13:49:02 -08001/*
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -08002 * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
Ben Romberger55886882014-01-10 13:49:02 -08003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
Ben Romberger61764e32014-01-10 13:49:02 -080030#define LOG_TAG "platform_info"
Ben Romberger55886882014-01-10 13:49:02 -080031#define LOG_NDDEBUG 0
32
33#include <errno.h>
34#include <stdio.h>
35#include <expat.h>
36#include <cutils/log.h>
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -070037#include <cutils/str_parms.h>
Ben Romberger55886882014-01-10 13:49:02 -080038#include <audio_hw.h>
Ben Romberger61764e32014-01-10 13:49:02 -080039#include "platform_api.h"
40#include <platform.h>
Ben Romberger55886882014-01-10 13:49:02 -080041
Ben Romberger55886882014-01-10 13:49:02 -080042#define BUF_SIZE 1024
43
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -070044typedef enum {
45 ROOT,
46 ACDB,
Amit Shekhar5a39c912014-10-14 15:39:30 -070047 BITWIDTH,
Apoorv Raghuvanshi21492162015-02-19 18:19:36 -080048 NATIVESUPPORT,
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -070049 PCM_ID,
50 BACKEND_NAME,
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -080051 INTERFACE_NAME,
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -070052 CONFIG_PARAMS,
Laxminath Kasam44f49402015-05-29 18:37:11 +053053 TZ_NAME,
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -070054} section_t;
55
56typedef void (* section_process_fn)(const XML_Char **attr);
57
58static void process_acdb_id(const XML_Char **attr);
Amit Shekhar5a39c912014-10-14 15:39:30 -070059static void process_bit_width(const XML_Char **attr);
Apoorv Raghuvanshi21492162015-02-19 18:19:36 -080060static void process_native_support(const XML_Char **attr);
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -070061static void process_pcm_id(const XML_Char **attr);
62static void process_backend_name(const XML_Char **attr);
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -080063static void process_interface_name(const XML_Char **attr);
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -070064static void process_config_params(const XML_Char **attr);
Laxminath Kasam44f49402015-05-29 18:37:11 +053065static void process_tz_name(const XML_Char **attr);
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -070066static void process_root(const XML_Char **attr);
67
68static section_process_fn section_table[] = {
69 [ROOT] = process_root,
70 [ACDB] = process_acdb_id,
Amit Shekhar5a39c912014-10-14 15:39:30 -070071 [BITWIDTH] = process_bit_width,
Apoorv Raghuvanshi21492162015-02-19 18:19:36 -080072 [NATIVESUPPORT] = process_native_support,
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -070073 [PCM_ID] = process_pcm_id,
74 [BACKEND_NAME] = process_backend_name,
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -080075 [INTERFACE_NAME] = process_interface_name,
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -070076 [CONFIG_PARAMS] = process_config_params,
Laxminath Kasam44f49402015-05-29 18:37:11 +053077 [TZ_NAME] = process_tz_name,
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -070078};
79
80static section_t section;
81
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -070082struct platform_info {
83 void *platform;
84 struct str_parms *kvpairs;
85};
86
87static struct platform_info my_data;
88
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -070089/*
90 * <audio_platform_info>
91 * <acdb_ids>
92 * <device name="???" acdb_id="???"/>
93 * ...
94 * ...
95 * </acdb_ids>
96 * <backend_names>
97 * <device name="???" backend="???"/>
98 * ...
99 * ...
100 * </backend_names>
101 * <pcm_ids>
102 * <usecase name="???" type="in/out" id="???"/>
103 * ...
104 * ...
105 * </pcm_ids>
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -0800106 * <interface_names>
Karthik Reddy Katta508eca42015-05-11 13:43:18 +0530107 * <device name="Use audio device name here, not sound device name" interface="PRIMARY_I2S" codec_type="external/internal"/>
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -0800108 * ...
109 * ...
110 * </interface_names>
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -0700111 * <config_params>
112 * <param key="snd_card_name" value="msm8994-tomtom-mtp-snd-card"/>
113 * ...
114 * ...
115 * </config_params>
116 *
Laxminath Kasam44f49402015-05-29 18:37:11 +0530117 * <tz_names>
118 * <device name="???" spkr_1_tz_name="???" spkr_2_tz_name="???"/>
119 * ...
120 * ...
121 * </tz_names>
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700122 * </audio_platform_info>
123 */
124
125static void process_root(const XML_Char **attr __unused)
126{
127}
128
129/* mapping from usecase to pcm dev id */
130static void process_pcm_id(const XML_Char **attr)
131{
132 int index;
133
134 if (strcmp(attr[0], "name") != 0) {
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -0700135 ALOGE("%s: 'name' not found, no pcm_id set!", __func__);
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700136 goto done;
137 }
138
139 index = platform_get_usecase_index((char *)attr[1]);
140 if (index < 0) {
141 ALOGE("%s: usecase %s not found!",
142 __func__, attr[1]);
143 goto done;
144 }
145
146 if (strcmp(attr[2], "type") != 0) {
147 ALOGE("%s: usecase type not mentioned", __func__);
148 goto done;
149 }
150
151 int type = -1;
152
153 if (!strcasecmp((char *)attr[3], "in")) {
154 type = 1;
155 } else if (!strcasecmp((char *)attr[3], "out")) {
156 type = 0;
157 } else {
158 ALOGE("%s: type must be IN or OUT", __func__);
159 goto done;
160 }
161
162 if (strcmp(attr[4], "id") != 0) {
163 ALOGE("%s: usecase id not mentioned", __func__);
164 goto done;
165 }
166
167 int id = atoi((char *)attr[5]);
168
169 if (platform_set_usecase_pcm_id(index, type, id) < 0) {
170 ALOGE("%s: usecase %s type %d id %d was not set!",
171 __func__, attr[1], type, id);
172 goto done;
173 }
174
175done:
176 return;
177}
178
179/* backend to be used for a device */
180static void process_backend_name(const XML_Char **attr)
181{
182 int index;
183
184 if (strcmp(attr[0], "name") != 0) {
185 ALOGE("%s: 'name' not found, no ACDB ID set!", __func__);
186 goto done;
187 }
188
189 index = platform_get_snd_device_index((char *)attr[1]);
190 if (index < 0) {
191 ALOGE("%s: Device %s not found, no ACDB ID set!",
192 __func__, attr[1]);
193 goto done;
194 }
195
196 if (strcmp(attr[2], "backend") != 0) {
197 ALOGE("%s: Device %s has no backend set!",
198 __func__, attr[1]);
199 goto done;
200 }
201
202 if (platform_set_snd_device_backend(index, attr[3]) < 0) {
203 ALOGE("%s: Device %s backend %s was not set!",
204 __func__, attr[1], attr[3]);
205 goto done;
206 }
207
208done:
209 return;
210}
211
212static void process_acdb_id(const XML_Char **attr)
Ben Romberger55886882014-01-10 13:49:02 -0800213{
Ben Romberger61764e32014-01-10 13:49:02 -0800214 int index;
Ben Romberger55886882014-01-10 13:49:02 -0800215
Ben Romberger61764e32014-01-10 13:49:02 -0800216 if (strcmp(attr[0], "name") != 0) {
217 ALOGE("%s: 'name' not found, no ACDB ID set!", __func__);
Ben Romberger55886882014-01-10 13:49:02 -0800218 goto done;
Ben Romberger61764e32014-01-10 13:49:02 -0800219 }
Ben Romberger55886882014-01-10 13:49:02 -0800220
Ben Romberger61764e32014-01-10 13:49:02 -0800221 index = platform_get_snd_device_index((char *)attr[1]);
222 if (index < 0) {
Helen Zeng6a16ad72014-02-23 22:04:44 -0800223 ALOGE("%s: Device %s in platform info xml not found, no ACDB ID set!",
224 __func__, attr[1]);
Ben Romberger55886882014-01-10 13:49:02 -0800225 goto done;
226 }
227
228 if (strcmp(attr[2], "acdb_id") != 0) {
Helen Zeng6a16ad72014-02-23 22:04:44 -0800229 ALOGE("%s: Device %s in platform info xml has no acdb_id, no ACDB ID set!",
230 __func__, attr[1]);
Ben Romberger55886882014-01-10 13:49:02 -0800231 goto done;
232 }
233
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700234 if (platform_set_snd_device_acdb_id(index, atoi((char *)attr[3])) < 0) {
235 ALOGE("%s: Device %s, ACDB ID %d was not set!",
Helen Zeng6a16ad72014-02-23 22:04:44 -0800236 __func__, attr[1], atoi((char *)attr[3]));
Ben Romberger55886882014-01-10 13:49:02 -0800237 goto done;
Ben Romberger61764e32014-01-10 13:49:02 -0800238 }
Ben Romberger55886882014-01-10 13:49:02 -0800239
Ben Romberger55886882014-01-10 13:49:02 -0800240done:
241 return;
242}
243
Amit Shekhar5a39c912014-10-14 15:39:30 -0700244static void process_bit_width(const XML_Char **attr)
245{
246 int index;
247
248 if (strcmp(attr[0], "name") != 0) {
249 ALOGE("%s: 'name' not found, no ACDB ID set!", __func__);
250 goto done;
251 }
252
253 index = platform_get_snd_device_index((char *)attr[1]);
254 if (index < 0) {
255 ALOGE("%s: Device %s in platform info xml not found, no ACDB ID set!",
256 __func__, attr[1]);
257 goto done;
258 }
259
260 if (strcmp(attr[2], "bit_width") != 0) {
261 ALOGE("%s: Device %s in platform info xml has no bit_width, no ACDB ID set!",
262 __func__, attr[1]);
263 goto done;
264 }
265
266 if (platform_set_snd_device_bit_width(index, atoi((char *)attr[3])) < 0) {
267 ALOGE("%s: Device %s, ACDB ID %d was not set!",
268 __func__, attr[1], atoi((char *)attr[3]));
269 goto done;
270 }
271
272done:
273 return;
274}
275
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -0800276static void process_interface_name(const XML_Char **attr)
277{
278 int ret;
279
280 if (strcmp(attr[0], "name") != 0) {
281 ALOGE("%s: 'name' not found, no Audio Interface set!", __func__);
282
283 goto done;
284 }
285
286 if (strcmp(attr[2], "interface") != 0) {
287 ALOGE("%s: Device %s has no Audio Interface set!",
288 __func__, attr[1]);
289
290 goto done;
291 }
292
Karthik Reddy Katta508eca42015-05-11 13:43:18 +0530293 if (strcmp(attr[4], "codec_type") != 0) {
294 ALOGE("%s: Device %s has no codec type set!",
295 __func__, attr[1]);
296
297 goto done;
298 }
299
300 ret = platform_set_audio_device_interface((char *)attr[1], (char *)attr[3],
301 (char *)attr[5]);
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -0800302 if (ret < 0) {
303 ALOGE("%s: Audio Interface not set!", __func__);
Apoorv Raghuvanshi21492162015-02-19 18:19:36 -0800304 goto done;
305 }
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -0800306
Apoorv Raghuvanshi21492162015-02-19 18:19:36 -0800307done:
308 return;
309}
310
311static void process_native_support(const XML_Char **attr)
312{
313 int index;
314
315 if (strcmp(attr[0], "name") != 0) {
316 ALOGE("%s: 'name' not found, no NATIVE_AUDIO_44.1 set!", __func__);
317 goto done;
318 }
319
320 if (strcmp(attr[2], "codec_support") != 0) {
321 ALOGE("%s: NATIVE_AUDIO_44.1 in platform info xml has no codec_support set!",
322 __func__);
323 goto done;
324 }
325
326 if (platform_set_native_support(atoi((char *)attr[3])) < 0) {
Preetam Singh Ranawat36f3d372015-06-18 22:59:53 +0530327 ALOGE("%s: NATIVE_AUDIO_44 was not set!", __func__);
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -0800328 goto done;
329 }
330
331done:
332 return;
333}
334
Laxminath Kasam44f49402015-05-29 18:37:11 +0530335static void process_tz_name(const XML_Char **attr)
336{
337 int ret, index;
338
339 if (strcmp(attr[0], "name") != 0) {
340 ALOGE("%s: 'name' not found, no Audio Interface set!", __func__);
341 goto done;
342 }
343
344 index = platform_get_snd_device_index((char *)attr[1]);
345 if (index < 0) {
346 ALOGE("%s: Device %s not found, no snd device set!",
347 __func__, attr[1]);
348 goto done;
349 }
350
351 if (strcmp(attr[2], "spkr_1_tz_name") != 0) {
352 ALOGE("%s: Device %s has no spkr_1_tz_name set!",
353 __func__, attr[1]);
354 }
355
356 if (strcmp(attr[4], "spkr_2_tz_name") != 0) {
357 ALOGE("%s: Device %s has no spkr_2_tz_name set!",
358 __func__, attr[1]);
359 }
360
Preetam Singh Ranawat61716b12015-12-14 11:55:24 +0530361 /* ret = platform_set_spkr_device_tz_names(index, (char *)attr[3], (char *)attr[5]);
Laxminath Kasam44f49402015-05-29 18:37:11 +0530362 if (ret < 0) {
363 ALOGE("%s: Audio Interface not set!", __func__);
364 goto done;
365 }
Preetam Singh Ranawat61716b12015-12-14 11:55:24 +0530366 */
Laxminath Kasam44f49402015-05-29 18:37:11 +0530367
368done:
369 return;
370}
371
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -0700372static void process_config_params(const XML_Char **attr)
373{
374 if (strcmp(attr[0], "key") != 0) {
375 ALOGE("%s: 'key' not found", __func__);
376 goto done;
377 }
378
379 if (strcmp(attr[2], "value") != 0) {
380 ALOGE("%s: 'value' not found", __func__);
381 goto done;
382 }
383
384 str_parms_add_str(my_data.kvpairs, (char*)attr[1], (char*)attr[3]);
385done:
386 return;
387}
388
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700389static void start_tag(void *userdata __unused, const XML_Char *tag_name,
Ben Romberger55886882014-01-10 13:49:02 -0800390 const XML_Char **attr)
391{
392 const XML_Char *attr_name = NULL;
393 const XML_Char *attr_value = NULL;
394 unsigned int i;
395
Amit Shekhar5a39c912014-10-14 15:39:30 -0700396 if (strcmp(tag_name, "bit_width_configs") == 0) {
397 section = BITWIDTH;
398 } else if (strcmp(tag_name, "acdb_ids") == 0) {
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700399 section = ACDB;
400 } else if (strcmp(tag_name, "pcm_ids") == 0) {
401 section = PCM_ID;
402 } else if (strcmp(tag_name, "backend_names") == 0) {
403 section = BACKEND_NAME;
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -0700404 } else if (strcmp(tag_name, "config_params") == 0) {
405 section = CONFIG_PARAMS;
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -0800406 } else if (strcmp(tag_name, "interface_names") == 0) {
407 section = INTERFACE_NAME;
Laxminath Kasam44f49402015-05-29 18:37:11 +0530408 } else if (strcmp(tag_name, "tz_names") == 0) {
409 section = TZ_NAME;
Apoorv Raghuvanshi21492162015-02-19 18:19:36 -0800410 } else if (strcmp(tag_name, "native_configs") == 0) {
411 section = NATIVESUPPORT;
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700412 } else if (strcmp(tag_name, "device") == 0) {
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -0800413 if ((section != ACDB) && (section != BACKEND_NAME) && (section != BITWIDTH) &&
Laxminath Kasam44f49402015-05-29 18:37:11 +0530414 (section != INTERFACE_NAME) && (section != TZ_NAME)) {
415 ALOGE("device tag only supported for acdb/backend names/bitwitdh/interface/tz names");
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700416 return;
417 }
418
419 /* call into process function for the current section */
420 section_process_fn fn = section_table[section];
421 fn(attr);
422 } else if (strcmp(tag_name, "usecase") == 0) {
423 if (section != PCM_ID) {
424 ALOGE("usecase tag only supported with PCM_ID section");
425 return;
426 }
427
428 section_process_fn fn = section_table[PCM_ID];
429 fn(attr);
Apoorv Raghuvanshi21492162015-02-19 18:19:36 -0800430 } else if (strcmp(tag_name, "feature") == 0) {
431 if (section != NATIVESUPPORT) {
432 ALOGE("usecase tag only supported with NATIVESUPPORT section");
433 return;
434 }
435
436 section_process_fn fn = section_table[NATIVESUPPORT];
437 fn(attr);
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -0700438 } else if (strcmp(tag_name, "param") == 0) {
439 if (section != CONFIG_PARAMS) {
440 ALOGE("param tag only supported with CONFIG_PARAMS section");
441 return;
442 }
443
444 section_process_fn fn = section_table[section];
445 fn(attr);
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700446 }
Ben Romberger55886882014-01-10 13:49:02 -0800447
448 return;
449}
450
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700451static void end_tag(void *userdata __unused, const XML_Char *tag_name)
Ben Romberger55886882014-01-10 13:49:02 -0800452{
Amit Shekhar5a39c912014-10-14 15:39:30 -0700453 if (strcmp(tag_name, "bit_width_configs") == 0) {
454 section = ROOT;
455 } else if (strcmp(tag_name, "acdb_ids") == 0) {
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700456 section = ROOT;
457 } else if (strcmp(tag_name, "pcm_ids") == 0) {
458 section = ROOT;
459 } else if (strcmp(tag_name, "backend_names") == 0) {
460 section = ROOT;
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -0700461 } else if (strcmp(tag_name, "config_params") == 0) {
462 section = ROOT;
463 platform_set_parameters(my_data.platform, my_data.kvpairs);
Narsinga Rao Chellaf928a982015-03-06 14:57:35 -0800464 } else if (strcmp(tag_name, "interface_names") == 0) {
465 section = ROOT;
Apoorv Raghuvanshi21492162015-02-19 18:19:36 -0800466 } else if (strcmp(tag_name, "native_configs") == 0) {
467 section = ROOT;
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700468 }
Ben Romberger55886882014-01-10 13:49:02 -0800469}
470
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -0700471int platform_info_init(const char *filename, void *platform)
Ben Romberger55886882014-01-10 13:49:02 -0800472{
473 XML_Parser parser;
474 FILE *file;
475 int ret = 0;
476 int bytes_read;
Ben Romberger55886882014-01-10 13:49:02 -0800477 void *buf;
478
Helen Zeng6a16ad72014-02-23 22:04:44 -0800479 file = fopen(filename, "r");
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700480 section = ROOT;
481
Ben Romberger55886882014-01-10 13:49:02 -0800482 if (!file) {
483 ALOGD("%s: Failed to open %s, using defaults.",
Helen Zeng6a16ad72014-02-23 22:04:44 -0800484 __func__, filename);
Ben Romberger55886882014-01-10 13:49:02 -0800485 ret = -ENODEV;
486 goto done;
487 }
488
489 parser = XML_ParserCreate(NULL);
490 if (!parser) {
491 ALOGE("%s: Failed to create XML parser!", __func__);
492 ret = -ENODEV;
493 goto err_close_file;
494 }
495
Ravi Kumar Alamanda14b0f2d2015-06-28 21:04:09 -0700496 my_data.platform = platform;
497 my_data.kvpairs = str_parms_create();
498
Ben Romberger55886882014-01-10 13:49:02 -0800499 XML_SetElementHandler(parser, start_tag, end_tag);
500
501 while (1) {
502 buf = XML_GetBuffer(parser, BUF_SIZE);
503 if (buf == NULL) {
504 ALOGE("%s: XML_GetBuffer failed", __func__);
505 ret = -ENOMEM;
506 goto err_free_parser;
507 }
508
509 bytes_read = fread(buf, 1, BUF_SIZE, file);
510 if (bytes_read < 0) {
511 ALOGE("%s: fread failed, bytes read = %d", __func__, bytes_read);
512 ret = bytes_read;
513 goto err_free_parser;
514 }
515
516 if (XML_ParseBuffer(parser, bytes_read,
517 bytes_read == 0) == XML_STATUS_ERROR) {
518 ALOGE("%s: XML_ParseBuffer failed, for %s",
Helen Zeng6a16ad72014-02-23 22:04:44 -0800519 __func__, filename);
Ben Romberger55886882014-01-10 13:49:02 -0800520 ret = -EINVAL;
521 goto err_free_parser;
522 }
523
524 if (bytes_read == 0)
525 break;
526 }
527
Ben Romberger55886882014-01-10 13:49:02 -0800528err_free_parser:
529 XML_ParserFree(parser);
530err_close_file:
531 fclose(file);
532done:
533 return ret;
534}