IntelFsp2Pkg\Tools\ConfigEditor:Added new USF config workstream.

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4638

Config Editor utility addition/changes:
Support to enable config editor tool to have a new feature that can load
and view the configuration data of compiled VFR or HFR in form of YAML.
This can help users to understand and track the configuration data when
modifications are made.

Requires compiled vfr file as input in YAML format.

Running Configuration Editor:
python ConfigEditor.py

Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Duggapu Chinni B <chinni.b.duggapu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Ray Han Lim Ng <ray.han.lim.ng@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Ted Kuo <ted.kuo@intel.com>
Cc: Ashraf Ali S <ashraf.ali.s@intel.com>
Cc: Susovan Mohapatra <susovan.mohapatra@intel.com>

Signed-off-by: Arun Sura <arun.surax.soundara.pandian@intel.com>
Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>
This commit is contained in:
Arun Sura 2024-01-10 10:59:23 +05:30 committed by mergify[bot]
parent bc34a79cd2
commit 7d055812cc
4 changed files with 602 additions and 55 deletions

View File

@ -1015,6 +1015,10 @@ class application(tkinter.Frame):
"Unsupported file '%s' !" % path)
return
# VFR Format Page modification
def page_construct(self):
self.left.bind("<<TreeviewSelect>>", self.on_config_page_select_change)
def search_bar(self):
# get data from text box
self.search_text = self.edit.get()
@ -1165,7 +1169,8 @@ class application(tkinter.Frame):
page_id = next(iter(page))
# Put CFG items into related page list
self.page_list[page_id] = self.cfg_data_obj.get_cfg_list(page_id)
self.page_list[page_id].sort(key=lambda x: x['order'])
if self.mode == 'fsp':
self.page_list[page_id].sort(key=lambda x: x['order'])
page_name = self.cfg_data_obj.get_page_title(page_id)
child = self.left.insert(
parent, 'end',
@ -1199,17 +1204,22 @@ class application(tkinter.Frame):
for item in self.get_current_config_data():
disp_list.append(item)
row = 0
disp_list.sort(key=lambda x: x['order'])
for item in disp_list:
self.add_config_item(item, row)
row += 2
if self.invalid_values:
string = 'The following contails invalid options/values \n\n'
for i in self.invalid_values:
string += i + ": " + str(self.invalid_values[i]) + "\n"
reply = messagebox.showwarning('Warning!', string)
if reply == 'ok':
self.invalid_values.clear()
if self.mode == 'fsp':
disp_list.sort(key=lambda x: x['order'])
for item in disp_list:
self.add_config_item(item, row)
row += 2
if self.invalid_values:
string = 'The following contails invalid options/values \n\n'
for i in self.invalid_values:
string += i + ": " + str(self.invalid_values[i]) + "\n"
reply = messagebox.showwarning('Warning!', string)
if reply == 'ok':
self.invalid_values.clear()
elif self.mode == 'vfr':
for item in disp_list:
self.add_vfr_config_item(item, row)
row += 2
fsp_version = ''
@ -1219,16 +1229,19 @@ class application(tkinter.Frame):
with open(file_name, "rb") as pkl_file:
gen_cfg_data.__dict__ = marshal.load(pkl_file)
gen_cfg_data.prepare_marshal(False)
elif file_name.endswith('.yaml'):
elif file_name.endswith('.yaml') or file_name.endswith('.yml'):
if gen_cfg_data.load_yaml(file_name) != 0:
raise Exception(gen_cfg_data.get_last_error())
else:
raise Exception('Unsupported file "%s" !' % file_name)
self.mode = gen_cfg_data.yaml_type
# checking fsp version
if gen_cfg_data.detect_fsp():
self.fsp_version = '2.X'
else:
self.fsp_version = '1.X'
if gen_cfg_data.yaml_type == 'fsp':
if gen_cfg_data.detect_fsp():
self.fsp_version = '2.X'
else:
self.fsp_version = '1.X'
return gen_cfg_data
@ -1252,7 +1265,7 @@ class application(tkinter.Frame):
elif ftype == 'bin':
question = 'All configuration will be reloaded from BIN file, \
continue ?'
elif ftype == 'yaml':
elif ftype == 'yaml' or ftype == 'yml':
question = ''
elif ftype == 'bsf':
question = ''
@ -1263,13 +1276,13 @@ class application(tkinter.Frame):
if reply == 'no':
return None
if ftype == 'yaml':
if self.mode == 'FSP':
if ftype == 'yaml' or ftype == 'yml':
if self.mode == 'fsp':
file_type = 'YAML'
file_ext = 'yaml'
else:
file_type = 'YAML or PKL'
file_ext = 'pkl *.yaml'
file_ext = 'pkl *.yaml *.yml'
else:
file_type = ftype.upper()
file_ext = ftype
@ -1364,20 +1377,22 @@ class application(tkinter.Frame):
self.left.delete(*self.left.get_children())
self.cfg_data_obj = self.load_config_data(path)
self.update_last_dir(path)
self.org_cfg_data_bin = self.cfg_data_obj.generate_binary_array()
self.build_config_page_tree(self.cfg_data_obj.get_cfg_page()['root'],
'')
msg_string = 'Click YES if it is FULL FSP '\
+ self.fsp_version + ' Binary'
reply = messagebox.askquestion('Form', msg_string)
if reply == 'yes':
self.load_from_bin()
self.update_last_dir(path)
if self.cfg_data_obj.yaml_type == 'fsp':
self.org_cfg_data_bin = self.cfg_data_obj.generate_binary_array()
for menu in self.menu_string:
self.file_menu.entryconfig(menu, state="normal")
msg_string = 'Click YES if it is FULL FSP '\
+ self.fsp_version + ' Binary'
reply = messagebox.askquestion('Form', msg_string)
if reply == 'yes':
self.load_from_bin()
for menu in self.menu_string:
self.file_menu.entryconfig(menu, state="normal")
return 0
@ -1405,8 +1420,9 @@ class application(tkinter.Frame):
return
self.update_config_data_on_page()
new_data = self.cfg_data_obj.generate_binary_array()
self.cfg_data_obj.generate_delta_file_from_bin(path,
if self.mode == "fsp":
new_data = self.cfg_data_obj.generate_binary_array()
self.cfg_data_obj.generate_delta_file_from_bin(path,
self.org_cfg_data_bin,
new_data, full)
@ -1526,6 +1542,13 @@ class application(tkinter.Frame):
new_value = bytes_to_bracket_str(widget.get())
self.set_config_item_value(item, new_value)
#YAML VFR Part Start
def update_vfr_config_data_from_widget(self, widget, args):
item = self.get_config_data_item_from_widget(widget)
#YAML VFR Part End
def evaluate_condition(self, item):
try:
result = self.cfg_data_obj.evaluate_condition(item)
@ -1535,6 +1558,132 @@ class application(tkinter.Frame):
result = 1
return result
#YAML VFR Part Start
def add_vfr_config_item(self, item, row):
parent = self.right_grid
widget = None
if item['type'] == 'string':
value = ''
name = tkinter.Label(parent, text=item['prompt'].split("#")[0], anchor="w")
txt_val = tkinter.StringVar()
widget = tkinter.Entry(parent, textvariable=txt_val)
txt_val.set(value)
elif item['type'] == 'text':
value = ''
name = tkinter.Label(parent, text=item['prompt'].split("#")[0], anchor="w")
txt_val = tkinter.StringVar()
widget = tkinter.Entry(parent, textvariable=txt_val)
txt_val.set(value)
elif item['type'] == 'label':
value = ''
name = tkinter.Label(parent, text=item['prompt'].split("#")[0], anchor="w")
txt_val = tkinter.StringVar()
widget = tkinter.Entry(parent, textvariable=txt_val)
txt_val.set(value)
elif item['type'] == 'checkbox':
name = tkinter.Label(parent, text=item['prompt'].split("#")[0], anchor="w")
widget = tkinter.Checkbutton(parent, text= item['prompt'].split("#")[0], variable= 1)
elif item['type'] == 'subtitle':
value = ''
name = tkinter.Label(parent, text=item['prompt'].split("#")[0], anchor="w")
txt_val = tkinter.StringVar()
widget = tkinter.Entry(parent, textvariable=txt_val)
txt_val.set(value)
elif item['type'] == 'oneof':
OPTIONS = []
name = tkinter.Label(parent, text=item['prompt'].split("#")[0], anchor="w")
for key in item:
if key.startswith("option"):
if type(item[key]) == type([]):
for option_data in item[key]:
OPTIONS.append(option_data['text'])
else:
OPTIONS.append(item[key]["text"])
txt_val = tkinter.StringVar()
txt_val.set(OPTIONS[0]) # set default value
widget = tkinter.OptionMenu(parent, txt_val, *OPTIONS)
txt_val.set(OPTIONS[0])
elif item['type'] == 'numeric':
value = 0
for key in item.keys():
if key == "value":
value = item['value']
elif key == 'default':
for dict_key in item['default']:
if dict_key == "value":
value = item['default']['value']
else:
continue
name = tkinter.Label(parent, text=item['prompt'].split("#")[0], anchor="w")
txt_val = tkinter.StringVar()
widget = tkinter.Entry(parent, textvariable=txt_val)
txt_val.set(value)
elif item['type'] == 'orderedlist':
OPTIONS = []
name = tkinter.Label(parent, text=item['prompt'].split("#")[0], anchor="w")
for key in item:
if key.startswith("option"):
if type(item[key]) == type([]):
for option_data in item[key]:
OPTIONS.append(option_data['text'])
else:
OPTIONS.append(item[key]["text"])
txt_val = tkinter.StringVar()
txt_val.set(OPTIONS[0]) # default value
widget = tkinter.OptionMenu(parent, txt_val, *OPTIONS)
txt_val.set(OPTIONS[0])
elif item['type'] == 'date':
value = ''
for key in item.keys():
if key == "value":
value = item['value']
elif key == 'default':
for dict_key in item['default']:
if dict_key == "value":
value = item['default']['value']
else:
continue
name = tkinter.Label(parent, text=item['prompt'].split("#")[0], anchor="w")
txt_val = tkinter.StringVar()
widget = tkinter.Entry(parent, textvariable=txt_val)
txt_val.set(value)
elif item['type'] == 'time':
value = ''
for key in item.keys():
if key == "value":
value = item['value']
elif key == 'default':
for dict_key in item['default']:
if dict_key == "value":
value = item['default']['value']
else:
continue
name = tkinter.Label(parent, text=item['prompt'].split("#")[0], anchor="w")
txt_val = tkinter.StringVar()
widget = tkinter.Entry(parent, textvariable=txt_val)
txt_val.set(value)
if widget:
if item['type'] == 'string' or item['type'] == 'text' or item['type'] == 'numeric' or item['type'] == "oneof"\
or item['type'] == 'date' or item['type'] == 'time' or item['type'] == 'orderedlist' or item['type'] == 'label':# or item['type'] == 'goto'or item['type'] == 'checkbox':
if 'help' in item.keys():
create_tool_tip(widget, item['help'].split("#")[0])
name.grid(row=row, column=0, padx=5, pady=5, sticky="nsew")
widget.grid(row=row + 1, rowspan=1, column=0,
padx=5, pady=5, sticky="nsew")
#YAML VFR Part End
def add_config_item(self, item, row):
parent = self.right_grid
@ -1611,9 +1760,15 @@ class application(tkinter.Frame):
padx=10, pady=5, sticky="nsew")
def update_config_data_on_page(self):
self.walk_widgets_in_layout(self.right_grid,
self.update_config_data_from_widget)
if self.mode == "fsp":
self.walk_widgets_in_layout(self.right_grid,
self.update_config_data_from_widget)
elif self.mode == "vfr":
self.walk_widgets_in_layout(self.right_grid,
self.update_vfr_config_data_from_widget)
else:
print("WARNING: Invalid config file!!")
if __name__ == '__main__':
root = tkinter.Tk()

View File

@ -226,6 +226,7 @@ class CFG_YAML():
TEMPLATE = 'template'
CONFIGS = 'configs'
VARIABLE = 'variable'
FORMSET = 'formset'
def __init__(self):
self.log_line = False
@ -235,6 +236,7 @@ class CFG_YAML():
self.var_dict = None
self.def_dict = {}
self.yaml_path = ''
self.yaml_type = 'fsp'
self.lines = []
self.full_lines = []
self.index = 0
@ -418,6 +420,7 @@ class CFG_YAML():
last_indent = None
key = ''
temp_chk = {}
temp_data = []
while True:
line = self.get_line()
@ -425,6 +428,9 @@ class CFG_YAML():
break
curr_line = line.strip()
if curr_line == "## DO NOT REMOVE -- YAML Mode":
self.yaml_type = "vfr"
if curr_line == '' or curr_line[0] == '#':
continue
@ -482,9 +488,14 @@ class CFG_YAML():
return curr
marker1 = curr_line[0]
marker2 = curr_line[-1]
start = 1 if marker1 == '-' else 0
pos = curr_line.find(': ')
if marker1 == '-':
marker2 = curr_line[curr_line.find(":")]
pos = -1
else:
marker2 = curr_line[-1]
if pos > 0:
child = None
key = curr_line[start:pos].strip()
@ -516,15 +527,31 @@ class CFG_YAML():
# special virtual nodes, rename to ensure unique key
key = '$ACTION_%04X' % self.index
self.index += 1
if key in curr:
if key not in temp_chk:
# check for duplicated keys at same level
temp_chk[key] = 1
else:
raise Exception("Duplicated item '%s:%s' found !"
% (parent_name, key))
curr[key] = child
if self.yaml_type =='fsp':
if key in curr:
if key not in temp_chk:
# check for duplicated keys at same level
temp_chk[key] = 1
else:
raise Exception("Duplicated item '%s:%s' found !"
% (parent_name, key))
curr[key] = child
if self.yaml_type == 'vfr':
if key in curr.keys():
if type(curr[key]) == type([]):
temp_data = curr[key]
else:
temp_data.append(curr[key])
temp_data.append(child)
if level < 5:
curr[key] = temp_data
temp_data = []
else:
if level < 5:
curr[key] = child
if self.var_dict is None and key == CFG_YAML.VARIABLE:
self.var_dict = child
if self.tmp_tree is None and key == CFG_YAML.TEMPLATE:
@ -537,6 +564,8 @@ class CFG_YAML():
if self.tmp_tree and key == CFG_YAML.CONFIGS:
# apply template for the main configs
self.allow_template = True
if self.tmp_tree and key == CFG_YAML.FORMSET:
self.allow_template = True
else:
child = None
# - !include cfg_opt.yaml
@ -550,8 +579,30 @@ class CFG_YAML():
self.yaml_path = os.path.dirname(opt_file)
self.load_file(opt_file)
yaml_tree = self.parse()
self.tmp_tree = yaml_tree[CFG_YAML.TEMPLATE]
self.cfg_tree = yaml_tree[CFG_YAML.CONFIGS]
for key in yaml_tree.keys():
if key.lower() == "configs":
self.yaml_type = 'fsp'
self.tmp_tree = yaml_tree[CFG_YAML.TEMPLATE]
self.cfg_tree = yaml_tree[CFG_YAML.CONFIGS]
break
else:
self.cfg_tree = yaml_tree
break
if self.yaml_type == 'vfr':
formset_found = True
for key in yaml_tree.keys():
if key == CFG_YAML.FORMSET:
self.cfg_tree = yaml_tree[CFG_YAML.FORMSET]
formset_found = False
break
if formset_found == True:
self.cfg_tree = yaml_tree
elif self.yaml_type == 'fsp':
self.tmp_tree = yaml_tree[CFG_YAML.TEMPLATE]
self.cfg_tree = yaml_tree[CFG_YAML.CONFIGS]
return self.cfg_tree
def expand_yaml(self, opt_file):
@ -594,9 +645,14 @@ class CGenYamlCfg:
self._cfg_list = []
self._cfg_page = {'root': {'title': '', 'child': []}}
self._cur_page = ''
self._main_page = ''
self._var_dict = {}
self._def_dict = {}
self._yaml_path = ''
self.yaml_type = ''
#Added to overcome duplicate formid
self.form_page_map = {}
self.formset_level = 0
@staticmethod
def deep_convert_dict(layer):
@ -760,13 +816,22 @@ class CGenYamlCfg:
return error
def get_cfg_list(self, page_id=None):
cfgs = []
if page_id is None:
# return full list
return self._cfg_list
else:
# build a new list for items under a page ID
cfgs = [i for i in self._cfg_list if i['cname'] and
(i['page'] == page_id)]
if self.yaml_type == 'fsp':
# build a new list for items under a page ID
cfgs = [i for i in self._cfg_list if i['cname'] and
(i['page'] == page_id)]
#VFR YAML Support Start
elif self.yaml_type =='vfr':
for cfg in self._cfg_list:
for i in cfg:
if (i['page'] == page_id):
cfgs.append(i)
#VFR YAML Support End
return cfgs
def get_cfg_page(self):
@ -1002,6 +1067,9 @@ option format '%s' !" % option)
def _locate_cfg_item(root, path, level=0):
if len(path) == level:
return root
if type(root) == type([]):
for temp_root in root:
return _locate_cfg_item(temp_root, path, level)
next_root = root.get(path[level], None)
if next_root is None:
if allow_exp:
@ -1158,7 +1226,7 @@ option format '%s' !" % option)
self.set_cur_page(item.get('page', ''))
if name[0] == '$':
if name != '' and name[0] == '$':
# skip all virtual node
return 0
@ -1188,7 +1256,7 @@ option format '%s' !" % option)
# define is length in bytes
length = length * 8
if not name.isidentifier():
if name != '' and not name.isidentifier():
raise Exception("Invalid config name '%s' for '%s' !" %
(name, '.'.join(path)))
@ -1288,6 +1356,90 @@ option format '%s' !" % option)
raise SystemExit("Error: Bits length not aligned for %s !" %
str(path))
#EDK2 VFR YAML Support start
def build_formset_list(self, form_name='', top=None, parent_form='',path =[]):
if self.formset_level == 1:
self._cfg_page['root']['title'] = 'Platform'
self._cfg_page['root']['child'].append({form_name: {'title': form_name,
'child': []}})
self._main_page = form_name
if top is None:
top = self._cfg_tree
form_name = "Formset"
self._cfg_page['root']['title'] = 'Formset'
is_leaf = True
if form_name == "form" or form_name == "formid":
self._cur_page = top["title"].split('#')[0]
self.form_page_map[top['formid'].split('#')[0]] = self._cur_page
for driver in self._cfg_page['root']['child']:
if list(driver.keys())[0] == self._main_page:
driver[self._main_page]['child'].append({self._cur_page: {'title': self._cur_page, 'child': []}})
if form_name == "formmap":
self._cur_page = top["formid"].split('#')[0]
self.form_page_map[top['FormId'].split('#')[0]] = self._cur_page
self._cfg_page['root']['child'].append({self._cur_page: {'title': self._cur_page,
'child': []}})
form_data = {}
temp_data = []
for key in top:
if key == 'include':
form_data['type'] = key
form_data["page"] = self._cur_page
continue
if type(top[key]) is list and self.formset_level <= 3:
self.formset_level += 1
path.append(key)
for data in top[key]:
self.build_formset_list(key, data, key, path)
path.pop()
self.formset_level -= 1
elif type(top[key]) is OrderedDict and (self.formset_level <= 3):
if parent_form != '':
self.formset_level += 1
path.append(key)
self.build_formset_list(key, top[key], form_name, path)
path.pop()
self.formset_level -= 1
else:
self.formset_level += 1
path.append(key)
self.build_formset_list(key, top[key], key, path)
path.pop()
self.formset_level -= 1
else:
form_data["page"] = self._cur_page
form_data[key] = top[key]
form_data['path'] = ".".join(path)
if form_name != 'form' or form_name != "formid":
form_data["type"] = form_name
else:
form_data["type"] = " "
count = 0
if self._cfg_list != []:
for cfg_name in self._cfg_list:
for list_data in cfg_name:
if key == list_data['type']:
count +=1
if count > 1:
temp_data = cfg_name
if len(temp_data) != 0 or len(form_data)!=0:
temp_data.append(form_data)
self._cfg_list.append(temp_data)
return
#EDK2 VFR YAML Support End
def get_field_value(self, top=None):
def _get_field_value(name, cfgs, level):
if 'indx' in cfgs:
@ -2196,10 +2348,14 @@ xbe\x8f\x64\x12\x05\x8d\x0a\xa8'
self.initialize()
self._cfg_tree = cfg_yaml.load_yaml(cfg_file)
self._def_dict = cfg_yaml.def_dict
self.yaml_type = cfg_yaml.yaml_type
self._yaml_path = os.path.dirname(cfg_file)
self.build_cfg_list()
self.build_var_dict()
self.update_def_value()
if self.yaml_type == 'vfr':
self.build_formset_list()
elif self.yaml_type == 'fsp':
self.build_cfg_list()
self.build_var_dict()
self.update_def_value()
return 0
@ -2338,7 +2494,8 @@ def main():
if dlt_file:
gen_cfg_data.override_default_value(dlt_file)
gen_cfg_data.detect_fsp()
if gen_cfg_data.yaml_type == 'fsp':
gen_cfg_data.detect_fsp()
if command == "GENBIN":
if len(file_list) == 3:

View File

@ -0,0 +1,233 @@
## DO NOT REMOVE -- YAML Mode
Bluetooth Connection Manager:
formset:
guid: {0x4f4ef7f0, 0xaa29, 0x4ce9, { 0xba, 0x41, 0x64, 0x3e, 0x1, 0x23, 0xa9, 0x9f}}
help: Config the Bluetooth parameter
title: Bluetooth Configuration
component:
- form:
formid: 2
title: Bluetooth Host Controller Management
component:
- text:
help: Address of the bluetooth host controller
prompt: Address
text: Address
- string:
questionid: 24578
varstoreid: 0 # Optional Input
varname: 65535 # Question VarName
varoffset: 65535 # Question VarOffset
questionflags: 4 # Optional Input
prompt: Local Name
help: Name for the host controller, valid length from 2 to 19
opcodeflags: 0x0 # optional input
minsize: 2
maxsize: 19
- numeric:
questionid: 4114
varstoreid: 4099 # Optional Input
varname: 0 # Question VarName
varoffset: 0 # Question VarOffset
questionflags: 0 # Optional Input
prompt: Host Id
help: Shows the Host Controller Id
opcodeflags: 0x11 # optional input
maximum: 65535 # Optional Input
minimum: 0 # Optional Input
step: 0 # Optional Input
component:
- default:
defaultId: 0
type: 1
value: 5
- goto:
questionid: 24577
varstoreid: 0 # Optional Input
varname: 65535 # Question VarName
varoffset: 65535 # Question VarOffset
questionflags: 4 # Optional Input
prompt: Device Management
help: Goto Device Management form
formid: 0x3
question: 0x6001 # Optional Input
- numeric:
questionid: 4114
varstoreid: 4099 # Optional Input
varname: 0 # Question VarName
varoffset: 0 # Question VarOffset
questionflags: 0 # Optional Input
prompt: Device Count
help: Shows the number of devices
opcodeflags: 0x11 # optional input
maximum: 65535 # Optional Input
minimum: 0 # Optional Input
step: 0 # Optional Input
component:
- default:
defaultId: 0
type: 1
value: 3
- form:
formid: 3
title: Bluetooth Management - Device Management
component:
- label:
prompt: Device Management
number: 0x1500 # Number
- subtitle:
prompt: Active Device
flags: 0 # Optional Input
- subtitle:
prompt: Paired Device
flags: 0 # Optional Input
- numeric:
questionid: 4114
varstoreid: 4099 # Optional Input
varname: 0 # Question VarName
varoffset: 0 # Question VarOffset
questionflags: 0 # Optional Input
prompt: Paired Device Count
help: Lists the Number of Paired Devices
opcodeflags: 0x11 # optional input
maximum: 65535 # Optional Input
minimum: 0 # Optional Input
step: 0 # Optional Input
component:
- default:
defaultId: 0
type: 1
value: 2
- action:
questionid: 24579
varstoreid: 0 # Optional Input
varname: 65535 # Question VarName
varoffset: 65535 # Question VarOffset
questionflags: 4 # Optional Input
prompt: Address
help: Address
config: 4 # QuestionConfig
component:
- refreshguid:
guid: {0xf5e655d9, 0x2a6, 0x46f2, { 0x9e, 0x76, 0xb8, 0xbe, 0x8e, 0x60, 0xab, 0x22}}
- subtitle:
prompt: Available Device
flags: 0 # Optional Input
- numeric:
questionid: 4114
varstoreid: 4099 # Optional Input
varname: 0 # Question VarName
varoffset: 0 # Question VarOffset
questionflags: 0 # Optional Input
prompt: Available Device Count
help: List the number of Available devices
opcodeflags: 0x11 # optional input
maximum: 65535 # Optional Input
minimum: 0 # Optional Input
step: 0 # Optional Input
component:
- default:
defaultId: 0
type: 1
value: 4
- form:
formid: 4
title: Remote Device Info
component:
- numeric:
questionid: 4114
varstoreid: 4099 # Optional Input
varname: 0 # Question VarName
varoffset: 0 # Question VarOffset
questionflags: 0 # Optional Input
prompt: Device Count
help: Lists the Device Count
opcodeflags: 0x11 # optional input
maximum: 65535 # Optional Input
minimum: 0 # Optional Input
step: 0 # Optional Input
component:
- default:
defaultId: 0
type: 1
value: 3
- text:
condition: grayoutif TRUE
help: Address for this bluetooth host controller
prompt: Address
text: Address
- subtitle:
condition: grayoutif TRUE
prompt: Remote Device
flags: 0 # Optional Input
- numeric:
questionid: 4114
varstoreid: 4099 # Optional Input
varname: 0 # Question VarName
varoffset: 0 # Question VarOffset
questionflags: 0 # Optional Input
prompt: Available Devices
help: Lists the available devices
opcodeflags: 0x11 # optional input
maximum: 65535 # Optional Input
minimum: 0 # Optional Input
step: 0 # Optional Input
component:
- default:
defaultId: 0
type: 1
value: 5
- text:
condition: grayoutif TRUE
help: Available Services for the remote device
prompt: Available Services
- oneof:
questionid: 4130
varstoreid: 4096 # Optional Input
varname: 5 # Question VarName
varoffset: 5 # Question VarOffset
questionflags: 0 # Optional Input
prompt: Active Device
help: 0x0015
opcodeflags: 0x10 # optional input
maximum: 3 # Optional Input
minimum: 0 # Optional Input
step: 0x0 # Optional Input
component:
- option:
text: 0x0016
flags: 16 # Optional Input
type: 0x0000 # Optional Input
value: 0x0
- option:
text: 0x0017
flags: 0 # Optional Input
type: 0x0000 # Optional Input
value: 0x1
- option:
text: 0x0018
flags: 0 # Optional Input
type: 0x0000 # Optional Input
value: 0x2
- option:
text: 0x0019
flags: 0 # Optional Input
type: 0x0000 # Optional Input
value: 0x3
- numeric:
questionid: 4114
varstoreid: 4099 # Optional Input
varname: 0 # Question VarName
varoffset: 0 # Question VarOffset
questionflags: 0 # Optional Input
prompt: Paired device count
help: Lists the number of devices paired
opcodeflags: 0x11 # optional input
maximum: 65535 # Optional Input
minimum: 0 # Optional Input
step: 0 # Optional Input
component:
- default:
defaultId: 0
type: 1
value: 3

View File

@ -12,6 +12,8 @@ It supports the following options:
## 1. Open Config YAML file
This option loads the YAML file for a FSP UPD into the ConfigEditor to change the desired configuration values.
This option loads the YAML file for a VFR config data into the ConfigEditor to view the desired form values.
#####Example:
```
![Example ConfigEditor 1](https://slimbootloader.github.io/_images/CfgEditOpen.png)