Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Trying to implement Wake on LAN (WOL) on N+


  • Please log in to reply
7 replies to this topic

#1 Michel Tol

Michel Tol

    Member

  • Members
  • PipPip
  • 16 posts
  • LocationNL

Posted 17 December 2010 - 10:27 PM

HI,

after almost 2 weeks waiting my netduino+ had arrived.
After the led examples I wanted to implement a Wake on LAN (WOL) so I could remotely boot my PC at home.
after connecting the n+ to the network, enabled DHCP (got an ip). I tried to execute to the following method:


 public static void WakeUp(byte[] mac)
        {
            using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
            {
                // IP 255.255.255.255 
                //IPEndPoint endPoint = new IPEndPoint(new IPAddress(4294967295), 40000);
                IPEndPoint endPoint = new IPEndPoint(new IPAddress(0xffffffffL), 40000);

                socket.Connect(endPoint);

                byte[] packet = new byte[17 * 6];
                for (int i = 0; i < 6; i++) packet[i] = 0xFF;
                for (int i = 1; i <= 16; i++)
                {
                    for (int j = 0; j < 6; j++)
                    {
                        packet[i * 6 + j] = mac[j];
                    }
                }

                var r = socket.Send(packet, packet.Length,System.Net.Sockets.SocketFlags.Broadcast);
            }
        }


I'm converting my MAC-address from string to byte[] via the ToBytes() method in the following class :
    public  class MacAddress 
    {
        private readonly string _address;
        private readonly string[] _macDigits;

        public MacAddress(string address)
        {
            _address = address;

            
            if (_address.IndexOf("-") > -1)
            {
                _macDigits = _address.Split('-');
            }
            else
            {
                _macDigits = _address.Split(':');
            }

            if (_macDigits.Length != 6)
            {
                throw new ArgumentException("Incorrect MAC address supplied!");
            }

            
        }

        public override string ToString()
        {
            return _address;
        }
        public byte[] ToBytes()
        {

            var datagram = new byte[96];

            for (int i = 0; i <= 5; i++)
            {
                datagram[i] = 0xff;
            }


            int start = 0;
            for (int i = 0; i < 16; i++)
            {
                for (int x = 0; x < 6; x++)
                {
                    datagram[start + i * 6 + x] = (byte)Convert.ToInt32(_macDigits[x], 16);
                }
            }


            int k = Encoding.UTF8.GetBytes(_address).Length;


            return datagram;
        }
    }


for some reason it doesn't work. The error happends at the following line:
var r = socket.Send(packet, packet.Length,System.Net.Sockets.SocketFlags.Broadcast);


Error produced:

#### Exception System.Net.Sockets.SocketException - CLR_E_FAIL (3) ####
#### Message:
#### Microsoft.SPOT.Net.SocketNative::send [IP: 0000] ####
#### System.Net.Sockets.Socket::Send [IP: 0018] ####
#### System.Net.Sockets.Socket::Send [IP: 0008] ####
#### WOLService.WakeOnLan::WakeUp [IP: 0087] ####
#### WOLService.WakeOnLan::WakeUp [IP: 000d] ####
#### WOLService.Program::button_OnInterrupt [IP: 0014] ####
#### SocketException ErrorCode = 10022
#### SocketException ErrorCode = 10022
A first chance exception of type 'System.Net.Sockets.SocketException' occurred in Microsoft.SPOT.Net.dll
#### SocketException ErrorCode = 10022
#### SocketException ErrorCode = 10022


I have no idea what is going wrong and can't find any info about error 'CLR_E_FAIL (3)' or error code 'ErrorCode = 10022'

Could somebody tell me what's wrong with my code or tell me where I can find more info about these error codes..

tnx!
michel

#2 Tecchie

Tecchie

    Member

  • Members
  • PipPip
  • 23 posts
  • LocationGermany

Posted 18 December 2010 - 01:11 PM

You have to enable broadcast sending on the socket:

  // ...
  IPEndPoint endPoint = new IPEndPoint(new IPAddress(0xffffffffL), 40000);
  socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
  socket.Connect(endPoint);
  // ...

Tecchie

#3 Michel Tol

Michel Tol

    Member

  • Members
  • PipPip
  • 16 posts
  • LocationNL

Posted 18 December 2010 - 09:33 PM

tecchie, tnx that did the trick! At least it doesn't error anymore. Will check it out tomorrow if the machine really boots aswell. tnx! michel

#4 Chris Seto

Chris Seto

    Advanced Member

  • Members
  • PipPipPip
  • 405 posts

Posted 19 December 2010 - 01:28 AM

WOL is tricky as hell. Don't be surprised if it doesn't work on some particular NIC. The only NIC I have ever been able to get to work with WOL properly has been my Intel Pro GT 10/100/1000's.

#5 Omar (OZ)

Omar (OZ)

    Advanced Member

  • Members
  • PipPipPip
  • 564 posts

Posted 19 December 2010 - 03:01 AM

This is neat idea, but I don't understand why it has to be this way.... Why can't you just connect a transistor to the computer's power button and turn it on by just sending a high signal to the transistor? Maybe I'm missing something, or just don't understand what the goal is... is there something special about WOL that I am missing?

#6 spur

spur

    Member

  • Members
  • PipPip
  • 27 posts

Posted 19 December 2010 - 03:55 AM

With WOL it's all done in software. You don't have to have wires between the Netduino and the computer (besides Ethernet). You can wake up any computer in the house regardless of location. A transistor for the power button would certainly also work though. And it can be more robust, since you can hard rest the computer if needed. Also, usually WOL requires the computer to be asleep and not off, and the transistor solution works for both.

#7 spur

spur

    Member

  • Members
  • PipPip
  • 27 posts

Posted 20 December 2010 - 04:05 PM

You have to enable broadcast sending on the socket:

  // ...
  IPEndPoint endPoint = new IPEndPoint(new IPAddress(0xffffffffL), 40000);
  socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
  socket.Connect(endPoint);
  // ...

Tecchie


Adding this makes the WOL signal work for me. Starts up the computer nicely. Thanks Tecchie :)

#8 Michel Tol

Michel Tol

    Member

  • Members
  • PipPip
  • 16 posts
  • LocationNL

Posted 21 December 2010 - 10:01 AM

Hereby my updated code:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;



namespace WOLService
{
    /// <summary>
    /// Wrapper around the MacAdress String
    /// </summary>
    public class MacAddress
    {
        private readonly string _address;
        
        private readonly string[] _macDigits;

        /// <summary>
        /// Constructor for creating a MAcAdress
        /// </summary>
        /// <param name="address"></param>
        public MacAddress(string address)
        {
            _address = address;

            if (_address.IndexOf("-") > -1)
            {
                _macDigits = _address.Split('-');
            }
            else
            {
                _macDigits = _address.Split(':');
            }

            if (_macDigits.Length != 6)
            {
                throw new ArgumentException("Incorrect MAC address supplied!");
            }
        }

        public override string ToString()
        {
            return _address;
        }
    
        public byte[] ToBytes()
        {

            var datagram = new byte[6];

            for (var x = 0; x < 6; x++)
            {
                datagram[x] = (byte)Convert.ToInt32(_macDigits[x], 16);
            }

            return datagram;
        }
    }


    public class WakeOnLan
    {
        public void WakeUp(MacAddress macAddress)
        {
            var wolPackage = CreateWolPackage(macAddress);


            Send(wolPackage);
        }

        private void Send(byte[] package)
        {

            using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
            {
                socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
                var endPoint = new IPEndPoint(new IPAddress(0xffffffffL), 40000);


                socket.Connect(endPoint);

                socket.Send(package);
            }
        }

        private static byte[] CreateWolPackage(MacAddress macAddress)
        {
            var datagram = new byte[108];

            for (int i = 0; i <= 5; i++)
            {
                datagram[i] = 0xff;
            }


            var macDigits = macAddress.ToBytes();
            int start = 6;
            for (int i = 0; i < 16; i++)
            {
                for (int x = 0; x < 6; x++)
                {
                    datagram[start + i * 6 + x] = macDigits[x];

                }
            }

            for (int i = 102; i < 108; i++)
            {
                datagram[i] = 0x00;
            }



            return datagram;
        }
    }
}


Together with the updated webserver posted in one of the other trheads, I am able to boot my machines at home remotely. Together with hamachi logmein.com I can connect to my machines at home any time I want without having my pc's running the whole day.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.