Lots of work, most rearranging
--- a/commands/byteslice.go Wed Feb 27 00:21:12 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-// overwrite will overwrite the a with the entire run of b
-func overwrite(a, b []byte) {
-// equal checks if byte slice a starts with b
-func equal(a, b []byte) bool {
--- a/commands/commands.go Wed Feb 27 00:21:12 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
- "bitbucket.org/rw_grim/gousb2snes/protocol"
-type Command interface {
- Send(rwc io.ReadWriteCloser) error
-func sync(rwc io.ReadWriteCloser, opcode protocol.OpCode, ns protocol.Namespace, flags protocol.Flag) ([]byte, error) {
- req := make([]byte, 512)
- header := []byte{'U', 'S', 'B', 'A', byte(opcode), byte(ns), byte(flags)}
- n, err := rwc.Write(req)
- return nil, errors.New("failed to write!")
- resp := make([]byte, 512)
- n, err = rwc.Read(resp[total:])
- if !equal(resp, []byte{'U', 'S', 'B', 'A', byte(protocol.OpCodeResponse)}) {
- return nil, errors.New("Bad response")
- return nil, errors.New("Bad response")
--- a/commands/info.go Wed Feb 27 00:21:12 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
- "bitbucket.org/rw_grim/gousb2snes/protocol"
- InfoFeatureDSPX InfoFeature = 1 << iota
-func (f InfoFeature) String() string {
- if f&InfoFeatureDSPX != 0 {
- r = append(r, "FEAT_DSPX")
- if f&InfoFeatureST0010 != 0 {
- r = append(r, "FEAT_ST0010")
- if f&InfoFeatureSRTC != 0 {
- r = append(r, "FEAT_SRTC")
- if f&InfoFeatureMSU1 != 0 {
- r = append(r, "FEAT_MSU1")
- if f&InfoFeature213F != 0 {
- r = append(r, "FEAT_213F")
- if f&InfoFeatureCmdUnlock != 0 {
- r = append(r, "FEAT_CMD_UNLOCK")
- if f&InfoFeatureUSB1 != 0 {
- r = append(r, "FEAT_USB1")
- if f&InfoFeatureDMA1 != 0 {
- r = append(r, "FEAT_DMA1")
- return strings.Join(r, "|")
-func (i *Info) Send(rwc io.ReadWriteCloser) error {
- resp, err := sync(rwc, protocol.OpCodeInfo, protocol.NamespaceSNES, protocol.FlagNone)
- fwver := binary.BigEndian.Uint32(resp[256:])
- i.fwver = fmt.Sprintf("%08x", fwver)
- i.version = nullTerminated(resp[260:])
- i.features = InfoFeature(resp[6])
- i.rom = nullTerminated(resp[16:])
-func (i *Info) String() string {
- "version: %s\nfwver: %s\nfeatures: %s\nrom: %s",
--- a/commands/string.go Wed Feb 27 00:21:12 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-func nullTerminated(buffer []byte) string {
- for _, b := range buffer {
--- a/main.go Wed Feb 27 00:21:12 2019 -0600
+++ b/main.go Sun Mar 03 18:52:34 2019 -0600
@@ -3,35 +3,54 @@
- "github.com/jacobsa/go-serial/serial"
- "bitbucket.org/rw_grim/gousb2snes/commands"
+ "bitbucket.org/rw_grim/gousb2snes/network" + "bitbucket.org/rw_grim/gousb2snes/sd2snes" - opts := serial.OpenOptions{
- PortName: "/dev/ttyACM0",
- sock, err := serial.Open(opts)
+ sock, err := sd2snes.New() fmt.Printf("failed to open serial device : %v\n", err)
- info := &commands.Info{}
+ info := &sd2snes.Info{} fmt.Printf("error: %v\n", err)
+ fmt.Printf("-----\n%s\n", info) - fmt.Printf("-----\n%s\n", info)
+ // setup the tcp server + server := network.NewServer() + err = server.Listen(":8001") + fmt.Printf("Error: %#v\n", err) + // create our error channel + errChan := make(chan error) + defer server.Shutdown() + // add unix signal handling + signalChan := make(chan os.Signal, 1) + signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) + fmt.Printf("Error: %#v\n", err) + case s := <-signalChan: + fmt.Printf("caught signal %v\n", s) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/network/client.go Sun Mar 03 18:52:34 2019 -0600
@@ -0,0 +1,60 @@
+func NewClient(c net.Conn) *Client { +func (c *Client) Run(errChan chan error) { + n, err := c.connection.Read(packet) + errChan <- fmt.Errorf("read %d bytes expected %d", n, packetSize) + typ := binary.BigEndian.Uint32(packet[0:]) + release := binary.BigEndian.Uint32(packet[4:]) + address := binary.BigEndian.Uint32(packet[8:]) + fmt.Printf("type: %v, release: %v, address: %v\n", typ, release, address) +func (c *Client) Close() { --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/network/server.go Sun Mar 03 18:52:34 2019 -0600
@@ -0,0 +1,52 @@
+func NewServer() *Server { +func (s *Server) Listen(addr string) error { + listener, err := net.Listen("tcp", addr) +func (s *Server) Run(errChan chan error) { + c, err := s.listener.Accept() +func (s *Server) Shutdown() { --- a/protocol/consts.go Wed Feb 27 00:21:12 2019 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
- OpCodeGet OpCode = iota
- FlagNone Flag = 1 << iota
- NamespaceFile Namespace = iota
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sd2snes/byteslice.go Sun Mar 03 18:52:34 2019 -0600
@@ -0,0 +1,23 @@
+// overwrite will overwrite the a with the entire run of b +func overwrite(a, b []byte) { +// equal checks if byte slice a starts with b +func equal(a, b []byte) bool { --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sd2snes/client.go Sun Mar 03 18:52:34 2019 -0600
@@ -0,0 +1,74 @@
+ "github.com/jacobsa/go-serial/serial" + sock io.ReadWriteCloser +func New() (*Client, error) { + opts := serial.OpenOptions{ + PortName: "/dev/ttyACM0", + sock, err := serial.Open(opts) +func (c *Client) Close() { +func (c *Client) Send(cmd Command) error { + opcode, ns, flags := cmd.Identifier() + req := make([]byte, 512) + header := []byte{'U', 'S', 'B', 'A', byte(opcode), byte(ns), byte(flags)} + n, err := c.sock.Write(req) + return errors.New("failed to write!") + resp := make([]byte, 512) + n, err = c.sock.Read(resp[total:]) + if !equal(resp, []byte{'U', 'S', 'B', 'A', byte(OpCodeResponse)}) { + return errors.New("Bad response") + return errors.New("Bad response") + return cmd.Process(resp) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sd2snes/commands.go Sun Mar 03 18:52:34 2019 -0600
@@ -0,0 +1,6 @@
+type Command interface { + Identifier() (OpCode, Namespace, Flag) --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sd2snes/consts.go Sun Mar 03 18:52:34 2019 -0600
@@ -0,0 +1,45 @@
+ OpCodeGet OpCode = iota + FlagNone Flag = 1 << iota + NamespaceFile Namespace = iota --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sd2snes/info.go Sun Mar 03 18:52:34 2019 -0600
@@ -0,0 +1,82 @@
+ InfoFeatureDSPX InfoFeature = 1 << iota +func (f InfoFeature) String() string { + if f&InfoFeatureDSPX != 0 { + r = append(r, "FEAT_DSPX") + if f&InfoFeatureST0010 != 0 { + r = append(r, "FEAT_ST0010") + if f&InfoFeatureSRTC != 0 { + r = append(r, "FEAT_SRTC") + if f&InfoFeatureMSU1 != 0 { + r = append(r, "FEAT_MSU1") + if f&InfoFeature213F != 0 { + r = append(r, "FEAT_213F") + if f&InfoFeatureCmdUnlock != 0 { + r = append(r, "FEAT_CMD_UNLOCK") + if f&InfoFeatureUSB1 != 0 { + r = append(r, "FEAT_USB1") + if f&InfoFeatureDMA1 != 0 { + r = append(r, "FEAT_DMA1") + return strings.Join(r, "|") +func (i *Info) Identifier() (OpCode, Namespace, Flag) { + return OpCodeInfo, NamespaceSNES, FlagNone +func (i *Info) Process(data []byte) error { + fwver := binary.BigEndian.Uint32(data[256:]) + i.fwver = fmt.Sprintf("%08x", fwver) + i.version = nullTerminated(data[260:]) + i.features = InfoFeature(data[6]) + i.rom = nullTerminated(data[16:]) +func (i *Info) String() string { + "version: %s\nfwver: %s\nfeatures: %s\nrom: %s", --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sd2snes/string.go Sun Mar 03 18:52:34 2019 -0600
@@ -0,0 +1,15 @@
+func nullTerminated(buffer []byte) string { + for _, b := range buffer {