giuliomoro@135
|
1 #include "ClockSync.h"
|
giuliomoro@135
|
2
|
giuliomoro@135
|
3 void ClockSync::setVirtualClock(VirtualClock &aVirtualClock){
|
giuliomoro@135
|
4 virtualClock=&aVirtualClock;
|
giuliomoro@135
|
5 }
|
giuliomoro@135
|
6 void ClockSync::init(bool thisIsSlave, int aPort, VirtualClock &aVirtualClock){
|
giuliomoro@135
|
7 setVirtualClock(aVirtualClock);
|
giuliomoro@135
|
8 slave=thisIsSlave;
|
giuliomoro@135
|
9 setPort(aPort);
|
giuliomoro@135
|
10 // isSlave() ? client.setServer("127.0.0.1") : client.setServer("127.0.0.1");
|
giuliomoro@135
|
11 isSlave() ? client.setServer("192.168.7.1") : client.setServer("192.168.7.2");
|
giuliomoro@135
|
12 bufferLength=kSyncMessageLength;
|
giuliomoro@141
|
13 resetTs();
|
giuliomoro@141
|
14 receiveLoopSleepUs=100;
|
giuliomoro@141
|
15 receiveLoopTimeout=1e5;
|
giuliomoro@141
|
16 movingAverage.setLength(31);
|
giuliomoro@141
|
17 expectedClockSyncType=isSlave() ? kSync : kNone;
|
giuliomoro@141
|
18 }
|
giuliomoro@141
|
19 void ClockSync::resetTs(){
|
giuliomoro@135
|
20 T1=-1;
|
giuliomoro@135
|
21 T1p=-1;
|
giuliomoro@135
|
22 T2=-1;
|
giuliomoro@135
|
23 T2p=-1;
|
giuliomoro@141
|
24 }
|
giuliomoro@141
|
25 bool ClockSync::areTsValid(){
|
giuliomoro@141
|
26 return T1>0 && T1p>0 && T2>0 && T2p>0;
|
giuliomoro@135
|
27 }
|
giuliomoro@135
|
28 ClockSync::ClockSync(bool thisIsSlave, int aPort, VirtualClock &aVirtualClock){
|
giuliomoro@135
|
29 init(thisIsSlave, aPort, aVirtualClock);
|
giuliomoro@135
|
30 }
|
giuliomoro@135
|
31 void* ClockSync::getBuffer(){
|
giuliomoro@135
|
32 return buffer;
|
giuliomoro@135
|
33 }
|
giuliomoro@135
|
34 bool ClockSync::isSlave(){
|
giuliomoro@135
|
35 return slave;
|
giuliomoro@135
|
36 }
|
giuliomoro@135
|
37 bool ClockSync::isMaster(){
|
giuliomoro@135
|
38 return !slave;
|
giuliomoro@135
|
39 }
|
giuliomoro@135
|
40 int ClockSync::getType(){
|
giuliomoro@135
|
41 return ((int*)buffer)[0];
|
giuliomoro@135
|
42 }
|
giuliomoro@135
|
43 myClock_t ClockSync::getTimestamp(){
|
giuliomoro@135
|
44 return *((myClock_t*)((char*)buffer+sizeof(int)));
|
giuliomoro@135
|
45 }
|
giuliomoro@135
|
46 void ClockSync::setType(int clockSyncType){
|
giuliomoro@135
|
47 ((int*)buffer)[0]=clockSyncType;
|
giuliomoro@135
|
48 }
|
giuliomoro@135
|
49 void ClockSync::setTimestamp(myClock_t timestamp){
|
giuliomoro@139
|
50 // printf("setting timestamp: %lld\n", timestamp);
|
giuliomoro@135
|
51 ((myClock_t*)((char*)buffer+sizeof(int)))[0]=timestamp;
|
giuliomoro@135
|
52 }
|
giuliomoro@135
|
53 void ClockSync::print(){
|
giuliomoro@135
|
54 //printf("type: %d, timestamp: %lld\n",*((int*)buffer),*((myClock_t*)(((int*)buffer)+1)));
|
giuliomoro@135
|
55 }
|
giuliomoro@135
|
56 void ClockSync::setPort(int aPort){
|
giuliomoro@135
|
57 if(aPort>0){
|
giuliomoro@135
|
58 int inPort=isSlave() ? aPort : aPort+1;
|
giuliomoro@135
|
59 int outPort=isSlave() ? aPort+1: aPort;
|
giuliomoro@135
|
60 server.bindToPort(inPort);
|
giuliomoro@135
|
61 client.setPort(outPort);
|
giuliomoro@135
|
62 //printf("Receiving on port %d\n", inPort);
|
giuliomoro@135
|
63 //printf("Sending to port %d\n", outPort);
|
giuliomoro@135
|
64 }
|
giuliomoro@135
|
65 }
|
giuliomoro@135
|
66 /**
|
giuliomoro@135
|
67 * sends a clockSync without blocking, checks results and returns the timestamp
|
giuliomoro@135
|
68 * immediately after the clockSync has been sent or -1 if there was an error or timeout expired.
|
giuliomoro@135
|
69 */
|
giuliomoro@135
|
70 myClock_t ClockSync::send(){
|
giuliomoro@135
|
71 // print();
|
giuliomoro@135
|
72 int ret;
|
giuliomoro@149
|
73 ret=client.waitUntilReady(false, isSlave() ? 110 : 5);
|
giuliomoro@135
|
74 if(ret<=0){ //don't retry
|
giuliomoro@135
|
75 return -1;
|
giuliomoro@135
|
76 }
|
giuliomoro@135
|
77 ret=client.send(buffer, bufferLength);
|
giuliomoro@135
|
78 myClock_t timestamp=(myClock_t)virtualClock->getNow();
|
giuliomoro@135
|
79 if(ret<0){
|
giuliomoro@135
|
80 //if there was an error while sending, don't retry
|
giuliomoro@135
|
81 return -1;
|
giuliomoro@135
|
82 }
|
giuliomoro@135
|
83 return timestamp; //get the accurate time *after* you sent the sync clockSync
|
giuliomoro@135
|
84 }
|
giuliomoro@135
|
85 /**
|
giuliomoro@135
|
86 * receives a clockSync without blocking, checks results and returns the timestamp
|
giuliomoro@135
|
87 * immediately after the clockSync has been received, or -1 if there was an error
|
giuliomoro@135
|
88 * or 0 if timeout expired.
|
giuliomoro@135
|
89 */
|
giuliomoro@135
|
90 myClock_t ClockSync::receive(){
|
giuliomoro@135
|
91 int ret;
|
giuliomoro@135
|
92 ret=server.waitUntilReady(true, 0);
|
giuliomoro@135
|
93 if(ret<=0){ //don't retry
|
giuliomoro@135
|
94 return 0;
|
giuliomoro@135
|
95 }
|
giuliomoro@135
|
96 ret=server.read(buffer, bufferLength, false);
|
giuliomoro@135
|
97 myClock_t timestamp=(myClock_t)virtualClock->getNow();
|
giuliomoro@135
|
98 if(timestamp==0){
|
giuliomoro@135
|
99 //printf("The virtualClock period is <=0\n");
|
giuliomoro@135
|
100 return -3;
|
giuliomoro@135
|
101 }
|
giuliomoro@135
|
102 if(ret==-1){
|
giuliomoro@135
|
103 //if there was an error while receiving, don't retry
|
giuliomoro@135
|
104 return -1;
|
giuliomoro@135
|
105 }
|
giuliomoro@135
|
106 if(ret!=bufferLength){
|
giuliomoro@135
|
107 //printf("Received a clockSync of the wrong size: %d\n", ret);
|
giuliomoro@135
|
108 return -2;
|
giuliomoro@135
|
109 }
|
giuliomoro@135
|
110 // print();
|
giuliomoro@135
|
111 return timestamp; //get the accurate time *after* you sent the sync clockSync
|
giuliomoro@135
|
112 }
|
giuliomoro@135
|
113
|
giuliomoro@135
|
114 int ClockSync::masterSendSync(){
|
giuliomoro@135
|
115 //let's send a sync clockSync!
|
giuliomoro@135
|
116 //printf("Sending a sync clockSync\n");
|
giuliomoro@135
|
117 setType(kSync);
|
giuliomoro@135
|
118 setTimestamp(-1);//do not care about sending the timestamp, a more accurate one will be sent in the follow up
|
giuliomoro@135
|
119 localTimestamp=send();
|
giuliomoro@135
|
120 if(localTimestamp<0){
|
giuliomoro@135
|
121 //printf("Could not send sync clockSync\n");
|
giuliomoro@135
|
122 return -1; //error, don't retry, start over
|
giuliomoro@135
|
123 }
|
giuliomoro@135
|
124 //let's send a followUp
|
giuliomoro@135
|
125 //printf("sent a sync clockSync\n");
|
giuliomoro@135
|
126 setType(kFollowUp);
|
giuliomoro@135
|
127 setTimestamp(localTimestamp);
|
giuliomoro@135
|
128 if(localTimestamp<0){
|
giuliomoro@135
|
129 //printf("Could not send followup clockSync\n");
|
giuliomoro@135
|
130 return -2; //error, don't retry, start over
|
giuliomoro@135
|
131 }
|
giuliomoro@135
|
132 int ret=send();
|
giuliomoro@135
|
133 if(ret<0){
|
giuliomoro@135
|
134 //printf("Error while sending followup\n");
|
giuliomoro@135
|
135 return -3;
|
giuliomoro@135
|
136 }
|
giuliomoro@135
|
137 //printf("sent a followUp clockSync\n");
|
giuliomoro@135
|
138 expectedClockSyncType=kDelayReq;
|
giuliomoro@135
|
139 return 1;
|
giuliomoro@135
|
140 }
|
giuliomoro@135
|
141 #ifdef USE_JUCE
|
giuliomoro@135
|
142 #define NOTGSHOULDSTOP 1
|
giuliomoro@135
|
143 #else
|
giuliomoro@135
|
144 extern bool gShouldStop;
|
giuliomoro@135
|
145 #define NOTGSHOULDSTOP (!gShouldStop)
|
giuliomoro@135
|
146 #endif /* USE_JUCE */
|
giuliomoro@135
|
147 int ClockSync::receiveLoop(){
|
giuliomoro@135
|
148 int receiveLoopElapsed=0;
|
giuliomoro@135
|
149 while( NOTGSHOULDSTOP && (isSlave() || (receiveLoopElapsed<receiveLoopTimeout))){ //when slave, does not timeout!
|
giuliomoro@135
|
150 receiveLoopElapsed+=receiveLoopSleepUs;
|
giuliomoro@135
|
151 usleep(receiveLoopSleepUs); //how often to check for new clockSyncs;
|
giuliomoro@135
|
152 // //printf("waiting for clockSyncs\n");
|
giuliomoro@135
|
153 localTimestamp=receive();
|
giuliomoro@135
|
154 if(localTimestamp<=0){
|
giuliomoro@135
|
155 if(localTimestamp==0){
|
giuliomoro@139
|
156 // printf("Socket not ready to be read: %lld\n", localTimestamp);
|
giuliomoro@135
|
157 }
|
giuliomoro@135
|
158 else if(localTimestamp==-1){
|
giuliomoro@139
|
159 printf("Error while receiving: %lld\n", localTimestamp);
|
giuliomoro@135
|
160 }
|
giuliomoro@135
|
161 else if(localTimestamp==-2){
|
giuliomoro@139
|
162 printf("Wrong size of the received clockSync: %lld\n", localTimestamp);
|
giuliomoro@135
|
163 }
|
giuliomoro@135
|
164 continue ; //keep waiting
|
giuliomoro@135
|
165 }
|
giuliomoro@135
|
166 clockSyncType=getType();
|
giuliomoro@135
|
167 clockSyncTimestamp=getTimestamp();
|
giuliomoro@135
|
168 if(clockSyncType!=expectedClockSyncType){
|
giuliomoro@135
|
169 //printf("Wrong clockSync type: %d, expected: %d\n",clockSyncType, expectedClockSyncType);
|
giuliomoro@135
|
170 return -2; //start over
|
giuliomoro@135
|
171 }
|
giuliomoro@139
|
172 // printf("Received clockSync type: %d, clockSyncTimestamp: %lld\n", clockSyncType, clockSyncTimestamp);
|
giuliomoro@135
|
173 if(isSlave()==true){
|
giuliomoro@135
|
174 int ret=slaveHandleMessage();
|
giuliomoro@135
|
175 if(ret==1 && clockSyncType==kDelayResp){ //we are done, end of a cycle!
|
giuliomoro@135
|
176 return 1;
|
giuliomoro@135
|
177 } else if (ret!=1) {
|
giuliomoro@135
|
178 return -1; //
|
giuliomoro@135
|
179 } else {
|
giuliomoro@135
|
180 continue;
|
giuliomoro@135
|
181 }
|
giuliomoro@135
|
182 }
|
giuliomoro@135
|
183 if(isMaster()==true){ //this is master
|
giuliomoro@135
|
184 int ret=masterHandleMessage();
|
giuliomoro@135
|
185 if(ret==1 && clockSyncType==kDelayReq){ //we are done, end of a cycle!
|
giuliomoro@135
|
186 return 1;
|
giuliomoro@135
|
187 } else {
|
giuliomoro@135
|
188 return -2; //we are done but something was wrong
|
giuliomoro@135
|
189 }
|
giuliomoro@135
|
190 }
|
giuliomoro@135
|
191 }
|
giuliomoro@135
|
192 //printf("Receive loop timeout\n");
|
giuliomoro@135
|
193 return -1;
|
giuliomoro@135
|
194 }
|
giuliomoro@135
|
195
|
giuliomoro@135
|
196 int ClockSync::slaveHandleMessage(){
|
giuliomoro@135
|
197 switch(clockSyncType){
|
giuliomoro@135
|
198 case kSync: //the clockSync timestamp is meaningless, the localTimestamp is when kSync was received
|
giuliomoro@141
|
199 resetTs();
|
giuliomoro@135
|
200 T1p=localTimestamp;
|
giuliomoro@135
|
201 expectedClockSyncType=kFollowUp;
|
giuliomoro@135
|
202 break;
|
giuliomoro@135
|
203 case kFollowUp: //the clockSyncTimestamp is the time when kSync was sent, the localTimestamp is meaningless
|
giuliomoro@135
|
204 T1=clockSyncTimestamp;
|
giuliomoro@135
|
205 //send delayReq
|
giuliomoro@135
|
206 setType(kDelayReq);
|
giuliomoro@135
|
207 setTimestamp(-1);
|
giuliomoro@135
|
208 T2=send();
|
giuliomoro@135
|
209 if(T2<0){
|
giuliomoro@135
|
210 //printf("Error while sending delayReq\n");
|
giuliomoro@135
|
211 return -1;
|
giuliomoro@135
|
212 }
|
giuliomoro@135
|
213 expectedClockSyncType=kDelayResp;
|
giuliomoro@135
|
214 break;
|
giuliomoro@135
|
215 case kDelayResp: {//the clockSyncTimestamp is the instant when the master received the kDelayResp clockSync, the localTimestamp is meaningless
|
giuliomoro@135
|
216 T2p=clockSyncTimestamp;
|
giuliomoro@135
|
217 //TODO: evaluate things
|
giuliomoro@135
|
218 double offset=(T1p-T1-T2p+T2)/2.0d;
|
giuliomoro@141
|
219 if(areTsValid()){
|
giuliomoro@141
|
220 processOffset(offset);
|
giuliomoro@141
|
221
|
giuliomoro@141
|
222 /*
|
giuliomoro@141
|
223 static int calls=0;
|
giuliomoro@141
|
224 static double referenceOffset=0;
|
giuliomoro@141
|
225
|
giuliomoro@141
|
226 if(calls<100){ // start by averaging everything
|
giuliomoro@141
|
227 movingAverage.add(offset);
|
giuliomoro@141
|
228 } else { //once we get an estimate, start discarding outliers
|
giuliomoro@141
|
229 float maxOffsetDeviation=20;
|
giuliomoro@141
|
230 float deviation=fabsf(movingAverage.getAverage()-offset);
|
giuliomoro@141
|
231 if(deviation<maxOffsetDeviation){
|
giuliomoro@141
|
232 movingAverage.add(offset);
|
giuliomoro@141
|
233 printf("w(end+1)=%4.1f;\n", movingAverage.getAverage());
|
giuliomoro@141
|
234 } else {
|
giuliomoro@141
|
235 // printf("Out of range: %f \n", deviation);
|
giuliomoro@141
|
236 }
|
giuliomoro@141
|
237 }
|
giuliomoro@141
|
238 printf("offset(end+1)=%f;\n", offset);
|
giuliomoro@141
|
239 if (calls==100){
|
giuliomoro@141
|
240 // printf("Update reference\n");
|
giuliomoro@141
|
241 referenceOffset=movingAverage.getAverage();
|
giuliomoro@141
|
242 } else if (calls==200){
|
giuliomoro@141
|
243 calls=99;
|
giuliomoro@141
|
244 }
|
giuliomoro@141
|
245 calls++;
|
giuliomoro@141
|
246 */
|
giuliomoro@141
|
247
|
giuliomoro@141
|
248 // printf("%lld, %lld, %lld, %lld \n", T1, T1p, T2, T2p);
|
giuliomoro@141
|
249 // if(T2-T1p<0){
|
giuliomoro@141
|
250 // printf("Negative: %lld, %lld, %lld, %lld \n", T1, T1p, T2, T2p);
|
giuliomoro@141
|
251 // }
|
giuliomoro@141
|
252 } else {
|
giuliomoro@141
|
253 printf("InvalidTs:\n %lld, %lld, %lld, %lld \n", T1, T1p, T2, T2p);
|
giuliomoro@141
|
254 }
|
giuliomoro@135
|
255 expectedClockSyncType=kSync; //end of the cycle, wait for next sync.
|
giuliomoro@135
|
256 break;
|
giuliomoro@135
|
257 }
|
giuliomoro@135
|
258 default:
|
giuliomoro@135
|
259 //printf("Unexpected message type\n"); // we should never get here
|
giuliomoro@135
|
260 return -1;
|
giuliomoro@135
|
261 }
|
giuliomoro@135
|
262 return 1;
|
giuliomoro@135
|
263 }
|
giuliomoro@141
|
264 void ClockSync::processOffset(double offset){
|
giuliomoro@141
|
265 static int calls=0;
|
giuliomoro@141
|
266 // TODO: change the flow control below so that it can happen multiple times
|
giuliomoro@141
|
267 //(base it upon the length of movingAverage rather than the number of calls)
|
giuliomoro@151
|
268 if(calls<30){
|
giuliomoro@151
|
269 // wait for the VirtualClock to stabilize and produce meaningful outputs
|
giuliomoro@151
|
270 } else if(calls<50) { //get an initial guess
|
giuliomoro@141
|
271 movingAverage.add(offset);
|
giuliomoro@141
|
272 // printf("-----------OFFSET IS : %04.4f samples, average: %04.4f samples\n",
|
giuliomoro@141
|
273 // offset, movingAverage.getAverage());
|
giuliomoro@151
|
274 } else if (calls==50){ //then compensate for initial offset
|
giuliomoro@151
|
275 // printf("compensating for offset: %f\n", movingAverage.getAverage());
|
giuliomoro@141
|
276 virtualClock->addOffset(movingAverage.getAverage());
|
giuliomoro@141
|
277 movingAverage.reset();
|
giuliomoro@151
|
278 } else if (calls>50){ //use IIR filter from now on
|
giuliomoro@141
|
279 //filter coefficients obtained from Matlab : [B,A]=butter(2,0.005);
|
giuliomoro@151
|
280 static IirFilter iir(1);
|
giuliomoro@151
|
281 static bool init = false;
|
giuliomoro@151
|
282 if(init == false){
|
giuliomoro@151
|
283 // double coeffs[5]={0.00554271721028068, 0.0110854344205614, 0.00554271721028068,
|
giuliomoro@151
|
284 // -1.77863177782459, 0.800802646665708};
|
giuliomoro@151
|
285 double coeffs[5]={0.0200833655642113, 0.0401667311284225, 0.0200833655642113,
|
giuliomoro@151
|
286 -1.56101807580072, 0.641351538057563};
|
giuliomoro@151
|
287 iir.setCoefficients(coeffs);
|
giuliomoro@151
|
288 init = true;
|
giuliomoro@151
|
289 }
|
giuliomoro@151
|
290 float expectedOffsetDifferenceMean = 0.2432;
|
giuliomoro@151
|
291 float expectedOffsetDifferenceStd = 6.487;
|
giuliomoro@151
|
292 float nlOffset;
|
giuliomoro@151
|
293 static float pastOffset = 0;
|
giuliomoro@151
|
294 float offsetIncrement = offset-pastOffset;
|
giuliomoro@151
|
295 if ( fabsf(offsetIncrement) > 1*expectedOffsetDifferenceStd && calls>51){
|
giuliomoro@151
|
296 // non-linear filtering: remove outliers
|
giuliomoro@151
|
297 nlOffset = pastOffset;
|
giuliomoro@151
|
298 // printf("%f %f 0,0,0,0,0,0\n", offset,pastOffset);
|
giuliomoro@151
|
299 } else {
|
giuliomoro@151
|
300 nlOffset=offset;
|
giuliomoro@151
|
301 }
|
giuliomoro@151
|
302 pastOffset=nlOffset;
|
giuliomoro@151
|
303 float iirOffset = iir.process(nlOffset);
|
giuliomoro@141
|
304 static float maxOffset=0;
|
giuliomoro@151
|
305 static float pastIirOffset=0;
|
giuliomoro@151
|
306 if( calls > 0 ) {
|
giuliomoro@151
|
307 maxOffset=fabsf(iirOffset) > fabsf(maxOffset) ? iirOffset : maxOffset;
|
giuliomoro@151
|
308 pid.setError(iirOffset);
|
giuliomoro@151
|
309 float correction=pid.getOutput()*0.0001;
|
giuliomoro@149
|
310 static float oldSamplingRate=44100;
|
giuliomoro@151
|
311 printf("%10.3f, %10.3f, %10.3f, %10.3f, %10.3f, %10.3f\n",
|
giuliomoro@151
|
312 offset, nlOffset, iirOffset, iirOffset - pastIirOffset, correction, oldSamplingRate); //unfiltered, filtered
|
giuliomoro@151
|
313 pastIirOffset = iirOffset;
|
giuliomoro@151
|
314 float targetSamplingRate;
|
giuliomoro@151
|
315 static int direction=1;
|
giuliomoro@151
|
316 float thresholdL = -1;
|
giuliomoro@151
|
317 // targetSamplingRate = oldSamplingRate - correction;
|
giuliomoro@151
|
318 float thresholdH = 3;
|
giuliomoro@151
|
319
|
giuliomoro@151
|
320 targetSamplingRate = 44100;
|
giuliomoro@151
|
321 if(
|
giuliomoro@151
|
322 (iirOffset > thresholdH && direction == 1) ||
|
giuliomoro@151
|
323 (iirOffset > thresholdL && direction == -1)
|
giuliomoro@151
|
324 ){
|
giuliomoro@151
|
325 targetSamplingRate = 44097;
|
giuliomoro@151
|
326 direction = -1;
|
giuliomoro@151
|
327 }
|
giuliomoro@151
|
328 else if (
|
giuliomoro@151
|
329 (iirOffset < -thresholdH && direction == -1) ||
|
giuliomoro@151
|
330 (iirOffset < -thresholdL && direction == 1)
|
giuliomoro@151
|
331 )
|
giuliomoro@151
|
332 {
|
giuliomoro@151
|
333 iirOffset = 44102;
|
giuliomoro@151
|
334 direction = 1;
|
giuliomoro@151
|
335 }
|
giuliomoro@151
|
336 #ifndef USE_JUCE
|
giuliomoro@151
|
337 if(oldSamplingRate != targetSamplingRate){
|
giuliomoro@151
|
338 gAudioCodec->setAudioSamplingRate(targetSamplingRate);
|
giuliomoro@151
|
339 }
|
giuliomoro@151
|
340 #endif
|
giuliomoro@149
|
341 oldSamplingRate=targetSamplingRate;
|
giuliomoro@141
|
342 }
|
giuliomoro@141
|
343 }
|
giuliomoro@141
|
344 calls++;
|
giuliomoro@141
|
345 }
|
giuliomoro@135
|
346 int ClockSync::masterHandleMessage(){
|
giuliomoro@135
|
347 switch(clockSyncType){
|
giuliomoro@135
|
348 case kDelayReq:
|
giuliomoro@135
|
349 //send kDelayResp
|
giuliomoro@135
|
350 setType(kDelayResp);
|
giuliomoro@135
|
351 setTimestamp(localTimestamp);
|
giuliomoro@135
|
352 send();
|
giuliomoro@135
|
353 expectedClockSyncType=kNone;
|
giuliomoro@141
|
354 return 1;
|
giuliomoro@135
|
355 break;
|
giuliomoro@141
|
356 default:
|
giuliomoro@141
|
357 return -1;
|
giuliomoro@135
|
358 }
|
giuliomoro@135
|
359 }
|
giuliomoro@135
|
360
|
giuliomoro@135
|
361 int ClockSync::sendReceiveLoop(){
|
giuliomoro@135
|
362 if(isSlave()==true){
|
giuliomoro@135
|
363 //printf("Waiting for a sync clockSync\n");
|
giuliomoro@135
|
364 } else { //if this is master
|
giuliomoro@151
|
365 usleep(30000); //this times (roughly) how often sync clockSyncs are being sent.
|
giuliomoro@135
|
366 int ret=masterSendSync();
|
giuliomoro@135
|
367 if(ret<=0)
|
giuliomoro@135
|
368 return -1;
|
giuliomoro@135
|
369 }
|
giuliomoro@135
|
370 int ret=receiveLoop();
|
giuliomoro@135
|
371 if(ret<=0)
|
giuliomoro@135
|
372 return -2;
|
giuliomoro@135
|
373 return 1;
|
giuliomoro@135
|
374 }
|
giuliomoro@135
|
375
|
giuliomoro@135
|
376
|