/** * Inherited from TransactionClientListener. When the TransactionClientListener goes into the * "Completed" state, receiving a failure response * * <p>If called for a INVITE transaction, it moves to D_CLOSE state, removes the listener from * SipProvider. * * <p>If called for a BYE transaction, it moves to D_CLOSE state, removes the listener from * SipProvider, and fires <i>onClose(this,msg)</i>. */ public void onTransFailureResponse(TransactionClient tc, Message msg) { printLog("inside onTransFailureResponse(" + tc.getTransactionId() + ",msg)", LogLevel.LOW); if (tc.getTransactionMethod().equals(SipMethods.INVITE)) { if (!verifyStatus(statusIs(D_INVITING) || statusIs(D_ReINVITING))) return; StatusLine statusline = msg.getStatusLine(); int code = statusline.getCode(); verifyThat(code >= 300 && code < 700, "error code was expected"); if (statusIs(D_ReINVITING)) { changeStatus(D_CALL); listener.onDlgReInviteFailureResponse(this, code, statusline.getReason(), msg); } else { changeStatus(D_CLOSE); if (code >= 300 && code < 400) listener.onDlgInviteRedirectResponse( this, code, statusline.getReason(), msg.getContacts(), msg); else listener.onDlgInviteFailureResponse(this, code, statusline.getReason(), msg); listener.onDlgClose(this); } } else if (tc.getTransactionMethod().equals(SipMethods.BYE)) { if (!verifyStatus(statusIs(D_BYEING))) return; StatusLine statusline = msg.getStatusLine(); int code = statusline.getCode(); verifyThat(code >= 300 && code < 700, "error code was expected"); changeStatus(InviteDialog.D_CALL); listener.onDlgByeFailureResponse(this, code, statusline.getReason(), msg); } }
/** Sends a Message */ public void sendMessage(Message msg) throws IOException { if (tcp_conn != null) { last_time = System.currentTimeMillis(); byte[] data = msg.toString().getBytes(); Log.e("Final Message: ", msg.toString()); int endindex = msg.toString().indexOf("image/jpeg") + 10; String headers = msg.toString().substring(0, endindex) + "\n \n"; Log.e("Initial Header:", headers); byte[] headerBytes = headers.getBytes(); byte[] imageBytes = JpegImage.imageBytes; byte[] finalBytes = new byte[headerBytes.length + imageBytes.length]; System.arraycopy(headerBytes, 0, finalBytes, 0, headerBytes.length); System.arraycopy(imageBytes, 0, finalBytes, headerBytes.length, imageBytes.length); // for(int i=0;i<headerBytes.length;i++){ // finalBytes[i] = headerBytes[i]; // } // int j=0; // for(int i=headerBytes.length;j<(imageBytes.length);i++){ // finalBytes[i]=imageBytes[j]; // j++; // } // Log.e("ImageBytes: ", // "Length:"+String.valueOf(finalBytes[finalBytes.length])+"read:"+String.valueOf(imageBytes[imageBytes.length])); Log.e("Modified headers: ", headers); // tcp_conn.send(data); Log.e("TCPTransport: ", "Total Image length=" + finalBytes.length); tcp_conn.send(finalBytes); } }
public void routeSIP(final Message message, final JID sender) { for (final SipRoutingListener routingListener : routingListeners) { routingListener.routingSIP(message, sender); } // Route Packet final byte[] bytes; try { final String msg = message.toString(); bytes = msg.getBytes("UTF-8"); final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); final SocketAddress destination = getDestinationAddress(message, sender); if (destination == null) { log.warn("Discarding Packet Without Destination: " + msg); return; } try { SipChannel c = message.getArrivedAt(); if (c == null) { c = channels.get(getSipChannelID(sender)); } if (sender != null && c == null) { log.debug("Creating SIP Channel for: " + sender); c = createSipChannel(sender, destination); } if (c == null) { log.warn("Could NOT Bind Message to any SipChannel."); return; } log.debug("Sending SIP: " + msg); c.send(byteBuffer, destination); updateKeepAliveTargets(destination); for (final SipRoutingListener routingListener : getRoutingListeners()) { routingListener.routedSIP(message, sender); } } catch (Exception e) { log.warn("Unresolved Address.", e); for (final SipRoutingListener routingListener : getRoutingListeners()) { routingListener.routingError(message, sender, SipRoutingError.unresolvedAddress); } } } catch (UnsupportedEncodingException e) { log.error("Packet Encoding Error.", e); } }
/** * Inherited from TransactionClientListener. When an TransactionClientListener goes into the * "Terminated" state, receiving a 2xx response * * <p>If called for a INVITE transaction, it updates the dialog information, moves to D_CALL * state, add a listener to the SipProvider, creates a new AckTransactionClient(ack,this), and * fires <i>onSuccessResponse(this,code,body,msg)</i>. * * <p>If called for a BYE transaction, it moves to D_CLOSE state, removes the listener from * SipProvider, and fires <i>onClose(this,msg)</i>. */ public void onTransSuccessResponse(TransactionClient tc, Message msg) { printLog("inside onTransSuccessResponse(tc,msg)", LogLevel.LOW); if (tc.getTransactionMethod().equals(SipMethods.INVITE)) { if (!verifyStatus(statusIs(D_INVITING) || statusIs(D_ReINVITING))) return; StatusLine statusline = msg.getStatusLine(); int code = statusline.getCode(); if (!verifyThat( code >= 200 && code < 300 && msg.getTransactionMethod().equals(SipMethods.INVITE), "2xx for invite was expected")) return; boolean re_inviting = statusIs(D_ReINVITING); changeStatus(D_CALL); update(Dialog.UAC, msg); if (invite_offer) { // invite_req=MessageFactory.createRequest(SipMethods.ACK,dialog_state,sdp.toString()); // ack=MessageFactory.createRequest(this,SipMethods.ACK,null); ack_req = MessageFactory.create2xxAckRequest(this, null); AckTransactionClient ack_tc = new AckTransactionClient(sip_provider, ack_req, null); ack_tc.request(); } if (!re_inviting) { listener.onDlgInviteSuccessResponse(this, code, statusline.getReason(), msg.getBody(), msg); listener.onDlgCall(this); } else listener.onDlgReInviteSuccessResponse( this, code, statusline.getReason(), msg.getBody(), msg); } else if (tc.getTransactionMethod().equals(SipMethods.BYE)) { if (!verifyStatus(statusIs(D_BYEING))) return; StatusLine statusline = msg.getStatusLine(); int code = statusline.getCode(); verifyThat(code >= 200 && code < 300, "2xx for bye was expected"); changeStatus(D_CLOSE); listener.onDlgByeSuccessResponse(this, code, statusline.getReason(), msg); listener.onDlgClose(this); } }
/** * Method derived from interface SipListener. It's fired from the SipProvider when a new message * is received for to the present TransactionClient. */ public void onReceivedMessage(SipProvider provider, Message msg) { if (msg.isResponse()) { int code = msg.getStatusLine().getCode(); if (code >= 100 && code < 200 && (statusIs(STATE_TRYING) || statusIs(STATE_PROCEEDING))) { if (statusIs(STATE_TRYING)) changeStatus(STATE_PROCEEDING); if (transaction_listener != null) transaction_listener.onTransProvisionalResponse(this, msg); return; } if (code >= 200 && code < 700 && (statusIs(STATE_TRYING) || statusIs(STATE_PROCEEDING))) { retransmission_to.halt(); transaction_to.halt(); changeStatus(STATE_COMPLETED); if (code < 300) { if (transaction_listener != null) transaction_listener.onTransSuccessResponse(this, msg); } else { if (transaction_listener != null) transaction_listener.onTransFailureResponse(this, msg); } transaction_listener = null; if (true || connection_id == null) // modified clearing_to.start(); else { printLog("clearing_to=0 for reliable transport", LogLevel.LOW); onTimeout(clearing_to); } return; } } }
/** When a new Message is received by the SipProvider. */ public void onReceivedMessage(SipProvider provider, Message msg) { printLog("onReceivedMessage()", LogLevel.MEDIUM); if (statusIs(D_TERMINATED)) { printLog("subscription already terminated: message discarded", LogLevel.MEDIUM); return; } // else if (msg.isRequest() && msg.isSubscribe()) { if (statusIs(NotifierDialog.D_WAITING)) { // the first SUBSCRIBE // request changeStatus(D_SUBSCRIBED); sip_provider.removeSipProviderListener(new MethodIdentifier(SipMethods.SUBSCRIBE)); } subscribe_req = msg; NameAddress target = msg.getToHeader().getNameAddress(); NameAddress subscriber = msg.getFromHeader().getNameAddress(); EventHeader eh = msg.getEventHeader(); if (eh != null) { event = eh.getEvent(); id = eh.getId(); } update(UAS, msg); subscribe_transaction = new TransactionServer(sip_provider, msg, null); if (listener != null) listener.onDlgSubscribe(this, target, subscriber, event, id, msg); } else { printLog("message is not a SUBSCRIBE: message discarded", LogLevel.HIGH); } }
/** When the delivery fails. */ private void onDeliveryFailure(TransactionClient tc, String result) { printLog("Message delivery failed (" + result + ")."); Message req = tc.getRequestMessage(); NameAddress recipient = req.getToHeader().getNameAddress(); String subject = null; if (req.hasSubjectHeader()) subject = req.getSubjectHeader().getSubject(); if (listener != null) listener.onMaDeliveryFailure(this, recipient, subject, result); }
/** * Inherited from TransactionClientListener. When the TransactionClientListener is in "Proceeding" * state and receives a new 1xx response * * <p>For INVITE transaction it fires <i>onFailureResponse(this,code,reason,body,msg)</i>. */ public void onTransProvisionalResponse(TransactionClient tc, Message msg) { printLog("inside onTransProvisionalResponse(tc,mdg)", LogLevel.LOW); if (tc.getTransactionMethod().equals(SipMethods.INVITE)) { StatusLine statusline = msg.getStatusLine(); listener.onDlgInviteProvisionalResponse( this, statusline.getCode(), statusline.getReason(), msg.getBody(), msg); } }
/** Terminates the subscription (subscription goes into 'terminated' state). */ public void terminate(String reason) { Message req = MessageFactory.createNotifyRequest(this, event, id, null, null); SubscriptionStateHeader sh = new SubscriptionStateHeader(TERMINATED); if (reason != null) sh.setReason(reason); // sh.setExpires(0); req.setSubscriptionStateHeader(sh); notify(req); }
/** Sends a NOTIFY. */ public void notify(String state, int expires, String content_type, String body) { Message req = MessageFactory.createNotifyRequest(this, event, id, content_type, body); if (state != null) { SubscriptionStateHeader sh = new SubscriptionStateHeader(state); if (expires >= 0) sh.setExpires(expires); req.setSubscriptionStateHeader(sh); } notify(req); }
/** * Responds with <i>resp</i>. This method can be called when the InviteDialog is in D_INVITED or * D_BYED states. * * <p>If the CSeq method is INVITE and the response is 2xx, it moves to state D_ACCEPTED, adds a * new listener to the SipProviderListener, and creates new AckTransactionServer * * <p>If the CSeq method is INVITE and the response is not 2xx, it moves to state D_REFUSED, and * sends the response. */ public void respond(Message resp) // private void respond(Message resp) { printLog("inside respond(resp)", LogLevel.MEDIUM); String method = resp.getCSeqHeader().getMethod(); if (method.equals(SipMethods.INVITE)) { if (!verifyStatus(statusIs(D_INVITED) || statusIs(D_ReINVITED))) { printLog( "respond(): InviteDialog not in (re)invited state: No response now", LogLevel.HIGH); return; } int code = resp.getStatusLine().getCode(); // 1xx provisional responses if (code >= 100 && code < 200) { invite_ts.respondWith(resp); return; } // For all final responses establish the dialog if (code >= 200) { // changeStatus(D_ACCEPTED); update(Dialog.UAS, resp); } // 2xx success responses if (code >= 200 && code < 300) { if (statusIs(D_INVITED)) changeStatus(D_ACCEPTED); else changeStatus(D_ReACCEPTED); // terminates the INVITE Transaction server and activates an ACK // Transaction server invite_ts.terminate(); ConnectionIdentifier conn_id = invite_ts.getConnectionId(); ack_ts = new AckTransactionServer(sip_provider, conn_id, resp, this); ack_ts.respond(); // if (statusIs(D_ReACCEPTED)) // listener.onDlgReInviteAccepted(this); // else listener.onDlgAccepted(this); return; } else // 300-699 failure responses // if (code>=300) { if (statusIs(D_INVITED)) changeStatus(D_REFUSED); else changeStatus(D_ReREFUSED); invite_ts.respondWith(resp); // if (statusIs(D_ReREFUSED)) // listener.onDlgReInviteRefused(this); // else listener.onDlgRefused(this); return; } } if (method.equals(SipMethods.BYE)) { if (!verifyStatus(statusIs(D_BYED))) return; bye_ts.respondWith(resp); } }
/** Method derived from interface SipListener. */ public void onReceivedMessage(SipProvider provider, Message msg) { if (msg.isRequest() && msg.isInvite()) { if (listener != null) listener.onNewInviteDialog( this, new InviteDialog(sip_provider, msg, listener), msg.getToHeader().getNameAddress(), msg.getFromHeader().getNameAddress(), msg.getBody(), msg); } }
/** * Responds with <i>code</i> and <i>reason</i>. This method can be called when the InviteDialog is * in D_INVITED, D_ReINVITED states */ public void respond( int code, String reason, int expires, String contact, String content_type, String body) { printLog("inside respond(" + code + "," + reason + ")", LogLevel.MEDIUM); NameAddress contact_url = null; if (contact != null) contact_url = new NameAddress(contact); Message resp = MessageFactory.createResponse( subscribe_req, code, SipResponses.reasonOf(code), contact_url); if (expires >= 0) resp.setExpiresHeader(new ExpiresHeader(expires)); if (body != null) resp.setBody(content_type, body); respond(resp); }
/** * Inherited from TransactionServerListener. When the TransactionServer goes into the "Trying" * state receiving a request * * <p>If called for a INVITE transaction, it initializes the dialog information, <br> * moves to D_INVITED state, and add a listener to the SipProvider, <br> * and fires <i>onInvite(caller,body,msg)</i>. */ public void onTransRequest(TransactionServer ts, Message req) { printLog("inside onTransRequest(ts,msg)", LogLevel.LOW); if (ts.getTransactionMethod().equals(SipMethods.INVITE)) { if (!verifyStatus(statusIs(D_WAITING))) return; changeStatus(D_INVITED); invite_req = req; update(Dialog.UAS, invite_req); listener.onDlgInvite( this, invite_req.getToHeader().getNameAddress(), invite_req.getFromHeader().getNameAddress(), invite_req.getBody(), invite_req); } }
/** When a new Message is received by the SipProvider. */ public void onReceivedMessage(SipProvider provider, Message msg) { // printLog("onReceivedMessage()", LogLevel.MEDIUM); if (statusIs(D_TERMINATED)) { printLog("subscription already terminated: message discarded", LogLevel.MEDIUM); return; } // else if (msg.isRequest() && msg.isSubscribe()) { if (statusIs(NotifierDialog.D_WAITING)) { // the first SUBSCRIBE // request changeStatus(D_SUBSCRIBED); sip_provider.removeSipProviderListener(new MethodIdentifier(SipMethods.SUBSCRIBE)); } subscribe_req = msg; NameAddress target = msg.getToHeader().getNameAddress(); NameAddress subscriber = msg.getFromHeader().getNameAddress(); EventHeader eh = msg.getEventHeader(); if (eh != null) { event = eh.getEvent(); id = eh.getId(); } // ==> jinsub for presence server if (event.endsWith("presence")) { notifyEvent = target.toString(); } // update(UAS, msg); // System.out.println("����� ��¿��?"); // subscribe_transaction = new TransactionServer(sip_provider, msg, null); if (listener != null) // Here is going to add vector_key listener.onDlgSubscribe(this, target, subscriber, event, id, msg); } else if (msg.isRequest() && msg.isPublish()) { // ==> jinsub for presence server NameAddress target = msg.getToHeader().getNameAddress(); NameAddress publisher = msg.getFromHeader().getNameAddress(); EventHeader eh = msg.getEventHeader(); if (eh.getEvent().endsWith(event) && target.toString().endsWith(notifyEvent)) { // System.out.println("����� ��¿��2?"); // publish_transaction = new TransactionServer(sip_provider, msg, null); if (listener != null) listener.onDlgPublish(this, target, publisher, event, id, msg); } // } else { printLog("message is not a SUBSCRIBE: message discarded", LogLevel.HIGH); } }
/** * Re-invites the remote user. * * <p>Starts a new InviteTransactionClient and changes the dialog state information * * <p>Parameters: <br> * - contact : the contact url OR the contact username; if null, the previous contact is used <br> * - session_descriptor : the message body */ public void reInvite(String contact, String session_descriptor) { printLog("inside reInvite(contact,sdp)", LogLevel.MEDIUM); if (!statusIs(D_CALL)) return; // else Message invite = MessageFactory.createInviteRequest(this, session_descriptor); if (contact != null) { NameAddress contact_url; if (contact.indexOf("sip:") >= 0) contact_url = new NameAddress(contact); else contact_url = new NameAddress( new SipURL(contact, sip_provider.getViaAddress(), sip_provider.getPort())); invite.setContactHeader(new ContactHeader(contact_url)); } reInvite(invite); }
/** * Responds with <i>code</i> and <i>reason</i>. This method can be called when the InviteDialog is * in D_INVITED, D_ReINVITED states */ public void respond(int code, String reason, String contact, String sdp) { printLog("inside respond(" + code + "," + reason + ")", LogLevel.MEDIUM); if (statusIs(D_INVITED) || statusIs(D_ReINVITED)) { NameAddress contact_address = null; if (contact != null) contact_address = new NameAddress(contact); Message resp = MessageFactory.createResponse(invite_req, code, reason, contact_address); resp.setBody(sdp); respond(resp); } else printWarning( "Dialog isn't in \"invited\" state: cannot respond (" + code + "/" + getStatus() + "/" + getDialogID() + ")", LogLevel.MEDIUM); }
/** When new data is received through the TcpConnection. */ public void onReceivedData(TcpConnection tcp_conn, byte[] data, int len) { last_time = System.currentTimeMillis(); text += new String(data, 0, len); SipParser par = new SipParser(text); Message msg = par.getSipMessage(); while (msg != null) { // System.out.println("DEBUG: message len: "+msg.getLength()); msg.setRemoteAddress(tcp_conn.getRemoteAddress().toString()); msg.setRemotePort(tcp_conn.getRemotePort()); msg.setTransport(PROTO_TCP); msg.setConnectionId(connection_id); if (listener != null) listener.onReceivedMessage(this, msg); text = par.getRemainingString(); // System.out.println("DEBUG: text left: "+text.length()); par = new SipParser(text); msg = par.getSipMessage(); } }
/** Sends a NOTIFY. */ public void notify(Message req) { String subscription_state = req.getSubscriptionStateHeader().getState(); if (subscription_state.equalsIgnoreCase(ACTIVE) && (statusIs(D_SUBSCRIBED) || statusIs(D_PENDING))) changeStatus(D_ACTIVE); else if (subscription_state.equalsIgnoreCase(PENDING) && statusIs(D_SUBSCRIBED)) changeStatus(D_PENDING); else if (subscription_state.equalsIgnoreCase(TERMINATED) && !statusIs(D_TERMINATED)) changeStatus(D_TERMINATED); TransactionClient notify_transaction = new TransactionClient(sip_provider, req, this); notify_transaction.request(); }
/** * Method derived from interface SipListener. It's fired from the SipProvider when a new message * is received for to the present TransactionServer. */ public void onReceivedMessage(SipProvider provider, Message msg) { if (msg.isRequest()) { if (statusIs(STATE_WAITING)) { request = new Message(msg); connection_id = msg.getConnectionId(); sip_provider.removeSipProviderListener(transaction_id); transaction_id = request.getTransactionId(); sip_provider.addSipProviderListener(transaction_id, this); changeStatus(STATE_TRYING); if (transaction_listener != null) transaction_listener.onTransRequest(this, msg); return; } if (statusIs(STATE_PROCEEDING) || statusIs(STATE_COMPLETED)) { // retransmission // of // the // last // response printLog("response retransmission", LogLevel.LOW); sip_provider.sendMessage(response, connection_id); return; } } }
/** Creates a new NotifierDialog for the already received SUBSCRIBE request <i>subscribe</i>. */ public NotifierDialog( SipProvider sip_provider, Message subscribe, NotifierDialogListener listener) { super(sip_provider); init(listener); changeStatus(D_SUBSCRIBED); subscribe_req = subscribe; subscribe_transaction = new TransactionServer(sip_provider, subscribe, null); update(Dialog.UAS, subscribe); EventHeader eh = subscribe.getEventHeader(); if (eh != null) { event = eh.getEvent(); id = eh.getId(); } }
/** When a new Message is received by the SipInterface. */ public void onReceivedMessage(SipInterface sip, Message msg) { // printLog("Message received: // "+msg.getFirstLine().substring(0,msg.toString().indexOf('\r'))); if (msg.isRequest()) { (new TransactionServer(sip_provider, msg, null)) .respondWith(MessageFactory.createResponse(msg, 200, SipResponses.reasonOf(200), null)); NameAddress sender = msg.getFromHeader().getNameAddress(); NameAddress recipient = msg.getToHeader().getNameAddress(); String subject = null; if (msg.hasSubjectHeader()) subject = msg.getSubjectHeader().getSubject(); String content_type = msg.getContentTypeHeader().getContentType(); String content = msg.getBody(); if (listener != null) listener.onMaReceivedMessage(this, sender, recipient, subject, content_type, content); } }
/** Sends a response message */ public void respondWith(Message resp) { response = resp; if (statusIs(STATE_TRYING) || statusIs(STATE_PROCEEDING)) { sip_provider.sendMessage(response, connection_id); int code = response.getStatusLine().getCode(); if (code >= 100 && code < 200 && statusIs(STATE_TRYING)) { changeStatus(STATE_PROCEEDING); } if (code >= 200 && code < 700) { changeStatus(STATE_COMPLETED); if (connection_id == null) clearing_to.start(); else { printLog("clearing_to=0 for reliable transport", LogLevel.LOW); onTimeout(clearing_to); } } } }
/** Updates log with the present message. */ public void update(Message msg) { String method = msg.getCSeqHeader().getMethod(); String call_id = msg.getCallIdHeader().getCallId(); if (method.equalsIgnoreCase(SipMethods.INVITE)) { if (msg.isRequest()) { if (!invite_dates.containsKey(call_id)) { Date time = new Date(); String caller = msg.getFromHeader().getNameAddress().getAddress().toString(); String callee = msg.getToHeader().getNameAddress().getAddress().toString(); insert(invite_dates, call_id, time); callers.put(call_id, caller); callees.put(call_id, callee); eventlog(time, call_id, SipMethods.INVITE, caller, callee); } } else { StatusLine status_line = msg.getStatusLine(); int code = status_line.getCode(); if (code >= 200 && code < 300 && !accepted_dates.containsKey(call_id)) { Date time = new Date(); insert(accepted_dates, call_id, time); String reason = status_line.getReason(); eventlog(time, call_id, String.valueOf(code) + " " + reason, "", ""); } else if (code >= 300 && !refused_dates.containsKey(call_id)) { Date time = new Date(); insert(refused_dates, call_id, time); String reason = status_line.getReason(); eventlog(time, call_id, String.valueOf(code) + " " + reason, "", ""); } } } else if (method.equalsIgnoreCase(SipMethods.BYE)) { if (msg.isRequest()) { if (!bye_dates.containsKey(call_id)) { Date time = new Date(); insert(bye_dates, call_id, time); eventlog(time, call_id, SipMethods.BYE, "", ""); calllog(call_id); } } } }
/** * Inherited from class SipProviderListener. Called when a new message is received (out of any * ongoing transaction) for the current InviteDialog. Always checks for out-of-date methods (CSeq * header sequence number). * * <p>If the message is ACK(2xx/INVITE) request, it moves to D_CALL state, and fires * <i>onDlgAck(this,body,msg)</i>. * * <p>If the message is 2xx(INVITE) response, it create a new AckTransactionClient * * <p>If the message is BYE, it moves to D_BYED state, removes the listener from SipProvider, * fires onDlgBye(this,msg) then it responds with 200 OK, moves to D_CLOSE state and fires * onDlgClose(this) */ public void onReceivedMessage(SipProvider sip_provider, Message msg) { printLog("inside onReceivedMessage(sip_provider,message)", LogLevel.MEDIUM); if (msg.isRequest() && !(msg.isAck() || msg.isCancel()) && msg.getCSeqHeader().getSequenceNumber() <= getRemoteCSeq()) { printLog("Request message is too late (CSeq too small): Message discarded", LogLevel.HIGH); return; } // invite received if (msg.isRequest() && msg.isInvite()) { verifyStatus(statusIs(D_INIT) || statusIs(D_CALL)); // NOTE: if the invite_ts.listen() is used, you should not arrive // here with the D_INIT state.. // however state D_INIT has been included for robustness against // further changes. if (statusIs(D_INIT)) changeStatus(D_INVITED); else changeStatus(D_ReINVITED); invite_req = msg; invite_ts = new InviteTransactionServer(sip_provider, invite_req, this); // ((TransactionServer)transaction).listen(); update(Dialog.UAS, invite_req); if (statusIs(D_INVITED)) listener.onDlgInvite( this, invite_req.getToHeader().getNameAddress(), invite_req.getFromHeader().getNameAddress(), invite_req.getBody(), invite_req); else listener.onDlgReInvite(this, invite_req.getBody(), invite_req); } else // ack (of 2xx of INVITE) if (msg.isRequest() && msg.isAck()) { if (!verifyStatus(statusIs(D_ACCEPTED) || statusIs(D_ReACCEPTED))) return; changeStatus(D_CALL); // terminates the AckTransactionServer ack_ts.terminate(); listener.onDlgAck(this, msg.getBody(), msg); listener.onDlgCall(this); } else // keep sending ACK (if already sent) for any "200 OK" received if (msg.isResponse()) { if (!verifyStatus(statusIs(D_CALL))) return; int code = msg.getStatusLine().getCode(); verifyThat(code >= 200 && code < 300, "code 2xx was expected"); if (ack_req != null) { AckTransactionClient ack_tc = new AckTransactionClient(sip_provider, ack_req, null); ack_tc.request(); } } else // bye received if (msg.isRequest() && msg.isBye()) { if (!verifyStatus(statusIs(D_CALL) || statusIs(D_BYEING))) return; changeStatus(D_BYED); bye_ts = new TransactionServer(sip_provider, msg, this); // automatically sends a 200 OK Message resp = MessageFactory.createResponse(msg, 200, SipResponses.reasonOf(200), null); respond(resp); listener.onDlgBye(this, msg); changeStatus(D_CLOSE); listener.onDlgClose(this); } else // cancel received if (msg.isRequest() && msg.isCancel()) { if (!verifyStatus(statusIs(D_INVITED) || statusIs(D_ReINVITED))) return; // create a CANCEL TransactionServer and send a 200 OK (CANCEL) TransactionServer ts = new TransactionServer(sip_provider, msg, null); // ts.listen(); ts.respondWith(MessageFactory.createResponse(msg, 200, SipResponses.reasonOf(200), null)); // automatically sends a 487 Cancelled Message resp = MessageFactory.createResponse(invite_req, 487, SipResponses.reasonOf(487), null); respond(resp); listener.onDlgCancel(this, msg); } else // any other request received if (msg.isRequest()) { TransactionServer ts = new TransactionServer(sip_provider, msg, null); // ts.listen(); ts.respondWith(MessageFactory.createResponse(msg, 405, SipResponses.reasonOf(405), null)); } }
/** When the TransactionClient goes into the "Completed" state receiving a 300-699 response */ public void onTransFailureResponse(TransactionClient tc, Message resp) { printLog("onTransFailureResponse()", LogLevel.MEDIUM); StatusLine status_line = resp.getStatusLine(); if (listener != null) listener.onDlgNotificationFailure(this, status_line.getCode(), status_line.getReason(), resp); }
SocketAddress getDestinationAddress(final Message message, final JID sender) { if (message.getSendTo() != null) { log.debug("Using sendTo Value for: " + message.toString()); return message.getSendTo(); } final SipAccount sipAccount = sipAccountProvider.getSipAccount(sender); if (sipAccount != null) { log.debug("Using sipAccount Value for: " + message.toString()); final SocketAddress result = CachedAddressResolver.getInstance().getSocketAddress(sipAccount.getOutboundproxy()); message.setSendTo(result); return result; } if (message.getToHeader() != null) { log.debug("Using message Header Value for: " + message.toString()); SipURL sipUrl = message.getContactHeader() != null ? message.getContactHeader().getNameAddress().getAddress() : null; if (sipUrl == null) { if (message.isRequest()) { sipUrl = message.getFromHeader().getNameAddress().getAddress(); } else { sipUrl = message.getFromHeader().getNameAddress().getAddress(); } } final SocketAddress result = CachedAddressResolver.getInstance() .getSIPSocketAddress(sipUrl.getHost(), sipUrl.getPort()); message.setSendTo(result); return result; } return null; }
/** Responds with <i>resp</i>. */ public void respond(Message resp) { printLog("inside respond(resp)", LogLevel.MEDIUM); if (resp.getStatusLine().getCode() >= 200) update(UAS, resp); subscribe_transaction.respondWith(resp); }
/** When the TransactionClient goes into the "Completed" state receiving a 2xx response */ public void onTransSuccessResponse(TransactionClient tc, Message resp) { onDeliverySuccess(tc, resp.getStatusLine().getReason()); }
/** When the TransactionClient goes into the "Completed" state receiving a 300-699 response */ public void onTransFailureResponse(TransactionClient tc, Message msg) { // SESCA // Autentikointi String method = tc.getTransactionMethod(); StatusLine status_line = msg.getStatusLine(); int code = status_line.getCode(); // AUTHENTICATION-BEGIN if ((code == 401 && msg.hasWwwAuthenticateHeader() && msg.getWwwAuthenticateHeader().getRealmParam().equalsIgnoreCase(user_profile.realm)) || (code == 407 && msg.hasProxyAuthenticateHeader() && msg.getProxyAuthenticateHeader() .getRealmParam() .equalsIgnoreCase(user_profile.realm))) { // req:ssa on cseq:ua kasvatettu Message req = tc.getRequestMessage(); req.setCSeqHeader(req.getCSeqHeader().incSequenceNumber()); WwwAuthenticateHeader wah; if (code == 401) wah = msg.getWwwAuthenticateHeader(); else wah = msg.getProxyAuthenticateHeader(); String qop_options = wah.getQopOptionsParam(); qop = (qop_options != null) ? "auth" : null; RequestLine rl = req.getRequestLine(); // SESCA // BUGI client ei saa lähettää qop:ia // DigestAuthentication digest=new // DigestAuthentication(rl.getMethod(),rl.getAddress().toString(),wah,qop,null,username,passwd); DigestAuthentication digest = new DigestAuthentication( rl.getMethod(), rl.getAddress().toString(), wah, null, null, user_profile.authID, user_profile.passwd); AuthorizationHeader ah; if (code == 401) ah = digest.getAuthorizationHeader(); else ah = digest.getProxyAuthorizationHeader(); req.setAuthorizationHeader(ah); // transactions.remove(tc.getTransactionId()); // SESCA // BUGI // Päivitetään invite_req:uun uusin invite-viesti. // Lähetämme uuden inviten, joten teemme uuden invitetransactionclientin, eikä transaction // clientia // if (method.equals(SipMethods.INVITE)) { // invite_req = req; // tc=new InviteTransactionClient(sip_provider,req,this); tc = new TransactionClient(sip_provider, req, this); // tc=new TransactionClient(sip_provider,req,this); // } // else { // tc=new TransactionClient(sip_provider,req,this); // } // transactions.put(tc.getTransactionId(),tc); tc.request(); } // AUTHENTICATION-END else onDeliveryFailure(tc, msg.getStatusLine().getReason()); }