diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 18f8f14..3cca35e 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -3,13 +3,7 @@ - - - - - - - + - @@ -984,7 +1021,7 @@ - @@ -996,7 +1033,7 @@ - + @@ -1017,7 +1054,7 @@ - + @@ -1106,37 +1143,37 @@ file://$PROJECT_DIR$/tee-listeners/recorder.go - 146 + 154 file://$PROJECT_DIR$/tee-listeners/recorder.go - 152 + 160 file://$PROJECT_DIR$/client/client-conn.go - 508 + 510 file://$PROJECT_DIR$/client/client-conn.go - 516 + 519 file://$PROJECT_DIR$/client/client-conn.go - 521 + 524 file://$PROJECT_DIR$/client/client-conn.go - 502 + 503 @@ -1148,13 +1185,13 @@ file://$PROJECT_DIR$/client/client-conn.go - 503 + 504 file://$PROJECT_DIR$/client/client-conn.go - 511 + 512 @@ -1190,19 +1227,19 @@ file://$PROJECT_DIR$/client/server-messages.go - 34 + 33 file://$PROJECT_DIR$/client/server-messages.go - 80 + 79 file://$PROJECT_DIR$/client/server-messages.go - 62 + 61 @@ -1257,6 +1294,10 @@ + + + + @@ -1291,6 +1332,10 @@ + + + + @@ -1316,6 +1361,21 @@ + + + + + + + + + + + + + + + @@ -1557,7 +1617,7 @@ - + @@ -1565,9 +1625,23 @@ - + + + + + + + + + + + + + + + @@ -1575,9 +1649,24 @@ - + + + + + + + + + + + + + + + + @@ -1601,9 +1690,13 @@ - + + + + + @@ -1611,9 +1704,17 @@ - + + + + + + + + + @@ -1622,22 +1723,24 @@ - + + + - - + + - - + + diff --git a/.vscode/launch.json b/.vscode/launch.json index 0cb3b68..9462ecd 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -68,6 +68,28 @@ }, "args": [], "showLog": true + }, + { + "name": "Launch fbs server", + "type": "go", + "request": "launch", + "mode": "debug", + "remotePath": "", + "port": 2345, + "host": "127.0.0.1", + "program": "${workspaceRoot}/server/", + "osx": { + "env": { + //"GOPATH": "${env.HOME}/Dropbox/go" + } + }, + "windows": { + "env": { + //"GOPATH": "${env.USERPROFILE}\\Dropbox\\go" + } + }, + "args": [], + "showLog": true } ] } \ No newline at end of file diff --git a/main.go b/main.go index abea0ae..43e2286 100644 --- a/main.go +++ b/main.go @@ -52,6 +52,7 @@ func main() { //&encodings.CopyRectEncoding{}, //coRRE := encodings.CoRREEncoding{}, //hextile := encodings.HextileEncoding{}, + &encodings.PseudoEncoding{int32(common.EncJPEGQualityLevelPseudo9)}, } // file, _ := os.OpenFile("stam.bin", os.O_CREATE|os.O_RDWR, 0755) @@ -60,6 +61,20 @@ func main() { //tight.SetOutput(file) clientConn.SetEncodings(encs) + clientConn.FramebufferUpdateRequest(false, 0, 0, 1280, 800) + // clientConn.SetPixelFormat(&common.PixelFormat{ + // BPP: 32, + // Depth: 24, + // BigEndian: 0, + // TrueColor: 1, + // RedMax: 255, + // GreenMax: 255, + // BlueMax: 255, + // RedShift: 16, + // GreenShift: 8, + // BlueShift: 0, + // }) + go func() { for { err = clientConn.FramebufferUpdateRequest(true, 0, 0, 1280, 800) diff --git a/server/fbs-reader.go b/server/fbs-reader.go new file mode 100644 index 0000000..54e4e39 --- /dev/null +++ b/server/fbs-reader.go @@ -0,0 +1,144 @@ +package server + +import ( + "encoding/binary" + "io" + "os" + "vncproxy/common" + "vncproxy/logger" +) + +type FbsReader struct { + reader io.Reader +} + +func NewFbsReader(fbsFile string) (*FbsReader, error) { + + reader, err := os.OpenFile(fbsFile, os.O_RDONLY, 0644) + if err != nil { + logger.Error("NewFbsReader: can't open fbs file: ", fbsFile) + return nil, err + } + return &FbsReader{reader: reader}, nil +} + +func (player *FbsReader) ReadStartSession() (*common.ServerInit, error) { + + initMsg := common.ServerInit{} + reader := player.reader + + var framebufferWidth uint16 + var framebufferHeight uint16 + var SecTypeNone uint32 + //read rfb header information (the only part done without the [size|data|timestamp] block wrapper) + //.("FBS 001.000\n") + bytes := make([]byte, 12) + _, err := reader.Read(bytes) + if err != nil { + logger.Error("error reading rbs init message - FBS file Version:", err) + return nil, err + } + + //read the version message into the buffer so it will be written in the first rbs block + //RFB 003.008\n + bytes = make([]byte, 12) + _, err = reader.Read(bytes) + if err != nil { + logger.Error("error reading rbs init - RFB Version: ", err) + return nil, err + } + + //push sec type and fb dimensions + binary.Read(reader, binary.BigEndian, &SecTypeNone) + if err != nil { + logger.Error("error reading rbs init - SecType: ", err) + } + + //read frame buffer width, height + binary.Read(reader, binary.BigEndian, &framebufferWidth) + if err != nil { + logger.Error("error reading rbs init - FBWidth: ", err) + return nil, err + } + initMsg.FBWidth = framebufferWidth + + binary.Read(reader, binary.BigEndian, &framebufferHeight) + if err != nil { + logger.Error("error reading rbs init - FBHeight: ", err) + return nil, err + } + initMsg.FBHeight = framebufferHeight + + //read pixel format + pixelFormat := &common.PixelFormat{} + binary.Read(reader, binary.BigEndian, pixelFormat) + if err != nil { + logger.Error("error reading rbs init - Pixelformat: ", err) + return nil, err + } + initMsg.PixelFormat = *pixelFormat + //read padding + bytes = make([]byte, 3) + reader.Read(bytes) + + //read desktop name + var desknameLen uint32 + binary.Read(reader, binary.BigEndian, &desknameLen) + if err != nil { + logger.Error("error reading rbs init - deskname Len: ", err) + return nil, err + } + initMsg.NameLength = desknameLen + + bytes = make([]byte, desknameLen) + reader.Read(bytes) + if err != nil { + logger.Error("error reading rbs init - desktopName: ", err) + return nil, err + } + + initMsg.NameText = bytes + + return &initMsg, nil +} + +func (player *FbsReader) ReadSegment() (*FbsSegment, error) { + reader := player.reader + var bytesLen uint32 + + //read length + err := binary.Read(reader, binary.BigEndian, &bytesLen) + if err != nil { + logger.Error("error reading rbs file: ", err) + return nil, err + } + + paddedSize := (bytesLen + 3) & 0x7FFFFFFC + + //read bytes + bytes := make([]byte, paddedSize) + _, err = reader.Read(bytes) + if err != nil { + logger.Error("error reading rbs file: ", err) + return nil, err + } + + //remove padding + actualBytes := bytes[:bytesLen] + + //read timestamp + var timeSinceStart uint32 + binary.Read(reader, binary.BigEndian, &timeSinceStart) + if err != nil { + logger.Error("error reading rbs file: ", err) + return nil, err + } + + //timeStamp := time.Unix(timeSinceStart, 0) + return &FbsSegment{actualBytes, timeSinceStart}, nil +} + +type FbsSegment struct { + bytes []byte + timeSinceStart uint32 +} diff --git a/server/main.go b/server/main.go new file mode 100644 index 0000000..5d89304 --- /dev/null +++ b/server/main.go @@ -0,0 +1,63 @@ +package server + +import ( + "log" + "vncproxy/common" + "vncproxy/encodings" + "vncproxy/logger" +) + +func newServerConnHandler(cfg *ServerConfig, conn *ServerConn) error { + return nil +} + +func main() { + + //chServer := make(chan common.ClientMessage) + chClient := make(chan common.ServerMessage) + + cfg := &ServerConfig{ + //SecurityHandlers: []SecurityHandler{&ServerAuthNone{}, &ServerAuthVNC{}}, + SecurityHandlers: []SecurityHandler{&ServerAuthVNC{"Ch_#!T@8"}}, + Encodings: []common.Encoding{&encodings.RawEncoding{}, &encodings.TightEncoding{}, &encodings.CopyRectEncoding{}}, + PixelFormat: common.NewPixelFormat(32), + //ClientMessageCh: chServer, + ServerMessageCh: chClient, + ClientMessages: DefaultClientMessages, + DesktopName: []byte("workDesk"), + Height: uint16(768), + Width: uint16(1024), + NewConnHandler: newServerConnHandler, + } + + loadFbsFile("c:\\Users\\betzalel\\Dropbox\\recording.rbs", cfg) + + url := "http://localhost:8091/" + go WsServe(url, cfg) + go TcpServe(":5904", cfg) + // Process messages coming in on the ClientMessage channel. + for { + msg := <-chClient + switch msg.Type() { + default: + log.Printf("Received message type:%v msg:%v\n", msg.Type(), msg) + } + } +} + +func loadFbsFile(filename string, cfg *ServerConfig) { + fbs, err := NewFbsReader(filename) + if err != nil { + logger.Error("failed to open fbs reader:", err) + } + //NewFbsReader("/Users/amitbet/vncRec/recording.rbs") + initMsg, err := fbs.ReadStartSession() + if err != nil { + logger.Error("failed to open read fbs start session:", err) + } + + cfg.PixelFormat = &initMsg.PixelFormat + cfg.Height = initMsg.FBHeight + cfg.Width = initMsg.FBWidth + cfg.DesktopName = initMsg.NameText +}