ref: 0ce01d66fb72ea51b7dd0e885a01e2bba1eda7ff
parent: 3acc9f1c414b3032531e1db73e77bb4af0f8ed38
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Wed Jul 28 10:07:08 EDT 2021
parse control packets
--- a/rtmp.c
+++ b/rtmp.c
@@ -28,6 +28,14 @@
CbStatus,
NumCbA,
+ CtlStreamBegin = 0,
+ CtlStreamEnd,
+ CtlStreamDry,
+ CtlStreamRecorded,
+ CtlPing = 6,
+ CtlBufferEmpty = 31,
+ CtlBufferReady,
+
PktChunkSz = 1,
PktBytesReadReport = 3,
PktControl = 4,
@@ -105,7 +113,7 @@
putobj(); \
}while(0)
-static szs[] = {
+static int szs[] = {
[SzTiny] = 1,
[SzSmall] = 4,
[SzMedium] = 8,
@@ -128,6 +136,16 @@
[PktFlashVideo] = "FlashVideo",
};
+static char *ctl2s[] = {
+ [CtlStreamBegin] = "StreamBegin",
+ [CtlStreamEnd] = "StreamEnd",
+ [CtlStreamDry] = "StreamDry",
+ [CtlStreamRecorded] = "StreamRecorded",
+ [CtlPing] = "Ping",
+ [CtlBufferEmpty] = "BufferEmpty",
+ [CtlBufferReady] = "BufferReady",
+};
+
extern int debug;
#pragma varargck type "T" int
@@ -156,9 +174,13 @@
p = va_arg(f->args, Packet*);
fmtprint(f, "type=%T chan=%d ts=%ud sz=%d", p->type, p->chan, p->ts, p->sz);
+
+ s = p->data;
+ e = s + p->sz;
+
if(p->type == PktInvoke){
fmtprint(f, ":");
- for(s = p->data, e = s + p->sz; s != nil && s != e;){
+ for(; s != nil && s != e;){
if((s = amfparse(&a, s, e)) != nil)
fmtprint(f, " %A", a);
else
@@ -414,6 +436,7 @@
int res, n, ok;
Amf *a[NumCbA];
u8int *s, *e;
+ s16int s16;
Packet *p;
Invoke *i;
RTMP *r;
@@ -435,12 +458,13 @@
break;
}
+ s = r->pk.data;
+ e = s + r->pk.sz;
+
switch(p->type){
case PktInvoke:
i = nil;
ok = 0;
- s = r->pk.data;
- e = s + r->pk.sz;
for(n = 0; n < NumCbA; n++){
if((s = amfparse(&a[n], s, e)) == nil)
goto err;
@@ -483,7 +507,7 @@
break;
case PktChunkSz:
- if(amfi32get(r->pk.data, r->pk.data+r->pk.sz, &r->chunk) == nil)
+ if(amfi32get(s, e, &r->chunk) == nil)
goto err;
if(r->chunk < 2){
werrstr("invalid chunk size: %d", r->chunk);
@@ -492,8 +516,35 @@
if(debug)
fprint(2, "new chunk size: %d bytes\n", r->chunk);
break;
+
case PktBytesReadReport:
case PktControl:
+ if((s = amfi16get(s, e, &s16)) == nil)
+ goto err;
+ if((s = amfi32get(s, e, &n)) == nil)
+ n = -1;
+ switch(s16){
+ case CtlStreamBegin:
+ case CtlStreamEnd:
+ case CtlStreamDry:
+ case CtlStreamRecorded:
+ case CtlBufferEmpty:
+ case CtlBufferReady:
+ if(0){
+ case CtlPing:
+ /* FIXME pong */
+ USED(n);
+ }
+ if(debug)
+ fprint(2, "control packet: %s %d\n", ctl2s[s16], n);
+ break;
+ default:
+ if(debug)
+ fprint(2, "unknown control packet %d (value %d)\n", s16, n);
+ break;
+ }
+ break;
+
case PktServerBW:
case PktClientBW:
case PktAudio: