From d1b5ade03675d5db86412583b55f3940204a5639 Mon Sep 17 00:00:00 2001 From: Muaz Ahmad Date: Tue, 15 Aug 2023 12:32:44 +0500 Subject: [PATCH] Added connect response writing --- rtmp/amf/command.go | 27 ++++++++++++++++++++++++++- rtmp/amf/encode.go | 37 +++++++++++++++++++++++++++++++++++++ rtmp/chunk_wrap.go | 12 ++++++++++++ rtmp/connect.go | 3 +++ 4 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 rtmp/amf/encode.go diff --git a/rtmp/amf/command.go b/rtmp/amf/command.go index a1e3621..d09f11f 100644 --- a/rtmp/amf/command.go +++ b/rtmp/amf/command.go @@ -1,6 +1,8 @@ package amf -import "errors" +import ( + "errors" +) func (amf_obj_root AMFObj) ProcessConnect() (err error) { err = errors.New("Bad AMF connect command") @@ -30,3 +32,26 @@ func (amf_obj_root AMFObj) ProcessConnect() (err error) { err = nil return } + +func EncodeConnectResponse(msg_ptr *Message) (error) { + amf_root_obj := make(AMFObj) + amf_root_obj[0] = "_result" + amf_root_obj[1] = 1.0 + + amf_root_obj[2] = make(AMFObj) + amf_prop_obj := amf_root_obj[2].(AMFObj) + amf_prop_obj["fmsVer"] = "FMS/3,5,5,2004" + amf_prop_obj["capabilities"] = 31.0 + + amf_root_obj[3] = make(AMFObj) + amf_event_obj := amf_root_obj[3].(AMFObj) + amf_event_obj["level"] = "status" + amf_event_obj["code"] = "NetConnection.Connect.Success" + amf_event_obj["description"] = "Connection Succeeded" + amf_event_obj["objectEncoding"] = 0.0 + + if err := Encode(amf_root_obj, msg_ptr); err != nil { + return err + } + return nil +} diff --git a/rtmp/amf/encode.go b/rtmp/amf/encode.go new file mode 100644 index 0000000..b354edd --- /dev/null +++ b/rtmp/amf/encode.go @@ -0,0 +1,37 @@ +package amf + +import ( + "math" + "encoding/binary" + "errors" +) + +func Encode(amf_root_obj AMFObj, msg_ptr *Message) (error) { + tmp_buffer := make([]byte, 1024) + bytes_encoded := 0 + + for i := 0; i < len(amf_root_obj); i++ { + if err := encode_next(amf_root_obj[i], &tmp_buffer, &bytes_encoded); err != nil { + return err + } + } + msg_ptr.msg_len = bytes_encoded + msg_ptr.data = tmp_buffer[:bytes_encoded] + return nil +} + +func encode_number(num_to_enc float64, tmp_buffer *[]byte, bytes_encoded *int) { + (*tmp_buffer)[*bytes_encoded] = 0 + binary.BigEndian.PutUint64((*tmp_buffer)[*bytes_encoded + 1:*bytes_encoded + 9], math.Float64bits(num_to_enc)) + *bytes_encoded += 9 +} + +func encode_next(amf_obj interface{}, tmp_buffer *[]byte, bytes_encoded *int) (error) { + switch amf_obj.(type) { + case float64: + encode_number(amf_obj.(float64), tmp_buffer, bytes_encoded) + default: + return errors.New("Type not implemented") + } + return nil +} diff --git a/rtmp/chunk_wrap.go b/rtmp/chunk_wrap.go index 6516bd4..14f4fa1 100644 --- a/rtmp/chunk_wrap.go +++ b/rtmp/chunk_wrap.go @@ -123,3 +123,15 @@ func (chnk_wrp_ptr *ChunkWrapper) WriteChunkSize() (error) { } return nil } + +func (chnk_wrp_ptr *ChunkWrapper) WriteConnectResponse() (error) { + msg_ptr := new(Message) + msg_ptr.msg_type = 20 + if err := amf.EncodeConnectResponse(msg_ptr); err != nil { + return err + } + if err := chnk_wrp_ptr.WriteChunk(3, 0, msg_ptr); err != nil { + return err + } + return nil +} diff --git a/rtmp/connect.go b/rtmp/connect.go index f4da7f9..c434d74 100644 --- a/rtmp/connect.go +++ b/rtmp/connect.go @@ -20,6 +20,9 @@ func NegotiateConnect(chnk_wrp_ptr *ChunkWrapper) (bool) { if err := chnk_wrp_ptr.WriteChunkSize(); err != nil { return false } + if err := chnk_wrp_ptr.WriteConnectResponse(); err != nil { + return false + } fmt.Println(chnk_wrp_ptr.params) return false }