/** 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); } }
/** 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); } }
/** 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); } }
/** 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); } }
/** * 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; } } }
/** * 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)); } }
/** * Creates a message Id. If the message is a request, the peer address is the sender, otherwise * its the recipient. This is due to the fact that depending on the direction, peer address may * change, but its still considered the same message. * * @param message The message */ public MessageID(final Message message) { this( message.getMessageId(), message.isRequest() ? message.getSender() : message.getRecipient()); }
/** * Decodes the payload from a Netty buffer in a big switch * * @param content The content type * @param buffer The buffer to read from * @param message The message to store the results * @throws IndexOutOfBoundsException If a buffer is read beyond its limits * @throws NoSuchAlgorithmException * @throws SignatureException * @throws InvalidKeyException * @throws InvalidKeySpecException * @throws InvalidKeySpecException * @throws IOException * @throws DecoderException * @throws ASN1Exception * @throws UnsupportedEncodingException If UTF-8 is not there */ public static boolean decodePayload( final Content content, final ChannelBuffer buffer, final Message message) throws InvalidKeyException, SignatureException, NoSuchAlgorithmException, InvalidKeySpecException, IOException, DecoderException { final int len; byte[] me; switch (content) { case KEY: if (buffer.readableBytes() < 20) return false; message.setKey0(readID(buffer)); return true; case KEY_KEY: if (buffer.readableBytes() < 40) return false; message.setKeyKey0(readID(buffer), readID(buffer)); return true; case MAP_KEY_DATA: if (buffer.readableBytes() < 4) return false; int size = buffer.readInt(); Map<Number160, Data> result = new HashMap<Number160, Data>(size); for (int i = 0; i < size; i++) { if (buffer.readableBytes() < 20) return false; Number160 key = readID(buffer); final Data data = decodeData(new ChannelDecoder(buffer), message.getSender()); if (data == null) return false; if (message.isRequest()) { if (data.isProtectedEntry() && message.getPublicKey() == null) throw new DecoderException( "You indicated that you want to protect the data, but you did not provide or provided too late a public key."); data.setPublicKey(message.getPublicKey()); } result.put(key, data); } message.setDataMap0(result); return true; case MAP_KEY_KEY: if (buffer.readableBytes() < 4) return false; len = buffer.readInt(); if (buffer.readableBytes() < ((20 + 20) * len)) return false; final Map<Number160, Number160> keyMap = new HashMap<Number160, Number160>(); for (int i = 0; i < len; i++) { final Number160 key1 = readID(buffer); final Number160 key2 = readID(buffer); keyMap.put(key1, key2); } message.setKeyMap0(keyMap); return true; case SET_KEYS: // can be 31bit long ~ 2GB if (buffer.readableBytes() < 4) return false; len = buffer.readInt(); if (buffer.readableBytes() < (20 * len)) return false; final Collection<Number160> tmp = new ArrayList<Number160>(len); for (int i = 0; i < len; i++) { Number160 key = readID(buffer); tmp.add(key); } message.setKeys0(tmp); return true; case SET_NEIGHBORS: if (buffer.readableBytes() < 1) return false; len = buffer.readUnsignedByte(); if (buffer.readableBytes() < (len * PeerAddress.SIZE_IPv4)) return false; final Collection<PeerAddress> neighbors = new ArrayList<PeerAddress>(len); for (int i = 0; i < len; i++) { PeerAddress peerAddress = readPeerAddress(buffer); if (peerAddress == null) return false; neighbors.add(peerAddress); } message.setNeighbors0(neighbors); return true; case SET_TRACKER_DATA: if (buffer.readableBytes() < 1) return false; len = buffer.readUnsignedByte(); if (buffer.readableBytes() < (len * (PeerAddress.SIZE_IPv4 + 1))) return false; final Collection<TrackerData> trackerDatas = new ArrayList<TrackerData>(len); for (int i = 0; i < len; i++) { PeerAddress peerAddress = readPeerAddress(buffer); if (peerAddress == null) return false; byte[] attachment = null; int offset = 0; int length = 0; if (buffer.readableBytes() < 1) return false; byte miniHeader = buffer.readByte(); if (miniHeader != 0) { if (buffer.readableBytes() < 4) return false; length = buffer.readInt(); if (buffer.readableBytes() < length) return false; attachment = new byte[length]; buffer.readBytes(attachment); } trackerDatas.add( new TrackerData(peerAddress, message.getSender(), attachment, offset, length)); } message.setTrackerData0(trackerDatas); return true; case CHANNEL_BUFFER: if (buffer.readableBytes() < 4) return false; len = buffer.readInt(); if (buffer.readableBytes() < len) return false; // you can only use slice if no execution handler is in place, // otherwise, you will overwrite stuff final ChannelBuffer tmpBuffer = buffer.slice(buffer.readerIndex(), len); buffer.skipBytes(len); message.setPayload0(tmpBuffer); return true; case LONG: if (buffer.readableBytes() < 8) return false; message.setLong0(buffer.readLong()); return true; case INTEGER: if (buffer.readableBytes() < 4) return false; message.setInteger0(buffer.readInt()); return true; case PUBLIC_KEY: case PUBLIC_KEY_SIGNATURE: if (buffer.readableBytes() < 2) return false; len = buffer.readUnsignedShort(); me = new byte[len]; if (buffer.readableBytes() < len) return false; message.setPublicKey0(decodePublicKey(new ChannelDecoder(buffer), me)); if (content == Content.PUBLIC_KEY_SIGNATURE) { message.setHintSign(true); } return true; case EMPTY: case RESERVED1: case RESERVED2: case RESERVED3: default: return true; } }