Line No. | Rev | Author | Line |
---|---|---|---|
1 | 32 | kaklik | /********************************************************************* |
2 | * |
||
3 | * Zero Confiruation (Zeroconf) IPV4 Link Local Addressing |
||
4 | * Module for Microchip TCP/IP Stack |
||
5 | * |
||
6 | ********************************************************************* |
||
7 | * FileName: ZeroconfLinkLocal.h |
||
8 | * Dependencies: IP, ARP |
||
9 | * Processor: PIC24F, PIC24H, dsPIC30F, dsPIC33F, PIC32 |
||
10 | * Compiler: Microchip C32 v1.05 or higher |
||
11 | * Microchip C30 v3.12 or higher |
||
12 | * Company: Microchip Technology, Inc. |
||
13 | * |
||
14 | * Software License Agreement |
||
15 | * |
||
16 | * Copyright (C) 2009-2010 Microchip Technology Inc. All rights |
||
17 | * reserved. |
||
18 | * |
||
19 | * Microchip licenses to you the right to use, modify, copy, and |
||
20 | * distribute: |
||
21 | * (i) the Software when embedded on a Microchip microcontroller or |
||
22 | * digital signal controller product ("Device") which is |
||
23 | * integrated into Licensee's product; or |
||
24 | * (ii) ONLY the Software driver source files ENC28J60.c, ENC28J60.h, |
||
25 | * ENCX24J600.c and ENCX24J600.h ported to a non-Microchip device |
||
26 | * used in conjunction with a Microchip ethernet controller for |
||
27 | * the sole purpose of interfacing with the ethernet controller. |
||
28 | * |
||
29 | * You should refer to the license agreement accompanying this |
||
30 | * Software for additional information regarding your rights and |
||
31 | * obligations. |
||
32 | * |
||
33 | * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT |
||
34 | * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT |
||
35 | * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A |
||
36 | * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL |
||
37 | * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR |
||
38 | * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF |
||
39 | * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS |
||
40 | * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE |
||
41 | * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER |
||
42 | * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT |
||
43 | * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE. |
||
44 | * |
||
45 | * |
||
46 | * Author Date Comment |
||
47 | *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||
48 | * Pradeep Reddy 01 Mar 2009 Initial |
||
49 | * Pradeep Reddy 12 May 2009 Enhancements and fixes |
||
50 | * Pradeep Reddy 13 May 2010 Code documentation and cleanup |
||
51 | * Brad Rex 05 Apr 2010 Updated for MRF24WB0M. |
||
52 | ********************************************************************/ |
||
53 | #define __Zeroconf__Link_Local_C |
||
54 | |||
55 | #include "TCPIP Stack/TCPIP.h" |
||
56 | |||
57 | #define TICK DWORD |
||
58 | |||
59 | #if defined(STACK_USE_ZEROCONF_LINK_LOCAL) |
||
60 | #include "TCPIP Stack/ZeroconfLinkLocal.h" |
||
61 | //#include "ZGCustomize.h" |
||
62 | |||
63 | extern void DisplayIPValue(IP_ADDR IPVal); |
||
64 | |||
65 | /* Constant to cross-check whether |
||
66 | * DHCP Clinet is configured to use */ |
||
67 | #if defined(STACK_USE_DHCP_CLIENT) |
||
68 | const BYTE g_zcll_dhcp_client = 1; |
||
69 | #else |
||
70 | const BYTE g_zcll_dhcp_client = 0; |
||
71 | #endif |
||
72 | |||
73 | /* constants from RFC2937, section 9 */ |
||
74 | #define PROBE_WAIT 1 /*second (initial random delay) */ |
||
75 | #define PROBE_MIN 1 /*second (minimum delay till repeated probe) */ |
||
76 | #define PROBE_MAX 2 /*seconds (maximum delay till repeated probe) */ |
||
77 | #define PROBE_NUM 3 /* (number of probe packets) */ |
||
78 | #define ANNOUNCE_WAIT 2 /*seconds (delay before announcing) */ |
||
79 | #define ANNOUNCE_NUM 2 /* (number of announcement packets) */ |
||
80 | #define ANNOUNCE_INTERVAL 2 /*seconds (time between announcement packets) */ |
||
81 | #define MAX_CONFLICTS 10 /* (max conflicts before rate limiting)*/ |
||
82 | #define RATE_LIMIT_INTERVAL 60 /*seconds (delay between successive attempts) */ |
||
83 | #define DEFEND_INTERVAL 10 /*seconds (min. wait between defensive ARPs) */ |
||
84 | |||
85 | /* compilation constants */ |
||
86 | #define IPV4_LLBASE 0xa9fe0100 /* 169.254.1.0 */ |
||
87 | |||
88 | /* ARP States Enum */ |
||
89 | typedef enum _ARPState{ |
||
90 | ARPProbe = 0, |
||
91 | ARPClaim, |
||
92 | ARPDefend |
||
93 | } ARP_STATE; |
||
94 | |||
95 | /* Link-Local States Enum */ |
||
96 | typedef enum _ZeroconfLLState |
||
97 | { |
||
98 | SM_INIT = 0, |
||
99 | SM_INTF_NOT_PRESENT, |
||
100 | SM_INTF_NOT_CONNECTED, |
||
101 | SM_DHCP_PRESENT, |
||
102 | SM_ADDR_INIT, |
||
103 | SM_ADDR_PROBE, |
||
104 | SM_ADDR_CLAIM, |
||
105 | SM_ADDR_DEFEND, |
||
106 | SM_ADDR_RELEASE, |
||
107 | } ZCLL_STATE; |
||
108 | |||
109 | /* Required for Tracking DHCP events */ |
||
110 | typedef enum __zcll_dhcp_substate { |
||
111 | ZCLL_DHCP_INIT = 0, |
||
112 | ZCLL_DHCP_PHASE_1, |
||
113 | ZCLL_DHCP_PHASE_2, |
||
114 | }ZCLL_DHCP_SUBSTATE; |
||
115 | |||
116 | /* ARP-Packet Types defined in RFC 2937 */ |
||
117 | typedef enum arp_pkt_type { |
||
118 | ARP_REQUEST_TYPE = 0, |
||
119 | ARP_PROBE_TYPE, |
||
120 | ARP_CLAIM_TYPE, |
||
121 | ARP_DEFEND_TYPE, |
||
122 | ARP_RESPONSE_TYPE, |
||
123 | UNKNOWN_TYPE, |
||
124 | }ARP_PKT_TYPE; |
||
125 | |||
126 | /* Flags for the ZCLL State Machine */ |
||
127 | typedef union _ZCLL_FLAGS |
||
128 | { |
||
129 | struct |
||
130 | { |
||
131 | unsigned char bIsIntfPresent : 1; // Whether or not Interface is present |
||
132 | unsigned char bIsDHCPPresent : 1; // Whether or not DHCP Client is enabled & |
||
133 | // DHCP server is detected |
||
134 | unsigned char bIsConnected : 1; // Indicates if WiFi interface is connected |
||
135 | unsigned char probe_conflict :1 ; // Conflict When selecting IP-addr |
||
136 | unsigned char late_conflict : 1; // Conflict When using IP-addr |
||
137 | } bits; |
||
138 | BYTE Val; |
||
139 | } ZCLL_FLAGS; |
||
140 | |||
141 | /**************** Global Declarations ***************/ |
||
142 | ZCLL_STATE zcll_state = SM_INIT; |
||
143 | ZCLL_DHCP_SUBSTATE zcll_dhcp_substate =ZCLL_DHCP_INIT; |
||
144 | static ZCLL_FLAGS zcll_flags = {{0x00}}; |
||
145 | |||
146 | static IP_ADDR temp_IP_addr; // Temporary IP address before checking uniquness |
||
147 | #ifdef STACK_CLIENT_MODE |
||
148 | static MAC_ADDR temp_MAC_addr; // Temporary MAC address |
||
149 | #endif |
||
150 | static BYTE probe_count = 0; |
||
151 | static BYTE conflict_count = 0; |
||
152 | static BYTE announce_count = 0; |
||
153 | |||
154 | static BOOL bDefaultIPTried = FALSE; |
||
155 | |||
156 | static CHAR arp_reg_id; |
||
157 | |||
158 | /***************** Forward Declarations **************/ |
||
159 | void ZeroconfARPPktNotify (DWORD SenderIPAddr, DWORD TargetIPAddr, |
||
160 | MAC_ADDR* SenderMACAddr, |
||
161 | MAC_ADDR* TargetMACAddr, BYTE op_req); |
||
162 | static struct arp_app_callbacks callbacks = |
||
163 | { |
||
164 | .ARPPkt_notify = ZeroconfARPPktNotify, |
||
165 | }; |
||
166 | |||
167 | //rex#if 0 |
||
168 | //rextZGVoidReturn |
||
169 | //rexZeroconfIndicate(tZGU8 type, tZGDataPtr fourByteHeader, tZGDataPtr pBuf, tZGU16 len) |
||
170 | //rex{ |
||
171 | //rex tZGU16 status; |
||
172 | //rex |
||
173 | //rex switch(type) |
||
174 | //rex { |
||
175 | //rex case kZGMgtIndDisconnect: |
||
176 | //rex /* A deauth indication occurs when the AP has announced |
||
177 | //rex * to our chip that the connection is no longer valid. It becomes |
||
178 | //rex * the responsibility of the wifiManager to determine what to do |
||
179 | //rex * in that situation */ |
||
180 | //rex INFO_ZCLL_PRINT("Zeroconf-Callback: Disconnect Event Notification \r\n"); |
||
181 | //rex zcll_flags.bits.bIsConnected = 0; |
||
182 | //rex break; |
||
183 | //rex |
||
184 | //rex case kZGMgtIndConnStatus: |
||
185 | //rex |
||
186 | //rex status = (fourByteHeader[0] << 8) | fourByteHeader[1]; |
||
187 | //rex if (status == kZGConnStatusFound) |
||
188 | //rex { |
||
189 | //rex //APPCXT.bConnLost = 0; |
||
190 | //rex //APPCXT.bConnFound = 1; |
||
191 | //rex zcll_flags.bits.bIsConnected = 1; |
||
192 | //rex } |
||
193 | //rex break; |
||
194 | //rex |
||
195 | //rex default: |
||
196 | //rex /* error condition un-recognized type */ |
||
197 | //rex break; |
||
198 | //rex } |
||
199 | //rex |
||
200 | //rex} |
||
201 | //rex#endif |
||
202 | |||
203 | DWORD zcll_rand(void) |
||
204 | { |
||
205 | return TickGet(); |
||
206 | } |
||
207 | |||
208 | /*************************************************************** |
||
209 | Function: |
||
210 | static void ZeroconfStateMachineReset(void) |
||
211 | |||
212 | Summary: |
||
213 | Resets Zeroconf's Link-Local state-machine |
||
214 | |||
215 | Description: |
||
216 | This function resets the state-machine of Link-Local module. |
||
217 | This is invoked in the initalization and when a address-conflict |
||
218 | is detected. |
||
219 | |||
220 | Parameters: |
||
221 | None |
||
222 | |||
223 | Returns: |
||
224 | None |
||
225 | ***************************************************************/ |
||
226 | #if 0 |
||
227 | #define ZeroconfStateMachineReset() \ |
||
228 | {probe_count = zcll_flags.bits.late_conflict = zcll_flags.bits.probe_conflict =0;} |
||
229 | #endif |
||
230 | |||
231 | static void ZeroconfStateMachineReset(BOOL bResetProbeCount) |
||
232 | { |
||
233 | if (bResetProbeCount) |
||
234 | { |
||
235 | probe_count = 0; |
||
236 | } |
||
237 | zcll_flags.bits.late_conflict = 0; |
||
238 | |||
239 | //conflict_count = 0; |
||
240 | //zcll_flags.bits.probe_conflict = 0; |
||
241 | } |
||
242 | |||
243 | |||
244 | /*************************************************************** |
||
245 | Function: |
||
246 | void ARPAction(IP_ADDR SrcIPAddr,IP_ADDR DestIPAddr ,BYTE op_req,ARP_STATE ARPAction) |
||
247 | |||
248 | Summary: |
||
249 | a).ARPProbe: |
||
250 | Sends out the ARP-probe packet. |
||
251 | b).ARPClaim: |
||
252 | Sends out the ARP-Claim packet. |
||
253 | c).ARPDefend: |
||
254 | Sends out the ARP-Defend packet, when a address-conflict is detected. |
||
255 | |||
256 | Description: |
||
257 | |||
258 | |||
259 | a).ARPProbe: |
||
260 | This function is used to send out the ARP-Probe packet to check |
||
261 | the uniquness of selected IP-address in private space(169.254.x.x) |
||
262 | |||
263 | This function makes use of ARPSendPkt User-API exposed by ARP |
||
264 | module. |
||
265 | |||
266 | ARP-Probe Packet: |
||
267 | ARP-Request |
||
268 | sender IP address: 0.0.0.0 |
||
269 | sender HW address: Self MAC address |
||
270 | target IP address: <probe addr> (Chosen IP-address 169.254.x.x) |
||
271 | target HW address: FF:FF:FF:FF:FF:FF |
||
272 | |||
273 | b).ARPClaim: |
||
274 | This function is used to send out the ARP-Claim packet to finalize |
||
275 | the uniquness of selected IP-address in private space(169.254.x.x). |
||
276 | This claim packet is final-step in decision making of selected IP- |
||
277 | address. |
||
278 | |||
279 | This function makes use of ARPSendPkt User-API exposed by ARP |
||
280 | module. |
||
281 | |||
282 | ARP-Probe Packet: |
||
283 | ARP-Request |
||
284 | sender IP address: <claim addr> (Chosen IP-address 169.254.x.x) |
||
285 | sender HW address: Self MAC address |
||
286 | target IP address: <claim addr> (Chosen IP-address 169.254.x.x) |
||
287 | target HW address: FF:FF:FF:FF:FF:FF |
||
288 | |||
289 | c).ARPDefend: |
||
290 | This function is used to send out the ARP-Defend packet to defend |
||
291 | the selected IP-address. When a conflicting ARP-packet (Probe or |
||
292 | Claim) is observed on local network ARP-defend packet will be sent |
||
293 | out to announe its authority of owning IP-address. |
||
294 | |||
295 | This function makes use of ARPSendPkt User-API exposed by ARP |
||
296 | module. |
||
297 | |||
298 | ARP-Probe Packet: |
||
299 | ARP-Response |
||
300 | sender IP address: <claim addr> (Chosen IP-address 169.254.x.x) |
||
301 | sender HW address: Self MAC address |
||
302 | target IP address: <claim addr> (Chosen IP-address 169.254.x.x) |
||
303 | target HW address: FF:FF:FF:FF:FF:FF |
||
304 | |||
305 | Parameters: |
||
306 | None |
||
307 | |||
308 | Returns: |
||
309 | None |
||
310 | ***************************************************************/ |
||
311 | |||
312 | void ARPAction(DWORD SrcIPAddr,DWORD DestIPAddr ,BYTE op_req,ARP_STATE ARPAction) |
||
313 | { |
||
314 | BOOL rc; |
||
315 | |||
316 | rc = ARPSendPkt( SrcIPAddr, DestIPAddr,op_req); |
||
317 | |||
318 | #if defined ( INFO_ZCLL ) |
||
319 | if(rc == FALSE) |
||
320 | { |
||
321 | switch (ARPAction) |
||
322 | { |
||
323 | case ARPProbe: |
||
324 | INFO_ZCLL_PRINT("ARPProbe: Error in sending out ARP-Probe pkt \n"); |
||
325 | break; |
||
326 | case ARPClaim: |
||
327 | INFO_ZCLL_PRINT("ARPClaim: Error in sending out ARP-Claim pkt \n"); |
||
328 | break; |
||
329 | case ARPDefend: |
||
330 | INFO_ZCLL_PRINT("ARPDefend: Error in sending out ARP-Defend pkt \n"); |
||
331 | break; |
||
332 | } |
||
333 | } |
||
334 | #endif |
||
335 | } |
||
336 | |||
337 | /*************************************************************** |
||
338 | Function: |
||
339 | ARP_PKT_TYPE FindARPPktType (DWORD SrcIPAddr, DWORD DestIPAddr, |
||
340 | BYTE op_req) |
||
341 | |||
342 | Summary: |
||
343 | Finds the Type of ARP-Packet based on the Source IP-address, |
||
344 | Destination IP-address and operation-request. |
||
345 | |||
346 | Description: |
||
347 | This function is used to find out the ARP-packet type. When ARP |
||
348 | module passes up a ARP-packet to Zeroconf Link-Local module, it |
||
349 | parses contents and finds the packet-type (like ARP-Probe, ARP- |
||
350 | Claim, ARP-Defend, or generic ARP-request/response) |
||
351 | |||
352 | Parameters: |
||
353 | SrcIPAddr - Source IP-Address |
||
354 | DestIPAddr - Destination IP-Address |
||
355 | op_req - Operation-Request (ARP-Request/Response) |
||
356 | |||
357 | Returns: |
||
358 | ARP_PKT_TYPE - Type of ARP-Packet (Probe, Claim, Defend or |
||
359 | generic ARP-request/response) |
||
360 | ***************************************************************/ |
||
361 | ARP_PKT_TYPE FindARPPktType (DWORD SrcIPAddr, DWORD DestIPAddr,BYTE op_req) |
||
362 | { |
||
363 | if(op_req == ARP_REQ) |
||
364 | { |
||
365 | if(SrcIPAddr == 0x0) |
||
366 | return ARP_PROBE_TYPE; |
||
367 | else if (SrcIPAddr == DestIPAddr) |
||
368 | return ARP_CLAIM_TYPE; |
||
369 | else |
||
370 | return ARP_REQUEST_TYPE; |
||
371 | |||
372 | } |
||
373 | |||
374 | else if(op_req == ARP_RESP) |
||
375 | { |
||
376 | if(SrcIPAddr == DestIPAddr) |
||
377 | return ARP_DEFEND_TYPE; |
||
378 | else |
||
379 | return ARP_RESPONSE_TYPE; |
||
380 | } |
||
381 | |||
382 | else |
||
383 | return UNKNOWN_TYPE; |
||
384 | } |
||
385 | |||
386 | /*************************************************************** |
||
387 | Function: |
||
388 | void ZeroconfARPPktNotify (DWORD SenderIPAddr, DWORD TargetIPAddr, |
||
389 | MAC_ADDR* SenderMACAddr, |
||
390 | MAC_ADDR* TargetMACAddr, BYTE op_req) |
||
391 | |||
392 | Summary: |
||
393 | Callback registered with ARP-Module. This gets invoked from ARP- |
||
394 | module and runs in the same context. |
||
395 | |||
396 | Description: |
||
397 | This function is registered as a callback with ARP-module to get |
||
398 | notified about incoming Packet-events. Based on the type of packet |
||
399 | received and Link-Local current state, appropriate action will be |
||
400 | taken. To find the type of ARP-Packet this function makes use of |
||
401 | FindARPPktType routine. |
||
402 | |||
403 | Primary purpose of this function is to decipher the ARP-Packet rxed |
||
404 | and check whether its leading to a conflict with the selected IP- |
||
405 | address. |
||
406 | |||
407 | Two types of conflicts are defined: Probe-Conflict and Late-Conflict |
||
408 | If the current state of Link-Local is Probe/Claim and a conflict is |
||
409 | detected its called "Probe-Conflict" |
||
410 | If the current state of Link-Local is Defend-state and a conflict is |
||
411 | detected its called "Late-Conflict" |
||
412 | |||
413 | Parameters: |
||
414 | SenderIPAddr - Sender IP-Address |
||
415 | TargetIPAddr - Target IP-Address |
||
416 | SenderMACAddr - Sender MAC-Address |
||
417 | TargetMACAddr - Target MAC-Address |
||
418 | op_req - Operation-Request (ARP-Request/Response) |
||
419 | |||
420 | Returns: |
||
421 | None |
||
422 | ***************************************************************/ |
||
423 | void ZeroconfARPPktNotify (DWORD SenderIPAddr, DWORD TargetIPAddr, |
||
424 | MAC_ADDR* SenderMACAddr, |
||
425 | MAC_ADDR* TargetMACAddr, BYTE op_req) |
||
426 | { |
||
427 | ARP_PKT_TYPE pkt_type; |
||
428 | |||
429 | pkt_type = FindARPPktType (SenderIPAddr, TargetIPAddr, op_req); |
||
430 | |||
431 | if(pkt_type == UNKNOWN_TYPE) |
||
432 | return; // Can't hit this |
||
433 | |||
434 | switch (zcll_state) |
||
435 | { |
||
436 | case SM_ADDR_PROBE: |
||
437 | case SM_ADDR_CLAIM: |
||
438 | { |
||
439 | switch(pkt_type) |
||
440 | { |
||
441 | case ARP_PROBE_TYPE: |
||
442 | case ARP_CLAIM_TYPE: |
||
443 | case ARP_DEFEND_TYPE: |
||
444 | if(temp_IP_addr.Val == TargetIPAddr ) // Probe-Conflict |
||
445 | { |
||
446 | if(memcmp(SenderMACAddr, &AppConfig.MyMACAddr, 6)) |
||
447 | { |
||
448 | DEBUG_ZCLL_PRINT("ARPPktNotify: Somebody has initiated " \ |
||
449 | "the procedure to use same Addr.\r\n"); |
||
450 | |||
451 | zcll_flags.bits.probe_conflict =1; |
||
452 | } |
||
453 | } |
||
454 | break; |
||
455 | |||
456 | case ARP_RESPONSE_TYPE: |
||
457 | /* Some-body has been using probed addr |
||
458 | * We need to choose different Address */ |
||
459 | if(temp_IP_addr.Val == SenderIPAddr) |
||
460 | { |
||
461 | DEBUG_ZCLL_PRINT("ARPPktNotify: Some-body has responded for " \ |
||
462 | "probed IP-addr \r\n"); |
||
463 | |||
464 | zcll_flags.bits.probe_conflict =1; |
||
465 | } |
||
466 | break; |
||
467 | default: |
||
468 | break; |
||
469 | } |
||
470 | } |
||
471 | break; |
||
472 | |||
473 | case SM_ADDR_DEFEND: |
||
474 | { |
||
475 | if(AppConfig.MyIPAddr.Val == SenderIPAddr) |
||
476 | { |
||
477 | if(memcmp(SenderMACAddr, &AppConfig.MyMACAddr, 6)) |
||
478 | { |
||
479 | DEBUG_ZCLL_PRINT("ARPPktNotify: Some-one has started using" \ |
||
480 | " our IP-address \r\n"); |
||
481 | |||
482 | zcll_flags.bits.late_conflict = 1; |
||
483 | } |
||
484 | } |
||
485 | } |
||
486 | break; |
||
487 | |||
488 | default: |
||
489 | break; // Nothing to do in other states |
||
490 | } |
||
491 | |||
492 | } |
||
493 | |||
494 | /*************************************************************** |
||
495 | Function: |
||
496 | static void zcll_seed_random() |
||
497 | |||
498 | Summary: |
||
499 | Seeds the Random-Number generator with Last four bytes of MAC- |
||
500 | address & current-time. |
||
501 | |||
502 | Description: |
||
503 | This function is used to seed the random-number generator. To get |
||
504 | better uniquness in random-number, last four bytes of MAC-address |
||
505 | is used as seed. Though the MAC-address is unique, the first 3 |
||
506 | bytes represent the manufacturer, which will be same for all the |
||
507 | Network-Interface cards from same manufacturer. |
||
508 | |||
509 | To add more randomness the current-time is also added as seed. The |
||
510 | current-time alone can't be used as seed. Because there's a fair |
||
511 | chance that all the devices in local-area network might be powered |
||
512 | up at the same-time, then which leads to conflict. |
||
513 | |||
514 | So combination of MAC-Address and current-time is good seed for a |
||
515 | random-number generator. |
||
516 | |||
517 | Parameters: |
||
518 | None |
||
519 | |||
520 | Returns: |
||
521 | None |
||
522 | ***************************************************************/ |
||
523 | #if 0 |
||
524 | static void zcll_seed_random() |
||
525 | { |
||
526 | DWORD_VAL temp; |
||
527 | DWORD tick = TickGet(); |
||
528 | temp.v[3] = AppConfig.MyMACAddr.v[2]; |
||
529 | temp.v[2] = AppConfig.MyMACAddr.v[3]; |
||
530 | temp.v[1] = AppConfig.MyMACAddr.v[4]; |
||
531 | temp.v[0] = AppConfig.MyMACAddr.v[5]; |
||
532 | srand( temp.Val + tick ); |
||
533 | } |
||
534 | #endif |
||
535 | |||
536 | /*************************************************************** |
||
537 | Function: |
||
538 | void ZeroconfLLInitialize(void) |
||
539 | |||
540 | Summary: |
||
541 | Initialization routine for Zeroconf Link-Local state-machine. |
||
542 | |||
543 | Description: |
||
544 | This is initialization function for Zeroconf Link-Local and |
||
545 | invoked from initialization portion of Main-function. |
||
546 | |||
547 | This function registers with ARP-module to get notifications |
||
548 | about the incoming packets. Checks whether the WiFi MAC is |
||
549 | connected to an Access-Point or not. |
||
550 | |||
551 | Parameters: |
||
552 | None |
||
553 | |||
554 | Returns: |
||
555 | None |
||
556 | ***************************************************************/ |
||
557 | void ZeroconfLLInitialize(void) |
||
558 | { |
||
559 | /* ARP is core module for IPv4 LL protocol. |
||
560 | * Register event callbacks with ARP, to get |
||
561 | * notified. */ |
||
562 | arp_reg_id = ARPRegisterCallbacks(&callbacks); |
||
563 | if(arp_reg_id <0) |
||
564 | { |
||
565 | WARN_ZCLL_PRINT("ZeroconfLLInitialize: ARP Callback registration Failed!!! \r\n"); |
||
566 | return; |
||
567 | } |
||
568 | |||
569 | /* Check for the presence of Interface |
||
570 | * Currently there's no way to check the |
||
571 | * presence of interface. So always true. |
||
572 | * Later it needs to replaced by actual |
||
573 | * condition */ |
||
574 | if(0) |
||
575 | { |
||
576 | zcll_state = SM_INTF_NOT_PRESENT; |
||
577 | return; |
||
578 | } |
||
579 | |||
580 | if(!MACIsLinked()) |
||
581 | { |
||
582 | zcll_state = SM_INTF_NOT_CONNECTED; |
||
583 | return; |
||
584 | } |
||
585 | |||
586 | /* check if DHCP-Client is enabled & able to detect DHCP-Server */ |
||
587 | if(g_zcll_dhcp_client) |
||
588 | { |
||
589 | zcll_state = SM_DHCP_PRESENT; |
||
590 | zcll_dhcp_substate = ZCLL_DHCP_INIT; |
||
591 | return; |
||
592 | |||
593 | } |
||
594 | |||
595 | zcll_state = SM_ADDR_INIT; |
||
596 | /* setup random number generator |
||
597 | * we key this off the MAC-48 HW identifier |
||
598 | * the first 3 octets are the manufacturer |
||
599 | * the next 3 the serial number |
||
600 | * we'll use the last four for the largest variety |
||
601 | */ |
||
602 | //zcll_seed_random(); |
||
603 | |||
604 | return; |
||
605 | } |
||
606 | |||
607 | /*************************************************************** |
||
608 | Function: |
||
609 | void ZeroconfLLProcess(void) |
||
610 | |||
611 | Summary: |
||
612 | Initialization routine for Zeroconf Link-Local state-machine. |
||
613 | |||
614 | Description: |
||
615 | This is Polled from Main-Application & Designed to support |
||
616 | co-operative multi-tasking. This needs to retrun to Main, |
||
617 | if we have to wait for Longer durations. |
||
618 | |||
619 | This is the main function for Zeroconf's Link-Local and takes |
||
620 | the actions accoding to current-state and event-notifications |
||
621 | from ARP-Module. |
||
622 | |||
623 | Parameters: |
||
624 | None |
||
625 | |||
626 | Returns: |
||
627 | None |
||
628 | ***************************************************************/ |
||
629 | |||
630 | |||
631 | void ZeroconfLLProcess(void) |
||
632 | { |
||
633 | static TICK event_time; // Internal Timer, to keep track of events |
||
634 | static unsigned char time_recorded; // Flag to indicate event_time is loaded |
||
635 | static unsigned char defended; // Flag to indicate, whether or not defended earlier |
||
636 | static TICK random_delay; |
||
637 | |||
638 | if(!MACIsLinked()) |
||
639 | { |
||
640 | zcll_state = SM_INTF_NOT_CONNECTED; |
||
641 | } |
||
642 | |||
643 | switch(zcll_state) |
||
644 | { |
||
645 | case SM_INIT: |
||
646 | WARN_ZCLL_PRINT("SM_INIT: Wrong state \r\n"); |
||
647 | break; |
||
648 | |||
649 | case SM_INTF_NOT_PRESENT: |
||
650 | DEBUG_ZCLL_PRINT("SM_INTF_NOT_PRESENT: Intf not detected \r\n"); |
||
651 | break; |
||
652 | |||
653 | case SM_INTF_NOT_CONNECTED: |
||
654 | |||
655 | //DEBUG_ZCLL_MESG(zeroconf_dbg_msg,"SM_INTF_NOT_CONNECTED \r\n"); |
||
656 | //DEBUG_ZCLL_PRINT((char*)zeroconf_dbg_msg); |
||
657 | |||
658 | if(!MACIsLinked()) |
||
659 | { |
||
660 | //INFO_ZCLL_PRINT((char *)("MAC is not connected yet \r\n")); |
||
661 | return; |
||
662 | } |
||
663 | else |
||
664 | { |
||
665 | /* Interface is connected now */ |
||
666 | zcll_state = SM_DHCP_PRESENT; |
||
667 | zcll_dhcp_substate = ZCLL_DHCP_INIT; |
||
668 | time_recorded = 0; |
||
669 | event_time = 0; |
||
670 | defended = 0; |
||
671 | } |
||
672 | |||
673 | case SM_DHCP_PRESENT: |
||
674 | { |
||
675 | //DEBUG_ZCLL_PRINT("SM_INTF_DHCP_PRESENT \r\n"); |
||
676 | |||
677 | if(!g_zcll_dhcp_client) |
||
678 | { |
||
679 | zcll_state = SM_ADDR_INIT; |
||
680 | } |
||
681 | #if defined(STACK_USE_DHCP_CLIENT) |
||
682 | else |
||
683 | { |
||
684 | |||
685 | switch(zcll_dhcp_substate) |
||
686 | { |
||
687 | case ZCLL_DHCP_INIT: |
||
688 | |||
689 | DEBUG_ZCLL_PRINT("ZCLL_DHCP_INIT: Entered \r\n"); |
||
690 | DEBUG_ZCLL_MESG((char *) zeroconf_dbg_msg,"TICKS_PER_SECOND = %ld \r\n", |
||
691 | ((TICK) (TICKS_PER_SECOND))); |
||
692 | DEBUG_ZCLL_PRINT((char *) zeroconf_dbg_msg); |
||
693 | if(!AppConfig.Flags.bIsDHCPEnabled) |
||
694 | { |
||
695 | DEBUG_ZCLL_PRINT("ZCLL_DHCP_INIT: Enabling DHCP client \r\n"); |
||
696 | DHCPEnable((BYTE) 0); //DHCPEnable(); |
||
697 | time_recorded = 0; |
||
698 | } |
||
699 | /* Start a Fisrt-phase Timer with 1 min Timeout |
||
700 | * to allow DHCP-client to IP-address DHCP-ser */ |
||
701 | |||
702 | AppConfig.MyIPAddr.Val = 0; |
||
703 | |||
704 | event_time = TickGet(); |
||
705 | time_recorded = 1; |
||
706 | random_delay = (TICK) (ZEROCONF_LINK_LOCAL_DHCP_TIMEOUT * \ |
||
707 | TICK_SECOND ); |
||
708 | zcll_dhcp_substate = ZCLL_DHCP_PHASE_1; |
||
709 | INFO_ZCLL_PRINT("Waiting for DHCP-Client to Get IP-addr from" \ |
||
710 | " DHCP-server..... \r\n"); |
||
711 | |||
712 | return; |
||
713 | |||
714 | case ZCLL_DHCP_PHASE_1: |
||
715 | |||
716 | if(time_recorded) |
||
717 | { |
||
718 | if(TickGet() - event_time < random_delay) |
||
719 | { |
||
720 | //if(DHCPFlags.bits.bDHCPServerDetected && |
||
721 | // DHCPFlags.bits.bIsBound) |
||
722 | if (DHCPIsServerDetected((BYTE) 0) && |
||
723 | DHCPIsBound((BYTE) 0)) |
||
724 | { |
||
725 | INFO_ZCLL_PRINT("DHCP IP-address received. No Zeroconf " \ |
||
726 | "Link-Local required !! \r\n"); |
||
727 | INFO_ZCLL_MESG(zeroconf_dbg_msg,"DHCP IP-Addr: " \ |
||
728 | "%d.%d.%d.%d \r\n", |
||
729 | AppConfig.MyIPAddr.v[0], |
||
730 | AppConfig.MyIPAddr.v[1], |
||
731 | AppConfig.MyIPAddr.v[2], |
||
732 | AppConfig.MyIPAddr.v[3]); |
||
733 | INFO_ZCLL_PRINT((char *)zeroconf_dbg_msg); |
||
734 | DisplayIPValue(AppConfig.MyIPAddr); // LCD Disaply |
||
735 | |||
736 | time_recorded = 0; // Cancel Timer |
||
737 | zcll_dhcp_substate = ZCLL_DHCP_PHASE_2; |
||
738 | return; |
||
739 | |||
740 | } |
||
741 | return; |
||
742 | } |
||
743 | // First Time out. Disable DHCP & Use Link-Local |
||
744 | time_recorded = 0; // Reset Timer Flag |
||
745 | event_time = 0; // Cancel Timer |
||
746 | |||
747 | break; |
||
748 | } |
||
749 | else |
||
750 | { |
||
751 | DEBUG_ZCLL_PRINT("ERROR !! Can't Enter this DHCP " \ |
||
752 | "Substate without timer \r\n"); |
||
753 | break; |
||
754 | } |
||
755 | |||
756 | case ZCLL_DHCP_PHASE_2: |
||
757 | |||
758 | /* Able to get an IP-address from DHCP, |
||
759 | * constantly moniotor for Validity. If |
||
760 | * found invalid, move back to phase-1. */ |
||
761 | |||
762 | //if( DHCPFlags.bits.bIsBound) |
||
763 | if (DHCPIsBound((BYTE) 0)) |
||
764 | { |
||
765 | return; |
||
766 | } |
||
767 | else |
||
768 | { |
||
769 | if(!AppConfig.Flags.bIsDHCPEnabled) |
||
770 | { |
||
771 | /* Somebody else had disabled DHCP client. |
||
772 | * Goto Link-Local addressing */ |
||
773 | DEBUG_ZCLL_PRINT("ZCLL_DHCP_PHASE_2: Externel module " \ |
||
774 | "disabled DHCP-Client \r\n"); |
||
775 | break; |
||
776 | } |
||
777 | |||
778 | temp_IP_addr.Val = 0x0; |
||
779 | time_recorded = 0; |
||
780 | zcll_dhcp_substate = ZCLL_DHCP_INIT; |
||
781 | return; |
||
782 | } |
||
783 | |||
784 | default: |
||
785 | |||
786 | DEBUG_ZCLL_PRINT("ERROR !! Invalid DHCP Substate \r\n"); |
||
787 | break; |
||
788 | } |
||
789 | } |
||
790 | |||
791 | // No break. Fall through |
||
792 | |||
793 | // The following is commented out, to implement the behavior described in |
||
794 | // RFC 3927, section 2.11. |
||
795 | // In particular, IPv4LL should not "stop the DHCP client from attempting |
||
796 | // to acquire a new IP address". |
||
797 | |||
798 | #if defined(DISREGARD_RFC3927_SECTION_2_11) |
||
799 | /* Disable DHCP Client, as it's not able to get an IP */ |
||
800 | INFO_ZCLL_PRINT("Disabling DHCP-Client. Going to use Link-Local \r\n"); |
||
801 | DHCPDisable((BYTE) 0); |
||
802 | #endif |
||
803 | |||
804 | #else |
||
805 | INFO_ZCLL_PRINT("DHCP-Client is not present. Going to use Link-Local \r\n"); |
||
806 | #endif |
||
807 | zcll_state = SM_ADDR_INIT; |
||
808 | /* Not yet seeded in init routine */ |
||
809 | /* setup random number generator |
||
810 | * we key this off the MAC-48 HW identifier |
||
811 | * the first 3 octets are the manufacturer |
||
812 | * the next 3 the serial number |
||
813 | * we'll use the last four for the largest variety |
||
814 | */ |
||
815 | //zcll_seed_random(); |
||
816 | DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"SM_DHCP_PRESENT --> SM_ADDR_INIT \r\n"); |
||
817 | DEBUG0_ZCLL_PRINT((char*)zeroconf_dbg_msg); |
||
818 | |||
819 | // No break. Fall through |
||
820 | } |
||
821 | |||
822 | case SM_ADDR_INIT: |
||
823 | |||
824 | ZeroconfStateMachineReset(FALSE); |
||
825 | conflict_count = 0; |
||
826 | AppConfig.MyIPAddr.Val = 0x0; |
||
827 | DisplayIPValue(AppConfig.MyIPAddr); // LCD Display |
||
828 | |||
829 | #ifdef STACK_CLIENT_MODE |
||
830 | ARPInit(); |
||
831 | #endif |
||
832 | probe_count = 0; |
||
833 | |||
834 | zcll_state = SM_ADDR_PROBE; |
||
835 | INFO_ZCLL_PRINT("ADDR_INIT --> ADDR_PROBE \r\n"); |
||
836 | |||
837 | // No break. Fall through |
||
838 | |||
839 | case SM_ADDR_PROBE: |
||
840 | |||
841 | //DEBUG_ZCLL_PRINT("SM_ADDR_PROBE \r\n"); |
||
842 | |||
843 | switch ( zgzc_wait_for(&random_delay, &event_time, &time_recorded) ) |
||
844 | { |
||
845 | case ZGZC_STARTED_WAITING: |
||
846 | |||
847 | if (probe_count == 0) |
||
848 | { |
||
849 | // First probe. Wait for [0 ~ PROBE_WAIT] seconds before sending the probe. |
||
850 | |||
851 | //random_delay = (TICK)(((zcll_rand()) % (PROBE_WAIT) * TICK_SECOND)); |
||
852 | //if (random_delay == 0) random_delay = (TICK) TICK_SECOND; |
||
853 | |||
854 | random_delay = (TICK) (zcll_rand() % (PROBE_WAIT * TICK_SECOND)); |
||
855 | |||
856 | DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"PROBE_WAIT Random Delay [%d]: %ld secs \r\n", |
||
857 | probe_count, |
||
858 | random_delay); |
||
859 | } |
||
860 | else if (probe_count < PROBE_NUM) |
||
861 | { |
||
862 | // Subsequent probes. Wait for [PROBE_MIN ~ PROBE_MAX] seconds before sending the probe. |
||
863 | |||
864 | // random_delay = (TICK) ( (((zcll_rand() % (PROBE_MAX-PROBE_MIN+1))+PROBE_MIN) * TICKS_PER_SECOND) + (TICKS_PER_SECOND>>3) ); |
||
865 | // Added a little bit more delay to pass conformance test. |
||
866 | |||
867 | random_delay = (TICK) ( (zcll_rand() % ((PROBE_MAX-PROBE_MIN) * TICKS_PER_SECOND) ) + |
||
868 | (PROBE_MIN * TICKS_PER_SECOND) ); |
||
869 | |||
870 | DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"PROBE Random Delay [%d]: %ld ticks \r\n", |
||
871 | probe_count, |
||
872 | random_delay); |
||
873 | } |
||
874 | else |
||
875 | { |
||
876 | // Completed PROBE_NUM of probes. Now wait for ANNOUNCE_WAIT seconds to determine if |
||
877 | // we can claim it. |
||
878 | |||
879 | random_delay = (TICK) (ANNOUNCE_WAIT * TICK_SECOND); |
||
880 | DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"ANNOUNCE_WAIT delay [%d]: %ld ticks\r\n", |
||
881 | probe_count, |
||
882 | random_delay /*TICK_SECOND */); |
||
883 | } |
||
884 | |||
885 | DEBUG0_ZCLL_PRINT((char*)zeroconf_dbg_msg); |
||
886 | |||
887 | // Intentional fall-through |
||
888 | |||
889 | case ZGZC_KEEP_WAITING: |
||
890 | |||
891 | // Not Completed the delay proposed |
||
892 | return; |
||
893 | } |
||
894 | |||
895 | // Completed the delay required |
||
896 | |||
897 | DEBUG0_ZCLL_MESG(zeroconf_dbg_msg," delay: %ld ticks " \ |
||
898 | "completed \r\n", random_delay); |
||
899 | DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg); |
||
900 | |||
901 | if(zcll_flags.bits.probe_conflict) |
||
902 | { |
||
903 | /* Conflict with selected address */ |
||
904 | INFO_ZCLL_PRINT("Probe Conflict-1 Detected. Need to select diff addr \r\n"); |
||
905 | ZeroconfStateMachineReset(FALSE); |
||
906 | temp_IP_addr.Val = 0x0; |
||
907 | |||
908 | conflict_count++; |
||
909 | AppConfig.MyIPAddr.Val = 0x0; |
||
910 | } |
||
911 | #ifdef STACK_CLIENT_MODE |
||
912 | else if((conflict_count == 0) && temp_IP_addr.Val && (ARPIsResolved(&temp_IP_addr, &temp_MAC_addr)) ) |
||
913 | { |
||
914 | if(!memcmp (&temp_MAC_addr, &AppConfig.MyMACAddr, 6) ) |
||
915 | { |
||
916 | DEBUG0_ZCLL_PRINT("SM_ADDR_PROBE: Resolved with our address only. " \ |
||
917 | "Rare Case !!!! \r\n"); |
||
918 | } |
||
919 | else |
||
920 | { |
||
921 | /* Conflict with selected address */ |
||
922 | INFO_ZCLL_PRINT("Probe Conflict-2 Detected. Need to select diff addr \r\n"); |
||
923 | ZeroconfStateMachineReset(FALSE); |
||
924 | temp_IP_addr.Val = 0x0; |
||
925 | |||
926 | conflict_count++; |
||
927 | AppConfig.MyIPAddr.Val = 0x0; |
||
928 | } |
||
929 | } |
||
930 | #endif |
||
931 | |||
932 | if ((zcll_flags.bits.probe_conflict == 1) || |
||
933 | (!bDefaultIPTried)) |
||
934 | { |
||
935 | /* |
||
936 | * Pick random IP address in IPv4 link-local range |
||
937 | * 169.254.1.0/16 is the allowed address range however |
||
938 | * 169.254.0.0/24 and 169.254.255.0/24 must be excluded, |
||
939 | * which removes 512 address from our 65535 candidates. |
||
940 | * That leaves us with 65023 (0xfdff) |
||
941 | */ |
||
942 | |||
943 | // Need to start/restart the probe procedure. |
||
944 | probe_count = 0; |
||
945 | |||
946 | if ((!bDefaultIPTried) && |
||
947 | (AppConfig.DefaultIPAddr.v[0] == 169) && |
||
948 | (AppConfig.DefaultIPAddr.v[1] == 254) && |
||
949 | (AppConfig.DefaultIPAddr.v[2] != 0) && |
||
950 | (AppConfig.DefaultIPAddr.v[2] != 255)) |
||
951 | { |
||
952 | // First probe, and the default IP is a valid IPv4LL address. |
||
953 | // Use it. |
||
954 | |||
955 | temp_IP_addr.Val = swapl(AppConfig.DefaultIPAddr.Val); |
||
956 | bDefaultIPTried = TRUE; |
||
957 | } |
||
958 | else |
||
959 | { |
||
960 | temp_IP_addr.Val = (IPV4_LLBASE | ((abs(zcll_rand()) % 0xfdff) )); |
||
961 | } |
||
962 | |||
963 | INFO_ZCLL_MESG(zeroconf_dbg_msg,"Picked IP-Addr [%d]: %d.%d.%d.%d \r\n", |
||
964 | probe_count, |
||
965 | temp_IP_addr.v[3],temp_IP_addr.v[2], |
||
966 | temp_IP_addr.v[1],temp_IP_addr.v[0]); |
||
967 | INFO_ZCLL_PRINT((char *)zeroconf_dbg_msg); |
||
968 | |||
969 | temp_IP_addr.Val = swapl((DWORD) temp_IP_addr.Val); |
||
970 | } |
||
971 | |||
972 | // ToDo: check the max probe limit and probing rate |
||
973 | if((zcll_flags.bits.probe_conflict == 1) || (probe_count < PROBE_NUM)) |
||
974 | { |
||
975 | |||
976 | zcll_flags.bits.probe_conflict = 0; |
||
977 | ARPAction(AppConfig.MyIPAddr.Val, temp_IP_addr.Val, ARP_REQ,ARPProbe); |
||
978 | probe_count++; |
||
979 | |||
980 | DEBUG0_ZCLL_MESG(zeroconf_dbg_msg, "Sending ARP [%d]\r\n", probe_count); |
||
981 | DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg); |
||
982 | |||
983 | break; |
||
984 | } |
||
985 | |||
986 | // No conflict detected ... |
||
987 | |||
988 | if(probe_count >= PROBE_NUM) |
||
989 | { |
||
990 | zcll_state = SM_ADDR_CLAIM; |
||
991 | announce_count = 0; |
||
992 | |||
993 | INFO_ZCLL_PRINT("ADDR_PROBE --> ADDR_CLAIM \r\n"); |
||
994 | |||
995 | return; |
||
996 | } |
||
997 | |||
998 | break; |
||
999 | |||
1000 | case SM_ADDR_CLAIM: |
||
1001 | |||
1002 | switch ( zgzc_wait_for(&random_delay, &event_time, &time_recorded) ) |
||
1003 | { |
||
1004 | case ZGZC_STARTED_WAITING: |
||
1005 | if (announce_count == 0) |
||
1006 | { |
||
1007 | // First announcement is immediate. We have passed the ANNOUNCE_WAIT in |
||
1008 | // PROBE state already. |
||
1009 | |||
1010 | random_delay = 0; |
||
1011 | } |
||
1012 | else |
||
1013 | { |
||
1014 | // Subsequent announcements need to wait ANNOUNCE_INTERVAL seconds |
||
1015 | // before sending the announcement. |
||
1016 | |||
1017 | random_delay = (TICK)(ANNOUNCE_INTERVAL * TICK_SECOND); |
||
1018 | } |
||
1019 | // Intentional fall-through |
||
1020 | |||
1021 | case ZGZC_KEEP_WAITING: |
||
1022 | |||
1023 | // Not Completed the delay proposed |
||
1024 | return; |
||
1025 | } |
||
1026 | |||
1027 | // Completed the delay required |
||
1028 | |||
1029 | DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"ANNOUNCE delay: %ld ticks completed \r\n", random_delay); |
||
1030 | DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg); |
||
1031 | |||
1032 | if ( announce_count < ANNOUNCE_NUM ) |
||
1033 | { |
||
1034 | ARPAction(temp_IP_addr.Val,temp_IP_addr.Val,ARP_REQ,ARPClaim); |
||
1035 | announce_count++; |
||
1036 | |||
1037 | DEBUG0_ZCLL_MESG(zeroconf_dbg_msg, "Sending ANNOUNCEMENT [%d]\r\n", announce_count); |
||
1038 | DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg); |
||
1039 | } |
||
1040 | else |
||
1041 | { |
||
1042 | // Claim it. Goto DEFEND state |
||
1043 | |||
1044 | AppConfig.MyIPAddr = temp_IP_addr; |
||
1045 | zcll_state = SM_ADDR_DEFEND; |
||
1046 | DisplayIPValue(AppConfig.MyIPAddr); |
||
1047 | INFO_ZCLL_MESG(zeroconf_dbg_msg,"\r\n******** Taken IP-Addr: " \ |
||
1048 | "%d.%d.%d.%d ******** \r\n", |
||
1049 | AppConfig.MyIPAddr.v[0], AppConfig.MyIPAddr.v[1], |
||
1050 | AppConfig.MyIPAddr.v[2],AppConfig.MyIPAddr.v[3]); |
||
1051 | INFO_ZCLL_PRINT((char *)zeroconf_dbg_msg); |
||
1052 | INFO_ZCLL_PRINT("ADDR_CLAIM --> ADDR_DEFEND \r\n"); |
||
1053 | } |
||
1054 | |||
1055 | break; |
||
1056 | |||
1057 | case SM_ADDR_DEFEND: |
||
1058 | |||
1059 | //DEBUG_ZCLL_PRINT("SM_ADDR_DEFEND \r\n"); |
||
1060 | |||
1061 | if( zcll_flags.bits.late_conflict) |
||
1062 | { |
||
1063 | if (!defended) |
||
1064 | { |
||
1065 | zcll_flags.bits.late_conflict = 0; |
||
1066 | INFO_ZCLL_PRINT("CONFLICT DETECTED !!! \r\n"); |
||
1067 | |||
1068 | INFO_ZCLL_PRINT("Defending the Self Address once \r\n"); |
||
1069 | ARPAction(AppConfig.MyIPAddr.Val, AppConfig.MyIPAddr.Val,ARP_RESP,ARPDefend); |
||
1070 | |||
1071 | defended = 1; |
||
1072 | } |
||
1073 | else |
||
1074 | { |
||
1075 | // We are not allowed to defend another conflict during an active defended period |
||
1076 | |||
1077 | INFO_ZCLL_PRINT("Releasing the IP-Address because of multiple Conflicts \r\n"); |
||
1078 | |||
1079 | zcll_state = SM_ADDR_RELEASE; |
||
1080 | |||
1081 | defended = 0; |
||
1082 | event_time = 0; |
||
1083 | random_delay = 0; |
||
1084 | |||
1085 | INFO_ZCLL_PRINT("ADDR_DEFEND --> ADDR_RELEASE \r\n"); |
||
1086 | break; |
||
1087 | } |
||
1088 | } |
||
1089 | |||
1090 | if (defended) |
||
1091 | { |
||
1092 | switch ( zgzc_wait_for(&random_delay, &event_time, &time_recorded) ) |
||
1093 | { |
||
1094 | case ZGZC_STARTED_WAITING: |
||
1095 | |||
1096 | random_delay = (TICK)(DEFEND_INTERVAL * TICK_SECOND); |
||
1097 | DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"DEFEND_INTERVAL Delay : %ld ticks\r\n", |
||
1098 | random_delay/*TICK_SECOND */); |
||
1099 | DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg); |
||
1100 | |||
1101 | // Intentional fall-through |
||
1102 | |||
1103 | case ZGZC_KEEP_WAITING: |
||
1104 | |||
1105 | // Not Completed the delay proposed |
||
1106 | return; |
||
1107 | } |
||
1108 | |||
1109 | // Completed the delay required |
||
1110 | |||
1111 | DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"ANNOUNCE delay: %ld ticks " \ |
||
1112 | "completed \r\n", random_delay); |
||
1113 | DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg); |
||
1114 | |||
1115 | defended = 0; |
||
1116 | } |
||
1117 | |||
1118 | break; |
||
1119 | |||
1120 | case SM_ADDR_RELEASE: |
||
1121 | |||
1122 | INFO_ZCLL_PRINT("ADDR_RELEASE --> ADDR_INIT\r\n"); |
||
1123 | |||
1124 | AppConfig.MyIPAddr.Val = 0x00; |
||
1125 | |||
1126 | // Need New Addr |
||
1127 | temp_IP_addr.Val = (IPV4_LLBASE | ((abs(zcll_rand()) % 0xfdff) )); |
||
1128 | temp_IP_addr.Val = swapl((DWORD) temp_IP_addr.Val); |
||
1129 | |||
1130 | zcll_state = SM_ADDR_INIT; |
||
1131 | time_recorded = 0; |
||
1132 | defended = 0; |
||
1133 | event_time = 0; |
||
1134 | break; |
||
1135 | |||
1136 | default: |
||
1137 | break; |
||
1138 | } |
||
1139 | } |
||
1140 | #endif //#if defined(STACK_USE_ZERCONF_LINK_LOCAL) |
||
1141 | |||
1142 | |||
1143 |
Powered by WebSVN v2.8.3