• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ability_sync.h"
17 
18 #include "message_transform.h"
19 #include "version.h"
20 #include "db_errno.h"
21 #include "log_print.h"
22 #include "sync_types.h"
23 #include "db_common.h"
24 #include "single_ver_kvdb_sync_interface.h"
25 #include "single_ver_sync_task_context.h"
26 #include "single_ver_kv_sync_task_context.h"
27 #ifdef RELATIONAL_STORE
28 #include "relational_db_sync_interface.h"
29 #include "single_ver_relational_sync_task_context.h"
30 #endif
31 
32 namespace DistributedDB {
AbilitySyncRequestPacket()33 AbilitySyncRequestPacket::AbilitySyncRequestPacket()
34     : protocolVersion_(ABILITY_SYNC_VERSION_V1),
35       sendCode_(E_OK),
36       softwareVersion_(SOFTWARE_VERSION_CURRENT),
37       secLabel_(0),
38       secFlag_(0),
39       schemaType_(0),
40       dbCreateTime_(0),
41       schemaVersion_(0)
42 {
43 }
44 
~AbilitySyncRequestPacket()45 AbilitySyncRequestPacket::~AbilitySyncRequestPacket()
46 {
47 }
48 
SetProtocolVersion(uint32_t protocolVersion)49 void AbilitySyncRequestPacket::SetProtocolVersion(uint32_t protocolVersion)
50 {
51     protocolVersion_ = protocolVersion;
52 }
53 
GetProtocolVersion() const54 uint32_t AbilitySyncRequestPacket::GetProtocolVersion() const
55 {
56     return protocolVersion_;
57 }
58 
SetSendCode(int32_t sendCode)59 void AbilitySyncRequestPacket::SetSendCode(int32_t sendCode)
60 {
61     sendCode_ = sendCode;
62 }
63 
GetSendCode() const64 int32_t AbilitySyncRequestPacket::GetSendCode() const
65 {
66     return sendCode_;
67 }
68 
SetSoftwareVersion(uint32_t swVersion)69 void AbilitySyncRequestPacket::SetSoftwareVersion(uint32_t swVersion)
70 {
71     softwareVersion_ = swVersion;
72 }
73 
GetSoftwareVersion() const74 uint32_t AbilitySyncRequestPacket::GetSoftwareVersion() const
75 {
76     return softwareVersion_;
77 }
78 
SetSchema(const std::string & schema)79 void AbilitySyncRequestPacket::SetSchema(const std::string &schema)
80 {
81     schema_ = schema;
82 }
83 
GetSchema() const84 std::string AbilitySyncRequestPacket::GetSchema() const
85 {
86     return schema_;
87 }
88 
SetSchemaType(uint32_t schemaType)89 void AbilitySyncRequestPacket::SetSchemaType(uint32_t schemaType)
90 {
91     schemaType_ = schemaType;
92 }
93 
GetSchemaType() const94 uint32_t AbilitySyncRequestPacket::GetSchemaType() const
95 {
96     return schemaType_;
97 }
98 
SetSecLabel(int32_t secLabel)99 void AbilitySyncRequestPacket::SetSecLabel(int32_t secLabel)
100 {
101     secLabel_ = secLabel;
102 }
103 
GetSecLabel() const104 int32_t AbilitySyncRequestPacket::GetSecLabel() const
105 {
106     return secLabel_;
107 }
108 
SetSecFlag(int32_t secFlag)109 void AbilitySyncRequestPacket::SetSecFlag(int32_t secFlag)
110 {
111     secFlag_ = secFlag;
112 }
113 
GetSecFlag() const114 int32_t AbilitySyncRequestPacket::GetSecFlag() const
115 {
116     return secFlag_;
117 }
118 
SetDbCreateTime(uint64_t dbCreateTime)119 void AbilitySyncRequestPacket::SetDbCreateTime(uint64_t dbCreateTime)
120 {
121     dbCreateTime_ = dbCreateTime;
122 }
123 
GetDbCreateTime() const124 uint64_t AbilitySyncRequestPacket::GetDbCreateTime() const
125 {
126     return dbCreateTime_;
127 }
128 
CalculateLen() const129 uint32_t AbilitySyncRequestPacket::CalculateLen() const
130 {
131     uint64_t len = 0;
132     len += Parcel::GetUInt32Len(); // protocolVersion_
133     len += Parcel::GetIntLen(); // sendCode_
134     len += Parcel::GetUInt32Len(); // softwareVersion_
135     uint32_t schemaLen = Parcel::GetStringLen(schema_);
136     if (schemaLen == 0) {
137         LOGE("[AbilitySyncRequestPacket][CalculateLen] schemaLen err!");
138         return 0;
139     }
140     len += schemaLen;
141     len += Parcel::GetIntLen(); // secLabel_
142     len += Parcel::GetIntLen(); // secFlag_
143     len += Parcel::GetUInt32Len(); // schemaType_
144     len += Parcel::GetUInt64Len(); // dbCreateTime_
145     len += DbAbility::CalculateLen(dbAbility_); // dbAbility_
146     len += Parcel::GetUInt64Len(); // schema version add in 109
147     // the reason why not 8-byte align is that old version is not 8-byte align
148     // so it is not possible to set 8-byte align for high version.
149     if (len > INT32_MAX) {
150         LOGE("[AbilitySyncRequestPacket][CalculateLen] err len:%" PRIu64, len);
151         return 0;
152     }
153     return len;
154 }
155 
GetDbAbility() const156 DbAbility AbilitySyncRequestPacket::GetDbAbility() const
157 {
158     return dbAbility_;
159 }
160 
SetDbAbility(const DbAbility & dbAbility)161 void AbilitySyncRequestPacket::SetDbAbility(const DbAbility &dbAbility)
162 {
163     dbAbility_ = dbAbility;
164 }
165 
SetSchemaVersion(uint64_t schemaVersion)166 void AbilitySyncRequestPacket::SetSchemaVersion(uint64_t schemaVersion)
167 {
168     schemaVersion_ = schemaVersion;
169 }
170 
GetSchemaVersion() const171 uint64_t AbilitySyncRequestPacket::GetSchemaVersion() const
172 {
173     return schemaVersion_;
174 }
175 
AbilitySyncAckPacket()176 AbilitySyncAckPacket::AbilitySyncAckPacket()
177     : protocolVersion_(ABILITY_SYNC_VERSION_V1),
178       softwareVersion_(SOFTWARE_VERSION_CURRENT),
179       ackCode_(E_OK),
180       secLabel_(0),
181       secFlag_(0),
182       schemaType_(0),
183       permitSync_(0),
184       requirePeerConvert_(0),
185       dbCreateTime_(0),
186       schemaVersion_(0)
187 {
188 }
189 
~AbilitySyncAckPacket()190 AbilitySyncAckPacket::~AbilitySyncAckPacket()
191 {
192 }
193 
SetProtocolVersion(uint32_t protocolVersion)194 void AbilitySyncAckPacket::SetProtocolVersion(uint32_t protocolVersion)
195 {
196     protocolVersion_ = protocolVersion;
197 }
198 
SetSoftwareVersion(uint32_t swVersion)199 void AbilitySyncAckPacket::SetSoftwareVersion(uint32_t swVersion)
200 {
201     softwareVersion_ = swVersion;
202 }
203 
GetSoftwareVersion() const204 uint32_t AbilitySyncAckPacket::GetSoftwareVersion() const
205 {
206     return softwareVersion_;
207 }
208 
GetProtocolVersion() const209 uint32_t AbilitySyncAckPacket::GetProtocolVersion() const
210 {
211     return protocolVersion_;
212 }
213 
SetAckCode(int32_t ackCode)214 void AbilitySyncAckPacket::SetAckCode(int32_t ackCode)
215 {
216     ackCode_ = ackCode;
217 }
218 
GetAckCode() const219 int32_t AbilitySyncAckPacket::GetAckCode() const
220 {
221     return ackCode_;
222 }
223 
SetSchema(const std::string & schema)224 void AbilitySyncAckPacket::SetSchema(const std::string &schema)
225 {
226     schema_ = schema;
227 }
228 
GetSchema() const229 std::string AbilitySyncAckPacket::GetSchema() const
230 {
231     return schema_;
232 }
233 
SetSchemaType(uint32_t schemaType)234 void AbilitySyncAckPacket::SetSchemaType(uint32_t schemaType)
235 {
236     schemaType_ = schemaType;
237 }
238 
GetSchemaType() const239 uint32_t AbilitySyncAckPacket::GetSchemaType() const
240 {
241     return schemaType_;
242 }
243 
SetSecLabel(int32_t secLabel)244 void AbilitySyncAckPacket::SetSecLabel(int32_t secLabel)
245 {
246     secLabel_ = secLabel;
247 }
248 
GetSecLabel() const249 int32_t AbilitySyncAckPacket::GetSecLabel() const
250 {
251     return secLabel_;
252 }
253 
SetSecFlag(int32_t secFlag)254 void AbilitySyncAckPacket::SetSecFlag(int32_t secFlag)
255 {
256     secFlag_ = secFlag;
257 }
258 
GetSecFlag() const259 int32_t AbilitySyncAckPacket::GetSecFlag() const
260 {
261     return secFlag_;
262 }
263 
SetPermitSync(uint32_t permitSync)264 void AbilitySyncAckPacket::SetPermitSync(uint32_t permitSync)
265 {
266     permitSync_ = permitSync;
267 }
268 
GetPermitSync() const269 uint32_t AbilitySyncAckPacket::GetPermitSync() const
270 {
271     return permitSync_;
272 }
273 
SetRequirePeerConvert(uint32_t requirePeerConvert)274 void AbilitySyncAckPacket::SetRequirePeerConvert(uint32_t requirePeerConvert)
275 {
276     requirePeerConvert_ = requirePeerConvert;
277 }
278 
GetRequirePeerConvert() const279 uint32_t AbilitySyncAckPacket::GetRequirePeerConvert() const
280 {
281     return requirePeerConvert_;
282 }
283 
SetDbCreateTime(uint64_t dbCreateTime)284 void AbilitySyncAckPacket::SetDbCreateTime(uint64_t dbCreateTime)
285 {
286     dbCreateTime_ = dbCreateTime;
287 }
288 
GetDbCreateTime() const289 uint64_t AbilitySyncAckPacket::GetDbCreateTime() const
290 {
291     return dbCreateTime_;
292 }
293 
GetSchemaVersion() const294 uint64_t AbilitySyncAckPacket::GetSchemaVersion() const
295 {
296     return schemaVersion_;
297 }
298 
SetSchemaVersion(uint64_t schemaVersion)299 void AbilitySyncAckPacket::SetSchemaVersion(uint64_t schemaVersion)
300 {
301     schemaVersion_ = schemaVersion;
302 }
303 
CalculateLen() const304 uint32_t AbilitySyncAckPacket::CalculateLen() const
305 {
306     uint64_t len = 0;
307     len += Parcel::GetUInt32Len();
308     len += Parcel::GetUInt32Len();
309     len += Parcel::GetIntLen();
310     uint32_t schemaLen = Parcel::GetStringLen(schema_);
311     if (schemaLen == 0) {
312         LOGE("[AbilitySyncAckPacket][CalculateLen] schemaLen err!");
313         return 0;
314     }
315     len += schemaLen;
316     len += Parcel::GetIntLen(); // secLabel_
317     len += Parcel::GetIntLen(); // secFlag_
318     len += Parcel::GetUInt32Len(); // schemaType_
319     len += Parcel::GetUInt32Len(); // permitSync_
320     len += Parcel::GetUInt32Len(); // requirePeerConvert_
321     len += Parcel::GetUInt64Len(); // dbCreateTime_
322     len += DbAbility::CalculateLen(dbAbility_); // dbAbility_
323     len += SchemaNegotiate::CalculateParcelLen(relationalSyncOpinion_);
324     len += Parcel::GetUInt64Len(); // schemaVersion_
325     if (len > INT32_MAX) {
326         LOGE("[AbilitySyncAckPacket][CalculateLen] err len:%" PRIu64, len);
327         return 0;
328     }
329     return len;
330 }
331 
GetDbAbility() const332 DbAbility AbilitySyncAckPacket::GetDbAbility() const
333 {
334     return dbAbility_;
335 }
336 
SetDbAbility(const DbAbility & dbAbility)337 void AbilitySyncAckPacket::SetDbAbility(const DbAbility &dbAbility)
338 {
339     dbAbility_ = dbAbility;
340 }
341 
SetRelationalSyncOpinion(const RelationalSyncOpinion & relationalSyncOpinion)342 void AbilitySyncAckPacket::SetRelationalSyncOpinion(const RelationalSyncOpinion &relationalSyncOpinion)
343 {
344     relationalSyncOpinion_ = relationalSyncOpinion;
345 }
346 
GetRelationalSyncOpinion() const347 RelationalSyncOpinion AbilitySyncAckPacket::GetRelationalSyncOpinion() const
348 {
349     return relationalSyncOpinion_;
350 }
351 
AbilitySync()352 AbilitySync::AbilitySync()
353     : communicator_(nullptr),
354       storageInterface_(nullptr),
355       metadata_(nullptr),
356       syncFinished_(false)
357 {
358 }
359 
~AbilitySync()360 AbilitySync::~AbilitySync()
361 {
362     communicator_ = nullptr;
363     storageInterface_ = nullptr;
364     metadata_ = nullptr;
365 }
366 
Initialize(ICommunicator * inCommunicator,ISyncInterface * inStorage,const std::shared_ptr<Metadata> & inMetadata,const std::string & deviceId)367 int AbilitySync::Initialize(ICommunicator *inCommunicator, ISyncInterface *inStorage,
368     const std::shared_ptr<Metadata> &inMetadata, const std::string &deviceId)
369 {
370     if (inCommunicator == nullptr || inStorage == nullptr || deviceId.empty() || inMetadata == nullptr) {
371         return -E_INVALID_ARGS;
372     }
373     communicator_ = inCommunicator;
374     storageInterface_ = inStorage;
375     metadata_ = inMetadata;
376     deviceId_ = deviceId;
377     return E_OK;
378 }
379 
SyncStart(uint32_t sessionId,uint32_t sequenceId,uint16_t remoteCommunicatorVersion,const CommErrHandler & handler,const ISyncTaskContext * context)380 int AbilitySync::SyncStart(uint32_t sessionId, uint32_t sequenceId, uint16_t remoteCommunicatorVersion,
381     const CommErrHandler &handler, const ISyncTaskContext *context)
382 {
383     AbilitySyncRequestPacket packet;
384     int errCode = SetAbilityRequestBodyInfo(remoteCommunicatorVersion, context, packet);
385     if (errCode != E_OK) {
386         return errCode;
387     }
388     Message *message = new (std::nothrow) Message(ABILITY_SYNC_MESSAGE);
389     if (message == nullptr) {
390         return -E_OUT_OF_MEMORY;
391     }
392     message->SetMessageType(TYPE_REQUEST);
393     errCode = message->SetCopiedObject<>(packet);
394     if (errCode != E_OK) {
395         LOGE("[AbilitySync][SyncStart] SetCopiedObject failed, err %d", errCode);
396         delete message;
397         message = nullptr;
398         return errCode;
399     }
400     message->SetVersion(MSG_VERSION_EXT);
401     message->SetSessionId(sessionId);
402     message->SetSequenceId(sequenceId);
403     SendConfig conf;
404     SetSendConfigParam(storageInterface_->GetDbProperties(), deviceId_, false, SEND_TIME_OUT, conf);
405     if (context != nullptr) {
406         conf.isRetryTask = context->IsRetryTask();
407     }
408     errCode = communicator_->SendMessage(deviceId_, message, conf, handler);
409     if (errCode != E_OK) {
410         LOGE("[AbilitySync][SyncStart] SendPacket failed, err %d", errCode);
411         delete message;
412         message = nullptr;
413     }
414     return errCode;
415 }
416 
AckRecv(const Message * message,ISyncTaskContext * context)417 int AbilitySync::AckRecv(const Message *message, ISyncTaskContext *context)
418 {
419     int errCode = AckMsgCheck(message, context);
420     if (errCode != E_OK) {
421         return errCode;
422     }
423     const AbilitySyncAckPacket *packet = message->GetObject<AbilitySyncAckPacket>();
424     if (packet == nullptr) {
425         return -E_INVALID_ARGS;
426     }
427     uint32_t remoteSoftwareVersion = packet->GetSoftwareVersion();
428     context->SetRemoteSoftwareVersion(remoteSoftwareVersion);
429     metadata_->SetRemoteSoftwareVersion(context->GetDeviceId(), context->GetTargetUserId(), remoteSoftwareVersion);
430     if (remoteSoftwareVersion > SOFTWARE_VERSION_RELEASE_2_0) {
431         errCode = AckRecvWithHighVersion(message, context, packet);
432     } else {
433         std::string schema = packet->GetSchema();
434         uint8_t schemaType = packet->GetSchemaType();
435         bool isCompatible = static_cast<SyncGenericInterface *>(storageInterface_)->CheckCompatible(schema, schemaType);
436         if (!isCompatible) { // LCOV_EXCL_BR_LINE
437             (static_cast<SingleVerSyncTaskContext *>(context))->SetTaskErrCode(-E_SCHEMA_MISMATCH);
438             LOGE("[AbilitySync][AckRecv] scheme check failed");
439             return -E_SCHEMA_MISMATCH;
440         }
441         LOGI("[AbilitySync][AckRecv]remoteSoftwareVersion = %u, isCompatible = %d,", remoteSoftwareVersion,
442             isCompatible);
443     }
444     return errCode;
445 }
446 
RequestRecv(const Message * message,ISyncTaskContext * context)447 int AbilitySync::RequestRecv(const Message *message, ISyncTaskContext *context)
448 {
449     if (message == nullptr || context == nullptr) {
450         return -E_INVALID_ARGS;
451     }
452     const AbilitySyncRequestPacket *packet = message->GetObject<AbilitySyncRequestPacket>();
453     if (packet == nullptr) {
454         return -E_INVALID_ARGS;
455     }
456     if (packet->GetSendCode() == -E_VERSION_NOT_SUPPORT) {
457         AbilitySyncAckPacket ackPacket;
458         (void)SendAck(context, message, -E_VERSION_NOT_SUPPORT, false, ackPacket);
459         LOGI("[AbilitySync][RequestRecv] version can not support, remote version is %u", packet->GetProtocolVersion());
460         return -E_VERSION_NOT_SUPPORT;
461     }
462 
463     std::string schema = packet->GetSchema();
464     uint8_t schemaType = packet->GetSchemaType();
465     bool isCompatible = static_cast<SyncGenericInterface *>(storageInterface_)->CheckCompatible(schema, schemaType);
466     if (!isCompatible) {
467         (static_cast<SingleVerSyncTaskContext *>(context))->SetTaskErrCode(-E_SCHEMA_MISMATCH);
468     }
469     uint32_t remoteSoftwareVersion = packet->GetSoftwareVersion();
470     context->SetRemoteSoftwareVersion(remoteSoftwareVersion);
471     return HandleRequestRecv(message, context, isCompatible);
472 }
473 
AckNotifyRecv(const Message * message,ISyncTaskContext * context)474 int AbilitySync::AckNotifyRecv(const Message *message, ISyncTaskContext *context)
475 {
476     if (message == nullptr || context == nullptr) {
477         return -E_INVALID_ARGS;
478     }
479     if (message->GetErrorNo() == E_FEEDBACK_UNKNOWN_MESSAGE) {
480         LOGE("[AbilitySync][AckNotifyRecv] Remote device dose not support this message id");
481         context->SetRemoteSoftwareVersion(SOFTWARE_VERSION_EARLIEST);
482         return -E_FEEDBACK_UNKNOWN_MESSAGE;
483     }
484     const AbilitySyncAckPacket *packet = message->GetObject<AbilitySyncAckPacket>();
485     if (packet == nullptr) {
486         return -E_INVALID_ARGS;
487     }
488     int errCode = packet->GetAckCode();
489     if (errCode != E_OK) {
490         LOGE("[AbilitySync][AckNotifyRecv] received an errCode %d", errCode);
491         return errCode;
492     }
493     uint32_t remoteSoftwareVersion = packet->GetSoftwareVersion();
494     context->SetRemoteSoftwareVersion(remoteSoftwareVersion);
495     AbilitySyncAckPacket sendPacket;
496     std::pair<bool, bool> schemaSyncStatus;
497     errCode = HandleVersionV3AckSchemaParam(packet, sendPacket, context, false, schemaSyncStatus);
498     errCode = errCode == -E_ABILITY_SYNC_FINISHED ? E_OK : errCode;
499     int ackCode = errCode;
500     LOGI("[AckNotifyRecv] receive dev = %s ack notify, remoteSoftwareVersion = %u, ackCode = %d",
501         STR_MASK(deviceId_), remoteSoftwareVersion, errCode);
502     if (errCode == E_OK) {
503         ackCode = AbilitySync::LAST_NOTIFY;
504     }
505     (void)SendAckWithEmptySchema(context, message, ackCode, true);
506     return errCode;
507 }
508 
GetAbilitySyncFinishedStatus() const509 bool AbilitySync::GetAbilitySyncFinishedStatus() const
510 {
511     return syncFinished_;
512 }
513 
SetAbilitySyncFinishedStatus(bool syncFinished,ISyncTaskContext & context)514 void AbilitySync::SetAbilitySyncFinishedStatus(bool syncFinished, ISyncTaskContext &context)
515 {
516     syncFinished_ = syncFinished;
517     if (context.GetRemoteSoftwareVersion() < SOFTWARE_VERSION_RELEASE_9_0) {
518         return;
519     }
520     // record finished with all schema compatible
521     if (syncFinished && !context.IsSchemaCompatible()) { // LCOV_EXCL_BR_LINE
522         return;
523     }
524     int errCode = metadata_->SetAbilitySyncFinishMark(deviceId_, context.GetTargetUserId(), syncFinished);
525     if (errCode != E_OK) {
526         LOGW("[AbilitySync] Set ability sync finish mark failed %d", errCode);
527     }
528 }
529 
SecLabelCheckInner(int32_t remoteSecLabel,int errCode,SecurityOption option,const AbilitySyncRequestPacket * packet) const530 bool AbilitySync::SecLabelCheckInner(int32_t remoteSecLabel, int errCode, SecurityOption option,
531     const AbilitySyncRequestPacket *packet) const
532 {
533     if (remoteSecLabel == NOT_SUPPORT_SEC_CLASSIFICATION || remoteSecLabel == SecurityLabel::NOT_SET) {
534         return true;
535     }
536     if (errCode == -E_NOT_SUPPORT || (errCode == E_OK && option.securityLabel == SecurityLabel::NOT_SET)) {
537         return true;
538     }
539     if (remoteSecLabel == FAILED_GET_SEC_CLASSIFICATION || errCode != E_OK) {
540         LOGE("[AbilitySync][RequestRecv] check error remoteL:%d, errCode:%d", remoteSecLabel, errCode);
541         return false;
542     }
543     if (remoteSecLabel == option.securityLabel) {
544         return true;
545     }
546     LOGE("[AbilitySync][RequestRecv] check error remote:%d , %d local:%d , %d",
547          remoteSecLabel, packet->GetSecFlag(), option.securityLabel, option.securityFlag);
548     return false;
549 }
550 
SecLabelCheck(const AbilitySyncRequestPacket * packet) const551 bool AbilitySync::SecLabelCheck(const AbilitySyncRequestPacket *packet) const
552 {
553     SecurityOption option;
554     auto *syncInterface = static_cast<SyncGenericInterface *>(storageInterface_);
555     if (syncInterface == nullptr) {
556         LOGE("[AbilitySync][RequestRecv] get sync interface wrong");
557         return false;
558     }
559     int errCode = syncInterface->GetSecurityOption(option);
560     int32_t remoteSecLabel = TransformSecLabelIfNeed(packet->GetSecLabel(), option.securityLabel);
561     LOGI("[AbilitySync][RequestRecv] remote label:%d local l:%d, f:%d, errCode:%d", remoteSecLabel,
562         option.securityLabel, option.securityFlag, errCode);
563     if (remoteSecLabel == NOT_SUPPORT_SEC_CLASSIFICATION && errCode == -E_NOT_SUPPORT) {
564         return true;
565     }
566     uint32_t remoteSoftwareVersion = packet->GetSoftwareVersion();
567     if (errCode != -E_NOT_SUPPORT && option.securityLabel == SecurityLabel::NOT_SET) {
568         LOGE("[AbilitySync][RequestRecv] local security label not set!");
569         return false;
570     }
571     if (remoteSoftwareVersion >= SOFTWARE_VERSION_RELEASE_7_0 && remoteSecLabel == SecurityLabel::NOT_SET) {
572         LOGE("[AbilitySync][RequestRecv] remote security label not set!");
573         return false;
574     }
575     return SecLabelCheckInner(remoteSecLabel, errCode, option, packet);
576 }
577 
HandleVersionV3RequestParam(const AbilitySyncRequestPacket * packet,ISyncTaskContext * context)578 void AbilitySync::HandleVersionV3RequestParam(const AbilitySyncRequestPacket *packet, ISyncTaskContext *context)
579 {
580     int32_t remoteSecLabel = packet->GetSecLabel();
581     int32_t remoteSecFlag = packet->GetSecFlag();
582     DbAbility remoteDbAbility = packet->GetDbAbility();
583     (static_cast<SingleVerSyncTaskContext *>(context))->SetDbAbility(remoteDbAbility);
584     (static_cast<SingleVerSyncTaskContext *>(context))->SetRemoteSeccurityOption({remoteSecLabel, remoteSecFlag});
585     (static_cast<SingleVerSyncTaskContext *>(context))->SetReceivcPermitCheck(false);
586     LOGI("[AbilitySync][HandleVersionV3RequestParam] remoteSecLabel = %d, remoteSecFlag = %d, remoteSchemaType = %u",
587         remoteSecLabel, remoteSecFlag, packet->GetSchemaType());
588 }
589 
HandleVersionV3AckSecOptionParam(const AbilitySyncAckPacket * packet,ISyncTaskContext * context)590 void AbilitySync::HandleVersionV3AckSecOptionParam(const AbilitySyncAckPacket *packet,
591     ISyncTaskContext *context)
592 {
593     int32_t remoteSecLabel = packet->GetSecLabel();
594     int32_t remoteSecFlag = packet->GetSecFlag();
595     SecurityOption secOption = {remoteSecLabel, remoteSecFlag};
596     (static_cast<SingleVerSyncTaskContext *>(context))->SetRemoteSeccurityOption(secOption);
597     (static_cast<SingleVerSyncTaskContext *>(context))->SetSendPermitCheck(false);
598     LOGI("[AbilitySync][AckRecv] remoteSecLabel = %d, remoteSecFlag = %d", remoteSecLabel, remoteSecFlag);
599 }
600 
HandleVersionV3AckSchemaParam(const AbilitySyncAckPacket * recvPacket,AbilitySyncAckPacket & sendPacket,ISyncTaskContext * context,bool sendOpinion,std::pair<bool,bool> & schemaSyncStatus)601 int AbilitySync::HandleVersionV3AckSchemaParam(const AbilitySyncAckPacket *recvPacket,
602     AbilitySyncAckPacket &sendPacket,  ISyncTaskContext *context, bool sendOpinion,
603     std::pair<bool, bool> &schemaSyncStatus)
604 {
605     if (IsSingleRelationalVer()) {
606         return HandleRelationAckSchemaParam(recvPacket, sendPacket, context, sendOpinion, schemaSyncStatus);
607     }
608     return HandleKvAckSchemaParam(recvPacket, context, sendPacket, schemaSyncStatus);
609 }
610 
GetPacketSecOption(const ISyncTaskContext * context,SecurityOption & option) const611 void AbilitySync::GetPacketSecOption(const ISyncTaskContext *context, SecurityOption &option) const
612 {
613     int errCode =
614         (static_cast<SyncGenericInterface *>(storageInterface_))->GetSecurityOption(option);
615     if (errCode == -E_NOT_SUPPORT) {
616         LOGE("[AbilitySync][SyncStart] GetSecOpt not surpport sec classification");
617         option.securityLabel = NOT_SUPPORT_SEC_CLASSIFICATION;
618     } else if (errCode != E_OK) {
619         LOGE("[AbilitySync][SyncStart] GetSecOpt errCode:%d", errCode);
620         option.securityLabel = FAILED_GET_SEC_CLASSIFICATION;
621     }
622     if (context == nullptr) {
623         return;
624     }
625     auto remoteSecOption = (static_cast<const SingleVerSyncTaskContext *>(context))->GetRemoteSeccurityOption();
626     option.securityLabel = TransformSecLabelIfNeed(option.securityLabel, remoteSecOption.securityLabel);
627 }
628 
RegisterTransformFunc()629 int AbilitySync::RegisterTransformFunc()
630 {
631     TransformFunc func;
632     func.computeFunc = [](const Message *inMsg) { return CalculateLen(inMsg); };
633     func.serializeFunc = [](uint8_t *buffer, uint32_t length, const Message *inMsg) {
634         return Serialization(buffer, length, inMsg);
635     };
636     func.deserializeFunc = [](const uint8_t *buffer, uint32_t length, Message *inMsg) {
637         return DeSerialization(buffer, length, inMsg);
638     };
639     return MessageTransform::RegTransformFunction(ABILITY_SYNC_MESSAGE, func);
640 }
641 
CalculateLen(const Message * inMsg)642 uint32_t AbilitySync::CalculateLen(const Message *inMsg)
643 {
644     if ((inMsg == nullptr) || (inMsg->GetMessageId() != ABILITY_SYNC_MESSAGE)) {
645         return 0;
646     }
647     int errCode;
648     uint32_t len = 0;
649     switch (inMsg->GetMessageType()) {
650         case TYPE_REQUEST:
651             errCode = RequestPacketCalculateLen(inMsg, len);
652             if (errCode != E_OK) {
653                 LOGE("[AbilitySync][CalculateLen] request packet calc length err %d", errCode);
654             }
655             break;
656         case TYPE_RESPONSE:
657             errCode = AckPacketCalculateLen(inMsg, len);
658             if (errCode != E_OK) {
659                 LOGE("[AbilitySync][CalculateLen] ack packet calc length err %d", errCode);
660             }
661             break;
662         case TYPE_NOTIFY:
663             errCode = AckPacketCalculateLen(inMsg, len);
664             if (errCode != E_OK) {
665                 LOGE("[AbilitySync][CalculateLen] ack packet calc length err %d", errCode);
666             }
667             break;
668         default:
669             LOGE("[AbilitySync][CalculateLen] message type not support, type %d", inMsg->GetMessageType());
670             break;
671     }
672     return len;
673 }
674 
Serialization(uint8_t * buffer,uint32_t length,const Message * inMsg)675 int AbilitySync::Serialization(uint8_t *buffer, uint32_t length, const Message *inMsg)
676 {
677     if ((buffer == nullptr) || (inMsg == nullptr)) {
678         return -E_INVALID_ARGS;
679     }
680 
681     switch (inMsg->GetMessageType()) {
682         case TYPE_REQUEST:
683             return RequestPacketSerialization(buffer, length, inMsg);
684         case TYPE_RESPONSE:
685         case TYPE_NOTIFY:
686             return AckPacketSerialization(buffer, length, inMsg);
687         default:
688             return -E_MESSAGE_TYPE_ERROR;
689     }
690 }
691 
DeSerialization(const uint8_t * buffer,uint32_t length,Message * inMsg)692 int AbilitySync::DeSerialization(const uint8_t *buffer, uint32_t length, Message *inMsg)
693 {
694     if ((buffer == nullptr) || (inMsg == nullptr)) {
695         return -E_INVALID_ARGS;
696     }
697 
698     switch (inMsg->GetMessageType()) {
699         case TYPE_REQUEST:
700             return RequestPacketDeSerialization(buffer, length, inMsg);
701         case TYPE_RESPONSE:
702         case TYPE_NOTIFY:
703             return AckPacketDeSerialization(buffer, length, inMsg);
704         default:
705             return -E_MESSAGE_TYPE_ERROR;
706     }
707 }
708 
RequestPacketCalculateLen(const Message * inMsg,uint32_t & len)709 int AbilitySync::RequestPacketCalculateLen(const Message *inMsg, uint32_t &len)
710 {
711     const AbilitySyncRequestPacket *packet = inMsg->GetObject<AbilitySyncRequestPacket>();
712     if (packet == nullptr) {
713         return -E_INVALID_ARGS;
714     }
715 
716     len = packet->CalculateLen();
717     return E_OK;
718 }
719 
AckPacketCalculateLen(const Message * inMsg,uint32_t & len)720 int AbilitySync::AckPacketCalculateLen(const Message *inMsg, uint32_t &len)
721 {
722     const AbilitySyncAckPacket *packet = inMsg->GetObject<AbilitySyncAckPacket>();
723     if (packet == nullptr) {
724         return -E_INVALID_ARGS;
725     }
726 
727     len = packet->CalculateLen();
728     return E_OK;
729 }
730 
RequestPacketSerialization(uint8_t * buffer,uint32_t length,const Message * inMsg)731 int AbilitySync::RequestPacketSerialization(uint8_t *buffer, uint32_t length, const Message *inMsg)
732 {
733     const AbilitySyncRequestPacket *packet = inMsg->GetObject<AbilitySyncRequestPacket>();
734     if ((packet == nullptr) || (length != packet->CalculateLen())) {
735         return -E_INVALID_ARGS;
736     }
737 
738     Parcel parcel(buffer, length);
739     parcel.WriteUInt32(packet->GetProtocolVersion());
740     parcel.WriteInt(packet->GetSendCode());
741     parcel.WriteUInt32(packet->GetSoftwareVersion());
742     parcel.WriteString(packet->GetSchema());
743     parcel.WriteInt(packet->GetSecLabel());
744     parcel.WriteInt(packet->GetSecFlag());
745     parcel.WriteUInt32(packet->GetSchemaType());
746     parcel.WriteUInt64(packet->GetDbCreateTime());
747     int errCode = DbAbility::Serialize(parcel, packet->GetDbAbility());
748     parcel.WriteUInt64(packet->GetSchemaVersion());
749     if (parcel.IsError() || errCode != E_OK) {
750         return -E_PARSE_FAIL;
751     }
752     return E_OK;
753 }
754 
AckPacketSerialization(uint8_t * buffer,uint32_t length,const Message * inMsg)755 int AbilitySync::AckPacketSerialization(uint8_t *buffer, uint32_t length, const Message *inMsg)
756 {
757     const AbilitySyncAckPacket *packet = inMsg->GetObject<AbilitySyncAckPacket>();
758     if ((packet == nullptr) || (length != packet->CalculateLen())) {
759         return -E_INVALID_ARGS;
760     }
761 
762     Parcel parcel(buffer, length);
763     parcel.WriteUInt32(ABILITY_SYNC_VERSION_V1);
764     parcel.WriteUInt32(SOFTWARE_VERSION_CURRENT);
765     parcel.WriteInt(packet->GetAckCode());
766     parcel.WriteString(packet->GetSchema());
767     parcel.WriteInt(packet->GetSecLabel());
768     parcel.WriteInt(packet->GetSecFlag());
769     parcel.WriteUInt32(packet->GetSchemaType());
770     parcel.WriteUInt32(packet->GetPermitSync());
771     parcel.WriteUInt32(packet->GetRequirePeerConvert());
772     parcel.WriteUInt64(packet->GetDbCreateTime());
773     int errCode = DbAbility::Serialize(parcel, packet->GetDbAbility());
774     if (parcel.IsError() || errCode != E_OK) {
775         return -E_PARSE_FAIL;
776     }
777     errCode = SchemaNegotiate::SerializeData(packet->GetRelationalSyncOpinion(), parcel);
778     if (parcel.IsError() || errCode != E_OK) {
779         return -E_PARSE_FAIL;
780     }
781     parcel.WriteUInt64(packet->GetSchemaVersion());
782     if (parcel.IsError()) {
783         LOGE("[AbilitySync] Serialize schema version failed");
784         return -E_PARSE_FAIL;
785     }
786     return E_OK;
787 }
788 
RequestPacketDeSerialization(const uint8_t * buffer,uint32_t length,Message * inMsg)789 int AbilitySync::RequestPacketDeSerialization(const uint8_t *buffer, uint32_t length, Message *inMsg)
790 {
791     auto *packet = new (std::nothrow) AbilitySyncRequestPacket();
792     if (packet == nullptr) {
793         return -E_OUT_OF_MEMORY;
794     }
795 
796     Parcel parcel(const_cast<uint8_t *>(buffer), length);
797     uint32_t version = 0;
798     uint32_t softwareVersion = 0;
799     std::string schema;
800     int32_t sendCode = 0;
801     int errCode = -E_PARSE_FAIL;
802 
803     parcel.ReadUInt32(version);
804     if (parcel.IsError()) {
805         goto ERROR_OUT;
806     }
807     packet->SetProtocolVersion(version);
808     if (version > ABILITY_SYNC_VERSION_V1) {
809         packet->SetSendCode(-E_VERSION_NOT_SUPPORT);
810         errCode = inMsg->SetExternalObject<>(packet);
811         if (errCode != E_OK) {
812             goto ERROR_OUT;
813         }
814         return errCode;
815     }
816     parcel.ReadInt(sendCode);
817     parcel.ReadUInt32(softwareVersion);
818     parcel.ReadString(schema);
819     errCode = RequestPacketDeSerializationTailPart(parcel, packet, softwareVersion);
820     if (parcel.IsError() || errCode != E_OK) {
821         goto ERROR_OUT;
822     }
823     packet->SetSendCode(sendCode);
824     packet->SetSoftwareVersion(softwareVersion);
825     packet->SetSchema(schema);
826 
827     errCode = inMsg->SetExternalObject<>(packet);
828     if (errCode == E_OK) {
829         return E_OK;
830     }
831 
832 ERROR_OUT:
833     delete packet;
834     return errCode;
835 }
836 
RequestPacketDeSerializationTailPart(Parcel & parcel,AbilitySyncRequestPacket * packet,uint32_t version)837 int AbilitySync::RequestPacketDeSerializationTailPart(Parcel &parcel, AbilitySyncRequestPacket *packet,
838     uint32_t version)
839 {
840     if (!parcel.IsError() && version > SOFTWARE_VERSION_RELEASE_2_0) {
841         int32_t secLabel = 0;
842         int32_t secFlag = 0;
843         uint32_t schemaType = 0;
844         parcel.ReadInt(secLabel);
845         parcel.ReadInt(secFlag);
846         parcel.ReadUInt32(schemaType);
847         packet->SetSecLabel(secLabel);
848         packet->SetSecFlag(secFlag);
849         packet->SetSchemaType(schemaType);
850     }
851     if (!parcel.IsError() && version > SOFTWARE_VERSION_RELEASE_3_0) {
852         uint64_t dbCreateTime = 0;
853         parcel.ReadUInt64(dbCreateTime);
854         packet->SetDbCreateTime(dbCreateTime);
855     }
856     DbAbility remoteDbAbility;
857     int errCode = DbAbility::DeSerialize(parcel, remoteDbAbility);
858     if (errCode != E_OK) {
859         LOGE("[AbilitySync] request packet DeSerializ failed.");
860         return errCode;
861     }
862     packet->SetDbAbility(remoteDbAbility);
863     if (version >= SOFTWARE_VERSION_RELEASE_9_0) {
864         uint64_t schemaVersion = 0u;
865         parcel.ReadUInt64(schemaVersion);
866         if (parcel.IsError()) {
867             LOGW("[AbilitySync] request packet read schema version failed");
868             return -E_PARSE_FAIL;
869         }
870         packet->SetSchemaVersion(schemaVersion);
871     }
872     return E_OK;
873 }
874 
AckPacketDeSerializationTailPart(Parcel & parcel,AbilitySyncAckPacket * packet,uint32_t version)875 int AbilitySync::AckPacketDeSerializationTailPart(Parcel &parcel, AbilitySyncAckPacket *packet, uint32_t version)
876 {
877     if (!parcel.IsError() && version > SOFTWARE_VERSION_RELEASE_2_0) {
878         int32_t secLabel = 0;
879         int32_t secFlag = 0;
880         uint32_t schemaType = 0;
881         uint32_t permitSync = 0;
882         uint32_t requirePeerConvert = 0;
883         parcel.ReadInt(secLabel);
884         parcel.ReadInt(secFlag);
885         parcel.ReadUInt32(schemaType);
886         parcel.ReadUInt32(permitSync);
887         parcel.ReadUInt32(requirePeerConvert);
888         packet->SetSecLabel(secLabel);
889         packet->SetSecFlag(secFlag);
890         packet->SetSchemaType(schemaType);
891         packet->SetPermitSync(permitSync);
892         packet->SetRequirePeerConvert(requirePeerConvert);
893     }
894     if (!parcel.IsError() && version > SOFTWARE_VERSION_RELEASE_3_0) {
895         uint64_t dbCreateTime = 0;
896         parcel.ReadUInt64(dbCreateTime);
897         packet->SetDbCreateTime(dbCreateTime);
898     }
899     DbAbility remoteDbAbility;
900     int errCode = DbAbility::DeSerialize(parcel, remoteDbAbility);
901     if (errCode != E_OK) {
902         LOGE("[AbilitySync] ack packet DeSerializ failed.");
903         return errCode;
904     }
905     packet->SetDbAbility(remoteDbAbility);
906     RelationalSyncOpinion relationalSyncOpinion;
907     errCode = SchemaNegotiate::DeserializeData(parcel, relationalSyncOpinion);
908     if (errCode != E_OK) {
909         LOGE("[AbilitySync] ack packet DeSerializ RelationalSyncOpinion failed.");
910         return errCode;
911     }
912     packet->SetRelationalSyncOpinion(relationalSyncOpinion);
913     if (version >= SOFTWARE_VERSION_RELEASE_9_0) {
914         uint64_t schemaVersion = 0;
915         parcel.ReadUInt64(schemaVersion);
916         if (parcel.IsError()) {
917             LOGW("[AbilitySync] ack packet read schema version failed.");
918             return -E_PARSE_FAIL;
919         }
920         packet->SetSchemaVersion(schemaVersion);
921     }
922     return E_OK;
923 }
924 
AckPacketDeSerialization(const uint8_t * buffer,uint32_t length,Message * inMsg)925 int AbilitySync::AckPacketDeSerialization(const uint8_t *buffer, uint32_t length, Message *inMsg)
926 {
927     auto *packet = new (std::nothrow) AbilitySyncAckPacket();
928     if (packet == nullptr) {
929         return -E_OUT_OF_MEMORY;
930     }
931 
932     Parcel parcel(const_cast<uint8_t *>(buffer), length);
933     uint32_t version = 0;
934     uint32_t softwareVersion = 0;
935     int32_t ackCode = E_OK;
936     std::string schema;
937     int errCode;
938     parcel.ReadUInt32(version);
939     if (parcel.IsError()) {
940         LOGE("[AbilitySync][RequestDeSerialization] read version failed!");
941         errCode = -E_PARSE_FAIL;
942         goto ERROR_OUT;
943     }
944     packet->SetProtocolVersion(version);
945     if (version > ABILITY_SYNC_VERSION_V1) {
946         packet->SetAckCode(-E_VERSION_NOT_SUPPORT);
947         errCode = inMsg->SetExternalObject<>(packet);
948         if (errCode != E_OK) {
949             goto ERROR_OUT;
950         }
951         return errCode;
952     }
953     parcel.ReadUInt32(softwareVersion);
954     parcel.ReadInt(ackCode);
955     parcel.ReadString(schema);
956     errCode = AckPacketDeSerializationTailPart(parcel, packet, softwareVersion);
957     if (parcel.IsError() || errCode != E_OK) {
958         LOGE("[AbilitySync][RequestDeSerialization] DeSerialization failed!");
959         errCode = -E_PARSE_FAIL;
960         goto ERROR_OUT;
961     }
962     packet->SetSoftwareVersion(softwareVersion);
963     packet->SetAckCode(ackCode);
964     packet->SetSchema(schema);
965     errCode = inMsg->SetExternalObject<>(packet);
966     if (errCode == E_OK) {
967         return E_OK;
968     }
969 
970 ERROR_OUT:
971     delete packet;
972     return errCode;
973 }
974 
SetAbilityRequestBodyInfoInner(uint16_t remoteCommunicatorVersion,AbilitySyncRequestPacket & packet,std::string & schemaStr,uint32_t schemaType) const975 void AbilitySync::SetAbilityRequestBodyInfoInner(uint16_t remoteCommunicatorVersion, AbilitySyncRequestPacket &packet,
976     std::string &schemaStr, uint32_t schemaType) const
977 {
978     // 102 version is forbidden to sync with 103 json-schema or flatbuffer-schema
979     // so schema should put null string while remote is 102 version to avoid this bug.
980     if (remoteCommunicatorVersion == 1) {
981         packet.SetSchema("");
982         packet.SetSchemaType(0);
983     } else {
984         packet.SetSchema(schemaStr);
985         packet.SetSchemaType(schemaType);
986     }
987 }
988 
SetAbilityRequestBodyInfo(uint16_t remoteCommunicatorVersion,const ISyncTaskContext * context,AbilitySyncRequestPacket & packet) const989 int AbilitySync::SetAbilityRequestBodyInfo(uint16_t remoteCommunicatorVersion, const ISyncTaskContext *context,
990     AbilitySyncRequestPacket &packet) const
991 {
992     if (storageInterface_ == nullptr) {
993         LOGE("[AbilitySync][FillAbilityRequest] storageInterface is nullptr");
994         return -E_INVALID_ARGS;
995     }
996     uint64_t dbCreateTime;
997     int errCode = (static_cast<SyncGenericInterface *>(storageInterface_))->GetDatabaseCreateTimestamp(dbCreateTime);
998     if (errCode != E_OK) {
999         LOGE("[AbilitySync][FillAbilityRequest] GetDatabaseCreateTimestamp failed, err %d", errCode);
1000         return errCode;
1001     }
1002     SecurityOption option;
1003     GetPacketSecOption(context, option);
1004     std::string schemaStr;
1005     uint32_t schemaType = 0;
1006     if (IsSingleKvVer()) {
1007         SchemaObject schemaObj = (static_cast<SingleVerKvDBSyncInterface *>(storageInterface_))->GetSchemaInfo();
1008         schemaStr = schemaObj.ToSchemaString();
1009         schemaType = static_cast<uint32_t>(schemaObj.GetSchemaType());
1010     } else if (IsSingleRelationalVer()) {
1011         auto schemaObj = (static_cast<RelationalDBSyncInterface *>(storageInterface_))->GetSchemaInfo();
1012         schemaStr = schemaObj.ToSchemaString();
1013         schemaType = static_cast<uint32_t>(schemaObj.GetSchemaType());
1014     }
1015     DbAbility dbAbility;
1016     errCode = GetDbAbilityInfo(dbAbility);
1017     if (errCode != E_OK) {
1018         LOGE("[AbilitySync][FillAbilityRequest] GetDbAbility failed, err %d", errCode);
1019         return errCode;
1020     }
1021     auto [err, localSchemaVer] = metadata_->GetLocalSchemaVersion();
1022     if (err != E_OK) {
1023         LOGE("[AbilitySync][FillAbilityRequest] GetLocalSchemaVersion failed, err %d", err);
1024         return err;
1025     }
1026     SetAbilityRequestBodyInfoInner(remoteCommunicatorVersion, packet, schemaStr, schemaType);
1027     packet.SetProtocolVersion(ABILITY_SYNC_VERSION_V1);
1028     packet.SetSoftwareVersion(SOFTWARE_VERSION_CURRENT);
1029     packet.SetSecLabel(option.securityLabel);
1030     packet.SetSecFlag(option.securityFlag);
1031     packet.SetDbCreateTime(dbCreateTime);
1032     packet.SetDbAbility(dbAbility);
1033     packet.SetSchemaVersion(localSchemaVer);
1034     LOGI("[AbilitySync][FillRequest] ver=%u,Lab=%d,Flag=%d,dbCreateTime=%" PRId64 ",schemaVer=%" PRId64,
1035         SOFTWARE_VERSION_CURRENT, option.securityLabel, option.securityFlag, dbCreateTime, localSchemaVer);
1036     return E_OK;
1037 }
1038 
SetAbilityAckBodyInfo(const ISyncTaskContext * context,int ackCode,bool isAckNotify,AbilitySyncAckPacket & ackPacket) const1039 int AbilitySync::SetAbilityAckBodyInfo(const ISyncTaskContext *context, int ackCode, bool isAckNotify,
1040     AbilitySyncAckPacket &ackPacket) const
1041 {
1042     ackPacket.SetProtocolVersion(ABILITY_SYNC_VERSION_V1);
1043     ackPacket.SetSoftwareVersion(SOFTWARE_VERSION_CURRENT);
1044     if (!isAckNotify) {
1045         SecurityOption option;
1046         GetPacketSecOption(context, option);
1047         ackPacket.SetSecLabel(option.securityLabel);
1048         ackPacket.SetSecFlag(option.securityFlag);
1049         uint64_t dbCreateTime = 0;
1050         int errCode =
1051             (static_cast<SyncGenericInterface *>(storageInterface_))->GetDatabaseCreateTimestamp(dbCreateTime);
1052         if (errCode != E_OK) {
1053             LOGE("[AbilitySync][SyncStart] GetDatabaseCreateTimestamp failed, err %d", errCode);
1054             ackCode = errCode;
1055         }
1056         DbAbility dbAbility;
1057         errCode = GetDbAbilityInfo(dbAbility);
1058         if (errCode != E_OK) {
1059             LOGE("[AbilitySync][FillAbilityRequest] GetDbAbility failed, err %d", errCode);
1060             return errCode;
1061         }
1062         ackPacket.SetDbCreateTime(dbCreateTime);
1063         ackPacket.SetDbAbility(dbAbility);
1064     }
1065     auto [ret, schemaVersion] = metadata_->GetLocalSchemaVersion();
1066     if (ret != E_OK) {
1067         return ret;
1068     }
1069     ackPacket.SetAckCode(ackCode);
1070     ackPacket.SetSchemaVersion(schemaVersion);
1071     return E_OK;
1072 }
1073 
SetAbilityAckSchemaInfo(AbilitySyncAckPacket & ackPacket,const ISchema & schemaObj)1074 void AbilitySync::SetAbilityAckSchemaInfo(AbilitySyncAckPacket &ackPacket, const ISchema &schemaObj)
1075 {
1076     ackPacket.SetSchema(schemaObj.ToSchemaString());
1077     ackPacket.SetSchemaType(static_cast<uint32_t>(schemaObj.GetSchemaType()));
1078 }
1079 
SetAbilityAckSyncOpinionInfo(AbilitySyncAckPacket & ackPacket,SyncOpinion localOpinion)1080 void AbilitySync::SetAbilityAckSyncOpinionInfo(AbilitySyncAckPacket &ackPacket, SyncOpinion localOpinion)
1081 {
1082     ackPacket.SetPermitSync(localOpinion.permitSync);
1083     ackPacket.SetRequirePeerConvert(localOpinion.requirePeerConvert);
1084 }
1085 
GetDbAbilityInfo(DbAbility & dbAbility)1086 int AbilitySync::GetDbAbilityInfo(DbAbility &dbAbility)
1087 {
1088     int errCode = E_OK;
1089     for (const auto &item : SyncConfig::ABILITYBITS) {
1090         errCode = dbAbility.SetAbilityItem(item, SUPPORT_MARK);
1091         if (errCode != E_OK) {
1092             return errCode;
1093         }
1094     }
1095     return errCode;
1096 }
1097 
AckMsgCheck(const Message * message,ISyncTaskContext * context) const1098 int AbilitySync::AckMsgCheck(const Message *message, ISyncTaskContext *context) const
1099 {
1100     if (message == nullptr || context == nullptr) {
1101         return -E_INVALID_ARGS;
1102     }
1103     if (message->GetErrorNo() == E_FEEDBACK_UNKNOWN_MESSAGE) {
1104         LOGE("[AbilitySync][AckMsgCheck] Remote device dose not support this message id");
1105         context->SetRemoteSoftwareVersion(SOFTWARE_VERSION_EARLIEST);
1106         context->SetTaskErrCode(-E_FEEDBACK_UNKNOWN_MESSAGE);
1107         return -E_FEEDBACK_UNKNOWN_MESSAGE;
1108     }
1109     if (message->GetErrorNo() == E_FEEDBACK_COMMUNICATOR_NOT_FOUND) {
1110         LOGE("[AbilitySync][AckMsgCheck] Remote db is closed");
1111         context->SetTaskErrCode(-E_FEEDBACK_COMMUNICATOR_NOT_FOUND);
1112         return -E_FEEDBACK_COMMUNICATOR_NOT_FOUND;
1113     }
1114     const AbilitySyncAckPacket *packet = message->GetObject<AbilitySyncAckPacket>();
1115     if (packet == nullptr) {
1116         return -E_INVALID_ARGS;
1117     }
1118     int ackCode = packet->GetAckCode();
1119     if (ackCode != E_OK) {
1120         LOGE("[AbilitySync][AckMsgCheck] received an errCode %d", ackCode);
1121         context->SetTaskErrCode(ackCode);
1122         return ackCode;
1123     }
1124     return E_OK;
1125 }
1126 
IsSingleKvVer() const1127 bool AbilitySync::IsSingleKvVer() const
1128 {
1129     return storageInterface_->GetInterfaceType() == ISyncInterface::SYNC_SVD;
1130 }
IsSingleRelationalVer() const1131 bool AbilitySync::IsSingleRelationalVer() const
1132 {
1133 #ifdef RELATIONAL_STORE
1134     return storageInterface_->GetInterfaceType() == ISyncInterface::SYNC_RELATION;
1135 #else
1136     return false;
1137 #endif
1138 }
1139 
HandleRequestRecv(const Message * message,ISyncTaskContext * context,bool isCompatible)1140 int AbilitySync::HandleRequestRecv(const Message *message, ISyncTaskContext *context, bool isCompatible)
1141 {
1142     const AbilitySyncRequestPacket *packet = message->GetObject<AbilitySyncRequestPacket>();
1143     if (packet == nullptr) {
1144         return -E_INVALID_ARGS;
1145     }
1146     uint32_t remoteSoftwareVersion = packet->GetSoftwareVersion();
1147     int ackCode;
1148     std::string schema = packet->GetSchema();
1149     if (remoteSoftwareVersion <= SOFTWARE_VERSION_RELEASE_2_0) {
1150         LOGI("[AbilitySync][RequestRecv] remote version = %u, CheckSchemaCompatible = %d",
1151             remoteSoftwareVersion, isCompatible);
1152         return SendAckWithEmptySchema(context, message, E_OK, false);
1153     }
1154     HandleVersionV3RequestParam(packet, context);
1155     if (SecLabelCheck(packet)) {
1156         ackCode = E_OK;
1157     } else {
1158         ackCode = -E_SECURITY_OPTION_CHECK_ERROR;
1159     }
1160     if (ackCode == E_OK && remoteSoftwareVersion > SOFTWARE_VERSION_RELEASE_3_0) {
1161         ackCode = metadata_->SetDbCreateTime(deviceId_, context->GetTargetUserId(), packet->GetDbCreateTime(), true);
1162     }
1163     if (ackCode == E_OK && remoteSoftwareVersion >= SOFTWARE_VERSION_RELEASE_9_0) {
1164         ackCode = metadata_->SetRemoteSchemaVersion(context->GetDeviceId(), context->GetTargetUserId(),
1165             packet->GetSchemaVersion());
1166     }
1167     AbilitySyncAckPacket ackPacket;
1168     if (IsSingleRelationalVer()) {
1169         ackPacket.SetRelationalSyncOpinion(MakeRelationSyncOpinion(packet, schema));
1170     } else {
1171         SetAbilityAckSyncOpinionInfo(ackPacket, MakeKvSyncOpinion(packet, schema, context));
1172     }
1173     LOGI("[AbilitySync][RequestRecv] remote dev=%s,ver=%u,schemaCompatible=%d", STR_MASK(deviceId_),
1174         remoteSoftwareVersion, isCompatible);
1175     int errCode = SendAck(context, message, ackCode, false, ackPacket);
1176     return ackCode != E_OK ? ackCode : errCode;
1177 }
1178 
SendAck(const ISyncTaskContext * context,const Message * message,int ackCode,bool isAckNotify,AbilitySyncAckPacket & ackPacket)1179 int AbilitySync::SendAck(const ISyncTaskContext *context, const Message *message, int ackCode, bool isAckNotify,
1180     AbilitySyncAckPacket &ackPacket)
1181 {
1182     int errCode = SetAbilityAckBodyInfo(context, ackCode, isAckNotify, ackPacket);
1183     if (errCode != E_OK) {
1184         return errCode;
1185     }
1186     if (IsSingleRelationalVer()) {
1187         auto schemaObj = (static_cast<RelationalDBSyncInterface *>(storageInterface_))->GetSchemaInfo();
1188         SetAbilityAckSchemaInfo(ackPacket, schemaObj);
1189     } else if (IsSingleKvVer()) {
1190         SchemaObject schemaObject = static_cast<SingleVerKvDBSyncInterface *>(storageInterface_)->GetSchemaInfo();
1191         SetAbilityAckSchemaInfo(ackPacket, schemaObject);
1192     }
1193     return SendAck(message, ackPacket, isAckNotify);
1194 }
1195 
SendAckWithEmptySchema(const ISyncTaskContext * context,const Message * message,int ackCode,bool isAckNotify)1196 int AbilitySync::SendAckWithEmptySchema(const ISyncTaskContext *context, const Message *message, int ackCode,
1197     bool isAckNotify)
1198 {
1199     AbilitySyncAckPacket ackPacket;
1200     int errCode = SetAbilityAckBodyInfo(context, ackCode, isAckNotify, ackPacket);
1201     if (errCode != E_OK) {
1202         return errCode;
1203     }
1204     SetAbilityAckSchemaInfo(ackPacket, SchemaObject());
1205     return SendAck(message, ackPacket, isAckNotify);
1206 }
1207 
SendAck(const Message * inMsg,const AbilitySyncAckPacket & ackPacket,bool isAckNotify)1208 int AbilitySync::SendAck(const Message *inMsg, const AbilitySyncAckPacket &ackPacket, bool isAckNotify)
1209 {
1210     Message *ackMessage = new (std::nothrow) Message(ABILITY_SYNC_MESSAGE);
1211     if (ackMessage == nullptr) {
1212         LOGE("[AbilitySync][SendAck] message create failed, may be memleak!");
1213         return -E_OUT_OF_MEMORY;
1214     }
1215     int errCode = ackMessage->SetCopiedObject<>(ackPacket);
1216     if (errCode != E_OK) {
1217         LOGE("[AbilitySync][SendAck] SetCopiedObject failed, err %d", errCode);
1218         delete ackMessage;
1219         ackMessage = nullptr;
1220         return errCode;
1221     }
1222     (!isAckNotify) ? ackMessage->SetMessageType(TYPE_RESPONSE) : ackMessage->SetMessageType(TYPE_NOTIFY);
1223     ackMessage->SetTarget(deviceId_);
1224     ackMessage->SetSessionId(inMsg->GetSessionId());
1225     ackMessage->SetSequenceId(inMsg->GetSequenceId());
1226     SendConfig conf;
1227     SetSendConfigParam(storageInterface_->GetDbProperties(), deviceId_, false, SEND_TIME_OUT, conf);
1228     errCode = communicator_->SendMessage(deviceId_, ackMessage, conf);
1229     if (errCode != E_OK) {
1230         LOGE("[AbilitySync][SendAck] SendPacket failed, err %d", errCode);
1231         delete ackMessage;
1232         ackMessage = nullptr;
1233     }
1234     return errCode;
1235 }
1236 
MakeKvSyncOpinion(const AbilitySyncRequestPacket * packet,const std::string & remoteSchema,ISyncTaskContext * context)1237 SyncOpinion AbilitySync::MakeKvSyncOpinion(const AbilitySyncRequestPacket *packet,
1238     const std::string &remoteSchema, ISyncTaskContext *context)
1239 {
1240     uint8_t remoteSchemaType = packet->GetSchemaType();
1241     SchemaObject localSchema = (static_cast<SingleVerKvDBSyncInterface *>(storageInterface_))->GetSchemaInfo();
1242     SyncOpinion localSyncOpinion = SchemaNegotiate::MakeLocalSyncOpinion(localSchema, remoteSchema, remoteSchemaType);
1243     if (IsBothKvAndOptAbilitySync(context->GetRemoteSoftwareVersion(),
1244         localSchema.GetSchemaType(), remoteSchemaType)) { // LCOV_EXCL_BR_LINE
1245         // both kv no need convert
1246         SyncStrategy localStrategy;
1247         localStrategy.permitSync = true;
1248         (static_cast<SingleVerKvSyncTaskContext *>(context))->SetSyncStrategy(localStrategy, true);
1249         SetAbilitySyncFinishedStatus(true, *context);
1250     }
1251     return localSyncOpinion;
1252 }
1253 
MakeRelationSyncOpinion(const AbilitySyncRequestPacket * packet,const std::string & remoteSchema) const1254 RelationalSyncOpinion AbilitySync::MakeRelationSyncOpinion(const AbilitySyncRequestPacket *packet,
1255     const std::string &remoteSchema) const
1256 {
1257     uint8_t remoteSchemaType = packet->GetSchemaType();
1258     RelationalSchemaObject localSchema = (static_cast<RelationalDBSyncInterface *>(storageInterface_))->GetSchemaInfo();
1259     return SchemaNegotiate::MakeLocalSyncOpinion(localSchema, remoteSchema, remoteSchemaType,
1260         packet->GetSoftwareVersion());
1261 }
1262 
HandleKvAckSchemaParam(const AbilitySyncAckPacket * recvPacket,ISyncTaskContext * context,AbilitySyncAckPacket & sendPacket,std::pair<bool,bool> & schemaSyncStatus)1263 int AbilitySync::HandleKvAckSchemaParam(const AbilitySyncAckPacket *recvPacket,
1264     ISyncTaskContext *context, AbilitySyncAckPacket &sendPacket, std::pair<bool, bool> &schemaSyncStatus)
1265 {
1266     std::string remoteSchema = recvPacket->GetSchema();
1267     uint8_t remoteSchemaType = recvPacket->GetSchemaType();
1268     bool permitSync = static_cast<bool>(recvPacket->GetPermitSync());
1269     bool requirePeerConvert = static_cast<bool>(recvPacket->GetRequirePeerConvert());
1270     SyncOpinion remoteOpinion = {permitSync, requirePeerConvert, true};
1271     SchemaObject localSchema = (static_cast<SingleVerKvDBSyncInterface *>(storageInterface_))->GetSchemaInfo();
1272     SyncOpinion syncOpinion = SchemaNegotiate::MakeLocalSyncOpinion(localSchema, remoteSchema, remoteSchemaType);
1273     SyncStrategy localStrategy = SchemaNegotiate::ConcludeSyncStrategy(syncOpinion, remoteOpinion);
1274     SetAbilityAckSyncOpinionInfo(sendPacket, syncOpinion);
1275     (static_cast<SingleVerKvSyncTaskContext *>(context))->SetSyncStrategy(localStrategy, true);
1276     schemaSyncStatus = {
1277         localStrategy.permitSync,
1278         true
1279     };
1280     if (localStrategy.permitSync) { // LCOV_EXCL_BR_LINE
1281         RecordAbilitySyncFinish(recvPacket->GetSchemaVersion(), *context);
1282     }
1283     if (IsBothKvAndOptAbilitySync(context->GetRemoteSoftwareVersion(),
1284         localSchema.GetSchemaType(), remoteSchemaType)) { // LCOV_EXCL_BR_LINE
1285         return -E_ABILITY_SYNC_FINISHED;
1286     }
1287     return E_OK;
1288 }
1289 
HandleRelationAckSchemaParam(const AbilitySyncAckPacket * recvPacket,AbilitySyncAckPacket & sendPacket,ISyncTaskContext * context,bool sendOpinion,std::pair<bool,bool> & schemaSyncStatus)1290 int AbilitySync::HandleRelationAckSchemaParam(const AbilitySyncAckPacket *recvPacket, AbilitySyncAckPacket &sendPacket,
1291     ISyncTaskContext *context, bool sendOpinion, std::pair<bool, bool> &schemaSyncStatus)
1292 {
1293     std::string remoteSchema = recvPacket->GetSchema();
1294     uint8_t remoteSchemaType = recvPacket->GetSchemaType();
1295     auto localSchema = (static_cast<RelationalDBSyncInterface *>(storageInterface_))->GetSchemaInfo();
1296     auto localOpinion = SchemaNegotiate::MakeLocalSyncOpinion(localSchema, remoteSchema, remoteSchemaType,
1297         recvPacket->GetSoftwareVersion());
1298     auto localStrategy = SchemaNegotiate::ConcludeSyncStrategy(localOpinion,
1299         recvPacket->GetRelationalSyncOpinion());
1300     (static_cast<SingleVerRelationalSyncTaskContext *>(context))->SetRelationalSyncStrategy(localStrategy, true);
1301     bool permitSync = std::any_of(localStrategy.begin(), localStrategy.end(),
1302         [] (const std::pair<std::string, SyncStrategy> &it) {
1303         return it.second.permitSync;
1304         });
1305     if (permitSync) {
1306         int innerErrCode = (static_cast<RelationalDBSyncInterface *>(storageInterface_)->SaveRemoteDeviceSchema(
1307             deviceId_, remoteSchema, remoteSchemaType));
1308         if (innerErrCode != E_OK) {
1309             LOGE("[AbilitySync][AckRecv] save remote device Schema failed,errCode=%d", innerErrCode);
1310             return innerErrCode;
1311         }
1312     }
1313     int errCode = (static_cast<RelationalDBSyncInterface *>(storageInterface_))->
1314         CreateDistributedDeviceTable(context->GetDeviceId(), localStrategy);
1315     if (errCode != E_OK) {
1316         LOGE("[AbilitySync][AckRecv] create distributed device table failed,errCode=%d", errCode);
1317     }
1318     if (sendOpinion) {
1319         sendPacket.SetRelationalSyncOpinion(localOpinion);
1320     }
1321     auto singleVerContext = static_cast<SingleVerSyncTaskContext *>(context);
1322     auto strategy = localStrategy.find(singleVerContext->GetQuery().GetRelationTableName());
1323     schemaSyncStatus = {
1324         !(strategy == localStrategy.end()) && strategy->second.permitSync,
1325         true
1326     };
1327     if (permitSync) {
1328         RecordAbilitySyncFinish(recvPacket->GetSchemaVersion(), *context);
1329     }
1330     return errCode;
1331 }
1332 
AckRecvWithHighVersion(const Message * message,ISyncTaskContext * context,const AbilitySyncAckPacket * packet)1333 int AbilitySync::AckRecvWithHighVersion(const Message *message, ISyncTaskContext *context,
1334     const AbilitySyncAckPacket *packet)
1335 {
1336     HandleVersionV3AckSecOptionParam(packet, context);
1337     AbilitySyncAckPacket ackPacket;
1338     std::pair<bool, bool> schemaSyncStatus;
1339     int errCode = E_OK;
1340     if (context->GetRemoteSoftwareVersion() > SOFTWARE_VERSION_RELEASE_3_0) {
1341         errCode = metadata_->SetDbCreateTime(deviceId_, context->GetTargetUserId(), packet->GetDbCreateTime(), true);
1342         if (errCode != E_OK) {
1343             LOGE("[AbilitySync][AckRecv] set db create time failed,errCode=%d", errCode);
1344             context->SetTaskErrCode(errCode);
1345             return errCode;
1346         }
1347     }
1348     errCode = HandleVersionV3AckSchemaParam(packet, ackPacket, context, true, schemaSyncStatus);
1349     DbAbility remoteDbAbility = packet->GetDbAbility();
1350     auto singleVerContext = static_cast<SingleVerSyncTaskContext *>(context);
1351     singleVerContext->SetDbAbility(remoteDbAbility);
1352     if (errCode == -E_ABILITY_SYNC_FINISHED) {
1353         return errCode;
1354     }
1355     if (errCode != E_OK) {
1356         context->SetTaskErrCode(errCode);
1357         return errCode;
1358     }
1359     if (!schemaSyncStatus.first) {
1360         singleVerContext->SetTaskErrCode(-E_SCHEMA_MISMATCH);
1361         LOGE("[AbilitySync][AckRecv] scheme check failed");
1362         return -E_SCHEMA_MISMATCH;
1363     }
1364     (void)SendAck(context, message, AbilitySync::CHECK_SUCCESS, true, ackPacket);
1365     return E_OK;
1366 }
1367 
TransformSecLabelIfNeed(int32_t originLabel,int targetLabel)1368 int32_t AbilitySync::TransformSecLabelIfNeed(int32_t originLabel, int targetLabel)
1369 {
1370     if ((originLabel == S0 && targetLabel == S1) || (originLabel == S1 && targetLabel == S0)) {
1371         LOGI("[AbilitySync] Accept SecLabel From %d To %d", originLabel, targetLabel);
1372         return targetLabel;
1373     }
1374     return originLabel;
1375 }
1376 
IsBothKvAndOptAbilitySync(uint32_t remoteVersion,SchemaType localType,uint8_t remoteType)1377 bool AbilitySync::IsBothKvAndOptAbilitySync(uint32_t remoteVersion, SchemaType localType, uint8_t remoteType)
1378 {
1379     return remoteVersion >= SOFTWARE_VERSION_RELEASE_8_0 && localType == SchemaType::NONE &&
1380         static_cast<SchemaType>(remoteType) == SchemaType::NONE;
1381 }
1382 
InitAbilitySyncFinishStatus(ISyncTaskContext & context)1383 void AbilitySync::InitAbilitySyncFinishStatus(ISyncTaskContext &context)
1384 {
1385     if (!metadata_->IsAbilitySyncFinish(context.GetDeviceId(), context.GetTargetUserId())) {
1386         return;
1387     }
1388     LOGI("[AbilitySync] Mark ability sync finish from db status");
1389     syncFinished_ = true;
1390     if (context.GetRemoteSoftwareVersion() == 0u) { // LCOV_EXCL_BR_LINE
1391         LOGI("[AbilitySync] Init remote version with default");
1392         context.SetRemoteSoftwareVersion(SOFTWARE_VERSION_RELEASE_9_0); // remote version >= 109
1393     }
1394     InitRemoteDBAbility(context);
1395 }
1396 
InitRemoteDBAbility(ISyncTaskContext & context)1397 void AbilitySync::InitRemoteDBAbility(ISyncTaskContext &context)
1398 {
1399     DbAbility ability;
1400     int errCode = GetDbAbilityInfo(ability);
1401     if (errCode != E_OK) {
1402         return;
1403     }
1404     context.SetDbAbility(ability);
1405     auto version = static_cast<uint32_t>(metadata_->GetRemoteSoftwareVersion(context.GetDeviceId(),
1406         context.GetTargetUserId()));
1407     // 111 trunk ver record schema version as software version
1408     // should clear it and do ability sync again
1409     if (version > SOFTWARE_VERSION_MAX) {
1410         context.SetRemoteSoftwareVersion(SOFTWARE_VERSION_RELEASE_9_0); // remote version is greater than 109
1411         SetAbilitySyncFinishedStatus(false, context);
1412         (void)metadata_->SetRemoteSoftwareVersion(deviceId_, context.GetTargetUserId(), SOFTWARE_VERSION_RELEASE_9_0);
1413         LOGW("[AbilitySync] Remote schema version is invalid[% " PRIu32 "]", version);
1414         return;
1415     }
1416     if (version > 0) {
1417         context.SetRemoteSoftwareVersion(version);
1418     }
1419 }
1420 
RecordAbilitySyncFinish(uint64_t remoteSchemaVersion,ISyncTaskContext & context)1421 void AbilitySync::RecordAbilitySyncFinish(uint64_t remoteSchemaVersion, ISyncTaskContext &context)
1422 {
1423     SetAbilitySyncFinishedStatus(true, context);
1424     if (context.GetRemoteSoftwareVersion() >= SOFTWARE_VERSION_RELEASE_9_0) { // LCOV_EXCL_BR_LINE
1425         (void)metadata_->SetRemoteSchemaVersion(deviceId_, context.GetTargetUserId(), remoteSchemaVersion);
1426     }
1427     (void)metadata_->SetRemoteSoftwareVersion(deviceId_, context.GetTargetUserId(), context.GetRemoteSoftwareVersion());
1428 }
1429 } // namespace DistributedDB