cddl 0.8.8 → 0.8.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/cddl +10 -2
- data/cddl.gemspec +2 -1
- data/data/cddl.abnf +1 -0
- data/lib/cddl.rb +132 -17
- data/test/test-cddl.rb +51 -0
- data/test-data/7807.cddl +14 -0
- data/test-data/abignum.cddl +1 -0
- data/test-data/bpv7.cddl +136 -0
- data/test-data/bpv7a.cddl +181 -0
- data/test-data/bpv7b.cddl +167 -0
- data/test-data/coral.cddl +10 -0
- data/test-data/coral1.cddl +5 -0
- data/test-data/coral2.cddl +7 -0
- data/test-data/coral3.cddl +7 -0
- data/test-data/feat1.cddl +4 -0
- data/test-data/feature-detail.cddl +5 -0
- data/test-data/foo.cddl +1 -0
- data/test-data/jim-cut-2.cddl +11 -0
- data/test-data/jim-cut.cddl +12 -0
- data/test-data/jsoniodef.cddl +719 -0
- data/test-data/mdl-ble.cddl +9 -0
- data/test-data/mdl-deve.cddl +54 -0
- data/test-data/mdl-dp.cddl +11 -0
- data/test-data/mdl-mso.cddl +20 -0
- data/test-data/mdl-request.cddl +26 -0
- data/test-data/mdl-response.cddl +66 -0
- data/test-data/mdl.cddl +11 -0
- data/test-data/mon-val.cddl +1 -0
- data/test-data/multipart-ct.cddl +2 -0
- data/test-data/named-group.cddl +7 -0
- data/test-data/sequence.cddl +1 -0
- data/test-data/test-gen.cddl +3 -0
- metadata +33 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e7b1df5544e11b299155468f15b649f61bf3d281644a0917be5eec9aa099f8bd
|
|
4
|
+
data.tar.gz: c29c65aec8cec554d0ca3e837dafd2cbb18bdec41552666c6f81db52f189e491
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5ba99f5a974fb235e2dfeea4fd55dd8feb2fa15a558e5fe77c1c8a921ccacd83c7f292bb767bda835616cb484d86015cd8c2d6a81a675f889c7f751079d62a54
|
|
7
|
+
data.tar.gz: b5b18dada347123ed8d7b664987a441820ff73c8ead7146b00b310249f54ef8a6f6ed156c90cf32dd92ad682f9c974664e3986066240ecc7ae996520ae37b231
|
data/bin/cddl
CHANGED
|
@@ -50,11 +50,15 @@ end
|
|
|
50
50
|
|
|
51
51
|
begin
|
|
52
52
|
case ARGV[1]
|
|
53
|
-
when /\A
|
|
53
|
+
when /\A..*p/
|
|
54
54
|
$annotate = true
|
|
55
55
|
require_relative '../lib/cbor-pp'
|
|
56
56
|
end
|
|
57
57
|
case ARGV[1]
|
|
58
|
+
when /\A..*s/
|
|
59
|
+
$sequence = true
|
|
60
|
+
end
|
|
61
|
+
case ARGV[1]
|
|
58
62
|
when /\Ar/ # secret
|
|
59
63
|
$advanced = true
|
|
60
64
|
my_pp parser.rules
|
|
@@ -83,7 +87,11 @@ begin
|
|
|
83
87
|
end
|
|
84
88
|
when /\Av/
|
|
85
89
|
instance = read_arg(ARGV[2])
|
|
86
|
-
instance =
|
|
90
|
+
instance = if $sequence
|
|
91
|
+
CBOR.decode("\x9f".b << instance.b << "\xff".b)
|
|
92
|
+
else
|
|
93
|
+
CBOR.decode(instance.b) rescue JSON.load(instance)
|
|
94
|
+
end
|
|
87
95
|
instance = instance.cbor_clone if $annotate && ENV["EXPERIMENTAL_ANNOTATE"]
|
|
88
96
|
ann = parser.validate(instance)
|
|
89
97
|
# my_pp ann
|
data/cddl.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
spec = Gem::Specification.new do |s|
|
|
2
2
|
s.name = 'cddl'
|
|
3
|
-
s.version = '0.8.
|
|
3
|
+
s.version = '0.8.15'
|
|
4
4
|
s.summary = "CDDL generator and validator."
|
|
5
5
|
s.description = %{A parser, generator, and validator for CDDL}
|
|
6
6
|
s.add_dependency('cbor-diag')
|
|
@@ -19,3 +19,4 @@ spec = Gem::Specification.new do |s|
|
|
|
19
19
|
s.homepage = "http://github.com/cabo/cddl"
|
|
20
20
|
s.license = 'MIT'
|
|
21
21
|
end
|
|
22
|
+
|
data/data/cddl.abnf
CHANGED
|
@@ -16,6 +16,7 @@ type1 = type2 [S (rangeop / annotator) S type2]
|
|
|
16
16
|
/ "#" "6" ["." uint] "(" S type S ")" ; note no space!
|
|
17
17
|
/ "#" DIGIT ["." uint] ; major/ai
|
|
18
18
|
/ "#" ; any
|
|
19
|
+
/ "~" S typename [genericarg]
|
|
19
20
|
/ "{" S group S "}"
|
|
20
21
|
/ "[" S group S "]"
|
|
21
22
|
/ "&" S "(" S group S ")"
|
data/lib/cddl.rb
CHANGED
|
@@ -329,8 +329,12 @@ module CDDL
|
|
|
329
329
|
unless kr
|
|
330
330
|
case vr[0]
|
|
331
331
|
when :grpent
|
|
332
|
-
fail "grpent in map #{vr.inspect}" unless vr.size == 2
|
|
333
|
-
g = Array.new(st) {
|
|
332
|
+
# fail "grpent in map #{vr.inspect}" unless vr.size == 2
|
|
333
|
+
g = Array.new(st) {
|
|
334
|
+
vr[1..-1].map{ |vrx|
|
|
335
|
+
generate1(vrx, true)
|
|
336
|
+
}.flatten(1)
|
|
337
|
+
}.flatten(1)
|
|
334
338
|
# warn "GGG #{g.inspect}"
|
|
335
339
|
return g
|
|
336
340
|
when :grpchoice
|
|
@@ -435,6 +439,31 @@ module CDDL
|
|
|
435
439
|
$default_warned = true
|
|
436
440
|
end
|
|
437
441
|
generate1(target, inmap)
|
|
442
|
+
when :feature
|
|
443
|
+
generate1(target, inmap)
|
|
444
|
+
when :cat
|
|
445
|
+
lhs = generate1(target, inmap)
|
|
446
|
+
rhs = generate1(control)
|
|
447
|
+
begin
|
|
448
|
+
lhs + rhs
|
|
449
|
+
rescue Exception => e
|
|
450
|
+
fail "Can't #{lhs.inspect} .cat #{rhs.inspect}: #{e.message}"
|
|
451
|
+
end
|
|
452
|
+
when :plus
|
|
453
|
+
lhs = generate1(target, inmap)
|
|
454
|
+
rhs = generate1(control)
|
|
455
|
+
begin
|
|
456
|
+
case lhs
|
|
457
|
+
when Integer
|
|
458
|
+
lhs + Integer(rhs)
|
|
459
|
+
when Numeric
|
|
460
|
+
lhs + rhs
|
|
461
|
+
else
|
|
462
|
+
fail "#{lhs.inspect}: Not a number"
|
|
463
|
+
end
|
|
464
|
+
rescue Exception => e
|
|
465
|
+
fail "Can't #{lhs.inspect} .plus #{rhs.inspect}: #{e.message}"
|
|
466
|
+
end
|
|
438
467
|
when :eq
|
|
439
468
|
content = generate1(control)
|
|
440
469
|
if validate1(content, where)
|
|
@@ -523,7 +552,7 @@ module CDDL
|
|
|
523
552
|
end
|
|
524
553
|
end
|
|
525
554
|
|
|
526
|
-
VALUE_TYPE = {text: String, int: Integer, float: Float}
|
|
555
|
+
VALUE_TYPE = {text: String, bytes: String, int: Integer, float: Float}
|
|
527
556
|
SIMPLE_VALUE = {
|
|
528
557
|
[:prim, 7, 20] => [true, false, :bool],
|
|
529
558
|
[:prim, 7, 21] => [true, true, :bool],
|
|
@@ -536,9 +565,34 @@ module CDDL
|
|
|
536
565
|
[true, t[1], vt]
|
|
537
566
|
elsif v = SIMPLE_VALUE[t]
|
|
538
567
|
v
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
568
|
+
elsif t[0] == :anno
|
|
569
|
+
_, conop, target, control = t
|
|
570
|
+
# warn ["EXV0", conop, target, control].inspect
|
|
571
|
+
if conop == :cat || conop == :plus
|
|
572
|
+
ok1, v1, vt1 = extract_value(target)
|
|
573
|
+
ok2, v2, vt2 = extract_value(control)
|
|
574
|
+
# warn ["EXV", ok1, v1, vt1, ok2, v2, vt2].inspect
|
|
575
|
+
if ok1 && ok2
|
|
576
|
+
if vt1 == Integer
|
|
577
|
+
[true, v1 + Integer(v2), Integer] if vt2 == Integer || vt2 == Float
|
|
578
|
+
elsif vt1 == Float
|
|
579
|
+
[true, v1 + v2, vt1] if vt2 == Integer || vt2 == Float
|
|
580
|
+
else
|
|
581
|
+
[true, v1 + v2, vt1] if vt1 == vt2
|
|
582
|
+
end
|
|
583
|
+
end rescue nil
|
|
584
|
+
end
|
|
585
|
+
end || [false]
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
def extract_array(t)
|
|
589
|
+
return [false] unless t[0] == :array
|
|
590
|
+
[true, *t[1..-1].map { |el|
|
|
591
|
+
return [false] unless el[0..3] == [:member, 1, 1, nil]
|
|
592
|
+
ok, v, vt = extract_value(el[4])
|
|
593
|
+
return [false] unless ok
|
|
594
|
+
[v, vt]
|
|
595
|
+
}]
|
|
542
596
|
end
|
|
543
597
|
|
|
544
598
|
def validate_diag
|
|
@@ -547,11 +601,17 @@ module CDDL
|
|
|
547
601
|
|
|
548
602
|
def validate(d, warn=true)
|
|
549
603
|
@recursion = 0
|
|
604
|
+
$features = Hash.new {|h, k| h[k] = {}}
|
|
550
605
|
result = validate1a(d, rules)
|
|
551
|
-
|
|
552
|
-
if
|
|
606
|
+
if warn
|
|
607
|
+
if result
|
|
608
|
+
if $features != {}
|
|
609
|
+
warn "** Features potentially used: #{$features.map {|k, v| "#{k}: #{v.keys}"}.join(", ")}"
|
|
610
|
+
end
|
|
611
|
+
else
|
|
553
612
|
warn "CDDL validation failure (#{result.inspect} for #{d.inspect}):"
|
|
554
613
|
PP::pp(validate_diag, STDERR)
|
|
614
|
+
puts(validate_diag.cbor_diagnostic)
|
|
555
615
|
end
|
|
556
616
|
end
|
|
557
617
|
result
|
|
@@ -741,16 +801,27 @@ module CDDL
|
|
|
741
801
|
idx, ann = validate_forward(d, 0, where)
|
|
742
802
|
ann if validate_result(idx == d.size) { "#{validate_diag.inspect} -- cannot complete (#{idx}, #{d.size}) array #{d} for #{where}" }
|
|
743
803
|
end
|
|
744
|
-
when :
|
|
804
|
+
when :int, :float
|
|
745
805
|
_, v = extract_value(where)
|
|
746
806
|
[] if d == v
|
|
807
|
+
when :text, :bytes
|
|
808
|
+
_, v = extract_value(where)
|
|
809
|
+
[] if d == v && ((d.encoding == Encoding::BINARY) == (v.encoding == Encoding::BINARY))
|
|
747
810
|
when :range
|
|
748
811
|
[] if where[2] === d && where[1].include?(d)
|
|
749
812
|
when :anno
|
|
750
|
-
target = where
|
|
751
|
-
if
|
|
752
|
-
|
|
753
|
-
|
|
813
|
+
_, conop, target, control = where
|
|
814
|
+
if conop == :cat || conop == :plus
|
|
815
|
+
ok1, v1, vt1 = extract_value(target)
|
|
816
|
+
ok2, v2, vt2 = extract_value(control)
|
|
817
|
+
# warn ["ANNO0", ok1, v1, vt1, ok2, v2, vt2, d].inspect
|
|
818
|
+
if ok1 && ok2
|
|
819
|
+
v2 = Integer(v2) if vt1 == Integer
|
|
820
|
+
# warn ["ANNO", ok1, v1, vt1, ok2, v2, vt2, d].inspect
|
|
821
|
+
[] if d == v1 + v2 # XXX Focus ArgumentError
|
|
822
|
+
end
|
|
823
|
+
elsif ann = validate1a(d, target)
|
|
824
|
+
case conop
|
|
754
825
|
when :size
|
|
755
826
|
case d
|
|
756
827
|
when Integer
|
|
@@ -789,8 +860,24 @@ module CDDL
|
|
|
789
860
|
$default_warned = true
|
|
790
861
|
end
|
|
791
862
|
ann
|
|
863
|
+
when :feature
|
|
864
|
+
ok, v, vt = extract_value(control)
|
|
865
|
+
if ok
|
|
866
|
+
nm = v
|
|
867
|
+
det = d
|
|
868
|
+
else
|
|
869
|
+
ok, *v = extract_array(control)
|
|
870
|
+
if ok && v.size == 2
|
|
871
|
+
nm = v[0][0]
|
|
872
|
+
det = v[1][0]
|
|
873
|
+
else
|
|
874
|
+
warn "*** feature controller not implemented: #{control.inspect}"
|
|
875
|
+
end
|
|
876
|
+
end
|
|
877
|
+
$features[nm][det] = true
|
|
878
|
+
ann
|
|
792
879
|
when :lt, :le, :gt, :ge, :eq, :ne
|
|
793
|
-
op = OPERATORS[
|
|
880
|
+
op = OPERATORS[conop]
|
|
794
881
|
ok, v, _vt = extract_value(control)
|
|
795
882
|
if ok
|
|
796
883
|
ann if d.send(op, v) rescue nil # XXX Focus ArgumentError
|
|
@@ -837,6 +924,14 @@ module CDDL
|
|
|
837
924
|
when 3
|
|
838
925
|
String === d && d.encoding != Encoding::BINARY # cheat
|
|
839
926
|
when 6
|
|
927
|
+
if Integer === d
|
|
928
|
+
t = 2 # assuming only 2/3 match an Integer
|
|
929
|
+
if d < 0
|
|
930
|
+
d = ~d
|
|
931
|
+
t = 3
|
|
932
|
+
end
|
|
933
|
+
d = CBOR::Tagged.new(t, d == 0 ? "".b : d.digits(256).reverse!.pack("C*"))
|
|
934
|
+
end
|
|
840
935
|
CBOR::Tagged === d && d.tag == where[2] && validate1a(d.data, where[3])
|
|
841
936
|
when 7
|
|
842
937
|
t, v = extract_value(where)
|
|
@@ -959,7 +1054,7 @@ module CDDL
|
|
|
959
1054
|
when ""
|
|
960
1055
|
parts[1].b
|
|
961
1056
|
when "h"
|
|
962
|
-
parts[1].gsub(/\s/, "").chars.each_slice(2).map{ |x| Integer(x.join, 16).chr("BINARY") }.join
|
|
1057
|
+
parts[1].gsub(/\s/, "").chars.each_slice(2).map{ |x| Integer(x.join, 16).chr("BINARY") }.join.b
|
|
963
1058
|
when "b64"
|
|
964
1059
|
Base64.urlsafe_decode64(parts[1])
|
|
965
1060
|
else
|
|
@@ -1142,7 +1237,7 @@ module CDDL
|
|
|
1142
1237
|
end
|
|
1143
1238
|
when :recurse_grpent # XXX we don't have the entry yet
|
|
1144
1239
|
when :member
|
|
1145
|
-
fail "map entry without member key given: #{member}" unless member[3] || member[4][0] == :grpent || member[4][0] == :grpchoice
|
|
1240
|
+
fail "map entry #{member.inspect} without member key given: #{member}" unless member[3] || member[4][0] == :grpent || member[4][0] == :grpchoice
|
|
1146
1241
|
else
|
|
1147
1242
|
fail ["type1 member", member].inspect unless member[0] == :member
|
|
1148
1243
|
end
|
|
@@ -1152,7 +1247,7 @@ module CDDL
|
|
|
1152
1247
|
BRACE = {"{" => :map, "[" => :array}
|
|
1153
1248
|
RANGE_EXCLUDE_END = {".." => false, "..." => true}
|
|
1154
1249
|
SUPPORTED_ANNOTATIONS = [:bits, :size, :regexp, :cbor, :cborseq, :within, :and,
|
|
1155
|
-
:default, :lt, :le, :gt, :ge, :eq, :ne]
|
|
1250
|
+
:default, :lt, :le, :gt, :ge, :eq, :ne, :feature, :cat, :plus]
|
|
1156
1251
|
|
|
1157
1252
|
def type1(n, canbegroup = false)
|
|
1158
1253
|
# puts "NVALUE #{n.value.inspect}"
|
|
@@ -1214,6 +1309,26 @@ module CDDL
|
|
|
1214
1309
|
v
|
|
1215
1310
|
}
|
|
1216
1311
|
]
|
|
1312
|
+
when /\A~/
|
|
1313
|
+
if tn = n.typename
|
|
1314
|
+
s = type_recall(tn.to_s, false, n.genericarg).flatten(1)
|
|
1315
|
+
else
|
|
1316
|
+
fail "No typename in unwrap #{n}"
|
|
1317
|
+
end
|
|
1318
|
+
if s[0] != :type1
|
|
1319
|
+
fail [:UNWRAPs0, s].inspect
|
|
1320
|
+
end
|
|
1321
|
+
case s[1]
|
|
1322
|
+
when :map, :array
|
|
1323
|
+
[:grpent, s[2..-1]]
|
|
1324
|
+
when :prim
|
|
1325
|
+
if s[2] != 6
|
|
1326
|
+
fail [:UNWRAPs2, s].inspect
|
|
1327
|
+
end
|
|
1328
|
+
s[4] # check :type1?
|
|
1329
|
+
else
|
|
1330
|
+
fail [:UNWRAPs1, s].inspect
|
|
1331
|
+
end
|
|
1217
1332
|
else
|
|
1218
1333
|
"unimplemented #{n}"
|
|
1219
1334
|
end
|
data/test/test-cddl.rb
CHANGED
|
@@ -171,6 +171,57 @@ HERE
|
|
|
171
171
|
assert parser.validate_for_test(true)
|
|
172
172
|
end
|
|
173
173
|
|
|
174
|
+
def test_validate_bignum
|
|
175
|
+
parser = CDDL::Parser.new <<HERE
|
|
176
|
+
test = bigint
|
|
177
|
+
HERE
|
|
178
|
+
assert parser.validate_for_test(2**4711)
|
|
179
|
+
assert parser.validate_for_test(-2**815)
|
|
180
|
+
assert parser.validate_for_test(1)
|
|
181
|
+
assert parser.validate_for_test(0)
|
|
182
|
+
assert parser.validate_for_test(-11)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def test_aaaaaaaa_invalidate_bignum
|
|
186
|
+
parser = CDDL::Parser.new <<HERE
|
|
187
|
+
test = bignint
|
|
188
|
+
HERE
|
|
189
|
+
refute parser.validate_for_test(2**4711, false)
|
|
190
|
+
assert parser.validate_for_test(-2**815)
|
|
191
|
+
refute parser.validate_for_test(1, false)
|
|
192
|
+
refute parser.validate_for_test(0, false)
|
|
193
|
+
assert parser.validate_for_test(-11)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def test_aaaaaaaa_validate_bignum0b
|
|
198
|
+
parser = CDDL::Parser.new <<HERE
|
|
199
|
+
test = #6.2("")
|
|
200
|
+
HERE
|
|
201
|
+
refute parser.validate_for_test(1, false)
|
|
202
|
+
refute parser.validate_for_test(0, false)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def test_aaaaaaaa_validate_bignum0
|
|
207
|
+
parser = CDDL::Parser.new <<HERE
|
|
208
|
+
test = #6.2(h'')
|
|
209
|
+
HERE
|
|
210
|
+
assert parser.validate_for_test(0)
|
|
211
|
+
refute parser.validate_for_test(1, false)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def test_aaaaaaaa_validate_bignum1
|
|
216
|
+
parser = CDDL::Parser.new <<HERE
|
|
217
|
+
test = #6.2(h'01')
|
|
218
|
+
HERE
|
|
219
|
+
assert parser.validate_for_test(1)
|
|
220
|
+
refute parser.validate_for_test(0, false)
|
|
221
|
+
refute parser.validate_for_test(2, false)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
|
|
174
225
|
def test_validate_a
|
|
175
226
|
parser = CDDL::Parser.new <<HERE
|
|
176
227
|
test = [* one: 1]
|
data/test-data/7807.cddl
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
coap-problem-details = {
|
|
2
|
+
type => uint,
|
|
3
|
+
? title => text,
|
|
4
|
+
? response-code => bstr .size 1,
|
|
5
|
+
? detail => text,
|
|
6
|
+
? instance => uri,
|
|
7
|
+
* $$coap-problem-details-extension,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type = 0
|
|
11
|
+
title = 1
|
|
12
|
+
response-code = 2
|
|
13
|
+
detail = 3
|
|
14
|
+
instance = 4
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
abignum = unsigned
|
data/test-data/bpv7.cddl
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
start = bundle
|
|
2
|
+
|
|
3
|
+
dtn-time = uint
|
|
4
|
+
|
|
5
|
+
creation-timestamp = [dtn-time, sequence: uint]
|
|
6
|
+
|
|
7
|
+
eid-generic = [uri-code, SSP: any]
|
|
8
|
+
|
|
9
|
+
uri-code = uint
|
|
10
|
+
|
|
11
|
+
eid = eid-choice .within eid-generic
|
|
12
|
+
|
|
13
|
+
eid-choice /= [dtn-code, SSP: (text / 0)]
|
|
14
|
+
|
|
15
|
+
dtn-code = 1 ; TBD
|
|
16
|
+
|
|
17
|
+
eid-choice /= [ipn-code, SSP: [nodenum: uint, servicenum: uint]]
|
|
18
|
+
|
|
19
|
+
ipn-code = 2 ; TBD
|
|
20
|
+
|
|
21
|
+
bundle-control-flags = uint .bits bundleflagbits
|
|
22
|
+
|
|
23
|
+
bundleflagbits = &(
|
|
24
|
+
|
|
25
|
+
reserved: 15
|
|
26
|
+
|
|
27
|
+
reserved: 14
|
|
28
|
+
|
|
29
|
+
reserved: 13
|
|
30
|
+
|
|
31
|
+
bundle-deletion-status-reports-are-requested: 12
|
|
32
|
+
|
|
33
|
+
bundle-delivery-status-reports-are-requested: 11
|
|
34
|
+
|
|
35
|
+
bundle-forwarding-status-reports-are-requested: 10
|
|
36
|
+
|
|
37
|
+
reserved: 9
|
|
38
|
+
|
|
39
|
+
bundle-reception-status-reports-are-requested: 8
|
|
40
|
+
|
|
41
|
+
bundle-contains-a-Manifest-block: 7
|
|
42
|
+
|
|
43
|
+
status-time-is-requested-in-all-status-reports: 6
|
|
44
|
+
|
|
45
|
+
user-application-acknowledgement-is-requested: 5
|
|
46
|
+
|
|
47
|
+
reserved: 4
|
|
48
|
+
|
|
49
|
+
reserved: 3
|
|
50
|
+
|
|
51
|
+
bundle-must-not-be-fragmented: 2
|
|
52
|
+
|
|
53
|
+
payload-is-an-administrative-record: 1
|
|
54
|
+
|
|
55
|
+
bundle-is-a-fragment: 0
|
|
56
|
+
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
crc = bytes
|
|
60
|
+
|
|
61
|
+
block-control-flags = uint .bits blockflagbits
|
|
62
|
+
|
|
63
|
+
blockflagbits = &(
|
|
64
|
+
|
|
65
|
+
reserved: 7
|
|
66
|
+
|
|
67
|
+
reserved: 6
|
|
68
|
+
|
|
69
|
+
reserved: 5
|
|
70
|
+
|
|
71
|
+
reserved: 4
|
|
72
|
+
|
|
73
|
+
bundle-must-be-deleted-if-block-cannot-be-processed: 3
|
|
74
|
+
|
|
75
|
+
status-report-must-be-transmitted-if-block-cannot-be-processed: 2
|
|
76
|
+
|
|
77
|
+
block-must-be-removed-from-bundle-if-it-cannot-be-processed: 1
|
|
78
|
+
|
|
79
|
+
block-must-be-replicated-in-every-fragment: 0
|
|
80
|
+
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
bundle = [primary-block, *extension-block, payload-block]
|
|
84
|
+
|
|
85
|
+
primary-block = [
|
|
86
|
+
|
|
87
|
+
version: 7,
|
|
88
|
+
|
|
89
|
+
bundle-control-flags,
|
|
90
|
+
|
|
91
|
+
crc-type: uint,
|
|
92
|
+
|
|
93
|
+
destination: eid,
|
|
94
|
+
|
|
95
|
+
source-node: eid,
|
|
96
|
+
|
|
97
|
+
report-to: eid,
|
|
98
|
+
|
|
99
|
+
creation-timestamp,
|
|
100
|
+
|
|
101
|
+
lifetime: uint,
|
|
102
|
+
|
|
103
|
+
? fragment-offset: uint,
|
|
104
|
+
|
|
105
|
+
? total-application-data-length: uint,
|
|
106
|
+
|
|
107
|
+
? crc,
|
|
108
|
+
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
canonical-block = [
|
|
112
|
+
|
|
113
|
+
block-type-code: uint,
|
|
114
|
+
|
|
115
|
+
canonical-block-common,
|
|
116
|
+
|
|
117
|
+
? crc
|
|
118
|
+
|
|
119
|
+
]
|
|
120
|
+
|
|
121
|
+
canonical-block-common = (
|
|
122
|
+
|
|
123
|
+
block-number: uint,
|
|
124
|
+
|
|
125
|
+
block-control-flags,
|
|
126
|
+
|
|
127
|
+
crc-type: uint,
|
|
128
|
+
|
|
129
|
+
block-type-specific-data: bytes
|
|
130
|
+
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
payload-block = ([block-type-code: 1, canonical-block-common, ?crc]) .within canonical-block
|
|
135
|
+
|
|
136
|
+
extension-block = ([block-type-code: (uint .ne 1), canonical-block-common, ?crc]) .within canonical-block
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
start = bundle / #6.55799(bundle)
|
|
2
|
+
|
|
3
|
+
; Times before 2000 are invalid
|
|
4
|
+
dtn-time = uint
|
|
5
|
+
|
|
6
|
+
; CRC enumerated type
|
|
7
|
+
crc-type = 0 / 1 / 2
|
|
8
|
+
; Either 16-bit or 32-bit
|
|
9
|
+
crc-value = (bstr .size 2) / (bstr .size 4)
|
|
10
|
+
|
|
11
|
+
creation-timestamp = [dtn-time, sequence: uint]
|
|
12
|
+
|
|
13
|
+
eid = $eid-choice .within eid-structure
|
|
14
|
+
eid-structure = [
|
|
15
|
+
uri-code: uint,
|
|
16
|
+
SSP: any
|
|
17
|
+
]
|
|
18
|
+
$eid-choice /= [
|
|
19
|
+
uri-code: 1,
|
|
20
|
+
SSP: (tstr / 0)
|
|
21
|
+
]
|
|
22
|
+
$eid-choice /= [
|
|
23
|
+
uri-code: 2,
|
|
24
|
+
SSP: [
|
|
25
|
+
nodenum: uint,
|
|
26
|
+
servicenum: uint
|
|
27
|
+
]
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
bundle-control-flags = uint .bits bundleflagbits
|
|
31
|
+
bundleflagbits = &(
|
|
32
|
+
reserved: 15
|
|
33
|
+
reserved: 14
|
|
34
|
+
reserved: 13
|
|
35
|
+
bundle-deletion-status-reports-are-requested: 12
|
|
36
|
+
bundle-delivery-status-reports-are-requested: 11
|
|
37
|
+
bundle-forwarding-status-reports-are-requested: 10
|
|
38
|
+
reserved: 9
|
|
39
|
+
bundle-reception-status-reports-are-requested: 8
|
|
40
|
+
bundle-contains-a-Manifest-block: 7
|
|
41
|
+
status-time-is-requested-in-all-status-reports: 6
|
|
42
|
+
user-application-acknowledgement-is-requested: 5
|
|
43
|
+
reserved: 4
|
|
44
|
+
reserved: 3
|
|
45
|
+
bundle-must-not-be-fragmented: 2
|
|
46
|
+
payload-is-an-administrative-record: 1
|
|
47
|
+
bundle-is-a-fragment: 0
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
block-control-flags = uint .bits blockflagbits
|
|
51
|
+
blockflagbits = &(
|
|
52
|
+
reserved: 7
|
|
53
|
+
reserved: 6
|
|
54
|
+
reserved: 5
|
|
55
|
+
reserved: 4
|
|
56
|
+
bundle-must-be-deleted-if-block-cannot-be-processed: 3
|
|
57
|
+
status-report-must-be-transmitted-if-block-cannot-be-processed: 2
|
|
58
|
+
block-must-be-removed-from-bundle-if-it-cannot-be-processed: 1
|
|
59
|
+
block-must-be-replicated-in-every-fragment: 0
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
bundle = [primary-block, *extension-block, payload-block]
|
|
63
|
+
|
|
64
|
+
primary-block = [
|
|
65
|
+
version: 7,
|
|
66
|
+
bundle-control-flags,
|
|
67
|
+
crc-type,
|
|
68
|
+
destination: eid,
|
|
69
|
+
source-node: eid,
|
|
70
|
+
report-to: eid,
|
|
71
|
+
creation-timestamp,
|
|
72
|
+
lifetime: uint,
|
|
73
|
+
? (
|
|
74
|
+
fragment-offset: uint,
|
|
75
|
+
; total-application-data-length: uint,
|
|
76
|
+
)
|
|
77
|
+
? crc-value,
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
; Abstract shared structure of all non-primary blocks
|
|
81
|
+
canonical-block-structure = [
|
|
82
|
+
block-type-code: uint,
|
|
83
|
+
block-number: uint,
|
|
84
|
+
block-control-flags,
|
|
85
|
+
crc-type,
|
|
86
|
+
; Each block type defines the content within the bytestring
|
|
87
|
+
block-type-specific-data,
|
|
88
|
+
? crc-value
|
|
89
|
+
]
|
|
90
|
+
block-type-specific-data = bstr / #6.24(bstr)
|
|
91
|
+
; Extension block type, which does not specialize any more than the code/number
|
|
92
|
+
extension-block = $extension-block-structure .within canonical-block-structure
|
|
93
|
+
$extension-block-structure = [
|
|
94
|
+
block-type-code: (uint .gt 1),
|
|
95
|
+
extension-block-number,
|
|
96
|
+
block-control-flags,
|
|
97
|
+
crc-type,
|
|
98
|
+
($extension-block-data .within block-type-specific-data)
|
|
99
|
+
? crc-value
|
|
100
|
+
]
|
|
101
|
+
extension-block-number = (uint .ne 0)
|
|
102
|
+
; Payload block type
|
|
103
|
+
payload-block = payload-block-structure .within canonical-block-structure
|
|
104
|
+
payload-block-structure = [
|
|
105
|
+
block-type-code: 1,
|
|
106
|
+
block-number: 0,
|
|
107
|
+
block-control-flags,
|
|
108
|
+
crc-type,
|
|
109
|
+
($payload-block-data .within block-type-specific-data)
|
|
110
|
+
? crc-value
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
; Arbitrary payload data
|
|
114
|
+
$payload-block-data /= bstr
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
; Administrative record as a payload data specialization
|
|
118
|
+
$payload-block-data /= block-type-specific-data .cbor admin-record
|
|
119
|
+
admin-record = $admin-record .within admin-record-structure
|
|
120
|
+
admin-record-structure = [
|
|
121
|
+
record-type-code: uint,
|
|
122
|
+
record-content: any
|
|
123
|
+
]
|
|
124
|
+
; Only one defined record type
|
|
125
|
+
$admin-record /= [1, status-record-content]
|
|
126
|
+
status-record-content = [
|
|
127
|
+
bundle-status-information,
|
|
128
|
+
status-report-reason-code: uint,
|
|
129
|
+
source-node-eid: eid,
|
|
130
|
+
subject-creation-timestamp: creation-timestamp,
|
|
131
|
+
? (
|
|
132
|
+
subject-payload-offset: uint,
|
|
133
|
+
subject-payload-length: uint
|
|
134
|
+
)
|
|
135
|
+
]
|
|
136
|
+
bundle-status-information = [
|
|
137
|
+
reporting-node-received-bundle: status-info-content,
|
|
138
|
+
reporting-node-forwarded-bundle: status-info-content,
|
|
139
|
+
reporting-node-delivered-bundle: status-info-content,
|
|
140
|
+
reporting-node-deleted-bundle: status-info-content
|
|
141
|
+
]
|
|
142
|
+
status-info-content = [
|
|
143
|
+
status-indicator: bool,
|
|
144
|
+
? timestamp: dtn-time
|
|
145
|
+
]
|
|
146
|
+
|
|
147
|
+
; Previous Node extension block
|
|
148
|
+
$extension-block-structure /= [
|
|
149
|
+
block-type-code: 7,
|
|
150
|
+
extension-block-number,
|
|
151
|
+
block-control-flags,
|
|
152
|
+
crc-type,
|
|
153
|
+
(block-type-specific-data .cbor ext-data-previous-node)
|
|
154
|
+
? crc-value
|
|
155
|
+
]
|
|
156
|
+
ext-data-previous-node = eid
|
|
157
|
+
|
|
158
|
+
; Bundle Age extension block
|
|
159
|
+
$extension-block-structure /= [
|
|
160
|
+
block-type-code: 8,
|
|
161
|
+
extension-block-number,
|
|
162
|
+
block-control-flags,
|
|
163
|
+
crc-type,
|
|
164
|
+
(block-type-specific-data .cbor ext-data-bundle-age)
|
|
165
|
+
? crc-value
|
|
166
|
+
]
|
|
167
|
+
ext-data-bundle-age = uint
|
|
168
|
+
|
|
169
|
+
; Hop Count extension block
|
|
170
|
+
$extension-block-structure /= [
|
|
171
|
+
block-type-code: 9,
|
|
172
|
+
extension-block-number,
|
|
173
|
+
block-control-flags,
|
|
174
|
+
crc-type,
|
|
175
|
+
(block-type-specific-data .cbor ext-data-hop-count)
|
|
176
|
+
? crc-value
|
|
177
|
+
]
|
|
178
|
+
ext-data-hop-count = [
|
|
179
|
+
hop-limit: uint,
|
|
180
|
+
hop-count: uint
|
|
181
|
+
]
|