Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
spbro
OpenXG-RAN
Commits
34424c77
Commit
34424c77
authored
2 years ago
by
Robert Schmidt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove unnecessary ASN.1 macros and generation scripts
parent
feeb017e
No related merge requests found
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
0 additions
and
1254 deletions
+0
-1254
cmake_targets/macros.cmake
cmake_targets/macros.cmake
+0
-15
cmake_targets/tools/asn1tostruct.py
cmake_targets/tools/asn1tostruct.py
+0
-697
cmake_targets/tools/fix_asn1
cmake_targets/tools/fix_asn1
+0
-221
cmake_targets/tools/fix_asn1.data/RRC.rel10/SystemInformation-r8-IEs.h.diff
...s/fix_asn1.data/RRC.rel10/SystemInformation-r8-IEs.h.diff
+0
-23
cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff
...x_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff
+0
-47
cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff
...s/fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff
+0
-23
cmake_targets/tools/fix_asn1.data/X2AP.rel11.2/X2ap-CriticalityDiagnostics-IE-List.h.diff
...a/X2AP.rel11.2/X2ap-CriticalityDiagnostics-IE-List.h.diff
+0
-15
cmake_targets/tools/generate_asn1
cmake_targets/tools/generate_asn1
+0
-179
cmake_targets/tools/make_asn1c_includes.sh
cmake_targets/tools/make_asn1c_includes.sh
+0
-34
No files found.
cmake_targets/macros.cmake
View file @
34424c77
...
...
@@ -82,21 +82,6 @@ function(make_version VERSION_VALUE)
set
(
${
VERSION_VALUE
}
"
${
RESULT
}
"
PARENT_SCOPE
)
endfunction
()
macro
(
compile_asn1 asn1Source asn1cCmd ResultFlag
)
# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
execute_process
(
COMMAND
${
asn1cCmd
}
${
asn1Source
}
RESULT_VARIABLE ret
)
if
(
NOT
${
ret
}
STREQUAL 0
)
message
(
FATAL_ERROR
"
${
ret
}
: error"
)
endif
(
NOT
${
ret
}
STREQUAL 0
)
add_custom_target
(
${
ResultFlag
}
ALL
${
asn1cCmd
}
${
asn1Source
}
DEPENDS
${
asn1Source
}
)
endmacro
(
compile_asn1
)
macro
(
eval_boolean VARIABLE
)
if
(
${
ARGN
}
)
set
(
${
VARIABLE
}
ON
)
...
...
This diff is collapsed.
Click to expand it.
cmake_targets/tools/asn1tostruct.py
deleted
100755 → 0
View file @
feeb017e
This diff is collapsed.
Click to expand it.
cmake_targets/tools/fix_asn1
deleted
100755 → 0
View file @
feeb017e
#!/bin/bash
# in those arrays, each line is:
# <file> <sha1sum of file (without line 4 which changes depending on the location of the files)> <patch to apply to file>
RRC_Rel14
=(
"SystemInformation-r8-IEs.h"
4df485c5ddf2540eca271876cdc512caa19b0890
"fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff"
"SystemInformation-NB-r13-IEs.h"
6d91332d5c39205819b06e5e36efe62ff8e5b33b
"fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff"
)
RRC_Rel10
=(
"SystemInformation-r8-IEs.h"
603cd6615cff36ec7020692d72c0d6de7c4859cb
"fix_asn1.data/RRC.rel10/SystemInformation-r8-IEs.h.diff"
)
X2AP_Rel11_2
=(
"X2ap-CriticalityDiagnostics-IE-List.h"
ae96308b37fcbcbf39da5012e42968135fc5f27b
"fix_asn1.data/X2AP.rel11.2/X2ap-CriticalityDiagnostics-IE-List.h.diff"
)
red_color
=
"
$(
tput setaf 1
)
"
green_color
=
"
$(
tput setaf 2
)
"
reset_color
=
"
$(
tput sgr0
)
"
function
error
()
{
echo
-e
"
$red_color
"
ERROR:
"
$@
""
$reset_color
"
# exit 1
}
function
check_sha1
()
{
local
file
=
"
$1
"
local
target_sha1
=
"
$2
"
if
[
!
-f
"
$file
"
]
then
error
"
$file
: no such file"
fi
# we don't use the line 4 of the file
# it contains the location of the ASN1 grammar
# and this location is not the same on every
# installation (this is for *.h files, for *.c
# files it's no big deal to skip that line)
local
computed_sha1
=
$(
sed
4d
"
$file
"
|
sha1sum
|
cut
-f
1
-d
' '
)
if
[
"
$target_sha1
"
!=
"
$computed_sha1
"
]
then
error
"
$file
: wrong SHA1"
fi
}
function
patch_file
()
{
local
patch
=
"
$1
"
local
file
=
"
$2
"
echo
-e
"
$green_color
""patch file
$file
with
$OPENAIR_DIR
/cmake_targets/tools/
$patch
""
$reset_color
"
# patch "$file" "$OPENAIR_DIR/cmake_targets/tools/$patch"
# if [ $? -ne 0 ]
# then
# error "patching of $file with $OPENAIR_DIR/cmake_targets/tools/$patch failed"
# fi
}
function
apply_patches
()
{
local
directory
=
"
$1
"
local
array
=
$2
local
len
=
$3
# the length could be computed locally but the way to do it is not clear to me [CROUX]
local
i
local
file
local
sha1
local
patch
local
item
for
((
i
=
0
;
i <
$len
;
i +
=
3
))
do
# special bash syntax to access the array
item
=
$array
[
$i
]
;
file
=
${
!item
}
item
=
$array
[
$((
i+1
))
]
;
sha1
=
${
!item
}
item
=
$array
[
$((
i+2
))
]
;
patch
=
${
!item
}
check_sha1
"
$directory
/
$file
"
"
$sha1
"
patch_file
"
$patch
"
"
$directory
/
$file
"
done
}
function
patch_rrc
()
{
local
directory
=
"
$1
"
local
version
=
"
$2
"
case
"
$version
"
in
Rel14
)
echo
"patching RRC files release 14"
#apply_patches "$directory" RRC_Rel14 ${#RRC_Rel14[*]}
;;
Rel10
)
echo
"patching RRC files release 10"
apply_patches
"
$directory
"
RRC_Rel10
${#
RRC_Rel10
[*]
}
;;
Rel8
)
echo
"patching RRC files release 8 TODO?"
;;
*
)
error unknwon/unhandled RRC version
\'
"
$version
"
\'
;;
esac
}
function
patch_nr_rrc
()
{
local
directory
=
"
$1
"
local
version
=
"
$2
"
case
"
$version
"
in
NR_Rel15
)
echo
"patching NR_RRC files release 15"
apply_patches
"
$directory
"
NR_RRC_Rel15
${#
NR_RRC_Rel15
[*]
}
;;
*
)
error unknwon/unhandled NR_RRC version
\'
"
$version
"
\'
;;
esac
}
function
patch_x2ap
()
{
local
directory
=
"
$1
"
local
version
=
"
$2
"
case
"
$version
"
in
R14
)
;;
R11
)
echo
"patching X2AP files release 11.2"
apply_patches
"
$directory
"
X2AP_Rel11_2
${#
X2AP_Rel11_2
[*]
}
;;
*
)
error unknwon/unhandled X2AP version
\'
"
$version
"
\'
;;
esac
}
function
patch_s1ap
()
{
local
directory
=
"
$1
"
local
version
=
"
$2
"
case
"
$version
"
in
R14
)
;;
R10
)
#nothing to do anymore (fixes went to asn1c)
;;
*
)
error unknwon/unhandled S1AP version
\'
"
$version
"
\'
;;
esac
}
function
patch_f1ap
()
{
local
directory
=
"
$1
"
local
version
=
"
$2
"
case
"
$version
"
in
R15
)
#nothing to do anymore (fixes went to asn1c)
;;
*
)
error unknwon/unhandled F1AP version
\'
"
$version
"
\'
;;
esac
}
function
main
()
{
if
[
$#
-ne
3
]
then
echo
"ERROR: pass <output directory> <module> <version>"
exit
1
fi
if
[
x
"
$OPENAIR_DIR
"
=
x
]
then
error
"the variable OPENAIR_DIR is not set"
fi
local
directory
=
"
$1
"
local
module
=
"
$2
"
local
version
=
"
$3
"
case
"
$module
"
in
RRC
)
patch_rrc
"
$directory
"
"
$version
"
;;
NR_RRC
)
patch_nr_rrc
"
$directory
"
"
$version
"
;;
X2AP
)
patch_x2ap
"
$directory
"
"
$version
"
;;
S1AP
)
patch_s1ap
"
$directory
"
"
$version
"
;;
F1AP
)
patch_f1ap
"
$directory
"
"
$version
"
;;
*
)
error unknown module
"
$module
"
;;
esac
exit
0
}
main
"
$@
"
This diff is collapsed.
Click to expand it.
cmake_targets/tools/fix_asn1.data/RRC.rel10/SystemInformation-r8-IEs.h.diff
deleted
100755 → 0
View file @
feeb017e
57,61d56
< /* SystemInformation-r8-IEs */
< typedef struct SystemInformation_r8_IEs {
< struct SystemInformation_r8_IEs__sib_TypeAndInfo {
< A_SEQUENCE_OF(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member {
< SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR present;
79c74,78
< } choice;
---
> };
>
> struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member {
> SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR present;
> union SystemInformation_r8_IEs__sib_TypeAndInfo__Member_u choice;
83c82,87
< } ) list;
---
> };
>
> /* SystemInformation-r8-IEs */
> typedef struct SystemInformation_r8_IEs {
> struct SystemInformation_r8_IEs__sib_TypeAndInfo {
> A_SEQUENCE_OF(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member) list;
This diff is collapsed.
Click to expand it.
cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff
deleted
100755 → 0
View file @
feeb017e
48a49,70
> struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member {
> SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR present;
> union SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_u {
> SystemInformationBlockType2_NB_r13_t sib2_r13;
> SystemInformationBlockType3_NB_r13_t sib3_r13;
> SystemInformationBlockType4_NB_r13_t sib4_r13;
> SystemInformationBlockType5_NB_r13_t sib5_r13;
> SystemInformationBlockType14_NB_r13_t sib14_r13;
> SystemInformationBlockType16_NB_r13_t sib16_r13;
> /*
> * This type is extensible,
> * possible extensions are below.
> */
> SystemInformationBlockType15_NB_r14_t sib15_v1430;
> SystemInformationBlockType20_NB_r14_t sib20_v1430;
> SystemInformationBlockType22_NB_r14_t sib22_v1430;
> } choice;
>
> /* Context for parsing across buffer boundaries */
> asn_struct_ctx_t _asn_ctx;
> };
>
52,72c74
< A_SEQUENCE_OF(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member {
< SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR present;
< union SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_u {
< SystemInformationBlockType2_NB_r13_t sib2_r13;
< SystemInformationBlockType3_NB_r13_t sib3_r13;
< SystemInformationBlockType4_NB_r13_t sib4_r13;
< SystemInformationBlockType5_NB_r13_t sib5_r13;
< SystemInformationBlockType14_NB_r13_t sib14_r13;
< SystemInformationBlockType16_NB_r13_t sib16_r13;
< /*
< * This type is extensible,
< * possible extensions are below.
< */
< SystemInformationBlockType15_NB_r14_t sib15_v1430;
< SystemInformationBlockType20_NB_r14_t sib20_v1430;
< SystemInformationBlockType22_NB_r14_t sib22_v1430;
< } choice;
<
< /* Context for parsing across buffer boundaries */
< asn_struct_ctx_t _asn_ctx;
< } ) list;
---
> A_SEQUENCE_OF(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member) list;
This diff is collapsed.
Click to expand it.
cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff
deleted
100755 → 0
View file @
feeb017e
73,77d72
< /* SystemInformation-r8-IEs */
< typedef struct SystemInformation_r8_IEs {
< struct SystemInformation_r8_IEs__sib_TypeAndInfo {
< A_SEQUENCE_OF(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member {
< SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR present;
103c98,102
< } choice;
---
> };
>
> struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member {
> SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR present;
> union SystemInformation_r8_IEs__sib_TypeAndInfo__Member_u choice;
107c106,111
< } ) list;
---
> };
>
> /* SystemInformation-r8-IEs */
> typedef struct SystemInformation_r8_IEs {
> struct SystemInformation_r8_IEs__sib_TypeAndInfo {
> A_SEQUENCE_OF(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member) list;
This diff is collapsed.
Click to expand it.
cmake_targets/tools/fix_asn1.data/X2AP.rel11.2/X2ap-CriticalityDiagnostics-IE-List.h.diff
deleted
100755 → 0
View file @
feeb017e
29,31c29
< /* X2ap-CriticalityDiagnostics-IE-List */
< typedef struct X2ap_CriticalityDiagnostics_IE_List {
< A_SEQUENCE_OF(struct X2ap_CriticalityDiagnostics_IE_List__Member {
---
> struct X2ap_CriticalityDiagnostics_IE_List__Member {
43c41,46
< } ) list;
---
> };
>
> /* X2ap-CriticalityDiagnostics-IE-List */
> typedef struct X2ap_CriticalityDiagnostics_IE_List {
> A_SEQUENCE_OF(struct X2ap_CriticalityDiagnostics_IE_List__Member
> ) list;
This diff is collapsed.
Click to expand it.
cmake_targets/tools/generate_asn1
deleted
100755 → 0
View file @
feeb017e
#!/bin/bash
function
main
()
{
PROTOCOL_DIR
=
$1
mkdir
-p
${
PROTOCOL_DIR
}
cd
${
PROTOCOL_DIR
}
# Because use $* also include directory, so we need shift
shift
local
module
=
"
$2
"
#if this script is called with only 2 arguments (so 1 here after the shift), it's for RRC
#(there may be a better way...)
if
[
$#
-eq
2
]
;
then
#asn1c does not work well with extension groups, we need the following fix:
# replace [[ by '<name> SEQUENCE {'
# and ]] by '} OPTIONAL'
#<name> is ext<N> with N starting from 1 and incremented at each new [[ ]] just
#following another [[ ]]
#
#this is what the following C program does
echo
generate asnfix.c
cat
<<
EOF
> asnfix.c
/* transforms:
* '[[' to 'name SEQUENCE {'
* ']]' to '} OPTIONAL'
* name is ext1, ext2, ..., for each [[ at the same level
* levels are delimited by { and }
* -- to end of line is a comment and unprocessed
* nested [[ ]] not handled
* { and } must be balanced
* [[ and ]] can be whatever, every combination is valid
*/
#include <stdio.h>
#include <stdlib.h>
void level(int toplevel)
{
int c;
int next_name = 1;
while (1) {
c = getchar();
next:
if (c == EOF) { if (toplevel) break; abort(); }
if (c == '-') {
c = getchar();
if (c != '-') { putchar('-'); goto next; }
putchar(c); putchar(c);
while (1) {
c = getchar(); if (c == EOF) abort();
putchar(c);
if (c == '
\n
') break;
}
continue;
}
if (c == '[') {
c = getchar();
if (c != '[') { putchar('['); goto next; }
printf("ext%d SEQUENCE {", next_name);
next_name++;
continue;
}
if (c == ']') {
c = getchar();
if (c != ']') { putchar(']'); goto next; }
printf("} OPTIONAL");
continue;
}
putchar(c);
if (c == '}') { if (toplevel) abort(); break; }
if (c == '{') level(0);
}
}
int main(void)
{
level(1);
fflush(stdout);
return 0;
}
EOF
echo
compile asnfix.c
gcc
-Wall
-o
asnfix asnfix.c
echo
run asnfix on
$1
./asnfix <
$1
>
fixed_grammar.asn
rm
-f
asnfix asnfix.c
echo
done
with asnfix
echo
running asn1c
case
"
$module
"
in
RRC
)
asn1c
-gen-PER
-fcompound-names
-no-gen-example
fixed_grammar.asn 2>&1 |
grep
-v
--
'->'
|
grep
-v
'^Compiled'
|grep
-v
sample
;;
NR_RRC
)
export
ASN1C_PREFIX
=
NR_
asn1c
-gen-PER
-fcompound-names
-findirect-choice
-no-gen-example
fixed_grammar.asn 2>&1 |
grep
-v
--
'->'
|
grep
-v
'^Compiled'
|grep
-v
sample
;;
S1AP
)
export
ASN1C_PREFIX
=
S1AP_
asn1c
-gen-PER
-fcompound-names
-no-gen-example
fixed_grammar.asn 2>&1 |
grep
-v
--
'->'
|
grep
-v
'^Compiled'
|grep
-v
sample
;;
X2AP
)
export
ASN1C_PREFIX
=
X2AP_
asn1c
-gen-PER
-fcompound-names
-no-gen-example
fixed_grammar.asn 2>&1 |
grep
-v
--
'->'
|
grep
-v
'^Compiled'
|grep
-v
sample
;;
esac
rm
-f
fixed_grammar.asn
echo
asn1c
done
elif
echo
${
PROTOCOL_DIR
}
|
grep
-q
"F1AP"
;
then
asn1c
-gen-PER
-fcompound-names
-no-gen-example
-findirect-choice
-fno-include-deps
$*
2>&1 |
grep
-v
--
'->'
|
grep
-v
'^Compiled'
|grep
-v
sample
else
case
"
$module
"
in
RRC
)
asn1c
-pdu
=
all
-fcompound-names
-gen-PER
-no-gen-OER
-no-gen-example
$*
2>&1 |
grep
-v
--
'->'
|
grep
-v
'^Compiled'
|grep
-v
sample
;;
NR_RRC
)
export
ASN1C_PREFIX
=
NR_
asn1c
-fcompound-names
-findirect-choice
-fno-include-deps
-gen-PER
-no-gen-OER
-no-gen-example
$*
2>&1 |
grep
-v
--
'->'
|
grep
-v
'^Compiled'
|grep
-v
sample
;;
S1AP
)
export
ASN1C_PREFIX
=
S1AP_
asn1c
-fcompound-names
-fno-include-deps
-gen-PER
-no-gen-OER
-no-gen-example
$*
2>&1 |
grep
-v
--
'->'
|
grep
-v
'^Compiled'
|grep
-v
sample
;;
X2AP
)
export
ASN1C_PREFIX
=
X2AP_
asn1c
-fcompound-names
-fno-include-deps
-gen-PER
-no-gen-OER
-no-gen-example
$*
2>&1 |
grep
-v
--
'->'
|
grep
-v
'^Compiled'
|grep
-v
sample
;;
esac
fi
awk
'
BEGIN {
print "#ifndef __ASN1_CONSTANTS_H__"
print "#define __ASN1_CONSTANTS_H__"
}
/INTEGER ::=/ {
gsub("INTEGER ::=","")
gsub("--","//")
gsub("-1","_minus_1")
gsub("-","_")
printf("#define %s\n",$0)
}
/::=.*INTEGER.*[(]/ {
nb_fields=split($0,val,"[:=().]+");
gsub("-","_",val[1]);
printf("#define min_val_%s %s\n",val[1],val[nb_fields-2]);
printf("#define max_val_%s %s\n",val[1],val[nb_fields-1]);
}
END {
print "#endif ";
} '
$1
>
asn1_constants.h
}
main
"
$@
"
This diff is collapsed.
Click to expand it.
cmake_targets/tools/make_asn1c_includes.sh
deleted
100755 → 0
View file @
feeb017e
#!/bin/bash
export
ASN1C_PREFIX
=
$1
shift
options
=
$1
shift
GENERATED_FULL_DIR
=
$1
shift
ASN1_SOURCE_DIR
=
$*
done_flag
=
"
$GENERATED_FULL_DIR
"
/done
rebuild
=
0
for
f
in
$ASN1_SOURCE_DIR
;
do
if
[
"
$done_flag
"
-ot
"
$f
"
]
;
then
rebuild
=
1
fi
done
if
[
$rebuild
-eq
1
]
;
then
rm
-f
"
$GENERATED_FULL_DIR
"
/
${
ASN1C_PREFIX
}*
.c
"
$GENERATED_FULL_DIR
"
/
${
ASN1C_PREFIX
}*
.h
mkdir
-p
"
$GENERATED_FULL_DIR
"
asn1c
-pdu
=
all
-fcompound-names
-gen-PER
-no-gen-OER
-no-gen-example
$options
-D
$GENERATED_FULL_DIR
$ASN1_SOURCE_DIR
|& egrep
-v
"^Copied|^Compiled"
|
sort
-u
if
[
"
$ASN1C_PREFIX
"
=
"X2AP_"
]
;
then
sed
-i
's/18446744073709551615))/18446744073709551615U))/g'
"
$GENERATED_FULL_DIR
"
/
${
ASN1C_PREFIX
}
E-RABUsageReport-Item.c
sed
-i
's/18446744073709551615 }/18446744073709551615U }/g'
"
$GENERATED_FULL_DIR
"
/
${
ASN1C_PREFIX
}
E-RABUsageReport-Item.c
fi
if
[
"
$ASN1C_PREFIX
"
=
"S1AP_"
]
;
then
sed
-i
's/18446744073709551615))/18446744073709551615U))/g'
"
$GENERATED_FULL_DIR
"
/
${
ASN1C_PREFIX
}
E-RABUsageReportItem.c
sed
-i
's/18446744073709551615 }/18446744073709551615U }/g'
"
$GENERATED_FULL_DIR
"
/
${
ASN1C_PREFIX
}
E-RABUsageReportItem.c
fi
if
[
"
$ASN1C_PREFIX
"
=
"NGAP_"
]
;
then
sed
-i
's/18446744073709551615))/18446744073709551615U))/g'
"
$GENERATED_FULL_DIR
"
/
${
ASN1C_PREFIX
}
VolumeTimedReport-Item.c
sed
-i
's/18446744073709551615 }/18446744073709551615U }/g'
"
$GENERATED_FULL_DIR
"
/
${
ASN1C_PREFIX
}
VolumeTimedReport-Item.c
fi
fi
touch
$done_flag
This diff is collapsed.
Click to expand it.
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