ninenano

Client implementation of the 9P protocol for constrained devices

git clone https://git.8pit.net/ninenano.git

 1package main
 2
 3import (
 4	"bytes"
 5	"errors"
 6	"fmt"
 7	"github.com/Harvey-OS/ninep/protocol"
 8	"io"
 9)
10
11// Handles an incoming T-message send by the client.
12type ServerFunc func(*bytes.Buffer) error
13
14// Contains an expected T-message type and the function which should be
15// called when this type is encountered.
16type ServerReply struct {
17	fn ServerFunc
18	ty protocol.MType
19}
20
21// Reply which should be used when an unknown control command was read
22// from the control socket.
23var failureReply ServerReply = ServerReply{
24	func(b *bytes.Buffer) error {
25		return errors.New("not implemented")
26	},
27	protocol.Tlast,
28}
29
30// Channel containing the reply to be used by the protocol connection
31// handler. The goal is to make sure that the protocol connection
32// handler doesn't access it before it has been set by the control
33// connection handler.
34var replyChan = make(chan ServerReply)
35
36// Creates a new ninep protocol server. The new server reads T-messages from
37// the given ReadCloser and writes R-messages to the given WriteCloser.
38// Debug information is created by calling the given tracer.
39func NewServer(d protocol.Tracer, t io.WriteCloser, f io.ReadCloser) *protocol.Server {
40	s := new(protocol.Server)
41	s.Trace = d
42	s.FromNet = f
43	s.ToNet = t
44	s.Replies = make(chan protocol.RPCReply, protocol.NumTags)
45	s.D = dispatch
46	return s
47}
48
49// Dispatches an incoming T-message using the current ServerReply. If a
50// server reply wasn't set or if the T-message send but the client
51// doesn't match the ServerReply message type an error is returned.
52// Besides an error may be returned if the current ServerReply handler
53// returns an error.
54func dispatch(s *protocol.Server, b *bytes.Buffer, t protocol.MType) error {
55	reply := <-replyChan
56	if reply.ty == protocol.Tlast {
57		return reply.fn(b)
58	} else if t != reply.ty {
59		return fmt.Errorf("Expected type %v - got %v", reply.ty, t)
60	}
61
62	return reply.fn(b)
63}