add vcs-* fields to debian/control
[debian/orchestra.git] / src / orchestra / wire.go
1 /* wire.go
2  *
3  * Wire Level Encapsulation
4 */
5
6 package orchestra;
7
8 import (
9         "os"
10         "net"
11         "fmt"
12 )
13
14 type WirePkt struct {
15         Type    byte
16         Length  uint16
17         Payload []byte
18 }
19
20 const (
21         TypeNop                 = 0
22         TypeIdentifyClient      = 1
23         TypeReadyForTask        = 2
24         TypeTaskRequest         = 3
25         TypeTaskResponse        = 4
26         TypeAcknowledgement     = 5
27 )
28
29 var (
30         ErrMalformedMessage = os.NewError("Malformed Message")
31         ErrUnknownMessage   = os.NewError("Unknown Message")
32 )
33
34 func (p *WirePkt) ValidUnidentified() bool {
35         if p.Type == TypeNop {
36                 return true
37         }
38         if p.Type == TypeIdentifyClient {
39                 return true
40         }
41
42         return false
43 }
44
45 func (p *WirePkt) Send(c net.Conn) (n int, err os.Error) {
46         n = 0
47         preamble := make([]byte, 3)
48         preamble[0] = p.Type
49         preamble[1] = byte((p.Length >> 8) & 0xFF)
50         preamble[2] = byte(p.Length & 0xFF)
51         ninc, err := c.Write(preamble)
52         n += ninc
53         if (err != nil) {
54                 return n, err
55         }       
56         ninc, err = c.Write(p.Payload[0:p.Length])
57         n += ninc
58         if (err != nil) {
59                 return n, err
60         }
61         return n, nil
62 }
63
64 func (p *WirePkt) Dump() {
65         fmt.Printf("Packet Dump: Type %d, Len %d\n", p.Type, p.Length)
66         for i := 0; i < int(p.Length); i++ {
67                 if i%16 == 0 {
68                         fmt.Printf("%04x: ", i)
69                 }
70                 fmt.Printf("%02x ", p.Payload[i])
71                 if i%16 == 15 {
72                         fmt.Println()
73                 }
74         }
75         fmt.Println()
76 }
77
78 func Receive(c net.Conn) (msg *WirePkt, err os.Error) {
79         msg = new(WirePkt)
80         preamble := make([]byte, 3)
81
82         n, err := c.Read(preamble)
83         if err != nil {
84                 return nil, err
85         }
86         if n < 3 {
87                 /* short read!  wtf! err? */
88                 return nil, ErrMalformedMessage
89         }
90         msg.Type = preamble[0]
91         msg.Length = (uint16(preamble[1]) << 8) | uint16(preamble[2])
92         if msg.Length > 0 {
93                 msg.Payload = make([]byte, msg.Length)
94                 n, err = c.Read(msg.Payload)
95                 if err != nil {
96                         return nil, err
97                 }
98                 if n < int(msg.Length) {
99                         /* short read!  wtf! err? */
100                         return nil, ErrMalformedMessage
101                 }
102         }
103
104         /* Decode! */
105         return msg, nil
106 }
107