1 // Copyright 2018 Espressif Systems (Shanghai) PTE LTD
2 //
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 #pragma once
16 
17 #include <protocomm_security.h>
18 #include <esp_err.h>
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 /**
25  * @brief Function prototype for protocomm endpoint handler
26  */
27 typedef esp_err_t (*protocomm_req_handler_t)(
28     uint32_t        session_id, /*!< Session ID for identifying protocomm client */
29     const uint8_t  *inbuf,      /*!< Pointer to user provided input data buffer */
30     ssize_t         inlen,      /*!< Length o the input buffer */
31     uint8_t       **outbuf,     /*!< Pointer to output buffer allocated by handler */
32     ssize_t        *outlen,     /*!< Length of the allocated output buffer */
33     void           *priv_data   /*!< Private data passed to the handler (NULL if not used) */
34 );
35 
36 /**
37  * @brief   This structure corresponds to a unique instance of protocomm
38  *          returned when the API `protocomm_new()` is called. The remaining
39  *          Protocomm APIs require this object as the first parameter.
40  *
41  * @note    Structure of the protocomm object is kept private
42  */
43 typedef struct protocomm protocomm_t;
44 
45 /**
46  * @brief   Create a new protocomm instance
47  *
48  * This API will return a new dynamically allocated protocomm instance
49  * with all elements of the protocomm_t structure initialized to NULL.
50  *
51  * @return
52  *  - protocomm_t* : On success
53  *  - NULL : No memory for allocating new instance
54  */
55 protocomm_t *protocomm_new(void);
56 
57 /**
58  * @brief   Delete a protocomm instance
59  *
60  * This API will deallocate a protocomm instance that was created
61  * using `protocomm_new()`.
62  *
63  * @param[in] pc    Pointer to the protocomm instance to be deleted
64  */
65 void protocomm_delete(protocomm_t *pc);
66 
67 /**
68  * @brief   Add endpoint request handler for a protocomm instance
69  *
70  * This API will bind an endpoint handler function to the specified
71  * endpoint name, along with any private data that needs to be pass to
72  * the handler at the time of call.
73  *
74  * @note
75  *  - An endpoint must be bound to a valid protocomm instance,
76  *    created using `protocomm_new()`.
77  *  - This function internally calls the registered `add_endpoint()`
78  *    function of the selected transport which is a member of the
79  *    protocomm_t instance structure.
80  *
81  * @param[in] pc        Pointer to the protocomm instance
82  * @param[in] ep_name   Endpoint identifier(name) string
83  * @param[in] h         Endpoint handler function
84  * @param[in] priv_data Pointer to private data to be passed as a
85  *                      parameter to the handler function on call.
86  *                      Pass NULL if not needed.
87  *
88  * @return
89  *  - ESP_OK : Success
90  *  - ESP_FAIL : Error adding endpoint / Endpoint with this name already exists
91  *  - ESP_ERR_NO_MEM : Error allocating endpoint resource
92  *  - ESP_ERR_INVALID_ARG : Null instance/name/handler arguments
93  */
94 esp_err_t protocomm_add_endpoint(protocomm_t *pc, const char *ep_name,
95                                  protocomm_req_handler_t h, void *priv_data);
96 
97 /**
98  * @brief   Remove endpoint request handler for a protocomm instance
99  *
100  * This API will remove a registered endpoint handler identified by
101  * an endpoint name.
102  *
103  * @note
104  *  - This function internally calls the registered `remove_endpoint()`
105  *    function which is a member of the protocomm_t instance structure.
106  *
107  * @param[in] pc        Pointer to the protocomm instance
108  * @param[in] ep_name   Endpoint identifier(name) string
109  *
110  * @return
111  *  - ESP_OK : Success
112  *  - ESP_ERR_NOT_FOUND : Endpoint with specified name doesn't exist
113  *  - ESP_ERR_INVALID_ARG : Null instance/name arguments
114  */
115 esp_err_t protocomm_remove_endpoint(protocomm_t *pc, const char *ep_name);
116 
117 /**
118  * @brief   Allocates internal resources for new transport session
119  *
120  * @note
121  *  - An endpoint must be bound to a valid protocomm instance,
122  *    created using `protocomm_new()`.
123  *
124  * @param[in]  pc         Pointer to the protocomm instance
125  * @param[in]  session_id Unique ID for a communication session
126  *
127  * @return
128  *  - ESP_OK : Request handled successfully
129  *  - ESP_ERR_NO_MEM : Error allocating internal resource
130  *  - ESP_ERR_INVALID_ARG : Null instance/name arguments
131  */
132 esp_err_t protocomm_open_session(protocomm_t *pc, uint32_t session_id);
133 
134 /**
135  * @brief   Frees internal resources used by a transport session
136  *
137  * @note
138  *  - An endpoint must be bound to a valid protocomm instance,
139  *    created using `protocomm_new()`.
140  *
141  * @param[in]  pc         Pointer to the protocomm instance
142  * @param[in]  session_id Unique ID for a communication session
143  *
144  * @return
145  *  - ESP_OK : Request handled successfully
146  *  - ESP_ERR_INVALID_ARG : Null instance/name arguments
147  */
148 esp_err_t protocomm_close_session(protocomm_t *pc, uint32_t session_id);
149 
150 /**
151  * @brief   Calls the registered handler of an endpoint session
152  *          for processing incoming data and generating the response
153  *
154  * @note
155  *  - An endpoint must be bound to a valid protocomm instance,
156  *    created using `protocomm_new()`.
157  *  - Resulting output buffer must be deallocated by the caller.
158  *
159  * @param[in]  pc         Pointer to the protocomm instance
160  * @param[in]  ep_name    Endpoint identifier(name) string
161  * @param[in]  session_id Unique ID for a communication session
162  * @param[in]  inbuf      Input buffer contains input request data which is to be
163  *                        processed by the registered handler
164  * @param[in]  inlen      Length of the input buffer
165  * @param[out] outbuf     Pointer to internally allocated output buffer,
166  *                        where the resulting response data output from
167  *                        the registered handler is to be stored
168  * @param[out] outlen     Buffer length of the allocated output buffer
169  *
170  * @return
171  *  - ESP_OK : Request handled successfully
172  *  - ESP_FAIL : Internal error in execution of registered handler
173  *  - ESP_ERR_NO_MEM : Error allocating internal resource
174  *  - ESP_ERR_NOT_FOUND : Endpoint with specified name doesn't exist
175  *  - ESP_ERR_INVALID_ARG : Null instance/name arguments
176  */
177 esp_err_t protocomm_req_handle(protocomm_t *pc, const char *ep_name, uint32_t session_id,
178                                const uint8_t *inbuf, ssize_t inlen,
179                                uint8_t **outbuf, ssize_t *outlen);
180 
181 /**
182  * @brief   Add endpoint security for a protocomm instance
183  *
184  * This API will bind a security session establisher to the specified
185  * endpoint name, along with any proof of possession that may be required
186  * for authenticating a session client.
187  *
188  * @note
189  *  - An endpoint must be bound to a valid protocomm instance,
190  *    created using `protocomm_new()`.
191  *  - The choice of security can be any `protocomm_security_t` instance.
192  *    Choices `protocomm_security0` and `protocomm_security1` are readily available.
193  *
194  * @param[in] pc        Pointer to the protocomm instance
195  * @param[in] ep_name   Endpoint identifier(name) string
196  * @param[in] sec       Pointer to endpoint security instance
197  * @param[in] pop       Pointer to proof of possession for authenticating a client
198  *
199  * @return
200  *  - ESP_OK : Success
201  *  - ESP_FAIL : Error adding endpoint / Endpoint with this name already exists
202  *  - ESP_ERR_INVALID_STATE : Security endpoint already set
203  *  - ESP_ERR_NO_MEM : Error allocating endpoint resource
204  *  - ESP_ERR_INVALID_ARG : Null instance/name/handler arguments
205  */
206 esp_err_t protocomm_set_security(protocomm_t *pc, const char *ep_name,
207                                  const protocomm_security_t *sec,
208                                  const protocomm_security_pop_t *pop);
209 
210 /**
211  * @brief   Remove endpoint security for a protocomm instance
212  *
213  * This API will remove a registered security endpoint identified by
214  * an endpoint name.
215  *
216  * @param[in] pc        Pointer to the protocomm instance
217  * @param[in] ep_name   Endpoint identifier(name) string
218  *
219  * @return
220  *  - ESP_OK : Success
221  *  - ESP_ERR_NOT_FOUND : Endpoint with specified name doesn't exist
222  *  - ESP_ERR_INVALID_ARG : Null instance/name arguments
223  */
224 esp_err_t protocomm_unset_security(protocomm_t *pc, const char *ep_name);
225 
226 /**
227  * @brief   Set endpoint for version verification
228  *
229  * This API can be used for setting an application specific protocol
230  * version which can be verified by clients through the endpoint.
231  *
232  * @note
233  *  - An endpoint must be bound to a valid protocomm instance,
234  *    created using `protocomm_new()`.
235 
236  * @param[in] pc        Pointer to the protocomm instance
237  * @param[in] ep_name   Endpoint identifier(name) string
238  * @param[in] version   Version identifier(name) string
239  *
240  * @return
241  *  - ESP_OK : Success
242  *  - ESP_FAIL : Error adding endpoint / Endpoint with this name already exists
243  *  - ESP_ERR_INVALID_STATE : Version endpoint already set
244  *  - ESP_ERR_NO_MEM : Error allocating endpoint resource
245  *  - ESP_ERR_INVALID_ARG : Null instance/name/handler arguments
246  */
247 esp_err_t protocomm_set_version(protocomm_t *pc, const char *ep_name,
248                                 const char *version);
249 
250 /**
251  * @brief   Remove version verification endpoint from a protocomm instance
252  *
253  * This API will remove a registered version endpoint identified by
254  * an endpoint name.
255  *
256  * @param[in] pc        Pointer to the protocomm instance
257  * @param[in] ep_name   Endpoint identifier(name) string
258  *
259  * @return
260  *  - ESP_OK : Success
261  *  - ESP_ERR_NOT_FOUND : Endpoint with specified name doesn't exist
262  *  - ESP_ERR_INVALID_ARG : Null instance/name arguments
263  */
264 esp_err_t protocomm_unset_version(protocomm_t *pc, const char *ep_name);
265 
266 #ifdef __cplusplus
267 }
268 #endif
269