Subversion Repositories HomeAutomation

Rev

Rev 363 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. /*********************************************************************
  2.  *
  3.  *                  Announce Module for Microchip TCP/IP Stack
  4.  *
  5.  *********************************************************************
  6.  * FileName:        Announce.c
  7.  * Dependencies:    UDP.h
  8.  * Processor:       PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F
  9.  * Complier:        Microchip C18 v3.02 or higher
  10.  *                  Microchip C30 v2.01 or higher
  11.  * Company:         Microchip Technology, Inc.
  12.  *
  13.  * Software License Agreement
  14.  *
  15.  * This software is owned by Microchip Technology Inc. ("Microchip")
  16.  * and is supplied to you for use exclusively as described in the
  17.  * associated software agreement.  This software is protected by
  18.  * software and other intellectual property laws.  Any use in
  19.  * violation of the software license may subject the user to criminal
  20.  * sanctions as well as civil liability.  Copyright 2006 Microchip
  21.  * Technology Inc.  All rights reserved.
  22.  *
  23.  * This software is provided "AS IS."  MICROCHIP DISCLAIMS ALL
  24.  * WARRANTIES, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, NOT LIMITED
  25.  * TO MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
  26.  * INFRINGEMENT.  Microchip shall in no event be liable for special,
  27.  * incidental, or consequential damages.
  28.  *
  29.  *
  30.  * Author               Date    Comment
  31.  *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  32.  * Howard Schlunder     10/7/04 Original
  33.  * Howard Schlunder     2/9/05  Simplified MAC address to text
  34.  *                              conversion logic
  35.  * Howard Schlunder     2/14/05 Fixed subnet broadcast calculation
  36.  ********************************************************************/
  37. #define THIS_IS_ANNOUNCE
  38.  
  39. #include "..\Include\StackTsk.h"
  40.  
  41. #if defined(STACK_USE_ANNOUNCE)
  42.  
  43. #include "..\Include\UDP.h"
  44. #include "..\Include\Helpers.h"
  45.  
  46.  
  47. #define ANNOUNCE_PORT   30303
  48.  
  49. extern NODE_INFO remoteNode;
  50.  
  51. /*********************************************************************
  52.  * Function:        void AnnounceIP(void)
  53.  *
  54.  * PreCondition:    Stack is initialized()
  55.  *
  56.  * Input:           None
  57.  *
  58.  * Output:          None
  59.  *
  60.  * Side Effects:    None
  61.  *
  62.  * Overview:        AnnounceIP opens a UDP socket and transmits a
  63.  *                  broadcast packet to port 30303.  If a computer is
  64.  *                  on the same subnet and a utility is looking for
  65.  *                  packets on the UDP port, it will receive the
  66.  *                  broadcast.  For this application, it is used to
  67.  *                  announce the change of this board's IP address.
  68.  *                  The messages can be viewed with the MCHPDetect.exe
  69.  *                  program.
  70.  *
  71.  * Note:            A UDP socket must be available before this
  72.  *                  function is called.  It is freed at the end of
  73.  *                  the function.  MAX_UDP_SOCKETS may need to be
  74.  *                  increased if other modules use UDP sockets.
  75.  ********************************************************************/
  76. void AnnounceIP(void)
  77. {
  78.     UDP_SOCKET  MySocket;
  79.     NODE_INFO   Remote;
  80.     BYTE        i;
  81.    
  82.     // Set the socket's destination to be a broadcast over our IP
  83.     // subnet
  84.     // Set the MAC destination to be a broadcast
  85.     memset(&Remote, 0xFF, sizeof(Remote));
  86.    
  87.     // Open a UDP socket for outbound transmission
  88.     MySocket = UDPOpen(2860, &Remote, ANNOUNCE_PORT);
  89.    
  90.     // Abort operation if no UDP sockets are available
  91.     // If this ever happens, incrementing MAX_UDP_SOCKETS in
  92.     // StackTsk.h may help (at the expense of more global memory
  93.     // resources).
  94.     if( MySocket == INVALID_UDP_SOCKET )
  95.         return;
  96.    
  97.     // Make certain the socket can be written to
  98.     while( !UDPIsPutReady(MySocket) );
  99.    
  100.     // Begin sending our MAC address in human readable form.
  101.     // The MAC address theoretically could be obtained from the
  102.     // packet header when the computer receives our UDP packet,
  103.     // however, in practice, the OS will abstract away the useful
  104.     // information and it would be difficult to obtain.  It also
  105.     // would be lost if this broadcast packet were forwarded by a
  106.     // router to a different portion of the network (note that
  107.     // broadcasts are normally not forwarded by routers).
  108.     for(i=0; i < sizeof(AppConfig.NetBIOSName)-1; i++)
  109.     {
  110.         UDPPut(AppConfig.NetBIOSName[i]);
  111.     }
  112.     UDPPut('\r');
  113.     UDPPut('\n');
  114.  
  115.     // Convert the MAC address bytes to hex (text) and then send it
  116.     i = 0;
  117.     while(1)
  118.     {
  119.         UDPPut(btohexa_high(AppConfig.MyMACAddr.v[i]));
  120.         UDPPut(btohexa_low(AppConfig.MyMACAddr.v[i]));
  121.         if(++i == 6)
  122.             break;
  123.         UDPPut('-');
  124.     }
  125.     UDPPut('\r');
  126.     UDPPut('\n');
  127.  
  128.     // Send some other human readable information.
  129.     UDPPut('D');
  130.     UDPPut('H');
  131.     UDPPut('C');
  132.     UDPPut('P');
  133.     UDPPut('/');
  134.     UDPPut('P');
  135.     UDPPut('o');
  136.     UDPPut('w');
  137.     UDPPut('e');
  138.     UDPPut('r');
  139.     UDPPut(' ');
  140.     UDPPut('e');
  141.     UDPPut('v');
  142.     UDPPut('e');
  143.     UDPPut('n');
  144.     UDPPut('t');
  145.     UDPPut(' ');
  146.     UDPPut('o');
  147.     UDPPut('c');
  148.     UDPPut('c');
  149.     UDPPut('u');
  150.     UDPPut('r');
  151.     UDPPut('r');
  152.     UDPPut('e');
  153.     UDPPut('d');
  154.    
  155.     // Send the packet
  156.     UDPFlush();
  157.    
  158.     // Close the socket so it can be used by other modules
  159.     UDPClose(MySocket);
  160. }
  161.  
  162. void DiscoveryTask(void)
  163. {
  164.     static enum {
  165.         DISCOVERY_HOME = 0,
  166.         DISCOVERY_LISTEN,
  167.         DISCOVERY_REQUEST_RECEIVED,
  168.         DISCOVERY_DISABLED
  169.     } DiscoverySM = DISCOVERY_HOME;
  170.  
  171.     static UDP_SOCKET   MySocket;
  172.     BYTE                i;
  173.    
  174.     switch(DiscoverySM)
  175.     {
  176.         case DISCOVERY_HOME:
  177.             // Open a UDP socket for inbound and outbound transmission
  178.             // Since we expect to only receive broadcast packets and
  179.             // only send unicast packets directly to the node we last
  180.             // received from, the remote NodeInfo parameter can be anything
  181.             MySocket = UDPOpen(ANNOUNCE_PORT, NULL, ANNOUNCE_PORT);
  182.  
  183.             if(MySocket == INVALID_UDP_SOCKET)
  184.                 return;
  185.             else
  186.                 DiscoverySM++;
  187.             break;
  188.  
  189.         case DISCOVERY_LISTEN:
  190.             // Do nothing if no data is waiting
  191.             if(!UDPIsGetReady(MySocket))
  192.                 return;
  193.            
  194.             // See if this is a discovery query or reply
  195.             UDPGet(&i);
  196.             UDPDiscard();
  197.             if(i != 'D')
  198.                 return;
  199.            
  200.             // We received a discovery request, reply
  201.             DiscoverySM++;
  202.             break;
  203.  
  204.         case DISCOVERY_REQUEST_RECEIVED:
  205.             if(!UDPIsPutReady(MySocket))
  206.                 return;
  207.  
  208.             // Begin sending our MAC address in human readable form.
  209.             // The MAC address theoretically could be obtained from the
  210.             // packet header when the computer receives our UDP packet,
  211.             // however, in practice, the OS will abstract away the useful
  212.             // information and it would be difficult to obtain.  It also
  213.             // would be lost if this broadcast packet were forwarded by a
  214.             // router to a different portion of the network (note that
  215.             // broadcasts are normally not forwarded by routers).
  216.             for(i=0; i < sizeof(AppConfig.NetBIOSName)-1; i++)
  217.             {
  218.                 UDPPut(AppConfig.NetBIOSName[i]);
  219.             }
  220.             UDPPut('\r');
  221.             UDPPut('\n');
  222.        
  223.             // Convert the MAC address bytes to hex (text) and then send it
  224.             i = 0;
  225.             while(1)
  226.             {
  227.                 UDPPut(btohexa_high(AppConfig.MyMACAddr.v[i]));
  228.                 UDPPut(btohexa_low(AppConfig.MyMACAddr.v[i]));
  229.                 if(++i == 6)
  230.                     break;
  231.                 UDPPut('-');
  232.             }
  233.             UDPPut('\r');
  234.             UDPPut('\n');
  235.  
  236.             // Change the destination to the unicast address of the last received packet
  237.             memcpy((void*)&UDPSocketInfo[MySocket].remoteNode, (const void*)&remoteNode, sizeof(remoteNode));
  238.        
  239.             // Send the packet
  240.             UDPFlush();
  241.  
  242.             // Listen for other discovery requests
  243.             DiscoverySM = DISCOVERY_LISTEN;
  244.             break;
  245.  
  246.         case DISCOVERY_DISABLED:
  247.             break;
  248.     }  
  249.  
  250. }
  251.  
  252.  
  253. #endif //#if defined(STACK_USE_ANNOUNCE)
  254.