code wiki / _hdl_build / nx_dash_get_gate.nx
nx_dash_get_gate.nx source
↩ module page · 64 lines · 3554 B
1import "nx_gate_gn.nx"
2import "nx_gate_base.nx"
3// nx_dash_get_gate.nx -- proves the DASH download orchestrator end-to-end: .mpd -> segment URLs -> per-segment
4// retry+integrity -> concat. Injects fetch failures / corruption via the callback (rctx scenario): all-ok,
5// fetch-retry, always-fail=abort-no-partial, corrupt-then-good=integrity-retry. license_tier: ORIGINAL expect_exit: 0
6import "nx_syscalls.nx"
7import "nx_robust_dl.nx"
8import "nx_dash_parse.nx"
9import "nx_dash_get.nx"
10
11func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw("
12" as *u8); return ok }
13func gsl(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
14
15func fill_ts(out: *u8, npkts: i64, valid: i64) -> i64 {
16 var i: i64 = 0
17 while i < (npkts * 188) { out[i] = 0 as u8; i = i + 1 }
18 if valid == 1 { var p: i64 = 0; while p < npkts { out[p * 188] = 0x47 as u8; p = p + 1 } }
19 return npkts * 188
20}
21func dgfetch(url: *u8, urllen: i64, attempt: i64, out: *u8, outcap: i64, rctx: i64) -> i64 {
22 if rctx == 0 { return fill_ts(out, 2, 1) }
23 if rctx == 1 { if attempt < 2 { return 0 } return fill_ts(out, 2, 1) }
24 if rctx == 2 { return 0 }
25 if rctx == 3 { if attempt == 0 { return fill_ts(out, 2, 0) } return fill_ts(out, 2, 1) }
26 return 0
27}
28
29// build a DgJob for scenario rctx (kind=TS so integrity is meaningful, max_tries=5).
30func mkjob(rctx: i64) -> *DgJob {
31 let j: *DgJob = sys_mmap(48) as *DgJob
32 j.fetch_fn = &dgfetch
33 j.rctx = rctx
34 j.kind = RDL_TS
35 j.max_tries = 5
36 return j
37}
38
39func main() -> i64 {
40 gw("dash-get SOVEREIGN gate (.mpd -> retry+integrity per segment -> concat)\n" as *u8)
41 var pass: i64 = 0
42 var ttl: i64 = 0
43 // 11-segment manifest (init + 10), same shape as nx_dash_parse_gate.
44 let mpd: *u8 = "<MPD><Period><AdaptationSet contentType=\"video\"><Representation id=\"v0\" bandwidth=\"1000000\"><SegmentTemplate media=\"seg-$RepresentationID$-$Number$.m4s\" initialization=\"init-$RepresentationID$.m4s\" startNumber=\"1\"><SegmentTimeline><S t=\"0\" d=\"4000\" r=\"9\"/></SegmentTimeline></SegmentTemplate></Representation></AdaptationSet></Period></MPD>" as *u8
45 let mln: i64 = gsl(mpd)
46 let out: *u8 = sys_mmap(1048576)
47
48 // DG1: all-ok -> 11 segments x 376 bytes = 4136.
49 let r1: i64 = dg_download(mpd, mln, mkjob(0), out, 1048576)
50 ttl=ttl+1; pass=pass+grow("DG1 all-ok -> 11 segs concatenated (4136 bytes)\x00" as *u8, (r1 == 4136) as i64)
51 // DG2: fetch fails 2x per segment then succeeds -> still all 11.
52 let r2: i64 = dg_download(mpd, mln, mkjob(1), out, 1048576)
53 ttl=ttl+1; pass=pass+grow("DG2 fetch-retry -> still 4136 (all recovered)\x00" as *u8, (r2 == 4136) as i64)
54 // DG3: a segment always fails -> ABORT (-1), no partial/broken file stitched.
55 let r3: i64 = dg_download(mpd, mln, mkjob(2), out, 1048576)
56 ttl=ttl+1; pass=pass+grow("DG3 unrecoverable seg -> -1 abort (no broken stitch)\x00" as *u8, (r3 == (0 - 1)) as i64)
57 // DG4: corrupt fragment then good -> integrity rejects + re-fetches -> 4136.
58 let r4: i64 = dg_download(mpd, mln, mkjob(3), out, 1048576)
59 ttl=ttl+1; pass=pass+grow("DG4 integrity-retry -> 4136 (corrupt rejected)\x00" as *u8, (r4 == 4136) as i64)
60
61 gw("pass=" as *u8); gn(pass); gw("/" as *u8); gn(ttl); gw("\n" as *u8)
62 if pass == ttl { gw("verdict=GREEN (DASH .mpd downloaded end-to-end: retry+integrity per segment, abort-not-stitch)\n" as *u8); sys_exit(0); return 0 }
63 gw("verdict=RED\n" as *u8); sys_exit(1); return 1
64}