private SignalServiceDataMessage createSignalServiceMessage(SignalServiceEnvelope envelope, DataMessage content) { SignalServiceGroup groupInfo = createGroupInfo(envelope, content); List <SignalServiceAttachment> attachments = new List <SignalServiceAttachment>(); bool endSession = ((content.Flags & (uint)DataMessage.Types.Flags.EndSession) != 0); bool expirationUpdate = ((content.Flags & (uint)DataMessage.Types.Flags.ExpirationTimerUpdate) != 0); foreach (AttachmentPointer pointer in content.Attachments) { attachments.Add(new SignalServiceAttachmentPointer(pointer.Id, pointer.ContentType, pointer.Key.ToByteArray(), envelope.getRelay(), pointer.SizeOneofCase == AttachmentPointer.SizeOneofOneofCase.Size ? pointer.Size : 0, pointer.ThumbnailOneofCase == AttachmentPointer.ThumbnailOneofOneofCase.Thumbnail ? pointer.Thumbnail.ToByteArray() : null, pointer.DigestOneofCase == AttachmentPointer.DigestOneofOneofCase.Digest ? pointer.Digest.ToByteArray() : null, pointer.FileNameOneofCase == AttachmentPointer.FileNameOneofOneofCase.FileName ? pointer.FileName : null, pointer.FlagsOneofCase == AttachmentPointer.FlagsOneofOneofCase.Flags && (pointer.Flags & (uint)AttachmentPointer.Types.Flags.VoiceMessage) != 0)); } return(new SignalServiceDataMessage() { Timestamp = envelope.getTimestamp(), Group = groupInfo, Attachments = attachments, Body = content.Body, EndSession = endSession, ExpiresInSeconds = (int)content.ExpireTimer, ExpirationUpdate = expirationUpdate }); }
private SignalServiceDataMessage CreateSignalServiceMessage(SignalServiceEnvelope envelope, DataMessage content) { SignalServiceGroup groupInfo = CreateGroupInfo(envelope, content); List <SignalServiceAttachment> attachments = new List <SignalServiceAttachment>(); bool endSession = ((content.Flags & (uint)DataMessage.Types.Flags.EndSession) != 0); bool expirationUpdate = ((content.Flags & (uint)DataMessage.Types.Flags.ExpirationTimerUpdate) != 0); bool profileKeyUpdate = ((content.Flags & (uint)DataMessage.Types.Flags.ProfileKeyUpdate) != 0); SignalServiceDataMessage.SignalServiceQuote quote = CreateQuote(envelope, content); foreach (AttachmentPointer pointer in content.Attachments) { attachments.Add(CreateAttachmentPointer(envelope.GetRelay(), pointer)); } if (content.TimestampOneofCase == DataMessage.TimestampOneofOneofCase.Timestamp && (long)content.Timestamp != envelope.GetTimestamp()) { throw new InvalidMessageException("Timestamps don't match: " + content.Timestamp + " vs " + envelope.GetTimestamp()); } return(new SignalServiceDataMessage() { Timestamp = envelope.GetTimestamp(), Group = groupInfo, Attachments = attachments, Body = content.Body, EndSession = endSession, ExpiresInSeconds = (int)content.ExpireTimer, ExpirationUpdate = expirationUpdate, ProfileKey = content.ProfileKeyOneofCase == DataMessage.ProfileKeyOneofOneofCase.ProfileKey ? content.ProfileKey.ToByteArray() : null, ProfileKeyUpdate = profileKeyUpdate, Quote = quote }); }
private GroupContext createGroupContent(SignalServiceGroup group) { GroupContext groupContext = new GroupContext { }; groupContext.Id = ByteString.CopyFrom(group.GroupId); if (group.Type != SignalServiceGroup.GroupType.DELIVER) { if (group.Type == SignalServiceGroup.GroupType.UPDATE) { groupContext.Type = GroupContext.Types.Type.Update; } else if (group.Type == SignalServiceGroup.GroupType.QUIT) { groupContext.Type = GroupContext.Types.Type.Quit; } else if (group.Type == SignalServiceGroup.GroupType.REQUEST_INFO) { groupContext.Type = GroupContext.Types.Type.RequestInfo; } else { throw new Exception("Unknown type: " + group.Type); } if (group.Name != null) { groupContext.Name = group.Name; } if (group.Members != null) { groupContext.Members.AddRange(group.Members); } if (group.Avatar != null && group.Avatar.isStream()) { AttachmentPointer pointer = createAttachmentPointer(group.Avatar.asStream()); groupContext.Avatar = pointer; } } else { groupContext.Type = GroupContext.Types.Type.Deliver; } return(groupContext); }
private async Task <GroupContext> createGroupContent(SignalServiceGroup group) { GroupContext.Builder builder = GroupContext.CreateBuilder(); builder.SetId(ByteString.CopyFrom(group.getGroupId())); if (group.getType() != SignalServiceGroup.Type.DELIVER) { if (group.getType() == SignalServiceGroup.Type.UPDATE) { builder.SetType(GroupContext.Types.Type.UPDATE); } else if (group.getType() == SignalServiceGroup.Type.QUIT) { builder.SetType(GroupContext.Types.Type.QUIT); } else if (group.getType() == SignalServiceGroup.Type.REQUEST_INFO) { builder.SetType(GroupContext.Types.Type.REQUEST_INFO); } else { throw new Exception("Unknown type: " + group.getType()); } if (group.getName().HasValue) { builder.SetName(group.getName().ForceGetValue()); } if (group.getMembers().HasValue) { builder.AddRangeMembers(group.getMembers().ForceGetValue()); } if (group.getAvatar().HasValue&& group.getAvatar().ForceGetValue().isStream()) { AttachmentPointer pointer = await createAttachmentPointer(group.getAvatar().ForceGetValue().asStream()); builder.SetAvatar(pointer); } } else { builder.SetType(GroupContext.Types.Type.DELIVER); } return(builder.Build()); }
private SignalServiceDataMessage createSignalServiceMessage(SignalServiceEnvelope envelope, DataMessage content) { SignalServiceGroup groupInfo = createGroupInfo(envelope, content); List <SignalServiceAttachment> attachments = new List <SignalServiceAttachment>(); bool endSession = ((content.Flags & (uint)DataMessage.Types.Flags.END_SESSION) != 0); bool expirationUpdate = ((content.Flags & (uint)DataMessage.Types.Flags.EXPIRATION_TIMER_UPDATE) != 0); foreach (AttachmentPointer pointer in content.AttachmentsList) { attachments.Add(new SignalServiceAttachmentPointer(pointer.Id, pointer.ContentType, pointer.Key.ToByteArray(), envelope.getRelay(), pointer.HasSize ? new May <uint>(pointer.Size) : May <uint> .NoValue, pointer.HasThumbnail ? new May <byte[]>(pointer.Thumbnail.ToByteArray()) : May <byte[]> .NoValue)); } return(new SignalServiceDataMessage(envelope.getTimestamp(), groupInfo, attachments, content.Body, endSession, (int)content.ExpireTimer, expirationUpdate)); }
private void HandleSignalMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp) { SignalMessageDirection type; SignalContact author; SignalMessageStatus status; string threadId; long composedTimestamp; string body = dataMessage.Body != null ? dataMessage.Body : ""; if (dataMessage.Group != null) { var rawId = dataMessage.Group.GroupId; threadId = Base64.encodeBytes(rawId); var g = SignalDBContext.GetOrCreateGroupLocked(threadId, timestamp, this); if (!g.CanReceive) { SignalServiceGroup group = new SignalServiceGroup() { Type = SignalServiceGroup.GroupType.REQUEST_INFO, GroupId = rawId }; SignalServiceDataMessage requestInfoMessage = new SignalServiceDataMessage() { Group = group, Timestamp = Util.CurrentTimeMillis() }; MessageSender.sendMessage(envelope.getSourceAddress(), requestInfoMessage); } composedTimestamp = envelope.getTimestamp(); } else { if (isSync) { var sent = content.SynchronizeMessage.getSent().ForceGetValue(); threadId = SignalDBContext.GetOrCreateContactLocked(sent.getDestination().ForceGetValue(), timestamp, this).ThreadId; composedTimestamp = sent.getTimestamp(); } else { threadId = SignalDBContext.GetOrCreateContactLocked(envelope.getSource(), timestamp, this).ThreadId; composedTimestamp = envelope.getTimestamp(); } } if (isSync) { type = SignalMessageDirection.Synced; status = SignalMessageStatus.Confirmed; author = null; } else { status = 0; type = SignalMessageDirection.Incoming; author = SignalDBContext.GetOrCreateContactLocked(envelope.getSource(), timestamp, this); } List <SignalAttachment> attachments = new List <SignalAttachment>(); SignalMessage message = new SignalMessage() { Direction = type, Status = status, Author = author, Content = new SignalMessageContent() { Content = body }, ThreadId = threadId, DeviceId = (uint)envelope.getSourceDevice(), Receipts = 0, ComposedTimestamp = composedTimestamp, ReceivedTimestamp = timestamp, AttachmentsCount = (uint)attachments.Count, Attachments = attachments }; if (dataMessage.Attachments != null) { var receivedAttachments = dataMessage.Attachments; foreach (var receivedAttachment in receivedAttachments) { var pointer = receivedAttachment.asPointer(); SignalAttachment sa = new SignalAttachment() { Message = message, Status = (uint)SignalAttachmentStatus.Default, SentFileName = pointer.FileName, ContentType = "", Key = pointer.Key, Relay = pointer.Relay, StorageId = pointer.Id }; attachments.Add(sa); } } Debug.WriteLine("received message: " + message.Content); if (type == SignalMessageDirection.Incoming) { if (App.WindowActive) { Utils.TryVibrate(true); } else { SendTileNotification(message); SendMessageNotification(message); } } Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() => { await UIHandleIncomingMessage(message); }).AsTask().Wait(); }
private void HandleGroupUpdateMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp) { if (dataMessage.Group != null) //TODO check signal droid: group messages have different types! { SignalServiceGroup group = dataMessage.Group; string groupid = Base64.encodeBytes(group.GroupId); SignalGroup g = new SignalGroup(); string displayname = "Unknown group"; string avatarfile = null; if (group.Name != null) { displayname = group.Name; } var dbgroup = SignalDBContext.InsertOrUpdateGroupLocked(groupid, displayname, avatarfile, true, timestamp, this); if (group.Members != null) { foreach (var member in group.Members) { SignalDBContext.InsertOrUpdateGroupMembershipLocked(dbgroup.Id, SignalDBContext.GetOrCreateContactLocked(member, 0, this).Id); } } /* insert message into conversation */ SignalMessageDirection type; SignalContact author; SignalMessageStatus status; string prefix; long composedTimestamp; if (isSync) { var sent = content.SynchronizeMessage.getSent().ForceGetValue(); type = SignalMessageDirection.Synced; status = SignalMessageStatus.Confirmed; composedTimestamp = sent.getTimestamp(); author = null; prefix = "You have"; } else { status = 0; type = SignalMessageDirection.Incoming; author = SignalDBContext.GetOrCreateContactLocked(envelope.getSource(), timestamp, this); prefix = $"{author.ThreadDisplayName} has"; composedTimestamp = envelope.getTimestamp(); } SignalMessage sm = new SignalMessage() { Direction = type, Type = SignalMessageType.GroupUpdate, Status = status, Author = author, Content = new SignalMessageContent() { Content = $"{prefix} updated the group." }, ThreadId = groupid, DeviceId = (uint)envelope.getSourceDevice(), Receipts = 0, ComposedTimestamp = composedTimestamp, ReceivedTimestamp = timestamp, }; Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() => { await UIHandleIncomingMessage(sm); }).AsTask().Wait(); } else { Debug.WriteLine("received group update without group info!"); } }
private async Task HandleSignalMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp) { SignalMessageDirection type; SignalContact author; SignalMessageStatus status; SignalConversation conversation; long composedTimestamp; string body = dataMessage.Body ?? ""; if (dataMessage.Group != null) { var rawId = dataMessage.Group.GroupId; var threadId = Base64.EncodeBytes(rawId); conversation = await SignalDBContext.GetOrCreateGroupLocked(threadId, timestamp); if (!conversation.CanReceive) { SignalServiceGroup group = new SignalServiceGroup() { Type = SignalServiceGroup.GroupType.REQUEST_INFO, GroupId = rawId }; SignalServiceDataMessage requestInfoMessage = new SignalServiceDataMessage() { Group = group, Timestamp = Util.CurrentTimeMillis() }; SignalLibHandle.Instance.OutgoingQueue.Add(new SignalServiceDataMessageSendable(requestInfoMessage, envelope.GetSourceAddress())); } composedTimestamp = envelope.GetTimestamp(); } else { if (isSync) { var sent = content.SynchronizeMessage.Sent; conversation = await SignalDBContext.GetOrCreateContactLocked(sent.Destination.ForceGetValue(), timestamp); composedTimestamp = sent.Timestamp; } else { conversation = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), timestamp); composedTimestamp = envelope.GetTimestamp(); } } if (isSync) { type = SignalMessageDirection.Synced; status = SignalMessageStatus.Confirmed; author = null; } else { status = 0; type = SignalMessageDirection.Incoming; author = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), timestamp); } if (author != null && author.Blocked) { // Don't save blocked messages return; } List <SignalAttachment> attachments = new List <SignalAttachment>(); SignalMessage message = new SignalMessage() { Direction = type, Status = status, Author = author, Content = new SignalMessageContent() { Content = body.Truncate(2000) }, ThreadId = conversation.ThreadId, DeviceId = (uint)envelope.GetSourceDevice(), Receipts = 0, ComposedTimestamp = composedTimestamp, ReceivedTimestamp = timestamp, AttachmentsCount = (uint)attachments.Count, Attachments = attachments }; if (dataMessage.Attachments != null) { var receivedAttachments = dataMessage.Attachments; foreach (var receivedAttachment in receivedAttachments) { var pointer = receivedAttachment.AsPointer(); SignalAttachment sa = new SignalAttachment() { Message = message, Status = (uint)SignalAttachmentStatus.Default, SentFileName = pointer.FileName, ContentType = receivedAttachment.ContentType, Key = pointer.Key, Relay = pointer.Relay, StorageId = pointer.Id, Size = (long)pointer.Size, Digest = pointer.Digest }; attachments.Add(sa); } // Make sure to update attachments count message.AttachmentsCount = (uint)attachments.Count; } await SignalLibHandle.Instance.SaveAndDispatchSignalMessage(message, null, conversation); }
private async Task HandleGroupUpdateMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp) { if (dataMessage.Group != null) //TODO check signal droid: group messages have different types! { SignalServiceGroup group = dataMessage.Group; string groupid = Base64.EncodeBytes(group.GroupId); SignalGroup g = new SignalGroup(); string displayname = "Unknown group"; string avatarfile = null; if (group.Name != null) { displayname = group.Name; } var dbgroup = SignalDBContext.InsertOrUpdateGroupLocked(groupid, displayname, avatarfile, true, timestamp); if (group.Members != null) { foreach (var member in group.Members) { SignalDBContext.InsertOrUpdateGroupMembershipLocked(dbgroup.Id, (await SignalDBContext.GetOrCreateContactLocked(member, 0)).Id); } } /* insert message into conversation */ SignalMessageDirection type; SignalContact author; SignalMessageStatus status; string prefix; long composedTimestamp; if (isSync) { var sent = content.SynchronizeMessage.Sent; type = SignalMessageDirection.Synced; status = SignalMessageStatus.Confirmed; composedTimestamp = sent.Timestamp; author = null; prefix = "You have"; } else { status = 0; type = SignalMessageDirection.Incoming; author = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), timestamp); prefix = $"{author.ThreadDisplayName} has"; composedTimestamp = envelope.GetTimestamp(); } SignalMessage sm = new SignalMessage() { Direction = type, Type = SignalMessageType.GroupUpdate, Status = status, Author = author, Content = new SignalMessageContent() { Content = $"{prefix} updated the group." }, ThreadId = groupid, DeviceId = (uint)envelope.GetSourceDevice(), Receipts = 0, ComposedTimestamp = composedTimestamp, ReceivedTimestamp = timestamp, }; SignalDBContext.SaveMessageLocked(sm); dbgroup.MessagesCount += 1; if (sm.Direction == SignalMessageDirection.Incoming) { dbgroup.UnreadCount += 1; } else { dbgroup.UnreadCount = 0; dbgroup.LastSeenMessageIndex = dbgroup.MessagesCount; } dbgroup.LastMessage = sm; await SignalLibHandle.Instance.DispatchAddOrUpdateConversation(dbgroup, sm); } else { Logger.LogError("HandleGroupUpdateMessage() received group update without group info"); } }
private async Task HandleGroupLeaveMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp) { SignalServiceGroup sentGroup = dataMessage.Group; if (sentGroup != null) { string groupid = Base64.EncodeBytes(sentGroup.GroupId); SignalGroup group = await SignalDBContext.GetOrCreateGroupLocked(groupid, 0); if (isSync) { SignalContact author = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), 0); SignalMessage sm = new SignalMessage() { Direction = SignalMessageDirection.Incoming, Type = SignalMessageType.GroupLeave, Status = SignalMessageStatus.Received, Author = author, Content = new SignalMessageContent() { Content = $"You have left the group." }, ThreadId = groupid, DeviceId = (uint)envelope.GetSourceDevice(), Receipts = 0, ComposedTimestamp = envelope.GetTimestamp(), ReceivedTimestamp = timestamp, }; SignalConversation updatedConversation = SignalDBContext.RemoveMemberFromGroup(groupid, author, sm); await SignalLibHandle.Instance.DispatchAddOrUpdateConversation(updatedConversation, sm); } else { SignalContact author = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), 0); SignalMessage sm = new SignalMessage() { Direction = SignalMessageDirection.Incoming, Type = SignalMessageType.GroupLeave, Status = SignalMessageStatus.Received, Author = author, Content = new SignalMessageContent() { Content = $"{author.ThreadDisplayName} has left the group." }, ThreadId = groupid, DeviceId = (uint)envelope.GetSourceDevice(), Receipts = 0, ComposedTimestamp = envelope.GetTimestamp(), ReceivedTimestamp = timestamp, }; SignalConversation updatedConversation = SignalDBContext.RemoveMemberFromGroup(groupid, author, sm); await SignalLibHandle.Instance.DispatchAddOrUpdateConversation(updatedConversation, sm); } } else { Logger.LogError("HandleGroupLeaveMessage() received group update without group info"); } }
private void HandleSignalMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp) { SignalMessageDirection type; SignalContact author; SignalMessageStatus status; SignalConversation conversation; long composedTimestamp; string body = dataMessage.Body ?? ""; if (dataMessage.Group != null) { var rawId = dataMessage.Group.GroupId; var threadId = Base64.encodeBytes(rawId); conversation = SignalDBContext.GetOrCreateGroupLocked(threadId, timestamp); if (!conversation.CanReceive) { SignalServiceGroup group = new SignalServiceGroup() { Type = SignalServiceGroup.GroupType.REQUEST_INFO, GroupId = rawId }; SignalServiceDataMessage requestInfoMessage = new SignalServiceDataMessage() { Group = group, Timestamp = Util.CurrentTimeMillis() }; //MessageSender.sendMessage(envelope.getSourceAddress(), requestInfoMessage); TODO } composedTimestamp = envelope.getTimestamp(); } else { if (isSync) { var sent = content.SynchronizeMessage.getSent().ForceGetValue(); conversation = SignalDBContext.GetOrCreateContactLocked(sent.getDestination().ForceGetValue(), timestamp); composedTimestamp = sent.getTimestamp(); } else { conversation = SignalDBContext.GetOrCreateContactLocked(envelope.getSource(), timestamp); composedTimestamp = envelope.getTimestamp(); } } if (isSync) { type = SignalMessageDirection.Synced; status = SignalMessageStatus.Confirmed; author = null; } else { status = 0; type = SignalMessageDirection.Incoming; author = SignalDBContext.GetOrCreateContactLocked(envelope.getSource(), timestamp); } List <SignalAttachment> attachments = new List <SignalAttachment>(); SignalMessage message = new SignalMessage() { Direction = type, Status = status, Author = author, Content = new SignalMessageContent() { Content = body }, ThreadId = conversation.ThreadId, DeviceId = (uint)envelope.getSourceDevice(), Receipts = 0, ComposedTimestamp = composedTimestamp, ReceivedTimestamp = timestamp, AttachmentsCount = (uint)attachments.Count, Attachments = attachments }; if (dataMessage.Attachments != null) { var receivedAttachments = dataMessage.Attachments; foreach (var receivedAttachment in receivedAttachments) { var pointer = receivedAttachment.asPointer(); SignalAttachment sa = new SignalAttachment() { Message = message, Status = (uint)SignalAttachmentStatus.Default, SentFileName = pointer.FileName, ContentType = "", Key = pointer.Key, Relay = pointer.Relay, StorageId = pointer.Id }; attachments.Add(sa); } } SignalLibHandle.Instance.SaveAndDispatchSignalMessage(message, conversation); }