1 /*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
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
16 #include <cstring>
17
18 #include "shm_utils.h"
19
20 using namespace std;
21 const int MAX_DATA_LENGTH = 1024;
22 const int PERMISSION = 0666;
23 const int CODE_HEAD = 4;
24 const int STR_KEY = 5;
25 const int SHARED_DATA_LEN = 5;
26 const int WAITTIME = 2;
27 const int DECIM_TEN = 10;
28 const int CALCU_TWO = 2;
29 const int CALCU_FOUR_AIGHT = 48;
30 const int RES_FAIL = -1;
31 const char LOGSTR[20] = "LOG_SHM::----";
32 static void* shm = nullptr; // 分配的共享内存的原始首地址
33 static struct shared_use_st* shared; // 指向shm
34 static int shmid; // 共享内存标识符
35
createShm(int key)36 int createShm(int key)
37 {
38 // 创建共享内存
39 LOG("%s createShm begin...", LOGSTR);
40 int a = sizeof(struct shared_use_st);
41 LOG("a=%d", a);
42 shmid = shmget(static_cast<key_t>(key), sizeof(struct shared_use_st), PERMISSION | IPC_CREAT);
43 LOG("shmget shmid=%d", shmid);
44 if (shmid == -1) {
45 LOG("%s err: shmget, shmid = -1", LOGSTR);
46 return -1;
47 }
48 // 将共享内存连接到当前进程的地址空间
49 shm = shmat(shmid, nullptr, 0);
50 int n = -1;
51 if (shm == static_cast<void*>(&n)) {
52 LOG("%s err: shmat, shm = -1", LOGSTR);
53 return -1;
54 }
55
56 shared = (struct shared_use_st*)shm;
57 initShm();
58 LOG("%s createShm end...", LOGSTR);
59 return 0;
60 }
61
initShm(void)62 void initShm(void)
63 {
64 LOG("%s initShm begin...", LOGSTR);
65 memset_s(shm, sizeof(struct shared_use_st), 0, sizeof(struct shared_use_st));
66 if (shared == nullptr) {
67 LOG("%s err:initShm shared = nullptr", LOGSTR);
68 return;
69 }
70 shared->written = 0;
71 memset_s(shared->data, MAX_DATA_LENGTH, 0, MAX_DATA_LENGTH);
72 LOG("%s initShm end...", LOGSTR);
73 return;
74 }
75
readDataFromShm(char * buf)76 int readDataFromShm(char* buf)
77 {
78 LOG("readDataFromShm begin...");
79 if (shared == nullptr) {
80 LOG("%s err:readDataFromShm shared = nullptr", LOGSTR);
81 return -1;
82 }
83
84 if (shared->written != 0) {
85 strcpy_s(buf, strlen(shared->data) + 1, shared->data);
86 LOG("readDataFromShm buf= %s", buf);
87 LOG("readDataFromShm shared->data= %s", shared->data);
88 shared->written = 0;
89 memset_s(shared->data, MAX_DATA_LENGTH, 0, MAX_DATA_LENGTH);
90 } else {
91 return -1;
92 }
93 LOG("SUCCESS: readDataFromShm return 0");
94 return 0;
95 }
96
readDataFromShmNoClear(char * buf)97 int readDataFromShmNoClear(char* buf)
98 {
99 LOG("readDataFromShmNoClear begin...");
100 if (shared == nullptr) {
101 return -1;
102 }
103 if (shared->written != 0) {
104 strcpy_s(buf, strlen(shared->data) + 1, shared->data);
105 LOG("readDataFromShmNoClear buf= %s", buf);
106 LOG("readDataFromShmNoClear shared->data= %s", shared->data);
107 } else {
108 return -1;
109 }
110 LOG("SUCCESS: readDataFromShmNoClear return 0");
111 return 0;
112 }
113
waitDataWithCode(char * code,char * data)114 int waitDataWithCode(char* code, char* data)
115 {
116 LOG("waitDataWithCode begin...");
117 int i = 0;
118 int timeout = 10;
119 char str[MAX_DATA_LENGTH] = { 0 };
120 if (code == nullptr || data == nullptr) {
121 LOG("code = nullptr ,data = nullptr");
122 return RES_FAIL;
123 }
124 while (i < timeout) {
125 if (readDataFromShmNoClear(str) != 0 || strncmp(code, str, CODE_HEAD) != 0) {
126 i++;
127 sleep(1);
128 LOG("while: waitDataWithCode 9999 str= %s, i=%d", str, i);
129 continue;
130 }
131
132 if (readDataFromShm(str) == 0 && strncmp(code, str, CODE_HEAD) == 0) {
133 if (strncpy_s(data, strlen("0") + 1, str + STR_KEY, 1) != EOK) {
134 LOG("ERR:strncpy_s");
135 return RES_FAIL;
136 }
137 LOG("waitDataWithCode 9999 str= %s", str);
138 LOG("waitDataWithCode 9999 data= %s", data);
139 LOG("SUCCESS:waitDataWithCode return 0");
140 return 0;
141 }
142 i++;
143 sleep(1);
144 LOG("while: waitDataWithCode 9999 str= %s, i=%d", str, i);
145 }
146 LOG("ERR :waitDataWithCode ");
147 return RES_FAIL;
148 }
149
writeCodeDataToShm(int code,char * buf)150 int writeCodeDataToShm(int code, char* buf)
151 {
152 LOG("writeCodeDataToShm, begin");
153 char* str = (char*)malloc(MAX_DATA_LENGTH);
154 if (str == nullptr) {
155 LOG("malloc fail");
156 return -1;
157 }
158 (void)memset_s(str, MAX_DATA_LENGTH, 0, MAX_DATA_LENGTH);
159
160 char codeStr[5] = { 0 };
161 char* str2 = Int2String(code, codeStr);
162 if (str2 == nullptr) {
163 LOG("ERROR: str2 == nullptr");
164 return -1;
165 }
166
167 if (strcpy_s(str, MAX_DATA_LENGTH, codeStr) != EOK) {
168 LOG("ERROR: strcpy_s != EOK");
169 return -1;
170 }
171 if (strcat_s(str, MAX_DATA_LENGTH, ":") != EOK) {
172 LOG("ERROR: 1. strcat_s!= EOK ");
173 return -1;
174 }
175
176 if (buf == nullptr) {
177 LOG("ERROR:buf == nullptr ");
178 return -1;
179 }
180 if (strcat_s(str, MAX_DATA_LENGTH, buf) != EOK) {
181 LOG("ERROR:2. strcat_s != EOK");
182 return -1;
183 }
184 int nres = writeDataToShm(str);
185 if (nres == -1) {
186 return -1;
187 }
188 return 0;
189 }
writeDataToShm(char * buf)190 int writeDataToShm(char* buf)
191 {
192 LOG("%s writeDataToShm, begin", LOGSTR);
193 if (shared == nullptr) {
194 LOG("%s err:writeDataToShm shared == nullptr", LOGSTR);
195 return -1;
196 }
197 if (buf == nullptr) {
198 LOG("%s err: writeDataToShm, buf == nullptr", LOGSTR);
199 return -1;
200 }
201 while (shared->written == 1) {
202 sleep(1);
203 }
204
205 LOG("writeDataToShm %s", buf);
206 memset_s(shared->data, SHARED_DATA_LEN, 0, SHARED_DATA_LEN);
207 strcpy_s(shared->data, strlen(buf) + 1, buf);
208 shared->written = 1;
209 LOG("writeDataToShm shared->data= %s", shared->data);
210 LOG("writeDataToShm shared->written= %d", shared->written);
211
212 sleep(WAITTIME);
213 return 0;
214 }
215
disconnectShm(void)216 int disconnectShm(void)
217 {
218 if (shmdt(shm) == -1) {
219 return -1;
220 }
221 return 0;
222 }
223
deleteShm(void)224 int deleteShm(void)
225 {
226 if (shmctl(shmid, IPC_RMID, nullptr) == -1) {
227 return -1;
228 }
229 return 0;
230 }
231
Int2String(int num,char * str)232 char* Int2String(int num, char* str) // 10进制
233 {
234 if (str == nullptr) {
235 return nullptr;
236 }
237 int i = 0; // 指示填充str
238 if (num < 0) {
239 num = -num;
240 str[i++] = '-';
241 }
242 // 转换
243 do {
244 str[i++] = num % DECIM_TEN + CALCU_FOUR_AIGHT;
245 num /= DECIM_TEN;
246 } while (num); // num不为0继续循环
247
248 str[i] = '\0';
249
250 // 确定开始调整的位置
251 int j = 0;
252 if (str[0] == '-') {
253 j = 1; // 从第二位开始调整
254 ++i; // 由于有负号,所以交换的对称轴也要后移一位
255 }
256 // 对称交换
257 for (; j < i / CALCU_TWO; j++) {
258 // 对称交换两端的值 其实就是省下中间变量交换a+b的值:a=a+b;b=a-b;a=a-b;
259 str[j] = str[j] + str[i - 1 - j];
260 str[i - 1 - j] = str[j] - str[i - 1 - j];
261 str[j] = str[j] - str[i - 1 - j];
262 }
263
264 return str; // 返回转换后的值
265 }