1 /*
2 * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3 */
4
5
6
7
8 #include <stdint.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <errno.h>
12
13 #include "iotx_coap_internal.h"
14 #include "Cloud_CoAPExport.h"
15 #include "Cloud_CoAPNetwork.h"
16
17 #ifdef COAP_DTLS_SUPPORT
18
19 static void Cloud_CoAPNetworkDTLS_freeSession(void *p_session);
20
Cloud_CoAPNetworkDTLS_read(void * p_session,unsigned char * p_data,unsigned int * p_datalen,unsigned int timeout)21 unsigned int Cloud_CoAPNetworkDTLS_read(void *p_session, unsigned char *p_data,
22 unsigned int *p_datalen,
23 unsigned int timeout)
24 {
25 unsigned int err_code = DTLS_SUCCESS;
26 const unsigned int read_len = *p_datalen;
27 DTLSContext *context = NULL;
28
29 COAP_TRC("<< secure_datagram_read, read buffer len %d, timeout %d",
30 read_len, timeout);
31 (void)read_len;
32 if (NULL != p_session) {
33 /* read dtls application data*/
34 context = (DTLSContext *)p_session;
35 err_code = HAL_DTLSSession_read(context, p_data, p_datalen, timeout);
36 if (DTLS_PEER_CLOSE_NOTIFY == err_code ||
37 DTLS_FATAL_ALERT_MESSAGE == err_code) {
38 COAP_INFO("dtls session read failed, return (0x%04x)", err_code);
39 Cloud_CoAPNetworkDTLS_freeSession(context);
40 }
41 if (DTLS_SUCCESS == err_code) {
42 return COAP_SUCCESS;
43 } else {
44 return COAP_ERROR_READ_FAILED;
45 }
46 }
47
48 return COAP_ERROR_INVALID_PARAM;
49 }
50
Cloud_CoAPNetworkDTLS_write(void * p_session,const unsigned char * p_data,unsigned int * p_datalen)51 unsigned int Cloud_CoAPNetworkDTLS_write(void *p_session,
52 const unsigned char *p_data,
53 unsigned int *p_datalen)
54 {
55 unsigned int err_code = DTLS_SUCCESS;
56 if (NULL != p_session) {
57 err_code =
58 HAL_DTLSSession_write((DTLSContext *)p_session, p_data, p_datalen);
59 if (DTLS_SUCCESS == err_code) {
60 return COAP_SUCCESS;
61 } else {
62 return COAP_ERROR_WRITE_FAILED;
63 }
64 }
65 return COAP_ERROR_INVALID_PARAM;
66 }
67
Cloud_CoAPNetworkDTLS_freeSession(void * p_session)68 static void Cloud_CoAPNetworkDTLS_freeSession(void *p_session)
69 {
70 /* Free the session.*/
71 HAL_DTLSSession_free((DTLSContext *)p_session);
72 }
73
Cloud_CoAPNetworkDTLS_createSession(char * p_host,unsigned short port,unsigned char * p_ca_cert_pem)74 void *Cloud_CoAPNetworkDTLS_createSession(char *p_host, unsigned short port,
75 unsigned char *p_ca_cert_pem)
76 {
77 DTLSContext *context = NULL;
78
79 coap_dtls_options_t dtls_options;
80
81 memset(&dtls_options, 0x00, sizeof(coap_dtls_options_t));
82 dtls_options.p_ca_cert_pem = p_ca_cert_pem;
83 dtls_options.p_host = p_host;
84 dtls_options.port = port;
85
86 context = HAL_DTLSSession_create(&dtls_options);
87 return (void *)context;
88 }
89
90 #endif
91
Cloud_CoAPNetwork_write(coap_network_t * p_network,const unsigned char * p_data,unsigned int datalen)92 unsigned int Cloud_CoAPNetwork_write(coap_network_t *p_network,
93 const unsigned char *p_data,
94 unsigned int datalen)
95 {
96 int rc = COAP_ERROR_WRITE_FAILED;
97
98 #ifdef COAP_DTLS_SUPPORT
99 if (COAP_ENDPOINT_DTLS == p_network->ep_type) {
100 rc = Cloud_CoAPNetworkDTLS_write(p_network->context, p_data, &datalen);
101 } else {
102 #endif
103 rc = HAL_UDP_write((intptr_t)p_network->context, p_data, datalen);
104 COAP_DEBUG("[CoAP-NWK]: Network write return %d", rc);
105
106 if (-1 == rc) {
107 rc = COAP_ERROR_WRITE_FAILED;
108 } else {
109 rc = COAP_SUCCESS;
110 }
111 #ifdef COAP_DTLS_SUPPORT
112 }
113 #endif
114 return (unsigned int)rc;
115 }
116
Cloud_CoAPNetwork_read(coap_network_t * network,unsigned char * data,unsigned int datalen,unsigned int timeout)117 int Cloud_CoAPNetwork_read(coap_network_t *network, unsigned char *data,
118 unsigned int datalen, unsigned int timeout)
119 {
120 int len = 0;
121
122 #ifdef COAP_DTLS_SUPPORT
123 if (COAP_ENDPOINT_DTLS == network->ep_type) {
124 len = datalen;
125 memset(data, 0x00, datalen);
126 Cloud_CoAPNetworkDTLS_read(network->context, data, (unsigned int *)&len,
127 timeout);
128 } else {
129 #endif
130 memset(data, 0x00, datalen);
131 len = HAL_UDP_readTimeout((intptr_t)network->context, data,
132 COAP_MSG_MAX_PDU_LEN, timeout);
133 #ifdef COAP_DTLS_SUPPORT
134 }
135 #endif
136 if (len > 0) {
137 COAP_TRC("<< CoAP recv %d bytes data", len);
138 }
139 return len;
140 }
141
Cloud_CoAPNetwork_init(const coap_network_init_t * p_param,coap_network_t * p_network)142 unsigned int Cloud_CoAPNetwork_init(const coap_network_init_t *p_param,
143 coap_network_t *p_network)
144 {
145 unsigned int err_code = COAP_SUCCESS;
146
147 if (NULL == p_param || NULL == p_network) {
148 return COAP_ERROR_INVALID_PARAM;
149 }
150
151 /* TODO : Parse the url here */
152 p_network->ep_type = p_param->ep_type;
153
154 #ifdef COAP_DTLS_SUPPORT
155 if (COAP_ENDPOINT_DTLS == p_param->ep_type) {
156 p_network->context = Cloud_CoAPNetworkDTLS_createSession(
157 p_param->p_host, p_param->port, p_param->p_ca_cert_pem);
158 if (NULL == p_network->context) {
159 return COAP_ERROR_NET_INIT_FAILED;
160 }
161 }
162 #endif
163 if (COAP_ENDPOINT_NOSEC == p_param->ep_type ||
164 COAP_ENDPOINT_PSK == p_param->ep_type) {
165 /*Create udp socket*/
166 p_network->context =
167 (void *)HAL_UDP_create(p_param->p_host, p_param->port);
168 if ((void *)-1 == p_network->context) {
169 return COAP_ERROR_NET_INIT_FAILED;
170 }
171 }
172 return err_code;
173 }
174
Cloud_CoAPNetwork_deinit(coap_network_t * p_network)175 unsigned int Cloud_CoAPNetwork_deinit(coap_network_t *p_network)
176 {
177 unsigned int err_code = COAP_SUCCESS;
178
179 #ifdef COAP_DTLS_SUPPORT
180 if (COAP_ENDPOINT_DTLS == p_network->ep_type) {
181 Cloud_CoAPNetworkDTLS_freeSession(p_network->context);
182 p_network->context = NULL;
183 }
184 #endif
185 if (COAP_ENDPOINT_NOSEC == p_network->ep_type ||
186 COAP_ENDPOINT_PSK == p_network->ep_type) {
187 HAL_UDP_close_without_connect((intptr_t)p_network->context);
188 }
189
190 return err_code;
191 }
192