
Currently, when an unpermitted character is added to ini, driver flags as an unknown config item and continues parsing. This could be an issue. Change is to return error when invalid character is parsed in ini. Change-Id: I0249d187f0e05a31dd256d5de56798a575903e5b CRs-Fixed: 3354669
308 wiersze
9.8 KiB
C
308 wiersze
9.8 KiB
C
/*
|
|
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
|
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for
|
|
* any purpose with or without fee is hereby granted, provided that the
|
|
* above copyright notice and this permission notice appear in all
|
|
* copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
|
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
|
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
|
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
|
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
/**
|
|
* DOC: UCFG APIs for the configuration component.
|
|
*
|
|
* Logically, configuration exists at the psoc level. This means, each psoc can
|
|
* have its own custom configuration, and calls to lookup configuration take a
|
|
* psoc parameter for reference. E.g.
|
|
*
|
|
* int32_t value = cfg_get(psoc, WLAN_SOME_INTEGER_CONFIG_ID);
|
|
*
|
|
* Configuration is cascading, and lookups happen in this order:
|
|
*
|
|
* 1) use psoc value, if configured
|
|
* 2) use global value, if configured
|
|
* 3) fallback to the default value for the configuration item
|
|
*
|
|
* This means a psoc configuration is a specialization of the global
|
|
* configuration, and does not need to explicitly set the same values if they
|
|
* would match the global config.
|
|
*
|
|
* In order to load and parse the global config, call cfg_parse(). In order to
|
|
* load and parse psoc configs, call cfg_psoc_parse(). cfg_parse() MUST be
|
|
* called before cfg_psoc_parse(), as global configuration will be consulted
|
|
* during the psoc parsing process.
|
|
*
|
|
* There are two basic lifecycles supported:
|
|
*
|
|
* 1) The type and number of psocs is *not* known at load time
|
|
*
|
|
* // driver is loading
|
|
* cfg_parse("/path/to/config");
|
|
*
|
|
* ...
|
|
*
|
|
* // a psoc has just been created
|
|
* cfg_psoc_parse(psoc, "/path/to/psoc/config");
|
|
*
|
|
* ...
|
|
*
|
|
* // driver is unloading
|
|
* cfg_release();
|
|
*
|
|
* 2) The type and number of psocs *is* known at load time
|
|
*
|
|
* // driver is loading
|
|
* cfg_parse("/path/to/config");
|
|
*
|
|
* ...
|
|
*
|
|
* // for each psoc
|
|
* cfg_psoc_parse(psoc, "/path/to/psoc/config");
|
|
*
|
|
* // no further psocs will be created after this point
|
|
* cfg_release();
|
|
*
|
|
* ...
|
|
*
|
|
* // driver is unloaded later
|
|
*
|
|
* Each configuration store is reference counted to reduce memory footprint, and
|
|
* the configuration component itself will hold one ref count on the global
|
|
* config store. All psocs for which psoc-specific configurations have *not*
|
|
* been provided will reference the global config store. Psocs for which psoc-
|
|
* specific configurations *have* been provided will check for existings stores
|
|
* with a matching path to use, before parsing the specified configuration file.
|
|
*
|
|
* If, at some point in time, it is known that no further psocs will ever be
|
|
* created, a call to cfg_release() will release the global ref count held by
|
|
* the configuration component. For systems which specify psoc-specific configs
|
|
* for all psocs, this will release the unnecessary memory used by the global
|
|
* config store. Otherwise, calling cfg_release() at unload time will ensure
|
|
* the global config store is properly freed.
|
|
*/
|
|
|
|
#ifndef __CFG_UCFG_H
|
|
#define __CFG_UCFG_H
|
|
|
|
#include "cfg_all.h"
|
|
#include "cfg_define.h"
|
|
#include "i_cfg.h"
|
|
#include "qdf_status.h"
|
|
#include "qdf_str.h"
|
|
#include "qdf_types.h"
|
|
#include "wlan_objmgr_psoc_obj.h"
|
|
|
|
/**
|
|
* cfg_parse() - parse an ini file, and populate the global config storei
|
|
* @path: The full file path of the ini file to parse
|
|
*
|
|
* Note: A matching cfg_release() call is required to release allocated
|
|
* resources.
|
|
*
|
|
* The *.ini file format is a simple format consisting of a list of key/value
|
|
* pairs, separated by an '=' character. e.g.
|
|
*
|
|
* gConfigItem1=some string value
|
|
* gConfigItem2=0xabc
|
|
*
|
|
* Comments are also supported, initiated with the '#' character:
|
|
*
|
|
* # This is a comment. It will be ignored by the *.ini parser
|
|
* gConfigItem3=aa:bb:cc:dd:ee:ff # this is also a comment
|
|
*
|
|
* Several datatypes are natively supported:
|
|
*
|
|
* gInt=-123 # bin (0b), octal (0o), hex (0x), and decimal supported
|
|
* gUint=123 # a non-negative integer value
|
|
* gBool=y # (1, Y, y) -> true; (0, N, n) -> false
|
|
* gString=any string # strings are useful for representing complex types
|
|
* gMacAddr=aa:bb:cc:dd:ee:ff # colons are optional, upper and lower case
|
|
* gIpv4Addr=127.0.0.1 # uses typical dot-decimal notation
|
|
* gIpv6Addr=::1 # typical notation, supporting zero-compression
|
|
*
|
|
* Return: QDF_STATUS
|
|
*/
|
|
QDF_STATUS cfg_parse(const char *path);
|
|
|
|
/**
|
|
* cfg_release() - release the global configuration store
|
|
*
|
|
* This API releases the configuration component's reference to the global
|
|
* config store.
|
|
*
|
|
* See also: this file's DOC section.
|
|
*
|
|
* Return: None
|
|
*/
|
|
void cfg_release(void);
|
|
|
|
/**
|
|
* cfg_psoc_parse() - specialize the config store for @psoc by parsing @path
|
|
* @psoc: The psoc whose config store should be specialized
|
|
* @path: The full file path of the ini file to parse
|
|
*
|
|
* See also: cfg_parse(), and this file's DOC section.
|
|
*
|
|
* Return: QDF_STATUS
|
|
*/
|
|
QDF_STATUS cfg_psoc_parse(struct wlan_objmgr_psoc *psoc, const char *path);
|
|
|
|
/**
|
|
* cfg_parse_to_psoc_store() - Parse file @path and update psoc ini store
|
|
* @psoc: The psoc whose config store should be updated
|
|
* @path: The full file path of the ini file to parse
|
|
*
|
|
* Return: QDF_STATUS
|
|
*/
|
|
QDF_STATUS cfg_parse_to_psoc_store(struct wlan_objmgr_psoc *psoc,
|
|
const char *path);
|
|
|
|
/**
|
|
* cfg_section_parse_to_psoc_store() - Parse specific section from file @path
|
|
* and update psoc ini store
|
|
* @psoc: The psoc whose config store should be updated
|
|
* @path: The full file path of the ini file to parse
|
|
* @section_name: Section name to be parsed
|
|
*
|
|
* Return: QDF_STATUS
|
|
*/
|
|
QDF_STATUS cfg_section_parse_to_psoc_store(struct wlan_objmgr_psoc *psoc,
|
|
const char *path,
|
|
const char *section_name);
|
|
|
|
/**
|
|
* cfg_parse_to_global_store() - Parse file @path and update global ini store
|
|
* @path: The full file path of the ini file to parse
|
|
*
|
|
* Return: QDF_STATUS
|
|
*/
|
|
QDF_STATUS cfg_parse_to_global_store(const char *path);
|
|
|
|
/**
|
|
* ucfg_cfg_store_print() - prints the cfg ini/non ini logs
|
|
* @psoc: psoc
|
|
*
|
|
* Return: QDF_STATUS
|
|
*/
|
|
QDF_STATUS ucfg_cfg_store_print(struct wlan_objmgr_psoc *psoc);
|
|
|
|
/**
|
|
* ucfg_cfg_ini_config_print() - prints the cfg ini/non ini to buffer
|
|
* @psoc: psoc
|
|
* @buf: cache to save ini config
|
|
* @plen: the pointer to length
|
|
* @buflen: total buf length
|
|
*
|
|
* Return: QDF_STATUS
|
|
*/
|
|
QDF_STATUS ucfg_cfg_ini_config_print(struct wlan_objmgr_psoc *psoc,
|
|
uint8_t *buf, ssize_t *plen,
|
|
ssize_t buflen);
|
|
/**
|
|
* cfg_valid_ini_check() - check ini file for invalid characters
|
|
* @path: path to ini file
|
|
*
|
|
* Return: true if no invalid characters found, false otherwise
|
|
*/
|
|
bool cfg_valid_ini_check(const char *path);
|
|
|
|
/**
|
|
* cfg_get() - lookup the configured value for @id from @psoc
|
|
* @psoc: The psoc from which to lookup the configured value
|
|
* @id: The id of the configured value to lookup
|
|
*
|
|
* E.g.
|
|
*
|
|
* int32_t value = cfg_get(psoc, WLAN_SOME_INTEGER_CONFIG_ID);
|
|
*
|
|
* Return: The configured value
|
|
*/
|
|
#define cfg_get(psoc, id) __cfg_get(psoc, __##id)
|
|
|
|
/* Configuration Access APIs */
|
|
#define __do_call(op, args...) op(args)
|
|
#define do_call(op, args) __do_call(op, rm_parens args)
|
|
|
|
#define cfg_id(id) #id
|
|
|
|
#define __cfg_mtype(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
|
|
mtype
|
|
#define cfg_mtype(id) do_call(__cfg_mtype, id)
|
|
|
|
#define __cfg_type(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
|
|
ctype
|
|
#define cfg_type(id) do_call(__cfg_type, id)
|
|
|
|
#define __cfg_name(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
|
|
name
|
|
#define cfg_name(id) do_call(__cfg_name, id)
|
|
|
|
#define __cfg_min(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
|
|
min
|
|
#define cfg_min(id) do_call(__cfg_min, id)
|
|
|
|
#define __cfg_max(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
|
|
max
|
|
#define cfg_max(id) do_call(__cfg_max, id)
|
|
|
|
#define __cfg_fb(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
|
|
fallback
|
|
#define cfg_fallback(id) do_call(__cfg_fb, id)
|
|
|
|
#define __cfg_desc(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
|
|
desc
|
|
#define cfg_description(id) do_call(__cfg_desc, id)
|
|
|
|
#define __cfg_def(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
|
|
def
|
|
#define cfg_default(id) do_call(__cfg_def, id)
|
|
|
|
#define __cfg_str(id...) #id
|
|
#define cfg_str(id) #id __cfg_str(id)
|
|
|
|
/* validate APIs */
|
|
static inline bool
|
|
cfg_string_in_range(const char *value, qdf_size_t min_len, qdf_size_t max_len)
|
|
{
|
|
qdf_size_t len = qdf_str_len(value);
|
|
|
|
return len >= min_len && len <= max_len;
|
|
}
|
|
|
|
#define __cfg_INT_in_range(value, min, max) (value >= min && value <= max)
|
|
#define __cfg_UINT_in_range(value, min, max) (value >= min && value <= max)
|
|
#define __cfg_STRING_in_range(value, min_len, max_len) \
|
|
cfg_string_in_range(value, min_len, max_len)
|
|
|
|
#define __cfg_in_range(id, value, mtype) \
|
|
__cfg_ ## mtype ## _in_range(value, cfg_min(id), cfg_max(id))
|
|
|
|
/* this may look redundant, but forces @mtype to be expanded */
|
|
#define __cfg_in_range_type(id, value, mtype) \
|
|
__cfg_in_range(id, value, mtype)
|
|
|
|
#define cfg_in_range(id, value) __cfg_in_range_type(id, value, cfg_mtype(id))
|
|
|
|
/* Value-or-Default APIs */
|
|
#define __cfg_value_or_default(id, value, def) \
|
|
(cfg_in_range(id, value) ? value : def)
|
|
|
|
#define cfg_value_or_default(id, value) \
|
|
__cfg_value_or_default(id, value, cfg_default(id))
|
|
|
|
/* Value-or-Clamped APIs */
|
|
#define __cfg_clamp(val, min, max) (val < min ? min : (val > max ? max : val))
|
|
#define cfg_clamp(id, value) __cfg_clamp(value, cfg_min(id), cfg_max(id))
|
|
|
|
#endif /* __CFG_UCFG_H */
|
|
|