private SignalServiceSyncMessage createSynchronizeMessage(SignalServiceEnvelope envelope, SyncMessage content) { if (content.SentOneofCase == SyncMessage.SentOneofOneofCase.Sent) { SyncMessage.Types.Sent sentContent = content.Sent; return(SignalServiceSyncMessage.forSentTranscript(new SentTranscriptMessage(sentContent.Destination, (long)sentContent.Timestamp, createSignalServiceMessage(envelope, sentContent.Message), (long)sentContent.ExpirationStartTimestamp))); } if (content.RequestOneofCase == SyncMessage.RequestOneofOneofCase.Request) { return(SignalServiceSyncMessage.forRequest(new RequestMessage(content.Request))); } if (content.Read.Count > 0) { List <ReadMessage> readMessages = new List <ReadMessage>(); foreach (SyncMessage.Types.Read read in content.Read) { readMessages.Add(new ReadMessage(read.Sender, (long)read.Timestamp)); } return(SignalServiceSyncMessage.forRead(readMessages)); } return(SignalServiceSyncMessage.empty()); }
/// <summary> /// Marks and dispatches a message as read. Must not be called on a task which holds the handle lock. /// </summary> /// <param name="message"></param> public async Task SetMessageRead(long index, SignalMessage message, SignalConversation conversation) { Logger.LogTrace("SetMessageRead() locking"); await SemaphoreSlim.WaitAsync(CancelSource.Token); try { Logger.LogTrace("SetMessageRead() locked"); conversation = SignalDBContext.UpdateMessageRead(index, conversation); OutgoingMessages.SendMessage(SignalServiceSyncMessage.ForRead(new List <ReadMessage>() { new ReadMessage(message.Author.ThreadId, message.ComposedTimestamp) })); await DispatchMessageRead(index + 1, conversation); } catch (Exception e) { Logger.LogError("SetMessageRead() failed: {0}\n{1}", e.Message, e.StackTrace); } finally { SemaphoreSlim.Release(); } Logger.LogTrace("SetMessageRead() released"); }
public void SendMessage(SignalServiceSyncMessage message) { lock (this) { MessageSender.SendMessage(Token, message); } }
public void sendMessage(SignalServiceSyncMessage message) { byte[] content; if (message.getContacts().HasValue) { content = createMultiDeviceContactsContent(message.getContacts().ForceGetValue().Contacts.asStream(), message.getContacts().ForceGetValue().Complete); } else if (message.getGroups().HasValue) { content = createMultiDeviceGroupsContent(message.getGroups().ForceGetValue().asStream()); } else if (message.getRead().HasValue) { content = createMultiDeviceReadContent(message.getRead().ForceGetValue()); } else if (message.getBlockedList().HasValue) { content = createMultiDeviceBlockedContent(message.getBlockedList().ForceGetValue()); } else { throw new Exception("Unsupported sync message!"); } sendMessage(localAddress, Util.CurrentTimeMillis(), content, false, false); }
/// <summary> /// Marks and dispatches a message as read. Must not be called on a task which holds the handle lock. /// </summary> /// <param name="message"></param> public async Task SetMessageRead(SignalMessage message) { Logger.LogTrace("SetMessageRead() locking"); await SemaphoreSlim.WaitAsync(CancelSource.Token); try { Logger.LogTrace("SetMessageRead() locked"); var updatedConversation = SignalDBContext.UpdateMessageRead(message.ComposedTimestamp); UpdateMessageExpiration(message, updatedConversation.ExpiresInSeconds); OutgoingQueue.Add(new SignalServiceSyncMessageSendable(SignalServiceSyncMessage.ForRead(new List <ReadMessage>() { new ReadMessage(message.Author.ThreadId, message.ComposedTimestamp) }))); await DispatchMessageRead(updatedConversation); } catch (Exception e) { Logger.LogError("SetMessageRead() failed: {0}\n{1}", e.Message, e.StackTrace); } finally { SemaphoreSlim.Release(); } Logger.LogTrace("SetMessageRead() released"); }
public async Task SendBlockedMessage() { List <SignalContact> blockedContacts = SignalDBContext.GetAllContactsLocked().Where(c => c.Blocked).ToList(); List <string> blockedNumbers = new List <string>(); foreach (var contact in blockedContacts) { blockedNumbers.Add(contact.ThreadId); } var blockMessage = SignalServiceSyncMessage.ForBlocked(new BlockedListMessage(blockedNumbers)); OutgoingMessages.SendMessage(blockMessage); await DispatchHandleBlockedContacts(blockedContacts); }
private SignalServiceContent(SignalServiceSyncMessage synchronizeMessage, SignalServiceAddress sender, int senderDevice, long timestamp, bool needsReceipt, SignalServiceContentProto serializedState) { Sender = sender; SenderDevice = senderDevice; Timestamp = timestamp; NeedsReceipt = needsReceipt; this.serializedState = serializedState; Message = null; SynchronizeMessage = synchronizeMessage; CallingMessage = null; ReadMessage = null; TypingMessage = null; }
public void RequestSync() { Task.Run(() => { Logger.LogTrace("RequestSync()"); var contactsRequest = SignalServiceSyncMessage.ForRequest(new RequestMessage(new SyncMessage.Types.Request() { Type = SyncMessage.Types.Request.Types.Type.Contacts })); OutgoingMessages.SendMessage(contactsRequest); var groupsRequest = SignalServiceSyncMessage.ForRequest(new RequestMessage(new SyncMessage.Types.Request() { Type = SyncMessage.Types.Request.Types.Type.Groups })); OutgoingMessages.SendMessage(groupsRequest); }); }
/// <summary> /// TODO /// </summary> /// <param name="token"></param> /// <param name="message"></param> public async Task SendMessage(CancellationToken token, SignalServiceSyncMessage message) { byte[] content; if (message.Contacts != null) { content = await CreateMultiDeviceContactsContent(token, message.Contacts.Contacts.AsStream(), message.Contacts.Complete); } else if (message.Groups != null) { content = await CreateMultiDeviceGroupsContent(token, message.Groups.AsStream()); } else if (message.Reads != null) { content = CreateMultiDeviceReadContent(message.Reads); } else if (message.BlockedList != null) { content = CreateMultiDeviceBlockedContent(message.BlockedList); } else if (message.Configuration != null) { content = CreateMultiDeviceConfigurationContent(message.Configuration); } else if (message.Verified != null) { await SendMessage(token, message.Verified); return; } else if (message.Request != null) { content = CreateRequestContent(message.Request); } else { throw new Exception("Unsupported sync message!"); } await SendMessage(token, localAddress, Util.CurrentTimeMillis(), content, false); }
public void RequestSync() { try { Logger.LogTrace("RequestSync()"); var contactsRequest = SignalServiceSyncMessage.ForRequest(new RequestMessage(new SyncMessage.Types.Request() { Type = SyncMessage.Types.Request.Types.Type.Contacts })); OutgoingQueue.Add(new SignalServiceSyncMessageSendable(contactsRequest)); var groupsRequest = SignalServiceSyncMessage.ForRequest(new RequestMessage(new SyncMessage.Types.Request() { Type = SyncMessage.Types.Request.Types.Type.Groups })); OutgoingQueue.Add(new SignalServiceSyncMessageSendable(groupsRequest)); } catch (Exception e) { Logger.LogError("RequestSync() failed: {0}\n{1}", e.Message, e.StackTrace); } }
public SignalServiceSyncMessageSendable(SignalServiceSyncMessage message) { SyncMessage = message; }
/// <summary> /// /// </summary> /// <param name="metadata"></param> /// <param name="content"></param> /// <returns></returns> /// <exception cref="ProtocolInvalidMessageException"></exception> /// <exception cref="ProtocolInvalidKeyException"></exception> private static SignalServiceSyncMessage CreateSynchronizeMessage(SignalServiceMetadata metadata, SyncMessage content) { if (content.Sent != null) { var unidentifiedStatuses = new Dictionary <SignalServiceAddress, bool>(); SyncMessage.Types.Sent sentContent = content.Sent; SignalServiceDataMessage dataMessage = CreateSignalServiceMessage(metadata, sentContent.Message); SignalServiceAddress? address = SignalServiceAddress.IsValidAddress(sentContent.DestinationUuid, sentContent.Destination) ? new SignalServiceAddress(UuidUtil.ParseOrNull(sentContent.DestinationUuid), sentContent.Destination) : null; if (address == null && dataMessage.Group == null) { throw new ProtocolInvalidMessageException(new InvalidMessageException("SyncMessage missing both destination and group ID!"), null, 0); } foreach (var status in sentContent.UnidentifiedStatus) { if (SignalServiceAddress.IsValidAddress(status.DestinationUuid, status.Destination)) { SignalServiceAddress recipient = new SignalServiceAddress(UuidUtil.ParseOrNull(status.DestinationUuid), status.Destination); unidentifiedStatuses.Add(recipient, status.Unidentified); } else { logger.LogWarning("Encountered an invalid UnidentifiedDeliveryStatus in a SentTranscript! Ignoring."); } } return(SignalServiceSyncMessage.ForSentTranscript(new SentTranscriptMessage(address !, (long)sentContent.Timestamp, CreateSignalServiceMessage(metadata, sentContent.Message), (long)sentContent.ExpirationStartTimestamp, unidentifiedStatuses, sentContent.IsRecipientUpdate))); } if (content.Request != null) { return(SignalServiceSyncMessage.ForRequest(new RequestMessage(content.Request))); } if (content.Read.Count > 0) { List <ReadMessage> readMessages = new List <ReadMessage>(); foreach (SyncMessage.Types.Read read in content.Read) { if (SignalServiceAddress.IsValidAddress(read.SenderUuid, read.Sender)) { SignalServiceAddress address = new SignalServiceAddress(UuidUtil.ParseOrNull(read.SenderUuid), read.Sender); readMessages.Add(new ReadMessage(address, (long)read.Timestamp)); } else { logger.LogWarning("Encountered an invalid ReadMessage! Ignoring."); } } return(SignalServiceSyncMessage.ForRead(readMessages)); } if (content.ViewOnceOpen != null) { if (SignalServiceAddress.IsValidAddress(content.ViewOnceOpen.SenderUuid, content.ViewOnceOpen.Sender)) { SignalServiceAddress address = new SignalServiceAddress(UuidUtil.ParseOrNull(content.ViewOnceOpen.SenderUuid), content.ViewOnceOpen.Sender); ViewOnceOpenMessage timerRead = new ViewOnceOpenMessage(address, (long)content.ViewOnceOpen.Timestamp); return(SignalServiceSyncMessage.ForViewOnceOpen(timerRead)); } else { throw new ProtocolInvalidMessageException(new InvalidMessageException("ViewOnceOpen message has no sender!"), null, 0); } } if (content.Contacts != null) { AttachmentPointer pointer = content.Contacts.Blob; return(SignalServiceSyncMessage.ForContacts(new ContactsMessage(CreateAttachmentPointer(pointer), content.Contacts.Complete))); } if (content.Groups != null) { AttachmentPointer pointer = content.Groups.Blob; return(SignalServiceSyncMessage.ForGroups(CreateAttachmentPointer(pointer))); } if (content.Verified != null) { if (SignalServiceAddress.IsValidAddress(content.Verified.DestinationUuid, content.Verified.Destination)) { try { Verified verified = content.Verified; SignalServiceAddress destination = new SignalServiceAddress(UuidUtil.ParseOrNull(verified.DestinationUuid), verified.Destination); IdentityKey identityKey = new IdentityKey(verified.IdentityKey.ToByteArray(), 0); VerifiedMessage.VerifiedState verifiedState; if (verified.State == Verified.Types.State.Default) { verifiedState = VerifiedMessage.VerifiedState.Default; } else if (verified.State == Verified.Types.State.Verified) { verifiedState = VerifiedMessage.VerifiedState.Verified; } else if (verified.State == Verified.Types.State.Unverified) { verifiedState = VerifiedMessage.VerifiedState.Unverified; } else { throw new ProtocolInvalidMessageException(new InvalidMessageException($"Unknown state: {(int)verified.State}"), metadata.Sender.GetIdentifier(), metadata.SenderDevice); } return(SignalServiceSyncMessage.ForVerified(new VerifiedMessage(destination, identityKey, verifiedState, Util.CurrentTimeMillis()))); } catch (InvalidKeyException ex) { throw new ProtocolInvalidKeyException(ex, metadata.Sender.GetIdentifier(), metadata.SenderDevice); } } else { throw new ProtocolInvalidMessageException(new InvalidMessageException("Verified message has no sender!"), null, 0); } } if (content.StickerPackOperation.Count > 0) { List <StickerPackOperationMessage> operations = new List <StickerPackOperationMessage>(); foreach (var operation in content.StickerPackOperation) { byte[]? packId = operation.HasPackId ? operation.PackId.ToByteArray() : null; byte[]? packKey = operation.HasPackKey ? operation.PackKey.ToByteArray() : null; StickerPackOperationMessage.OperationType?type = null; if (operation.HasType) { switch (operation.Type) { case SyncMessage.Types.StickerPackOperation.Types.Type.Install: type = StickerPackOperationMessage.OperationType.Install; break; case SyncMessage.Types.StickerPackOperation.Types.Type.Remove: type = StickerPackOperationMessage.OperationType.Remove; break; } } operations.Add(new StickerPackOperationMessage(packId, packKey, type)); } return(SignalServiceSyncMessage.ForStickerPackOperations(operations)); } if (content.Blocked != null) { List <string> numbers = content.Blocked.Numbers.ToList(); List <string> uuids = content.Blocked.Uuids.ToList(); List <SignalServiceAddress> addresses = new List <SignalServiceAddress>(numbers.Count + uuids.Count); List <byte[]> groupIds = new List <byte[]>(content.Blocked.GroupIds.Count); foreach (string e164 in numbers) { SignalServiceAddress?address = SignalServiceAddress.FromRaw(null, e164); if (address != null) { addresses.Add(address); } } foreach (string uuid in uuids) { SignalServiceAddress?address = SignalServiceAddress.FromRaw(uuid, null); if (address != null) { addresses.Add(address); } } foreach (ByteString groupId in content.Blocked.GroupIds) { groupIds.Add(groupId.ToByteArray()); } return(SignalServiceSyncMessage.ForBlocked(new BlockedListMessage(addresses, groupIds))); } if (content.Configuration != null) { bool?readReceipts = content.Configuration.HasReadReceipts ? content.Configuration.ReadReceipts : (bool?)null; bool?unidentifiedDeliveryIndicators = content.Configuration.HasUnidentifiedDeliveryIndicators ? content.Configuration.UnidentifiedDeliveryIndicators : (bool?)null; bool?typingIndicators = content.Configuration.HasTypingIndicators ? content.Configuration.TypingIndicators : (bool?)null; bool?linkPreviews = content.Configuration.HasLinkPreviews ? content.Configuration.LinkPreviews : (bool?)null; return(SignalServiceSyncMessage.ForConfiguration(new ConfigurationMessage(readReceipts, unidentifiedDeliveryIndicators, typingIndicators, linkPreviews))); } return(SignalServiceSyncMessage.Empty()); }
public SignalServiceContent(SignalServiceSyncMessage synchronizeMessage) { message = May.NoValue; this.synchronizeMessage = new May <SignalServiceSyncMessage>(synchronizeMessage); }
private SignalServiceSyncMessage CreateSynchronizeMessage(Metadata metadata, SyncMessage content) { if (content.SentOneofCase == SyncMessage.SentOneofOneofCase.Sent) { SyncMessage.Types.Sent sentContent = content.Sent; var unidentifiedStatuses = new Dictionary <string, bool>(); foreach (var status in sentContent.UnidentifiedStatus) { unidentifiedStatuses[status.Destination] = status.Unidentified; } return(SignalServiceSyncMessage.ForSentTranscript(new SentTranscriptMessage(sentContent.Destination, (long)sentContent.Timestamp, CreateSignalServiceMessage(metadata, sentContent.Message), (long)sentContent.ExpirationStartTimestamp, unidentifiedStatuses))); } if (content.RequestOneofCase == SyncMessage.RequestOneofOneofCase.Request) { return(SignalServiceSyncMessage.ForRequest(new RequestMessage(content.Request))); } if (content.Read.Count > 0) { List <ReadMessage> readMessages = new List <ReadMessage>(); foreach (SyncMessage.Types.Read read in content.Read) { readMessages.Add(new ReadMessage(read.Sender, (long)read.Timestamp)); } return(SignalServiceSyncMessage.ForRead(readMessages)); } if (content.ContactsOneofCase == SyncMessage.ContactsOneofOneofCase.Contacts) { AttachmentPointer pointer = content.Contacts.Blob; return(SignalServiceSyncMessage.ForContacts(new ContactsMessage(CreateAttachmentPointer(pointer), content.Contacts.Complete))); } if (content.GroupsOneofCase == SyncMessage.GroupsOneofOneofCase.Groups) { AttachmentPointer pointer = content.Groups.Blob; return(SignalServiceSyncMessage.ForGroups(CreateAttachmentPointer(pointer))); } if (content.VerifiedOneofCase == SyncMessage.VerifiedOneofOneofCase.Verified) { try { Verified verified = content.Verified; string destination = verified.Destination; IdentityKey identityKey = new IdentityKey(verified.IdentityKey.ToByteArray(), 0); VerifiedMessage.VerifiedState verifiedState; if (verified.State == Verified.Types.State.Default) { verifiedState = VerifiedMessage.VerifiedState.Default; } else if (verified.State == Verified.Types.State.Verified) { verifiedState = VerifiedMessage.VerifiedState.Verified; } else if (verified.State == Verified.Types.State.Unverified) { verifiedState = VerifiedMessage.VerifiedState.Unverified; } else { throw new InvalidMessageException("Unknown state: " + verified.State); } return(SignalServiceSyncMessage.ForVerified(new VerifiedMessage(destination, identityKey, verifiedState, Util.CurrentTimeMillis()))); } catch (InvalidKeyException e) { throw new InvalidMessageException(e); } } if (content.BlockedOneofCase == SyncMessage.BlockedOneofOneofCase.Blocked) { List <string> blockedNumbers = new List <string>(content.Blocked.Numbers.Count); foreach (var blocked in content.Blocked.Numbers) { blockedNumbers.Add(blocked); } return(SignalServiceSyncMessage.ForBlocked(new BlockedListMessage(blockedNumbers, content.Blocked.GroupIds.Select(gid => gid.ToByteArray()).ToList()))); } if (content.VerifiedOneofCase == SyncMessage.VerifiedOneofOneofCase.Verified) { try { Verified verified = content.Verified; string destination = verified.Destination; IdentityKey identityKey = new IdentityKey(verified.IdentityKey.ToByteArray(), 0); VerifiedMessage.VerifiedState verifiedState; if (verified.State == Verified.Types.State.Default) { verifiedState = VerifiedMessage.VerifiedState.Default; } else if (verified.State == Verified.Types.State.Verified) { verifiedState = VerifiedMessage.VerifiedState.Verified; } else if (verified.State == Verified.Types.State.Unverified) { verifiedState = VerifiedMessage.VerifiedState.Unverified; } else { throw new ProtocolInvalidMessageException(new InvalidMessageException("Unknown state: " + verified.State), metadata.Sender, metadata.SenderDevice); } return(SignalServiceSyncMessage.ForVerified(new VerifiedMessage(destination, identityKey, verifiedState, Util.CurrentTimeMillis()))); } catch (InvalidKeyException e) { throw new ProtocolInvalidKeyException(e, metadata.Sender, metadata.SenderDevice); } } return(SignalServiceSyncMessage.Empty()); }