/// <summary> /// Sends a <seealso cref="QueryArchiveMessage"/> to the server and requests the MAM archive. /// </summary> /// <param name="filter">A filter for filtering the MAM results like filtering by JID.</param> /// <param name="rsm">Optional configuration for the result set.</param> /// <param name="to">The target of the request. null for request to your own server. Used for requesting MUC-MAMs.</param> /// <returns>The result of the request.</returns> public async Task<MessageResponseHelperResult<MamResult>> requestMamAsync(QueryFilter filter, Set rsm, string to) { QueryArchiveMessage msg = new QueryArchiveMessage(filter, rsm, CONNECTION.account.getFullJid(), to); List<QueryArchiveResultMessage> results = new List<QueryArchiveResultMessage>(); Predicate<AbstractAddressableMessage> predicate = (x) => { if (x is QueryArchiveResultMessage result && string.Equals(result.QUERY_ID, msg.QUERY_ID)) { results.Insert(0, result); return false; } return x is QueryArchiveFinishMessage fin && string.Equals(fin.ID, msg.ID) && string.Equals(fin.QUERY_ID, msg.QUERY_ID); }; AsyncMessageResponseHelper<AbstractAddressableMessage> helper = new AsyncMessageResponseHelper<AbstractAddressableMessage>(CONNECTION, predicate) { matchId = false }; MessageResponseHelperResult<AbstractAddressableMessage> finResult = await helper.startAsync(msg); MamResult mamResult = null; if (finResult.STATE == MessageResponseHelperResultState.SUCCESS) { mamResult = new MamResult(finResult.RESULT as QueryArchiveFinishMessage, results); } return new MessageResponseHelperResult<MamResult>(finResult.STATE, mamResult); }
private async Task <bool> DiscoAsync(string discoTarget, CheckDiscoResponseAsync action, DiscoType discoType) { MessageResponseHelperResult <IQMessage> result = await CONNECTION.GENERAL_COMMAND_HELPER.discoAsync(discoTarget, discoType); if (result.STATE != MessageResponseHelperResultState.SUCCESS) { Logger.Error($"Failed to perform server DISCO#{discoType} for '{CONNECTION.account.getBareJid()}' - {result.STATE}"); return(false); } if (result.RESULT is IQErrorMessage errorMessage) { Logger.Error($"Failed to perform server DISCO#{discoType} for '{CONNECTION.account.getBareJid()}' - {errorMessage.ERROR_OBJ}"); return(false); } // Success: if (result.RESULT is DiscoResponseMessage disco) { await OnDiscoResponseMessage(disco, action, discoTarget); return(true); } Logger.Error($"Failed to perform server DISCO#{discoType} for '{CONNECTION.account.getBareJid()}' - invalid response."); return(false); }
private async Task DisablePushAsync() { PushAccountModel push = CLIENT.dbAccount.push; if (string.IsNullOrEmpty(push.bareJid)) { Logger.Info("No need to disable push. Has never been activated on this device (push bare JID is null)."); return; } MessageResponseHelperResult <IQMessage> result = await CLIENT.xmppClient.GENERAL_COMMAND_HELPER.disablePushNotificationsAsync(push.bareJid); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { if (result.RESULT is IQErrorMessage errorMessage) { Logger.Error($"Failed to disable push notifications for '{CLIENT.dbAccount.bareJid}' - " + errorMessage.ERROR_OBJ.ToString()); } else if (result.RESULT.TYPE != IQMessage.RESULT) { Logger.Error($"Failed to disable push notifications for '{CLIENT.dbAccount.bareJid}' - server responded with: " + result.RESULT.TYPE); } else { push.state = PushState.DISABLED; push.Update(); Logger.Info($"Successfully disabled push notifications for: '{CLIENT.dbAccount.bareJid}'"); } } else { Logger.Error($"Failed to disable push notifications for '{CLIENT.dbAccount.bareJid}' - " + result.STATE); } }
public async Task EnablePushNotificationsAsync() { MessageResponseHelperResult <IQMessage> result = await GENERAL_COMMAND_HELPER.enablePushNotificationsAsync(account.pushServerBareJid, account.pushNode, account.pushNodeSecret); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { if (result.RESULT is IQErrorMessage errorMessage) { account.CONNECTION_INFO.pushState = PushState.ERROR; Logger.Error("Failed to enable push notifications for '" + account.getBareJid() + "' - " + errorMessage.ERROR_OBJ.ToString()); } else if (result.RESULT.TYPE != IQMessage.RESULT) { account.CONNECTION_INFO.pushState = PushState.ERROR; Logger.Error("Failed to enable push notifications for '" + account.getBareJid() + "' - server responded with: " + result.RESULT.TYPE); } else { account.pushNodePublished = true; account.CONNECTION_INFO.pushState = PushState.ENABLED; Logger.Info("Successfully enabled push notifications for: '" + account.getBareJid() + '\''); } } else { account.CONNECTION_INFO.pushState = PushState.ERROR; Logger.Error("Failed to enable push notifications for '" + account.getBareJid() + "' - " + result.STATE); } }
private async Task <List <ChatMessageDataTemplate> > LoadMoreMamMessagesAsync() { Logger.Info("Requesting MAM messages for \"" + MODEL.Chat.Chat.id + "\"."); QueryFilter filter = GenerateMamQueryFilter(); // For MUCs ask the MUC server and for everything else ask our own server for messages: string target = MODEL.Chat.Chat.chatType == ChatType.CHAT ? MODEL.Chat.Client.getXMPPAccount().getBareJid() : MODEL.Chat.Chat.chatJabberId; MessageResponseHelperResult <MamResult> result = await MODEL.Chat.Client.GENERAL_COMMAND_HELPER.requestMamAsync(filter, target); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { Logger.Info("Found " + result.RESULT.COUNT + " MAM messages for \"" + MODEL.Chat.Chat.id + "\"."); Logger.Debug("MAM result: " + result.RESULT.ToString()); mamRequested = result.RESULT.COMPLETE; List <ChatMessageDataTemplate> msgs = new List <ChatMessageDataTemplate>(); foreach (QueryArchiveResultMessage msg in result.RESULT.RESULTS) { ChatMessageDataTemplate tmp = new ChatMessageDataTemplate { Message = new ChatMessageTable(msg.MESSAGE, MODEL.Chat.Chat), Chat = MODEL.Chat.Chat, MUC = MODEL.Chat.MucInfo }; msgs.Add(tmp); await ChatDBManager.INSTANCE.setChatMessageAsync(tmp.Message, false, false); } return(msgs); } else { Logger.Error("Failed to load more MAM messages for \"" + MODEL.Chat.Chat.id + "\". Failed with: " + result.STATE); return(new List <ChatMessageDataTemplate>()); } }
private async Task <bool> UpdateNicknameAsync(ChatDataTemplate chat) { MessageResponseHelperResult <MUCMemberPresenceMessage> result = await chat.Client.MUC_COMMAND_HELPER.changeNicknameAsync(chat.Chat.chatJabberId, chat.MucInfo.nickname); if (!string.IsNullOrEmpty(result.RESULT.ERROR_TYPE)) { Logger.Warn("Failed to change nickname for room \"" + chat.Chat.chatJabberId + "\" to \"" + chat.MucInfo.nickname + "\" with: " + result.RESULT.ERROR_MESSAGE); return(false); } // Nickname has been updated successfully: else if (result.RESULT.STATUS_CODES.Contains(MUCPresenceStatusCode.MEMBER_NICK_CHANGED)) { return(true); } // The room has change the nickname: else if (result.RESULT.STATUS_CODES.Contains(MUCPresenceStatusCode.ROOM_NICK_CHANGED)) { if (!Utils.isFullJid(result.RESULT.JID)) { Logger.Error("Expected a full JID as a MUC nickname changed message with status code 210, but received: " + result.RESULT.JID); return(false); } chat.MucInfo.nickname = Utils.getJidResourcePart(result.RESULT.JID); return(true); } // Should not happen: Logger.Error("Unknown MUC member presence status code combination received. This should not happen!"); return(false); }
private async Task EnablePushAsync() { PushAccountModel push = CLIENT.dbAccount.push; if (string.IsNullOrEmpty(push.bareJid) || string.IsNullOrEmpty(push.node)) { Logger.Info($"Skipping push initialization for '{CLIENT.dbAccount.bareJid}' - server JID or node is empty."); return; } MessageResponseHelperResult <IQMessage> result = await CLIENT.xmppClient.GENERAL_COMMAND_HELPER.enablePushNotificationsAsync(push.bareJid, push.node, push.secret); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { if (result.RESULT is IQErrorMessage errorMessage) { Logger.Error($"Failed to enable push notifications for '{CLIENT.dbAccount.bareJid}' - " + errorMessage.ERROR_OBJ.ToString()); } else if (result.RESULT.TYPE != IQMessage.RESULT) { Logger.Error($"Failed to enable push notifications for '{CLIENT.dbAccount.bareJid}' - server responded with: " + result.RESULT.TYPE); } else { push.state = PushState.ENABLED; push.Update(); Logger.Info($"Successfully enabled push notifications for: '{CLIENT.dbAccount.bareJid}'"); } } else { Logger.Error($"Failed to enable push notifications for '{CLIENT.dbAccount.bareJid}' - " + result.STATE); } }
public async Task RefreshOmemoDevicesAsync(XMPPClient client) { MODEL.RefreshingDevices = true; MessageResponseHelperResult <IQMessage> result = await client.OMEMO_COMMAND_HELPER.requestDeviceListAsync(client.getXMPPAccount().getBareJid()); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { if (result.RESULT is OmemoDeviceListResultMessage deviceListResultMessage) { MODEL.DEVICES.Clear(); MODEL.DEVICES.AddRange(deviceListResultMessage.DEVICES.IDS.Select(x => new UintDataTemplate { Value = x })); } else { Logger.Warn("Failed to request device list (" + result.RESULT.ToString() + ")."); } } else { Logger.Warn("Failed to request device list (" + result.STATE.ToString() + ")."); } MODEL.RefreshingDevices = false; }
private async Task DiscoAsync(string discoTarget, CheckDiscoFeaturesAsync action) { MessageResponseHelperResult <IQMessage> result = await CONNECTION.GENERAL_COMMAND_HELPER.discoAsync(discoTarget, DiscoType.INFO); if (result.STATE != MessageResponseHelperResultState.SUCCESS) { Logger.Error("Failed to perform server DISCO for '" + CONNECTION.account.getBareJid() + "' - " + result.STATE); } else if (result.RESULT is IQErrorMessage errorMessage) { Logger.Error("Failed to perform server DISCO for '" + CONNECTION.account.getBareJid() + "' - " + errorMessage.ERROR_OBJ.ToString()); } // Success: else if (result.RESULT is DiscoResponseMessage disco) { await OnDiscoResponseMessage(disco, action, discoTarget); return; } else { Logger.Error("Failed to perform server DISCO for '" + CONNECTION.account.getBareJid() + "' - invalid response."); } CONNECTION.account.CONNECTION_INFO.msgCarbonsState = MessageCarbonsState.ERROR; CONNECTION.account.CONNECTION_INFO.pushState = PushState.ERROR; }
//--------------------------------------------------------Constructor:----------------------------------------------------------------\\ #region --Constructors-- #endregion //--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\ #region --Set-, Get- Methods-- #endregion //--------------------------------------------------------Misc Methods:---------------------------------------------------------------\\ #region --Misc Methods (Public)-- public async Task LoadAsync() { MODEL.IsLoading = true; // Unsubscribe while we are loading: MODEL.Chat.Client.NewPubSubEvent -= Client_NewPubSubEvent; // Request nodes: string targetBareJid = MODEL.Chat.Chat.chatJabberId; MessageResponseHelperResult <IQMessage> result = await MODEL.Chat.Client.PUB_SUB_COMMAND_HELPER.discoNodesAsync(targetBareJid); if (result.STATE == MessageResponseHelperResultState.SUCCESS && result.RESULT is DiscoResponseMessage discoResponse) { await SubscribeToIoTNodesAsync(discoResponse.ITEMS, MODEL.Chat.Client, targetBareJid); await RequestUiNodeAsync(MODEL.Chat.Client, targetBareJid); await RequestSensorsNodeAsync(MODEL.Chat.Client, targetBareJid); await RequestActuatorsNodeAsync(MODEL.Chat.Client, targetBareJid); } else { // Workaround since prosody does not allow us to query all nodes: await SubscribeToNodeAsync(IoTConsts.NODE_NAME_UI, MODEL.Chat.Client, targetBareJid); await SubscribeToNodeAsync(IoTConsts.NODE_NAME_SENSORS, MODEL.Chat.Client, targetBareJid); await SubscribeToNodeAsync(IoTConsts.NODE_NAME_ACTUATORS, MODEL.Chat.Client, targetBareJid); // Request Nodes: await RequestUiNodeAsync(MODEL.Chat.Client, targetBareJid); await RequestSensorsNodeAsync(MODEL.Chat.Client, targetBareJid); await RequestActuatorsNodeAsync(MODEL.Chat.Client, targetBareJid); Logger.Warn("Failed to request PubSub nodes from: " + targetBareJid); } // Subscribe again: MODEL.Chat.Client.NewPubSubEvent += Client_NewPubSubEvent; MODEL.IsLoading = false; }
public async Task EnableMessageCarbonsAsync() { account.CONNECTION_INFO.msgCarbonsState = MessageCarbonsState.REQUESTED; MessageResponseHelperResult <IQMessage> result = await GENERAL_COMMAND_HELPER.enableMessageCarbonsAsync(); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { if (result.RESULT is IQErrorMessage errorMessage) { account.CONNECTION_INFO.msgCarbonsState = MessageCarbonsState.ERROR; Logger.Error("Failed to enable push message carbons for '" + account.getBareJid() + "' - " + errorMessage.ERROR_OBJ.ToString()); } else if (result.RESULT.TYPE != IQMessage.RESULT) { account.CONNECTION_INFO.msgCarbonsState = MessageCarbonsState.ERROR; Logger.Error("Failed to enable push message carbons for '" + account.getBareJid() + "' - server responded with: " + result.RESULT.TYPE); } else { account.CONNECTION_INFO.msgCarbonsState = MessageCarbonsState.ENABLED; Logger.Info("Successfully enable push message carbons for: '" + account.getBareJid() + '\''); } } else { account.CONNECTION_INFO.msgCarbonsState = MessageCarbonsState.ERROR; Logger.Error("Failed to enable push message carbons for '" + account.getBareJid() + "' - " + result.STATE); } }
private async Task requestDeviceListAsync() { setState(OmemoHelperState.REQUESTING_DEVICE_LIST); Logger.Info("[OMEMO HELPER](" + CONNECTION.account.getBareJid() + ") Requesting device list."); MessageResponseHelperResult <IQMessage> result = await CONNECTION.OMEMO_COMMAND_HELPER.requestDeviceListAsync(CONNECTION.account.getBareJid()); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { if (result.RESULT is OmemoDeviceListResultMessage devMsg) { await updateDevicesIfNeededAsync(devMsg.DEVICES); } else if (result.RESULT is IQErrorMessage errMsg) { if (errMsg.ERROR_OBJ.ERROR_NAME == ErrorName.ITEM_NOT_FOUND) { Logger.Warn("[OMEMO HELPER](" + CONNECTION.account.getBareJid() + ") Failed to request OMEMO device list - node does not exist. Creating node."); await updateDevicesIfNeededAsync(null); } else { Logger.Error("[OMEMO HELPER](" + CONNECTION.account.getBareJid() + ") Failed to request OMEMO device list form: " + CONNECTION.account.user.domainPart + "\n" + errMsg.ERROR_OBJ.ToString()); setState(OmemoHelperState.ERROR); } } } else { onRequestError(result); } }
public void Save(ChatDataTemplate chat) { Task.Run(async() => { MODEL.IsLoading = true; MODEL.Form.Form.type = DataFormType.SUBMIT; MessageResponseHelperResult <IQMessage> result = await chat.Client.MUC_COMMAND_HELPER.saveRoomConfigurationAsync(chat.Chat.chatJabberId, MODEL.Form.Form); if (result.STATE != MessageResponseHelperResultState.SUCCESS) { SetError("Failed to save room configuration:\n**" + result.STATE + "**"); Logger.Warn("Failed to save the room configuration for '" + chat.Chat.chatJabberId + "': " + result.STATE); } else if (result.RESULT is IQErrorMessage errorMessage) { SetError("Failed to save room configuration:\n**" + errorMessage + "**"); Logger.Warn("Failed to save the room configuration for '" + chat.Chat.chatJabberId + "': " + errorMessage); } else { SetError(""); Logger.Info("Successfully saved the room configuration for '" + chat.Chat.chatJabberId + '\''); } MODEL.IsLoading = false; }); }
private async Task announceBundleInfoAsync() { setState(OmemoHelperState.ANNOUNCING_BUNDLE_INFO); Logger.Info("[OMEMO HELPER](" + CONNECTION.account.getBareJid() + ") Announcing bundle information for: " + CONNECTION.account.omemoDeviceId); MessageResponseHelperResult <IQMessage> result = await CONNECTION.OMEMO_COMMAND_HELPER.setBundleInfoAsync(CONNECTION.account.getOmemoBundleInformation(), CONNECTION.account.omemoDeviceId); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { if (result.RESULT is IQMessage) { Logger.Info("[OMEMO HELPER](" + CONNECTION.account.getBareJid() + ") Bundle info announced."); setState(OmemoHelperState.ENABLED); CONNECTION.account.omemoBundleInfoAnnounced = true; } else if (result.RESULT is IQErrorMessage errMsg) { Logger.Error("[OMEMO HELPER](" + CONNECTION.account.getBareJid() + ") Failed to announce OMEMO bundle info to: " + CONNECTION.account.user.domainPart + "\n" + errMsg.ERROR_OBJ.ToString()); setState(OmemoHelperState.ERROR); } } else { onRequestError(result); } }
private async Task RequestSensorsNodeAsync(XMPPClient client, string pubSubServer) { MessageResponseHelperResult <IQMessage> result = await client.PUB_SUB_COMMAND_HELPER.requestNodeAsync(pubSubServer, IoTConsts.NODE_NAME_SENSORS, 0); if (result.STATE == MessageResponseHelperResultState.SUCCESS && result.RESULT is SensorsNodeItemsResponseMessage sensorsResponse) { UpdateFields(sensorsResponse.VALUES); } }
private async Task RequestUiNodeAsync(XMPPClient client, string pubSubServer) { MessageResponseHelperResult <IQMessage> result = await client.PUB_SUB_COMMAND_HELPER.requestNodeAsync(pubSubServer, IoTConsts.NODE_NAME_UI, 0); if (result.STATE == MessageResponseHelperResultState.SUCCESS && result.RESULT is UiNodeItemsResponseMessage uiResponse) { UpdateForm(uiResponse.form); } }
private async Task <MessageResponseHelperResult <MamResult> > RequestMamWithRetry(QueryFilter filter, int numOfTries) { MessageResponseHelperResult <MamResult> result = await ccHandler.client.GENERAL_COMMAND_HELPER.requestMamAsync(filter); if (result.STATE == MessageResponseHelperResultState.SUCCESS || numOfTries <= 0 || state != SetupState.REQUESTING_MAM) { return(result); } return(await RequestMamWithRetry(filter, --numOfTries)); }
private async Task AddMucAsync(Client client, string roomBareJid, string nickname, string password, bool bookmark, bool autoJoin) { ChatModel chat = new ChatModel(roomBareJid, client.dbAccount) { chatType = ChatType.MUC, inRoster = bookmark, subscription = "none", isChatActive = true }; MucInfoModel muc = new MucInfoModel() { chat = chat, subject = null, autoEnterRoom = autoJoin, name = null, nickname = nickname, password = string.IsNullOrEmpty(password) ? null : password, state = MucState.DISCONNECTED }; chat.muc = muc; SemaLock semaLock = DataCache.INSTANCE.NewChatSemaLock(); semaLock.Wait(); DataCache.INSTANCE.AddChatUnsafe(chat, client); semaLock.Dispose(); if (muc.autoEnterRoom) { await MucHandler.INSTANCE.EnterMucAsync(client.xmppClient, muc); } if (bookmark) { List <ConferenceItem> conferenceItems; using (MainDbContext ctx = new MainDbContext()) { conferenceItems = ctx.GetXEP0048ConferenceItemsForAccount(client.dbAccount.bareJid); } MessageResponseHelperResult <IQMessage> result = await client.xmppClient.PUB_SUB_COMMAND_HELPER.setBookmars_xep_0048Async(conferenceItems); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { if (result.RESULT is IQErrorMessage errMsg) { Logger.Warn("Failed to set bookmarks: " + errMsg.ToString()); } } else { Logger.Warn("Failed to set bookmarks: " + result.STATE); } } }
private async Task <MessageResponseHelperResult <MamResult> > RequestMamWithRetry(QueryFilter filter, Set rsm, int numOfTries) { MessageResponseHelperResult <MamResult> result = await ccHandler.client.xmppClient.GENERAL_COMMAND_HELPER.requestMamAsync(filter, rsm); if (result.STATE == MessageResponseHelperResultState.SUCCESS || numOfTries <= 0 || state != SetupState.REQUESTING_MAM) { return(result); } Logger.Warn($"MAM request failed for '{ccHandler.client.dbAccount.bareJid}' failed with {result.STATE}. Retrying..."); return(await RequestMamWithRetry(filter, rsm, --numOfTries)); }
private void onRequestError(MessageResponseHelperResult <IQMessage> result) { switch (STATE) { case OmemoHelperState.REQUESTING_DEVICE_LIST: case OmemoHelperState.UPDATING_DEVICE_LIST: case OmemoHelperState.ANNOUNCING_BUNDLE_INFO: Logger.Error("[OMEMO HELPER](" + CONNECTION.account.getBareJid() + ") Failed in state " + STATE + " - timeout!"); setState(OmemoHelperState.ERROR); break; } }
private async Task AddMucAsync(XMPPClient client, string roomBareJid, string nickname, string password, bool bookmark, bool autoJoin) { ChatTable muc = new ChatTable(roomBareJid, client.getXMPPAccount().getBareJid()) { chatType = ChatType.MUC, inRoster = bookmark, subscription = "none", isChatActive = true }; MUCChatInfoTable info = new MUCChatInfoTable() { chatId = muc.id, subject = null, state = MUCState.DISCONNECTED, name = null, password = string.IsNullOrEmpty(password) ? null : password, nickname = nickname, autoEnterRoom = autoJoin, }; await Task.Run(() => { ChatDBManager.INSTANCE.setChat(muc, false, true); MUCDBManager.INSTANCE.setMUCChatInfo(info, false, true); }); if (info.autoEnterRoom) { await MUCHandler.INSTANCE.enterMUCAsync(client, muc, info); } if (bookmark) { List <ConferenceItem> conferenceItems = MUCDBManager.INSTANCE.getXEP0048ConferenceItemsForAccount(client.getXMPPAccount().getBareJid()); MessageResponseHelperResult <IQMessage> result = await client.PUB_SUB_COMMAND_HELPER.setBookmars_xep_0048Async(conferenceItems); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { if (result.RESULT is IQErrorMessage errMsg) { Logger.Warn("Failed to set bookmarks: " + errMsg.ToString()); } } else { Logger.Warn("Failed to set bookmarks: " + result.STATE); } } }
private async Task <bool> PublishAvatarAsync(AvatarDataPubSubItem avatar) { MessageResponseHelperResult <IQMessage> result = await MODEL.Client.xmppClient.PUB_SUB_COMMAND_HELPER.publishAvatarAsync(avatar); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { if (result.RESULT is IQErrorMessage errorMsg) { Logger.Error($"Failed to publish avatar: {errorMsg.ERROR_OBJ}"); return(false); } Logger.Info("Successfully published avatar."); return(true); } Logger.Error($"Failed to publish avatar: {result.STATE}"); return(false); }
private async Task updateDeviceListAsync(OmemoXmlDevices devices) { setState(OmemoHelperState.UPDATING_DEVICE_LIST); // Make sure we set the item ID to "current": devices.setId(); Logger.Info("[OMEMO HELPER](" + CONNECTION.account.getBareJid() + ") Updating device list."); MessageResponseHelperResult <IQMessage> result = await CONNECTION.OMEMO_COMMAND_HELPER.setDeviceListAsync(devices); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { if (result.RESULT is IQErrorMessage errMsg) { Logger.Error("[OMEMO HELPER](" + CONNECTION.account.getBareJid() + ") Failed to set OMEMO device list to: " + CONNECTION.account.user.domainPart + "\n" + errMsg.ERROR_OBJ.ToString()); setState(OmemoHelperState.ERROR); } else { Logger.Info("[OMEMO HELPER](" + CONNECTION.account.getBareJid() + ") Device list updated."); if (tmpDeviceId != 0) { if (CONNECTION.account.omemoDeviceId != tmpDeviceId) { CONNECTION.account.omemoDeviceId = tmpDeviceId; CONNECTION.account.omemoBundleInfoAnnounced = false; } } if (!CONNECTION.account.omemoBundleInfoAnnounced) { await announceBundleInfoAsync(); } else { setState(OmemoHelperState.ENABLED); } } } else { onRequestError(result); } }
private async Task <bool> UpdateBookmarksAsync(ChatDataTemplate chat) { List <ConferenceItem> conferences = MUCDBManager.INSTANCE.getXEP0048ConferenceItemsForAccount(chat.Client.getXMPPAccount().getBareJid()); MessageResponseHelperResult <IQMessage> result = await chat.Client.PUB_SUB_COMMAND_HELPER.setBookmars_xep_0048Async(conferences); if (string.Equals(result.RESULT.TYPE, IQMessage.RESULT)) { return(true); } if (result.RESULT is IQErrorMessage errorMessage) { Logger.Warn("Failed to update XEP-0048 Bookmarks: " + errorMessage.ERROR_OBJ.ToString()); } else { Logger.Warn("Failed to update XEP-0048 Bookmarks: " + result.RESULT.TYPE); } return(false); }
/// <summary> /// Sends a <seealso cref="QueryArchiveMessage"/> to the server and requests the MAM archive. /// </summary> /// <param name="filter">A filter for filtering the MAM results like filtering by JID.</param> /// <param name="rsm">Optional configuration for the result set.</param> /// <param name="to">The target of the request. null for request to your own server. Used for requesting MUC-MAMs.</param> /// <returns>The result of the request.</returns> public async Task <MessageResponseHelperResult <MamResult> > requestMamAsync(QueryFilter filter, Set rsm, string to) { QueryArchiveMessage msg = new QueryArchiveMessage(filter, rsm, CONNECTION.account.getFullJid(), to); List <QueryArchiveResultMessage> results = new List <QueryArchiveResultMessage>(); Predicate <AbstractAddressableMessage> predicate = (x) => { if (x is QueryArchiveResultMessage result && string.Equals(result.QUERY_ID, msg.QUERY_ID)) { results.Insert(0, result); return(false); } if (x is IQErrorMessage && string.Equals(msg.ID, x.ID)) { return(true); } return(x is QueryArchiveFinishMessage fin && string.Equals(fin.ID, msg.ID)); }; AsyncMessageResponseHelper <AbstractAddressableMessage> helper = new AsyncMessageResponseHelper <AbstractAddressableMessage>(CONNECTION, predicate) { matchId = false }; MessageResponseHelperResult <AbstractAddressableMessage> finResult = await helper.startAsync(msg); MamResult mamResult = null; if (finResult.STATE == MessageResponseHelperResultState.SUCCESS) { if (finResult.RESULT is QueryArchiveFinishMessage archiveFinishMessage) { mamResult = new MamResult(finResult.RESULT as QueryArchiveFinishMessage, results); } else { if (finResult.RESULT is IQErrorMessage errorMessage) { Logger.Warn($"Failed to request MAM from {to} with: {errorMessage.ERROR_OBJ}"); } return(new MessageResponseHelperResult <MamResult>(MessageResponseHelperResultState.ERROR, null)); } } return(new MessageResponseHelperResult <MamResult>(finResult.STATE, mamResult)); }
public async Task refreshDevicesAsync() { MessageResponseHelperResult <IQMessage> result = await CONNECTION.OMEMO_COMMAND_HELPER.requestDeviceListAsync(CONNECTION.account.getBareJid()); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { if (result.RESULT is OmemoDeviceListResultMessage devMsg) { DEVICES = devMsg.DEVICES; // Store the new list in the DB: OMEMO_STORAGE.StoreDevices(DEVICES.toOmemoProtocolAddress(CONNECTION.account.getBareJid()), CONNECTION.account.getBareJid()); } else if (result.RESULT is IQErrorMessage errMsg) { Logger.Error("[OMEMO HELPER](" + CONNECTION.account.getBareJid() + ") Failed to request OMEMO device list form: " + CONNECTION.account.user.domainPart + "\n" + errMsg.ERROR_OBJ.ToString()); } } else { Logger.Error("[OMEMO HELPER](" + CONNECTION.account.getBareJid() + ") Failed to request OMEMO device list form: " + CONNECTION.account.user.domainPart + " with: " + result.STATE); } }
private async Task <bool> SubscribeToNodeAsync(string nodeName, XMPPClient client, string pubSubServer) { MessageResponseHelperResult <IQMessage> result = await client.PUB_SUB_COMMAND_HELPER.requestNodeSubscriptionAsync(pubSubServer, nodeName); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { if (result.RESULT is PubSubSubscriptionsResultMessage pubSubResult) { Logger.Debug("Subscribed to node: " + nodeName); return(true); } else if (result.RESULT is IQErrorMessage errorMessage) { Logger.Warn("Subscribing to node failed with: " + errorMessage.ERROR_OBJ.ToString()); } } else { Logger.Warn("Subscribing to node failed with: " + result.RESULT); } return(false); }
private void RequestConfiguartion(ChatDataTemplate chat) { Task.Run(async() => { MODEL.IsLoading = true; MessageResponseHelperResult <IQMessage> result = await chat.Client.MUC_COMMAND_HELPER.requestRoomConfigurationAsync(chat.Chat.chatJabberId); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { if (result.RESULT is RoomConfigMessage configMessage) { MODEL.Form = new DataFormDataTemplate(configMessage.ROOM_CONFIG); MODEL.IsLoading = false; MODEL.Success = true; SetError(""); return; } else if (result.RESULT is IQErrorMessage errorMessage) { SetError("Failed to request room configuration:\n**" + errorMessage + "**"); Logger.Warn("Failed to request the room configuration for '" + chat.Chat.chatJabberId + "': " + errorMessage); } else { SetError("Failed to request room configuration:\n**Unexpected response - " + result.RESULT?.GetType().ToString() + "**"); Logger.Warn("Failed to request the room configuration for '" + chat.Chat.chatJabberId + "': Unexpected response - " + result.RESULT?.GetType().ToString()); } } else { SetError("Failed to request room configuration:\n**" + result.STATE + "**"); Logger.Warn("Failed to request the room configuration for '" + chat.Chat.chatJabberId + "': " + result.STATE); } MODEL.IsLoading = false; MODEL.Success = false; }); }
public void SaveDeviceLabel(string deviceLabel, Client client) { OmemoAccountInformationModel omemoInfo = client.dbAccount.omemoInfo; deviceLabel = deviceLabel.Trim(); string newLabel; if (string.IsNullOrEmpty(deviceLabel) || string.Equals(deviceLabel, omemoInfo.deviceId.ToString())) { newLabel = null; } else { newLabel = deviceLabel; } // Prevent unnecessary updates in case for example the control loaded: if (string.Equals(newLabel, omemoInfo.deviceLabel)) { return; } MODEL.Saving = true; Task.Run(async() => { try { if (client.xmppClient.isConnected()) { MessageResponseHelperResult <IQMessage> result = await client.xmppClient.OMEMO_COMMAND_HELPER.requestDeviceListAsync(client.dbAccount.bareJid); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { if (result.RESULT is OmemoDeviceListResultMessage deviceListResultMessage) { OmemoXmlDevice device = deviceListResultMessage.DEVICES.DEVICES.Where(d => d.ID == omemoInfo.deviceId).FirstOrDefault(); if (device is null) { device = new OmemoXmlDevice(omemoInfo.deviceId, deviceLabel); deviceListResultMessage.DEVICES.DEVICES.Add(device); } else if (string.Equals(device.label, deviceLabel)) { MODEL.ErrorSaving = false; MODEL.Saving = false; Logger.Info("No need to update devices. Label already the same."); return; } else { device.label = newLabel; result = await client.xmppClient.OMEMO_COMMAND_HELPER.setDeviceListAsync(deviceListResultMessage.DEVICES); if (result.STATE != MessageResponseHelperResultState.SUCCESS) { Logger.Error("Failed to set device list (" + result.STATE + ")."); } else if (result.RESULT is IQErrorMessage errorMessage) { Logger.Error("Failed to set device list (" + errorMessage.ERROR_OBJ.ToString() + ")."); } else { MODEL.ErrorSaving = false; omemoInfo.deviceLabel = newLabel; omemoInfo.Update(); MODEL.Saving = false; Logger.Info($"Device label for device {omemoInfo.deviceId} successfully updated to: '{newLabel}'."); return; } } } else { Logger.Error("Failed to request device list (" + result.RESULT.ToString() + ")."); } } else { Logger.Error("Failed to request device list (" + result.STATE.ToString() + ")."); } } else { Logger.Error("Failed to update device label. Client not connected"); } } catch (Exception e) { Logger.Error("Failed to update device label.", e); } MODEL.Saving = false; MODEL.ErrorSaving = true; }); }
private async Task RequestMamAsync() { state = SetupState.REQUESTING_MAM; if (!ccHandler.client.connection.DISCO_HELPER.HasFeature(Consts.XML_XEP_0313_NAMESPACE, ccHandler.client.getXMPPAccount().getBareJid())) { Logger.Info("No need to request MAM for " + ccHandler.client.getXMPPAccount().getBareJid() + " - not supported."); Continue(); return; } bool extendedMamSupport = ccHandler.client.connection.DISCO_HELPER.HasFeature(Consts.XML_XEP_0313_EXTENDED_NAMESPACE, ccHandler.client.getXMPPAccount().getBareJid()); Logger.Info("Extended MAM support for " + ccHandler.client.getXMPPAccount().getBareJid() + ": " + extendedMamSupport); MamRequestTable mamRequest = MamDBManager.INSTANCE.getLastRequest(ccHandler.client.getXMPPAccount().getBareJid()); string lastMsgId = null; DateTime lastMsgDate = DateTime.MinValue; if (!(mamRequest is null)) { lastMsgId = mamRequest.lastMsgId; lastMsgDate = mamRequest.lastUpdate; } // Request all MAM messages: bool done = false; int iteration = 1; while (!done) { QueryFilter filter = new QueryFilter(); if (extendedMamSupport) { // Only extended MAM supports setting the 'after-id' property. // Reference: https://xmpp.org/extensions/xep-0313.html#support if (!(lastMsgId is null)) { filter.AfterId(lastMsgId); } } else { // Fallback for servers not supporting 'urn:xmpp:mam:2#extended'. if (lastMsgDate != DateTime.MinValue) { filter.Start(lastMsgDate); } } MessageResponseHelperResult <MamResult> result = await RequestMamWithRetry(filter, 2); if (result.STATE == MessageResponseHelperResultState.SUCCESS) { mamRequest = new MamRequestTable { accountId = ccHandler.client.getXMPPAccount().getBareJid(), lastUpdate = DateTime.Now }; if (result.RESULT.RESULTS.Count > 0) { mamRequest.lastMsgId = result.RESULT.LAST; lastMsgId = result.RESULT.LAST; HandleMamMessages(result.RESULT); Logger.Info("MAM request for " + ccHandler.client.getXMPPAccount().getBareJid() + " received " + result.RESULT.RESULTS.Count + " messages in iteration " + iteration + '.'); Logger.Debug("First: " + result.RESULT.RESULTS[result.RESULT.RESULTS.Count - 1].QUERY_ID + " Last: " + result.RESULT.RESULTS[0].QUERY_ID); } if (result.RESULT.COMPLETE || result.RESULT.RESULTS.Count <= 0) { done = true; Logger.Info("MAM request for " + ccHandler.client.getXMPPAccount().getBareJid()); } DateTime newDate = GetLastMessageDate(result.RESULT); if (newDate == mamRequest.lastUpdate) { done = true; Logger.Info("MAM request for " + ccHandler.client.getXMPPAccount().getBareJid()); } else { lastMsgDate = newDate; } MamDBManager.INSTANCE.setLastRequest(mamRequest); } else if (state == SetupState.REQUESTING_MAM) { done = true; Logger.Warn("Failed to request MAM archive for " + ccHandler.client.getXMPPAccount().getBareJid() + " with: " + result.STATE); } ++iteration; } Continue(); }