Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
asn1Demo
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
王思远
asn1Demo
Commits
884ebf15
Commit
884ebf15
authored
Nov 21, 2025
by
王思远
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
UTC:2025-11-21 9:33:34 :
parent
80067a9c
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
172 additions
and
49 deletions
+172
-49
CMakeLists.txt
CMakeLists.txt
+2
-0
main.cpp
source/main.cpp
+170
-49
No files found.
CMakeLists.txt
View file @
884ebf15
...
...
@@ -31,6 +31,8 @@ list (REMOVE_ITEM SOURCES
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/generated_msgs/converter-example.c"
)
# add_definitions ("-DASN_EMIT_DEBUG=1")
add_executable
(
asn1Demo
${
SOURCES
}
)
source/main.cpp
View file @
884ebf15
#include <array>
#include <atomic>
#include <cerrno>
#include <chrono>
#include <cstdint>
#include <cstring>
#include <iostream>
#include <memory>
#include <random>
#include <string>
#include <arpa/inet.h>
...
...
@@ -16,6 +18,10 @@
#include <sys/socket.h>
#include <unistd.h>
extern
"C"
{
#include <asn_random_fill.h>
}
#include <MessageFrame.h>
constexpr
::
std
::
size_t
MTU
=
1024
;
...
...
@@ -39,7 +45,6 @@ using MessagePtr = ::std::unique_ptr<MessageType, void (*)(MessageType *)>;
auto
fill
=
stream
.
fill
();
auto
width
=
stream
.
width
();
stream
<<
"MessageFrame{"
;
::
std
::
unique_ptr
<
char
[]
>
buffer
;
::
std
::
size_t
bufferSize
=
1024
;
while
(
true
)
{
...
...
@@ -49,14 +54,14 @@ using MessagePtr = ::std::unique_ptr<MessageType, void (*)(MessageType *)>;
reinterpret_cast
<
const
void
*>
(
&
message
),
buffer
.
get
(),
bufferSize
);
if
(
encodeResult
.
encoded
<
0
)
{
stream
<<
"ENCODE_ERROR"
;
}
else
if
(
encodeResult
.
encoded
<=
bufferSize
)
{
}
else
if
(
static_cast
<::
std
::
size_t
>
(
encodeResult
.
encoded
)
<=
bufferSize
)
{
stream
.
write
(
buffer
.
get
(),
encodeResult
.
encoded
);
break
;
}
else
{
bufferSize
*=
2
;
}
}
stream
<<
"}"
;
stream
.
flags
(
flags
);
stream
.
fill
(
fill
);
...
...
@@ -66,6 +71,63 @@ using MessagePtr = ::std::unique_ptr<MessageType, void (*)(MessageType *)>;
}
/**
* @brief Fill random string.
*
* @param[out] output String to fill.
* @param[in] minSize Minimum size.
* @param[in] maxSize Maximum size.
*/
void
fillRandomString
(
OCTET_STRING
&
output
,
::
std
::
size_t
minSize
,
::
std
::
size_t
maxSize
)
{
::
std
::
random_device
randomDev
;
::
std
::
default_random_engine
engine
(
randomDev
());
::
std
::
size_t
size
=
minSize
==
maxSize
?
minSize
:
::
std
::
uniform_int_distribution
<::
std
::
size_t
>
(
minSize
,
maxSize
)(
engine
);
output
.
buf
=
reinterpret_cast
<::
std
::
uint8_t
*>
(
::
calloc
(
1
,
size
));
output
.
size
=
size
;
::
std
::
uniform_int_distribution
<::
std
::
uint8_t
>
generator
(
0x20
,
0x7E
);
for
(
::
std
::
size_t
i
=
0
;
i
<
size
;
++
i
)
{
output
.
buf
[
i
]
=
generator
(
engine
);
}
}
/**
* @brief Fill random number.
*
* @tparam NumType Number type.
*
* @param[out] output Output value to fill.
* @param[in] minSize Minimum size.
* @param[in] maxSize Maximum size.
*/
template
<
typename
NumType
>
void
fillRandomNumber
(
NumType
&
output
,
::
std
::
int64_t
min
,
::
std
::
int64_t
max
)
{
::
std
::
random_device
randomDev
;
::
std
::
default_random_engine
engine
(
randomDev
());
::
std
::
uniform_int_distribution
<
NumType
>
generator
(
static_cast
<
NumType
>
(
min
),
static_cast
<
NumType
>
(
max
));
output
=
generator
(
engine
);
return
;
}
/**
* @brief Get message count.
*
* @return Message count.
*/
::
std
::
uint64_t
getCount
()
{
static
::
std
::
atomic
<::
std
::
uint64_t
>
count
(
0
);
return
count
.
fetch_add
(
1
);
}
/**
* @brief Make BSM message.
*
* @return Fake message made.
...
...
@@ -76,14 +138,14 @@ MessagePtr<MessageFrame> makeBSMMessage()
reinterpret_cast
<
MessageFrame
*>
(
::
calloc
(
1
,
sizeof
(
MessageFrame
))),
releaseMessage
(
MessageFrame
));
ret
->
present
=
MessageFrame_PR
::
MessageFrame_PR_bsmFrame
;
::
asn_dec_rval_t
result
=
::
asn_decode
(
nullptr
,
ATS_RANDOM
,
&::
asn_DEF_BasicSafetyMessage
,
reinterpret_cast
<
void
**>
(
&
ret
->
choice
.
bsmFrame
),
nullptr
,
0
);
if
(
result
.
code
!=
RC_OK
)
{
::
std
::
cerr
<<
"Failed to generate BSM message."
<<
::
std
::
endl
;
return
MessagePtr
<
MessageFrame
>
(
nullptr
,
releaseMessage
(
MessageFrame
));
}
ret
->
present
=
MessageFrame_PR
::
MessageFrame_PR_bsmFrame
;
ret
->
choice
.
bsmFrame
.
msgCnt
=
getCount
();
fillRandomString
(
ret
->
choice
.
bsmFrame
.
id
,
8
,
8
);
fillRandomNumber
(
ret
->
choice
.
bsmFrame
.
size
.
width
,
3
,
5
);
fillRandomNumber
(
ret
->
choice
.
bsmFrame
.
size
.
length
,
10
,
20
);
ret
->
choice
.
bsmFrame
.
size
.
height
=
reinterpret_cast
<
VehicleHeight_t
*>
(
::
malloc
(
sizeof
(
VehicleHeight_t
)
));
fillRandomNumber
(
*
(
ret
->
choice
.
bsmFrame
.
size
.
height
),
3
,
5
);
return
ret
;
}
...
...
@@ -98,15 +160,17 @@ MessagePtr<MessageFrame> makeMapMessage()
MessagePtr
<
MessageFrame
>
ret
(
reinterpret_cast
<
MessageFrame
*>
(
::
calloc
(
1
,
sizeof
(
MessageFrame
))),
releaseMessage
(
MessageFrame
));
ret
->
present
=
MessageFrame_PR
::
MessageFrame_PR_mapFrame
;
::
asn_dec_rval_t
result
=
::
asn_decode
(
nullptr
,
ATS_RANDOM
,
&::
asn_DEF_MapData
,
reinterpret_cast
<
void
**>
(
&
ret
->
choice
.
mapFrame
),
nullptr
,
0
);
if
(
result
.
code
!=
RC_OK
)
{
::
std
::
cerr
<<
"Failed to generate Map message."
<<
::
std
::
endl
;
return
MessagePtr
<
MessageFrame
>
(
nullptr
,
releaseMessage
(
MessageFrame
));
}
ret
->
present
=
MessageFrame_PR
::
MessageFrame_PR_mapFrame
;
ret
->
choice
.
mapFrame
.
msgCnt
=
getCount
();
ret
->
choice
.
mapFrame
.
timeStamp
=
reinterpret_cast
<
MinuteOfTheYear_t
*>
(
::
calloc
(
1
,
sizeof
(
MinuteOfTheYear_t
)));
fillRandomNumber
(
*
ret
->
choice
.
mapFrame
.
timeStamp
,
0
,
3000
);
Node_t
*
node
=
reinterpret_cast
<
Node_t
*>
(
::
calloc
(
1
,
sizeof
(
Node_t
)));
fillRandomNumber
(
node
->
id
.
id
,
0
,
65535
);
fillRandomNumber
(
node
->
refPos
.
Long
,
0
,
10000
);
fillRandomNumber
(
node
->
refPos
.
lat
,
0
,
10000
);
asn_sequence_add
(
&
(
ret
->
choice
.
mapFrame
.
nodes
.
list
),
node
);
return
ret
;
}
...
...
@@ -116,20 +180,45 @@ MessagePtr<MessageFrame> makeMapMessage()
*
* @return Fake message made.
*/
MessagePtr
<
MessageFrame
>
makeS
PAT
Message
()
MessagePtr
<
MessageFrame
>
makeS
pat
Message
()
{
MessagePtr
<
MessageFrame
>
ret
(
reinterpret_cast
<
MessageFrame
*>
(
::
calloc
(
1
,
sizeof
(
MessageFrame
))),
releaseMessage
(
MessageFrame
));
ret
->
present
=
MessageFrame_PR
::
MessageFrame_PR_spatFrame
;
::
asn_dec_rval_t
result
=
::
asn_decode
(
nullptr
,
ATS_RANDOM
,
&::
asn_DEF_SPAT
,
reinterpret_cast
<
void
**>
(
&
ret
->
choice
.
spatFrame
),
nullptr
,
0
);
if
(
result
.
code
!=
RC_OK
)
{
::
std
::
cerr
<<
"Failed to generate SPAT message."
<<
::
std
::
endl
;
return
MessagePtr
<
MessageFrame
>
(
nullptr
,
releaseMessage
(
MessageFrame
));
}
ret
->
present
=
MessageFrame_PR
::
MessageFrame_PR_spatFrame
;
ret
->
choice
.
spatFrame
.
msgCnt
=
getCount
();
ret
->
choice
.
spatFrame
.
timeStamp
=
reinterpret_cast
<
DSecond_t
*>
(
::
calloc
(
1
,
sizeof
(
DSecond_t
)));
fillRandomNumber
(
*
ret
->
choice
.
spatFrame
.
timeStamp
,
0
,
65535
);
IntersectionState_t
*
intersectionState
=
reinterpret_cast
<
IntersectionState_t
*>
(
::
calloc
(
1
,
sizeof
(
IntersectionState_t
)));
fillRandomNumber
(
intersectionState
->
intersectionId
.
id
,
0
,
65535
);
intersectionState
->
status
.
bits_unused
=
0
;
intersectionState
->
status
.
buf
=
reinterpret_cast
<::
std
::
uint8_t
*>
(
::
calloc
(
1
,
2
));
intersectionState
->
status
.
buf
[
0
]
=
0x01
;
intersectionState
->
status
.
buf
[
1
]
=
0x00
;
intersectionState
->
status
.
size
=
2
;
intersectionState
->
timeStamp
=
reinterpret_cast
<
MinuteOfTheYear_t
*>
(
::
calloc
(
1
,
sizeof
(
MinuteOfTheYear_t
)));
fillRandomNumber
(
*
intersectionState
->
timeStamp
,
0
,
3000
);
Phase_t
*
phase
=
reinterpret_cast
<
Phase_t
*>
(
::
calloc
(
1
,
sizeof
(
Phase_t
)));
fillRandomNumber
(
phase
->
id
,
0
,
255
);
PhaseState_t
*
phaseState
=
reinterpret_cast
<
PhaseState_t
*>
(
::
calloc
(
1
,
sizeof
(
PhaseState_t
)));
fillRandomNumber
(
phaseState
->
light
,
0
,
8
);
asn_sequence_add
(
&
(
phase
->
phaseStates
.
list
),
phaseState
);
asn_sequence_add
(
&
(
intersectionState
->
phases
.
list
),
phase
);
asn_sequence_add
(
&
(
ret
->
choice
.
spatFrame
.
intersections
.
list
),
intersectionState
);
return
ret
;
}
...
...
@@ -175,20 +264,23 @@ void readData(int fd)
*/
void
writeData
(
int
fd
)
{
MessagePtr
<
MessageFrame
>
messages
[]
{
makeBSMMessage
(),
makeMapMessage
(),
makeSPATMessage
()};
for
(
auto
&
message
:
messages
)
{
using
Generator
=
MessagePtr
<
MessageFrame
>
(
*
)();
Generator
generators
[]
=
{
makeBSMMessage
,
makeMapMessage
,
makeSpatMessage
};
for
(
auto
&
generator
:
generators
)
{
auto
message
=
generator
();
if
(
message
==
nullptr
)
{
continue
;
return
;
}
::
std
::
cout
<<
"Message generated."
<<
::
std
::
endl
;
char
buffer
[
MTU
];
::
asn_enc_rval_t
encodeResult
=
asn_encode_to_buffer
(
nullptr
,
ATS_UNALIGNED_CANONICAL_PER
,
&
asn_DEF_MessageFrame
,
reinterpret_cast
<
void
*>
(
message
.
get
()),
buffer
,
sizeof
(
buffer
));
reinterpret_cast
<
const
void
*>
(
message
.
get
()),
buffer
,
sizeof
(
buffer
));
if
(
encodeResult
.
encoded
>
0
)
{
ssize_t
sizeSent
=
::
send
(
fd
,
buffer
,
encodeResult
.
encoded
,
0
);
if
(
sizeSent
<
=
0
)
{
if
(
sizeSent
>
=
0
)
{
::
std
::
cout
<<
::
std
::
chrono
::
duration_cast
<::
std
::
chrono
::
seconds
>
(
::
std
::
chrono
::
system_clock
::
now
()
...
...
@@ -197,11 +289,33 @@ void writeData(int fd)
<<
" Data sent: "
<<
*
message
<<
::
std
::
endl
;
}
else
{
int
err
=
errno
;
::
std
::
cerr
<<
"Failed to send data: "
<<
::
strerror
(
err
);
::
std
::
cerr
<<
"Failed to send data: "
<<
::
strerror
(
err
)
<<
::
std
::
endl
;
return
;
}
}
else
{
::
std
::
cerr
<<
"Encode error."
<<
::
std
::
endl
;
int
err
=
errno
;
switch
(
err
)
{
case
EINVAL
:
{
::
std
::
cerr
<<
"Encode error: Incorrect parameters to the "
"function, such as NULLs."
<<
::
std
::
endl
;
}
break
;
case
ENOENT
:
{
::
std
::
cerr
<<
"Encode error: Encoding transfer syntax is "
"not defined (for this type)."
<<
::
std
::
endl
;
}
break
;
case
EBADF
:
{
::
std
::
cerr
<<
"Encode error: The structure has invalid "
"form or content constraint "
"failed."
<<
::
std
::
endl
;
}
break
;
default
:
::
std
::
cerr
<<
"Encode error: "
<<
::
strerror
(
err
)
<<
::
std
::
endl
;
}
}
}
}
...
...
@@ -232,7 +346,8 @@ int main(int argc, char *argv[])
int
fd
=
::
socket
(
AF_INET
,
SOCK_DGRAM
,
0
);
if
(
fd
<
0
)
{
int
err
=
errno
;
::
std
::
cerr
<<
"Failed to create socket: "
<<
::
strerror
(
err
);
::
std
::
cerr
<<
"Failed to create socket: "
<<
::
strerror
(
err
)
<<
::
std
::
endl
;
return
-
1
;
}
::
std
::
unique_ptr
<
int
,
void
(
*
)(
int
*
)
>
autoCloseFd
(
&
fd
,
...
...
@@ -251,7 +366,8 @@ int main(int argc, char *argv[])
sizeof
(
bindAddress
));
if
(
bindResult
<
0
)
{
int
err
=
errno
;
::
std
::
cerr
<<
"Failed to bind listen port: "
<<
::
strerror
(
err
);
::
std
::
cerr
<<
"Failed to bind listen port: "
<<
::
strerror
(
err
)
<<
::
std
::
endl
;
return
-
1
;
}
...
...
@@ -265,11 +381,12 @@ int main(int argc, char *argv[])
}
targetAddress
.
sin_port
=
targetPort
;
auto
connectResult
=
::
connect
(
AF_INET
,
reinterpret_cast
<::
sockaddr
*>
(
&
targetAddress
),
sizeof
(
target
Port
));
=
::
connect
(
fd
,
reinterpret_cast
<::
sockaddr
*>
(
&
targetAddress
),
sizeof
(
target
Address
));
if
(
connectResult
<
0
)
{
int
err
=
errno
;
::
std
::
cerr
<<
"Failed to connect to DMD3A port: "
<<
::
strerror
(
err
);
::
std
::
cerr
<<
"Failed to connect to DMD3A port: "
<<
::
strerror
(
err
)
<<
::
std
::
endl
;
return
-
1
;
}
...
...
@@ -284,7 +401,8 @@ int main(int argc, char *argv[])
quitEvent
=
::
eventfd
(
0
,
0
);
if
(
quitEvent
<
0
)
{
int
err
=
errno
;
::
std
::
cerr
<<
"Failed to create quit event: "
<<
::
strerror
(
err
);
::
std
::
cerr
<<
"Failed to create quit event: "
<<
::
strerror
(
err
)
<<
::
std
::
endl
;
return
-
1
;
}
::
std
::
unique_ptr
<
int
,
void
(
*
)(
int
*
)
>
autoCloseQuitEvent
(
...
...
@@ -319,11 +437,14 @@ int main(int argc, char *argv[])
::
std
::
array
<::
pollfd
,
2
>
fds
{
::
pollfd
{.
fd
=
fd
,
.
events
=
POLLIN
,
.
revents
=
0
},
::
pollfd
{.
fd
=
quitEvent
,
.
events
=
POLLIN
,
.
revents
=
0
}};
auto
pollResult
=
::
poll
(
fds
.
data
(),
fds
.
size
(),
::
std
::
chrono
::
duration_cast
<::
std
::
chrono
::
milliseconds
>
(
nextTimestamp
-
::
std
::
chrono
::
steady_clock
::
now
())
.
count
());
now
=
::
std
::
chrono
::
steady_clock
::
now
();
auto
pollResult
=
::
poll
(
fds
.
data
(),
fds
.
size
(),
(
now
<
nextTimestamp
?
::
std
::
chrono
::
duration_cast
<::
std
::
chrono
::
milliseconds
>
(
nextTimestamp
-
now
)
.
count
()
:
0
));
if
(
pollResult
>
0
)
{
for
(
auto
&
status
:
fds
)
{
if
(
status
.
revents
&
POLLIN
)
{
...
...
@@ -331,7 +452,7 @@ int main(int argc, char *argv[])
::
readData
(
fd
);
}
else
if
(
status
.
fd
==
quitEvent
)
{
::
std
::
cout
<<
"Quit event received."
<<
::
std
::
endl
;
break
;
return
0
;
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a 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