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-2009, 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         unknown;
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        unknown2;
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                 uint32_t        uint32;
00114                 int32_t         min1900;
00115                 uint16_t        code;
00116                 uint8_t         raw[1];
00117                 int16_t         int16;
00118 
00119         } __attribute__ ((packed)) u;
00120 
00121 } __attribute__ ((packed));
00122 #define COMMON_FIELD_HEADER_SIZE        (sizeof(Barry::Protocol::CommonField) - sizeof(Barry::Protocol::CommonField::CommonFieldData))
00123 #define COMMON_FIELD_MIN1900_SIZE       (sizeof(int32_t))
00124 
00125 struct CommandTableField
00126 {
00127         uint8_t         size;           // no null terminator
00128         uint8_t         code;
00129         uint8_t         name[1];
00130 } __attribute__ ((packed));
00131 #define COMMAND_FIELD_HEADER_SIZE       (sizeof(Barry::Protocol::CommandTableField) - 1)
00132 
00133 struct OldDBDBField
00134 {
00135         uint16_t        dbNumber;
00136         uint8_t         unknown1;
00137         uint32_t        dbSize;                 // assumed from Cassis docs...
00138                                                 // always 0 in USB
00139         uint16_t        dbRecordCount;
00140         uint16_t        unknown2;
00141         uint16_t        nameSize;               // includes null terminator
00142         uint8_t         name[1];
00143 } __attribute__ ((packed));
00144 #define OLD_DBDB_FIELD_HEADER_SIZE      (sizeof(Barry::Protocol::OldDBDBField) - 1)
00145 
00146 struct DBDBField
00147 {
00148         uint16_t        dbNumber;
00149         uint8_t         unknown1;
00150         uint32_t        dbSize;                 // assumed from Cassis docs...
00151                                                 // always 0 in USB
00152         uint32_t        dbRecordCount;
00153         uint16_t        unknown2;
00154         uint16_t        nameSize;               // includes null terminator
00155         uint8_t         unknown3;
00156         uint8_t         name[1];                // followed by 2 zeros!
00157         uint16_t        unknown;                // this comes after the
00158                                                 // null terminated name, but
00159                                                 // is here for size calcs
00160 } __attribute__ ((packed));
00161 #define DBDB_FIELD_HEADER_SIZE  (sizeof(Barry::Protocol::DBDBField) - 1)
00162 
00163 struct RecordStateTableField
00164 {
00165         uint8_t         rectype;                // it is unknown exactly what
00166                                                 // this field does, but it
00167                                                 // shows up here and in the
00168                                                 // tagged record header, and
00169                                                 // for some of the records
00170                                                 // they must match when writing
00171         uint16_t        index;
00172         uint32_t        uniqueId;               // matches the uniqueId of say,
00173                                                 // address book records
00174         uint8_t         flags;                  // bit 0x01 is the dirty flag
00175                                                 // don't know if any other bits
00176                                                 // are used
00177 #define BARRY_RSTF_DIRTY        0x01
00178         uint8_t         unknown2[4];
00179 } __attribute__ ((packed));
00180 
00181 struct CalendarRecurrenceDataField  // as documented in the Cassis project spec
00182 {
00183         uint8_t         type;
00184 #define CRDF_TYPE_DAY           0x01
00185 #define CRDF_TYPE_MONTH_BY_DATE 0x03
00186 #define CRDF_TYPE_MONTH_BY_DAY  0x04
00187 #define CRDF_TYPE_YEAR_BY_DATE  0x05
00188 #define CRDF_TYPE_YEAR_BY_DAY   0x06
00189 #define CRDF_TYPE_WEEK          0x0c
00190 
00191         uint8_t         unknown;                // always 0x01
00192         uint16_t        interval;
00193         uint32_t        startTime;
00194         uint32_t        endTime;                // 0xFFFFFFFF for never
00195 
00196         union Additional
00197         {
00198                 // Note: blank fields should be set to 0
00199 
00200                 struct Day
00201                 {
00202                         uint8_t day[6];         // always zeros!
00203                 } __attribute__ ((packed)) day;
00204 
00205                 struct MonthByDate
00206                 {
00207                         uint8_t monthDay;       // day of month to recur on
00208                                                 // (1-31)
00209                         uint8_t blank[5];
00210                 } __attribute__ ((packed)) month_by_date;
00211 
00212                 struct MonthByDay
00213                 {
00214                         uint8_t weekDay;        // day of week to recur on (0-6)
00215                         uint8_t week;           // week of month to recur on
00216                                                 // (1 to 5, first week, second
00217                                                 // week, etc)
00218                         uint8_t blank[4];
00219                 } __attribute__ ((packed)) month_by_day;
00220 
00221                 struct YearByDate
00222                 {
00223                         uint8_t monthDay;       // day of month to recur on
00224                                                 // (1-31)
00225                         uint8_t blank;
00226                         uint8_t month;          // month to recur on (1-12)
00227                         uint8_t blank_[3];
00228                 } __attribute__ ((packed)) year_by_date;
00229 
00230                 struct YearByDay
00231                 {
00232                         uint8_t weekDay;        // day of week to recur on (0-6)
00233                         uint8_t week;           // week of month (1 to 5)
00234                         uint8_t month;          // (1-12)
00235                         uint8_t blank[3];
00236                 } __attribute__ ((packed)) year_by_day;
00237 
00238                 struct Week
00239                 {
00240                         uint8_t days;           // bitmask
00241                         #define CRDF_WD_SUN     0x01
00242                         #define CRDF_WD_MON     0x02
00243                         #define CRDF_WD_TUE     0x04
00244                         #define CRDF_WD_WED     0x08
00245                         #define CRDF_WD_THU     0x10
00246                         #define CRDF_WD_FRI     0x20
00247                         #define CRDF_WD_SAT     0x40
00248 
00249                         uint8_t blank[5];
00250                 } __attribute__ ((packed)) week;
00251 
00252         } __attribute__ ((packed)) u;
00253 
00254 } __attribute__ ((packed));
00255 #define CALENDAR_RECURRENCE_DATA_FIELD_SIZE     sizeof(Barry::Protocol::CalendarRecurrenceDataField)
00256 
00257 //
00258 // Calendar record: field constants
00259 //
00260 
00261 #define CR_FREEBUSY_FREE                0
00262 #define CR_FREEBUSY_TENTATIVE           1
00263 #define CR_FREEBUSY_BUSY                2
00264 #define CR_FREEBUSY_OUT_OF_OFFICE       3
00265 #define CR_FREEBUSY_RANGE_LOW           0
00266 #define CR_FREEBUSY_RANGE_HIGH          3
00267 
00268 #define CR_CLASS_PUBLIC                 0
00269 #define CR_CLASS_CONFIDENTIAL           1
00270 #define CR_CLASS_PRIVATE                2
00271 #define CR_CLASS_RANGE_LOW              0
00272 #define CR_CLASS_RANGE_HIGH             2
00273 
00274 
00275 //
00276 // Task record: field constants
00277 //
00278 
00279 #define TR_ALARM_DATE                   1
00280 #define TR_ALARM_RELATIVE               2
00281 #define TR_ALARM_RANGE_LOW              1
00282 #define TR_ALARM_RANGE_HIGH             2
00283 
00284 #define TR_PRIORITY_HIGH                0
00285 #define TR_PRIORITY_NORMAL              1
00286 #define TR_PRIORITY_LOW                 2
00287 #define TR_PRIORITY_RANGE_LOW           0
00288 #define TR_PRIORITY_RANGE_HIGH          2
00289 
00290 #define TR_STATUS_NOT_STARTED           0
00291 #define TR_STATUS_IN_PROGRESS           1
00292 #define TR_STATUS_COMPLETED             2
00293 #define TR_STATUS_WAITING               3
00294 #define TR_STATUS_DEFERRED              4
00295 #define TR_STATUS_RANGE_LOW             0
00296 #define TR_STATUS_RANGE_HIGH            4
00297 
00298 //
00299 // Phone Call Logs record: field constants
00300 //
00301 //
00302 #define CLL_DIRECTION_RECEIVER          0
00303 #define CLL_DIRECTION_EMITTER           1
00304 #define CLL_DIRECTION_FAILED            2
00305 #define CLL_DIRECTION_MISSING           3
00306 #define CLL_DIRECTION_RANGE_LOW         0
00307 #define CLL_DIRECTION_RANGE_HIGH        3
00308 
00309 #define CLL_PHONETYPE_UNDEFINED         0
00310 #define CLL_PHONETYPE_OFFICE            1
00311 #define CLL_PHONETYPE_HOME                      2
00312 #define CLL_PHONETYPE_MOBILE            3
00313 #define CLL_PHONETYPE_RANGE_LOW         0
00314 #define CLL_PHONETYPE_RANGE_HIGH        3
00315 
00316 //
00317 // Folder record: field constants
00318 //
00319 
00320 #define FR_TYPE_SUBTREE                 0x00
00321 #define FR_TYPE_DELETED                 0x01
00322 #define FR_TYPE_INBOX                   0x02
00323 #define FR_TYPE_OUTBOX                  0x03
00324 #define FR_TYPE_SENT                    0x04
00325 #define FR_TYPE_OTHER                   0x05
00326 #define FR_TYPE_DRAFT                   0x0a
00327 
00328 #define FR_STATUS_ORPHAN                0x50
00329 #define FR_STATUS_UNFILED               0x51
00330 #define FR_STATUS_FILED                 0x52
00331 
00332 
00333 ///////////////////////////////////////////////////////////////////////////////
00334 // Packed field structures - odd format used with Service Book records
00335 
00336 struct PackedField_02
00337 {
00338         uint8_t         code;
00339         uint8_t         size;
00340         uint8_t         type;
00341         uint8_t         raw[1];
00342 } __attribute__ ((packed));
00343 #define PACKED_FIELD_02_HEADER_SIZE     (sizeof(Barry::Protocol::PackedField_02) - 1)
00344 
00345 struct PackedField_10
00346 {
00347         uint8_t         type;
00348         uint8_t         size;
00349         uint8_t         raw[1];
00350 } __attribute__ ((packed));
00351 #define PACKED_FIELD_10_HEADER_SIZE     (sizeof(Barry::Protocol::PackedField_10) - 1)
00352 
00353 
00354 
00355 
00356 ///////////////////////////////////////////////////////////////////////////////
00357 // Service Book field and record structures
00358 
00359 struct ServiceBookConfigField
00360 {
00361         uint8_t         format;
00362         uint8_t         fields[1];
00363 } __attribute__ ((packed));
00364 #define SERVICE_BOOK_CONFIG_FIELD_HEADER_SIZE (sizeof(Barry::Protocol::ServiceBookConfigField) - 1)
00365 
00366 
00367 ///////////////////////////////////////////////////////////////////////////////
00368 // DB Command Parameter structures
00369 
00370 struct DBC_Record
00371 {
00372         uint16_t        recordIndex;    // index comes from RecordStateTable
00373         uint8_t         data[1];
00374 } __attribute__ ((packed));
00375 #define DBC_RECORD_HEADER_SIZE          (sizeof(Barry::Protocol::DBC_Record) - 1)
00376 
00377 struct DBC_RecordFlags
00378 {
00379         uint8_t         unknown;
00380         uint16_t        index;
00381         uint8_t         unknown2[5];
00382 } __attribute__ ((packed));
00383 #define DBC_RECORD_FLAGS_SIZE           (sizeof(Barry::Protocol::DBC_RecordFlags))
00384 
00385 struct DBC_TaggedUpload
00386 {
00387         uint8_t         rectype;                // it is unknown exactly what
00388                                                 // this field does, but it
00389                                                 // shows up here and in the
00390                                                 // RecordStateTable, and
00391                                                 // for some of the records
00392                                                 // they must match when writing
00393         uint32_t        uniqueId;
00394         uint8_t         unknown2;
00395         uint8_t         data[1];
00396 } __attribute__ ((packed));
00397 #define DBC_TAGGED_UPLOAD_HEADER_SIZE   (sizeof(Barry::Protocol::DBC_TaggedUpload) - 1)
00398 
00399 struct DBC_IndexedUpload
00400 {
00401         uint8_t         unknown;        // observed: 00 or 05
00402         uint16_t        index;
00403         uint8_t         data[1];
00404 } __attribute__ ((packed));
00405 #define DBC_INDEXED_UPLOAD_HEADER_SIZE  (sizeof(Barry::Protocol::DBC_IndexedUpload) - 1)
00406 
00407 struct PasswordChallenge
00408 {
00409         uint8_t         remaining_tries;        // number of password attempts
00410                                                 // the device will accept before
00411                                                 // committing suicide...
00412                                                 // starts at 10 and counts down
00413                                                 // on each bad password
00414         uint8_t         unknown;                // observed as 0... probably just
00415                                                 // the top byte of a uint16
00416                                                 // remaining_tries, but I don't
00417                                                 // want to take that chance
00418         uint16_t        param;                  // seems to be a secondary command
00419                                                 // of some kind, observed as 0x14
00420                                                 // or 0x04, but purpose unknown
00421                                                 // possibly a send/receive flag
00422                                                 // bit (0x10/0x00)
00423         union Hash
00424         {
00425                 uint32_t        seed;
00426                 uint8_t         hash[20];
00427         } __attribute__ ((packed)) u;
00428 
00429 } __attribute__ ((packed));
00430 #define PASSWORD_CHALLENGE_HEADER_SIZE  (sizeof(Barry::Protocol::PasswordChallenge) - sizeof(Barry::Protocol::PasswordChallenge::Hash))
00431 #define PASSWORD_CHALLENGE_SEED_SIZE    (PASSWORD_CHALLENGE_HEADER_SIZE + sizeof(uint32_t))
00432 #define PASSWORD_CHALLENGE_SIZE         (sizeof(Barry::Protocol::PasswordChallenge))
00433 
00434 struct AttributeFetch
00435 {
00436         uint16_t        object;
00437         uint16_t        attribute;
00438         uint8_t         raw[1];                 // used only in response
00439 } __attribute__ ((packed));
00440 #define ATTRIBUTE_FETCH_COMMAND_SIZE    (sizeof(Barry::Protocol::AttributeFetch) - 1)
00441 
00442 struct ModeSelect
00443 {
00444         uint8_t         name[16];
00445         struct ResponseBlock
00446         {
00447                 uint8_t         unknown[20];
00448         } __attribute__ ((packed)) response;
00449 } __attribute__ ((packed));
00450 
00451 struct Echo
00452 {
00453         uint64_t        ticks;                  // number of microseconds since
00454                                                 // host system startup
00455 } __attribute__ ((packed));
00456 #define ECHO_COMMAND_SIZE               (sizeof(Barry::Protocol::Echo))
00457 
00458 
00459 ///////////////////////////////////////////////////////////////////////////////
00460 // Protocol command structures
00461 
00462 struct SocketCommand
00463 {
00464         uint16_t        socket;
00465         uint8_t         sequence;               // incremented on each socket 0
00466                                                 // communication, replies return
00467                                                 // the same number from command
00468 
00469         union PacketData
00470         {
00471 
00472                 PasswordChallenge       password;
00473                 AttributeFetch          fetch;
00474                 ModeSelect              mode;
00475                 uint8_t                 raw[1];
00476                 Echo                    echo;
00477 
00478         } __attribute__ ((packed)) u;
00479 } __attribute__ ((packed));
00480 #define SOCKET_COMMAND_HEADER_SIZE              (sizeof(Barry::Protocol::SocketCommand) - sizeof(Barry::Protocol::SocketCommand::PacketData))
00481 
00482 struct SequenceCommand
00483 {
00484         uint8_t         unknown1;
00485         uint8_t         unknown2;
00486         uint8_t         unknown3;
00487         uint32_t        sequenceId;
00488 } __attribute__ ((packed));
00489 
00490 struct DBCommand
00491 {
00492         uint8_t         operation;      // see below
00493         uint16_t        databaseId;     // value from the Database Database
00494 
00495         union Parameters
00496         {
00497 
00498                 DBC_Record              record;
00499                 DBC_RecordFlags         flags;
00500                 DBC_TaggedUpload        tag_upload;
00501                 DBC_IndexedUpload       index_upload;
00502                 uint8_t                 raw[1];
00503 
00504         } __attribute__ ((packed)) u;
00505 } __attribute__ ((packed));
00506 #define DB_COMMAND_HEADER_SIZE          (sizeof(Barry::Protocol::DBCommand) - sizeof(Barry::Protocol::DBCommand::Parameters))
00507 
00508 
00509 
00510 ///////////////////////////////////////////////////////////////////////////////
00511 // Protocol response parameter structures
00512 
00513 struct DBR_OldDBDBRecord
00514 {
00515         uint16_t        count;                  // number of fields in record
00516         OldDBDBField    field[1];
00517 } __attribute__ ((packed));
00518 #define OLD_DBDB_RECORD_HEADER_SIZE     (sizeof(Barry::Protocol::DBR_OldDBDBRecord) - sizeof(Barry::Protocol::OldDBDBField))
00519 
00520 struct DBR_DBDBRecord
00521 {
00522         uint16_t        count;
00523         uint8_t         unknown[3];
00524         DBDBField       field[1];
00525 } __attribute__ ((packed));
00526 #define DBDB_RECORD_HEADER_SIZE         (sizeof(Barry::Protocol::DBR_DBDBRecord) - sizeof(Barry::Protocol::DBDBField))
00527 
00528 // Records with a uniqueId.  This covers the following records:
00529 //
00530 //      Old Contact records
00531 //      Old Service Book records
00532 //      Old Calendar records
00533 //
00534 struct DBR_OldTaggedRecord
00535 {
00536         uint8_t         rectype;
00537         uint16_t        index;
00538         uint32_t        uniqueId;
00539         uint8_t         unknown2;
00540 
00541         union TaggedData
00542         {
00543                 CommonField     field[1];
00544         } __attribute__ ((packed)) u;
00545 } __attribute__ ((packed));
00546 #define DBR_OLD_TAGGED_RECORD_HEADER_SIZE (sizeof(Barry::Protocol::DBR_OldTaggedRecord) - sizeof(Barry::Protocol::DBR_OldTaggedRecord::TaggedData))
00547 
00548 struct MessageRecord
00549 {
00550         uint8_t         field1;         // always 'j'
00551         uint32_t        field2;         // always 0x00000000
00552         uint32_t        flags;          // flags
00553         uint32_t        field4;         // normal email and pin recv this is 0x7ff
00554                                         // changes on sent and reply to 0x01ffffff
00555                                         // and 0x003fffff on pin send
00556         uint32_t        field5;         // always 0x00000000
00557         uint32_t        field6;         // always 0x00000000
00558         uint32_t        field7;         // always 0x00000000
00559         uint32_t        field8;         // always 0x00000000
00560         uint16_t        field9;         // always 0x0000
00561 
00562         uint16_t        dateReceived;   // the first two of these time fields are always the same
00563         uint16_t        timeReceived;   //
00564         uint16_t        dateDuplicate;  // On mail sent from the BB all three fields are identical
00565         uint16_t        timeDuplicate;  // (time sent)
00566         uint16_t        dateSent;
00567         uint16_t        timeSent;
00568 
00569         uint16_t        priority;       // priority field
00570         uint32_t        field14;        // always 0x00000000
00571         uint32_t        field15;        // always 0x00000000
00572         uint16_t        field16;        // always 0x0000
00573         uint32_t        field13;        // PIN reply 0x00000000 other time 0xffffffff or 0xfffffffe
00574         uint16_t        messageSize;    // Message size, 0x0000 if Reply or Saved, 0xffff if below ????
00575         uint32_t        field18;        // 0x0's and 0xF'x
00576         uint32_t        field19;        // 0x0's and 0xF's
00577         uint16_t        field20;        // always 0x0000
00578         uint16_t        field21;        // 0x01 unless PIN reply then 0x00
00579         uint32_t        inReplyTo;      // reply to message?
00580         uint32_t        field22;        // always 0x00000000
00581         uint16_t        field23;        // FIXME
00582 
00583         uint32_t        folderOne;      // these are the 'folders' the message is in
00584         uint32_t        folderTwo;      //
00585 
00586         uint16_t        replyMessageFlags;      // 0xfffe on recvd messages
00587                                         // 0x001b on reply
00588                                         // 0x0015 on send
00589                                         // 0x3 pin send
00590                                         // 0x2 on pin recv
00591         uint16_t        field27;        // set to 0x00000004 on PIN reply, 0x00000005 otherwise
00592         uint32_t        headerUID;      // yet another copy of the UID (RecId)
00593 
00594         uint32_t        field29;        // always 0x00000000
00595         uint16_t        field30;        // always 0x0002
00596         uint16_t        field31;        // always 0x00000000
00597         uint16_t        field32;        // always 0x0004
00598         uint16_t        field34;        // always 0x0000
00599         uint8_t         field33;        // always 'd'
00600         uint32_t        timeBlock;      // FIXME
00601         CommonField     field[1];
00602 } __attribute__ ((packed));
00603 #define MESSAGE_RECORD_HEADER_SIZE (sizeof(Barry::Protocol::MessageRecord) - sizeof(Barry::Protocol::CommonField))
00604 
00605 
00606 
00607 ///////////////////////////////////////////////////////////////////////////////
00608 // Protocol response structures
00609 
00610 struct DBResponse
00611 {
00612         uint8_t         operation;
00613 
00614         union Parameters
00615         {
00616 
00617                 DBR_OldTaggedRecord     tagged;
00618                 DBR_OldDBDBRecord       old_dbdb;
00619                 DBR_DBDBRecord          dbdb;
00620 
00621         } __attribute__ ((packed)) u;
00622 
00623 } __attribute__ ((packed));
00624 #define DB_RESPONSE_HEADER_SIZE         (sizeof(Barry::Protocol::DBResponse) - sizeof(Barry::Protocol::DBResponse::Parameters))
00625 
00626 
00627 
00628 ///////////////////////////////////////////////////////////////////////////////
00629 // Database access command structure
00630 
00631 // even fragmented packets have a tableCmd
00632 struct DBAccess
00633 {
00634         uint8_t         tableCmd;
00635 
00636         union DBData
00637         {
00638                 DBCommand               command;
00639                 DBResponse              response;
00640                 CommandTableField       table[1];
00641                 uint8_t                 return_code;
00642                 uint8_t                 fragment[1];
00643 
00644         } __attribute__ ((packed)) u;
00645 } __attribute__ ((packed));
00646 #define SB_DBACCESS_HEADER_SIZE                 (sizeof(Barry::Protocol::DBAccess) - sizeof(Barry::Protocol::DBAccess::DBData))
00647 #define SB_DBACCESS_RETURN_CODE_SIZE            (1)
00648 
00649 
00650 
00651 ///////////////////////////////////////////////////////////////////////////////
00652 // Javaloader protocol structure
00653 
00654 struct JLDirEntry
00655 {
00656         uint16_t        unknown;
00657         uint32_t        timestamp;
00658         uint16_t        filename_size;
00659         uint8_t         filename[1];
00660         // the rest of the packet is variable length
00661         // another string for version, then:
00662         // uint32_t     cod_size;
00663 
00664 } __attribute__ ((packed));
00665 #define SB_JLDIRENTRY_HEADER_SIZE               (sizeof(Barry::Protocol::JLDirEntry) - 1)
00666 
00667 struct JLCommand
00668 {
00669         uint8_t         command;
00670         uint8_t         unknown;        // nearly always 0, might be top half of command
00671         uint16_t        size;
00672 } __attribute__ ((packed));
00673 #define SB_JLCOMMAND_HEADER_SIZE                (sizeof(Barry::Protocol::JLCommand))
00674 
00675 struct JLResponse
00676 {
00677         uint8_t         command;
00678         uint8_t         unknown;
00679         uint16_t        expect;
00680 } __attribute__ ((packed));
00681 #define SB_JLRESPONSE_HEADER_SIZE               (sizeof(Barry::Protocol::JLResponse))
00682 
00683 struct JLScreenInfo
00684 {
00685         uint16_t        unknown1;
00686         uint16_t        unknown2;
00687         uint16_t        unknown3;
00688         uint16_t        width;
00689         uint16_t        height;
00690         uint16_t        unknown4;
00691         uint16_t        unknown5;
00692         uint16_t        unknown6;
00693 } __attribute__ ((packed));
00694 #define SB_JLSCREENINFO_SIZE                    (sizeof(Barry::Protocol::JLScreenInfo))
00695 
00696 struct JLEventlogEntry
00697 {
00698         uint16_t        size;
00699         // remainder of packet is variable
00700         // it contains the log data as an ASCII (UTF-8?) string
00701 } __attribute__ ((packed));
00702 #define SB_JLEVENTLOG_ENTRY_HEADER_SIZE         (sizeof(Barry::Protocol::JLEventlogEntry))
00703 
00704 struct JLDeviceInfo
00705 {
00706         uint32_t        hardware_id;
00707         uint32_t        pin;
00708         uint32_t        os_version;
00709         uint32_t        vm_version;
00710         uint32_t        radio_id;
00711         uint32_t        vendor_id;
00712         uint32_t        active_wafs;
00713         // older devices (such as 7130) don't this extra data in the
00714         // device info packet and will therefore fail the size check
00715         //uint8_t               raw[4];
00716 } __attribute__ ((packed));
00717 #define SB_JLDEVICEINFO_SIZE                    (sizeof(Barry::Protocol::JLDeviceInfo))
00718 
00719 struct JLPacket
00720 {
00721         uint16_t        socket;
00722         uint16_t        size;           // total size of data packet
00723 
00724         union PacketData
00725         {
00726                 JLCommand               command;
00727                 JLResponse              response;
00728                 JLScreenInfo            screeninfo;
00729                 JLEventlogEntry         logentry;
00730                 JLDeviceInfo            devinfo;
00731                 uint8_t                 raw[1];
00732                 char                    filename[1];
00733                 uint32_t                cod_size;
00734                 uint32_t                timestamp;
00735                 uint16_t                id;
00736         } __attribute__ ((packed)) u;
00737 
00738 } __attribute__ ((packed));
00739 #define SB_JLPACKET_HEADER_SIZE         (sizeof(Barry::Protocol::JLPacket) - sizeof(Barry::Protocol::JLPacket::PacketData))
00740 
00741 ///////////////////////////////////////////////////////////////////////////////
00742 // Main packet struct
00743 
00744 struct Packet
00745 {
00746         uint16_t        socket;         // socket ID... 0 exists by default
00747         uint16_t        size;           // total size of data packet
00748         uint8_t         command;
00749 
00750         union PacketData
00751         {
00752 
00753                 SocketCommand           socket;
00754                 SequenceCommand         sequence;
00755                 DBAccess                db;
00756                 uint8_t                 raw[1];
00757 
00758         } __attribute__ ((packed)) u;
00759 } __attribute__ ((packed));
00760 #define SB_PACKET_HEADER_SIZE                   (sizeof(Barry::Protocol::Packet) - sizeof(Barry::Protocol::Packet::PacketData))
00761 
00762 // WARNING : For JavaLoader we have some packet with 5 size !
00763 #define MIN_PACKET_SIZE                 5
00764 #define MIN_PACKET_DATA_SIZE            4
00765 
00766 
00767 // maximum sizes
00768 #define MAX_PACKET_SIZE                 0x400   // anything beyond this needs to be fragmented
00769 #define MAX_PACKET_DATA_SIZE            0x7FC   // for data packet (JavaLoader)
00770 
00771 /////////////////////////////////////////////////////////////////////////////
00772 //
00773 // various useful sizes
00774 //
00775 
00776 #define SB_PACKET_DBACCESS_HEADER_SIZE          (SB_PACKET_HEADER_SIZE + SB_DBACCESS_HEADER_SIZE)
00777 #define SB_FRAG_HEADER_SIZE                     SB_PACKET_DBACCESS_HEADER_SIZE
00778 
00779 #define SB_PACKET_COMMAND_HEADER_SIZE           (SB_PACKET_DBACCESS_HEADER_SIZE + DB_COMMAND_HEADER_SIZE)
00780 #define SB_PACKET_RESPONSE_HEADER_SIZE          (SB_PACKET_DBACCESS_HEADER_SIZE + DB_RESPONSE_HEADER_SIZE)
00781 
00782 #define SB_PACKET_DBDB_HEADER_SIZE              (SB_PACKET_RESPONSE_HEADER_SIZE + DBDB_RECORD_HEADER_SIZE)
00783 #define SB_PACKET_OLD_DBDB_HEADER_SIZE          (SB_PACKET_RESPONSE_HEADER_SIZE + OLD_DBDB_RECORD_HEADER_SIZE)
00784 
00785 #define SB_PACKET_UPLOAD_HEADER_SIZE            (SB_PACKET_DBACCESS_HEADER_SIZE + UPLOAD_HEADER_SIZE)
00786 
00787 #define SB_SEQUENCE_PACKET_SIZE                 (SB_PACKET_HEADER_SIZE + sizeof(Barry::Protocol::SequenceCommand))
00788 #define SB_SOCKET_PACKET_HEADER_SIZE            (SB_PACKET_HEADER_SIZE + SOCKET_COMMAND_HEADER_SIZE)
00789 #define SB_MODE_PACKET_COMMAND_SIZE             (SB_SOCKET_PACKET_HEADER_SIZE + sizeof(Barry::Protocol::ModeSelect) - sizeof(Barry::Protocol::ModeSelect::ResponseBlock))
00790 #define SB_MODE_PACKET_RESPONSE_SIZE            (SB_SOCKET_PACKET_HEADER_SIZE + sizeof(Barry::Protocol::ModeSelect))
00791 
00792 
00793 // Macros
00794 #define COMMAND(data)                           (((const Barry::Protocol::Packet *)data.GetData())->command)
00795 #define IS_COMMAND(data, cmd)                   (COMMAND(data) == cmd)
00796 #define MAKE_PACKET(var, data)                  const Barry::Protocol::Packet *var = (const Barry::Protocol::Packet *) (data).GetData()
00797 #define MAKE_JLPACKET(var, data)                const Barry::Protocol::JLPacket *var = (const Barry::Protocol::JLPacket *) (data).GetData()
00798 #define MAKE_PACKETPTR_BUF(var, ptr)            Barry::Protocol::Packet *var = (Barry::Protocol::Packet *)ptr
00799 #define MAKE_JLPACKETPTR_BUF(var, ptr)          Barry::Protocol::JLPacket *var = (Barry::Protocol::JLPacket *)ptr
00800 #define MAKE_RECORD(type,var,data,off)          type *var = (type *) ((data).GetData() + (off))
00801 #define MAKE_RECORD_PTR(type,var,data,off)      type *var = (type *) ((data) + (off))
00802 
00803 // fragmentation protocol
00804 // send DATA first, then keep sending DATA packets, FRAGMENTing
00805 // as required until finished, then send DONE.  Both sides behave
00806 // this way, so different sized data can be sent in both
00807 // directions
00808 //
00809 // the fragmented piece only has a the param header, and then continues
00810 // right on with the data
00811 
00812 
00813 
00814 // checks packet size and throws BError if not right
00815 void CheckSize(const Barry::Data &packet, size_t requiredsize);
00816 unsigned int GetSize(const Barry::Data &packet);
00817 
00818 }} // namespace Barry::Protocol
00819 
00820 #endif
00821 

Generated on Tue Jun 30 16:08:14 2009 for Barry by  doxygen 1.5.8