1 /*
2  * Copyright (c) 2023-2024 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 "dp_subscribe_info.h"
17 #include "cJSON.h"
18 #include "distributed_device_profile_constants.h"
19 #include "ipc_utils.h"
20 #include "macro_utils.h"
21 #include "profile_change_listener_stub.h"
22 #include "profile_utils.h"
23 
24 namespace OHOS {
25 namespace DistributedDeviceProfile {
26 namespace {
27     const std::string TAG = "SubscribeInfo";
28 }
SubscribeInfo(int32_t saId,const std::string & subscribeKey,std::unordered_set<ProfileChangeType> subscribeChangeTypes,sptr<IProfileChangeListener> profileChangeListener)29 SubscribeInfo::SubscribeInfo(int32_t saId, const std::string& subscribeKey,
30     std::unordered_set<ProfileChangeType> subscribeChangeTypes, sptr<IProfileChangeListener> profileChangeListener)
31 {
32     this->saId_ = saId;
33     this->subscribeKey_ = subscribeKey;
34     this->subscribeChangeTypes_ = subscribeChangeTypes;
35     if (profileChangeListener == nullptr) {
36         HILOGI("constructor!");
37         return;
38     }
39     if (profileChangeListener->AsObject() == nullptr) {
40         HILOGI("constructor!");
41         return;
42     }
43     this->listener_ = profileChangeListener->AsObject();
44 }
45 
SubscribeInfo()46 SubscribeInfo::SubscribeInfo()
47 {
48 }
49 
~SubscribeInfo()50 SubscribeInfo::~SubscribeInfo()
51 {
52 }
53 
GetSaId() const54 int32_t SubscribeInfo::GetSaId() const
55 {
56     return saId_;
57 }
58 
SetSaId(int32_t saId)59 void SubscribeInfo::SetSaId(int32_t saId)
60 {
61     saId_ = saId;
62 }
63 
SetSubscribeKey(const std::string & deviceId,const std::string & deviceAttribute)64 void SubscribeInfo::SetSubscribeKey(const std::string& deviceId, const std::string& deviceAttribute)
65 {
66     subscribeKey_ = DEV_PREFIX + SEPARATOR + deviceId + SEPARATOR + deviceAttribute;
67 }
68 
SetSubscribeKey(const std::string & deviceId,const std::string & serviceName,const std::string & serviceAttribute)69 void SubscribeInfo::SetSubscribeKey(const std::string& deviceId, const std::string& serviceName,
70     const std::string& serviceAttribute)
71 {
72     subscribeKey_ = SVR_PREFIX + SEPARATOR + deviceId + SEPARATOR + serviceName + SEPARATOR + serviceAttribute;
73 }
SetSubscribeKey(const std::string & deviceId,const std::string & serviceName,const std::string & characteristicKey,const std::string & characteristicAttribute)74 void SubscribeInfo::SetSubscribeKey(const std::string& deviceId, const std::string& serviceName,
75     const std::string& characteristicKey, const std::string& characteristicAttribute)
76 {
77     subscribeKey_ = CHAR_PREFIX + SEPARATOR + deviceId + SEPARATOR + serviceName + SEPARATOR + characteristicKey +
78         SEPARATOR + characteristicAttribute;
79 }
80 
GetSubscribeKey() const81 std::string SubscribeInfo::GetSubscribeKey() const
82 {
83     return subscribeKey_;
84 }
85 
SetSubscribeKey(const std::string & subscribeKey)86 void SubscribeInfo::SetSubscribeKey(const std::string& subscribeKey)
87 {
88     subscribeKey_ = subscribeKey;
89 }
90 
GetListener() const91 sptr<IRemoteObject> SubscribeInfo::GetListener() const
92 {
93     return listener_;
94 }
95 
GetProfileChangeTypes() const96 std::unordered_set<ProfileChangeType> SubscribeInfo::GetProfileChangeTypes() const
97 {
98     return subscribeChangeTypes_;
99 }
100 
AddProfileChangeType(ProfileChangeType profileChangeType)101 void SubscribeInfo::AddProfileChangeType(ProfileChangeType profileChangeType)
102 {
103     if (profileChangeType <= PROFILE_CHANGE_TYPE_MIN || profileChangeType >= PROFILE_CHANGE_TYPE_MAX) {
104         return;
105     }
106     if (subscribeChangeTypes_.size() > MAX_SUBSCRIBE_CHANGE_SIZE) {
107         return;
108     }
109     subscribeChangeTypes_.emplace(profileChangeType);
110 }
111 
SetListener(sptr<IProfileChangeListener> listener)112 void SubscribeInfo::SetListener(sptr<IProfileChangeListener> listener)
113 {
114     if (listener == nullptr) {
115         HILOGE("listener is null!");
116         return;
117     }
118     if (listener->AsObject() == nullptr) {
119         HILOGE("listener cast fail!");
120         return;
121     }
122     listener_ = listener->AsObject();
123 }
124 
Marshalling(MessageParcel & parcel) const125 bool SubscribeInfo::Marshalling(MessageParcel& parcel) const
126 {
127     WRITE_HELPER_RET(parcel, Int32, saId_, false);
128     WRITE_HELPER_RET(parcel, String, subscribeKey_, false);
129     IpcUtils::Marshalling(parcel, subscribeChangeTypes_);
130     WRITE_HELPER_RET(parcel, RemoteObject, listener_, false);
131     return true;
132 }
133 
UnMarshalling(MessageParcel & parcel)134 bool SubscribeInfo::UnMarshalling(MessageParcel& parcel)
135 {
136     READ_HELPER_RET(parcel, Int32, saId_, false);
137     READ_HELPER_RET(parcel, String, subscribeKey_, false);
138     IpcUtils::UnMarshalling(parcel, subscribeChangeTypes_);
139     listener_ = parcel.ReadRemoteObject();
140     if (listener_ == nullptr) {
141         HILOGE("read remoteObject failed!");
142         return false;
143     }
144     return true;
145 }
146 
dump() const147 std::string SubscribeInfo::dump() const
148 {
149     cJSON* json = cJSON_CreateObject();
150     if (!cJSON_IsObject(json)) {
151         cJSON_Delete(json);
152         return EMPTY_STRING;
153     }
154     cJSON_AddNumberToObject(json, SA_ID.c_str(), saId_);
155     cJSON_AddStringToObject(json, SUBSCRIBE_KEY.c_str(), ProfileUtils::GetDbKeyAnonyString(subscribeKey_).c_str());
156     cJSON* jsonArr = cJSON_CreateArray();
157     if (!cJSON_IsArray(jsonArr)) {
158         cJSON_Delete(jsonArr);
159     } else {
160         for (const auto &subChangeType : subscribeChangeTypes_) {
161             cJSON* jsonArrItem = cJSON_CreateNumber(static_cast<int32_t>(subChangeType));
162             if (jsonArrItem == NULL) {
163                 continue;
164             }
165             if (!cJSON_AddItemToArray(jsonArr, jsonArrItem)) {
166                 cJSON_Delete(jsonArrItem);
167                 continue;
168             }
169         }
170         if (!cJSON_AddItemToObject(json, SUBSCRIBE_CHANGE_TYPES.c_str(), jsonArr)) {
171             HILOGE("cJSON formatted to string failed!");
172             cJSON_Delete(jsonArr);
173         }
174     }
175     char* jsonChars = cJSON_PrintUnformatted(json);
176     if (jsonChars == NULL) {
177         cJSON_Delete(json);
178         HILOGE("cJSON formatted to string failed!");
179         return EMPTY_STRING;
180     }
181     std::string jsonStr = jsonChars;
182     cJSON_Delete(json);
183     cJSON_free(jsonChars);
184     return jsonStr;
185 }
186 } // namespace DistributedDeviceProfile
187 } // namespace OHOS
188 
189