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