Browse Source

cmRtNet.h/c: Completed initial working cmRtNetTest().

master
kpl 11 years ago
parent
commit
8f9689faa8
2 changed files with 109 additions and 28 deletions
  1. 77
    27
      cmRtNet.c
  2. 32
    1
      cmRtNet.h

+ 77
- 27
cmRtNet.c View File

@@ -12,7 +12,9 @@
12 12
 enum
13 13
 {
14 14
   kLocalNetFl    = 0x01,
15
-  kSockAddrNetFl = 0x02
15
+  kSockAddrNetFl = 0x02,
16
+  kRegNodeNetFl  = 0x04,
17
+  kRecvNodeNetFl = 0x08
16 18
 };
17 19
 
18 20
 typedef enum
@@ -31,7 +33,8 @@ typedef enum
31 33
   kHelloSelNetId,
32 34
   kHelloAckSelNetId,
33 35
   kEndpointSelNetId,
34
-  kEndpointAckSelNetId
36
+  kEndpointAckSelNetId,
37
+  kDoneSelNetId
35 38
 } cmRtNetSelId_t;
36 39
 
37 40
 typedef struct cmRtNetEnd_str
@@ -50,7 +53,7 @@ typedef struct cmRtNetNode_str
50 53
   cmUdpPort_t             port;
51 54
   unsigned                flags;
52 55
   cmRtNetNodeState_t      state;
53
-  unsigned                epIdx;
56
+  unsigned                epIdx;         // tracks the next endpoint to send during sync-mode
54 57
   cmTimeSpec_t            lastSendTime;
55 58
   cmRtNetEnd_t*           ends;
56 59
   struct cmRtNetNode_str* link;
@@ -65,6 +68,7 @@ typedef struct
65 68
   cmRtNetNode_t*  nodes;
66 69
   cmRtNetNode_t*  localNode;
67 70
   bool            syncModeFl;
71
+  bool            masterFl;
68 72
   unsigned        udpRecvBufByteCnt;
69 73
   unsigned        udpTimeOutMs;
70 74
   unsigned        interSyncSendTimeMs;
@@ -189,7 +193,7 @@ cmRtNetRC_t  _cmRtNetReleaseNode( cmRtNet_t* p, cmRtNetNode_t* np )
189 193
   return cmErrMsg(&p->err,kNodeNotFoundNetRC,"Node to release not found.");
190 194
 }
191 195
 
192
-cmRtNetRC_t _cmRtNetCreateNode( cmRtNet_t* p, const cmChar_t* label, const cmChar_t* addr, cmUdpPort_t port, const struct sockaddr_in* saddr )
196
+cmRtNetRC_t _cmRtNetCreateNode( cmRtNet_t* p, const cmChar_t* label, const cmChar_t* addr, cmUdpPort_t port, const struct sockaddr_in* saddr, unsigned flags )
193 197
 {
194 198
   cmRtNetRC_t rc = kOkNetRC;
195 199
   cmRtNetNode_t* np;
@@ -209,7 +213,7 @@ cmRtNetRC_t _cmRtNetCreateNode( cmRtNet_t* p, const cmChar_t* label, const cmCha
209 213
   np->label = cmMemAllocStr(label);
210 214
   np->addr  = addr==NULL ? NULL : cmMemAllocStr(addr);
211 215
   np->port  = port;
212
-  np->flags = cmEnaFlag(np->flags,kLocalNetFl,localNodeFl);
216
+  np->flags = cmEnaFlag(flags,kLocalNetFl,localNodeFl);
213 217
   np->link  = p->nodes;
214 218
   p->nodes  = np;
215 219
 
@@ -323,7 +327,9 @@ cmRtNetRC_t _cmRtNetSendSyncMsg( cmRtNet_t* p, cmRtNetNode_t* np, cmRtNetSelId_t
323 327
 
324 328
   // store this nodes current sync state
325 329
   cmRtNetNodeState_t orgState = np->state;
326
-  np->state = nextStId;
330
+
331
+  if( nextStId != kInvalidStNetId )
332
+    np->state = nextStId;
327 333
 
328 334
  
329 335
   // send the msg
@@ -425,7 +431,7 @@ cmRtNetRC_t cmRtNetCreateNode( cmRtNetH_t h, const cmChar_t* nodeLabel, const cm
425 431
   cmRtNetRC_t rc;
426 432
 
427 433
   // create a node
428
-  if((rc = _cmRtNetCreateNode(p,nodeLabel,ipAddr, port, NULL)) != kOkNetRC )
434
+  if((rc = _cmRtNetCreateNode(p,nodeLabel,ipAddr, port, NULL, kRegNodeNetFl)) != kOkNetRC )
429 435
     return rc;
430 436
 
431 437
   // if this is not the local node
@@ -476,7 +482,7 @@ cmRtNetRC_t cmRtNetBeginSyncMode( cmRtNetH_t h )
476 482
   cmRtNet_t* p = _cmRtNetHandleToPtr(h);
477 483
 
478 484
   p->syncModeFl = true;
479
-  
485
+  p->masterFl   = true;
480 486
   return rc;
481 487
 }
482 488
 
@@ -513,13 +519,17 @@ cmRtNetRC_t _cmRtNetRecvAck( cmRtNet_t* p, const struct sockaddr_in* fromAddr, c
513 519
 
514 520
   if( np->state != expectedState )
515 521
   {
516
-    rc = cmErrMsg(&p->err,kNodeStateErrNetRC,"Node '%s' expected in state %i was in state %i.",kWaitHelloAckStNetId,np->state);
522
+    rc = cmErrMsg(&p->err,kNodeStateErrNetRC,"Node '%s' expected in state %i was in state %i.",cmStringNullGuard(np->label),kWaitHelloAckStNetId,np->state);
517 523
     np->state = kErrorStNetId;
518 524
     goto errLabel;
519 525
   }
520 526
 
521 527
   np->state = nextState;
522 528
 
529
+  // if we are about to send another endpoint - incr the endpoint index
530
+  if( nextState == kSendEndpointStNetId )
531
+    np->epIdx += 1;
532
+
523 533
  errLabel:
524 534
   return rc;
525 535
 }
@@ -532,6 +542,8 @@ cmRtNetRC_t  cmRtNetSyncModeRecv( cmRtNetH_t h, const char* data, unsigned dataB
532 542
   cmRtNetNode_t*   np = NULL;
533 543
   cmRtNetSyncMsg_t m;
534 544
 
545
+  m.endPtLabel = NULL;
546
+
535 547
   assert( cmRtNetIsSyncModeMsg(data,dataByteCnt));
536 548
   
537 549
   if( _cmRtNetDeserializeSyncMsg(data,dataByteCnt,&m) != kOkNetRC )
@@ -558,11 +570,12 @@ cmRtNetRC_t  cmRtNetSyncModeRecv( cmRtNetH_t h, const char* data, unsigned dataB
558 570
         }
559 571
 
560 572
         //  create a node proxy to represent the remote node
561
-        if(( rc = _cmRtNetCreateNode(p,m.endPtLabel,NULL,0,fromAddr)) != kOkNetRC )
573
+        if(( rc = _cmRtNetCreateNode(p,m.endPtLabel,NULL,0,fromAddr,kRecvNodeNetFl)) != kOkNetRC )
562 574
           goto errLabel;
563 575
 
564 576
         // send an ackknowledgement of the 'hello' msg
565 577
         rc = _cmRtNetSendAck(p,kHelloAckSelNetId,fromAddr);
578
+
566 579
       }
567 580
       break;
568 581
 
@@ -573,7 +586,6 @@ cmRtNetRC_t  cmRtNetSyncModeRecv( cmRtNetH_t h, const char* data, unsigned dataB
573 586
 
574 587
         _cmRtNetRpt(p,"rcv endpoint\n");
575 588
 
576
-
577 589
         // locate the remote node which sent the endpoint
578 590
         if((np = _cmRtNetFindNodeFromSockAddr(p,fromAddr)) == NULL )
579 591
         {
@@ -596,16 +608,29 @@ cmRtNetRC_t  cmRtNetSyncModeRecv( cmRtNetH_t h, const char* data, unsigned dataB
596 608
       }
597 609
       break;
598 610
 
611
+    case kDoneSelNetId:
612
+      {
613
+        _cmRtNetRpt(p,"rcv done\n");
614
+
615
+        if( p->masterFl==false  )
616
+          p->syncModeFl = true;
617
+      }
618
+      break;
619
+
599 620
     case kHelloAckSelNetId: // master response
600
-      assert( p->syncModeFl );
601
-      _cmRtNetRpt(p,"rcv hello ack\n");
602
-      rc = _cmRtNetRecvAck(p,fromAddr,kWaitHelloAckStNetId,kSendEndpointStNetId);
621
+      {
622
+        assert( p->syncModeFl );
623
+        _cmRtNetRpt(p,"rcv hello ack\n");
624
+        rc = _cmRtNetRecvAck(p,fromAddr,kWaitHelloAckStNetId,kSendEndpointStNetId);
625
+      }
603 626
       break;
604 627
 
605 628
     case kEndpointAckSelNetId: // master response
606
-      assert( p->syncModeFl );  
607
-      _cmRtNetRpt(p,"rcv endpoint ack\n");
608
-      rc = _cmRtNetRecvAck(p,fromAddr,kWaitEndpointAckStNetId,kSendEndpointStNetId);
629
+      {
630
+        assert( p->syncModeFl );  
631
+        _cmRtNetRpt(p,"rcv endpoint ack\n");
632
+        rc = _cmRtNetRecvAck(p,fromAddr,kWaitEndpointAckStNetId,kSendEndpointStNetId);
633
+      }
609 634
       break;
610 635
 
611 636
     default:
@@ -613,6 +638,8 @@ cmRtNetRC_t  cmRtNetSyncModeRecv( cmRtNetH_t h, const char* data, unsigned dataB
613 638
   }
614 639
 
615 640
  errLabel:
641
+
642
+  cmMemFree((cmChar_t*)m.endPtLabel);
616 643
   return rc;
617 644
 }
618 645
 
@@ -624,11 +651,15 @@ cmRtNetRC_t _cmRtNetSendNodeSync( cmRtNet_t* p, cmRtNetNode_t* np )
624 651
   switch( np->state )
625 652
   {
626 653
     case kSendHelloStNetId:
627
-      // send a 'hello' to this remote node
628
-      if((rc = _cmRtNetSendSyncMsg(p,np,kHelloSelNetId,p->localNode->label, cmInvalidId, kWaitHelloAckStNetId )) != kOkNetRC )
629
-        rc = cmErrMsg(&p->err,rc,"Send 'hello' to %s:%s:%i failed.",cmStringNullGuard(np->label),cmStringNullGuard(np->addr),np->port);
630
-      else
631
-        _cmRtNetRpt(p,"send hello\n");
654
+      {
655
+        np->epIdx = -1;
656
+
657
+        // send a 'hello' to this remote node
658
+        if((rc = _cmRtNetSendSyncMsg(p,np,kHelloSelNetId,p->localNode->label, cmInvalidId, kWaitHelloAckStNetId )) != kOkNetRC )
659
+          rc = cmErrMsg(&p->err,rc,"Send 'hello' to %s:%s:%i failed.",cmStringNullGuard(np->label),cmStringNullGuard(np->addr),np->port);
660
+        else
661
+          _cmRtNetRpt(p,"%s sent hello\n",cmStringNullGuard(np->label));
662
+      }
632 663
       break;
633 664
 
634 665
     case kSendEndpointStNetId:
@@ -637,14 +668,20 @@ cmRtNetRC_t _cmRtNetSendNodeSync( cmRtNet_t* p, cmRtNetNode_t* np )
637 668
 
638 669
         // if all of the endpoints have been sent to this node ...
639 670
         if((ep = _cmRtNetIndexToEndpoint(p,p->localNode,np->epIdx)) == NULL )
640
-          np->state = kDoneStNetId; // ... we are done
671
+        {
672
+          // notify the remote node that all endpoints have been sent
673
+          if((rc = _cmRtNetSendSyncMsg(p,np,kDoneSelNetId,p->localNode->label,cmInvalidId, kDoneStNetId )) != kOkNetRC )
674
+            rc = cmErrMsg(&p->err,rc,"Send 'done' to %s:%s:%i failed.",cmStringNullGuard(np->label),cmStringNullGuard(np->addr),np->port);
675
+          else
676
+            _cmRtNetRpt(p,"Node %s done.\n",cmStringNullGuard(np->label));
677
+        }
641 678
         else
642 679
         {
643 680
           // send an endpoint to this node 
644
-          if((rc = _cmRtNetSendSyncMsg(p,np,kHelloSelNetId,ep->endPtLabel, ep->endPtId, kWaitEndpointAckStNetId )) != kOkNetRC )
681
+          if((rc = _cmRtNetSendSyncMsg(p,np,kEndpointSelNetId,ep->endPtLabel, ep->endPtId, kWaitEndpointAckStNetId )) != kOkNetRC )
645 682
             rc = cmErrMsg(&p->err,rc,"Endpoint (%s index:%i) transmission to %s:%s:%i failed.",cmStringNullGuard(ep->endPtLabel),cmStringNullGuard(np->label),cmStringNullGuard(np->addr),np->port);
646 683
           else
647
-            _cmRtNetRpt(p,"send endpoint\n");
684
+            _cmRtNetRpt(p,"%s sent endpoint %s\n",cmStringNullGuard(np->label),cmStringNullGuard(ep->endPtLabel));
648 685
 
649 686
         }
650 687
       }
@@ -688,14 +725,21 @@ cmRtNetRC_t cmRtNetSyncModeSend( cmRtNetH_t h )
688 725
   unsigned     activeCnt = 0;
689 726
   cmRtNetNode_t* np        = p->nodes;
690 727
   for(; np != NULL; np=np->link )
691
-    if( np != p->localNode && np->state != kDoneStNetId && np->state != kErrorStNetId )
728
+  {
729
+    bool fl = (p->masterFl && cmIsFlag(np->flags,kRegNodeNetFl)) || (p->masterFl==false && cmIsFlag(np->flags,kRecvNodeNetFl));
730
+
731
+    if( fl && np != p->localNode && np->state != kDoneStNetId && np->state != kErrorStNetId  )
692 732
     {
693 733
       _cmRtNetSendNodeSync(p,np);
694 734
       activeCnt += 1;
695 735
     }
696
-    
736
+  }
737
+ 
697 738
   if( activeCnt == 0 )
739
+  {
698 740
     p->syncModeFl = false;
741
+    _cmRtNetRpt(p,"sync mode complete.\n");
742
+  }
699 743
 
700 744
   return rc;
701 745
 }
@@ -853,6 +897,12 @@ void  cmRtNetTest( cmCtx_t* ctx, bool mstrFl )
853 897
   cmRptPrintf(&ctx->rpt,"%s q=quit\n", mstrFl ? "Master: " : "Slave: ");
854 898
   while( (c=getchar()) != 'q' )
855 899
   {
900
+    switch(c)
901
+    {
902
+      case 'r':
903
+        cmRtNetReport(p->netH);
904
+        break;
905
+    }
856 906
     
857 907
   }
858 908
 

+ 32
- 1
cmRtNet.h View File

@@ -104,7 +104,38 @@ extern "C" {
104 104
      {
105 105
        if( cmRtNetIsSyncModeMsg(dataV,dataN) )
106 106
          cmRtNetSyncModeRecv(dataV,dataN,addr)
107
-     }   
107
+     } 
108
+
109
+
110
+     The 'master' is the machine which cmRtNetBeginSyncMode() is called on.
111
+     1) 'master' sends local endpoints to all registered remote nodes.
112
+     2) When a 'slave' receives the kDoneSelNetId msg it transmits
113
+     it's own local endpoints back to the master.
114
+
115
+     a. Each node in the node list has a type id:
116
+       1. local 
117
+       2. registered - remote node that was explicitely registered on a master
118
+       3. received   - remote node that was received from a master
119
+
120
+     b. 
121
+       1. All nodes are created in the 'send-hello' state.
122
+       2. If a master machine is in 'sync-mode' then it systematically sends
123
+       each of it's local endpoints to all 'registered' nodes.
124
+       3. When a slave machine recives a 'hello' it creates a
125
+       'received' node.
126
+       4. When a slave machine recieves a 'done' it enters sync mode
127
+       and systematically sends each of its local endpoints to
128
+       the 'done' source.
129
+       
130
+
131
+   Protocol:
132
+     1. A: broadcast - 'hello'
133
+     2. Bs: respond 'hello' ack
134
+     3. A: send local node and endpoints to each responder
135
+     4. A: send done
136
+     5. Bs: send local endpoints to A
137
+
138
+
108 139
    */  
109 140
 
110 141
 #ifdef __cplusplus

Loading…
Cancel
Save