[fidl][golang] Write magic number into message header

Bug: 35492

Test: fx run-test go_fidl_tests
Change-Id: I1c2242bff645ed46469deb8b74e1f417f327b65e
diff --git a/src/syscall/zx/fidl/fidl_test/encoding_new_test.go b/src/syscall/zx/fidl/fidl_test/encoding_new_test.go
index 0c0cca4..9801c37 100644
--- a/src/syscall/zx/fidl/fidl_test/encoding_new_test.go
+++ b/src/syscall/zx/fidl/fidl_test/encoding_new_test.go
@@ -20,6 +20,26 @@
 	"syscall/zx/fidl/conformance"
 )
 
+func TestMarshalMessageHeader(t *testing.T) {
+	data := []byte{
+		0x12, 0x34, 0x56, 0x78,                         // txid
+		0xAB, 0xCD, 0xEF,                               // flags
+		0x01,                                           // magic number
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // method ordinal
+	}
+	var header MessageHeader
+	hnb, _, err := Unmarshal(data, nil, &header)
+	if err != nil {
+		t.Fatalf("unmarshal failed: %s", err)
+	}
+	if hnb != 16 {
+		t.Fatalf("expected 16 bytes read, was %d", hnb)
+	}
+	if header.Magic != 0x01 {
+		t.Fatalf("expected header txid of 0x01, was %x", header.Magic)
+	}
+}
+
 func TestCheckUnmarshalReadSize(t *testing.T) {
 	examples := [][]byte{
 		{
diff --git a/src/syscall/zx/fidl/interface.go b/src/syscall/zx/fidl/interface.go
index 34f9e47..8f24c6d 100644
--- a/src/syscall/zx/fidl/interface.go
+++ b/src/syscall/zx/fidl/interface.go
@@ -134,6 +134,7 @@
 	header := MessageHeader{
 		Txid:    0, // Txid == 0 for messages without a response.
 		Ordinal: ordinal,
+		Magic:   FidlWireFormatMagicNumberInitial,
 	}
 	nb, nh, err := MarshalHeaderThenMessage(&header, req, respb[:], resph[:])
 	if err != nil {
@@ -179,6 +180,7 @@
 	// Marshal the message into the buffer
 	header := MessageHeader{
 		Ordinal: ordinal,
+		Magic:   FidlWireFormatMagicNumberInitial,
 	}
 	nb, nh, err := MarshalHeaderThenMessage(&header, req, respb[:], resph[:])
 	if err != nil {
diff --git a/src/syscall/zx/fidl/interface_test.go b/src/syscall/zx/fidl/interface_test.go
index ed79d62..490cc04 100644
--- a/src/syscall/zx/fidl/interface_test.go
+++ b/src/syscall/zx/fidl/interface_test.go
@@ -7,14 +7,18 @@
 package fidl_test
 
 import (
+	"flag"
 	"fmt"
 	"math/rand"
 	"sync"
 	"syscall/zx"
 	"syscall/zx/fidl"
+	"syscall/zx/fidl/bindingstest"
 	"testing"
 )
 
+func init() { flag.CommandLine.Set("test.v", "true") }
+
 var _ fidl.Message = (*message)(nil)
 
 type message struct {
@@ -113,3 +117,33 @@
 		})
 	}
 }
+
+func TestMagicNumberSend(t *testing.T) {
+	ch, sh, err := zx.NewChannel(0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	msg := bindingstest.TestSimple{X: 3}
+	client := fidl.ChannelProxy{Channel: ch}
+	if err := client.Send(0, &msg); err != nil {
+		t.Fatal(err)
+	}
+
+	respb := make([]byte, zx.ChannelMaxMessageBytes)
+	resph := make([]zx.Handle, zx.ChannelMaxMessageHandles)
+	nb, nh, err := sh.Read(respb[:], resph[:], 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	var header fidl.MessageHeader
+	if err = fidl.UnmarshalHeaderThenMessage(respb[:nb], resph[:nh], &header, &msg); err != nil {
+		t.Fatal(err)
+	}
+
+	if header.Magic != fidl.FidlWireFormatMagicNumberInitial {
+		t.Logf("expected client to send initial magic number")
+		t.Fatal(err)
+	}
+}
diff --git a/src/syscall/zx/fidl/message.go b/src/syscall/zx/fidl/message.go
index 5401313..dcb57b9 100644
--- a/src/syscall/zx/fidl/message.go
+++ b/src/syscall/zx/fidl/message.go
@@ -12,6 +12,8 @@
 	"syscall/zx"
 )
 
+const FidlWireFormatMagicNumberInitial = 1
+
 // messageBytesPool is a pool of buffers that can fit the data part of any
 // FIDL message.
 var messageBytesPool = sync.Pool{
@@ -30,10 +32,11 @@
 
 // MessageHeader represents a transactional message header.
 type MessageHeader struct {
-	_        struct{} `fidl2:"s,16,8"`
-	Txid     uint32
-	Reserved uint32
-	Ordinal  uint64
+	_       struct{} `fidl2:"s,16,8"`
+	Txid    uint32
+	Flags   [3]uint8
+	Magic   uint8
+	Ordinal uint64
 }
 
 var mMessageHeader = MustCreateMarshaler(MessageHeader{})