Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
asn1-value-editor
Commits
59a97144
Commit
59a97144
authored
Nov 29, 2015
by
Maxime Perrotin
Browse files
Merge branch 'master' of gitrepos.estec.esa.int:taste/asn1-value-editor
parents
e49f417f
de81a6d3
Changes
4
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
59a97144
...
...
@@ -6,7 +6,7 @@ This directory contains the code for the ASN.1 Value editor:
** WARNING **
This version is different than the one present in the old Subversion repos
It contains a setup.py and is meant to be installed using the Python way:
$ sudo make install
This command will update the Qt resource file and call: python setup.py install --record
...
...
@@ -32,3 +32,5 @@ Author: Maxime Perrotin
LICENSE: LGPL - see LICENSE file
CHANGELOG:
1.
0.7 - fixed bug in value notation parser
asn1_value_editor/asn1_value_editor.py
View file @
59a97144
...
...
@@ -16,7 +16,7 @@
__author__
=
"Maxime Perrotin"
__license__
=
"LGPLv3"
__version__
=
"1.0.
6
"
__version__
=
"1.0.
7
"
__url__
=
"http://taste.tuxfamily.org"
import
sys
...
...
@@ -39,12 +39,14 @@ ASN1TYPE = Qt.UserRole
class
myTextEdit
(
QTextEdit
):
''' Customized text editor that contains a context menu for loading data from a file '''
''' Customized text editor that contains a context menu for loading
data from a file '''
def
__init__
(
self
,
parent
=
None
):
super
(
myTextEdit
,
self
).
__init__
(
parent
)
def
contextMenuEvent
(
self
,
event
):
''' When the context menu is open, add the Load from file action and open the menu '''
''' When the context menu is open, add the Load from file action
and open the menu '''
myMenu
=
self
.
createStandardContextMenu
()
myAction
=
'Load data from file'
myMenu
.
addAction
(
myAction
)
...
...
@@ -416,10 +418,10 @@ class asn1Editor(QTreeView):
elif
asnType
==
'ENUMERATED'
:
child
.
setText
(
value
[
'Enum'
])
elif
asnType
in
(
'SEQUENCE'
,
'SET'
):
self
.
updateModel
(
root
.
child
(
i
),
value
)
# update recursively
self
.
updateModel
(
root
.
child
(
i
),
value
)
# update recursively
elif
asnType
==
'CHOICE'
:
child
.
setText
(
str
(
value
[
'Choice'
]))
self
.
updateModel
(
root
.
child
(
i
),
value
)
# update recursively
self
.
updateModel
(
root
.
child
(
i
),
value
)
# update recursively
elif
asnType
==
'SEQOF'
:
child
.
setText
(
str
(
len
(
value
)))
self
.
updateModel
(
root
.
child
(
i
),
value
,
len
(
value
))
...
...
asn1_value_editor/sdlHandler.py
View file @
59a97144
...
...
@@ -264,7 +264,7 @@ class sdlHandler(QObject):
self
.
proc
=
root_ast
.
processes
[
0
]
except
IndexError
:
raise
IOError
(
'SDL Handler failed to initialize'
)
opengeode
.
Helper
.
flatten
(
self
.
proc
)
#
opengeode.Helper.flatten(self.proc)
graph
=
opengeode
.
Statechart
.
create_dot_graph
(
self
.
proc
,
basic
=
True
)
self
.
sdl_scene
=
opengeode
.
SDL_Scene
(
'statechart'
)
self
.
sdl_view
=
opengeode
.
SDL_View
(
self
.
sdl_scene
)
...
...
@@ -317,7 +317,7 @@ class sdlHandler(QObject):
def
active_tc
(
self
):
''' Yield list of TCs that can be sent (including timeouts) '''
# Find the list of allowed TC based on the current state
st
=
unicode
(
self
.
current_sdl_state
.
decode
(
'latin1'
))
st
=
self
.
current_sdl_state
inputs
=
self
.
proc
.
mapping
[
st
.
replace
(
UNICODE_SEP
,
'_'
).
lower
()]
allowed_tc
=
(
tc
for
each
in
inputs
for
tc
in
each
.
inputlist
)
for
each
in
allowed_tc
:
...
...
@@ -365,13 +365,44 @@ class sdlHandler(QObject):
self
.
parent
.
tabifyDockWidget
(
self
.
dock_simu
,
self
.
dock_checker
)
# Add the state list to the ASN.1 Editor (at row 0)
row
=
0
statenames
=
[
CleanName
(
s
)
for
s
in
self
.
proc
.
mapping
.
viewkeys
()
if
not
s
.
endswith
(
u
'START'
)]
# Build up the list of states, including state compositions
context
=
self
.
proc
# get the list of state aggregations
aggregates
=
opengeode
.
Helper
.
state_aggregations
(
context
)
get_statenames
=
lambda
c
:
[
CleanName
(
s
)
for
s
in
c
.
mapping
.
viewkeys
()
if
not
s
.
endswith
(
u
'START'
)]
statenames
=
get_statenames
(
context
)
def
rec_findstates
(
context
,
prefix
=
''
):
for
each
in
context
.
composite_states
:
prefix
+=
each
.
statename
+
'__'
for
name
in
get_statenames
(
each
):
yield
prefix
+
name
for
substate
in
rec_findstates
(
each
,
prefix
):
yield
substate
statenames
.
extend
(
list
(
rec_findstates
(
context
)))
states
=
{
'id'
:
'Current SDL state'
,
'type'
:
'ENUMERATED'
,
'values'
:
statenames
}
'values'
:
list
(
statenames
)
}
self
.
tree_items
[
'_states'
]
=
self
.
asn1_editor
.
setAsn1Model
(
states
,
row
)
if
aggregates
:
statenames
.
append
(
'(not in state)'
)
# Add state variables for parelle states in aggregations
for
agg
,
substates
in
aggregates
.
viewitems
():
for
each
in
substates
:
row
+=
1
states
=
{
'id'
:
'Substate {}.{}'
.
format
(
CleanName
(
agg
),
each
.
statename
),
'type'
:
'ENUMERATED'
,
'values'
:
list
(
statenames
)}
self
.
tree_items
[
'substate_{}'
.
format
(
each
.
statename
)]
=
\
self
.
asn1_editor
.
setAsn1Model
(
states
,
row
)
# Add the SDL variables to the ASN.1 editor
row
=
1
row
+
=
1
for
var
,
(
sort
,
_
)
in
self
.
proc
.
variables
.
viewitems
():
item
=
asn1sccToasn1ValueEditorTypes
(
self
.
proc
.
dataview
,
var
,
sort
)
self
.
tree_items
[
var
]
=
self
.
asn1_editor
.
setAsn1Model
(
item
,
row
)
...
...
@@ -387,7 +418,7 @@ class sdlHandler(QObject):
'{}_state'
.
format
(
self
.
proc
.
processName
))
self
.
get_sdl_state
.
restype
=
ctypes
.
c_char_p
# Initialization: set current state and internal variables
self
.
current_sdl_state
=
''
self
.
current_sdl_state
=
u
''
self
.
check_state
()
self
.
init_timers
()
self
.
init_state
=
self
.
current_hash
=
self
.
on_event
()
...
...
@@ -472,13 +503,14 @@ class sdlHandler(QObject):
def
check_state
(
self
):
''' Highlight the current state on the statechart diagram
Return True if the state has changed '''
state
=
self
.
get_sdl_state
()
state
=
self
.
get_sdl_state
()
.
decode
(
'latin1'
)
if
state
!=
self
.
current_sdl_state
:
self
.
current_sdl_state
=
state
self
.
sdl_scene
.
clear_highlight
()
state
=
state
.
decode
(
'latin1'
)
# Recover the unicode chars
for
each
in
self
.
sdl_scene
.
find_text
(
u
'
\\
b{}
\\
b'
.
format
(
state
)):
self
.
sdl_scene
.
highlight
(
each
)
composition
=
state
.
split
(
UNICODE_SEP
)
for
each
in
composition
:
for
symb
in
self
.
sdl_scene
.
find_text
(
u
'
\\
b{}
\\
b'
.
format
(
each
)):
self
.
sdl_scene
.
highlight
(
symb
)
self
.
log_area
.
addItem
(
'New state: {}'
.
format
(
CleanName
(
state
)))
return
True
return
False
...
...
@@ -591,8 +623,12 @@ class sdlHandler(QObject):
# Add the SDL state to the new global state
complete_state
.
append
(
self
.
current_sdl_state
)
# Update the SDL state in the global state panel
# state_as_pyside = vn.fromValueNotationToPySide('Current SDL state',
# '{}'.format(self.current_sdl_state.lower().replace('_', '-')
# .replace(UNICODE_SEP, '--')))
readable_state
=
self
.
current_sdl_state
.
replace
(
UNICODE_SEP
,
'--'
)
state_as_pyside
=
vn
.
fromValueNotationToPySide
(
'Current SDL state'
,
'{}'
.
format
(
self
.
current_sdl
_state
.
lower
().
replace
(
'_'
,
'-'
))
)
readable
_state
.
lower
().
replace
(
'_'
,
'-'
))
self
.
asn1_editor
.
updateVariable
(
state_as_pyside
,
root
=
self
.
tree_items
[
'_states'
])
# And save this new state in the graph, if it was not there yet
...
...
@@ -612,24 +648,35 @@ class sdlHandler(QObject):
if
check_ppty
:
# When doing undo, dont check propertis again
self
.
check_properties
(
new_hash
)
# TEMP TO TEST
# for name, typedef in self.proc.dataview.viewitems():
# if name != 'MySeq': continue
# print 'All combinations of ', name
# for combi in compute_combinations(typedef, self.proc.dataview):
# print combi
# END TEMP
self
.
check_properties
(
new_hash
)
return
new_hash
def
update_button_state
(
self
,
tc_name
=
None
):
''' Depending on the current SDL state, enable or disable the buttons
for sending TCs '''
# Find the list of allowed TC based on the current state
st
=
unicode
(
self
.
current_sdl_state
.
decode
(
'latin1'
))
inputs
=
self
.
proc
.
mapping
[
st
.
replace
(
UNICODE_SEP
,
'_'
).
lower
()]
allowed_tc
=
[]
for
each
in
inputs
:
allowed_tc
.
extend
(
each
.
inputlist
)
st
=
self
.
current_sdl_state
.
split
(
UNICODE_SEP
)
st_iter
=
st
.
pop
(
0
)
context
=
self
.
proc
def
find_allowed_tc
(
context
,
statename
):
inputs
=
context
.
mapping
[
statename
.
lower
()]
for
each
in
inputs
:
for
inp
in
each
.
inputlist
:
yield
inp
allowed_tc
=
list
(
find_allowed_tc
(
context
,
st_iter
))
while
len
(
st
):
# Handle state composition
next_st
=
st
.
pop
(
0
)
for
each
in
context
.
composite_states
:
if
each
.
statename
.
lower
()
==
st_iter
.
lower
():
context
=
each
break
allowed_tc
.
extend
(
list
(
find_allowed_tc
(
context
,
next_st
)))
st_iter
=
next_st
# Remove timers from the list
allowed_tc
=
set
(
allowed_tc
)
-
set
(
self
.
proc
.
timers
)
# Enable/disable the parameterless TC buttons accordingly
...
...
asn1_value_editor/vn.py
View file @
59a97144
...
...
@@ -10,7 +10,6 @@
Parse a string containing an ASN.1 value expressed in GSER
(also called ASN.1 Value Notation) and return a Python structure that
is compatible with the widget of the ASN.1 Value Editor
Copyright (c) 2012-2015 European Space Agency
2) toASN1ValueNotation(val)
Does the reverse (from Qt widget to ASN.1 Value Notation/GSER)
...
...
@@ -119,14 +118,12 @@ value = (BitStringLiteral
namedValue
=
identifier
+
value
# ASN.1 CHOICE
choiceValue
<<
(
identifier
+
':'
+
value
).
setResultsName
(
'CHOICE'
)
choiceValue
<<
(
identifier
+
':'
+
value
)
#
.setResultsName('CHOICE')
# ASN.1 SEQUENCE
#NAMED_VALUE_LIST << nestedExpr('{','}', delimitedList(namedValue, delim=',')).setResultsName('SEQUENCE', True)
NAMED_VALUE_LIST
<<
LBRACKET
+
delimitedList
(
namedValue
)
+
RBRACKET
# ASN.1 SEQUENCE OF
#VALUE_LIST << nestedExpr('{', '}', delimitedList(value, delim=',')).setResultsName('SEQOF', True)
VALUE_LIST
<<
LBRACKET
+
Optional
(
delimitedList
(
value
))
+
RBRACKET
# Parse actions allow to modify the AST to be compliant with the ASN.1 Editor input
...
...
@@ -134,8 +131,23 @@ NAMED_VALUE_LIST.setParseAction(lambda s, l, t: reduce(lambda a, b: a.update(b)
# below: works only with Python 2.7+
#NAMED_VALUE_LIST.setParseAction(lambda s, l, t: {c:a[c] for a in t for c in a.iterkeys()})
VALUE_LIST
.
setParseAction
(
lambda
s
,
l
,
t
:
[
t
.
asList
()])
choiceValue
.
setParseAction
(
lambda
s
,
l
,
t
:
{
'Choice'
:
t
[
0
].
replace
(
'-'
,
'_'
),
t
[
0
].
replace
(
'-'
,
'_'
):
t
[
2
]})
valuereference
.
setParseAction
(
lambda
s
,
l
,
t
:
{
'Enum'
:
t
[
0
].
replace
(
'-'
,
'_'
)})
def
parseChoiceValue
(
s
,
l
,
t
):
''' Parsing CHOICE '''
choice
=
t
[
0
].
replace
(
'-'
,
'_'
)
return
{
'Choice'
:
choice
,
choice
:
t
[
2
]}
choiceValue
.
setParseAction
(
parseChoiceValue
)
def
parseValueReference
(
s
,
l
,
t
):
''' Parsing ENUMERATED Id '''
value
=
t
[
0
].
replace
(
'-'
,
'_'
)
return
{
'Enum'
:
value
}
valuereference
.
setParseAction
(
parseValueReference
)
#choiceValue.setParseAction(lambda s, l, t: {'Choice': t[0].replace('-', '_'), t[0].replace('-', '_'): t[2]})
#valuereference.setParseAction(lambda s, l, t: {'Enum': t[0].replace('-', '_')})
namedValue
.
setParseAction
(
lambda
s
,
l
,
t
:
{
t
[
0
].
replace
(
'-'
,
'_'
):
t
[
1
]})
FloatingPointLiteral
.
setParseAction
(
lambda
s
,
l
,
t
:
float
(
t
[
0
]))
INT
.
setParseAction
(
lambda
s
,
l
,
t
:
int
(
t
[
0
]))
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment