summaryrefslogtreecommitdiff
path: root/src/sysync_SDK/Sources/san.h
blob: 604336523777a4a70a00e5904df553e42f505a00 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/*
 *  File:         san.h
 *
 *  Author:			  Beat Forster (bfo@synthesis.ch)
 *
 *  Server Alerted Notification
 *    for OMA DS 1.2
 *
 *  Copyright (c) 2005-2009 by Synthesis AG (www.synthesis.ch)
 *
 */

#ifndef San_H
#define San_H


// ---------- standalone definitions ------------------------------
#include "generic_types.h" // some basic defs, which aren't available
#include "syerror.h"       // error code definitions

#include <cstdio>         // used for printf calls
#include <cstring>        // used for strcpy/strlen calls

#ifdef __cplusplus
  #include <string>      // STL includes
  #include <list>

  using namespace std;
#endif

typedef unsigned char  byte;

// ----------------------------------------------------


namespace sysync {


// The digest field structure
#define DigestSize 16

struct TDigestField {
  uInt8 b[ DigestSize ];
}; // TDigestField


enum UI_Mode {
  UI_not_specified    = 0, // "00"
  UI_background       = 1, // "01"
  UI_informative      = 2, // "10"
  UI_user_interaction = 3  // "11"
};

enum Initiator {
  Initiator_User      = 0, //  "0"
  Initiator_Server    = 1  //  "1"
};


/*!
 *  How to create a SAN package (on server side):
 *     1) Prepare the SAN package using 'PreparePackage'
 *
 *        If      all datastores need to be notified, skip 2 and 3
 *        If specific datastores need to be notified, call 2 and 3
 *
 *     2) Call 'CreateEmptyNotificationBody' (not needed 1st time) and
 *     3) call 'AddSync' for each datastore to be notified
 *
 *     4) Create the SAN package with 'GetPackage'.
 *        A vendor specific record can be added, if required.
 *
 *--------------------------------------------------------------------
 *  How to check a SAN package (on client side):
 *     1) pass the san message with 'PassSan'
 *     1) create <fDigest> first (using 'CreateDigest')
 *     2) call 'DigestOK', to verify it
 *
 *  How to get the <n>th sync message:
 *        call 'GetNthSync( n, .. )'
 *      [ call 'GetHeader (       )' or
 *              GetNthSync( 0, .. )' to get header params only ]
 *
 */
class SanPackage {
  public:
    SanPackage(); // constructor
   ~SanPackage(); //  destructor

    /*! Base64 encoded MD5, two strings can be concatenated with ":" */
    string B64_H( string s1, string s2= "" );

    /*! Base64 encoded MD5 of the notification part of <san>,<sanSize>. */
    string B64_H_Notification( void* san, size_t sanSize );


    /*! Prepare the SAN package */
    void PreparePackage( string    aB64_H_srvID_pwd,
                         string    aNonce,
                         uInt16    aProtocolVersion,
                         UI_Mode   aUI_Mode,
                         Initiator aInitiator,
                         uInt16    aSessionID,
                         string    aSrvID );



    /*! These variables will be assigned with the 'PreparePackage' call
     *  <fProtocolVersion>: 10*version => max= V102.3 / V1.0 = 10 )
     *                      for OMA DS 1.2 use '12'
     */
    string    fB64_H_srvID_pwd;
    string    fNonce;
    uInt16    fProtocolVersion; // 10 bit
    UI_Mode   fUI_Mode;         //  2 bit
    Initiator fInitiator;       //  1 bit
    uInt16    fSessionID;       // 16 bit
    string    fServerID;


    /*! Create an empty notification body */
    void CreateEmptyNotificationBody();


    /*! Add a sync sequence to the notification body
     *
     *  (in)
     *  @param  <syncType>     206..210 (internally less 200: 206 -> 6)
     *  @param  <contentType>  MIME media content type (24 bit)
     *  @param  <serverURI>    server's URI
     */
    TSyError AddSync( int syncType, uInt32 contentType, const char* serverURI );


    /*! Get the SAN package
     *
     *  (out)
     *  @param  <san>                get the pointer to the SAN message.
     *  @param  <sanSize>            get the SAN message size (in bytes).
     *
     *  (in)
     *  @param  <vendorSpecific>     reference to vendor specific part
     *  @param  <vendorSpecificSize> size (in bytes) of vendor specific part
     *
     *  @return error code           if operation can't be performed
     *
     *  NOTE: The notification body will be added automatically
     *
     */
    TSyError GetPackage( void* &san, size_t &sanSize,
                         void*  vendorSpecific= NULL,
                         size_t vendorSpecificSize= 0 );


    /*! Create the digest for the SAN package:
     *  digest= H(B64(H(server-identifier:password)):nonce:B64(H(notification)))
     *  where notification will be calculated from <san>/<sanSize>.
     */
    TSyError CreateDigest( const char* aSrvID,
                           const char* aPwd,
                           const char* aNonce,
                           void* san, size_t sanSize );

    /*! overloaded version, if only the B64 hashes are available */
    TSyError CreateDigest( const char* b64_h_srvID_pwd,
                           const char* aNonce,
                           void* san, size_t sanSize );


    /*! Check, if the digest of <san> is correct */
    bool DigestOK( void* san );


    /*! Pass SAN message <san>,<sanSize> to object,
     *  a local copy will be kept then internally
     */
    TSyError PassSan( void* san, size_t sanSize );


    /*! Get the effective size of an already created <san> message
     *  (without vendor specific part)
     *
     *  (in)
     *  @param  <san>          the pointer to the SAN message
     *  @param  <sanSize>      the max. SAN message size (in bytes)
     *                         0, if unknown.
     *  (out)
     *  @param  <sanSize>      the effective SAN message size (in bytes)
     *
     *  @return error code     403, if input <sanSize> is too small
     */
    TSyError GetSanSize( void* san, size_t &sanSize );


    /*! Get the nth sync info
     *
     *  (in)
     *  @param  <san>          the pointer to the SAN message
     *  @param  <sanSize>      the SAN message size (in bytes)
     *  @param  <nth>          asks for the <nth> sync info
     *                         nth=0 is allowed also, but will only assign
     *                         the header variables
     *  (out)
     *  @param  <syncType>     206..210 (internally less 200: 206 -> 6)
     *  @param  <contentType>  MIME media content type (24 bit)
     *  @param  <serverURI>    server's URI
     *
     *  @return error code     403, if <sanSize> is too small
     *                         404, if <nth> is out of range
     */
  //TSyError GetNthSync( void*  san, size_t sanSize, int nth,
    TSyError GetNthSync( int    nth,
                         int    &syncType,
                         uInt32 &contentType,
                         string &serverURI );

    /*! Alternative call for GetNthSync( 0, ... ) */
  //TSyError GetHeader ( void*  san, size_t sanSize );
    TSyError GetHeader ();


    TDigestField fDigest; // The digest, created with "CreateDigest"
    int          fNSync;  // number of actual sync fields

  private:
    /*! the internally built notification-body structure */
    byte   fEmpty;    // direct reference to empty structure
    void*  fBody;     // the body structure ...
    size_t fBodySize; // .. and its size

    /*! local copies of <san>,<sanSize> */
    void*  fSan;
    size_t fSanSize;

    /*! MD5 conversion */
    TDigestField H( string s );

    /* Try to interpret SyncML 1.1 SAN */
    TSyError Check_11( void* san, size_t sanSize );

    /*! Add <value> into field <b> at <pos>,<n> */
    void   AddBits( void* ptr, int pos, int n, uInt32 value );
    /*! Get  value  from field <b> at <pos>,<n> */
    uInt32 GetBits( void* ptr, int pos, int n );

    /*! Release notification body */
    void ReleaseNotificationBody();

    /*! Release the SAN package */
    void ReleasePackage();
}; // SanPackage


}	// namespace sysync
#endif	// San_H
// eof