UPnP (Universal Plug and Play)

Defined by its name, UPnP is a protocol providing a solution for a new device to be used in a network, simply plug it and then you can play with it. Normally, when you buy a new device, a new laser printer for instance, there are many steps to do until you can finally use the printer, and even use it with its Wifi feature. By applying UPnP, you can simply plug the new device into your PC, or even just turn the device on, its UPnP feature would allow you to use the device without doing anything.



Before burning the bin file into your EVB:

      1. Connect W5500 EVB to the router/NAT that you are using, or any other device that allows you to connect to the internet
      2. Manually change the Network configuration:
          • Go to the definition of function “set_default()” (Should be inside device.c), make sure the subnet mask, local IP address, gateway and DNS are set according to the internet setting you are using with your router/NAT
      3. Rebuild the sample code and burn it into W5500EVB
      4. Change your PC’s IP address to a static IP if you are not using router

Brief Explanation of UPnP

First of all, for better reading and understanding, it would be better if you pay attention to the following abbreviations:

  •       IGD – Internet Gateway Device
  •       IWF – Interworking Function
  •       NAT – Network Address Translation
  •       UPnP – Universal Plug and Play

UPnP consists of a number of protocols, including but not limited to IP, TCP, UDP, SSDP, HTTP, XML, DHCP. The architecture of UPnP are as follows:

Figure 2 illustrates the architecture model as adopted by the UPnP Forum [IGD2]. In Figure 2, the following UPnP terminology is used:

  • ‘Client’ refers to a host located in the local network.
  • ‘IGD Control Point’ is a device using UPnP to control an IGD (Internet Gateway Device).
  • ‘IGD’ is a router supporting a UPnP IGD.  It is typically a NAT or a firewall.
  •  ‘Host’ is a remote peer reachable on the Internet.

Besides, it can be divided into Six stages of steps which is: Addressing, Discovery, Description, Control, Eventing and Presentation:

Addressing: Finding address in the new network. DHCP would be applied to let our device automatically find an address without any manual setting.

Discovery: Once an address is attained, the IGD Control Point would send a broadcast packet to find any device in the same network that is equipped with UPnP(in this case) feature. The process is also known as M search. Responses would be received from those devices with UPnP enabled.

Description: Since the information about those devices with UPnP enabled is limited in the responses packet, more information such as what function do those devices have and many more. A packet would be sent to get the required information in URL form. The packet lists the URLs for control, eventing and service description. Each service description includes a list of the commands, or actions, to which the service responds, and parameters, or arguments, for each action

Control: After getting information we need to control devices, we can start controlling them, or to get updated information, if there is any, of those devices by the responses from IGM after sending requests to it.

Eventing: other than sending requests for updated information every time, the control point can subscript desired services. The subscripted services(devices) then send packets every time whenever there is an update after subscription.

Presentation: If a device has a URL for presentation, the IGD control point is able to retrieve a page from this URL, loading the page into a web browser, and allowing a user to control the device and/or view device status, depending on the capabilities of the page. To what extent the mentioned function can be accomplished depends on the specific capabilities of the presentation page and device.


Code Explanation

There are two version of codes

If you are not using the free version of Keil Vision, you would be able to build the original version of the sample code, which includes DHCP Client. If so, you will first run DHCP client to attain network parameters such as IP, subnet mask from the NAT. If the DHCP Client fails, you can still get the parameters from the previously and manually set network settings.

While if you are using the free version of Keil Vision, since the size of the original version exceeds the allowance size (32KB), there is a modified version, which excludes the DHCP Client and uses manually set network settings instead.

But before running the DHCP Client, there are some initialization.

int main()
{
  uint8 dhcpret=0;
  GPIO_Configuration();
  NVIC_Configuration();
  
  Systick_Init(72);
  USART1_Init();
  at24c16_init();
  printf("W5500 EVB initialization over.\r\n");
  
  Reset_W5500();
  WIZ_SPI_Init();
  set_w5500_mac();
  printf("W5500 initialized!\r\n"); 
  init_dhcp_client();    //Initialize elements of packet for DHCP Client

After all initialization, W5500EVB goes into the main loop.

while(1)
{
  dhcpret = check_DHCP_state(SOCK_DHCP);
  switch(dhcpret)
  {
    case DHCP_RET_NONE:
    break;

    case DHCP_RET_TIMEOUT:
    break;

    case DHCP_RET_UPDATE:
      set_default();
      set_network();
    C_Flag = 1;
    break;

    case DHCP_RET_CONFLICT:
      while(1);
    default:
    break;
  }

After the network setting,known as Addressing, W5500EVB goes into Discovery stage, sending an SSDP packet to complete the M search process, through the function SSDPProcess(). Basically the function SSDPProcess() constructs a packet according to the required structure and sends it.

After Discovery, a packet of getting description will be sent. Similar to SSDPProcess(), the process of getting description is done by GetDescriptionProcess(). Again, similar to the aforementioned functions, W5500EVB runs the function SetEventing() to make a subscription. This function subscribes to the eventing message from IGD.

  if(C_Flag == 1)
  {
    do
    {
      printf("Send SSDP..\r\n");
    }
    while(SSDPProcess(SOCK_SSDP)!=0);
    // Try to Get Description of IGD
    if(GetDescriptionProcess(SOCK_UPNP)==0) 
      printf("GetDescription Success!!\r\n");
    else printf("GetDescription Fail!!\r\n");
    // Try to Subscribe Eventing
    if(SetEventing(SOCK_UPNP)==0) 
      printf("SetEventing Success!!\r\n");
    else 
      printf("SetEventing Fail!!\r\n");

    Main_Menu();

    while(1) {} 
    }
  }
}


After all these stages, W550EVB enters into a loop of Main_Meun(), which eventually allows the user to control the UPnP device in reality, or control the LEDs and sockets on the EVB in this case. Working as a IGD control point is the ultimate goal of this sample code.

    Main_Menu();

    while(1) {} 
    }
  }
}


Main_Menu()

As shown on the printed text message, users have 8 options to choose. The seventh option, UPnP PortForwarding: AddPort, may be new to you. To briefly elaborate, port forwarding is a concept of allowing devices or PCs from outside of the subnet to connect to W5500EVB. Port forwarding is a popular concept, therefore you can easily find related information on the Internet.

Basically, to request for port forwarding, the IGD control point, which is W5500EVB in this case, can simply send a proper request to IGD to get the request done, through AddPortProcess() in this case. Option 7 allows you to choose the type of connection for port forwarding, as well as the port number. Eventually W5500EVB sends the request upon our choices.

void Main_Menu(void)
{
  static char choice[3];
  static char msg[256], ipaddr[12], protocol[4];
  static unsigned short ret, external_port, internal_port;
  static bool bTreat;
  static u8 Sip[4];
  static char key = 0;

  while (1)
  {
    /* Display Menu on HyperTerminal Window */
    bTreat = (bool)RESET ;
    SerialPutString("\r\n====================== W5500_Control_Point ===================\r\n");
    SerialPutString("This Application is basic example of UART interface with\r\n");
    SerialPutString("Windows Hyper Terminal. \r\n");
    SerialPutString("\r\n==========================================================\r\n");
    SerialPutString("                          APPLICATION MENU :\r\n");
    SerialPutString("\r\n==========================================================\r\n\n");
    SerialPutString(" 1 - Set LD1 on \r\n");
    SerialPutString(" 2 - Set LD1 off \r\n");
    SerialPutString(" 3 - Show network setting\r\n");
    SerialPutString(" 4 - Set  network setting\r\n");
    SerialPutString(" 5 - Run TCP Loopback\r\n");
    SerialPutString(" 6 - Run UDP Loopback\r\n");
    SerialPutString(" 7 - UPnP PortForwarding: AddPort\r\n");
    SerialPutString(" 8 - UPnP PortForwarding: DeletePort\r\n");
		
    SerialPutString("Enter your choice : ");
    GetInputString(choice);

    if (strcmp(choice,"1") == 0){}
    if (strcmp(choice,"2") == 0){}
    if (strcmp(choice,"3") == 0){}
    if (strcmp(choice,"4") == 0){}
    if (strcmp(choice,"5") == 0){}		
    if (strcmp(choice,"6") == 0){}
    if (strcmp(choice,"7") == 0)
    {
      bTreat = (bool)SET;		
      SerialPutString("\r\nType a Protocol(TCP/UDP) : ");
      GetInputString(msg);
      strncpy(protocol, msg, 3);
      protocol[3] = '\0';

      SerialPutString("\r\nType a External Port Number : ");
      GetInputString(msg);
      external_port = ATOI(msg, 10);

      SerialPutString("\r\nType a Internal Port Number : ");
      GetInputString(msg);
      internal_port = ATOI(msg, 10);
      TCP_LISTEN_PORT=internal_port;
      close(7);
      // Try to Add Port Action
      getSIPR(Sip);
      sprintf(ipaddr, "%d.%d.%d.%d", Sip[0], Sip[1], Sip[2], Sip[3]);
      if((ret = AddPortProcess(SOCK_UPNP, protocol, external_port, ipaddr, internal_port, "W5500_uPnPGetway"))==0) printf("AddPort Success!!\r\n");
      else printf("AddPort Error Code is %d\r\n", ret);
    }


    if (strcmp(choice,"8")== 0){}

     /* OTHERS CHOICE*/
    if (bTreat == (bool)RESET)
    {
      SerialPutString(" wrong choice  \r\n");
    }			
    eventing_listener(SOCK_UPNP_EVENTING);
  } /* While(1)*/
}/* Main_Menu */



Remarks

For multiple sockets, the main loop is structured in the same way as one socket. The only difference is that pulling method is used to function all sockets, therefore delay for sending message is significantly noticeable. The sample code are only for demonstration, users are free to use any other method to do open multiple sockets(interrupt for example). For the sample code of multiple sockets, only two sockets are allowed by default. Users are free to change it if necessary.