Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
363 johboh 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)