/// <summary> /// Gets the concatenation information of a message. /// </summary> /// <param name="pdu">The message to get the information of.</param> /// <returns>An object implementing <see cref="T:GSMCommunication.PDUDecoder.SmartMessaging.IConcatenationInfo" />, if /// the message is a part of a concatenated message, null otherwise.</returns> /// <remarks> /// <para>The returned information can be used to discover the parts of a concatenated message /// or recombine the parts back into one message.</para> /// </remarks> public static IConcatenationInfo GetConcatenationInfo(SmsPdu pdu) { if (pdu != null) { IConcatenationInfo concatenationInfo = null; if (pdu.UserDataHeaderPresent) { byte[] userDataHeader = pdu.GetUserDataHeader(); InformationElement[] informationElementArray = SmartMessageDecoder.DecodeUserDataHeader(userDataHeader); InformationElement[] informationElementArray1 = informationElementArray; int num = 0; while (num < (int)informationElementArray1.Length) { InformationElement informationElement = informationElementArray1[num]; if (informationElement as IConcatenationInfo == null) { num++; } else { concatenationInfo = (IConcatenationInfo)informationElement; break; } } } return(concatenationInfo); } else { throw new ArgumentNullException("pdu"); } }
private static bool HaveSameReferenceNumber(SmsPdu pdu1, SmsPdu pdu2) { bool flag = false; if (SmartMessageDecoder.IsPartOfConcatMessage(pdu1) && SmartMessageDecoder.IsPartOfConcatMessage(pdu2)) { IConcatenationInfo concatenationInfo = SmartMessageDecoder.GetConcatenationInfo(pdu1); IConcatenationInfo concatenationInfo1 = SmartMessageDecoder.GetConcatenationInfo(pdu2); if (concatenationInfo.ReferenceNumber == concatenationInfo1.ReferenceNumber) { flag = true; } } return(flag); }
private static SortedList <IConcatenationInfo, SmsPdu> SortConcatMessageParts(IList <SmsPdu> parts) { IConcatenationInfo concatenationInfo; IConcatenationInfo concatenationInfo1 = null; SortedList <IConcatenationInfo, SmsPdu> concatenationInfos = new SortedList <IConcatenationInfo, SmsPdu>(new ConcatInfoComparer()); foreach (SmsPdu part in parts) { if (concatenationInfo1 != null) { if (!SmartMessageDecoder.IsPartOfConcatMessage(part)) { throw new ArgumentException("A non-concatenated message part is present at an invalid position.", "parts"); } else { concatenationInfo = SmartMessageDecoder.GetConcatenationInfo(part); if (concatenationInfo1.ReferenceNumber == concatenationInfo.ReferenceNumber) { if (concatenationInfo1.TotalMessages != concatenationInfo.TotalMessages) { throw new ArgumentException("The number of total messages differs between the message parts.", "parts"); } } else { throw new ArgumentException("The reference numbers differ between the message parts.", "parts"); } } } else { concatenationInfo = SmartMessageDecoder.GetConcatenationInfo(part); } concatenationInfos.Add(concatenationInfo, part); concatenationInfo1 = concatenationInfo; } return(concatenationInfos); }
/// <summary> /// Retrieves the user data of all parts of a concatenated message. /// </summary> /// <param name="parts">The parts that make up the concatenated message.</param> /// <param name="outputAsText">If true, formats the returned user data as text. If false, returns the user data /// in its binary form.</param> /// <param name="allowMissingParts">Specifies whether missing parts are allowed. If true, null is returned /// in the resulting list in place of every missing part. If false, an exception is raised when a part is /// missing.</param> /// <param name="noOutput">If set to true, does not fill the returned list with data. If set to false, the data is returned /// normally. Use this in conjunction with allowMissingParts set to true to verify whether all message parts are present.</param> /// <param name="allPartsAvailable">Is set to true if all message parts are available, false otherwise. Use this in conjunction /// with allowMissingParts set to true to verify whether all message parts are present.</param> /// <returns>A list of objects containing the user data of every part without any headers. /// The outputAsText parameter determines the actual data type that is returned. If outputAsText is true, the return type is a /// list of byte arrays, if false a list of strings is returned. /// </returns> /// <remarks> /// <para>The parts can be in any order.</para> /// <para>If the first part is a non-concatenated message, its user data is returned back, and no more parts are processed /// afterwards.</para> /// </remarks> /// <exception cref="T:System.ArgumentNullException">parts is null.</exception> /// <exception cref="T:System.ArgumentException"> /// <para>Not all parts of the message are available and allowMissingParts is false.</para> /// <para> -or- </para> /// <para>The reference numbers differ between the message parts.</para> /// <para> -or- </para> /// <para>The number of total messages differs between the message parts.</para> /// <para> -or- </para> /// <para>A non-concatenated message part is present at an invalid position.</para> /// </exception> private static List <object> GetConcatUserData(IList <SmsPdu> parts, bool outputAsText, bool allowMissingParts, bool noOutput, out bool allPartsAvailable) { if (parts != null) { allPartsAvailable = true; List <object> objs = new List <object>(); if (parts.Count > 0) { SmsPdu item = parts[0]; if (!SmartMessageDecoder.IsPartOfConcatMessage(item)) { if (!noOutput) { if (!outputAsText) { objs.Add(item.UserData); } else { objs.Add(item.UserDataText); } } } else { SortedList <IConcatenationInfo, SmsPdu> concatenationInfos = SmartMessageDecoder.SortConcatMessageParts(parts); int totalMessages = concatenationInfos.Keys[0].TotalMessages; int num = 0; for (int i = 1; i <= totalMessages; i++) { bool flag = false; if (num < concatenationInfos.Count) { IConcatenationInfo concatenationInfo = concatenationInfos.Keys[num]; SmsPdu smsPdu = concatenationInfos.Values[num]; if (i == concatenationInfo.CurrentNumber) { if (!noOutput) { if (!outputAsText) { objs.Add(smsPdu.GetUserDataWithoutHeader()); } else { objs.Add(smsPdu.GetUserDataTextWithoutHeader()); } } num++; } else { flag = true; } } else { flag = true; } if (flag) { allPartsAvailable = false; if (!allowMissingParts) { throw new ArgumentException(string.Concat("Not all parts of the message are available. Part #", i, " is missing."), "parts"); } else { if (!noOutput) { objs.Add(null); } } } } } } return(objs); } else { throw new ArgumentNullException("parts"); } }
void ReceiveMessages() { Log.Add(LogLevel.Verbose, "SMS", "Reading SMS messages from device..."); Stopwatch sw = new Stopwatch(); sw.Start(); DecodedShortMessage[] msgs = _gsm.ReadMessages(PhoneMessageStatus.All, "MT"); Log.Add(LogLevel.Verbose, "SMS", String.Format("{0} messages in storage", msgs.Length)); foreach (DecodedShortMessage msg in msgs) { string from = string.Empty; string text = string.Empty; DateTime received = DateTime.Now; bool _fullMessageReceived = false; SmsDeliverPdu pdu = (SmsDeliverPdu)msg.Data; if (SmartMessageDecoder.IsPartOfConcatMessage(pdu)) { IConcatenationInfo info = SmartMessageDecoder.GetConcatenationInfo(pdu); Log.Add(LogLevel.Debug, "SMS", string.Format("Received multi-part message {0}: {1}/{2}", info.ReferenceNumber, info.CurrentNumber, info.TotalMessages)); if (_concatPdus.ContainsKey(info.ReferenceNumber)) { _concatPdus[info.ReferenceNumber].Add(pdu); } else { _concatPdus.Add(info.ReferenceNumber, new List <SmsPdu>() { pdu }); } if (SmartMessageDecoder.AreAllConcatPartsPresent(_concatPdus[info.ReferenceNumber])) { _fullMessageReceived = true; from = pdu.OriginatingAddress; received = pdu.SCTimestamp.ToDateTime(); text = SmartMessageDecoder.CombineConcatMessageText(_concatPdus[info.ReferenceNumber]); } } else { Log.Add(LogLevel.Debug, "SMS", "Received single-part SMS."); _fullMessageReceived = true; from = String.Format("{0}", pdu.OriginatingAddress); received = pdu.SCTimestamp.ToDateTime(); text = pdu.UserDataText; } if (_fullMessageReceived) { Log.Add(LogLevel.Info, "SMS", String.Format("Incoming SMS from {0}", from)); if (NormalizeNumbers) { from = NormalizeNumber(from); } if (_resolveNumbers) { from = ResolveNameByNumber(from); } Log.Add(LogLevel.Debug, "SMS", String.Format("Message from {0} at {1}: {2}", from, received, text)); if (OnMessageReceived != null) { OnMessageReceived(this, new Message(from, received, text)); } } _gsm.DeleteMessage(msg.Index, msg.Storage); } sw.Stop(); Log.Add(LogLevel.Verbose, "SMS", String.Format("Reading took {0}ms", sw.Elapsed.TotalMilliseconds)); }