1 |
/*********************************************************************
|
2 |
*
|
3 |
* Announce Client and Server
|
4 |
* Module for Microchip TCP/IP Stack
|
5 |
* -Provides device hostname and IP address discovery on a local
|
6 |
* Ethernet subnet (same broadcast domain)
|
7 |
* -Reference: None. Hopefully AN833 in the future.
|
8 |
*
|
9 |
*********************************************************************
|
10 |
* FileName: Announce.c
|
11 |
* Dependencies: UDP.h
|
12 |
* Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F
|
13 |
* Complier: Microchip C18 v3.02 or higher
|
14 |
* Microchip C30 v2.01 or higher
|
15 |
* Company: Microchip Technology, Inc.
|
16 |
*
|
17 |
* Software License Agreement
|
18 |
*
|
19 |
* Copyright © 2002-2007 Microchip Technology Inc. All rights
|
20 |
* reserved.
|
21 |
*
|
22 |
* Microchip licenses to you the right to use, modify, copy, and
|
23 |
* distribute:
|
24 |
* (i) the Software when embedded on a Microchip microcontroller or
|
25 |
* digital signal controller product (“Device”) which is
|
26 |
* integrated into Licensee’s product; or
|
27 |
* (ii) ONLY the Software driver source files ENC28J60.c and
|
28 |
* ENC28J60.h ported to a non-Microchip device used in
|
29 |
* conjunction with a Microchip ethernet controller for the
|
30 |
* sole purpose of interfacing with the ethernet controller.
|
31 |
*
|
32 |
* You should refer to the license agreement accompanying this
|
33 |
* Software for additional information regarding your rights and
|
34 |
* obligations.
|
35 |
*
|
36 |
* THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” WITHOUT
|
37 |
* WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
|
38 |
* LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
|
39 |
* PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
40 |
* MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
|
41 |
* CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
|
42 |
* PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
|
43 |
* BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
|
44 |
* THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
|
45 |
* SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
|
46 |
* (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
|
47 |
*
|
48 |
*
|
49 |
* Author Date Comment
|
50 |
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
51 |
* Howard Schlunder 10/7/04 Original
|
52 |
* Howard Schlunder 2/9/05 Simplified MAC address to text
|
53 |
* conversion logic
|
54 |
* Howard Schlunder 2/14/05 Fixed subnet broadcast calculation
|
55 |
* Howard Schlunder 10/3/06 Fixed a remoteNode saving bug
|
56 |
********************************************************************/
|
57 |
#define __ANNOUNCE_C
|
58 |
|
59 |
#include "TCPIP Stack/TCPIP.h"
|
60 |
|
61 |
#if defined(STACK_USE_ANNOUNCE)
|
62 |
|
63 |
#define ANNOUNCE_PORT 30303
|
64 |
|
65 |
|
66 |
|
67 |
extern NODE_INFO remoteNode;
|
68 |
|
69 |
/*********************************************************************
|
70 |
* Function: void AnnounceIP(void)
|
71 |
*
|
72 |
* PreCondition: Stack is initialized()
|
73 |
*
|
74 |
* Input: None
|
75 |
*
|
76 |
* Output: None
|
77 |
*
|
78 |
* Side Effects: None
|
79 |
*
|
80 |
* Overview: AnnounceIP opens a UDP socket and transmits a
|
81 |
* broadcast packet to port 30303. If a computer is
|
82 |
* on the same subnet and a utility is looking for
|
83 |
* packets on the UDP port, it will receive the
|
84 |
* broadcast. For this application, it is used to
|
85 |
* announce the change of this board's IP address.
|
86 |
* The messages can be viewed with the MCHPDetect.exe
|
87 |
* program.
|
88 |
*
|
89 |
* Note: A UDP socket must be available before this
|
90 |
* function is called. It is freed at the end of
|
91 |
* the function. MAX_UDP_SOCKETS may need to be
|
92 |
* increased if other modules use UDP sockets.
|
93 |
********************************************************************/
|
94 |
void AnnounceIP(void)
|
95 |
{
|
96 |
UDP_SOCKET MySocket;
|
97 |
BYTE i;
|
98 |
|
99 |
// Open a UDP socket for outbound broadcast transmission
|
100 |
MySocket = UDPOpen(2860, NULL, ANNOUNCE_PORT);
|
101 |
|
102 |
// Abort operation if no UDP sockets are available
|
103 |
// If this ever happens, incrementing MAX_UDP_SOCKETS in
|
104 |
// StackTsk.h may help (at the expense of more global memory
|
105 |
// resources).
|
106 |
if(MySocket == INVALID_UDP_SOCKET)
|
107 |
return;
|
108 |
|
109 |
// Make certain the socket can be written to
|
110 |
while(!UDPIsPutReady(MySocket));
|
111 |
|
112 |
// Begin sending our MAC address in human readable form.
|
113 |
// The MAC address theoretically could be obtained from the
|
114 |
// packet header when the computer receives our UDP packet,
|
115 |
// however, in practice, the OS will abstract away the useful
|
116 |
// information and it would be difficult to obtain. It also
|
117 |
// would be lost if this broadcast packet were forwarded by a
|
118 |
// router to a different portion of the network (note that
|
119 |
// broadcasts are normally not forwarded by routers).
|
120 |
UDPPutArray((BYTE*)AppConfig.NetBIOSName, sizeof(AppConfig.NetBIOSName)-1);
|
121 |
UDPPut('\r');
|
122 |
UDPPut('\n');
|
123 |
|
124 |
// Convert the MAC address bytes to hex (text) and then send it
|
125 |
i = 0;
|
126 |
while(1)
|
127 |
{
|
128 |
UDPPut(btohexa_high(AppConfig.MyMACAddr.v[i]));
|
129 |
UDPPut(btohexa_low(AppConfig.MyMACAddr.v[i]));
|
130 |
if(++i == 6u)
|
131 |
break;
|
132 |
UDPPut('-');
|
133 |
}
|
134 |
|
135 |
// Send some other human readable information.
|
136 |
UDPPutROMString((ROM BYTE*)"\r\nDHCP/Power event occurred");
|
137 |
|
138 |
// Send the packet
|
139 |
UDPFlush();
|
140 |
|
141 |
// Close the socket so it can be used by other modules
|
142 |
UDPClose(MySocket);
|
143 |
}
|
144 |
|
145 |
void DiscoveryTask(void)
|
146 |
{
|
147 |
static enum {
|
148 |
DISCOVERY_HOME = 0,
|
149 |
DISCOVERY_LISTEN,
|
150 |
DISCOVERY_REQUEST_RECEIVED,
|
151 |
DISCOVERY_DISABLED
|
152 |
} DiscoverySM = DISCOVERY_HOME;
|
153 |
|
154 |
static UDP_SOCKET MySocket;
|
155 |
BYTE i;
|
156 |
|
157 |
switch(DiscoverySM)
|
158 |
{
|
159 |
case DISCOVERY_HOME:
|
160 |
// Open a UDP socket for inbound and outbound transmission
|
161 |
// Since we expect to only receive broadcast packets and
|
162 |
// only send unicast packets directly to the node we last
|
163 |
// received from, the remote NodeInfo parameter can be anything
|
164 |
MySocket = UDPOpen(ANNOUNCE_PORT, NULL, ANNOUNCE_PORT);
|
165 |
|
166 |
if(MySocket == INVALID_UDP_SOCKET)
|
167 |
return;
|
168 |
else
|
169 |
DiscoverySM++;
|
170 |
break;
|
171 |
|
172 |
case DISCOVERY_LISTEN:
|
173 |
// Do nothing if no data is waiting
|
174 |
if(!UDPIsGetReady(MySocket))
|
175 |
return;
|
176 |
|
177 |
// See if this is a discovery query or reply
|
178 |
UDPGet(&i);
|
179 |
UDPDiscard();
|
180 |
if(i != 'D')
|
181 |
return;
|
182 |
|
183 |
// We received a discovery request, reply when we can
|
184 |
DiscoverySM++;
|
185 |
|
186 |
// Change the destination to the unicast address of the last received packet
|
187 |
memcpy((void*)&UDPSocketInfo[MySocket].remoteNode, (const void*)&remoteNode, sizeof(remoteNode));
|
188 |
|
189 |
// No break needed. If we get down here, we are now ready for the DISCOVERY_REQUEST_RECEIVED state
|
190 |
|
191 |
case DISCOVERY_REQUEST_RECEIVED:
|
192 |
if(!UDPIsPutReady(MySocket))
|
193 |
return;
|
194 |
|
195 |
// Begin sending our MAC address in human readable form.
|
196 |
// The MAC address theoretically could be obtained from the
|
197 |
// packet header when the computer receives our UDP packet,
|
198 |
// however, in practice, the OS will abstract away the useful
|
199 |
// information and it would be difficult to obtain. It also
|
200 |
// would be lost if this broadcast packet were forwarded by a
|
201 |
// router to a different portion of the network (note that
|
202 |
// broadcasts are normally not forwarded by routers).
|
203 |
UDPPutArray((BYTE*)AppConfig.NetBIOSName, sizeof(AppConfig.NetBIOSName)-1);
|
204 |
UDPPut('\r');
|
205 |
UDPPut('\n');
|
206 |
|
207 |
// Convert the MAC address bytes to hex (text) and then send it
|
208 |
i = 0;
|
209 |
while(1)
|
210 |
{
|
211 |
UDPPut(btohexa_high(AppConfig.MyMACAddr.v[i]));
|
212 |
UDPPut(btohexa_low(AppConfig.MyMACAddr.v[i]));
|
213 |
if(++i == 6u)
|
214 |
break;
|
215 |
UDPPut('-');
|
216 |
}
|
217 |
UDPPut('\r');
|
218 |
UDPPut('\n');
|
219 |
|
220 |
// Send the packet
|
221 |
UDPFlush();
|
222 |
|
223 |
// Listen for other discovery requests
|
224 |
DiscoverySM = DISCOVERY_LISTEN;
|
225 |
break;
|
226 |
|
227 |
case DISCOVERY_DISABLED:
|
228 |
break;
|
229 |
}
|
230 |
|
231 |
}
|
232 |
|
233 |
|
234 |
#endif //#if defined(STACK_USE_ANNOUNCE)
|