1 /*
2  * Copyright (c) 2020-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 /**
17  * @addtogroup Samgr
18  * @{
19  *
20  * @brief Manages system capabilities.
21  *
22  * This module provides the development framework base of the service-oriented architecture (SOA).
23  * You can develop your own abilities based on the Samgr development framework. \n
24  * This module provides basic models of services, features, and functions, and registration and
25  * discovery capabilities. \n
26  *
27  * @since 1.0
28  * @version 1.0
29  */
30 
31 /**
32  * @file message.h
33  *
34  * @brief Provides message communication APIs that help you to implement asynchronous functions
35  * of {@link IUnknown}.
36  *
37  * This API is used to implement asynchronous functions of {@link IUnknown}. \n
38  *
39  * @since 1.0
40  * @version 1.0
41  */
42 
43 #ifndef LITE_MESSAGE_H
44 #define LITE_MESSAGE_H
45 
46 #include "common.h"
47 
48 #ifdef __cplusplus
49 #if __cplusplus
50 extern "C" {
51 #endif
52 #endif
53 typedef struct Identity Identity;
54 typedef struct Request Request;
55 typedef struct Response Response;
56 
57 /**
58  * @brief Handles asynchronous responses.
59  *
60  * This function will be used when a service or feature uses {@link IUnknown} to send a request. \n
61  * If the caller is a feature, this function is used to handle the response that is sent after the
62  * feature processes a request. \n
63  * If the caller is a service, <b>Handler</b> will run in the service thread. \n
64  *
65  */
66 typedef void (*Handler)(const Request *request, const Response *response);
67 
68 // Will be used for message interaction, so use one-byte alignment
69 #pragma pack(1)
70 /**
71  * @brief Identifies a service and feature.
72  *
73  * You can use this structure to identity a {@link IUnknown} feature to which messages will be
74  * sent through the asynchronous function of {@link IUnknown}. \n
75  *
76  */
77 struct Identity {
78     /** Service ID */
79     int16 serviceId;
80     /** Feature ID */
81     int16 featureId;
82     /** Message queue ID */
83     MQueueId queueId;
84 };
85 
86 /**
87  * @brief Defines a request.
88  *
89  * You can use this structure to define the request that will be sent to a feature through the
90  * asynchronous function of {@link IUnknown}. \n
91  * Request, which is data that is packed to send to a feature. \n
92  * If the data is not empty and the length is not 0, the system automatically releases the data. \n
93  *
94  */
95 struct Request {
96     /** Message ID */
97     int16 msgId;
98     /** Data length */
99     int16 len;
100     /** Data content */
101     void *data;
102     /** Message value, which is defined by developers */
103     uint32 msgValue;
104 };
105 
106 /**
107  * @brief Defines a response.
108  *
109  * This structure is used to send a response after the message processing function of a service
110  * or feature processes a request. \n
111  * If the data is not empty and the length is not 0, the system automatically releases the data. \n
112  *
113  */
114 struct Response {
115     /** Data content */
116     void *data;
117     /** Data length */
118     int16 len;
119     void *reply;
120 };
121 #pragma pack()
122 
123 /**
124  * @brief Sends a request to a service or feature of a specified identity.
125  *
126  * This function is called by a service to send messages to its own features through the
127  * asynchronous function of {@link IUnknown}. \n
128  *
129  * @param identity Indicates the pointer to the ID of the feature or service that processes
130  * the message.
131  * @param request Indicates the pointer to the request.
132  * @param handler Indicates the function handling the response. If the value is <b>NULL</b>,
133  * no response is required.
134  * @return Returns <b>EC_SUCCESS</b> if the request is sent successfully; returns other error codes
135  * if the request fails to be sent. The caller needs to release the memory applied in the request.
136  * @since 1.0
137  * @version 1.0
138  */
139 int32 SAMGR_SendRequest(const Identity *identity, const Request *request, Handler handler);
140 
141 /**
142  * @brief Sends a request to multiple services or features to save memory.
143  *
144  * This function is used to publish topics for the {@link Broadcast} service to broadcast messages. \n
145  *
146  * @param identity Indicates the pointer to the IDs of services or features, to which requests
147  * are sent.
148  * @param request Indicates the pointer to the request.
149  * @param token Indicates the pointer to reference counting.
150  * @param handler Indicates the function handling the response. If the value is <b>NULL</b>,
151  * no response is required.
152  * @retval Returns the token if the request is sent successfully; returns <b>NULL</b> if the
153  * request fails to be sent.
154  * @attention
155  *  <ul><li>Ensure that the thread specified by <b>identity</b> processes the message after
156  *  all messages are sent. Common practice: Add a lock before sending a request and add
157  *  the same lock during processing. </li>
158  *  <li>If <b>NULL</b> is returned, the caller needs to release the memory of the request. </li></ul>
159  * @since 1.0
160  * @version 1.0
161  */
162 uint32 *SAMGR_SendSharedRequest(const Identity *identity, const Request *request, uint32 *token, Handler handler);
163 
164 /**
165  * @brief Sends a request and response of a caller to the feature thread. The handler is directly
166  * called to process the request and response without using the message processing functions.
167  * (Customized function for the broadcast service)
168  *
169  * This function is used to publish topics for the {@link Broadcast} service to broadcast messages. \n
170  * The value of reference counting is incremented by one each time this function is called. \n
171  *
172  * @param id Indicates the pointer to the IDs of services or features, to which the request and
173  * response are sent.
174  * @param request Indicates the pointer to the request.
175  * @param resp Indicates the pointer to the response.
176  * @param ref Indicates the reference counting.
177  * @param handler Indicates the function for handling the request and response. This parameter
178  * cannot be <b>NULL</b>.
179  * @return Returns <b>EC_SUCCESS</b> if the request and response are sent successfully; returns
180  * other error codes if the request and response fail to be sent.
181  * @attention
182  *  <ul><li>Ensure that the thread specified by <b>identity</b> processes the message after all
183  *  messages are sent. Common practice: Add a lock before sending a request and add the same lock
184  *  during processing. </li>
185  *  <li>If <b>NULL</b> is returned, the caller needs to release the memory of the request and
186  *  response. </li>
187  *  <li>If the response changes each time when a request is sent, ensure that the response
188  *  will not be released. (Set <b>len</b> to <b>0</b>, the <b>data</b> of response will be
189  *  the resident memory.) </li></ul>
190  * @since 1.0
191  * @version 1.0
192  */
193 int32 SAMGR_SendSharedDirectRequest(const Identity *id, const Request *req, const Response *resp, uint32 **ref,
194                                     Handler handler);
195 
196 /**
197  * @brief Sends a response after processing a request.
198  *
199  * This function is called to send a response after processing a request by {@link MessageHandle}
200  * of a service or {@link OnMessage} of a feature. \n
201  *
202  * @param request Indicates the pointer to the original request.
203  * @param response Indicates the pointer to the response content.
204  * @return Returns <b>EC_SUCCESS</b> if the response is sent successfully; returns other error
205  * codes if the response fails to be sent.
206  * @attention
207  *  <ul><li>This function can be called only in {@link MessageHandle} or {@link OnMessage}. </li>
208  *  <li>The request must be the original one passed from {@link MessageHandle} or
209  *  {@link OnMessage}. Otherwise, a memory exception occurs. </li>
210  *  <li> When the caller sends a request, the <b>handler</b> callback function must be carried. </li>
211  *  <li>The response is sent to the message queue of the service to which the requester belongs
212  *  for processing. Therefore, the requester should wait for the response in non-blocking mode. </li></ul>
213  * @since 1.0
214  * @version 1.0
215  */
216 int32 SAMGR_SendResponse(const Request *request, const Response *response);
217 
218 /**
219  * @brief Sends a response to a specified service or feature after processing the original request.
220  * (Customized function for <b>bootstrap</b>)
221  *
222  * This function is called to send a response after processing a request by {@link MessageHandle}
223  * of a service or {@link OnMessage} of a feature. \n
224  * This function can be customized to implement phased startup of different types of services. \n
225  *
226  * @param id Indicates the pointer to the ID of a service or feature. The response is sent to the
227  * thread of the service or feature for processing.
228  * @param request Indicates the pointer to the original request.
229  * @param response Indicates the pointer to the response content.
230  * @return Returns <b>EC_SUCCESS</b> if the response is sent successfully; returns other error
231  * codes if the response fails to be sent.
232  * @attention
233  *  <ul><li>This function can be called only in <b>MessageHandle</b> or <b>OnMessage</b>. </li>
234  *  <li>The request must be the original one passed from <b>MessageHandle</b> or <b>OnMessage</b>.
235  *  Otherwise, a memory exception occurs. </li>
236  *  <li> When the caller sends a request, the <b>handler</b> callback function must be carried. </li>
237  *  <li>The response is sent to the message queue of a specified ID for processing. Therefore,
238  *  wait for the response in non-blocking mode. </li></ul>
239  * @since 1.0
240  * @version 1.0
241  */
242 int32 SAMGR_SendResponseByIdentity(const Identity *id, const Request *request, const Response *response);
243 
244 #ifdef __cplusplus
245 #if __cplusplus
246 }
247 #endif
248 #endif
249 #endif // LITE_MESSAGE_H
250 /** @} */
251