Skip to content

Commit

Permalink
initial attempt
Browse files Browse the repository at this point in the history
  • Loading branch information
monoxane committed Sep 28, 2022
1 parent 7ce4b07 commit f0b56fa
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
*.out

# Dependency directories (remove the comment below to include it)
# vendor/
# vendor/
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/monoxane/nk

go 1.19

require github.com/pkg/errors v0.9.1
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
46 changes: 46 additions & 0 deletions model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package nk

import "net"

// Aliases

type Model = string
type TBusAddress = uint8
type Destination = uint16
type Source = uint16
type Level = uint32

// Structs

type Router struct {
IP string
Address TBusAddress
Destinations uint16
Sources uint16
Level Level
Conn net.Conn
}

type TBusPacketPayload struct {
NK2Header uint32
RTRAddress TBusAddress
UNKNB uint16
Destination Destination
Source Source
LevelMask Level
UNKNC uint8
}

type TBusPacket struct {
HeaderA uint32
HeaderB uint16
Payload TBusPacketPayload
CRC uint16
}

type CrosspointRequest struct {
Source Source
Destination Destination
Level Level
Address TBusAddress
}
127 changes: 127 additions & 0 deletions nk.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package nk

import (
"bufio"
"fmt"
"io"
"log"
"net"
"strings"
"time"

"github.com/pkg/errors"
)

const (
LVL_MDVID uint32 = 1

MODEL_NK_3G72 Model = "NK-3G72"
MODEL_NK_3G64 Model = "NK-3G64"
MODEL_NK_3G34 Model = "NK-3G34"
MODEL_NK_3G16 Model = "NK-3G16"
MODEL_NK_3G16_RCP Model = "NK-3G16-RCP"
MODEL_NK_3G164 Model = "NK-3G164"
MODEL_NK_3G164_RCP Model = "NK-3G164-RCP"
)

func New(IP string, RTRAddress uint8, model Model) *Router {
rtr := &Router{
IP: IP,
Address: RTRAddress,
}

switch model {
case MODEL_NK_3G72:
rtr.Destinations = 72
rtr.Sources = 72
rtr.Level = LVL_MDVID
case MODEL_NK_3G64:
rtr.Destinations = 64
rtr.Sources = 64
rtr.Level = LVL_MDVID
case MODEL_NK_3G34:
rtr.Destinations = 34
rtr.Sources = 34
rtr.Level = LVL_MDVID
case MODEL_NK_3G16, MODEL_NK_3G16_RCP:
rtr.Destinations = 16
rtr.Sources = 16
rtr.Level = LVL_MDVID
case MODEL_NK_3G164, MODEL_NK_3G164_RCP:
rtr.Destinations = 4
rtr.Sources = 16
rtr.Level = LVL_MDVID
}

return rtr
}

func (rtr *Router) Connect() {
conn, err := net.Dial("tcp", rtr.IP+":5000")
if err != nil {
log.Fatalln(err)
}
rtr.Conn = conn
defer rtr.Conn.Close()

serverReader := bufio.NewReader(rtr.Conn)

openConnStr := strings.TrimSpace("PHEONIX-DB")
if _, err = rtr.Conn.Write([]byte(openConnStr + "\n")); err != nil {
log.Printf("failed to send the client request: %v\n", err)
}

go func() {
for range time.Tick(10 * time.Second) {
rtr.Conn.Write([]byte("HI"))
}
}()

for {

serverResponse, err := serverReader.ReadString('\n')
switch err {
case nil:
log.Println(strings.TrimSpace(serverResponse))
case io.EOF:
log.Println("server closed the connection")
return
default:
log.Printf("server error: %v\n", err)
return
}
}
}

func (rtr *Router) SetCrosspoint(level Level, destination Destination, source Source) error {
if level != rtr.Level {
return fmt.Errorf("requested level is not possible on this router")
}

if destination <= 0 || destination > rtr.Destinations {
return fmt.Errorf("requested destination is outside the range available on this router model")
}

if source <= 0 || source > rtr.Sources {
return fmt.Errorf("requested source is outside the range available on this router model")
}

xptreq := CrosspointRequest{
Source: source,
Destination: destination,
Level: level,
Address: rtr.Address,
}

packet, err := xptreq.GeneratePacket()
if err != nil {
return errors.Wrap(err, "unable to generate crosspoint route request")
}

_, err = rtr.Conn.Write(packet)
if err != nil {
return errors.Wrap(err, "unable to send route request to router")
}

return nil
}
44 changes: 44 additions & 0 deletions routing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package nk

import (
"bytes"
"encoding/binary"
"log"
)

// GenerateXPTRequest Just returns payload to send to router to close xpt
func (xpt *CrosspointRequest) GeneratePacket() ([]byte, error) {
destination := xpt.Destination - 1
source := xpt.Source - 1

payload := TBusPacketPayload{
NK2Header: 0x4e4b3200,
RTRAddress: xpt.Address,
UNKNB: 0x0409,
Destination: destination,
Source: source,
LevelMask: xpt.Level,
UNKNC: 0x00,
}

payloadBuffer := new(bytes.Buffer)
err := binary.Write(payloadBuffer, binary.BigEndian, payload)
if err != nil {
log.Println("TBusPacketPayload binary.Write failed:", err)
}

packet := TBusPacket{
HeaderA: 0x50415332,
HeaderB: 0x0012,
Payload: payload,
CRC: crc16(payloadBuffer.Bytes()),
}

packetBuffer := new(bytes.Buffer)
err = binary.Write(packetBuffer, binary.BigEndian, packet)
if err != nil {
log.Println("TBustPacket binary.Write failed:", err)
}

return packetBuffer.Bytes(), nil
}
22 changes: 22 additions & 0 deletions utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package nk

// Simple 2 byte CRC for XPT payload
func crc16(buffer []byte) uint16 {
var crc = 0xFFFF
var odd = 0x0000

for i := 0; i < len(buffer); i++ {
crc = crc ^ int(buffer[i])

for j := 0; j < 8; j++ {
odd = crc & 0x0001
crc = crc >> 1
if odd == 1 {
crc = crc ^ 0xA001
}
}
}

crc = ((crc & 0xFF) << 8) | ((crc & 0xFF00) >> 8)
return uint16(crc)
}

0 comments on commit f0b56fa

Please sign in to comment.