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 <sys/time.h>
17 #include "logger.h"
18 #include "securec.h"
19 #include "lock.h"
20 #include "channel_res.h"
21
22 #define SUCCESS 0
23 #define ERROR (-1)
24
25 static ControlChannelRes g_channelRes;
26
SetControlChannelRes(ControlChannelRes * channelInfo,char * srcDomainPath,char * peerDomainPath)27 static int SetControlChannelRes(ControlChannelRes *channelInfo, char *srcDomainPath, char *peerDomainPath)
28 {
29 int ret;
30
31 // Translate the source address.
32 ret = memset_s(&(channelInfo->srcAddr), sizeof(struct sockaddr_un), 0, sizeof(struct sockaddr_un));
33 if (ret != EOK) {
34 LOG_ERROR("memset_s Error\n");
35 return ERROR;
36 }
37
38 ret = memcpy_s(channelInfo->srcDomainPath, DOMAIN_PATH_LEN, srcDomainPath, strlen(srcDomainPath));
39 if (ret != EOK) {
40 LOG_ERROR("memcpy_s Error\n");
41 return ERROR;
42 }
43
44 channelInfo->srcAddr.sun_family = AF_UNIX;
45 ret = strcpy_s(channelInfo->srcAddr.sun_path, strlen(srcDomainPath) + 1, srcDomainPath);
46 if (ret != EOK) {
47 LOG_ERROR("strcpy_s Error");
48 return ERROR;
49 }
50
51 ret = memset_s(channelInfo->peerDomainPath, sizeof(channelInfo->peerDomainPath),
52 0, sizeof(channelInfo->peerDomainPath));
53 if (ret != EOK) {
54 LOG_ERROR("memset_s Error\n");
55 return ERROR;
56 }
57
58 if (peerDomainPath != NULL) {
59 ret = memcpy_s(channelInfo->peerDomainPath, DOMAIN_PATH_LEN, peerDomainPath, strlen(peerDomainPath));
60 if (ret != EOK) {
61 LOG_ERROR("memcpy_s Error\n");
62 return ERROR;
63 }
64
65 channelInfo->peerAddr.sun_family = AF_UNIX;
66 ret = strcpy_s(channelInfo->peerAddr.sun_path, strlen(peerDomainPath) + 1, peerDomainPath);
67 if (ret != EOK) {
68 LOG_ERROR("strcpy_s Error");
69 return ERROR;
70 }
71 }
72 return SUCCESS;
73 }
74
InitControlChannelRes(char * srcDomainPath,int srcDomainPathLen,char * peerDomainPath,int peerDomainPathLen)75 int InitControlChannelRes(char *srcDomainPath, int srcDomainPathLen, char *peerDomainPath, int peerDomainPathLen)
76 {
77 int ret;
78 if ((srcDomainPathLen <= 0) && (peerDomainPathLen <= 0)) {
79 LOG_ERROR("srcDomainPathLen or peerDomainPathLen is 0");
80 return ERROR;
81 }
82 ret = memset_s(&g_channelRes, sizeof(ControlChannelRes), 0, sizeof(ControlChannelRes));
83 if (ret != EOK) {
84 return ERROR;
85 }
86
87 // Initializing the Send Buffer Lock
88 g_channelRes.sendBufferLock = OsLockNew();
89 if (g_channelRes.sendBufferLock == NULL) {
90 LOG_ERROR("OsLockNew Error");
91 return ERROR;
92 }
93
94 // Initialize the receive buffer lock.
95 g_channelRes.rcvBufferLock = OsLockNew();
96 if (g_channelRes.rcvBufferLock == NULL) {
97 LOG_ERROR("OsLockNew Error");
98 return ERROR;
99 }
100
101 // Initializes the communication address used for UDP Domain Socket communication.
102 return SetControlChannelRes(&g_channelRes, srcDomainPath, peerDomainPath);
103 }
104
GetControlChannelRes(void)105 ControlChannelRes *GetControlChannelRes(void)
106 {
107 return &g_channelRes;
108 }
109
PushResultToChannelSendBuffer(ControlChannelRes * channelInfo,char * result)110 int PushResultToChannelSendBuffer(ControlChannelRes *channelInfo, char *result)
111 {
112 int ret;
113 OsLock(channelInfo->sendBufferLock);
114 if (channelInfo->sendBufferNum == MAX_SEND_BUFFER_NUM) {
115 LOG_ERROR("Channel Send Buffer Is Full, Please Try Again");
116 OsUnLock(channelInfo->sendBufferLock);
117 return 1; // The value 1 indicates that the current buffer is full and needs to be retried.
118 }
119 (void)memset_s(channelInfo->sendBuffer + channelInfo->sendBufferNum,
120 CONTROL_CHANNEL_MAX_MSG_LEN, 0, CONTROL_CHANNEL_MAX_MSG_LEN);
121 ret = memcpy_s(channelInfo->sendBuffer + channelInfo->sendBufferNum,
122 CONTROL_CHANNEL_MAX_MSG_LEN, result, strlen(result));
123 if (ret != EOK) {
124 LOG_ERROR("memcpy_s Error");
125 OsUnLock(channelInfo->sendBufferLock);
126 return ERROR;
127 }
128 channelInfo->sendBufferNum++;
129 channelInfo->sendBufferNum %= MAX_SEND_BUFFER_NUM;
130 OsUnLock(channelInfo->sendBufferLock);
131 return SUCCESS;
132 }
133
PushResultToChannelRcvBuffer(ControlChannelRes * channelInfo,char * result)134 int PushResultToChannelRcvBuffer(ControlChannelRes *channelInfo, char *result)
135 {
136 int ret;
137 OsLock(channelInfo->rcvBufferLock);
138 if (channelInfo->rcvBufferNum == MAX_RCV_BUFFER_NUM) {
139 LOG_ERROR("Channel Send Buffer Is Full, Please Try Again");
140 OsUnLock(channelInfo->rcvBufferLock);
141 return 1; // The value 1 indicates that the current buffer is full and needs to be retried.
142 }
143 (void)memset_s(channelInfo->rcvBuffer + channelInfo->rcvBufferNum,
144 CONTROL_CHANNEL_MAX_MSG_LEN, 0, CONTROL_CHANNEL_MAX_MSG_LEN);
145 ret = memcpy_s(channelInfo->rcvBuffer + channelInfo->rcvBufferNum,
146 CONTROL_CHANNEL_MAX_MSG_LEN, result, strlen(result));
147 if (ret != EOK) {
148 LOG_ERROR("memcpy_s Error");
149 OsUnLock(channelInfo->rcvBufferLock);
150 return ERROR;
151 }
152 channelInfo->rcvBufferNum++;
153 channelInfo->rcvBufferNum %= MAX_RCV_BUFFER_NUM;
154 OsUnLock(channelInfo->rcvBufferLock);
155 return SUCCESS;
156 }
157
PushResultToChannelIdBuffer(ControlChannelRes * channelInfo,char * result,int id)158 int PushResultToChannelIdBuffer(ControlChannelRes *channelInfo, char *result, int id)
159 {
160 int ret;
161 OsLock(channelInfo->rcvBufferLock);
162 (void)memset_s(channelInfo->rcvBuffer + (id % MAX_RCV_BUFFER_NUM),
163 CONTROL_CHANNEL_MAX_MSG_LEN, 0, CONTROL_CHANNEL_MAX_MSG_LEN);
164 ret = memcpy_s(channelInfo->rcvBuffer + (id % MAX_RCV_BUFFER_NUM),
165 CONTROL_CHANNEL_MAX_MSG_LEN, result, strlen(result));
166 if (ret != EOK) {
167 LOG_ERROR("memcpy_s Error");
168 OsUnLock(channelInfo->rcvBufferLock);
169 return ERROR;
170 }
171 OsUnLock(channelInfo->rcvBufferLock);
172 return SUCCESS;
173 }
174
FreeControlChannelRes(void)175 void FreeControlChannelRes(void)
176 {
177 if (g_channelRes.tid != 0) {
178 g_channelRes.isExit = true;
179 pthread_join(g_channelRes.tid, NULL);
180 }
181 OsLockDestroy(g_channelRes.sendBufferLock);
182 OsLockDestroy(g_channelRes.rcvBufferLock);
183 memset_s(&g_channelRes, sizeof(g_channelRes), 0, sizeof(g_channelRes));
184 return;
185 }
186