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}