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 #include <string.h>
18
19 #include "shm_utils.h"
20
21 using namespace std;
22
23 static void* shm = NULL; //分配的共享内存的原始首地址
24 static struct shared_use_st* shared; //指向shm
25 static int shmid; //共享内存标识符
26 const int CALCU_TWO = 2;
27 const int CODE_HEAD = 4;
28 const int STR_KEY = 5;
29 const int RES_FAIL = -1;
30 const char LOGSTR[20] = "LOG_SHM::----";
31
createShm(int key)32 int createShm(int key)
33 {
34 //创建共享内存
35 LOG("%s createShm begin...", LOGSTR);
36 shmid = shmget((key_t)key, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
37 LOG("%s shmget", LOGSTR);
38 LOG("%s shmget shmid=%d", LOGSTR, shmid);
39 if (shmid == -1) {
40 LOG("%s err: shmget, shmid = -1", LOGSTR);
41 return -1;
42 }
43 //将共享内存连接到当前进程的地址空间
44 shm = shmat(shmid, nullptr, 0);
45 int n = -1;
46 if (shm == static_cast<void*>(&n)) {
47 LOG("%s err: shmat, shm = -1", LOGSTR);
48 return -1;
49 }
50
51 shared = (struct shared_use_st*)shm;
52 initShm();
53 LOG("%s createShm end...", LOGSTR);
54 return 0;
55 }
56
initShm(void)57 void initShm(void)
58 {
59 LOG("%s initShm begin...", LOGSTR);
60 memset_s(shm, sizeof(struct shared_use_st), 0, sizeof(struct shared_use_st));
61 if (shared == nullptr) {
62 LOG("%s err:initShm shared = nullptr", LOGSTR);
63 return;
64 }
65 shared->written = 0;
66 memset_s(shared->data, MAX_DATA_LENGTH, 0, MAX_DATA_LENGTH);
67 LOG("%s initShm end...", LOGSTR);
68 return;
69 }
70
readDataFromShm(char * buf)71 int readDataFromShm(char* buf)
72 {
73 // LOG("readDataFormShm, begin");
74 if (shared == nullptr) {
75 LOG("%s err:readDataFromShm shared = nullptr", LOGSTR);
76 return -1;
77 }
78 if (shared->written != 0) {
79 strcpy_s(buf, strlen(shared->data) + 1, shared->data);
80 shared->written = 0;
81 LOG("readDataFromShm %s", buf);
82 memset_s(shared->data, MAX_DATA_LENGTH, 0, MAX_DATA_LENGTH);
83 } else {
84 return -1;
85 }
86 return 0;
87 }
88
waitDataWithCode(char * code,char * data)89 int waitDataWithCode(char* code, char* data)
90 {
91 int i = 0;
92 int timeout = 10;
93 char str[1024] = { 0 };
94 memset_s(str, MAX_DATA_LENGTH, 0, MAX_DATA_LENGTH);
95 while (i < timeout) {
96 if (readDataFromShm(str) == 0 && strncmp(code, str, CODE_HEAD) == 0) {
97 errno_t ret = 1;
98 ret = strncpy_s(data, strlen("0") + 1, str + STR_KEY, 1);
99 if (ret != EOK) {
100 LOG("ERR:ret=%d", ret);
101 return RES_FAIL;
102 }
103 return 0;
104 }
105 i++;
106 sleep(1);
107 }
108
109 return -1;
110 }
111
writeCodeDataToShm(int code,char * buf)112 int writeCodeDataToShm(int code, char* buf)
113 {
114 char str[1024] = { 0 };
115 memset_s(str, MAX_DATA_LENGTH, 0, MAX_DATA_LENGTH);
116 char codeStr[5] = { 0 };
117 memset_s(codeStr, 5, 0, 5);
118 Int2String(code, codeStr);
119 strcpy_s(str, strlen(codeStr) + 1, codeStr);
120 strcat_s(str, MAX_DATA_LENGTH, ":");
121 strcat_s(str, MAX_DATA_LENGTH, buf);
122 writeDataToShm(str);
123 return 0;
124 }
writeDataToShm(char * buf)125 int writeDataToShm(char* buf)
126 {
127 LOG("%s writeDataToShm, begin", LOGSTR);
128 if (shared == nullptr) {
129 LOG("%s err:writeDataToShm shared = nullptr", LOGSTR);
130 return -1;
131 }
132 if (buf == nullptr) {
133 LOG("%s err: writeDataToShm, buf = nullptr", LOGSTR);
134 return -1;
135 }
136 while (shared->written == 1) {
137 sleep(1);
138 }
139
140 LOG("writeDataToShm %s", buf);
141 memset_s(shared->data, 5, 0, 5);
142 strcpy_s(shared->data, strlen(buf) + 1, buf);
143 shared->written = 1;
144 sleep(2);
145 return 0;
146 }
147
disconnectShm(void)148 int disconnectShm(void)
149 {
150 if (shmdt(shm) == -1) {
151 return -1;
152 }
153 return 0;
154 }
155
deleteShm(void)156 int deleteShm(void)
157 {
158 if (shmctl(shmid, IPC_RMID, nullptr) == -1) {
159 return -1;
160 }
161 return 0;
162 }
163
Int2String(int num,char * str)164 char* Int2String(int num, char* str) // 10进制
165 {
166 int i = 0; //指示填充str
167 if (num < 0) //如果num为负数,将num变正
168 {
169 num = -num;
170 str[i++] = '-';
171 }
172 //转换
173 do {
174 str[i++] = num % 10 + 48; //取num最低位 字符0~9的ASCII码是48~57:简单来说数字0+48=48,ASCII码对应字符'0'
175 num /= 10; //去掉最低位
176 } while (num); // num不为0继续循环
177
178 str[i] = '\0';
179
180 //确定开始调整的位置
181 int j = 0;
182 if (str[0] == '-') //如果有负号,负号不用调整
183 {
184 j = 1; //从第二位开始调整
185 ++i; //由于有负号,所以交换的对称轴也要后移一位
186 }
187 //对称交换
188 for (; j < i / CALCU_TWO; j++) {
189 //对称交换两端的值 其实就是省下中间变量交换a+b的值:a=a+b;b=a-b;a=a-b;
190 str[j] = str[j] + str[i - 1 - j];
191 str[i - 1 - j] = str[j] - str[i - 1 - j];
192 str[j] = str[j] - str[i - 1 - j];
193 }
194
195 return str; //返回转换后的值
196 }
197