+ messagePipe = null;
+ }
+ }
+ }
+
+ private void handleMessage(SignalServiceEnvelope envelope, SignalServiceContent content, boolean ignoreAttachments) {
+ if (content != null) {
+ if (content.getDataMessage().isPresent()) {
+ SignalServiceDataMessage message = content.getDataMessage().get();
+ handleSignalServiceDataMessage(message, false, envelope.getSource(), username, ignoreAttachments);
+ }
+ if (content.getSyncMessage().isPresent()) {
+ isMultiDevice = true;
+ SignalServiceSyncMessage syncMessage = content.getSyncMessage().get();
+ if (syncMessage.getSent().isPresent()) {
+ SignalServiceDataMessage message = syncMessage.getSent().get().getMessage();
+ handleSignalServiceDataMessage(message, true, envelope.getSource(), syncMessage.getSent().get().getDestination().get(), ignoreAttachments);
+ }
+ if (syncMessage.getRequest().isPresent()) {
+ RequestMessage rm = syncMessage.getRequest().get();
+ if (rm.isContactsRequest()) {
+ try {
+ sendContacts();
+ } catch (UntrustedIdentityException | IOException e) {
+ e.printStackTrace();
+ }
+ }
+ if (rm.isGroupsRequest()) {
+ try {
+ sendGroups();
+ } catch (UntrustedIdentityException | IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ if (syncMessage.getGroups().isPresent()) {
+ File tmpFile = null;
+ try {
+ tmpFile = Util.createTempFile();
+ try (InputStream attachmentAsStream = retrieveAttachmentAsStream(syncMessage.getGroups().get().asPointer(), tmpFile)) {
+ DeviceGroupsInputStream s = new DeviceGroupsInputStream(attachmentAsStream);
+ DeviceGroup g;
+ while ((g = s.read()) != null) {
+ GroupInfo syncGroup = groupStore.getGroup(g.getId());
+ if (syncGroup == null) {
+ syncGroup = new GroupInfo(g.getId());
+ }
+ if (g.getName().isPresent()) {
+ syncGroup.name = g.getName().get();
+ }
+ syncGroup.members.addAll(g.getMembers());
+ syncGroup.active = g.isActive();
+ if (g.getColor().isPresent()) {
+ syncGroup.color = g.getColor().get();
+ }
+
+ if (g.getAvatar().isPresent()) {
+ retrieveGroupAvatarAttachment(g.getAvatar().get(), syncGroup.groupId);
+ }
+ groupStore.updateGroup(syncGroup);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (tmpFile != null) {
+ try {
+ Files.delete(tmpFile.toPath());
+ } catch (IOException e) {
+ System.err.println("Failed to delete received groups temp file “" + tmpFile + "”: " + e.getMessage());
+ }
+ }
+ }
+ if (syncMessage.getBlockedList().isPresent()) {
+ // TODO store list of blocked numbers
+ }
+ }
+ if (syncMessage.getContacts().isPresent()) {
+ File tmpFile = null;
+ try {
+ tmpFile = Util.createTempFile();
+ final ContactsMessage contactsMessage = syncMessage.getContacts().get();
+ try (InputStream attachmentAsStream = retrieveAttachmentAsStream(contactsMessage.getContactsStream().asPointer(), tmpFile)) {
+ DeviceContactsInputStream s = new DeviceContactsInputStream(attachmentAsStream);
+ if (contactsMessage.isComplete()) {
+ contactStore.clear();
+ }
+ DeviceContact c;
+ while ((c = s.read()) != null) {
+ ContactInfo contact = contactStore.getContact(c.getNumber());
+ if (contact == null) {
+ contact = new ContactInfo();
+ contact.number = c.getNumber();
+ }
+ if (c.getName().isPresent()) {
+ contact.name = c.getName().get();
+ }
+ if (c.getColor().isPresent()) {
+ contact.color = c.getColor().get();
+ }
+ if (c.getProfileKey().isPresent()) {
+ contact.profileKey = Base64.encodeBytes(c.getProfileKey().get());
+ }
+ if (c.getVerified().isPresent()) {
+ final VerifiedMessage verifiedMessage = c.getVerified().get();
+ signalProtocolStore.saveIdentity(verifiedMessage.getDestination(), verifiedMessage.getIdentityKey(), TrustLevel.fromVerifiedState(verifiedMessage.getVerified()));
+ }
+ if (c.getExpirationTimer().isPresent()) {
+ ThreadInfo thread = threadStore.getThread(c.getNumber());
+ thread.messageExpirationTime = c.getExpirationTimer().get();
+ threadStore.updateThread(thread);
+ }
+ if (c.isBlocked()) {
+ // TODO store list of blocked numbers
+ }
+ contactStore.updateContact(contact);
+
+ if (c.getAvatar().isPresent()) {
+ retrieveContactAvatarAttachment(c.getAvatar().get(), contact.number);
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (tmpFile != null) {
+ try {
+ Files.delete(tmpFile.toPath());
+ } catch (IOException e) {
+ System.err.println("Failed to delete received contacts temp file “" + tmpFile + "”: " + e.getMessage());
+ }
+ }
+ }
+ }
+ if (syncMessage.getVerified().isPresent()) {
+ final VerifiedMessage verifiedMessage = syncMessage.getVerified().get();
+ signalProtocolStore.saveIdentity(verifiedMessage.getDestination(), verifiedMessage.getIdentityKey(), TrustLevel.fromVerifiedState(verifiedMessage.getVerified()));
+ }
+ }
+ }
+ }
+
+ private SignalServiceEnvelope loadEnvelope(File file) throws IOException {
+ try (FileInputStream f = new FileInputStream(file)) {
+ DataInputStream in = new DataInputStream(f);
+ int version = in.readInt();
+ if (version > 2) {
+ return null;
+ }
+ int type = in.readInt();
+ String source = in.readUTF();
+ int sourceDevice = in.readInt();
+ if (version == 1) {
+ // read legacy relay field
+ in.readUTF();
+ }
+ long timestamp = in.readLong();
+ byte[] content = null;
+ int contentLen = in.readInt();
+ if (contentLen > 0) {
+ content = new byte[contentLen];
+ in.readFully(content);
+ }
+ byte[] legacyMessage = null;
+ int legacyMessageLen = in.readInt();
+ if (legacyMessageLen > 0) {
+ legacyMessage = new byte[legacyMessageLen];
+ in.readFully(legacyMessage);
+ }
+ long serverTimestamp = 0;
+ String uuid = null;
+ if (version == 2) {
+ serverTimestamp = in.readLong();
+ uuid = in.readUTF();
+ if ("".equals(uuid)) {
+ uuid = null;
+ }
+ }
+ return new SignalServiceEnvelope(type, source, sourceDevice, timestamp, legacyMessage, content, serverTimestamp, uuid);
+ }
+ }
+
+ private void storeEnvelope(SignalServiceEnvelope envelope, File file) throws IOException {
+ try (FileOutputStream f = new FileOutputStream(file)) {
+ try (DataOutputStream out = new DataOutputStream(f)) {
+ out.writeInt(2); // version
+ out.writeInt(envelope.getType());
+ out.writeUTF(envelope.getSource());
+ out.writeInt(envelope.getSourceDevice());
+ out.writeLong(envelope.getTimestamp());
+ if (envelope.hasContent()) {
+ out.writeInt(envelope.getContent().length);
+ out.write(envelope.getContent());
+ } else {
+ out.writeInt(0);
+ }
+ if (envelope.hasLegacyMessage()) {
+ out.writeInt(envelope.getLegacyMessage().length);
+ out.write(envelope.getLegacyMessage());
+ } else {
+ out.writeInt(0);
+ }
+ out.writeLong(envelope.getServerTimestamp());
+ String uuid = envelope.getUuid();
+ out.writeUTF(uuid == null ? "" : uuid);
+ }