// Send a message to the network, fragmenting first if necessary. // All messages to be sent to the network should go through this // method immediately before they are sent, ie after encryption. String fragmentAndSend(String message, int fragPolicy, OTRCallbacks callback) { int mms = callback.maxMessageSize(this); // Don't incur overhead of fragmentation unless necessary if (mms == 0 || message.length() <= mms) { // No fragmentation necessary if (fragPolicy == Policy.FRAGMENT_SEND_ALL) { callback.injectMessage(this.accountName, this.protocol, this.recName, message); return null; } else { // return the entire given message. return message; } } int fragment_count = ((message.length() - 1) / (mms - 19)) + 1; // like ceil(msglen/(mms - 19)) String[] frags = Proto.fragmentCreate(mms, fragment_count, message); String returnFragment = null; // Determine which fragments to send and which to return // based on given Fragment Policy. If the first fragment // should be returned instead of sent, store it. if (fragPolicy == Policy.FRAGMENT_SEND_ALL_BUT_FIRST) { returnFragment = frags[0]; } else { callback.injectMessage(accountName, protocol, recName, frags[0]); } // Prevent the demo receiver to receive all the messages in a single read try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 1; i < fragment_count - 1; i++) { callback.injectMessage(accountName, protocol, recName, frags[i]); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } // If the last fragment should be stored instead of sent, // store it if (fragPolicy == Policy.FRAGMENT_SEND_ALL_BUT_LAST) { returnFragment = frags[fragment_count - 1]; } else { callback.injectMessage(accountName, protocol, recName, frags[fragment_count - 1]); } return returnFragment; }