1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include "simulate_io.h"
17 #include "hitls_error.h"
18 #include "bsl_sal.h"
19 #include "bsl_log_internal.h"
20 #include "bsl_log.h"
21 #include "bsl_errno.h"
22 #include "bsl_uio.h"
23 #include "securec.h"
24
25 #define FAKE_BSL_UIO_FD 666
26
FRAME_IO_CreateUserData(void)27 FrameUioUserData *FRAME_IO_CreateUserData(void)
28 {
29 FrameUioUserData *userData = BSL_SAL_Calloc(1u, sizeof(FrameUioUserData));
30 if (userData == NULL) {
31 return NULL;
32 }
33 return userData;
34 }
35
FRAME_IO_FreeUserData(FrameUioUserData * userData)36 void FRAME_IO_FreeUserData(FrameUioUserData *userData)
37 {
38 if (userData == NULL) {
39 return;
40 }
41
42 BSL_SAL_FREE(userData);
43 return;
44 }
45
FRAME_Write(BSL_UIO * uio,const void * buf,uint32_t len,uint32_t * writeLen)46 int32_t FRAME_Write(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen)
47 {
48 *writeLen = 0;
49 FrameUioUserData *ioUserData = BSL_UIO_GetUserData(uio);
50 if (ioUserData == NULL) {
51 return BSL_NULL_INPUT;
52 }
53
54 // This indicates that there is still a message in the buffer. The second message can be sent only after the peer
55 // end receives the message.
56 if (ioUserData->sndMsg.len != 0) {
57 return BSL_SUCCESS;
58 }
59
60 memcpy_s(ioUserData->sndMsg.msg, MAX_RECORD_LENTH, buf, len);
61 ioUserData->sndMsg.len = len;
62 *writeLen = len;
63
64 return BSL_SUCCESS;
65 }
66
FRAME_Read(BSL_UIO * uio,void * buf,uint32_t len,uint32_t * readLen)67 int32_t FRAME_Read(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen)
68 {
69 *readLen = 0;
70 FrameUioUserData *ioUserData = BSL_UIO_GetUserData(uio);
71 if (ioUserData == NULL) {
72 return BSL_NULL_INPUT;
73 }
74 // This indicates that the user inserts data. Therefore, the simulated data inserted by the user is received first.
75 if (ioUserData->userInsertMsg.len != 0) {
76 if (len < ioUserData->userInsertMsg.len) {
77 return BSL_UIO_FAIL;
78 }
79
80 memcpy_s(buf, len, ioUserData->userInsertMsg.msg, ioUserData->userInsertMsg.len);
81 *readLen = ioUserData->userInsertMsg.len;
82 ioUserData->userInsertMsg.len = 0;
83 return BSL_SUCCESS;
84 } else if (ioUserData->recMsg.len != 0) {
85 uint32_t copyLen = len < ioUserData->recMsg.len ? len : ioUserData->recMsg.len;
86 memcpy_s(buf, len, ioUserData->recMsg.msg, copyLen);
87 *readLen = copyLen;
88 if (copyLen < ioUserData->recMsg.len) {
89 memmove_s(ioUserData->recMsg.msg, ioUserData->recMsg.len,
90 &ioUserData->recMsg.msg[copyLen], ioUserData->recMsg.len - copyLen);
91 }
92 ioUserData->recMsg.len -= copyLen;
93 return BSL_SUCCESS;
94 } // If there is no data in the receive buffer, a success message is returned and *readLen is set to 0.
95
96 return BSL_SUCCESS;
97 }
98
FRAME_Ctrl(BSL_UIO * uio,int32_t cmd,int32_t larg,void * param)99 int32_t FRAME_Ctrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *param)
100 {
101 (void)uio;
102 (void)larg;
103 if (cmd == BSL_UIO_SCTP_SND_BUFF_IS_EMPTY) {
104 *(uint8_t *)param = true;
105 }
106
107 if (cmd == BSL_UIO_GET_FD) {
108 *(int32_t *)param = FAKE_BSL_UIO_FD;
109 }
110
111 return BSL_SUCCESS;
112 }
113
114 /*
115 Frame_TransportSendMsg: Sends messages in the send buffer in the I/O.
116 Copy uio->userData to the buffer.
117 */
FRAME_TransportSendMsg(BSL_UIO * uio,void * buf,uint32_t len,uint32_t * readLen)118 int32_t FRAME_TransportSendMsg(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen)
119 {
120 *readLen = 0;
121 FrameUioUserData *ioUserData = BSL_UIO_GetUserData(uio);
122 if (ioUserData == NULL) {
123 return HITLS_NULL_INPUT;
124 }
125
126 if (ioUserData->sndMsg.len != 0) {
127 // The length of the data in the buffer exceeds len.
128 if (len < ioUserData->sndMsg.len) {
129 return HITLS_UIO_FAIL;
130 }
131
132 memcpy_s(buf, len, ioUserData->sndMsg.msg, ioUserData->sndMsg.len);
133 *readLen = ioUserData->sndMsg.len;
134 ioUserData->sndMsg.len = 0;
135 } // If there is no data in the receive buffer, a success message is returned and *readLen is set to 0.
136
137 return HITLS_SUCCESS;
138 }
139
140 /*
141 Frame_TransportRecMsg simulates receiving messages from the I/O.
142 Copy the data in the buffer to uio->userData.
143 */
FRAME_TransportRecMsg(BSL_UIO * uio,void * buf,uint32_t len)144 int32_t FRAME_TransportRecMsg(BSL_UIO *uio, void *buf, uint32_t len)
145 {
146 FrameUioUserData *ioUserData = BSL_UIO_GetUserData(uio);
147 if (ioUserData == NULL) {
148 return HITLS_NULL_INPUT;
149 }
150
151 if (ioUserData->recMsg.len != 0 || len > MAX_RECORD_LENTH) {
152 return HITLS_UIO_FAIL;
153 }
154
155 memcpy_s(ioUserData->recMsg.msg, MAX_RECORD_LENTH, buf, len);
156 ioUserData->recMsg.len = len;
157
158 return HITLS_SUCCESS;
159 }
160
161 #ifdef __cplusplus
162 }
163 #endif
164