1 /*
2  * Copyright (c) 2020 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 "dmslite_famgr.h"
17 
18 #include <malloc.h>
19 
20 #include "dmslite_feature.h"
21 #include "dmslite_log.h"
22 #include "dmslite_packet.h"
23 #include "dmslite_permission.h"
24 #include "dmslite_session.h"
25 #include "dmslite_tlv_common.h"
26 #include "dmslite_utils.h"
27 
28 #include "message.h"
29 #include "ohos_errno.h"
30 #include "securec.h"
31 
32 #define DMS_VERSION_VALUE 200
33 #define ENDING_SYMBOL_LEN 1
34 
35 static int32_t FillRequestData(RequestData *reqdata, const Want *want,
36     const CallerInfo *callerInfo, const IDmsListener *callback);
37 static int32_t MarshallDmsMessage(const Want *want, const CallerInfo *callerInfo);
38 
StartAbilityFromRemote(const char * bundleName,const char * abilityName,StartAbilityCallback onStartAbilityDone)39 int32_t StartAbilityFromRemote(const char *bundleName, const char *abilityName,
40     StartAbilityCallback onStartAbilityDone)
41 {
42     return EC_SUCCESS;
43 }
44 
StartRemoteAbilityInner(const Want * want,const CallerInfo * callerInfo,const IDmsListener * callback)45 int32_t StartRemoteAbilityInner(const Want *want, const CallerInfo *callerInfo,
46     const IDmsListener *callback)
47 {
48     if (want == NULL || want->element == NULL || callerInfo == NULL) {
49         HILOGE("[param error!]");
50         return DMS_EC_FAILURE;
51     }
52     RequestData *reqdata = (RequestData *)DMS_ALLOC(sizeof(RequestData));
53     if (reqdata == NULL) {
54         HILOGE("[mem alloc error!]");
55         return DMS_EC_FAILURE;
56     }
57     if (memset_s(reqdata, sizeof(RequestData), 0x00, sizeof(RequestData)) != EOK) {
58         DMS_FREE(reqdata);
59         HILOGE("[RequestData memset failed]");
60         return DMS_EC_FAILURE;
61     }
62 
63     if (FillRequestData(reqdata, want, callerInfo, callback) != DMS_EC_SUCCESS) {
64         FreeRequestData(reqdata->want, reqdata->callerInfo);
65         DMS_FREE(reqdata);
66         HILOGE("[FillRequestData failed]");
67         return DMS_EC_FAILURE;
68     }
69 
70     Request request = {
71         .msgId = START_REMOTE_ABILITY,
72         .data = (void *)reqdata,
73         .len = sizeof(RequestData),
74         .msgValue = 0
75     };
76     int32_t result = SAMGR_SendRequest((const Identity*)&(GetDmsLiteFeature()->identity), &request, NULL);
77     if (result != EC_SUCCESS) {
78         FreeRequestData(reqdata->want, reqdata->callerInfo);
79         DMS_FREE(reqdata);
80         HILOGD("[StartRemoteAbilityInner SendRequest errCode = %d]", result);
81     }
82     return result;
83 }
84 
StartRemoteAbility(const Want * want,CallerInfo * callerInfo,IDmsListener * callback)85 int32_t StartRemoteAbility(const Want *want, CallerInfo *callerInfo, IDmsListener *callback)
86 {
87     HILOGI("[StartRemoteAbility]");
88     if (want == NULL || want->element == NULL || callerInfo == NULL) {
89         return DMS_EC_INVALID_PARAMETER;
90     }
91     if (IsDmsBusy()) {
92         HILOGI("[StartRemoteAbility dms busy]");
93         return DMS_EC_FAILURE;
94     }
95 #ifndef XTS_SUITE_TEST
96     if (!PreprareBuild()) {
97         return DMS_EC_FAILURE;
98     }
99 #endif
100     if (MarshallDmsMessage(want, callerInfo) != DMS_EC_SUCCESS) {
101         return DMS_EC_FAILURE;
102     }
103 #ifndef XTS_SUITE_TEST
104     int32_t ret = SendDmsMessage(GetPacketBufPtr(), GetPacketSize(),
105         want->element->deviceId, callback);
106     return ret;
107 #else
108     return DMS_EC_SUCCESS;
109 #endif
110 }
111 
MarshallDmsMessage(const Want * want,const CallerInfo * callerInfo)112 static int32_t MarshallDmsMessage(const Want *want, const CallerInfo *callerInfo)
113 {
114     PACKET_MARSHALL_HELPER(Uint16, COMMAND_ID, DMS_MSG_CMD_START_FA);
115     PACKET_MARSHALL_HELPER(Uint16, DMS_VERSION, DMS_VERSION_VALUE);
116     PACKET_MARSHALL_HELPER(String, CALLEE_BUNDLE_NAME, want->element->bundleName);
117     PACKET_MARSHALL_HELPER(String, CALLEE_ABILITY_NAME, want->element->abilityName);
118 
119     BundleInfo bundleInfo = {0};
120     int32_t ret = GetCallerBundleInfo(callerInfo, &bundleInfo);
121     if (ret != DMS_EC_SUCCESS) {
122         HILOGE("[StartRemoteAbility GetCallerBundleInfo error = %d]", ret);
123         return DMS_EC_FAILURE;
124     }
125     if (!MarshallString(bundleInfo.appId, CALLER_SIGNATURE)) {
126         HILOGE("[StartRemoteAbility Marshall appId failed]");
127         ClearBundleInfo(&bundleInfo);
128         return DMS_EC_FAILURE;
129     }
130     ClearBundleInfo(&bundleInfo);
131 
132     if (want->data != NULL && want->dataLength > 0) {
133         RAWDATA_MARSHALL_HELPER(RawData, CALLER_PAYLOAD, want->data, want->dataLength);
134     }
135     return DMS_EC_SUCCESS;
136 }
137 
FillCallerInfo(RequestData * reqdata,const CallerInfo * callerInfo)138 static int32_t FillCallerInfo(RequestData *reqdata, const CallerInfo *callerInfo)
139 {
140     if (callerInfo == NULL || reqdata == NULL) {
141         return DMS_EC_FAILURE;
142     }
143     CallerInfo *callerData = (CallerInfo *)DMS_ALLOC(sizeof(CallerInfo));
144     if (callerData == NULL) {
145         return DMS_EC_FAILURE;
146     }
147     if (memset_s(callerData, sizeof(CallerInfo), 0x00, sizeof(CallerInfo)) != EOK) {
148         DMS_FREE(callerData);
149         HILOGE("[CallerInfo memset error]");
150         return DMS_EC_FAILURE;
151     }
152     reqdata->callerInfo = callerData;
153 
154     callerData->uid = callerInfo->uid;
155     if (callerInfo->bundleName != NULL) {
156         int32_t size = strlen(callerInfo->bundleName) + ENDING_SYMBOL_LEN;
157         char *data = (char *)DMS_ALLOC(size);
158         if (data == NULL) {
159             return DMS_EC_FAILURE;
160         }
161         if (memcpy_s(data, size, callerInfo->bundleName, size) != EOK) {
162             DMS_FREE(data);
163             return DMS_EC_FAILURE;
164         }
165         data[size - ENDING_SYMBOL_LEN] = '\0';
166         callerData->bundleName = data;
167     }
168     return DMS_EC_SUCCESS;
169 }
170 
FillRequestData(RequestData * reqdata,const Want * want,const CallerInfo * callerInfo,const IDmsListener * callback)171 static int32_t FillRequestData(RequestData *reqdata, const Want *want,
172     const CallerInfo *callerInfo, const IDmsListener *callback)
173 {
174     Want *wantData = (Want *)DMS_ALLOC(sizeof(Want));
175     if (wantData == NULL) {
176         return DMS_EC_FAILURE;
177     }
178     if (memset_s(wantData, sizeof(Want), 0x00, sizeof(Want)) != EOK) {
179         DMS_FREE(wantData);
180         return DMS_EC_FAILURE;
181     }
182     reqdata->want = wantData;
183 
184     ElementName elementData;
185     if (memset_s(&elementData, sizeof(ElementName), 0x00, sizeof(ElementName)) != EOK) {
186         return DMS_EC_FAILURE;
187     }
188     if (!(SetElementBundleName(&elementData, want->element->bundleName)
189         && SetElementAbilityName(&elementData, want->element->abilityName)
190         && SetElementDeviceID(&elementData, want->element->deviceId)
191         && SetWantElement(wantData, elementData))) {
192         HILOGE("[FillRequestData error]");
193         ClearElement(&elementData);
194         ClearWant(wantData);
195         return DMS_EC_FAILURE;
196     }
197     ClearElement(&elementData);
198 
199     if (want->data != NULL && want->dataLength > 0) {
200         void *data = DMS_ALLOC(want->dataLength);
201         if (data == NULL) {
202             return DMS_EC_FAILURE;
203         }
204         if (memcpy_s(data, want->dataLength, want->data, want->dataLength) != EOK) {
205             DMS_FREE(data);
206             return DMS_EC_FAILURE;
207         }
208         wantData->data = data;
209         wantData->dataLength = want->dataLength;
210     }
211 
212     if (FillCallerInfo(reqdata, callerInfo) != DMS_EC_SUCCESS) {
213         return DMS_EC_FAILURE;
214     }
215 
216     reqdata->callback = (IDmsListener *)callback;
217     return DMS_EC_SUCCESS;
218 }
219 
FreeRequestData(const Want * want,CallerInfo * callerInfo)220 void FreeRequestData(const Want *want, CallerInfo *callerInfo)
221 {
222     if (want != NULL) {
223         ClearWant((Want *)want);
224         DMS_FREE(want);
225     }
226 
227     if (callerInfo != NULL) {
228         DMS_FREE(callerInfo->bundleName);
229         DMS_FREE(callerInfo);
230     }
231 }