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