protostructs.h

Go to the documentation of this file.
00001 ///
00002 /// \file       protostructs.h
00003 ///             USB Blackberry bulk protocol API.  This is split out from
00004 ///             protocol.h so that low level, packed structs can be
00005 ///             compiled separately from the application.  This prevents
00006 ///             aliasing problems in the application, or using
00007 ///             -fno-strict-aliasing, which the library only needs.
00008 ///
00009 ///             Do not include this in any Barry library header.
00010 ///             This may only be included from .cc files, in order
00011 ///             to hide aliasing concernes from the application.
00012 ///
00013 
00014 /*
00015     Copyright (C) 2005-2012, Net Direct Inc. (http://www.netdirect.ca/)
00016 
00017     This program is free software; you can redistribute it and/or modify
00018     it under the terms of the GNU General Public License as published by
00019     the Free Software Foundation; either version 2 of the License, or
00020     (at your option) any later version.
00021 
00022     This program is distributed in the hope that it will be useful,
00023     but WITHOUT ANY WARRANTY; without even the implied warranty of
00024     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00025 
00026     See the GNU General Public License in the COPYING file at the
00027     root directory of this project for more details.
00028 */
00029 
00030 #ifndef __BARRY_PROTOSTRUCTS_H__
00031 #define __BARRY_PROTOSTRUCTS_H__
00032 
00033 #include <stdint.h>
00034 #include <sys/types.h>
00035 #include "platform.h"           // safe to include platform.h here, since
00036                                 // protostructs.h is not installed either
00037 
00038 #if USE_PACK_PRAGMA
00039 #pragma pack(push, 1)
00040 #endif
00041 
00042 // forward declarations
00043 namespace Barry { class Data; }
00044 
00045 namespace Barry { namespace Protocol {
00046 
00047 ///////////////////////////////////////////////////////////////////////////////
00048 union SizePacket
00049 {
00050         uint16_t size;
00051         char buffer[4];
00052 } ATTRIBUTE_PACKED;
00053 
00054 
00055 ///////////////////////////////////////////////////////////////////////////////
00056 // Record sub-field structs
00057 
00058 struct GroupLink                                // used for Contacts records
00059 {
00060         uint32_t        uniqueId;
00061         uint16_t        unknown;
00062 } ATTRIBUTE_PACKED;
00063 
00064 struct MessageAddress                           // used for Message records
00065 {
00066         uint8_t         unknown[8];
00067         uint8_t         addr[1];        // 2 null terminated strings: first
00068                                         // contains full name, second contains
00069                                         // the email address
00070 } ATTRIBUTE_PACKED;
00071 
00072 
00073 ///////////////////////////////////////////////////////////////////////////////
00074 // SMS Message field and record structures
00075 
00076 struct SMSMetaData
00077 {
00078         uint8_t         recv; // if received, this is set to 1; otherwise 0
00079         uint8_t         flags;
00080 #define SMS_FLG_NEW_CONVERSATION 0x20
00081 #define SMS_FLG_SAVED 0x10
00082 #define SMS_FLG_DELETED 0x08
00083 #define SMS_FLG_OPENED 0x01
00084 
00085         uint8_t         new_flag;
00086         uint16_t        zero; // constantly 0
00087         uint32_t        status;
00088 #define SMS_STA_RECEIVED 0x000007ff
00089 #define SMS_STA_DRAFT 0x7fffffff
00090 
00091         uint32_t        error_id;
00092         uint64_t        timestamp;
00093         uint64_t        service_center_timestamp;
00094         uint8_t         dcs;
00095 #define SMS_DCS_7BIT 0x00
00096 #define SMS_DCS_8BIT 0x01
00097 #define SMS_DCS_UCS2 0x02
00098 
00099 } ATTRIBUTE_PACKED;
00100 #define SMS_METADATA_SIZE       (sizeof(::Barry::Protocol::SMSMetaData))
00101 
00102 
00103 
00104 ///////////////////////////////////////////////////////////////////////////////
00105 // Record Field Formats
00106 
00107 struct CommonField
00108 {
00109         uint16_t        size;                   // including null terminator
00110         uint8_t         type;
00111 
00112         union CommonFieldData
00113         {
00114 
00115                 GroupLink       link;
00116                 MessageAddress  addr;
00117                 SMSMetaData     sms_metadata;
00118                 uint64_t        timestamp;
00119                 uint64_t        uint64;
00120                 uint32_t        uint32;
00121                 int32_t         min1900;
00122                 uint16_t        code;
00123                 uint8_t         raw[1];
00124                 int16_t         int16;
00125 
00126         } ATTRIBUTE_PACKED u;
00127 
00128 } ATTRIBUTE_PACKED;
00129 #define COMMON_FIELD_HEADER_SIZE        (sizeof(::Barry::Protocol::CommonField) - sizeof(::Barry::Protocol::CommonField::CommonFieldData))
00130 #define COMMON_FIELD_MIN1900_SIZE       (sizeof(int32_t))
00131 
00132 struct CommandTableField
00133 {
00134         uint8_t         size;           // no null terminator
00135         uint8_t         code;
00136         uint8_t         name[1];
00137 } ATTRIBUTE_PACKED;
00138 #define COMMAND_FIELD_HEADER_SIZE       (sizeof(::Barry::Protocol::CommandTableField) - 1)
00139 
00140 struct OldDBDBField
00141 {
00142         uint16_t        dbNumber;
00143         uint8_t         unknown1;
00144         uint32_t        dbSize;                 // assumed from Cassis docs...
00145                                                 // always 0 in USB
00146         uint16_t        dbRecordCount;
00147         uint16_t        unknown2;
00148         uint16_t        nameSize;               // includes null terminator
00149         uint8_t         name[1];
00150 } ATTRIBUTE_PACKED;
00151 #define OLD_DBDB_FIELD_HEADER_SIZE      (sizeof(::Barry::Protocol::OldDBDBField) - 1)
00152 
00153 struct DBDBField
00154 {
00155         uint16_t        dbNumber;
00156         uint8_t         unknown1;
00157         uint32_t        dbSize;                 // assumed from Cassis docs...
00158                                                 // always 0 in USB
00159         uint32_t        dbRecordCount;
00160         uint16_t        unknown2;
00161         uint16_t        nameSize;               // includes null terminator
00162         uint8_t         unknown3;
00163         uint8_t         name[1];                // followed by 2 zeros!
00164         uint16_t        unknown;                // this comes after the
00165                                                 // null terminated name, but
00166                                                 // is here for size calcs
00167 } ATTRIBUTE_PACKED;
00168 #define DBDB_FIELD_HEADER_SIZE  (sizeof(::Barry::Protocol::DBDBField) - 1)
00169 
00170 struct RecordStateTableField
00171 {
00172         uint8_t         rectype;                // it is unknown exactly what
00173                                                 // this field does, but it
00174                                                 // shows up here and in the
00175                                                 // tagged record header, and
00176                                                 // for some of the records
00177                                                 // they must match when writing
00178         uint16_t        index;
00179         uint32_t        uniqueId;               // matches the uniqueId of say,
00180                                                 // address book records
00181         uint8_t         flags;                  // bit 0x01 is the dirty flag
00182                                                 // don't know if any other bits
00183                                                 // are used
00184 #define BARRY_RSTF_DIRTY        0x01
00185         uint8_t         unknown2[4];
00186 } ATTRIBUTE_PACKED;
00187 
00188 struct CalendarRecurrenceDataField  // as documented in the Cassis project spec
00189 {
00190         uint8_t         type;
00191 #define CRDF_TYPE_DAY           0x01
00192 #define CRDF_TYPE_MONTH_BY_DATE 0x03
00193 #define CRDF_TYPE_MONTH_BY_DAY  0x04
00194 #define CRDF_TYPE_YEAR_BY_DATE  0x05
00195 #define CRDF_TYPE_YEAR_BY_DAY   0x06
00196 #define CRDF_TYPE_WEEK          0x0c
00197 
00198         uint8_t         unknown;                // always 0x01
00199         uint16_t        interval;
00200         uint32_t        startTime;
00201         uint32_t        endTime;                // 0xFFFFFFFF for never
00202 
00203         union Additional
00204         {
00205                 // Note: blank fields should be set to 0
00206 
00207                 struct Day
00208                 {
00209                         uint8_t day[6];         // always zeros!
00210                 } ATTRIBUTE_PACKED day;
00211 
00212                 struct MonthByDate
00213                 {
00214                         uint8_t monthDay;       // day of month to recur on
00215                                                 // (1-31)
00216                         uint8_t blank[5];
00217                 } ATTRIBUTE_PACKED month_by_date;
00218 
00219                 struct MonthByDay
00220                 {
00221                         uint8_t weekDay;        // day of week to recur on (0-6)
00222                         uint8_t week;           // week of month to recur on
00223                                                 // (1 to 5, first week, second
00224                                                 // week, etc)
00225                         uint8_t blank[4];
00226                 } ATTRIBUTE_PACKED month_by_day;
00227 
00228                 struct YearByDate
00229                 {
00230                         uint8_t monthDay;       // day of month to recur on
00231                                                 // (1-31)
00232                         uint8_t blank;
00233                         uint8_t month;          // month to recur on (1-12)
00234                         uint8_t blank_[3];
00235                 } ATTRIBUTE_PACKED year_by_date;
00236 
00237                 struct YearByDay
00238                 {
00239                         uint8_t weekDay;        // day of week to recur on (0-6)
00240                         uint8_t week;           // week of month (1 to 5)
00241                         uint8_t month;          // (1-12)
00242                         uint8_t blank[3];
00243                 } ATTRIBUTE_PACKED year_by_day;
00244 
00245                 struct Week
00246                 {
00247                         uint8_t days;           // bitmask
00248                         #define CRDF_WD_SUN     0x01
00249                         #define CRDF_WD_MON     0x02
00250                         #define CRDF_WD_TUE     0x04
00251                         #define CRDF_WD_WED     0x08
00252                         #define CRDF_WD_THU     0x10
00253                         #define CRDF_WD_FRI     0x20
00254                         #define CRDF_WD_SAT     0x40
00255 
00256                         uint8_t blank[5];
00257                 } ATTRIBUTE_PACKED week;
00258 
00259         } ATTRIBUTE_PACKED u;
00260 
00261 } ATTRIBUTE_PACKED;
00262 #define CALENDAR_RECURRENCE_DATA_FIELD_SIZE     sizeof(::Barry::Protocol::CalendarRecurrenceDataField)
00263 
00264 //
00265 // Calendar record: field constants
00266 //
00267 
00268 #define CR_FREEBUSY_FREE                0
00269 #define CR_FREEBUSY_TENTATIVE           1
00270 #define CR_FREEBUSY_BUSY                2
00271 #define CR_FREEBUSY_OUT_OF_OFFICE       3
00272 #define CR_FREEBUSY_RANGE_LOW           0
00273 #define CR_FREEBUSY_RANGE_HIGH          3
00274 
00275 #define CR_CLASS_PUBLIC                 0
00276 #define CR_CLASS_CONFIDENTIAL           1
00277 #define CR_CLASS_PRIVATE                2
00278 #define CR_CLASS_RANGE_LOW              0
00279 #define CR_CLASS_RANGE_HIGH             2
00280 
00281 
00282 //
00283 // Task record: field constants
00284 //
00285 
00286 #define TR_ALARM_DATE                   1
00287 #define TR_ALARM_RELATIVE               2
00288 #define TR_ALARM_RANGE_LOW              1
00289 #define TR_ALARM_RANGE_HIGH             2
00290 
00291 #define TR_PRIORITY_HIGH                0
00292 #define TR_PRIORITY_NORMAL              1
00293 #define TR_PRIORITY_LOW                 2
00294 #define TR_PRIORITY_RANGE_LOW           0
00295 #define TR_PRIORITY_RANGE_HIGH          2
00296 
00297 #define TR_STATUS_NOT_STARTED           0
00298 #define TR_STATUS_IN_PROGRESS           1
00299 #define TR_STATUS_COMPLETED             2
00300 #define TR_STATUS_WAITING               3
00301 #define TR_STATUS_DEFERRED              4
00302 #define TR_STATUS_RANGE_LOW             0
00303 #define TR_STATUS_RANGE_HIGH            4
00304 
00305 //
00306 // Phone Call Logs record: field constants
00307 //
00308 //
00309 #define CLL_DIRECTION_RECEIVER          0
00310 #define CLL_DIRECTION_EMITTER           1
00311 #define CLL_DIRECTION_FAILED            2
00312 #define CLL_DIRECTION_MISSING           3
00313 #define CLL_DIRECTION_RANGE_LOW         0
00314 #define CLL_DIRECTION_RANGE_HIGH        3
00315 
00316 #define CLL_PHONETYPE_UNDEFINED         0
00317 #define CLL_PHONETYPE_OFFICE            1
00318 #define CLL_PHONETYPE_HOME              2
00319 #define CLL_PHONETYPE_MOBILE            3
00320 #define CLL_PHONETYPE_RANGE_LOW         0
00321 #define CLL_PHONETYPE_RANGE_HIGH        3
00322 
00323 //
00324 // Browser Bookmarks record: field constants
00325 //
00326 //
00327 #define BMK_BROWSER_AUTO                0
00328 #define BMK_BROWSER_BLACKBERRY          1
00329 #define BMK_BROWSER_FIREFOX             2
00330 #define BMK_BROWSER_INTERNET_EXPLORER   3
00331 
00332 #define BMK_DISPLAY_AUTO                0
00333 #define BMK_DISPLAY_COLOMN              1
00334 #define BMK_DISPLAY_PAGE                2
00335 
00336 #define BMK_JAVASCRIPT_AUTO             0
00337 #define BMK_JAVASCRIPT_ENABLED          1
00338 #define BMK_JAVASCRIPT_DISABLED         2
00339 
00340 struct StringField
00341 {
00342         uint16_t        be_size;        // may or may not have a null term.
00343                                         // big-endian
00344         uint8_t         data[1];
00345 } ATTRIBUTE_PACKED;
00346 #define STRING_FIELD_HEADER_SIZE        (sizeof(::Barry::Protocol::StringField) - 1)
00347 
00348 struct BookmarkId
00349 {
00350         uint32_t        bookmark_id;
00351         uint8_t         index;
00352 } ATTRIBUTE_PACKED;
00353 #define BOOKMARK_ID_SIZE                (sizeof(::Barry::Protocol::BookmarkId))
00354 
00355 struct VarStringField
00356 {
00357         uint8_t         present;
00358         uint16_t        be_size;        // big-endian
00359         uint8_t         data[1];
00360 } ATTRIBUTE_PACKED;
00361 #define VARSTRING_FIELD_HEADER_SIZE     (sizeof(::Barry::Protocol::VarStringField) - 1)
00362 
00363 struct BookmarkFolders
00364 {
00365         uint32_t        id1;            // these two fields contain
00366         uint32_t        id2;            // b9 fc f8 f6 c2 e3 a4 d5
00367                                         // whenever there is a record in
00368                                         // the Blackberry Bookmarks folder,
00369                                         // even across multiple devices!
00370                                         // this was true for the 9550 and
00371                                         // the oooold 7750, and the 8700
00372         uint8_t         unknown;        // may be a section code?  seems to
00373                                         // always be 0x08
00374         uint8_t         flag;           // unknown flag
00375 } ATTRIBUTE_PACKED;
00376 #define BOOKMARK_FOLDERS_HEADER_SIZE    (sizeof(::Barry::Protocol::BookmarkFolders))
00377 
00378 
00379 //
00380 // Folder record: field constants
00381 //
00382 
00383 #define FR_TYPE_SUBTREE                 0x00
00384 #define FR_TYPE_DELETED                 0x01
00385 #define FR_TYPE_INBOX                   0x02
00386 #define FR_TYPE_OUTBOX                  0x03
00387 #define FR_TYPE_SENT                    0x04
00388 #define FR_TYPE_OTHER                   0x05
00389 #define FR_TYPE_DRAFT                   0x0a
00390 
00391 #define FR_STATUS_ORPHAN                0x50
00392 #define FR_STATUS_UNFILED               0x51
00393 #define FR_STATUS_FILED                 0x52
00394 
00395 
00396 ///////////////////////////////////////////////////////////////////////////////
00397 // Packed field structures - odd format used with Service Book records
00398 
00399 struct PackedField_02
00400 {
00401         uint8_t         code;
00402         uint8_t         size;
00403         uint8_t         type;
00404         uint8_t         raw[1];
00405 } ATTRIBUTE_PACKED;
00406 #define PACKED_FIELD_02_HEADER_SIZE     (sizeof(::Barry::Protocol::PackedField_02) - 1)
00407 
00408 struct PackedField_10
00409 {
00410         uint8_t         type;
00411         uint8_t         size;
00412         uint8_t         raw[1];
00413 } ATTRIBUTE_PACKED;
00414 #define PACKED_FIELD_10_HEADER_SIZE     (sizeof(::Barry::Protocol::PackedField_10) - 1)
00415 
00416 
00417 
00418 
00419 ///////////////////////////////////////////////////////////////////////////////
00420 // Service Book field and record structures
00421 
00422 struct ServiceBookConfigField
00423 {
00424         uint8_t         format;
00425         uint8_t         fields[1];
00426 } ATTRIBUTE_PACKED;
00427 #define SERVICE_BOOK_CONFIG_FIELD_HEADER_SIZE (sizeof(::Barry::Protocol::ServiceBookConfigField) - 1)
00428 
00429 
00430 ///////////////////////////////////////////////////////////////////////////////
00431 // DB Command Parameter structures
00432 
00433 struct DBC_Record
00434 {
00435         uint16_t        recordIndex;    // index comes from RecordStateTable
00436         uint8_t         data[1];
00437 } ATTRIBUTE_PACKED;
00438 #define DBC_RECORD_HEADER_SIZE          (sizeof(::Barry::Protocol::DBC_Record) - 1)
00439 
00440 struct DBC_RecordFlags
00441 {
00442         uint8_t         unknown;
00443         uint16_t        index;
00444         uint8_t         unknown2[5];
00445 } ATTRIBUTE_PACKED;
00446 #define DBC_RECORD_FLAGS_SIZE           (sizeof(::Barry::Protocol::DBC_RecordFlags))
00447 
00448 struct DBC_TaggedUpload
00449 {
00450         uint8_t         rectype;                // it is unknown exactly what
00451                                                 // this field does, but it
00452                                                 // shows up here and in the
00453                                                 // RecordStateTable, and
00454                                                 // for some of the records
00455                                                 // they must match when writing
00456         uint32_t        uniqueId;
00457         uint8_t         unknown2;
00458         uint8_t         data[1];
00459 } ATTRIBUTE_PACKED;
00460 #define DBC_TAGGED_UPLOAD_HEADER_SIZE   (sizeof(::Barry::Protocol::DBC_TaggedUpload) - 1)
00461 
00462 struct DBC_IndexedUpload
00463 {
00464         uint8_t         unknown;        // observed: 00 or 05
00465         uint16_t        index;
00466         uint8_t         data[1];
00467 } ATTRIBUTE_PACKED;
00468 #define DBC_INDEXED_UPLOAD_HEADER_SIZE  (sizeof(::Barry::Protocol::DBC_IndexedUpload) - 1)
00469 
00470 struct PasswordChallenge
00471 {
00472         uint8_t         remaining_tries;        // number of password attempts
00473                                                 // the device will accept before
00474                                                 // committing suicide...
00475                                                 // starts at 10 and counts down
00476                                                 // on each bad password
00477         uint8_t         unknown;                // observed as 0... probably just
00478                                                 // the top byte of a uint16
00479                                                 // remaining_tries, but I don't
00480                                                 // want to take that chance
00481         uint16_t        param;                  // seems to be a secondary command
00482                                                 // of some kind, observed as 0x14
00483                                                 // or 0x04, but purpose unknown
00484                                                 // possibly a send/receive flag
00485                                                 // bit (0x10/0x00)
00486         union Hash
00487         {
00488                 uint32_t        seed;
00489                 uint8_t         hash[20];
00490         } ATTRIBUTE_PACKED u;
00491 
00492 } ATTRIBUTE_PACKED;
00493 #define PASSWORD_CHALLENGE_HEADER_SIZE  (sizeof(::Barry::Protocol::PasswordChallenge) - sizeof(::Barry::Protocol::PasswordChallenge::Hash))
00494 #define PASSWORD_CHALLENGE_SEED_SIZE    (PASSWORD_CHALLENGE_HEADER_SIZE + sizeof(uint32_t))
00495 #define PASSWORD_CHALLENGE_SIZE         (sizeof(::Barry::Protocol::PasswordChallenge))
00496 
00497 struct AttributeFetch
00498 {
00499         uint16_t        object;
00500         uint16_t        attribute;
00501         uint8_t         raw[1];                 // used only in response
00502 } ATTRIBUTE_PACKED;
00503 #define ATTRIBUTE_FETCH_COMMAND_SIZE    (sizeof(::Barry::Protocol::AttributeFetch) - 1)
00504 
00505 struct ModeSelect
00506 {
00507         uint8_t         name[16];
00508         struct ResponseBlock
00509         {
00510                 uint8_t         unknown[20];
00511         } ATTRIBUTE_PACKED response;
00512 } ATTRIBUTE_PACKED;
00513 
00514 struct Echo
00515 {
00516         uint64_t        ticks;                  // number of microseconds since
00517                                                 // host system startup
00518 } ATTRIBUTE_PACKED;
00519 #define ECHO_COMMAND_SIZE               (sizeof(::Barry::Protocol::Echo))
00520 
00521 
00522 ///////////////////////////////////////////////////////////////////////////////
00523 // Protocol command structures
00524 
00525 struct SocketCommand
00526 {
00527         uint16_t        socket;
00528         uint8_t         sequence;               // incremented on each socket 0
00529                                                 // communication, replies return
00530                                                 // the same number from command
00531 
00532         union PacketData
00533         {
00534 
00535                 PasswordChallenge       password;
00536                 AttributeFetch          fetch;
00537                 ModeSelect              mode;
00538                 uint8_t                 raw[1];
00539                 Echo                    echo;
00540 
00541         } ATTRIBUTE_PACKED u;
00542 } ATTRIBUTE_PACKED;
00543 #define SOCKET_COMMAND_HEADER_SIZE              (sizeof(::Barry::Protocol::SocketCommand) - sizeof(::Barry::Protocol::SocketCommand::PacketData))
00544 
00545 struct SequenceCommand
00546 {
00547         uint8_t         socket;                 // socket number, single byte
00548         uint8_t         unknown2;
00549         uint8_t         unknown3;
00550         uint32_t        sequenceId;
00551 } ATTRIBUTE_PACKED;
00552 
00553 struct DBCommand
00554 {
00555         uint8_t         operation;      // see below
00556         uint16_t        databaseId;     // value from the Database Database
00557 
00558         union Parameters
00559         {
00560 
00561                 DBC_Record              record;
00562                 DBC_RecordFlags         flags;
00563                 DBC_TaggedUpload        tag_upload;
00564                 DBC_IndexedUpload       index_upload;
00565                 uint8_t                 raw[1];
00566 
00567         } ATTRIBUTE_PACKED u;
00568 } ATTRIBUTE_PACKED;
00569 #define DB_COMMAND_HEADER_SIZE          (sizeof(::Barry::Protocol::DBCommand) - sizeof(::Barry::Protocol::DBCommand::Parameters))
00570 
00571 
00572 
00573 ///////////////////////////////////////////////////////////////////////////////
00574 // Protocol response parameter structures
00575 
00576 struct DBR_OldDBDBRecord
00577 {
00578         uint16_t        count;                  // number of fields in record
00579         OldDBDBField    field[1];
00580 } ATTRIBUTE_PACKED;
00581 #define OLD_DBDB_RECORD_HEADER_SIZE     (sizeof(::Barry::Protocol::DBR_OldDBDBRecord) - sizeof(::Barry::Protocol::OldDBDBField))
00582 
00583 struct DBR_DBDBRecord
00584 {
00585         uint16_t        count;
00586         uint8_t         unknown[3];
00587         DBDBField       field[1];
00588 } ATTRIBUTE_PACKED;
00589 #define DBDB_RECORD_HEADER_SIZE         (sizeof(::Barry::Protocol::DBR_DBDBRecord) - sizeof(::Barry::Protocol::DBDBField))
00590 
00591 // Records with a uniqueId.  This covers the following records:
00592 //
00593 //      Old Contact records
00594 //      Old Service Book records
00595 //      Old Calendar records
00596 //
00597 struct DBR_OldTaggedRecord
00598 {
00599         uint8_t         rectype;
00600         uint16_t        index;
00601         uint32_t        uniqueId;
00602         uint8_t         unknown2;
00603 
00604         union TaggedData
00605         {
00606                 CommonField     field[1];
00607         } ATTRIBUTE_PACKED u;
00608 } ATTRIBUTE_PACKED;
00609 #define DBR_OLD_TAGGED_RECORD_HEADER_SIZE (sizeof(::Barry::Protocol::DBR_OldTaggedRecord) - sizeof(::Barry::Protocol::DBR_OldTaggedRecord::TaggedData))
00610 
00611 struct MessageRecord
00612 {
00613         uint8_t         field1;         // always 'j'
00614         uint32_t        field2;         // always 0x00000000
00615         uint32_t        flags;          // flags
00616         uint32_t        field4;         // normal email and pin recv this is 0x7ff
00617                                         // changes on sent and reply to 0x01ffffff
00618                                         // and 0x003fffff on pin send
00619         uint32_t        field5;         // always 0x00000000
00620         uint32_t        field6;         // always 0x00000000
00621         uint32_t        field7;         // always 0x00000000
00622         uint32_t        field8;         // always 0x00000000
00623         uint16_t        field9;         // always 0x0000
00624 
00625         uint16_t        dateReceived;   // the first two of these time fields are always the same
00626         uint16_t        timeReceived;   //
00627         uint16_t        dateDuplicate;  // On mail sent from the BB all three fields are identical
00628         uint16_t        timeDuplicate;  // (time sent)
00629         uint16_t        dateSent;
00630         uint16_t        timeSent;
00631 
00632         uint16_t        priority;       // priority field
00633         uint32_t        field14;        // always 0x00000000
00634         uint32_t        field15;        // always 0x00000000
00635         uint16_t        field16;        // always 0x0000
00636         uint32_t        field13;        // PIN reply 0x00000000 other time 0xffffffff or 0xfffffffe
00637         uint16_t        messageSize;    // Message size, 0x0000 if Reply or Saved, 0xffff if below ????
00638         uint32_t        field18;        // 0x0's and 0xF'x
00639         uint32_t        field19;        // 0x0's and 0xF's
00640         uint16_t        field20;        // always 0x0000
00641         uint16_t        field21;        // 0x01 unless PIN reply then 0x00
00642         uint32_t        inReplyTo;      // reply to message?
00643         uint32_t        field22;        // always 0x00000000
00644         uint16_t        field23;        // FIXME
00645 
00646         uint32_t        folderOne;      // these are the 'folders' the message is in
00647         uint32_t        folderTwo;      //
00648 
00649         uint16_t        replyMessageFlags;      // 0xfffe on recvd messages
00650                                         // 0x001b on reply
00651                                         // 0x0015 on send
00652                                         // 0x3 pin send
00653                                         // 0x2 on pin recv
00654         uint16_t        field27;        // set to 0x00000004 on PIN reply, 0x00000005 otherwise
00655         uint32_t        headerUID;      // yet another copy of the UID (RecId)
00656 
00657         uint32_t        field29;        // always 0x00000000
00658         uint16_t        field30;        // always 0x0002
00659         uint16_t        field31;        // always 0x00000000
00660         uint16_t        field32;        // always 0x0004
00661         uint16_t        field34;        // always 0x0000
00662         uint8_t         field33;        // always 'd'
00663         uint32_t        timeBlock;      // FIXME
00664         CommonField     field[1];
00665 } ATTRIBUTE_PACKED;
00666 #define MESSAGE_RECORD_HEADER_SIZE (sizeof(::Barry::Protocol::MessageRecord) - sizeof(::Barry::Protocol::CommonField))
00667 
00668 
00669 
00670 ///////////////////////////////////////////////////////////////////////////////
00671 // Protocol response structures
00672 
00673 struct DBResponse
00674 {
00675         uint8_t         operation;
00676 
00677         union Parameters
00678         {
00679 
00680                 DBR_OldTaggedRecord     tagged;
00681                 DBR_OldDBDBRecord       old_dbdb;
00682                 DBR_DBDBRecord          dbdb;
00683 
00684         } ATTRIBUTE_PACKED u;
00685 
00686 } ATTRIBUTE_PACKED;
00687 #define DB_RESPONSE_HEADER_SIZE         (sizeof(::Barry::Protocol::DBResponse) - sizeof(::Barry::Protocol::DBResponse::Parameters))
00688 
00689 
00690 
00691 ///////////////////////////////////////////////////////////////////////////////
00692 // Database access command structure
00693 
00694 // even fragmented packets have a tableCmd
00695 struct DBAccess
00696 {
00697         uint8_t         tableCmd;
00698 
00699         union DBData
00700         {
00701                 DBCommand               command;
00702                 DBResponse              response;
00703                 CommandTableField       table[1];
00704                 uint8_t                 return_code;
00705                 uint8_t                 fragment[1];
00706 
00707         } ATTRIBUTE_PACKED u;
00708 } ATTRIBUTE_PACKED;
00709 #define SB_DBACCESS_HEADER_SIZE                 (sizeof(::Barry::Protocol::DBAccess) - sizeof(::Barry::Protocol::DBAccess::DBData))
00710 #define SB_DBACCESS_RETURN_CODE_SIZE            (1)
00711 
00712 
00713 
00714 ///////////////////////////////////////////////////////////////////////////////
00715 // Javaloader protocol structure
00716 
00717 struct JLDirEntry
00718 {
00719         uint16_t        unknown;
00720         uint32_t        timestamp;
00721         uint16_t        filename_size;
00722         uint8_t         filename[1];
00723         // the rest of the packet is variable length
00724         // another string for version, then:
00725         // uint32_t     cod_size;
00726 
00727 } ATTRIBUTE_PACKED;
00728 #define SB_JLDIRENTRY_HEADER_SIZE               (sizeof(::Barry::Protocol::JLDirEntry) - 1)
00729 
00730 struct JLCommand
00731 {
00732         uint8_t         command;
00733         uint8_t         unknown;        // nearly always 0, might be top half of command
00734         uint16_t        size;
00735 } ATTRIBUTE_PACKED;
00736 #define SB_JLCOMMAND_HEADER_SIZE                (sizeof(::Barry::Protocol::JLCommand))
00737 
00738 struct JLResponse
00739 {
00740         uint8_t         command;
00741         uint8_t         unknown;
00742         uint16_t        expect;
00743 } ATTRIBUTE_PACKED;
00744 #define SB_JLRESPONSE_HEADER_SIZE               (sizeof(::Barry::Protocol::JLResponse))
00745 
00746 struct JLScreenInfo
00747 {
00748         uint16_t        unknown1;
00749         uint16_t        unknown2;
00750         uint16_t        unknown3;
00751         uint16_t        width;
00752         uint16_t        height;
00753         uint16_t        unknown4;
00754         uint16_t        unknown5;
00755         uint16_t        unknown6;
00756 } ATTRIBUTE_PACKED;
00757 #define SB_JLSCREENINFO_SIZE                    (sizeof(::Barry::Protocol::JLScreenInfo))
00758 
00759 struct JLEventlogEntry
00760 {
00761         uint16_t        size;
00762         // remainder of packet is variable
00763         // it contains the log data as an ASCII (UTF-8?) string
00764 } ATTRIBUTE_PACKED;
00765 #define SB_JLEVENTLOG_ENTRY_HEADER_SIZE         (sizeof(::Barry::Protocol::JLEventlogEntry))
00766 
00767 struct JLDeviceInfo
00768 {
00769         uint32_t        hardware_id;
00770         uint32_t        pin;
00771         uint32_t        os_version;
00772         uint32_t        vm_version;
00773         uint32_t        radio_id;
00774         uint32_t        vendor_id;
00775         uint32_t        active_wafs;
00776         // older devices (such as 7130) don't this extra data in the
00777         // device info packet and will therefore fail the size check
00778         //uint8_t               raw[4];
00779 } ATTRIBUTE_PACKED;
00780 #define SB_JLDEVICEINFO_SIZE                    (sizeof(::Barry::Protocol::JLDeviceInfo))
00781 
00782 struct JLPacket
00783 {
00784         uint16_t        socket;
00785         uint16_t        size;           // total size of data packet
00786 
00787         union PacketData
00788         {
00789                 JLCommand               command;
00790                 JLResponse              response;
00791                 JLScreenInfo            screeninfo;
00792                 JLEventlogEntry         logentry;
00793                 JLDeviceInfo            devinfo;
00794                 uint8_t                 raw[1];
00795                 char                    filename[1];
00796                 uint32_t                cod_size;
00797                 uint32_t                timestamp;
00798                 uint16_t                id;
00799         } ATTRIBUTE_PACKED u;
00800 
00801 } ATTRIBUTE_PACKED;
00802 #define SB_JLPACKET_HEADER_SIZE         (sizeof(::Barry::Protocol::JLPacket) - sizeof(::Barry::Protocol::JLPacket::PacketData))
00803 
00804 
00805 ///////////////////////////////////////////////////////////////////////////////
00806 // JavaDebug protocol structures
00807 
00808 namespace JDWP {
00809 
00810         // Packet command
00811         //----------------
00812 
00813         struct PacketEventRequestSet {
00814                 uint8_t eventKind;
00815                 uint8_t suspendPolicy;
00816                 uint32_t modifiers;
00817         } ATTRIBUTE_PACKED;
00818 
00819 
00820         struct PacketEventRequest {
00821                 union PacketEventRequestData {
00822                         PacketEventRequestSet set;
00823                 } ATTRIBUTE_PACKED u;
00824         } ATTRIBUTE_PACKED;
00825 
00826 
00827         struct PacketCommand {
00828                 uint8_t commandset;
00829                 uint8_t command;
00830 
00831                 union PacketCommandData {
00832                         PacketEventRequest eventRequest;
00833                 } ATTRIBUTE_PACKED u;
00834         } ATTRIBUTE_PACKED;
00835         #define JDWP_COMMAND_HEADER_SIZE                        (sizeof(::Barry::Protocol::JDWP::PacketCommand))
00836 
00837 
00838         // Packet response
00839         //-----------------
00840 
00841         struct PacketVirtualMachineIDSizes {
00842                 uint32_t fieldIDSize;
00843                 uint32_t methodIDSize;
00844                 uint32_t objectIDSize;
00845                 uint32_t referenceTypeIDSize;
00846                 uint32_t frameIDSize;
00847         } ATTRIBUTE_PACKED;
00848 
00849         #define JDWP_PACKETVIRTUALMACHINEIDSIZES_DATA_SIZE              sizeof(::Barry::Protocol::JDWP::PacketVirtualMachineIDSizes)
00850 
00851 
00852         struct PacketVirtualMachine {
00853                 union PacketVirtualMachineData {
00854                         PacketVirtualMachineIDSizes IDSizes;
00855                 } ATTRIBUTE_PACKED u;
00856         } ATTRIBUTE_PACKED;
00857 
00858 
00859         struct PacketResponse {
00860                 uint16_t errorcode;
00861 
00862                 union PacketResponseData {
00863                         PacketVirtualMachine virtualMachine;
00864                         uint32_t value;
00865                         uint8_t raw[1];
00866                 } ATTRIBUTE_PACKED u;
00867         } ATTRIBUTE_PACKED;
00868         #define JDWP_RESPONSE_HEADER_SIZE                       (sizeof(::Barry::Protocol::JDWP::PacketResponse) - sizeof(::Barry::Protocol::JDWP::PacketResponse::PacketResponseData))
00869 
00870 
00871         // Generic packet
00872         //----------------
00873 
00874         struct Packet {
00875                 uint32_t length;
00876                 uint32_t id;
00877                 uint8_t flags;
00878 
00879                 union PacketType {
00880                         PacketCommand command;
00881                         PacketResponse response;
00882                 } ATTRIBUTE_PACKED u;
00883         } ATTRIBUTE_PACKED;
00884         #define JDWP_PACKET_HEADER_SIZE                 (sizeof(::Barry::Protocol::JDWP::Packet) - sizeof(::Barry::Protocol::JDWP::Packet::PacketType))
00885 
00886 
00887         #define MAKE_JDWPPACKET(var, data)              const ::Barry::Protocol::JDWP::Packet *var = (const ::Barry::Protocol::JDWP::Packet *) (data).GetData()
00888         #define MAKE_JDWPPACKETPTR_BUF(var, ptr)                ::Barry::Protocol::JDWP::Packet *var = (::Barry::Protocol::JDWP::Packet *)ptr
00889 
00890 
00891 } // namespace JDWP
00892 
00893 struct JDWField {
00894         uint32_t size;
00895 
00896         union JDWFieldData {
00897                 uint8_t raw[1];
00898         } ATTRIBUTE_PACKED u;
00899 } ATTRIBUTE_PACKED;
00900 #define JDWP_FIELD_HEADER_SIZE                  (sizeof(::Barry::Protocol::JDWField) - sizeof(::Barry::Protocol::JDWField::JDWFieldData))
00901 
00902 struct JVMCommand
00903 {
00904         uint16_t        size;
00905         uint8_t         command;
00906         uint8_t         raw[1];
00907 } ATTRIBUTE_PACKED;
00908 #define SB_JVMCOMMAND_HEADER_SIZE               (sizeof(::Barry::Protocol::JVMCommand))
00909 
00910 struct JVMResponse
00911 {
00912         uint8_t         command;
00913         uint8_t         unknown;
00914         uint16_t        expect;
00915 } ATTRIBUTE_PACKED;
00916 #define SB_JVMRESPONSE_HEADER_SIZE              (sizeof(::Barry::Protocol::JVMResponse))
00917 
00918 struct JVMModulesList
00919 {
00920         uint32_t        nbr;
00921         // remainder of packet is variable
00922         // it contains the modules list
00923 } ATTRIBUTE_PACKED;
00924 #define SB_JVMMODULES_LIST_HEADER_SIZE          (sizeof(::Barry::Protocol::JVMModulesList))
00925 
00926 struct JVMModulesEntry
00927 {
00928         uint32_t        id;
00929         uint32_t        uniqueId;
00930         uint16_t        sizename;
00931         // remainder of packet is variable
00932         // it contains the module name
00933 } ATTRIBUTE_PACKED;
00934 #define SB_JVMMODULES_ENTRY_HEADER_SIZE         (sizeof(::Barry::Protocol::JVMModulesEntry))
00935 
00936 struct JVMThreadsList
00937 {
00938         uint32_t        nbr;
00939         // remainder of packet is variable
00940         // it contains the threads list
00941 } ATTRIBUTE_PACKED;
00942 #define SB_JVMTHREADS_LIST_HEADER_SIZE          (sizeof(::Barry::Protocol::JVMThreadsList))
00943 
00944 struct JVMUnknown01
00945 {
00946         uint8_t         byte;
00947         uint32_t        address;
00948 } ATTRIBUTE_PACKED;
00949 #define SB_JVMUNKNOWN01_HEADER_SIZE                     (sizeof(::Barry::Protocol::JVMUnknown01))
00950 
00951 struct JVMUnknown02
00952 {
00953         uint32_t        address1;
00954         uint32_t        address2;
00955 } ATTRIBUTE_PACKED;
00956 #define SB_JVMUNKNOWN02_HEADER_SIZE                     (sizeof(::Barry::Protocol::JVMUnknown02))
00957 
00958 struct JVMPacket
00959 {
00960         uint16_t        socket;
00961         uint16_t        size;           // total size of data packet
00962 
00963         union PacketData
00964         {
00965                 JVMCommand              command;
00966                 JVMResponse             response;
00967                 JVMModulesList          moduleslist;
00968                 JVMThreadsList          threadslist;
00969                 JVMUnknown01            unknown01;
00970                 JVMUnknown02            unknown02;
00971                 uint32_t                address;
00972                 uint16_t                expect;
00973                 uint16_t                msglength;
00974                 uint16_t                value;
00975                 uint8_t                 status;
00976                 uint8_t                 raw[1];
00977         } ATTRIBUTE_PACKED u;
00978 
00979 } ATTRIBUTE_PACKED;
00980 #define SB_JVMPACKET_HEADER_SIZE                (sizeof(::Barry::Protocol::JVMPacket) - sizeof(::Barry::Protocol::JVMPacket::PacketData))
00981 
00982 
00983 /////////////////////////////////////////////////////////////////////////////
00984 // Raw channel packet structure
00985 struct ChannelPacket
00986 {
00987         uint16_t        socket;         // socket ID... 0 exists by default
00988         uint16_t        size;           // total size of data packet
00989 
00990         union PacketData
00991         {
00992                 uint8_t                 data[1];
00993         } ATTRIBUTE_PACKED u;
00994 } ATTRIBUTE_PACKED;
00995 #define SB_CHANNELPACKET_HEADER_SIZE            (sizeof(::Barry::Protocol::ChannelPacket) - sizeof(::Barry::Protocol::ChannelPacket::PacketData))
00996 
00997 #define SB_CHANNELPACKET_MAX_DATA_SIZE          0x3FFC
00998 
00999 ///////////////////////////////////////////////////////////////////////////////
01000 // Main packet struct
01001 
01002 struct Packet
01003 {
01004         uint16_t        socket;         // socket ID... 0 exists by default
01005         uint16_t        size;           // total size of data packet
01006         uint8_t         command;
01007 
01008         union PacketData
01009         {
01010 
01011                 SocketCommand           socket;
01012                 SequenceCommand         sequence;
01013                 DBAccess                db;
01014                 uint8_t                 raw[1];
01015 
01016         } ATTRIBUTE_PACKED u;
01017 } ATTRIBUTE_PACKED;
01018 #define SB_PACKET_SOCKET_SIZE                   (sizeof(uint16_t)) // size needed to read the socket in a packet
01019 #define SB_PACKET_HEADER_SIZE                   (sizeof(::Barry::Protocol::Packet) - sizeof(::Barry::Protocol::Packet::PacketData))
01020 
01021 // WARNING : For JavaLoader we have some packet with 5 size !
01022 #define MIN_PACKET_SIZE                 5
01023 #define MIN_PACKET_DATA_SIZE            4
01024 
01025 
01026 // maximum sizes
01027 #define MAX_PACKET_SIZE                 0x400   // anything beyond this needs to be fragmented
01028 #define MAX_PACKET_DATA_SIZE            0x7FC   // for data packet (JavaLoader)
01029 
01030 /////////////////////////////////////////////////////////////////////////////
01031 //
01032 // various useful sizes
01033 //
01034 
01035 #define SB_PACKET_DBACCESS_HEADER_SIZE          (SB_PACKET_HEADER_SIZE + SB_DBACCESS_HEADER_SIZE)
01036 #define SB_FRAG_HEADER_SIZE                     SB_PACKET_DBACCESS_HEADER_SIZE
01037 
01038 #define SB_PACKET_COMMAND_HEADER_SIZE           (SB_PACKET_DBACCESS_HEADER_SIZE + DB_COMMAND_HEADER_SIZE)
01039 #define SB_PACKET_RESPONSE_HEADER_SIZE          (SB_PACKET_DBACCESS_HEADER_SIZE + DB_RESPONSE_HEADER_SIZE)
01040 
01041 #define SB_PACKET_DBDB_HEADER_SIZE              (SB_PACKET_RESPONSE_HEADER_SIZE + DBDB_RECORD_HEADER_SIZE)
01042 #define SB_PACKET_OLD_DBDB_HEADER_SIZE          (SB_PACKET_RESPONSE_HEADER_SIZE + OLD_DBDB_RECORD_HEADER_SIZE)
01043 
01044 #define SB_PACKET_UPLOAD_HEADER_SIZE            (SB_PACKET_DBACCESS_HEADER_SIZE + UPLOAD_HEADER_SIZE)
01045 
01046 #define SB_SEQUENCE_PACKET_SIZE                 (SB_PACKET_HEADER_SIZE + sizeof(::Barry::Protocol::SequenceCommand))
01047 #define SB_SOCKET_PACKET_HEADER_SIZE            (SB_PACKET_HEADER_SIZE + SOCKET_COMMAND_HEADER_SIZE)
01048 #define SB_MODE_PACKET_COMMAND_SIZE             (SB_SOCKET_PACKET_HEADER_SIZE + sizeof(::Barry::Protocol::ModeSelect) - sizeof(::Barry::Protocol::ModeSelect::ResponseBlock))
01049 #define SB_MODE_PACKET_RESPONSE_SIZE            (SB_SOCKET_PACKET_HEADER_SIZE + sizeof(::Barry::Protocol::ModeSelect))
01050 
01051 
01052 // Macros
01053 #define COMMAND(data)                           (((const ::Barry::Protocol::Packet *)data.GetData())->command)
01054 #define IS_COMMAND(data, cmd)                   (COMMAND(data) == cmd)
01055 #define MAKE_PACKET(var, data)                  const ::Barry::Protocol::Packet *var = (const ::Barry::Protocol::Packet *) (data).GetData()
01056 #define MAKE_JLPACKET(var, data)                const ::Barry::Protocol::JLPacket *var = (const ::Barry::Protocol::JLPacket *) (data).GetData()
01057 #define MAKE_JVMPACKET(var, data)               const ::Barry::Protocol::JVMPacket *var = (const ::Barry::Protocol::JVMPacket *) (data).GetData()
01058 #define MAKE_CHANNELPACKET(var, data)           const ::Barry::Protocol::ChannelPacket *var = (const ::Barry::Protocol::ChannelPacket *) (data).GetData()
01059 #define MAKE_PACKETPTR_BUF(var, ptr)            ::Barry::Protocol::Packet *var = (::Barry::Protocol::Packet *)ptr
01060 #define MAKE_JLPACKETPTR_BUF(var, ptr)          ::Barry::Protocol::JLPacket *var = (::Barry::Protocol::JLPacket *)ptr
01061 #define MAKE_JVMPACKETPTR_BUF(var, ptr)         ::Barry::Protocol::JVMPacket *var = (::Barry::Protocol::JVMPacket *)ptr
01062 #define MAKE_CHANNELPACKETPTR_BUF(var, ptr)     ::Barry::Protocol::ChannelPacket *var = (::Barry::Protocol::ChannelPacket *)ptr
01063 #define MAKE_RECORD(type,var,data,off)          type *var = (type *) ((data).GetData() + (off))
01064 #define MAKE_RECORD_PTR(type,var,data,off)      type *var = (type *) ((data) + (off))
01065 
01066 // fragmentation protocol
01067 // send DATA first, then keep sending DATA packets, FRAGMENTing
01068 // as required until finished, then send DONE.  Both sides behave
01069 // this way, so different sized data can be sent in both
01070 // directions
01071 //
01072 // the fragmented piece only has a the param header, and then continues
01073 // right on with the data
01074 
01075 
01076 
01077 // checks packet size and throws BError if not right
01078 void CheckSize(const Barry::Data &packet, size_t requiredsize);
01079 unsigned int GetSize(const Barry::Data &packet);
01080 
01081 bool IsSequencePacket(const Barry::Data &data);
01082 
01083 }} // namespace Barry::Protocol
01084 
01085 #if USE_PACK_PRAGMA
01086 #pragma pack(pop)
01087 #endif
01088 
01089 #endif
01090