/* * * Initial hack of an Arduino VNC server * * LGPL 2.0 * * 28 March 2009 * * follower@rancidbacon.com * */ #include // network configuration. gateway and subnet are optional. byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; byte ip[] = { 169, 254, 254, 169 }; // vnc defaults to port 5900 Server server(5900); void setup() { // initialize the ethernet device Ethernet.begin(mac, ip); // start listening for clients server.begin(); } void skipBytesFromClient(Client client, int numBytesToSkip) { /* Note: No timeout */ for (int i = 0; i < numBytesToSkip; i++) { while (!client.available()) { // Wait for byte from client } client.read(); } } //#define BUFFER_SIZE (0xff * 2) #define BUFFER_SIZE 0xff char buffer[BUFFER_SIZE]; void loop() { Client client = server.connected(); // Note: Needs my Ethernet library edit if (client) { client.print("RFB 003.003\n"); // Hacky check for client response // requesting the protocol version we expect. // TODO: In all cases change to handle client disconnect etc skipBytesFromClient(client, 12); // Specify security type = None // For 3.3 protocol client is expected to just accept this // and not acknowledge it. client.write(0); client.write(0); client.write(0); client.write(1); // Begin Initialisation phase // Wait for ClientInit message from client & // throw away shared-flag value in ClientInit message skipBytesFromClient(client, 1); // Send ServerInit message char const serverInitMsg[] = { 0,0xff, // framebuffer-width 0,0xff, // framebuffer-height // server-pixel-format 0x08, // bits-per-pixel 0x08, // depth 0x01, // big-endian-ßag (ignored for 8-bit) 0x01, // true-colour-ßag 0x00, 0x07,// red-max (2 bit) 0x00, 0x07,// green-max (2 bit) 0x00, 0x03,// blue-max (2 bit) 0x00, // red-shift -- assume bbgggrrr (bgr233) 0x03, // green-shift 0x06, // blue-shift 0x00, 0x00, 0x00, // padding 0x00, 0x00, 0x00, 0x07, // name-length 'A','r','d','u','i','n','o' // name-string }; client.write(serverInitMsg, sizeof(serverInitMsg)); // Note: Needs my other Ethernet edit // Wait for client to send pixel configuration // Assume SetPixelFormat message (first byte '0') skipBytesFromClient(client, 1 + 19); // Wait for client to send encoding config // Assume SetEncodings message (first byte '2') // TODO: Handle encoding list properly skipBytesFromClient(client, 1 + (1 + 2 + 4)); // Note: This will only work if only 1 encoding is sent. // Wait for client to send FramebufferUpdateRequest // Assume FramebufferUpdateRequest message (first byte '3') // TODO: Handle request properly skipBytesFromClient(client, 1 + (1 + 2 + 2 + 2 + 2)); // TODO: Handle requests properly client.write('\x02'); // Send a bell. // Send clipboard text. const char clipboardText[] = {0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 'H','e','l','l','o'}; client.write(clipboardText, sizeof(clipboardText)); for (int j = 0; j < 0x10 ; j++) { // Send a frame const char updateHeader[] = {0x00, // FramebufferUpdate 0x00, // padding 0x00, 0x01, // number-of-rectangles // rectangle 0x00, 0x00, // x-position 0x00, 0x00, // y-position 0x00, 0xff, // width 0x00, 0xff, // height 0x00, 0x00, 0x00, 0x00, // encoding-type }; client.write(updateHeader, sizeof(updateHeader)); int offset = 0; for (unsigned int i = 0; i < (0xff * 0xff); i++) { //buffer[offset] = (byte) (i + j) % 0xff; buffer[offset] = j; if (offset == (BUFFER_SIZE - 1)) { client.write(buffer, sizeof(buffer)); offset = 0; } else { offset++; } } } client.write('\x02'); // Send a bell. #if 0 while (client.connected()) { } #endif client.stop(); } }