1 /*
2  * Copyright (c) 2021-2022 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 <hdf_dlist.h>
17 #include <hdf_log.h>
18 #include <hdf_remote_service.h>
19 #include <hdf_service_status_inner.h>
20 #include <osal_mem.h>
21 
22 #define SERVSTAT_LISTENER_INTERFACE_DESCRIPTOR "HDI.IServiceStatusListener.V1_0"
23 #define HDF_LOG_TAG servstat_listener
24 
25 struct ServstatListenerStub {
26     struct ServiceStatusListener listener;
27     struct HdfRemoteService *remote;
28 };
29 
ServstatListenerStubRemoteDispatch(struct HdfRemoteService * remote,int cmdid,struct HdfSBuf * data,struct HdfSBuf * reply)30 int ServstatListenerStubRemoteDispatch(
31     struct HdfRemoteService *remote, int cmdid, struct HdfSBuf *data, struct HdfSBuf *reply)
32 {
33     (void)reply;
34     struct ServstatListenerStub *stub = (struct ServstatListenerStub *)remote;
35     struct ServiceStatus status;
36 
37     if (cmdid != SERVIE_STATUS_LISTENER_NOTIFY) {
38         return HDF_ERR_NOT_SUPPORT;
39     }
40     if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
41         HDF_LOGE("failed to check interface");
42         return HDF_ERR_INVALID_PARAM;
43     }
44     if (ServiceStatusUnMarshalling(&status, data) != HDF_SUCCESS) {
45         return HDF_ERR_INVALID_PARAM;
46     }
47     HDF_LOGI("ServstatListenerStubRemoteDispatch: service name %{public}s", status.serviceName);
48 
49     if (stub->listener.callback != NULL) {
50         stub->listener.callback(&stub->listener, &status);
51         return HDF_SUCCESS;
52     }
53     return HDF_ERR_INVALID_OBJECT;
54 }
55 
ServiceStatusListenerMarshalling(struct ServiceStatusListener * listener,struct HdfSBuf * buf)56 int ServiceStatusListenerMarshalling(struct ServiceStatusListener *listener, struct HdfSBuf *buf)
57 {
58     if (listener == NULL || buf == NULL) {
59         return HDF_ERR_INVALID_PARAM;
60     }
61 
62     struct ServstatListenerStub *listenerStub = CONTAINER_OF(listener, struct ServstatListenerStub, listener);
63     if (listenerStub->remote == NULL) {
64         return HDF_ERR_INVALID_OBJECT;
65     }
66     return HdfSbufWriteRemoteService(buf, listenerStub->remote);
67 }
68 
HdiServiceStatusListenerNewInstance(void)69 struct ServiceStatusListener *HdiServiceStatusListenerNewInstance(void)
70 {
71     struct ServstatListenerStub *stub = OsalMemCalloc(sizeof(struct ServstatListenerStub));
72     if (stub == NULL) {
73         return NULL;
74     }
75     static struct HdfRemoteDispatcher remoteDispatch = {
76         .Dispatch = ServstatListenerStubRemoteDispatch,
77     };
78 
79     stub->remote = HdfRemoteServiceObtain((struct HdfObject *)stub, &remoteDispatch);
80     if (stub->remote == NULL) {
81         OsalMemFree(stub);
82         return NULL;
83     }
84     if (!HdfRemoteServiceSetInterfaceDesc(stub->remote, SERVSTAT_LISTENER_INTERFACE_DESCRIPTOR)) {
85         HdfRemoteServiceRecycle(stub->remote);
86         stub->remote = NULL;
87         OsalMemFree(stub);
88         return NULL;
89     }
90     return &stub->listener;
91 }
92 
HdiServiceStatusListenerFree(struct ServiceStatusListener * listener)93 void HdiServiceStatusListenerFree(struct ServiceStatusListener *listener)
94 {
95     if (listener == NULL) {
96         return;
97     }
98 
99     struct ServstatListenerStub *stub = CONTAINER_OF(listener, struct ServstatListenerStub, listener);
100     HdfRemoteServiceRecycle(stub->remote);
101     OsalMemFree(stub);
102 }