1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*==================================================================================================
18
19    Source Name: dmt.cc
20
21    General Description: Implementation of DmtTreeFactory class.
22
23==================================================================================================*/
24
25#include "dmt.hpp"
26#include "dmtTreeImpl.hpp"
27#include "dm_tree_class.H"
28#include "dmSessionFactory.h"
29#include "xpl_Logger.h"
30#include "dmNotification.h"
31#include "dmprofile.h"
32#include "dmLockingHelper.h"
33
34//------------------------------------------------------------------------
35//            Source Name: dmt.cpp
36//  General Description: This file contains External API for DMTree C++ API
37//------------------------------------------------------------------------
38
39BOOLTYPE DmtTreeFactory::Initialize()
40{
41
42  DM_PERFORMANCE(DM_INITIALIZE_ENTER);
43
44   BOOLTYPE dm_stat = true;
45  if ( dmTreeObj.Init() == SYNCML_DM_SUCCESS )
46      dm_stat = true;
47  else
48      dm_stat = false;
49
50  DM_PERFORMANCE(DM_INITIALIZE_EXIT);
51  return dm_stat;
52}
53
54
55
56SYNCML_DM_RET_STATUS_T DmtTreeFactory::Uninitialize()
57{
58   DM_PERFORMANCE(DM_UNINITIALIZE_ENTER);
59   SYNCML_DM_RET_STATUS_T dm_stat = dmTreeObj.DeInit(FALSE);
60   DM_PERFORMANCE(DM_UNINITIALIZE_EXIT);
61   return dm_stat;
62}
63
64SYNCML_DM_RET_STATUS_T DmtTreeFactory::GetTree(
65      const DmtPrincipal& principal,
66      PDmtTree& ptrTree
67   )
68{
69  return GetSubtree( principal, NULL, ptrTree );
70}
71
72
73SYNCML_DM_RET_STATUS_T DmtTreeFactory::GetSubtree(
74      const DmtPrincipal& principal,
75      CPCHAR szSubtreeRoot,
76      PDmtTree& ptrTree
77   )
78{
79  return GetSubtreeEx( principal, szSubtreeRoot, SYNCML_DM_LOCK_TYPE_AUTOMATIC, ptrTree );
80}
81
82SYNCML_DM_RET_STATUS_T DmtTreeFactory::GetSubtreeEx(
83      const DmtPrincipal& principal,
84      CPCHAR szSubtreeRoot,
85      SYNCML_DM_TREE_LOCK_TYPE_T nLockType,
86      PDmtTree& ptrTree
87   )
88{
89  DM_PERFORMANCE(DM_GET_TREE_ENTER);
90
91  ptrTree = NULL;
92
93  if ( !dmTreeObj.IsInitialized() ) {
94    return SYNCML_DM_FAIL;
95  }
96
97  XPL_LOG_DM_API_Debug(("GetSubtreeEx  path=%s, nLockType=%dn", szSubtreeRoot, nLockType));
98
99#ifdef DM_NO_LOCKING
100  if ( IsLocked() )
101    return SYNCML_DM_SESSION_BUSY;
102#endif
103
104  PDmtTree ptrNewTree;
105
106  DmtTreeImpl* pNewTree = new DmtTreeImpl;
107  ptrNewTree = pNewTree;
108
109  if ( !pNewTree )
110    return SYNCML_DM_DEVICE_FULL;
111
112  SYNCML_DM_RET_STATUS_T ret_status = pNewTree->StartSession( principal, szSubtreeRoot, nLockType );
113
114  if ( ret_status == SYNCML_DM_SUCCESS )
115  {
116      ptrTree = ptrNewTree;
117#ifdef DM_NO_LOCKING
118      // dmTreeObj.GetLockContextManager().Lock();
119#endif
120  }
121
122  DM_PERFORMANCE(DM_GET_TREE_EXIT);
123
124  return ret_status;
125}
126
127SYNCML_DM_RET_STATUS_T DmtTreeFactory::ProcessScript(const DmtPrincipal& principal,
128                                                    const UINT8 * buf,
129                                                    INT32 len,
130                                                    BOOLEAN isWBXML,
131                                                    DMString& oResult)
132{
133
134  if ( !dmTreeObj.IsInitialized() )
135    return SYNCML_DM_FAIL;
136
137  if ( !buf || len <= 0 )
138    return SYNCML_DM_INVALID_PARAMETER;
139
140#ifdef DM_NO_LOCKING
141  if ( IsLocked() )
142     return SYNCML_DM_SESSION_BUSY;
143#endif
144
145
146  DMGlobalOMAWorkspaceSharing  oOMAWorkspaceLock;  // global lock for OMA workspace
147
148
149  SYNCML_DM_RET_STATUS_T ret_status;
150
151  XPL_FS_HANDLE_T hLockFile;
152  XPL_FS_RET_STATUS_T xpl_status;
153
154  hLockFile = XPL_FS_Open(DM_ISP_LOCK, XPL_FS_FILE_WRITE, &xpl_status);
155
156  INT32 nLock = 0;
157
158  {
159    DMLockingHelper oLock( 0, ".", principal.getName().c_str(), SYNCML_DM_LOCK_TYPE_EXCLUSIVE, FALSE );
160    nLock = oLock.GetID();
161
162      if ( !oLock.IsLockedSuccessfully() ){
163        return oLock.GetError();
164      }
165
166
167    DMBuffer oResultDoc;
168
169    ret_status = DmProcessScriptData( buf ,(UINT32)len, isWBXML, oResultDoc);
170
171    if( ret_status == SYNCML_DM_SUCCESS )
172       oResultDoc.copyTo(oResult);
173  }
174
175  dmTreeObj.ReleaseLock( nLock );
176
177  XPL_FS_Remove(DM_ISP_LOCK);
178
179  return ret_status;
180}
181
182
183SYNCML_DM_RET_STATUS_T DmtTreeFactory::ProcessScript(const DmtPrincipal& principal,
184                                                    const UINT8 * buf,
185                                                    INT32 len,
186                                                    BOOLEAN isWBXML,
187                                                    DMVector<UINT8> & oResult)
188{
189
190  if ( !dmTreeObj.IsInitialized() )
191    return SYNCML_DM_FAIL;
192
193  if ( !buf || len <= 0 )
194    return SYNCML_DM_INVALID_PARAMETER;
195
196#ifdef DM_NO_LOCKING
197  if ( IsLocked() )
198     return SYNCML_DM_SESSION_BUSY;
199#endif
200
201
202  DMGlobalOMAWorkspaceSharing  oOMAWorkspaceLock;  // global lock for OMA workspace
203
204  XPL_FS_HANDLE_T hLockFile;
205  XPL_FS_RET_STATUS_T xpl_status;
206  hLockFile = XPL_FS_Open(DM_ISP_LOCK, XPL_FS_FILE_WRITE, &xpl_status);
207
208
209  INT32 nLock = 0;
210  SYNCML_DM_RET_STATUS_T ret_status;
211  {
212    DMLockingHelper oLock( 0, ".", principal.getName().c_str(), SYNCML_DM_LOCK_TYPE_EXCLUSIVE, FALSE );
213    nLock = oLock.GetID();
214
215      if ( !oLock.IsLockedSuccessfully() ){
216        return oLock.GetError();
217      }
218
219
220    DMBuffer oResultDoc;
221
222    ret_status = DmProcessScriptData( buf ,(UINT32)len, isWBXML, oResultDoc);
223
224    XPL_LOG_DM_SESS_Debug(("DmtTreeFactory::ProcessScript before release lock, ret_status=%d, result-size=%d\n", ret_status, oResultDoc.getSize()));
225
226    if( ret_status == SYNCML_DM_SUCCESS ) {
227
228      oResult.set_size(oResultDoc.getSize());
229
230      memcpy(oResult.get_data(), oResultDoc.getBuffer(), oResultDoc.getSize());
231    }
232
233    if (oResultDoc.getSize() > 0 ) {
234         char *szResult = new char[oResultDoc.getSize()+1];
235         memcpy(szResult, oResultDoc.getBuffer(), oResultDoc.getSize());
236         szResult[oResultDoc.getSize()] = 0;
237         XPL_LOG_DM_SESS_Debug(("DmtTreeFactory::ProcessScript szResult=%s\n", szResult));
238         delete [] szResult;
239    }
240
241  }
242
243
244
245
246  dmTreeObj.ReleaseLock( nLock );
247
248  XPL_FS_Remove(DM_ISP_LOCK);
249
250  return ret_status;
251}
252
253
254SYNCML_DM_RET_STATUS_T DmtTreeFactory::Bootstrap(const DmtPrincipal& principal,
255                                                   const UINT8 * buf,
256                                                   INT32 len,
257                                                   BOOLEAN isWBXML,
258                                                   BOOLEAN isProcess,
259                                                   DMString & serverID)
260{
261
262    if ( !dmTreeObj.IsInitialized() )
263        return SYNCML_DM_FAIL;
264
265    if ( !buf || len <= 0 )
266        return SYNCML_DM_INVALID_PARAMETER;
267
268#ifdef DM_NO_LOCKING
269    if ( IsLocked() )
270        return SYNCML_DM_SESSION_BUSY;
271#endif
272
273
274    DMGlobalOMAWorkspaceSharing  oOMAWorkspaceLock;  // global lock for OMA workspace
275
276
277    INT32 nLock = 0;
278    SYNCML_DM_RET_STATUS_T ret_status;
279    {
280        DMLockingHelper oLock( 0, ".", principal.getName().c_str(), SYNCML_DM_LOCK_TYPE_EXCLUSIVE, FALSE );
281        nLock = oLock.GetID();
282
283        if ( !oLock.IsLockedSuccessfully() )
284            return oLock.GetError();
285
286        ret_status = DmBootstrap( buf ,(UINT32)len, isWBXML, isProcess, serverID);
287  }
288
289  dmTreeObj.ReleaseLock( nLock );
290
291  return ret_status;
292}
293
294
295
296/**
297* Starts server session based on principal information
298*/
299SYNCML_DM_RET_STATUS_T DmtTreeFactory::StartServerSession( const DmtPrincipal& principal,
300                                                          const DmtSessionProp& sessionProp)
301{
302
303  if ( !dmTreeObj.IsInitialized() )
304    return SYNCML_DM_FAIL;
305
306#ifdef DM_NO_LOCKING
307  if ( IsLocked() ) {
308    XPL_LOG_DM_SESS_Error(("StartServerSession locked\n"));
309    //return SYNCML_DM_SESSION_BUSY;
310  }
311#endif
312
313
314  DMGlobalOMAWorkspaceSharing  oOMAWorkspaceLock;  // global lock for OMA workspace
315
316  XPL_LOG_DM_SESS_Debug(("Opening session lock file\n"));
317
318  XPL_FS_HANDLE_T hLockFile;
319  XPL_FS_RET_STATUS_T xpl_status;
320  hLockFile = XPL_FS_Open(DM_ISP_LOCK, XPL_FS_FILE_WRITE, &xpl_status);
321
322  SYNCML_DM_RET_STATUS_T ret_status;
323  INT32 nLock = 0;
324  {
325      DMLockingHelper oLock( 0, ".", principal.getName().c_str(), SYNCML_DM_LOCK_TYPE_EXCLUSIVE, FALSE );
326      nLock = oLock.GetID();
327
328      if ( !oLock.IsLockedSuccessfully() ) {
329    XPL_LOG_DM_SESS_Error(("Opening session lock file failed reason=%d\n", oLock.GetError()));
330        return oLock.GetError();
331      }
332  }
333
334
335#ifndef DM_NO_LOCKING
336  dmTreeObj.ReleaseLock( nLock );
337#endif
338
339  ret_status = DmProcessServerData(principal.getName().c_str(), sessionProp);
340#ifdef DM_NO_LOCKING
341  dmTreeObj.ReleaseLock( nLock );
342#endif
343
344  XPL_FS_Remove(DM_ISP_LOCK);
345
346  DM_MEMORY_STATISTICS_WRITE("ServerSession done\n");
347  XPL_LOG_DM_SESS_Debug(("Returning from StartServerSession status=%d\n", ret_status));
348
349  return ret_status;
350}
351
352
353SYNCML_DM_RET_STATUS_T DmtTreeFactory::ProcessNotification(
354  const DmtPrincipal& principal,
355  const UINT8 *buf,
356  INT32 len,
357  DmtNotification & notification)
358{
359
360  if ( !dmTreeObj.IsInitialized() )
361    return SYNCML_DM_FAIL;
362
363#ifdef DM_NO_LOCKING
364  if ( IsLocked() )
365    return SYNCML_DM_SESSION_BUSY;
366#endif
367
368
369  SYNCML_DM_RET_STATUS_T ret_status;
370  INT32 nLock = 0;
371    {
372      DMLockingHelper oLock( 0, ".", principal.getName().c_str(), SYNCML_DM_LOCK_TYPE_EXCLUSIVE, FALSE );
373      nLock = oLock.GetID();
374
375      if ( !oLock.IsLockedSuccessfully() )
376        return oLock.GetError();
377
378    }
379
380  ret_status = DmProcessNotification((const UINT8*)buf,len,notification);
381
382  dmTreeObj.ReleaseLock( nLock );
383
384  return ret_status;
385}
386
387
388BOOLEAN DmtTreeFactory::IsLocked()
389{
390#ifdef DM_NO_LOCKING
391    BOOLEAN result = dmTreeObj.GetLockContextManager().IsLocked();
392    XPL_LOG_DM_SESS_Debug(("isLocked()  returning=%d\n", result));
393    return result;
394#else
395    XPL_LOG_DM_SESS_Debug(("isLocked()  returning false\n"));
396    return FALSE;
397#endif
398}
399
400
401BOOLEAN DmtTreeFactory::IsSessionInProgress()
402{
403    return XPL_FS_Exist(DM_ISP_LOCK);
404}
405
406
407SYNCML_DM_RET_STATUS_T
408DmtTreeFactory::SubscribeEvent(CPCHAR szPath,
409                               const DmtEventSubscription & oEvent)
410{
411
412     if ( !dmTreeObj.IsInitialized() )
413        return SYNCML_DM_FAIL;
414
415     if ( !szPath )
416        return SYNCML_DM_INVALID_PARAMETER;
417
418
419     INT32 nLockID = 0;
420     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
421     {
422        DMLockingHelper oLock( 0, ".", "localhost", SYNCML_DM_LOCK_TYPE_EXCLUSIVE, FALSE );
423        nLockID = oLock.GetID();
424
425        if ( !oLock.IsLockedSuccessfully() )
426            return SYNCML_DM_FAIL;
427
428        DMSubscriptionManager & oEventManager =  dmTreeObj.GetSubscriptionManager();
429
430        dm_stat = oEventManager.EnableEvent(szPath, oEvent);
431    }
432
433     dmTreeObj.ReleaseLock( nLockID );
434
435     return dm_stat;
436
437}
438
439
440SYNCML_DM_RET_STATUS_T
441DmtTreeFactory::UnSubscribeEvent(CPCHAR szPath)
442{
443     if ( !dmTreeObj.IsInitialized() )
444        return SYNCML_DM_FAIL;
445
446     if ( !szPath )
447        return SYNCML_DM_INVALID_PARAMETER;
448
449     INT32 nLockID = 0;
450     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
451     {
452        DMLockingHelper oLock( 0, ".", "localhost", SYNCML_DM_LOCK_TYPE_EXCLUSIVE, FALSE );
453        nLockID = oLock.GetID();
454
455        if ( !oLock.IsLockedSuccessfully() )
456            return SYNCML_DM_FAIL;
457
458        DMSubscriptionManager & oEventManager =  dmTreeObj.GetSubscriptionManager();
459
460        dm_stat = oEventManager.Delete(szPath);
461    }
462
463    dmTreeObj.ReleaseLock( nLockID );
464
465    return dm_stat;
466
467
468}
469
470SYNCML_DM_RET_STATUS_T
471DmtTreeFactory::GetEventSubscription(CPCHAR szPath,
472                                    DmtEventSubscription & oEvent)
473{
474     if ( !dmTreeObj.IsInitialized() )
475        return SYNCML_DM_FAIL;
476
477     if ( !szPath )
478        return SYNCML_DM_INVALID_PARAMETER;
479
480     INT32 nLockID = 0;
481     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
482     {
483        DMLockingHelper oLock( 0, ".", "localhost", SYNCML_DM_LOCK_TYPE_EXCLUSIVE, FALSE );
484        nLockID = oLock.GetID();
485
486        if ( !oLock.IsLockedSuccessfully() )
487            return SYNCML_DM_FAIL;
488
489        DMSubscriptionManager & oEventManager =  dmTreeObj.GetSubscriptionManager();
490
491        dm_stat = oEventManager.GetEvent(szPath, oEvent);
492
493    }
494    dmTreeObj.ReleaseLock( nLockID );
495
496    return dm_stat;
497
498}
499
500
501SYNCML_DM_RET_STATUS_T
502DmtTreeFactory::ParseUpdateEvent(UINT8 * pBuffer,
503                                UINT32 size,
504                                DmtEventMap & aEventMap)
505{
506    if ( pBuffer == NULL || size == 0 )
507        return SYNCML_DM_INVALID_PARAMETER;
508
509    SYNCML_DM_RET_STATUS_T dm_stat  = SYNCML_DM_SUCCESS;
510
511    DMBufferReader oBuffer(pBuffer,size);
512    dm_stat = DMEventLogger::Deserialize(oBuffer,aEventMap);
513
514    return dm_stat;
515
516}
517
518
519
520
521void*  DmtMemAllocEx( size_t nSize, CPCHAR szFile, INT32 nLine )
522{
523  return DmAllocMemEx( nSize, szFile,  nLine );
524}
525
526void   DmtMemFree( void* p )
527{
528  DmFreeMem( p );
529}
530