carbons
This commit is contained in:
		
							parent
							
								
									892f565a30
								
							
						
					
					
						commit
						c6440aab12
					
				| @ -157,4 +157,8 @@ public class Contact extends AbstractEntity implements Serializable { | |||||||
| 	public int getMostAvailableStatus() { | 	public int getMostAvailableStatus() { | ||||||
| 		return this.presences.getMostAvailableStatus(); | 		return this.presences.getMostAvailableStatus(); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	public void setPresences(Presences pres) { | ||||||
|  | 		this.presences = pres;	 | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ import de.gultsch.chat.entities.Account; | |||||||
| import de.gultsch.chat.entities.Contact; | import de.gultsch.chat.entities.Contact; | ||||||
| import de.gultsch.chat.entities.Conversation; | import de.gultsch.chat.entities.Conversation; | ||||||
| import de.gultsch.chat.entities.Message; | import de.gultsch.chat.entities.Message; | ||||||
|  | import de.gultsch.chat.entities.Presences; | ||||||
| import android.content.ContentValues; | import android.content.ContentValues; | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.database.Cursor; | import android.database.Cursor; | ||||||
| @ -214,12 +215,13 @@ public class DatabaseBackend extends SQLiteOpenHelper { | |||||||
| 		SQLiteDatabase db = this.getWritableDatabase(); | 		SQLiteDatabase db = this.getWritableDatabase(); | ||||||
| 		for (int i = 0; i < contacts.size(); i++) { | 		for (int i = 0; i < contacts.size(); i++) { | ||||||
| 			Contact contact = contacts.get(i); | 			Contact contact = contacts.get(i); | ||||||
| 			String[] columns = {Contact.UUID}; | 			String[] columns = {Contact.UUID, Contact.PRESENCES}; | ||||||
| 			String[] args = {contact.getAccount().getUuid(), contact.getJid()}; | 			String[] args = {contact.getAccount().getUuid(), contact.getJid()}; | ||||||
| 			Cursor cursor = db.query(Contact.TABLENAME, columns,Contact.ACCOUNT+"=? AND "+Contact.JID+"=?", args, null, null, null); | 			Cursor cursor = db.query(Contact.TABLENAME, columns,Contact.ACCOUNT+"=? AND "+Contact.JID+"=?", args, null, null, null); | ||||||
| 			if (cursor.getCount()>=1) { | 			if (cursor.getCount()>=1) { | ||||||
| 				cursor.moveToFirst(); | 				cursor.moveToFirst(); | ||||||
| 				contact.setUuid(cursor.getString(0)); | 				contact.setUuid(cursor.getString(0)); | ||||||
|  | 				contact.setPresences(Presences.fromJsonString(cursor.getString(1))); | ||||||
| 				updateContact(contact); | 				updateContact(contact); | ||||||
| 			} else { | 			} else { | ||||||
| 				contact.setUuid(UUID.randomUUID().toString()); | 				contact.setUuid(UUID.randomUUID().toString()); | ||||||
|  | |||||||
| @ -62,20 +62,49 @@ public class XmppConnectionService extends Service { | |||||||
| 			if ((packet.getType() == MessagePacket.TYPE_CHAT) | 			if ((packet.getType() == MessagePacket.TYPE_CHAT) | ||||||
| 					|| (packet.getType() == MessagePacket.TYPE_GROUPCHAT)) { | 					|| (packet.getType() == MessagePacket.TYPE_GROUPCHAT)) { | ||||||
| 				boolean notify = true; | 				boolean notify = true; | ||||||
|  | 				int status = Message.STATUS_RECIEVED; | ||||||
|  | 				String body; | ||||||
|  | 				String fullJid; | ||||||
| 				if (!packet.hasChild("body")) { | 				if (!packet.hasChild("body")) { | ||||||
| 					return; | 					Element forwarded; | ||||||
|  | 					if (packet.hasChild("received")) { | ||||||
|  | 						forwarded = packet.findChild("received").findChild( | ||||||
|  | 								"forwarded"); | ||||||
|  | 					} else if (packet.hasChild("sent")) { | ||||||
|  | 						forwarded = packet.findChild("sent").findChild( | ||||||
|  | 								"forwarded"); | ||||||
|  | 						status = Message.STATUS_SEND; | ||||||
|  | 					} else { | ||||||
|  | 						return; // massage has no body and is not carbon. just | ||||||
|  | 								// skip | ||||||
|  | 					} | ||||||
|  | 					if (forwarded != null) { | ||||||
|  | 						Element message = forwarded.findChild("message"); | ||||||
|  | 						if ((message == null) || (!message.hasChild("body"))) | ||||||
|  | 							return; // either malformed or boring | ||||||
|  | 						if (status == Message.STATUS_RECIEVED) { | ||||||
|  | 							fullJid = message.getAttribute("from"); | ||||||
|  | 						} else { | ||||||
|  | 							fullJid = message.getAttribute("to"); | ||||||
|  | 						} | ||||||
|  | 						body = message.findChild("body").getContent(); | ||||||
|  | 					} else { | ||||||
|  | 						return; // packet malformed. has no forwarded element | ||||||
|  | 					} | ||||||
|  | 				} else { | ||||||
|  | 					fullJid = packet.getFrom(); | ||||||
|  | 					body = packet.getBody(); | ||||||
| 				} | 				} | ||||||
| 				Conversation conversation = null; | 				Conversation conversation = null; | ||||||
| 				String fullJid = packet.getFrom(); |  | ||||||
| 				String[] fromParts = fullJid.split("/"); | 				String[] fromParts = fullJid.split("/"); | ||||||
| 				String jid = fromParts[0]; | 				String jid = fromParts[0]; | ||||||
| 				Contact contact = findOrCreateContact(account, jid); | 				Contact contact = findOrCreateContact(account, jid); | ||||||
| 				boolean muc = (packet.getType() == MessagePacket.TYPE_GROUPCHAT); | 				boolean muc = (packet.getType() == MessagePacket.TYPE_GROUPCHAT); | ||||||
| 				String counterPart = null; | 				String counterPart = null; | ||||||
| 				int status = Message.STATUS_RECIEVED; |  | ||||||
| 				conversation = findOrCreateConversation(account, contact, muc); | 				conversation = findOrCreateConversation(account, contact, muc); | ||||||
| 				if (muc) { | 				if (muc) { | ||||||
| 					if ((fromParts.length==1)||(packet.hasChild("subject"))||(packet.hasChild("delay"))) { | 					if ((fromParts.length == 1) || (packet.hasChild("subject")) | ||||||
|  | 							|| (packet.hasChild("delay"))) { | ||||||
| 						return; | 						return; | ||||||
| 					} | 					} | ||||||
| 					counterPart = fromParts[1]; | 					counterPart = fromParts[1]; | ||||||
| @ -86,8 +115,8 @@ public class XmppConnectionService extends Service { | |||||||
| 				} else { | 				} else { | ||||||
| 					counterPart = fullJid; | 					counterPart = fullJid; | ||||||
| 				} | 				} | ||||||
| 				Message message = new Message(conversation, counterPart, | 				Message message = new Message(conversation, counterPart, body, | ||||||
| 						packet.getBody(), Message.ENCRYPTION_NONE, status); | 						Message.ENCRYPTION_NONE, status); | ||||||
| 				conversation.getMessages().add(message); | 				conversation.getMessages().add(message); | ||||||
| 				databaseBackend.createMessage(message); | 				databaseBackend.createMessage(message); | ||||||
| 				if (convChangedListener != null) { | 				if (convChangedListener != null) { | ||||||
| @ -124,28 +153,28 @@ public class XmppConnectionService extends Service { | |||||||
| 				PresencePacket packet) { | 				PresencePacket packet) { | ||||||
| 			String[] fromParts = packet.getAttribute("from").split("/"); | 			String[] fromParts = packet.getAttribute("from").split("/"); | ||||||
| 			Contact contact = findOrCreateContact(account, fromParts[0]); | 			Contact contact = findOrCreateContact(account, fromParts[0]); | ||||||
| 			if (contact.getUuid()==null) { | 			if (contact.getUuid() == null) { | ||||||
| 				//most likely muc, self or roster not synced | 				// most likely muc, self or roster not synced | ||||||
| 				Log.d(LOGTAG,"got presence for non contact "+packet.toString()); | 				// Log.d(LOGTAG,"got presence for non contact "+packet.toString()); | ||||||
| 			} | 			} | ||||||
| 			String type = packet.getAttribute("type"); | 			String type = packet.getAttribute("type"); | ||||||
| 			if (type == null) { | 			if (type == null) { | ||||||
| 				Element show = packet.findChild("show"); | 				Element show = packet.findChild("show"); | ||||||
| 				if (show==null) { | 				if (show == null) { | ||||||
| 					contact.updatePresence(fromParts[1],Presences.ONLINE); | 					contact.updatePresence(fromParts[1], Presences.ONLINE); | ||||||
| 				} else if (show.getContent().equals("away")) { | 				} else if (show.getContent().equals("away")) { | ||||||
| 					contact.updatePresence(fromParts[1],Presences.AWAY); | 					contact.updatePresence(fromParts[1], Presences.AWAY); | ||||||
| 				} else if (show.getContent().equals("xa")) { | 				} else if (show.getContent().equals("xa")) { | ||||||
| 					contact.updatePresence(fromParts[1],Presences.XA); | 					contact.updatePresence(fromParts[1], Presences.XA); | ||||||
| 				} else if (show.getContent().equals("chat")) { | 				} else if (show.getContent().equals("chat")) { | ||||||
| 					contact.updatePresence(fromParts[1],Presences.CHAT); | 					contact.updatePresence(fromParts[1], Presences.CHAT); | ||||||
| 				} else if (show.getContent().equals("dnd")) { | 				} else if (show.getContent().equals("dnd")) { | ||||||
| 					contact.updatePresence(fromParts[1],Presences.DND); | 					contact.updatePresence(fromParts[1], Presences.DND); | ||||||
| 				} | 				} | ||||||
| 				databaseBackend.updateContact(contact); | 				databaseBackend.updateContact(contact); | ||||||
| 			} else if (type.equals("unavailable")) { | 			} else if (type.equals("unavailable")) { | ||||||
| 				if (fromParts.length!=2) { | 				if (fromParts.length != 2) { | ||||||
| 					Log.d(LOGTAG,"received presence with no resource "+packet.toString()); | 					// Log.d(LOGTAG,"received presence with no resource "+packet.toString()); | ||||||
| 				} else { | 				} else { | ||||||
| 					contact.removePresence(fromParts[1]); | 					contact.removePresence(fromParts[1]); | ||||||
| 					databaseBackend.updateContact(contact); | 					databaseBackend.updateContact(contact); | ||||||
| @ -194,7 +223,7 @@ public class XmppConnectionService extends Service { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void sendMessage(final Account account, final Message message) { | 	public void sendMessage(final Account account, final Message message) { | ||||||
| 		if (message.getConversation().getMode()==Conversation.MODE_SINGLE) { | 		if (message.getConversation().getMode() == Conversation.MODE_SINGLE) { | ||||||
| 			databaseBackend.createMessage(message); | 			databaseBackend.createMessage(message); | ||||||
| 		} | 		} | ||||||
| 		MessagePacket packet = new MessagePacket(); | 		MessagePacket packet = new MessagePacket(); | ||||||
| @ -206,9 +235,9 @@ public class XmppConnectionService extends Service { | |||||||
| 		packet.setTo(message.getCounterpart()); | 		packet.setTo(message.getCounterpart()); | ||||||
| 		packet.setFrom(account.getJid()); | 		packet.setFrom(account.getJid()); | ||||||
| 		packet.setBody(message.getBody()); | 		packet.setBody(message.getBody()); | ||||||
| 		if (account.getStatus()==Account.STATUS_ONLINE) { | 		if (account.getStatus() == Account.STATUS_ONLINE) { | ||||||
| 			connections.get(account).sendMessagePacket(packet); | 			connections.get(account).sendMessagePacket(packet); | ||||||
| 			if (message.getConversation().getMode()==Conversation.MODE_SINGLE) { | 			if (message.getConversation().getMode() == Conversation.MODE_SINGLE) { | ||||||
| 				message.setStatus(Message.STATUS_SEND); | 				message.setStatus(Message.STATUS_SEND); | ||||||
| 				databaseBackend.updateMessage(message); | 				databaseBackend.updateMessage(message); | ||||||
| 			} | 			} | ||||||
|  | |||||||
| @ -38,6 +38,7 @@ public class DialogContactDetails extends DialogFragment { | |||||||
| 		 | 		 | ||||||
| 		boolean subscriptionSend = false; | 		boolean subscriptionSend = false; | ||||||
| 		boolean subscriptionReceive = false; | 		boolean subscriptionReceive = false; | ||||||
|  | 		if (contact.getSubscription()!=null) { | ||||||
| 			if (contact.getSubscription().equals("both")) { | 			if (contact.getSubscription().equals("both")) { | ||||||
| 				subscriptionReceive = true; | 				subscriptionReceive = true; | ||||||
| 				subscriptionSend = true; | 				subscriptionSend = true; | ||||||
| @ -46,6 +47,7 @@ public class DialogContactDetails extends DialogFragment { | |||||||
| 			} else if (contact.getSubscription().equals("to")) { | 			} else if (contact.getSubscription().equals("to")) { | ||||||
| 				subscriptionReceive = true; | 				subscriptionReceive = true; | ||||||
| 			} | 			} | ||||||
|  | 		} | ||||||
| 		 | 		 | ||||||
| 		switch (contact.getMostAvailableStatus()) { | 		switch (contact.getMostAvailableStatus()) { | ||||||
| 		case Presences.CHAT: | 		case Presences.CHAT: | ||||||
|  | |||||||
| @ -181,7 +181,9 @@ public class NewConversationActivity extends XmppActivity { | |||||||
| 					}); | 					}); | ||||||
| 					accountChooser.create().show(); | 					accountChooser.create().show(); | ||||||
| 				} else { | 				} else { | ||||||
|  | 					if (clickedContact.getAccount()==null) { | ||||||
| 						clickedContact.setAccount(accounts.get(0)); | 						clickedContact.setAccount(accounts.get(0)); | ||||||
|  | 					} | ||||||
| 					showIsMucDialogIfNeeded(clickedContact); | 					showIsMucDialogIfNeeded(clickedContact); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| @ -226,6 +228,7 @@ public class NewConversationActivity extends XmppActivity { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void startConversation(Contact contact, Account account, boolean muc) { | 	public void startConversation(Contact contact, Account account, boolean muc) { | ||||||
|  | 		Log.d("xmppService","starting conversation for account:"+account.getJid()+" and contact:"+contact.getJid()); | ||||||
| 		Conversation conversation = xmppConnectionService | 		Conversation conversation = xmppConnectionService | ||||||
| 				.findOrCreateConversation(account, contact, muc); | 				.findOrCreateConversation(account, contact, muc); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -7,7 +7,9 @@ import java.math.BigInteger; | |||||||
| import java.net.Socket; | import java.net.Socket; | ||||||
| import java.net.UnknownHostException; | import java.net.UnknownHostException; | ||||||
| import java.security.SecureRandom; | import java.security.SecureRandom; | ||||||
|  | import java.util.HashSet; | ||||||
| import java.util.Hashtable; | import java.util.Hashtable; | ||||||
|  | import java.util.List; | ||||||
| 
 | 
 | ||||||
| import javax.net.ssl.SSLSocket; | import javax.net.ssl.SSLSocket; | ||||||
| import javax.net.ssl.SSLSocketFactory; | import javax.net.ssl.SSLSocketFactory; | ||||||
| @ -40,11 +42,12 @@ public class XmppConnection implements Runnable { | |||||||
| 
 | 
 | ||||||
| 	private boolean isTlsEncrypted = false; | 	private boolean isTlsEncrypted = false; | ||||||
| 	private boolean isAuthenticated = false; | 	private boolean isAuthenticated = false; | ||||||
| 	//private boolean shouldUseTLS = false; | 	// private boolean shouldUseTLS = false; | ||||||
| 	private boolean shouldConnect = true; | 	private boolean shouldConnect = true; | ||||||
| 	private boolean shouldBind = true; | 	private boolean shouldBind = true; | ||||||
| 	private boolean shouldAuthenticate = true; | 	private boolean shouldAuthenticate = true; | ||||||
| 	private Element streamFeatures; | 	private Element streamFeatures; | ||||||
|  | 	private HashSet<String> discoFeatures = new HashSet<String>(); | ||||||
| 
 | 
 | ||||||
| 	private static final int PACKET_IQ = 0; | 	private static final int PACKET_IQ = 0; | ||||||
| 	private static final int PACKET_MESSAGE = 1; | 	private static final int PACKET_MESSAGE = 1; | ||||||
| @ -69,9 +72,10 @@ public class XmppConnection implements Runnable { | |||||||
| 			Bundle namePort = DNSHelper.getSRVRecord(account.getServer()); | 			Bundle namePort = DNSHelper.getSRVRecord(account.getServer()); | ||||||
| 			String srvRecordServer = namePort.getString("name"); | 			String srvRecordServer = namePort.getString("name"); | ||||||
| 			int srvRecordPort = namePort.getInt("port"); | 			int srvRecordPort = namePort.getInt("port"); | ||||||
| 			if (srvRecordServer!=null) { | 			if (srvRecordServer != null) { | ||||||
| 				Log.d(LOGTAG,account.getJid()+": using values from dns "+srvRecordServer+":"+srvRecordPort); | 				Log.d(LOGTAG, account.getJid() + ": using values from dns " | ||||||
| 				socket = new Socket(srvRecordServer,srvRecordPort); | 						+ srvRecordServer + ":" + srvRecordPort); | ||||||
|  | 				socket = new Socket(srvRecordServer, srvRecordPort); | ||||||
| 			} else { | 			} else { | ||||||
| 				socket = new Socket(account.getServer(), 5222); | 				socket = new Socket(account.getServer(), 5222); | ||||||
| 			} | 			} | ||||||
| @ -96,21 +100,21 @@ public class XmppConnection implements Runnable { | |||||||
| 			} | 			} | ||||||
| 		} catch (UnknownHostException e) { | 		} catch (UnknownHostException e) { | ||||||
| 			account.setStatus(Account.STATUS_SERVER_NOT_FOUND); | 			account.setStatus(Account.STATUS_SERVER_NOT_FOUND); | ||||||
| 			if (statusListener!=null) { | 			if (statusListener != null) { | ||||||
| 				statusListener.onStatusChanged(account); | 				statusListener.onStatusChanged(account); | ||||||
| 			} | 			} | ||||||
| 			return; | 			return; | ||||||
| 		} catch (IOException e) { | 		} catch (IOException e) { | ||||||
| 			Log.d(LOGTAG,"bla "+e.getMessage()); | 			Log.d(LOGTAG, "bla " + e.getMessage()); | ||||||
| 			if (shouldConnect) { | 			if (shouldConnect) { | ||||||
| 				Log.d(LOGTAG,account.getJid()+": connection lost"); | 				Log.d(LOGTAG, account.getJid() + ": connection lost"); | ||||||
| 				account.setStatus(Account.STATUS_OFFLINE); | 				account.setStatus(Account.STATUS_OFFLINE); | ||||||
| 				if (statusListener!=null) { | 				if (statusListener != null) { | ||||||
| 					statusListener.onStatusChanged(account); | 					statusListener.onStatusChanged(account); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} catch (XmlPullParserException e) { | 		} catch (XmlPullParserException e) { | ||||||
| 			Log.d(LOGTAG,"xml exception "+e.getMessage()); | 			Log.d(LOGTAG, "xml exception " + e.getMessage()); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @ -119,7 +123,7 @@ public class XmppConnection implements Runnable { | |||||||
| 	@Override | 	@Override | ||||||
| 	public void run() { | 	public void run() { | ||||||
| 		shouldConnect = true; | 		shouldConnect = true; | ||||||
| 		while(shouldConnect) { | 		while (shouldConnect) { | ||||||
| 			connect(); | 			connect(); | ||||||
| 			try { | 			try { | ||||||
| 				if (shouldConnect) { | 				if (shouldConnect) { | ||||||
| @ -130,7 +134,7 @@ public class XmppConnection implements Runnable { | |||||||
| 				e.printStackTrace(); | 				e.printStackTrace(); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		Log.d(LOGTAG,"end run"); | 		Log.d(LOGTAG, "end run"); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void processStream(Tag currentTag) throws XmlPullParserException, | 	private void processStream(Tag currentTag) throws XmlPullParserException, | ||||||
| @ -145,17 +149,18 @@ public class XmppConnection implements Runnable { | |||||||
| 				switchOverToTls(nextTag); | 				switchOverToTls(nextTag); | ||||||
| 			} else if (nextTag.isStart("success")) { | 			} else if (nextTag.isStart("success")) { | ||||||
| 				isAuthenticated = true; | 				isAuthenticated = true; | ||||||
| 				Log.d(LOGTAG,account.getJid()+": read success tag in stream. reset again"); | 				Log.d(LOGTAG, account.getJid() | ||||||
|  | 						+ ": read success tag in stream. reset again"); | ||||||
| 				tagReader.readTag(); | 				tagReader.readTag(); | ||||||
| 				tagReader.reset(); | 				tagReader.reset(); | ||||||
| 				sendStartStream(); | 				sendStartStream(); | ||||||
| 				processStream(tagReader.readTag()); | 				processStream(tagReader.readTag()); | ||||||
| 				break; | 				break; | ||||||
| 			} else if(nextTag.isStart("failure")) { | 			} else if (nextTag.isStart("failure")) { | ||||||
| 				Element failure = tagReader.readElement(nextTag); | 				Element failure = tagReader.readElement(nextTag); | ||||||
| 				Log.d(LOGTAG,"read failure element"+failure.toString()); | 				Log.d(LOGTAG, "read failure element" + failure.toString()); | ||||||
| 				account.setStatus(Account.STATUS_UNAUTHORIZED); | 				account.setStatus(Account.STATUS_UNAUTHORIZED); | ||||||
| 				if (statusListener!=null) { | 				if (statusListener != null) { | ||||||
| 					statusListener.onStatusChanged(account); | 					statusListener.onStatusChanged(account); | ||||||
| 				} | 				} | ||||||
| 				tagWriter.writeTag(Tag.end("stream")); | 				tagWriter.writeTag(Tag.end("stream")); | ||||||
| @ -173,13 +178,14 @@ public class XmppConnection implements Runnable { | |||||||
| 		} | 		} | ||||||
| 		if (account.getStatus() == Account.STATUS_ONLINE) { | 		if (account.getStatus() == Account.STATUS_ONLINE) { | ||||||
| 			account.setStatus(Account.STATUS_OFFLINE); | 			account.setStatus(Account.STATUS_OFFLINE); | ||||||
| 			if (statusListener!=null) { | 			if (statusListener != null) { | ||||||
| 				statusListener.onStatusChanged(account); | 				statusListener.onStatusChanged(account); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private Element processPacket(Tag currentTag, int packetType) throws XmlPullParserException, IOException { | 	private Element processPacket(Tag currentTag, int packetType) | ||||||
|  | 			throws XmlPullParserException, IOException { | ||||||
| 		Element element; | 		Element element; | ||||||
| 		switch (packetType) { | 		switch (packetType) { | ||||||
| 		case PACKET_IQ: | 		case PACKET_IQ: | ||||||
| @ -196,7 +202,7 @@ public class XmppConnection implements Runnable { | |||||||
| 		} | 		} | ||||||
| 		element.setAttributes(currentTag.getAttributes()); | 		element.setAttributes(currentTag.getAttributes()); | ||||||
| 		Tag nextTag = tagReader.readTag(); | 		Tag nextTag = tagReader.readTag(); | ||||||
| 		while(!nextTag.isEnd(element.getName())) { | 		while (!nextTag.isEnd(element.getName())) { | ||||||
| 			if (!nextTag.isNo()) { | 			if (!nextTag.isNo()) { | ||||||
| 				Element child = tagReader.readElement(nextTag); | 				Element child = tagReader.readElement(nextTag); | ||||||
| 				element.addChild(child); | 				element.addChild(child); | ||||||
| @ -206,43 +212,48 @@ public class XmppConnection implements Runnable { | |||||||
| 		return element; | 		return element; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 
 | 	private IqPacket processIq(Tag currentTag) throws XmlPullParserException, | ||||||
| 	private IqPacket processIq(Tag currentTag) throws XmlPullParserException, IOException { | 			IOException { | ||||||
| 		IqPacket packet = (IqPacket) processPacket(currentTag,PACKET_IQ); | 		IqPacket packet = (IqPacket) processPacket(currentTag, PACKET_IQ); | ||||||
| 		if (iqPacketCallbacks.containsKey(packet.getId())) { | 		if (iqPacketCallbacks.containsKey(packet.getId())) { | ||||||
| 			iqPacketCallbacks.get(packet.getId()).onIqPacketReceived(account,packet); | 			iqPacketCallbacks.get(packet.getId()).onIqPacketReceived(account, | ||||||
|  | 					packet); | ||||||
| 			iqPacketCallbacks.remove(packet.getId()); | 			iqPacketCallbacks.remove(packet.getId()); | ||||||
| 		} else if (this.unregisteredIqListener != null) { | 		} else if (this.unregisteredIqListener != null) { | ||||||
| 			this.unregisteredIqListener.onIqPacketReceived(account,packet); | 			this.unregisteredIqListener.onIqPacketReceived(account, packet); | ||||||
| 		} | 		} | ||||||
| 		return packet; | 		return packet; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void processMessage(Tag currentTag) throws XmlPullParserException, IOException { | 	private void processMessage(Tag currentTag) throws XmlPullParserException, | ||||||
| 		MessagePacket packet = (MessagePacket) processPacket(currentTag, PACKET_MESSAGE); | 			IOException { | ||||||
|  | 		MessagePacket packet = (MessagePacket) processPacket(currentTag, | ||||||
|  | 				PACKET_MESSAGE); | ||||||
| 		if (this.messageListener != null) { | 		if (this.messageListener != null) { | ||||||
| 			this.messageListener.onMessagePacketReceived(account,packet); | 			this.messageListener.onMessagePacketReceived(account, packet); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void processPresence(Tag currentTag) throws XmlPullParserException, IOException { | 	private void processPresence(Tag currentTag) throws XmlPullParserException, | ||||||
| 		PresencePacket packet = (PresencePacket) processPacket(currentTag, PACKET_PRESENCE); | 			IOException { | ||||||
|  | 		PresencePacket packet = (PresencePacket) processPacket(currentTag, | ||||||
|  | 				PACKET_PRESENCE); | ||||||
| 		if (this.presenceListener != null) { | 		if (this.presenceListener != null) { | ||||||
| 			this.presenceListener.onPresencePacketReceived(account,packet); | 			this.presenceListener.onPresencePacketReceived(account, packet); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void sendStartTLS() { | 	private void sendStartTLS() { | ||||||
| 		Tag startTLS = Tag.empty("starttls"); | 		Tag startTLS = Tag.empty("starttls"); | ||||||
| 		startTLS.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-tls"); | 		startTLS.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-tls"); | ||||||
| 		Log.d(LOGTAG,account.getJid()+": sending starttls"); | 		Log.d(LOGTAG, account.getJid() + ": sending starttls"); | ||||||
| 		tagWriter.writeTag(startTLS); | 		tagWriter.writeTag(startTLS); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void switchOverToTls(Tag currentTag) throws XmlPullParserException, | 	private void switchOverToTls(Tag currentTag) throws XmlPullParserException, | ||||||
| 			IOException { | 			IOException { | ||||||
| 		Tag nextTag = tagReader.readTag(); // should be proceed end tag | 		Tag nextTag = tagReader.readTag(); // should be proceed end tag | ||||||
| 		Log.d(LOGTAG,account.getJid()+": now switch to ssl"); | 		Log.d(LOGTAG, account.getJid() + ": now switch to ssl"); | ||||||
| 		SSLSocket sslSocket; | 		SSLSocket sslSocket; | ||||||
| 		try { | 		try { | ||||||
| 			sslSocket = (SSLSocket) ((SSLSocketFactory) SSLSocketFactory | 			sslSocket = (SSLSocket) ((SSLSocketFactory) SSLSocketFactory | ||||||
| @ -257,7 +268,9 @@ public class XmppConnection implements Runnable { | |||||||
| 			processStream(tagReader.readTag()); | 			processStream(tagReader.readTag()); | ||||||
| 			sslSocket.close(); | 			sslSocket.close(); | ||||||
| 		} catch (IOException e) { | 		} catch (IOException e) { | ||||||
| 			Log.d(LOGTAG, account.getJid()+": error on ssl '" + e.getMessage()+"'"); | 			Log.d(LOGTAG, | ||||||
|  | 					account.getJid() + ": error on ssl '" + e.getMessage() | ||||||
|  | 							+ "'"); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -268,25 +281,29 @@ public class XmppConnection implements Runnable { | |||||||
| 		auth.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-sasl"); | 		auth.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-sasl"); | ||||||
| 		auth.setAttribute("mechanism", "PLAIN"); | 		auth.setAttribute("mechanism", "PLAIN"); | ||||||
| 		auth.setContent(saslString); | 		auth.setContent(saslString); | ||||||
| 		Log.d(LOGTAG,account.getJid()+": sending sasl "+auth.toString()); | 		Log.d(LOGTAG, account.getJid() + ": sending sasl " + auth.toString()); | ||||||
| 		tagWriter.writeElement(auth); | 		tagWriter.writeElement(auth); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void processStreamFeatures(Tag currentTag) | 	private void processStreamFeatures(Tag currentTag) | ||||||
| 			throws XmlPullParserException, IOException { | 			throws XmlPullParserException, IOException { | ||||||
| 		this.streamFeatures = tagReader.readElement(currentTag); | 		this.streamFeatures = tagReader.readElement(currentTag); | ||||||
| 		Log.d(LOGTAG,account.getJid()+": process stream features "+streamFeatures); | 		Log.d(LOGTAG, account.getJid() + ": process stream features " | ||||||
| 		if (this.streamFeatures.hasChild("starttls")&&account.isOptionSet(Account.OPTION_USETLS)) { | 				+ streamFeatures); | ||||||
|  | 		if (this.streamFeatures.hasChild("starttls") | ||||||
|  | 				&& account.isOptionSet(Account.OPTION_USETLS)) { | ||||||
| 			sendStartTLS(); | 			sendStartTLS(); | ||||||
| 		} else if (this.streamFeatures.hasChild("mechanisms")&&shouldAuthenticate) { | 		} else if (this.streamFeatures.hasChild("mechanisms") | ||||||
|  | 				&& shouldAuthenticate) { | ||||||
| 			sendSaslAuth(); | 			sendSaslAuth(); | ||||||
| 		} | 		} | ||||||
| 		if (this.streamFeatures.hasChild("bind")&&shouldBind) { | 		if (this.streamFeatures.hasChild("bind") && shouldBind) { | ||||||
| 			sendBindRequest(); | 			sendBindRequest(); | ||||||
| 			if (this.streamFeatures.hasChild("session")) { | 			if (this.streamFeatures.hasChild("session")) { | ||||||
| 				IqPacket startSession = new IqPacket(IqPacket.TYPE_SET); | 				IqPacket startSession = new IqPacket(IqPacket.TYPE_SET); | ||||||
| 				Element session = new Element("session"); | 				Element session = new Element("session"); | ||||||
| 				session.setAttribute("xmlns","urn:ietf:params:xml:ns:xmpp-session"); | 				session.setAttribute("xmlns", | ||||||
|  | 						"urn:ietf:params:xml:ns:xmpp-session"); | ||||||
| 				session.setContent(""); | 				session.setContent(""); | ||||||
| 				startSession.addChild(session); | 				startSession.addChild(session); | ||||||
| 				sendIqPacket(startSession, null); | 				sendIqPacket(startSession, null); | ||||||
| @ -301,17 +318,65 @@ public class XmppConnection implements Runnable { | |||||||
| 	private void sendBindRequest() throws IOException { | 	private void sendBindRequest() throws IOException { | ||||||
| 		IqPacket iq = new IqPacket(IqPacket.TYPE_SET); | 		IqPacket iq = new IqPacket(IqPacket.TYPE_SET); | ||||||
| 		Element bind = new Element("bind"); | 		Element bind = new Element("bind"); | ||||||
| 		bind.setAttribute("xmlns","urn:ietf:params:xml:ns:xmpp-bind"); | 		bind.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-bind"); | ||||||
| 		iq.addChild(bind); | 		iq.addChild(bind); | ||||||
| 		this.sendIqPacket(iq, new OnIqPacketReceived() { | 		this.sendIqPacket(iq, new OnIqPacketReceived() { | ||||||
| 			@Override | 			@Override | ||||||
| 			public void onIqPacketReceived(Account account, IqPacket packet) { | 			public void onIqPacketReceived(Account account, IqPacket packet) { | ||||||
| 				String resource = packet.findChild("bind").findChild("jid").getContent().split("/")[1]; | 				String resource = packet.findChild("bind").findChild("jid") | ||||||
|  | 						.getContent().split("/")[1]; | ||||||
| 				account.setResource(resource); | 				account.setResource(resource); | ||||||
| 				account.setStatus(Account.STATUS_ONLINE); | 				account.setStatus(Account.STATUS_ONLINE); | ||||||
| 				if (statusListener!=null) { | 				if (statusListener != null) { | ||||||
| 					statusListener.onStatusChanged(account); | 					statusListener.onStatusChanged(account); | ||||||
| 				} | 				} | ||||||
|  | 				sendServiceDiscovery(); | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private void sendServiceDiscovery() { | ||||||
|  | 		IqPacket iq = new IqPacket(IqPacket.TYPE_GET); | ||||||
|  | 		iq.setAttribute("to", account.getServer()); | ||||||
|  | 		Element query = new Element("query"); | ||||||
|  | 		query.setAttribute("xmlns", "http://jabber.org/protocol/disco#info"); | ||||||
|  | 		iq.addChild(query); | ||||||
|  | 		this.sendIqPacket(iq, new OnIqPacketReceived() { | ||||||
|  | 
 | ||||||
|  | 			@Override | ||||||
|  | 			public void onIqPacketReceived(Account account, IqPacket packet) { | ||||||
|  | 				if (packet.hasChild("query")) { | ||||||
|  | 					List<Element> elements = packet.findChild("query") | ||||||
|  | 							.getChildren(); | ||||||
|  | 					for (int i = 0; i < elements.size(); ++i) { | ||||||
|  | 						if (elements.get(i).getName().equals("feature")) { | ||||||
|  | 							discoFeatures.add(elements.get(i).getAttribute( | ||||||
|  | 									"var")); | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				if (discoFeatures.contains("urn:xmpp:carbons:2")) { | ||||||
|  | 					sendEnableCarbons(); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	private void sendEnableCarbons() { | ||||||
|  | 		Log.d(LOGTAG,account.getJid()+": enable carbons"); | ||||||
|  | 		IqPacket iq = new IqPacket(IqPacket.TYPE_SET); | ||||||
|  | 		Element enable = new Element("enable"); | ||||||
|  | 		enable.setAttribute("xmlns", "urn:xmpp:carbons:2"); | ||||||
|  | 		iq.addChild(enable); | ||||||
|  | 		this.sendIqPacket(iq, new OnIqPacketReceived() { | ||||||
|  | 			 | ||||||
|  | 			@Override | ||||||
|  | 			public void onIqPacketReceived(Account account, IqPacket packet) { | ||||||
|  | 				if (!packet.hasChild("error")) { | ||||||
|  | 					Log.d(LOGTAG,account.getJid()+": successfully enabled carbons"); | ||||||
|  | 				} else { | ||||||
|  | 					Log.d(LOGTAG,account.getJid()+": error enableing carbons "+packet.toString()); | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| @ -337,32 +402,35 @@ public class XmppConnection implements Runnable { | |||||||
| 
 | 
 | ||||||
| 	public void sendIqPacket(IqPacket packet, OnIqPacketReceived callback) { | 	public void sendIqPacket(IqPacket packet, OnIqPacketReceived callback) { | ||||||
| 		String id = nextRandomId(); | 		String id = nextRandomId(); | ||||||
| 		packet.setAttribute("id",id); | 		packet.setAttribute("id", id); | ||||||
| 		tagWriter.writeElement(packet); | 		tagWriter.writeElement(packet); | ||||||
| 		if (callback != null) { | 		if (callback != null) { | ||||||
| 			iqPacketCallbacks.put(id, callback); | 			iqPacketCallbacks.put(id, callback); | ||||||
| 		} | 		} | ||||||
| 		Log.d(LOGTAG,account.getJid()+": sending: "+packet.toString()); | 		//Log.d(LOGTAG, account.getJid() + ": sending: " + packet.toString()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void sendMessagePacket(MessagePacket packet){ | 	public void sendMessagePacket(MessagePacket packet) { | ||||||
| 		tagWriter.writeElement(packet); | 		tagWriter.writeElement(packet); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void sendPresencePacket(PresencePacket packet) { | 	public void sendPresencePacket(PresencePacket packet) { | ||||||
| 		tagWriter.writeElement(packet); | 		tagWriter.writeElement(packet); | ||||||
| 		Log.d(LOGTAG,account.getJid()+": sending: "+packet.toString()); | 		Log.d(LOGTAG, account.getJid() + ": sending: " + packet.toString()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void setOnMessagePacketReceivedListener(OnMessagePacketReceived listener) { | 	public void setOnMessagePacketReceivedListener( | ||||||
|  | 			OnMessagePacketReceived listener) { | ||||||
| 		this.messageListener = listener; | 		this.messageListener = listener; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void setOnUnregisteredIqPacketReceivedListener(OnIqPacketReceived listener) { | 	public void setOnUnregisteredIqPacketReceivedListener( | ||||||
|  | 			OnIqPacketReceived listener) { | ||||||
| 		this.unregisteredIqListener = listener; | 		this.unregisteredIqListener = listener; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void setOnPresencePacketReceivedListener(OnPresencePacketReceived listener) { | 	public void setOnPresencePacketReceivedListener( | ||||||
|  | 			OnPresencePacketReceived listener) { | ||||||
| 		this.presenceListener = listener; | 		this.presenceListener = listener; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Daniel Gultsch
						Daniel Gultsch