Преглед на файлове

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

master
kpl преди 11 години
родител
ревизия
8f9689faa8
променени са 2 файла, в които са добавени 109 реда и са изтрити 28 реда
  1. 77
    27
      cmRtNet.c
  2. 32
    1
      cmRtNet.h

+ 77
- 27
cmRtNet.c Целия файл

12
 enum
12
 enum
13
 {
13
 {
14
   kLocalNetFl    = 0x01,
14
   kLocalNetFl    = 0x01,
15
-  kSockAddrNetFl = 0x02
15
+  kSockAddrNetFl = 0x02,
16
+  kRegNodeNetFl  = 0x04,
17
+  kRecvNodeNetFl = 0x08
16
 };
18
 };
17
 
19
 
18
 typedef enum
20
 typedef enum
31
   kHelloSelNetId,
33
   kHelloSelNetId,
32
   kHelloAckSelNetId,
34
   kHelloAckSelNetId,
33
   kEndpointSelNetId,
35
   kEndpointSelNetId,
34
-  kEndpointAckSelNetId
36
+  kEndpointAckSelNetId,
37
+  kDoneSelNetId
35
 } cmRtNetSelId_t;
38
 } cmRtNetSelId_t;
36
 
39
 
37
 typedef struct cmRtNetEnd_str
40
 typedef struct cmRtNetEnd_str
50
   cmUdpPort_t             port;
53
   cmUdpPort_t             port;
51
   unsigned                flags;
54
   unsigned                flags;
52
   cmRtNetNodeState_t      state;
55
   cmRtNetNodeState_t      state;
53
-  unsigned                epIdx;
56
+  unsigned                epIdx;         // tracks the next endpoint to send during sync-mode
54
   cmTimeSpec_t            lastSendTime;
57
   cmTimeSpec_t            lastSendTime;
55
   cmRtNetEnd_t*           ends;
58
   cmRtNetEnd_t*           ends;
56
   struct cmRtNetNode_str* link;
59
   struct cmRtNetNode_str* link;
65
   cmRtNetNode_t*  nodes;
68
   cmRtNetNode_t*  nodes;
66
   cmRtNetNode_t*  localNode;
69
   cmRtNetNode_t*  localNode;
67
   bool            syncModeFl;
70
   bool            syncModeFl;
71
+  bool            masterFl;
68
   unsigned        udpRecvBufByteCnt;
72
   unsigned        udpRecvBufByteCnt;
69
   unsigned        udpTimeOutMs;
73
   unsigned        udpTimeOutMs;
70
   unsigned        interSyncSendTimeMs;
74
   unsigned        interSyncSendTimeMs;
189
   return cmErrMsg(&p->err,kNodeNotFoundNetRC,"Node to release not found.");
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
   cmRtNetRC_t rc = kOkNetRC;
198
   cmRtNetRC_t rc = kOkNetRC;
195
   cmRtNetNode_t* np;
199
   cmRtNetNode_t* np;
209
   np->label = cmMemAllocStr(label);
213
   np->label = cmMemAllocStr(label);
210
   np->addr  = addr==NULL ? NULL : cmMemAllocStr(addr);
214
   np->addr  = addr==NULL ? NULL : cmMemAllocStr(addr);
211
   np->port  = port;
215
   np->port  = port;
212
-  np->flags = cmEnaFlag(np->flags,kLocalNetFl,localNodeFl);
216
+  np->flags = cmEnaFlag(flags,kLocalNetFl,localNodeFl);
213
   np->link  = p->nodes;
217
   np->link  = p->nodes;
214
   p->nodes  = np;
218
   p->nodes  = np;
215
 
219
 
323
 
327
 
324
   // store this nodes current sync state
328
   // store this nodes current sync state
325
   cmRtNetNodeState_t orgState = np->state;
329
   cmRtNetNodeState_t orgState = np->state;
326
-  np->state = nextStId;
330
+
331
+  if( nextStId != kInvalidStNetId )
332
+    np->state = nextStId;
327
 
333
 
328
  
334
  
329
   // send the msg
335
   // send the msg
425
   cmRtNetRC_t rc;
431
   cmRtNetRC_t rc;
426
 
432
 
427
   // create a node
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
     return rc;
435
     return rc;
430
 
436
 
431
   // if this is not the local node
437
   // if this is not the local node
476
   cmRtNet_t* p = _cmRtNetHandleToPtr(h);
482
   cmRtNet_t* p = _cmRtNetHandleToPtr(h);
477
 
483
 
478
   p->syncModeFl = true;
484
   p->syncModeFl = true;
479
-  
485
+  p->masterFl   = true;
480
   return rc;
486
   return rc;
481
 }
487
 }
482
 
488
 
513
 
519
 
514
   if( np->state != expectedState )
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
     np->state = kErrorStNetId;
523
     np->state = kErrorStNetId;
518
     goto errLabel;
524
     goto errLabel;
519
   }
525
   }
520
 
526
 
521
   np->state = nextState;
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
  errLabel:
533
  errLabel:
524
   return rc;
534
   return rc;
525
 }
535
 }
532
   cmRtNetNode_t*   np = NULL;
542
   cmRtNetNode_t*   np = NULL;
533
   cmRtNetSyncMsg_t m;
543
   cmRtNetSyncMsg_t m;
534
 
544
 
545
+  m.endPtLabel = NULL;
546
+
535
   assert( cmRtNetIsSyncModeMsg(data,dataByteCnt));
547
   assert( cmRtNetIsSyncModeMsg(data,dataByteCnt));
536
   
548
   
537
   if( _cmRtNetDeserializeSyncMsg(data,dataByteCnt,&m) != kOkNetRC )
549
   if( _cmRtNetDeserializeSyncMsg(data,dataByteCnt,&m) != kOkNetRC )
558
         }
570
         }
559
 
571
 
560
         //  create a node proxy to represent the remote node
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
           goto errLabel;
574
           goto errLabel;
563
 
575
 
564
         // send an ackknowledgement of the 'hello' msg
576
         // send an ackknowledgement of the 'hello' msg
565
         rc = _cmRtNetSendAck(p,kHelloAckSelNetId,fromAddr);
577
         rc = _cmRtNetSendAck(p,kHelloAckSelNetId,fromAddr);
578
+
566
       }
579
       }
567
       break;
580
       break;
568
 
581
 
573
 
586
 
574
         _cmRtNetRpt(p,"rcv endpoint\n");
587
         _cmRtNetRpt(p,"rcv endpoint\n");
575
 
588
 
576
-
577
         // locate the remote node which sent the endpoint
589
         // locate the remote node which sent the endpoint
578
         if((np = _cmRtNetFindNodeFromSockAddr(p,fromAddr)) == NULL )
590
         if((np = _cmRtNetFindNodeFromSockAddr(p,fromAddr)) == NULL )
579
         {
591
         {
596
       }
608
       }
597
       break;
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
     case kHelloAckSelNetId: // master response
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
       break;
626
       break;
604
 
627
 
605
     case kEndpointAckSelNetId: // master response
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
       break;
634
       break;
610
 
635
 
611
     default:
636
     default:
613
   }
638
   }
614
 
639
 
615
  errLabel:
640
  errLabel:
641
+
642
+  cmMemFree((cmChar_t*)m.endPtLabel);
616
   return rc;
643
   return rc;
617
 }
644
 }
618
 
645
 
624
   switch( np->state )
651
   switch( np->state )
625
   {
652
   {
626
     case kSendHelloStNetId:
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
       break;
663
       break;
633
 
664
 
634
     case kSendEndpointStNetId:
665
     case kSendEndpointStNetId:
637
 
668
 
638
         // if all of the endpoints have been sent to this node ...
669
         // if all of the endpoints have been sent to this node ...
639
         if((ep = _cmRtNetIndexToEndpoint(p,p->localNode,np->epIdx)) == NULL )
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
         else
678
         else
642
         {
679
         {
643
           // send an endpoint to this node 
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
             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);
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
           else
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
   unsigned     activeCnt = 0;
725
   unsigned     activeCnt = 0;
689
   cmRtNetNode_t* np        = p->nodes;
726
   cmRtNetNode_t* np        = p->nodes;
690
   for(; np != NULL; np=np->link )
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
       _cmRtNetSendNodeSync(p,np);
733
       _cmRtNetSendNodeSync(p,np);
694
       activeCnt += 1;
734
       activeCnt += 1;
695
     }
735
     }
696
-    
736
+  }
737
+ 
697
   if( activeCnt == 0 )
738
   if( activeCnt == 0 )
739
+  {
698
     p->syncModeFl = false;
740
     p->syncModeFl = false;
741
+    _cmRtNetRpt(p,"sync mode complete.\n");
742
+  }
699
 
743
 
700
   return rc;
744
   return rc;
701
 }
745
 }
853
   cmRptPrintf(&ctx->rpt,"%s q=quit\n", mstrFl ? "Master: " : "Slave: ");
897
   cmRptPrintf(&ctx->rpt,"%s q=quit\n", mstrFl ? "Master: " : "Slave: ");
854
   while( (c=getchar()) != 'q' )
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 Целия файл

104
      {
104
      {
105
        if( cmRtNetIsSyncModeMsg(dataV,dataN) )
105
        if( cmRtNetIsSyncModeMsg(dataV,dataN) )
106
          cmRtNetSyncModeRecv(dataV,dataN,addr)
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
 #ifdef __cplusplus
141
 #ifdef __cplusplus

Loading…
Отказ
Запис