?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 32

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  
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3