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 | #ifdef HAVE_CONFIG_H1 |
63 | # include <config.h> |
64 | #endif |
65 | |
66 | #include "prefix_file.h" |
67 | #include "sync_include.h" |
68 | #include "san.h" |
69 | #include "sysync_md5.h" |
70 | #include "sysync_b64.h" |
71 | |
72 | #ifndef WITHOUT_SAN_1_1 |
73 | #include "sysync_utils.h" |
74 | #endif |
75 | |
76 | |
77 | const uInt16 SyncML12 = 12; |
78 | const uInt16 SyncML11 = 11; |
79 | const uInt16 SyncML10 = 10; |
80 | |
81 | #pragma options align= packed // allow direct mapping of the structure |
82 | |
83 | |
84 | using namespace sysync; |
85 | |
86 | namespace sysync { |
87 | |
88 | |
89 | #define BpB8 8 // bits per byte |
90 | #define NBits7 7 // bytes of the notification-hdr bits |
91 | #define BBits4 4 // bytes of the notification-body bits |
92 | |
93 | #define DB_Full420 420 // memory full error |
94 | #define DB_Error510 510 // general DB error |
95 | |
96 | struct TPackage { |
97 | TDigestField digest; |
98 | |
99 | uInt8 bitField[ NBits7 ]; |
100 | uInt8 serverID_len; |
101 | }; |
102 | |
103 | |
104 | struct TBody { |
105 | uInt8 bitField[ BBits4 ]; |
106 | uInt8 serverURI_len; |
107 | }; |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | static void MD5B64_Local(const char *aString, sInt32 aLen, string &aMD5B64) |
115 | { |
116 | |
117 | if (aLen<=0) aLen=strlen(aString); |
118 | |
119 | md5::SYSYNC_MD5_CTX context; |
120 | uInt8 digest[16]; |
121 | md5::Init (&context); |
122 | md5::Update (&context, (const uInt8 *)aString,aLen); |
123 | md5::Final (digest, &context); |
124 | |
125 | uInt32 b64md5len; |
126 | char *b64md5=b64::encode(digest,16,&b64md5len); |
127 | |
128 | aMD5B64.assign(b64md5,b64md5len); |
129 | |
130 | b64::free(b64md5); |
131 | } |
132 | |
133 | |
134 | |
135 | |
136 | SanPackage::SanPackage() |
137 | { |
138 | fBody= NULL__null; |
139 | CreateEmptyNotificationBody(); |
140 | |
141 | memset( &fDigest, 0, DigestSize16 ); |
142 | fProtocolVersion= 0; |
143 | fUI_Mode = UI_not_specified; |
144 | fInitiator = Initiator_Server; |
145 | fSessionID = 0; |
146 | |
147 | fSan = NULL__null; |
148 | fSanSize = 0; |
149 | } |
150 | |
151 | |
152 | SanPackage::~SanPackage() |
153 | { |
154 | ReleasePackage(); |
155 | ReleaseNotificationBody(); |
156 | } |
157 | |
158 | |
159 | |
160 | |
161 | TDigestField SanPackage::H( string s ) |
162 | { |
163 | TDigestField df; |
164 | |
165 | |
166 | md5::SYSYNC_MD5_CTX context; |
167 | md5::Init ( &context ); |
168 | md5::Update ( &context, (const uInt8 *)s.c_str(), s.length() ); |
169 | md5::Final( df.b, &context ); |
170 | return df; |
171 | } |
172 | |
173 | |
174 | string SanPackage::B64_H( string s1, string s2 ) |
175 | { |
176 | if (!s2.empty()) s1+= ":" + s2; |
177 | MD5B64_Local( s1.c_str(), s1.size(), s1 ); |
178 | return s1; |
179 | } |
180 | |
181 | |
182 | string SanPackage::B64_H_Notification( void* san, size_t sanSize ) |
183 | { |
184 | string s; |
185 | const char* v= (const char*)san + DigestSize16; |
186 | size_t nfySize= sanSize - DigestSize16; |
187 | MD5B64_Local( v, nfySize, s ); |
188 | return s; |
189 | } |
190 | |
191 | |
192 | |
193 | |
194 | void SanPackage::PreparePackage( string aB64_H_srvID_pwd, |
195 | string aNonce, |
196 | uInt16 aProtocolVersion, |
197 | UI_Mode aUI_Mode, |
198 | Initiator aInitiator, |
199 | uInt16 aSessionID, |
200 | string aSrvID ) |
201 | { |
202 | fB64_H_srvID_pwd= aB64_H_srvID_pwd; |
203 | fNonce = aNonce; |
204 | fProtocolVersion= aProtocolVersion; |
205 | fUI_Mode = aUI_Mode; |
206 | fInitiator = aInitiator; |
207 | fSessionID = aSessionID; |
208 | fServerID = aSrvID; |
209 | } |
210 | |
211 | |
212 | |
213 | TSyError SanPackage::CreateDigest( const char* b64_h_serverID_password, |
214 | const char* aNonce, |
215 | void* san, size_t sanSize ) |
216 | { |
217 | string s= b64_h_serverID_password; |
218 | if ( s.empty()) { |
219 | for (int i= 0; i<DigestSize16; i++) { |
220 | fDigest.b[ i ]= 0x00; |
221 | } |
222 | } |
223 | else { s+= ":"; |
224 | s+= aNonce; s+= ":"; |
225 | s+= B64_H_Notification( san,sanSize ); |
226 | fDigest= H( s ); |
227 | } |
228 | |
229 | return LOCERR_OK; |
230 | } |
231 | |
232 | |
233 | TSyError SanPackage::CreateDigest( const char* aServerID, |
234 | const char* aPassword, |
235 | const char* aNonce, |
236 | void* san, size_t sanSize ) |
237 | { |
238 | return CreateDigest( B64_H( aServerID,aPassword ).c_str(), |
239 | aNonce, |
240 | san,sanSize ); |
241 | } |
242 | |
243 | |
244 | |
245 | bool SanPackage::DigestOK( void* san ) |
246 | { |
247 | TDigestField* sanD= (TDigestField*)san; |
248 | |
249 | for (int i= 0; i<DigestSize16; i++) { |
250 | if (fDigest.b[ i ]!=sanD->b[ i ]) return false; |
251 | } |
252 | |
253 | return true; |
254 | } |
255 | |
256 | |
257 | |
258 | |
259 | void SanPackage::AddBits( void* ptr, int pos, int n, uInt32 value ) |
260 | { |
261 | byte* b= (byte*)ptr; |
262 | int lim= pos+n; |
263 | if (lim>BpB8*NBits7) return; |
264 | while (lim>BpB8) { b++; lim-= BpB8; } |
265 | |
266 | int i; |
267 | for (i=0; i<n; i++) { |
268 | uInt8 db= 1<<(BpB8-lim); |
269 | |
270 | if ((value % 2)==1) *b|= db; |
271 | else *b&= ~db; |
272 | value= value / 2; |
273 | |
274 | lim--; |
275 | if (lim==0) { lim= BpB8; b--; } |
276 | } |
277 | } |
278 | |
279 | |
280 | uInt32 SanPackage::GetBits( void* ptr, int pos, int n ) |
281 | { |
282 | uInt32 value= 0; |
283 | |
284 | byte* b= (byte*)ptr; |
285 | int lim= pos+n; |
286 | if (lim>BpB8*NBits7) return 0; |
287 | while (lim>BpB8) { b++; lim-= BpB8; } |
288 | |
289 | int i; |
290 | for (i=0; i<n; i++) { |
291 | uInt8 db= 1<<(BpB8-lim); |
292 | |
293 | if ((*b & db)!=0) value|= (1<<n); |
294 | value= value / 2; |
295 | |
296 | lim--; |
297 | if (lim==0) { lim= BpB8; b--; } |
298 | } |
299 | |
300 | return value; |
301 | } |
302 | |
303 | |
304 | |
305 | |
306 | void SanPackage::CreateEmptyNotificationBody() |
307 | { |
308 | ReleaseNotificationBody(); |
309 | |
310 | fEmpty= 0x00; |
311 | fBody= &fEmpty; |
312 | fBodySize= sizeof(fEmpty); |
313 | fNSync= 0; |
314 | } |
315 | |
316 | |
317 | |
318 | TSyError SanPackage::AddSync( int syncType, uInt32 contentType, |
319 | const char* serverURI ) |
320 | { |
321 | int len= strlen(serverURI); |
322 | int nLen= BBits4 + 1 + len; |
323 | int newLen= fBodySize + nLen; |
324 | |
325 | void* fb= malloc( newLen ); |
326 | memcpy( fb, fBody,fBodySize ); |
327 | |
328 | byte* b = (byte*)fb; |
329 | b+= fBodySize; |
330 | |
331 | ReleaseNotificationBody(); |
332 | fNSync++; |
333 | fBody = fb; |
334 | fBodySize= newLen; |
335 | |
336 | |
337 | AddBits( fBody, 0, 4, fNSync ); |
338 | AddBits( fBody, 4, 4, 0 ); |
339 | |
340 | |
341 | TBody* tb= (TBody*)b; |
342 | AddBits( tb->bitField, 0, 4, syncType-200 ); |
343 | AddBits( tb->bitField, 4, 4, 0 ); |
344 | AddBits( tb->bitField, 8,24, contentType ); |
345 | tb->serverURI_len= len; |
346 | |
347 | byte* pp= (byte*)(tb+1); |
348 | memcpy( (void*) pp, (void*)serverURI, len ); |
349 | return LOCERR_OK; |
350 | } |
351 | |
352 | |
353 | |
354 | void SanPackage::ReleaseNotificationBody() |
355 | { |
356 | if (fBody!=NULL__null && |
357 | fBody!=&fEmpty) { free( fBody ); fBody= NULL__null; } |
358 | } |
359 | |
360 | |
361 | #ifndef WITHOUT_SAN_1_1 |
362 | |
363 | static Ret_t univ( ... ) |
364 | { |
365 | |
366 | return 0; |
367 | } |
368 | |
369 | |
370 | static Ret_t startM( InstanceID_t id, VoidPtr_t userData, SmlSyncHdrPtr_t pContent ) |
371 | { |
372 | cAppCharP Sy= "SyncML/"; |
373 | size_t n = strlen(Sy); |
374 | |
375 | SanPackage* a= (SanPackage*)userData; |
376 | string mup = ""; |
377 | string nonce= ""; |
378 | |
379 | uInt16 major=0,minor=0; |
380 | |
381 | cAppCharP verP = smlPCDataToCharP(pContent->proto); |
382 | if (strucmp(verP,Sy,n)==0) { |
383 | n+=StrToUShort(verP+n,major); |
384 | if (verP[n]=='.') { |
385 | n++; |
386 | StrToUShort(verP+n,minor); |
387 | } |
388 | } |
389 | |
390 | sInt32 sessionID; |
391 | smlPCDataToLong( pContent->sessionID, sessionID ); |
392 | |
393 | string srvID= smlSrcTargLocURIToCharP(pContent->source); |
394 | |
395 | a->PreparePackage( mup, nonce, 10*major+minor, UI_not_specified, Initiator_Server, sessionID, srvID ); |
396 | a->CreateEmptyNotificationBody(); |
397 | return 0; |
398 | } |
399 | |
400 | |
401 | static Ret_t alertM( InstanceID_t id, VoidPtr_t userData, SmlAlertPtr_t pContent ) |
402 | { |
403 | SanPackage* a= (SanPackage*)userData; |
404 | |
405 | sInt32 syncType; |
406 | smlPCDataToLong( pContent->data, syncType ); |
407 | uInt32 contentType= 0; |
408 | |
409 | SmlItemListPtr_t el= pContent->itemList; |
410 | |
411 | while (true) { |
412 | string locURI= smlSrcTargLocURIToCharP(el->item->source); |
413 | a->AddSync( syncType, contentType, locURI.c_str() ); |
414 | |
415 | if (el->next==NULL__null) break; |
416 | el= el->next; |
417 | } |
418 | |
419 | |
420 | return 0; |
421 | } |
422 | |
423 | |
424 | static Ret_t endM( InstanceID_t id, VoidPtr_t userData, Boolean_t final ) |
425 | { |
426 | |
427 | return 0; |
428 | } |
429 | |
430 | |
431 | |
432 | static const SmlCallbacks_t mySmlCallbacks = { |
433 | |
434 | startM, |
435 | endM, |
436 | |
437 | (smlStartSyncFunc) univ, |
438 | (smlEndSyncFunc) univ, |
439 | #ifdef ATOMIC_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ |
440 | univ, |
441 | univ, |
442 | #endif |
443 | #ifdef SEQUENCE_RECEIVE |
444 | univ, |
445 | univ, |
446 | #endif |
447 | |
448 | (smlAddCmdFunc) univ, |
449 | alertM, |
450 | (smlDeleteCmdFunc)univ, |
451 | (smlGetCmdFunc) univ, |
452 | (smlPutCmdFunc) univ, |
453 | #ifdef MAP_RECEIVE |
454 | (smlMapCmdFunc) univ, |
455 | #endif |
456 | #ifdef RESULT_RECEIVE |
457 | (smlResultsCmdFunc)univ, |
458 | #endif |
459 | (smlStatusCmdFunc) univ, |
460 | (smlReplaceCmdFunc)univ, |
461 | |
462 | #ifdef COPY_RECEIVE /* these callbacks are NOT included in the Toolkit lite version */ |
463 | univ, |
464 | #endif |
465 | #ifdef EXEC_RECEIVE |
466 | univ, |
467 | #endif |
468 | #ifdef SEARCH_RECEIVE |
469 | univ, |
470 | #endif |
471 | smlMoveCmdFunc(univ), |
472 | |
473 | smlHandleErrorFunc (univ), |
474 | smlTransmitChunkFunc(univ) |
475 | }; |
476 | |
477 | |
478 | |
479 | |
480 | |
481 | |
482 | TSyError SanPackage::Check_11( void* san, size_t sanSize ) |
483 | { |
484 | TSyError err; |
485 | SmlCallbacks_t scb= mySmlCallbacks; |
486 | SmlInstanceOptions_t sIOpts; |
487 | InstanceID_t id; |
488 | Ret_t cer; |
489 | MemPtr_t wPos; |
490 | MemSize_t freeSize; |
491 | |
492 | |
493 | sIOpts.encoding = SML_WBXML; |
494 | sIOpts.workspaceSize = 1024*30; |
495 | sIOpts.maxOutgoingSize= 0; |
496 | |
497 | err= smlInitInstance( &scb, &sIOpts, this, &id ); if (err) return err; |
498 | |
499 | do { |
500 | err= smlLockWriteBuffer ( id, &wPos, &freeSize ); if (err) break; |
501 | |
502 | memcpy( wPos, san,sanSize ); |
503 | err= smlUnlockWriteBuffer( id, sanSize ); if (err) break; |
504 | err= smlProcessData ( id, SML_ALL_COMMANDS ); if (err) break; |
505 | } while (false); |
506 | |
507 | cer= smlTerminateInstance( id ); if (!err) err= cer; |
508 | |
509 | return err; |
510 | } |
511 | #endif // WITHOUT_SAN_1_1 |
512 | |
513 | |
514 | TSyError SanPackage::PassSan( void* san, size_t sanSize, int mode) |
515 | { |
516 | TSyError err = LOCERR_OK; |
517 | bool use_as_12= true; |
518 | |
519 | ReleasePackage(); |
520 | |
521 | |
522 | #ifndef WITHOUT_SAN_1_1 |
523 | if (mode == 0 || mode == 1) { |
524 | err= Check_11 ( san,sanSize ); |
525 | if (!err) err= GetPackage( san,sanSize ); |
526 | |
527 | use_as_12= err!=0; |
528 | |
529 | } |
530 | #endif |
531 | |
532 | if (use_as_12 && mode !=1) { |
533 | err= DB_Full420; |
534 | |
535 | fSan= malloc( sanSize ); |
536 | if (fSan) { |
537 | fSanSize= sanSize; |
538 | memcpy( fSan, san,sanSize ); |
539 | err= LOCERR_OK; |
540 | } |
541 | } |
542 | |
543 | return err; |
544 | } |
545 | |
546 | |
547 | TSyError SanPackage::GetSanSize( void* san, size_t &sanSize ) |
548 | { |
549 | TPackage* tp= (TPackage*)san; |
550 | TBody* tb = NULL__null; |
| 1 | 'tb' initialized to a null pointer value | |
|
551 | |
552 | byte* b= (byte*)(tp+1); |
553 | byte* v; |
554 | |
555 | b+= tp->serverID_len; |
556 | |
557 | int nth= GetBits( b, 0,4 ); |
558 | |
559 | b++; |
560 | int n= nth; |
561 | while (n>0) { |
| |
| 3 | | Loop condition is false. Execution continues on line 574 | |
|
562 | n--; |
563 | tb= (TBody*)b; |
564 | b = (byte*)(tb+1); |
565 | |
566 | if (b > (byte*)san+sanSize && sanSize>0) return DB_Forbidden; |
567 | v= b + tb->serverURI_len; |
568 | if (b > (byte*)san+sanSize && sanSize>0) return DB_Forbidden; |
569 | |
570 | if (n==0) break; |
571 | b= v; |
572 | } |
573 | |
574 | b+= tb->serverURI_len; |
| 4 | | Access to field 'serverURI_len' results in a dereference of a null pointer (loaded from variable 'tb') |
|
575 | |
576 | size_t rslt= b - (byte*)san; |
577 | if (sanSize>0 && sanSize<rslt) return DB_Forbidden; |
578 | |
579 | sanSize= rslt; |
580 | return LOCERR_OK; |
581 | } |
582 | |
583 | |
584 | |
585 | TSyError SanPackage::GetNthSync( int nth, |
586 | int &syncType, |
587 | uInt32 &contentType, |
588 | string &serverURI ) |
589 | { |
590 | syncType = 0; |
591 | contentType= 0; |
592 | serverURI = ""; |
593 | |
594 | TPackage* tp= (TPackage*)fSan; |
595 | TBody* tb; |
596 | |
597 | fDigest = tp->digest; |
598 | fProtocolVersion= GetBits( tp->bitField, 0,10 ); |
599 | fUI_Mode = (UI_Mode)GetBits( tp->bitField, 10, 2 ); |
600 | fInitiator = (Initiator)GetBits( tp->bitField, 12, 1 ); |
601 | fSessionID = GetBits( tp->bitField, 40,16 ); |
602 | |
603 | |
604 | if (fProtocolVersion!=SyncML12 && |
605 | fProtocolVersion!=SyncML11 && |
606 | fProtocolVersion!=SyncML10) return DB_Forbidden; |
607 | |
608 | byte* b= (byte*)(tp+1); |
609 | byte* v; |
610 | |
611 | fServerID.assign( (const char*)b,(unsigned int)tp->serverID_len ); |
612 | b+= tp->serverID_len; |
613 | |
614 | fNSync= GetBits( b, 0,4 ); |
615 | |
616 | if (nth==0) return LOCERR_OK; |
617 | if (nth<1 || nth>fNSync ) return DB_NotFound; |
618 | |
619 | b++; |
620 | int n= nth; |
621 | while (n>0) { |
622 | n--; |
623 | tb= (TBody*)b; |
624 | b = (byte*)(tb+1); |
625 | |
626 | if (b > (byte*)fSan+fSanSize) return DB_Forbidden; |
627 | v= b + tb->serverURI_len; |
628 | if (v > (byte*)fSan+fSanSize) return DB_Forbidden; |
629 | |
630 | if (n==0) break; |
631 | b= v; |
632 | } |
633 | |
634 | syncType = 200 + GetBits( tb->bitField, 0, 4 ); |
635 | contentType= GetBits( tb->bitField, 8,24 ); |
636 | |
637 | serverURI.assign( (const char*)b,(unsigned int)tb->serverURI_len ); |
638 | |
639 | return LOCERR_OK; |
640 | } |
641 | |
642 | |
643 | TSyError SanPackage::GetHeader() |
644 | { |
645 | int syncType; |
646 | uInt32 contentType; |
647 | string serverURI; |
648 | |
649 | return GetNthSync( 0, syncType,contentType,serverURI ); |
650 | } |
651 | |
652 | |
653 | |
654 | |
655 | TSyError SanPackage::GetPackage( void* &san, size_t &sanSize, |
656 | void* vendorSpecific, |
657 | size_t vendorSpecificSize ) |
658 | { |
659 | ReleasePackage(); |
660 | |
661 | byte len = (byte)fServerID.length(); |
662 | sanSize= sizeof(TPackage) + len + fBodySize + vendorSpecificSize; |
663 | |
664 | fSan = malloc( sanSize ); |
665 | san = fSan; |
666 | TPackage* tp= (TPackage*)fSan; |
667 | |
668 | |
669 | AddBits( tp->bitField, 0,10, fProtocolVersion ); |
670 | AddBits( tp->bitField, 10, 2, fUI_Mode ); |
671 | AddBits( tp->bitField, 12, 1, fInitiator ); |
672 | AddBits( tp->bitField, 13,27, 0 ); |
673 | AddBits( tp->bitField, 40,16, fSessionID ); |
674 | tp->serverID_len= len; |
675 | |
676 | |
677 | byte* pp= (byte*)(tp+1); |
678 | memcpy( (void*) pp, (void*)fServerID.c_str(), len ); |
679 | memcpy( (void*)(pp+len), fBody, fBodySize ); |
680 | |
681 | if (vendorSpecific!=NULL__null && |
682 | vendorSpecificSize>0) |
683 | memcpy( (void*)(pp+len+fBodySize), vendorSpecific,vendorSpecificSize ); |
684 | |
685 | CreateDigest( fB64_H_srvID_pwd.c_str(), fNonce.c_str(), san,sanSize ); |
686 | tp->digest= fDigest; |
687 | |
688 | fSanSize= sanSize; |
689 | return LOCERR_OK; |
690 | } |
691 | |
692 | |
693 | void SanPackage::ReleasePackage() { |
694 | if (fSan!=NULL__null) { free( fSan ); fSan= NULL__null; } |
695 | } |
696 | |
697 | #ifndef WITHOUT_SAN_1_1 |
698 | |
699 | const char * const SyncMLVerProtoNames[] = |
700 | { |
701 | "undefined", |
702 | "SyncML/1.0", |
703 | "SyncML/1.1", |
704 | "SyncML/1.2" |
705 | }; |
706 | |
707 | const char *const SyncMLVerDTDNames[] = |
708 | { |
709 | "???", |
710 | "1.0", |
711 | "1.1", |
712 | "1.2" |
713 | }; |
714 | |
715 | const SmlVersion_t SmlVersionCodes[] = |
716 | { |
717 | SML_VERS_UNDEF, |
718 | SML_VERS_1_0, |
719 | SML_VERS_1_1, |
720 | SML_VERS_1_1 |
721 | }; |
722 | |
723 | TSyError SanPackage::GetPackageLegacy( void* &san, |
724 | size_t &sanSize, |
725 | const vector<pair <string, string> >& sources, |
726 | int alertCode, |
727 | bool wbxml) |
728 | { |
729 | ReleasePackage(); |
730 | TSyError err; |
731 | SmlCallbacks_t scb= mySmlCallbacks; |
732 | SmlInstanceOptions_t sIOpts; |
733 | InstanceID_t id; |
734 | |
735 | |
736 | |
737 | sIOpts.encoding = wbxml ? SML_WBXML : SML_XML; |
738 | sIOpts.workspaceSize = 1024; |
739 | sIOpts.maxOutgoingSize= 0; |
740 | |
741 | err= smlInitInstance( &scb, &sIOpts, this, &id ); if (err) return err; |
742 | |
743 | SmlSyncHdrPtr_t headerP = NULL__null; |
744 | SmlAlertPtr_t alertP = NULL__null; |
745 | |
746 | do { |
747 | SYSYNC_TRYtry{ |
748 | |
749 | headerP = SML_NEW (SmlSyncHdr_t)((SmlSyncHdr_t*) _smlMalloc(sizeof(SmlSyncHdr_t))); |
750 | headerP->elementType = SML_PE_HEADER; |
751 | if (fProtocolVersion != 10 && fProtocolVersion != 11){ |
752 | |
753 | err = DB_Error510; |
754 | break; |
755 | } |
756 | int version = fProtocolVersion - 10 + 1; |
757 | headerP->version = newPCDataString (SyncMLVerDTDNames[version]); |
758 | headerP->proto = newPCDataString (SyncMLVerProtoNames[version]); |
759 | headerP->sessionID = newPCDataLong (fSessionID); |
760 | headerP->msgID = newPCDataString ("1"); |
761 | headerP->target = newLocation ("/", ""); |
762 | headerP->source = newLocation (fServerID.c_str(), ""); |
763 | headerP->respURI = NULL__null; |
764 | headerP->meta = NULL__null; |
765 | headerP->flags = 0; |
766 | |
767 | headerP->cred = NULL__null; |
768 | |
769 | |
770 | err = smlStartMessageExt (id, headerP, SmlVersionCodes[version]); if (err) break; |
771 | |
772 | |
773 | alertP = SML_NEW (SmlAlert_t)((SmlAlert_t*) _smlMalloc(sizeof(SmlAlert_t))); |
774 | alertP->elementType = SML_PE_ALERT; |
775 | alertP->cmdID = newPCDataLong(1); |
776 | alertP->flags = 0; |
777 | alertP->data = newPCDataLong (alertCode); |
778 | alertP->cred = NULL__null; |
779 | alertP->itemList = NULL__null; |
780 | alertP->flags = 0; |
781 | |
782 | |
783 | for (unsigned int num =0; num < sources.size(); num++) { |
784 | SmlItemPtr_t alertItemP = newItem(); |
785 | alertItemP->source = newOptLocation (sources[num].second.c_str()); |
786 | alertItemP->meta = newMetaType (sources[num].first.c_str()); |
787 | addItemToList (alertItemP, &alertP->itemList); |
788 | } |
789 | |
790 | err = smlAlertCmd (id, alertP); if (err) break; |
791 | err = smlEndMessage (id, true); if (err) break; |
792 | |
793 | MemPtr_t buf = NULL__null; |
794 | err = smlLockReadBuffer (id, (MemPtr_t *) &buf, (MemSize_t *)&sanSize); if (err) break; |
795 | fSan = malloc( sanSize ); if (!fSan) {err = DB_Full420; break;} |
796 | san = fSan; |
797 | memcpy (san, buf, sanSize); |
798 | err = smlUnlockReadBuffer (id, sanSize); if (err) break; |
799 | } SYSYNC_CATCH (...)catch(...) { |
800 | if (headerP) { |
801 | smlFreeProtoElement (headerP); |
802 | headerP = NULL__null; |
803 | } |
804 | if (alertP) { |
805 | smlFreeProtoElement (alertP); |
806 | alertP = NULL__null; |
807 | } |
808 | err = DB_Full420; |
809 | SYSYNC_ENDCATCH} |
810 | } while (false); |
811 | if (headerP) { |
812 | smlFreeProtoElement (headerP); |
813 | } |
814 | if (alertP) { |
815 | smlFreeProtoElement (alertP); |
816 | } |
817 | if (err) return err; |
818 | |
819 | err = smlTerminateInstance( id ); |
820 | return err; |
821 | } |
822 | #endif |
823 | |
824 | } |
825 | |
826 | |