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 39 BOOLTYPE 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 56 SYNCML_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 64 SYNCML_DM_RET_STATUS_T DmtTreeFactory::GetTree( 65 const DmtPrincipal& principal, 66 PDmtTree& ptrTree 67 ) 68 { 69 return GetSubtree( principal, NULL, ptrTree ); 70 } 71 72 73 SYNCML_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 82 SYNCML_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 127 SYNCML_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 183 SYNCML_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 254 SYNCML_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 */ 299 SYNCML_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 353 SYNCML_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 388 BOOLEAN 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 401 BOOLEAN DmtTreeFactory::IsSessionInProgress() 402 { 403 return XPL_FS_Exist(DM_ISP_LOCK); 404 } 405 406 407 SYNCML_DM_RET_STATUS_T 408 DmtTreeFactory::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 440 SYNCML_DM_RET_STATUS_T 441 DmtTreeFactory::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 470 SYNCML_DM_RET_STATUS_T 471 DmtTreeFactory::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 501 SYNCML_DM_RET_STATUS_T 502 DmtTreeFactory::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 521 void* DmtMemAllocEx( size_t nSize, CPCHAR szFile, INT32 nLine ) 522 { 523 return DmAllocMemEx( nSize, szFile, nLine ); 524 } 525 526 void DmtMemFree( void* p ) 527 { 528 DmFreeMem( p ); 529 } 530