Bug fixed
@@ -16,7 +16,6 @@ | ||
16 | 16 | */ |
17 | 17 | public final static int JITTER_BUFFER = 1; |
18 | 18 | |
19 | - | |
20 | 19 | /** |
21 | 20 | * Constructor. Initializes the player. |
22 | 21 | * @throws PlayerException |
@@ -23,6 +23,6 @@ | ||
23 | 23 | * Sends a packet udp from an array of bytes |
24 | 24 | * @param data the data to send |
25 | 25 | */ |
26 | - public abstract void send(byte data[]); | |
26 | + public abstract void send(byte data[]) throws Exception; | |
27 | 27 | |
28 | 28 | } |
\ No newline at end of file |
@@ -65,7 +65,7 @@ | ||
65 | 65 | // Wait until receiving the data of a packet |
66 | 66 | socket.receive( packet ); |
67 | 67 | recv(packet); |
68 | - } catch (IOException e) { | |
68 | + } catch (Exception e) { | |
69 | 69 | e.printStackTrace(); |
70 | 70 | } |
71 | 71 | } |
@@ -85,13 +85,13 @@ | ||
85 | 85 | /* (non-Javadoc) |
86 | 86 | * @see iax.protocol.connection.IConnection#send(byte[]) |
87 | 87 | */ |
88 | - public void send(byte data[]) { | |
89 | - try { | |
88 | + public void send(byte data[]) throws Exception { | |
89 | +// try { | |
90 | 90 | DatagramPacket packet = new DatagramPacket(data, data.length, hostIAddr, port); |
91 | 91 | socket.send(packet); |
92 | - } catch (Exception e) { | |
93 | - e.printStackTrace(); | |
94 | - } | |
92 | +// } catch (Exception e) { | |
93 | +// e.printStackTrace(); | |
94 | +// } | |
95 | 95 | } |
96 | 96 | |
97 | 97 | } |
\ No newline at end of file |
@@ -498,6 +498,21 @@ | ||
498 | 498 | } |
499 | 499 | |
500 | 500 | /** |
501 | + * Gets a msgcount subclass | |
502 | + * @return the cause code as an integer. | |
503 | + * @throws FrameException | |
504 | + */ | |
505 | + public int getMsgCount() throws FrameException { | |
506 | + try { | |
507 | + byte data[] = (byte[])infoElements.get(new Integer(InfoElement.MSGCOUNT)); | |
508 | + ByteBuffer byteBuffer = new ByteBuffer(data); | |
509 | + return byteBuffer.get16bits(); | |
510 | + } catch (Exception e) { | |
511 | + throw new FrameException(e); | |
512 | + } | |
513 | + } | |
514 | + | |
515 | + /** | |
501 | 516 | * Gets the user name. |
502 | 517 | * @return The user name as string. |
503 | 518 | * @throws FrameException |
@@ -112,6 +112,8 @@ | ||
112 | 112 | ProtocolControlFrame protocolControlFrame = (ProtocolControlFrame) frame; |
113 | 113 | switch (protocolControlFrame.getSubclass()) { |
114 | 114 | case ProtocolControlFrame.ACCEPT_SC: |
115 | + protocolControlFrame.setCapability(call.getAudioFactory().getCodec()); | |
116 | + protocolControlFrame.setFormat(call.getAudioFactory().getCodec()); | |
115 | 117 | call.sendFullFrameAndWaitForAck(protocolControlFrame); |
116 | 118 | break; |
117 | 119 | default: |
@@ -27,11 +27,13 @@ | ||
27 | 27 | CallCommandRecvFacade.ack(call, protocolControlFrame); |
28 | 28 | break; |
29 | 29 | case ProtocolControlFrame.HANGUP_SC: |
30 | +// System.out.println("%%%%%%%%%%%%% CakkState#handleRecvFrame HANGUP_SC %%%%%%%%%%%%%%%%%%%%%%%"); | |
30 | 31 | CallCommandRecvFacade.hangup(call, protocolControlFrame); |
31 | 32 | call.setState(Initial.getInstance()); |
32 | 33 | call.endCall(); |
33 | 34 | break; |
34 | 35 | case ProtocolControlFrame.INVAL_SC: |
36 | +// System.out.println("%%%%%%%%%%%%% CakkState#handleRecvFrame INVAL_SC %%%%%%%%%%%%%%%%%%%%%%%"); | |
35 | 37 | call.setState(Initial.getInstance()); |
36 | 38 | call.endCall(); |
37 | 39 | break; |
@@ -15,6 +15,7 @@ | ||
15 | 15 | import iax.client.protocol.frame.ProtocolControlFrame; |
16 | 16 | import iax.client.protocol.peer.Peer; |
17 | 17 | import iax.client.protocol.peer.PeerException; |
18 | +import iax.client.protocol.peer.state.Unregistered; | |
18 | 19 | |
19 | 20 | import java.util.Iterator; |
20 | 21 | import java.util.Timer; |
@@ -31,7 +32,7 @@ | ||
31 | 32 | * Interval in milliseconds that the miniframe's timestamp is reset |
32 | 33 | */ |
33 | 34 | public static final int TIMESTAMP_MINIFRAME_RESET = 65536; |
34 | - | |
35 | + | |
35 | 36 | // Maximum size of a sequence number |
36 | 37 | private final int SEQNO_MAXSIZE = 256; |
37 | 38 | // ***** PING DESACTIVATED ***** |
@@ -41,9 +42,7 @@ | ||
41 | 42 | private final int RETRY_MAXCOUNT = 10; |
42 | 43 | //Peer's retry refresh in seconds |
43 | 44 | private final int RETRY_REFRESH = 1; |
44 | - | |
45 | - private final int MAX_FAILURE = 5; | |
46 | - | |
45 | + private final int MAX_CONTINUAL_FAILURE = 0; | |
47 | 46 | // HashMap with the frames that are waiting for an ack |
48 | 47 | private ConcurrentHashMap<Long, FullFrame> framesWaitingAck; |
49 | 48 | // HashMap with the frames that are waiting for a specific reply |
@@ -89,8 +88,7 @@ | ||
89 | 88 | |
90 | 89 | private boolean callTokenReceived = false; |
91 | 90 | |
92 | - private int failureCount = 0; | |
93 | - | |
91 | + private int continualFailureCount = 0; | |
94 | 92 | /** |
95 | 93 | * Constructor. Initialize the player and the recorder |
96 | 94 | * @param peer the peer that handles this call |
@@ -298,6 +296,7 @@ | ||
298 | 296 | * Ends a call. For that stops the player and the recorder, and notifies the peer that this call is finished |
299 | 297 | */ |
300 | 298 | public void endCall() { |
299 | +// System.out.println("%%%%%%%%%%%%%%%%% Call#endCall called %%%%%%%%%%%%%%%%%%%%%%%%%"); | |
301 | 300 | // ***** PING DESACTIVATED ***** |
302 | 301 | // pingTimer.cancel(); |
303 | 302 | retryTimer.cancel(); |
@@ -430,6 +429,7 @@ | ||
430 | 429 | */ |
431 | 430 | public synchronized void ackedFrame(long timeStamp) { |
432 | 431 | framesWaitingAck.remove(new Long(timeStamp)); |
432 | + continualFailureCount = 0; | |
433 | 433 | } |
434 | 434 | |
435 | 435 | /** |
@@ -438,6 +438,7 @@ | ||
438 | 438 | */ |
439 | 439 | public synchronized void repliedFrame(int id) { |
440 | 440 | framesWaitingReply.remove(new Integer(id)); |
441 | + continualFailureCount = 0; | |
441 | 442 | } |
442 | 443 | |
443 | 444 | /** |
@@ -468,7 +469,7 @@ | ||
468 | 469 | peer.sendFrame(fullFrame); |
469 | 470 | } |
470 | 471 | |
471 | - static int x = 0; | |
472 | +// static int x = 0; | |
472 | 473 | /** |
473 | 474 | * Plays audio from the audio frames received through the player. If the player is stopped, starts it. |
474 | 475 | * @param timestamp the timestamp of the frame |
@@ -475,7 +476,7 @@ | ||
475 | 476 | * @param data the audio data of the frame |
476 | 477 | * @param absolute if the timestamp absolute or not |
477 | 478 | */ |
478 | - public void writeAudioIn(long timestamp, byte[] data, boolean absolute) { | |
479 | + public synchronized void writeAudioIn(long timestamp, byte[] data, boolean absolute) { | |
479 | 480 | if (!hold) { |
480 | 481 | if (!playing) { |
481 | 482 | player.play(); |
@@ -501,8 +502,8 @@ | ||
501 | 502 | retryFullFrame.incRetryCount(); |
502 | 503 | if (retryFullFrame.getRetryCount() < RETRY_MAXCOUNT) { |
503 | 504 | peer.sendFrame(retryFullFrame); |
504 | - failureCount = 0; | |
505 | 505 | } else{ |
506 | + iterator.remove(); | |
506 | 507 | throw new PeerException("Reached retries maximun in the call " + srcCallNo + |
507 | 508 | " for a full frame of type " + retryFullFrame.getFrameType() + ", subclass " + retryFullFrame.getSubclass()); |
508 | 509 | } |
@@ -513,19 +514,24 @@ | ||
513 | 514 | retryFullFrame.incRetryCount(); |
514 | 515 | if (retryFullFrame.getRetryCount() < RETRY_MAXCOUNT) { |
515 | 516 | peer.sendFrame(retryFullFrame); |
516 | - failureCount = 0; | |
517 | 517 | } else { |
518 | + iterator.remove(); | |
518 | 519 | throw new PeerException("Reached retries maximun in the call " + srcCallNo + |
519 | 520 | " for a full frame of type " + retryFullFrame.getFrameType() + ", subclass " + retryFullFrame.getSubclass()); |
520 | 521 | } |
521 | 522 | } |
522 | 523 | } catch (PeerException e) { |
523 | - framesWaitingAck.clear(); | |
524 | - framesWaitingReply.clear(); | |
525 | - if (failureCount++ >= MAX_FAILURE){ | |
526 | - endCall(); // RgAEgµÄ¢½ | |
527 | - } | |
528 | - e.printStackTrace(); // RgAEgµÄ¢½ | |
524 | +// if (continualFailureCount < MAX_CONTINUAL_FAILURE) { | |
525 | +// continualFailureCount++; | |
526 | +// } else { | |
527 | +// System.out.println("%%%%%%%%%%%%%%%%% retryFramesWaiting retry over %%%%%%%%%%%%%%%%%%%%%%%%%"); | |
528 | + framesWaitingAck.clear(); | |
529 | + framesWaitingReply.clear(); | |
530 | + CallCommandSendFacade.hangup(this); | |
531 | + endCall(); | |
532 | + peer.setState(Unregistered.getInstance()); | |
533 | +// } | |
534 | + e.printStackTrace(); | |
529 | 535 | } |
530 | 536 | } |
531 | 537 |
@@ -537,7 +543,6 @@ | ||
537 | 543 | } |
538 | 544 | |
539 | 545 | public void listen(final byte[] buffer, int length) { |
540 | - // TODO think about length | |
541 | 546 | CallCommandSendFacade.sendVoice(this, buffer); |
542 | 547 | } |
543 | 548 |
@@ -549,12 +554,10 @@ | ||
549 | 554 | return dtmfCode; |
550 | 555 | } |
551 | 556 | |
552 | - | |
553 | 557 | public AudioFactory getAudioFactory() { |
554 | 558 | return audioFactory; |
555 | 559 | } |
556 | 560 | |
557 | - | |
558 | 561 | public void setAudioFactory(AudioFactory audioFactory) { |
559 | 562 | this.audioFactory = audioFactory; |
560 | 563 | } |
@@ -575,14 +578,12 @@ | ||
575 | 578 | this.recorder = recorder; |
576 | 579 | } |
577 | 580 | |
578 | - | |
579 | 581 | public boolean isCallTokenReceived() { |
580 | 582 | return callTokenReceived; |
581 | 583 | } |
582 | 584 | |
583 | - | |
584 | 585 | public void setCallTokenReceived(boolean callTokenReceived) { |
585 | 586 | this.callTokenReceived = callTokenReceived; |
586 | 587 | } |
587 | - | |
588 | + | |
588 | 589 | } |
\ No newline at end of file |
@@ -1,7 +1,6 @@ | ||
1 | 1 | package iax.client.protocol.call.command.send; |
2 | 2 | |
3 | 3 | import iax.client.protocol.call.Call; |
4 | -import iax.client.protocol.frame.FrameException; | |
5 | 4 | import iax.client.protocol.frame.ProtocolControlFrame; |
6 | 5 | |
7 | 6 | /** |
@@ -27,7 +26,7 @@ | ||
27 | 26 | } |
28 | 27 | |
29 | 28 | public void run() { |
30 | - ProtocolControlFrame acceptFrame = new ProtocolControlFrame(call.getSrcCallNo(), | |
29 | + call.handleSendFrame(new ProtocolControlFrame(call.getSrcCallNo(), | |
31 | 30 | false, |
32 | 31 | call.getDestCallNo(), |
33 | 32 | recvCallFrame.getTimestamp(), |
@@ -34,21 +33,6 @@ | ||
34 | 33 | recvCallFrame.getOseqno(), |
35 | 34 | recvCallFrame.getIseqno(), |
36 | 35 | false, |
37 | - ProtocolControlFrame.ACCEPT_SC); | |
38 | - try { | |
39 | - acceptFrame.setCapability(call.getAudioFactory().getCodec()); | |
40 | - acceptFrame.setFormat(call.getAudioFactory().getCodec()); | |
41 | - call.handleSendFrame(acceptFrame); | |
42 | - } catch (FrameException e) { | |
43 | - e.printStackTrace(); | |
44 | - } | |
45 | -// call.handleSendFrame(new ProtocolControlFrame(call.getSrcCallNo(), | |
46 | -// false, | |
47 | -// call.getDestCallNo(), | |
48 | -// recvCallFrame.getTimestamp(), | |
49 | -// recvCallFrame.getOseqno(), | |
50 | -// recvCallFrame.getIseqno(), | |
51 | -// false, | |
52 | -// ProtocolControlFrame.ACCEPT_SC)); | |
36 | + ProtocolControlFrame.ACCEPT_SC)); | |
53 | 37 | } |
54 | 38 | } |
@@ -36,7 +36,10 @@ | ||
36 | 36 | PeerCommandRecvFacade.regack(peer, protocolControlFrame); |
37 | 37 | if (peer.isProcessingExit()) |
38 | 38 | peer.setState(Unregistered.getInstance()); |
39 | - else peer.setState(Registered.getInstance()); | |
39 | + else { | |
40 | + peer.setMsgCount(protocolControlFrame.getMsgCount()); | |
41 | + peer.setState(Registered.getInstance()); | |
42 | + } | |
40 | 43 | break; |
41 | 44 | case ProtocolControlFrame.REGAUTH_SC: |
42 | 45 | if (peer.isProcessingExit()) |
@@ -39,7 +39,9 @@ | ||
39 | 39 | //Peer's retry refresh in seconds |
40 | 40 | private final int RETRY_REFRESH = 1; |
41 | 41 | //Peer's retry max |
42 | - private final int RETRY_MAXCOUNT = 10; | |
42 | + private final int RETRY_MAXCOUNT = 5; | |
43 | + | |
44 | +// private final int MAX_CONTINUAL_FAILURE = 2; | |
43 | 45 | |
44 | 46 | //Registration user name. |
45 | 47 | private String userName; |
@@ -64,7 +66,7 @@ | ||
64 | 66 | //Source timestamp for full frames from the first full frame sent by this call |
65 | 67 | private long srcTimestamp; |
66 | 68 | //Register timer task |
67 | - private Timer registerTimer; | |
69 | + private Timer registerTimer = null; | |
68 | 70 | //Retry timer task to retry frames not committed whit a specific frame or an ack frame |
69 | 71 | private Timer retryTimer; |
70 | 72 | //Flag for determining if the peer is processing the exit |
@@ -71,8 +73,16 @@ | ||
71 | 73 | private boolean processingExit; |
72 | 74 | //Max calls |
73 | 75 | // private int maxCalls; |
76 | +// private int continualFailureCount = 0; | |
74 | 77 | |
78 | + private int regRefresh = 5; | |
79 | + | |
80 | + // How many messages waiting | |
81 | + private int msgCount = 0; | |
82 | + | |
75 | 83 | private AudioFactory audioFactory; |
84 | + | |
85 | + private boolean reconnectFlag = false; | |
76 | 86 | |
77 | 87 | /** |
78 | 88 | * Constructor. Initializes the peer with the given values.Using NullAudioFactory class and J2SEConnection class |
@@ -141,17 +151,23 @@ | ||
141 | 151 | } |
142 | 152 | }; |
143 | 153 | retryTimer.schedule(retryTimerTask, RETRY_REFRESH*1000, RETRY_REFRESH*1000); |
144 | - this.registerTimer = new Timer(); | |
145 | - if (register) { | |
146 | - TimerTask registerTimerTask = new TimerTask() { | |
147 | - public void run() { | |
148 | - register(); | |
149 | - } | |
150 | - }; | |
151 | - registerTimer.schedule(registerTimerTask, 0, REGISTER_REFRESH*1000); | |
152 | - } | |
154 | + setRegisterSchedule(); | |
153 | 155 | } |
154 | 156 | |
157 | + private void setRegisterSchedule() { | |
158 | + if (registerTimer != null){ | |
159 | + registerTimer.cancel(); | |
160 | + } | |
161 | + registerTimer = new Timer(); | |
162 | + TimerTask registerTimerTask = new TimerTask() { | |
163 | + public void run() { | |
164 | + register(); | |
165 | + } | |
166 | + }; | |
167 | +// System.out.println("VVVVVVVVVVVVVVVVVVVV setRegisterSchedule regRefresh = " + regRefresh + " VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"); | |
168 | + registerTimer.schedule(registerTimerTask, 0, regRefresh * 1000); | |
169 | + } | |
170 | + | |
155 | 171 | /** |
156 | 172 | * Gets peer user name. |
157 | 173 | * @return String with user name. |
@@ -192,6 +208,8 @@ | ||
192 | 208 | public long getTimestamp() { |
193 | 209 | long now = System.currentTimeMillis(); |
194 | 210 | return now-srcTimestamp; |
211 | +// srcTimestamp += 20; | |
212 | +// return srcTimestamp; | |
195 | 213 | } |
196 | 214 | |
197 | 215 | /** |
@@ -208,12 +226,19 @@ | ||
208 | 226 | */ |
209 | 227 | public void setState(PeerState state) { |
210 | 228 | this.state = state; |
211 | - if (state instanceof Registered) | |
229 | + if (state instanceof Registered) { | |
212 | 230 | peerListener.registered(); |
213 | - else if (state instanceof Waiting) | |
231 | + if (regRefresh != REGISTER_REFRESH) { | |
232 | + regRefresh = REGISTER_REFRESH; | |
233 | + setRegisterSchedule(); | |
234 | + } | |
235 | + } else if (state instanceof Waiting) { | |
214 | 236 | peerListener.waiting(); |
215 | - else if (state instanceof Unregistered) | |
237 | + } else if (state instanceof Unregistered) { | |
216 | 238 | peerListener.unregistered(); |
239 | + regRefresh = 5; | |
240 | + setRegisterSchedule(); | |
241 | + } | |
217 | 242 | } |
218 | 243 | |
219 | 244 |
@@ -231,6 +256,7 @@ | ||
231 | 256 | */ |
232 | 257 | public synchronized void ackedFrame(long timeStamp) { |
233 | 258 | framesWaitingAck.remove(new Long(timeStamp)); |
259 | +// continualFailureCount = 0; | |
234 | 260 | } |
235 | 261 | |
236 | 262 | /** |
@@ -239,6 +265,7 @@ | ||
239 | 265 | */ |
240 | 266 | public synchronized void repliedFrame(int id) { |
241 | 267 | framesWaitingReply.remove(new Integer(id)); |
268 | +// continualFailureCount = 0; | |
242 | 269 | } |
243 | 270 | |
244 | 271 | /** |
@@ -246,6 +273,7 @@ | ||
246 | 273 | */ |
247 | 274 | public void register() { |
248 | 275 | srcTimestamp = System.currentTimeMillis(); |
276 | +// srcTimestamp = 0; | |
249 | 277 | PeerCommandSendFacade.regreq(this); |
250 | 278 | } |
251 | 279 |
@@ -358,6 +386,10 @@ | ||
358 | 386 | try { |
359 | 387 | connection.send(frame.serialize()); |
360 | 388 | } catch (Exception e) { |
389 | + if (call != null) { | |
390 | + call.endCall(); | |
391 | + } | |
392 | + setState(Unregistered.getInstance()); | |
361 | 393 | e.printStackTrace(); |
362 | 394 | } |
363 | 395 | } |
@@ -411,6 +443,7 @@ | ||
411 | 443 | * @param call The call to end. |
412 | 444 | */ |
413 | 445 | public void endCall(Call call) { |
446 | +// System.out.println("%%%%%%%%%%%%%%%%% Peer#endCall called %%%%%%%%%%%%%%%%%%%%%%%%%"); | |
414 | 447 | peerListener.hungup(call.getCalledNumber()); |
415 | 448 | this.call = null; |
416 | 449 | } |
@@ -421,8 +454,7 @@ | ||
421 | 454 | * @return The new call. |
422 | 455 | * @throws PeerException |
423 | 456 | */ |
424 | - //public synchronized Call newCall(String calledNumber) throws PeerException { | |
425 | - public Call newCall(String calledNumber) throws PeerException { | |
457 | + public synchronized Call newCall(String calledNumber) throws PeerException { | |
426 | 458 | if (call == null && peerListener.isEnabled()) { |
427 | 459 | Call newCall = null; |
428 | 460 | try { |
@@ -483,8 +515,15 @@ | ||
483 | 515 | retryFullFrame.incRetryCount(); |
484 | 516 | if (retryFullFrame.getRetryCount() < RETRY_MAXCOUNT) { |
485 | 517 | sendFrame(retryFullFrame); |
486 | - } else throw new PeerException("Reached retries maximun in the peer for full frame of type " + | |
487 | - retryFullFrame.getFrameType() + ", subclass " + retryFullFrame.getSubclass()); | |
518 | + } else { | |
519 | + iterator.remove(); | |
520 | + if (retryFullFrame.getFrameType() == 6 | |
521 | + && retryFullFrame.getSubclass() == 13){ | |
522 | + reconnectFlag = true; | |
523 | + } | |
524 | + throw new PeerException("Reached retries maximun in the peer for full frame of type " + | |
525 | + retryFullFrame.getFrameType() + ", subclass " + retryFullFrame.getSubclass()); | |
526 | + } | |
488 | 527 | } |
489 | 528 | iterator = framesWaitingReply.values().iterator(); |
490 | 529 | while (iterator.hasNext()) { |
@@ -492,15 +531,39 @@ | ||
492 | 531 | retryFullFrame.incRetryCount(); |
493 | 532 | if (retryFullFrame.getRetryCount() < RETRY_MAXCOUNT) { |
494 | 533 | sendFrame(retryFullFrame); |
495 | - } else throw new PeerException("Reached retries maximun in the peer for full frame of type " + | |
534 | + } else { | |
535 | + iterator.remove(); | |
536 | + if (retryFullFrame.getFrameType() == 6 | |
537 | + && retryFullFrame.getSubclass() == 13){ | |
538 | + reconnectFlag = true; | |
539 | + } | |
540 | + throw new PeerException("Reached retries maximun in the peer for full frame of type " + | |
496 | 541 | retryFullFrame.getFrameType() + ", subclass " + retryFullFrame.getSubclass()); |
542 | + } | |
497 | 543 | } |
498 | 544 | } catch (PeerException e) { |
499 | 545 | framesWaitingAck.clear(); |
500 | 546 | framesWaitingReply.clear(); |
501 | - setState(Unregistered.getInstance()); | |
547 | + setState(Unregistered.getInstance()); | |
502 | 548 | e.printStackTrace(); |
503 | 549 | } |
504 | 550 | } |
551 | + | |
552 | + /** | |
553 | + * @return the msgCount | |
554 | + */ | |
555 | + public int getMsgCount() { | |
556 | + return msgCount; | |
557 | + } | |
558 | + | |
559 | + /** | |
560 | + * @param msgCount the msgCount to set | |
561 | + */ | |
562 | + public void setMsgCount(int msgCount) { | |
563 | + this.msgCount = msgCount; | |
564 | + } | |
505 | 565 | |
566 | + public boolean isReconnect() { | |
567 | + return reconnectFlag; | |
568 | + } | |
506 | 569 | } |
\ No newline at end of file |