00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "r_message.h"
00023 #include "record-internal.h"
00024 #include "protocol.h"
00025 #include "protostructs.h"
00026 #include "data.h"
00027 #include "time.h"
00028 #include "error.h"
00029 #include "endian.h"
00030 #include <ostream>
00031 #include <iomanip>
00032 #include <time.h>
00033 #include <stdexcept>
00034
00035 #define __DEBUG_MODE__
00036 #include "debug.h"
00037
00038 using namespace std;
00039 using namespace Barry::Protocol;
00040
00041 namespace Barry {
00042
00043
00044
00045
00046
00047
00048 #define MFC_TO 0x01 // can occur multiple times
00049 #define MFC_CC 0x02 // ditto
00050 #define MFC_BCC 0x03 // ditto
00051 #define MFC_SENDER 0x04
00052 #define MFC_FROM 0x05
00053 #define MFC_REPLY_TO 0x06
00054 #define MFC_SUBJECT 0x0b
00055 #define MFC_BODY 0x0c
00056 #define MFC_REPLY_UNKNOWN 0x12 // This shows up as 0x00 on replies but we don't do much with it now
00057 #define MFC_ATTACHMENT 0x16
00058 #define MFC_RECORDID 0x4b
00059 #define MFC_END 0xffff
00060
00061 #define PRIORITY_MASK 0x003f
00062 #define PRIORITY_HIGH 0x0008
00063 #define PRIORITY_LOW 0x0002
00064
00065 #define SENSITIVE_MASK 0xff80
00066 #define SENSITIVE_CONFIDENTIAL 0x0100
00067 #define SENSITIVE_PERSONAL 0x0080
00068 #define SENSITIVE_PRIVATE 0x0040 // actual pattern is 0x00C0
00069
00070 #define MESSAGE_READ 0x0800
00071 #define MESSAGE_REPLY 0x0001
00072 #define MESSAGE_SAVED 0x0002
00073 #define MESSAGE_FORWARD 0x0008
00074 #define MESSAGE_TRUNCATED 0x0020
00075 #define MESSAGE_SAVED_DELETED 0x0080
00076
00077 FieldLink<Message> MessageFieldLinks[] = {
00078 { MFC_TO, "To", 0, 0, 0, &Message::To, 0 },
00079 { MFC_CC, "Cc", 0, 0, 0, &Message::Cc, 0 },
00080 { MFC_BCC, "Bcc", 0, 0, 0, &Message::Bcc, 0 },
00081 { MFC_SENDER, "Sender", 0, 0, 0, &Message::Sender, 0 },
00082 { MFC_FROM, "From", 0, 0, 0, &Message::From, 0 },
00083 { MFC_REPLY_TO, "ReplyTo", 0, 0, 0, &Message::ReplyTo, 0 },
00084 { MFC_SUBJECT, "Subject", 0, 0, &Message::Subject, 0, 0 },
00085 { MFC_BODY, "Body", 0, 0, &Message::Body, 0, 0 },
00086 { MFC_ATTACHMENT, "Attachment", 0, 0, &Message::Attachment, 0, 0 },
00087 { MFC_END, "End of List", 0, 0, 0, 0, 0 }
00088 };
00089
00090 Message::Message()
00091 {
00092 Clear();
00093 }
00094
00095 Message::~Message()
00096 {
00097 }
00098
00099 const unsigned char* Message::ParseField(const unsigned char *begin,
00100 const unsigned char *end)
00101 {
00102 const CommonField *field = (const CommonField *) begin;
00103
00104
00105 begin += COMMON_FIELD_HEADER_SIZE + btohs(field->size);
00106 if( begin > end )
00107 return begin;
00108
00109 if( !btohs(field->size) )
00110 return begin;
00111
00112
00113 for( FieldLink<Message> *b = MessageFieldLinks;
00114 b->type != MFC_END;
00115 b++ )
00116 {
00117 if( b->type == field->type ) {
00118 if( b->strMember ) {
00119
00120 std::string &s = this->*(b->strMember);
00121 s = ParseFieldString(field);
00122 return begin;
00123 }
00124 else if( b->addrMember ) {
00125
00126
00127 const char *fa = (const char*)field->u.addr.addr;
00128 std::string dual(fa, btohs(field->size) - sizeof(field->u.addr.unknown));
00129
00130
00131 EmailAddress &a = this->*(b->addrMember);
00132 a.Name = dual.c_str();
00133
00134
00135 a.Email = dual.c_str() + a.Name.size() + 1;
00136 return begin;
00137 }
00138 }
00139 }
00140
00141 char swallow;
00142 switch( field->type )
00143 {
00144 case MFC_RECORDID:
00145 MessageRecordId = btohl(field->u.uint32);
00146 return begin;
00147 case MFC_REPLY_UNKNOWN:
00148 swallow = field->u.raw[0];
00149 return begin;
00150 }
00151
00152 UnknownField uf;
00153 uf.type = field->type;
00154 uf.data.assign((const char*)field->u.raw, btohs(field->size));
00155 Unknowns.push_back(uf);
00156
00157 return begin;
00158 }
00159
00160 uint8_t Message::GetRecType() const
00161 {
00162 throw std::logic_error("Message::GetRecType() called, and not supported by the USB protocol. Should never get called.");
00163 }
00164
00165
00166 uint32_t Message::GetUniqueId() const
00167 {
00168 throw std::logic_error("Message::GetUniqueId() called, and not supported by the USB protocol. Should never get called.");
00169 }
00170
00171 void Message::ParseHeader(const Data &data, size_t &offset)
00172 {
00173 Protocol::CheckSize(data, offset + MESSAGE_RECORD_HEADER_SIZE);
00174
00175 MAKE_RECORD(const Barry::Protocol::MessageRecord, mr, data, offset);
00176
00177
00178 MessagePriority = NormalPriority;
00179
00180 uint16_t priority = btohs(mr->priority);
00181 if( priority & PRIORITY_MASK ) {
00182 if( priority & PRIORITY_HIGH ) {
00183 MessagePriority = HighPriority;
00184 }
00185 else if( priority & PRIORITY_LOW ) {
00186 MessagePriority = LowPriority;
00187 }
00188 else
00189 MessagePriority = UnknownPriority;
00190 }
00191
00192 MessageSensitivity = NormalSensitivity;
00193 if( priority & SENSITIVE_MASK ) {
00194 if(( priority & SENSITIVE_CONFIDENTIAL ) == SENSITIVE_CONFIDENTIAL ) {
00195 MessageSensitivity = Confidential;
00196 }
00197 else if(( priority & SENSITIVE_PRIVATE ) == SENSITIVE_PRIVATE ) {
00198 MessageSensitivity = Private;
00199 }
00200 else if(( priority & SENSITIVE_PERSONAL ) == SENSITIVE_PERSONAL ) {
00201 MessageSensitivity = Personal;
00202 }
00203 else
00204 MessageSensitivity = UnknownSensitivity;
00205 }
00206
00207 if( mr->inReplyTo )
00208 MessageReplyTo = btohl(mr->inReplyTo);
00209
00210
00211 uint32_t flags = btohl(mr->flags);
00212 if( !( flags & MESSAGE_READ ))
00213 MessageRead = true;
00214
00215 if(( flags & MESSAGE_REPLY ) == MESSAGE_REPLY )
00216 MessageReply = true;
00217
00218 if( !( flags & MESSAGE_TRUNCATED ))
00219 MessageTruncated = true;
00220
00221
00222 if( !( flags & MESSAGE_SAVED ))
00223 MessageSaved = true;
00224 if( !( flags & MESSAGE_SAVED_DELETED ))
00225 MessageSavedDeleted = true;
00226
00227 MessageDateSent = Message2Time(mr->dateSent, mr->timeSent);
00228 MessageDateReceived = Message2Time(mr->dateReceived, mr->timeReceived);
00229
00230 offset += MESSAGE_RECORD_HEADER_SIZE;
00231 }
00232
00233 void Message::ParseFields(const Data &data, size_t &offset)
00234 {
00235 const unsigned char *finish = ParseCommonFields(*this,
00236 data.GetData() + offset, data.GetData() + data.GetSize());
00237 offset += finish - (data.GetData() + offset);
00238 }
00239
00240 void Message::BuildHeader(Data &data, size_t &offset) const
00241 {
00242 throw std::logic_error("Message::BuildHeader not yet implemented");
00243 }
00244
00245 void Message::BuildFields(Data &data, size_t &offset) const
00246 {
00247 throw std::logic_error("Message::BuildFields not yet implemented");
00248 }
00249
00250 void Message::Clear()
00251 {
00252 From.clear();
00253 To.clear();
00254 Cc.clear();
00255 Bcc.clear();
00256 Sender.clear();
00257 ReplyTo.clear();
00258 Subject.clear();
00259 Body.clear();
00260 Attachment.clear();
00261
00262 MessageRecordId = 0;
00263 MessageReplyTo = 0;
00264 MessageDateSent = 0;
00265 MessageDateReceived = 0;
00266 MessageTruncated = false;
00267 MessageRead = false;
00268 MessageReply = false;
00269 MessageSaved = false;
00270 MessageSavedDeleted = false;
00271
00272 Unknowns.clear();
00273 }
00274
00275 std::string Message::SimpleEmailAddress() const
00276 {
00277 if( From.Email.size() ) {
00278
00279 std::string ret;
00280 for( size_t i = 0; i < From.Email.size(); i++ )
00281 if( From.Email[i] != ' ' )
00282 ret += From.Email[i];
00283
00284 return ret;
00285 }
00286 else {
00287 return "unknown";
00288 }
00289 }
00290
00291
00292 void Message::Dump(std::ostream &os) const
00293 {
00294 static const char *MessageImportance[] =
00295 { "Low", "Normal", "High", "Unknown Priority" };
00296 static const char *MessageSensitivityString[] =
00297 { "Normal", "Personal", "Private", "Confidential", "Unknown Sensivity" };
00298
00299 os << "From " << SimpleEmailAddress() << " " << ctime( &MessageDateReceived );
00300 os << "X-Record-ID: (" << setw(8) << std::hex << MessageRecordId << ")\n";
00301 if( MessageReplyTo )
00302 os << "X-rim-org-msg-ref-id: " << std::dec << MessageReplyTo << "\n";
00303 if( MessageSaved )
00304 os << "X-Message-Status: Saved\n";
00305 else if( MessageRead )
00306 os << "Message Status: Opened\n";
00307 if( MessagePriority != NormalPriority )
00308 os << "Importance: " << MessageImportance[MessagePriority] << "\n";
00309 if( MessageSensitivity != NormalSensitivity )
00310 os << "Sensitivity: " << MessageSensitivityString[MessageSensitivity] << "\n";
00311 os << "Date: " << ctime(&MessageDateSent);
00312 os << "From: " << From << "\n";
00313 if( To.Email.size() )
00314 os << "To: " << To << "\n";
00315 if( Cc.Email.size() )
00316 os << "Cc: " << Cc << "\n";
00317 if( Bcc.Email.size() )
00318 os << "Bcc: " << Bcc << "\n";
00319 if( Sender.Email.size() )
00320 os << "Sender: " << Sender << "\n";
00321 if( ReplyTo.Email.size())
00322 os << "Reply To: " << ReplyTo << "\n";
00323 if( Subject.size() )
00324 os << "Subject: " << Subject << "\n";
00325 os << "\n";
00326 for( std::string::const_iterator i = Body.begin();
00327 i != Body.end() && *i;
00328 i++)
00329 {
00330 if( *i == '\r' )
00331 os << '\n';
00332 else
00333 os << *i;
00334 }
00335 os << "\n";
00336 if( Attachment.size() )
00337 os << "Attachments: " << Attachment << "\n";
00338
00339 os << Unknowns;
00340 os << "\n\n";
00341 }
00342
00343
00344 }
00345