1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 
5 #ifndef IOT_EXPORT_HTTP2_H
6 #define IOT_EXPORT_HTTP2_H
7 
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11 
12 #include "linkkit/http2_api.h"
13 #include "linkkit/wrappers/wrappers.h"
14 
15 #ifdef INFRA_LOG
16 #include "linkkit/infra/infra_log.h"
17 #define h2_emerg(...)   log_emerg("h2", __VA_ARGS__)
18 #define h2_crit(...)    log_crit("h2", __VA_ARGS__)
19 #define h2_err(...)     log_err("h2", __VA_ARGS__)
20 #define h2_warning(...) log_warning("h2", __VA_ARGS__)
21 #define h2_info(...)    log_info("h2", __VA_ARGS__)
22 #define h2_debug(...)   log_debug("h2", __VA_ARGS__)
23 #else
24 #define h2_emerg(...)            \
25     do {                         \
26         HAL_Printf(__VA_ARGS__); \
27         HAL_Printf("\r\n");      \
28     } while (0)
29 #define h2_crit(...)             \
30     do {                         \
31         HAL_Printf(__VA_ARGS__); \
32         HAL_Printf("\r\n");      \
33     } while (0)
34 #define h2_err(...)              \
35     do {                         \
36         HAL_Printf(__VA_ARGS__); \
37         HAL_Printf("\r\n");      \
38     } while (0)
39 #define h2_warning(...)          \
40     do {                         \
41         HAL_Printf(__VA_ARGS__); \
42         HAL_Printf("\r\n");      \
43     } while (0)
44 #define h2_info(...)             \
45     do {                         \
46         HAL_Printf(__VA_ARGS__); \
47         HAL_Printf("\r\n");      \
48     } while (0)
49 #define h2_debug(...)            \
50     do {                         \
51         HAL_Printf(__VA_ARGS__); \
52         HAL_Printf("\r\n");      \
53     } while (0)
54 #endif
55 
56 #ifdef INFRA_MEM_STATS
57 #include "linkkit/infra/infra_mem_stats.h"
58 #define HTTP2_STREAM_MALLOC(size) LITE_malloc(size, MEM_MAGIC, "http2.stream")
59 #define HTTP2_STREAM_FREE(ptr)    LITE_free(ptr)
60 #else
61 #define HTTP2_STREAM_MALLOC(size) HAL_Malloc(size)
62 #define HTTP2_STREAM_FREE(ptr) \
63     do {                       \
64         if (ptr != NULL) {     \
65             HAL_Free(ptr);     \
66             ptr = NULL;        \
67         }                      \
68     } while (0)
69 #endif /* #ifdef INFRA_MEM_STATS */
70 
71 #define POINTER_SANITY_CHECK(ptr, err) \
72     do {                               \
73         if (NULL == (ptr)) {           \
74             return (err);              \
75         }                              \
76     } while (0)
77 
78 #define ARGUMENT_SANITY_CHECK(expr, err) \
79     do {                                 \
80         if (!(expr)) {                   \
81             return (err);                \
82         }                                \
83     } while (0)
84 
85 typedef enum {
86     HTTP2_FLAG_NONE = 0,
87 
88     HTTP2_FLAG_END_STREAM = 0x01,
89 
90 } http2_flag;
91 
92 typedef struct http2_list_s {
93     struct http2_list_s *prev;
94     struct http2_list_s *next;
95 } http2_list_t;
96 
97 typedef void (*on_user_header_callback)(int32_t stream_id, int cat,
98                                         const uint8_t *name, uint32_t namelen,
99                                         const uint8_t *value, uint32_t valuelen,
100                                         uint8_t flags);
101 
102 typedef void (*on_user_chunk_recv_callback)(int32_t stream_id,
103                                             const uint8_t *data, uint32_t len,
104                                             uint8_t flags);
105 
106 typedef void (*on_user_stream_close_callback)(int32_t stream_id,
107                                               uint32_t error_code);
108 
109 typedef void (*on_user_frame_send_callback)(int32_t stream_id, int type,
110                                             uint8_t flags);
111 
112 typedef void (*on_user_frame_recv_callback)(int32_t stream_id, int type,
113                                             uint8_t flags);
114 
115 typedef struct {
116     on_user_header_callback on_user_header_cb;
117     on_user_chunk_recv_callback on_user_chunk_recv_cb;
118     on_user_stream_close_callback on_user_stream_close_cb;
119     on_user_frame_send_callback on_user_frame_send_cb;
120     on_user_frame_recv_callback on_user_frame_recv_cb;
121 } http2_user_cb_t;
122 
123 typedef struct http2_connection {
124     void *network; /* iot network ptr */
125     void *session; /* http2 session */
126     int flag;      /* check the stream is end or not */
127     int status;
128     http2_user_cb_t *cbs;
129 } http2_connection_t;
130 
131 typedef struct http2_data_struct {
132     http2_header *header; /* header data. */
133     int header_count;     /* the count of header data. */
134     char *data;           /* send data. */
135     int len;              /* send data length. */
136     int stream_id;        /* send data over specify stream */
137     int flag;             /* send data flag. */
138 } http2_data;
139 
140 typedef struct {
141     http2_connection_t *http2_connect;
142     void *mutex;
143     void *semaphore;
144     void *rw_thread;
145     http2_list_t stream_list;
146     int init_state;
147     http2_stream_cb_t *cbs;
148     uint8_t connect_state;
149     uint8_t retry_cnt;
150 } stream_handle_t;
151 
152 #ifdef FS_ENABLED
153 
154 typedef struct {
155     char fs_upload_id[50];
156     int fs_offset;
157 } fs_rsp_header_val_t;
158 
159 int IOT_HTTP2_FS_Close(void *hd, stream_data_info_t *info,
160                        header_ext_info_t *header);
161 
162 #endif /* #ifdef FS_ENABLED */
163 
164 /**
165  * @brief          the http2 client connect.
166  * @param[in]      pclient: http client. <struct httpclient_t>
167  * @return         http2 client connection handler.
168  */
169 extern http2_connection_t *iotx_http2_client_connect(void *pclient, char *url,
170                                                      int port);
171 
172 http2_connection_t *iotx_http2_client_connect_with_cb(void *pclient, char *url,
173                                                       int port,
174                                                       http2_user_cb_t *cb);
175 /**
176  * @brief          the http2 client send data.
177  * @param[in]      handler: http2 client connection handler.
178  * @param[in]      data: send data.
179  * @return         The result. 0 is ok.
180  */
181 extern int iotx_http2_client_send(http2_connection_t *conn,
182                                   http2_data *h2_data);
183 /**
184  * @brief          the http2 client receive data.
185  * @param[in]      handler: http2 client connection handler.
186  * @param[in]      data: receive data buffer.
187  * @param[in]      data_len: buffer length.
188  * @param[in]      len: receive data length.
189  * @param[in]      timeout: receive data timeout.
190  * @return         The result. 0 is ok.
191  */
192 extern int iotx_http2_client_recv(http2_connection_t *conn, char *data,
193                                   int data_len, int *len, int timeout);
194 /**
195  * @brief          the http2 client connect.
196  * @param[in]      handler: http2 client connection handler.
197  * @return         The result. 0 is ok.
198  */
199 extern int iotx_http2_client_disconnect(http2_connection_t *conn);
200 /**
201  * @brief          the http2 client send ping to keep alive.
202  * @param[in]      handler: http2 client connection handler.
203  * @return         The result. 0 is ok.
204  */
205 extern int iotx_http2_client_send_ping(http2_connection_t *conn);
206 /**
207  * @brief          the http2 client get available windows size.
208  * @param[in]      handler: http2 client connection handler.
209  * @return         The window size.
210  */
211 extern int iotx_http2_get_available_window_size(http2_connection_t *conn);
212 /**
213  * @brief          the http2 client receive windows size packet to update
214  * window.
215  * @param[in]      handler: http2 client connection handler.
216  * @return         The result. 0 is ok.
217  */
218 extern int iotx_http2_update_window_size(http2_connection_t *conn);
219 /**
220  * @brief          the http2 client performs the network I/O.
221  * @param[in]      handler: http2 client connection handler.
222  * @return         The result. 0 is ok.
223  */
224 extern int iotx_http2_exec_io(http2_connection_t *connection);
225 
226 extern int iotx_http2_client_recv_ping(void);
227 
228 int iotx_http2_reset_stream(http2_connection_t *connection, int32_t stream_id);
229 #ifdef __cplusplus
230 }
231 #endif
232 
233 #endif /* IOT_EXPORT_HTTP2_H */
234