10704ebd2Sopenharmony_ci/* 20704ebd2Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd. 30704ebd2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 40704ebd2Sopenharmony_ci * you may not use this file except in compliance with the License. 50704ebd2Sopenharmony_ci * You may obtain a copy of the License at 60704ebd2Sopenharmony_ci * 70704ebd2Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 80704ebd2Sopenharmony_ci * 90704ebd2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 100704ebd2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 110704ebd2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 120704ebd2Sopenharmony_ci * See the License for the specific language governing permissions and 130704ebd2Sopenharmony_ci * limitations under the License. 140704ebd2Sopenharmony_ci */ 150704ebd2Sopenharmony_ci 160704ebd2Sopenharmony_ci#include <cstring> 170704ebd2Sopenharmony_ci 180704ebd2Sopenharmony_ci#include "shm_utils.h" 190704ebd2Sopenharmony_ci 200704ebd2Sopenharmony_ciusing namespace std; 210704ebd2Sopenharmony_ciconst int MAX_DATA_LENGTH = 1024; 220704ebd2Sopenharmony_ciconst int PERMISSION = 0666; 230704ebd2Sopenharmony_ciconst int CODE_HEAD = 4; 240704ebd2Sopenharmony_ciconst int STR_KEY = 5; 250704ebd2Sopenharmony_ciconst int SHARED_DATA_LEN = 5; 260704ebd2Sopenharmony_ciconst int WAITTIME = 2; 270704ebd2Sopenharmony_ciconst int DECIM_TEN = 10; 280704ebd2Sopenharmony_ciconst int CALCU_TWO = 2; 290704ebd2Sopenharmony_ciconst int CALCU_FOUR_AIGHT = 48; 300704ebd2Sopenharmony_ciconst int RES_FAIL = -1; 310704ebd2Sopenharmony_ciconst char LOGSTR[20] = "LOG_SHM::----"; 320704ebd2Sopenharmony_cistatic void* shm = nullptr; // 分配的共享内存的原始首地址 330704ebd2Sopenharmony_cistatic struct shared_use_st* shared; // 指向shm 340704ebd2Sopenharmony_cistatic int shmid; // 共享内存标识符 350704ebd2Sopenharmony_ci 360704ebd2Sopenharmony_ciint createShm(int key) 370704ebd2Sopenharmony_ci{ 380704ebd2Sopenharmony_ci // 创建共享内存 390704ebd2Sopenharmony_ci LOG("%s createShm begin...", LOGSTR); 400704ebd2Sopenharmony_ci int a = sizeof(struct shared_use_st); 410704ebd2Sopenharmony_ci LOG("a=%d", a); 420704ebd2Sopenharmony_ci shmid = shmget(static_cast<key_t>(key), sizeof(struct shared_use_st), PERMISSION | IPC_CREAT); 430704ebd2Sopenharmony_ci LOG("shmget shmid=%d", shmid); 440704ebd2Sopenharmony_ci if (shmid == -1) { 450704ebd2Sopenharmony_ci LOG("%s err: shmget, shmid = -1", LOGSTR); 460704ebd2Sopenharmony_ci return -1; 470704ebd2Sopenharmony_ci } 480704ebd2Sopenharmony_ci // 将共享内存连接到当前进程的地址空间 490704ebd2Sopenharmony_ci shm = shmat(shmid, nullptr, 0); 500704ebd2Sopenharmony_ci int n = -1; 510704ebd2Sopenharmony_ci if (shm == static_cast<void*>(&n)) { 520704ebd2Sopenharmony_ci LOG("%s err: shmat, shm = -1", LOGSTR); 530704ebd2Sopenharmony_ci return -1; 540704ebd2Sopenharmony_ci } 550704ebd2Sopenharmony_ci 560704ebd2Sopenharmony_ci shared = (struct shared_use_st*)shm; 570704ebd2Sopenharmony_ci initShm(); 580704ebd2Sopenharmony_ci LOG("%s createShm end...", LOGSTR); 590704ebd2Sopenharmony_ci return 0; 600704ebd2Sopenharmony_ci} 610704ebd2Sopenharmony_ci 620704ebd2Sopenharmony_civoid initShm(void) 630704ebd2Sopenharmony_ci{ 640704ebd2Sopenharmony_ci LOG("%s initShm begin...", LOGSTR); 650704ebd2Sopenharmony_ci memset_s(shm, sizeof(struct shared_use_st), 0, sizeof(struct shared_use_st)); 660704ebd2Sopenharmony_ci if (shared == nullptr) { 670704ebd2Sopenharmony_ci LOG("%s err:initShm shared = nullptr", LOGSTR); 680704ebd2Sopenharmony_ci return; 690704ebd2Sopenharmony_ci } 700704ebd2Sopenharmony_ci shared->written = 0; 710704ebd2Sopenharmony_ci memset_s(shared->data, MAX_DATA_LENGTH, 0, MAX_DATA_LENGTH); 720704ebd2Sopenharmony_ci LOG("%s initShm end...", LOGSTR); 730704ebd2Sopenharmony_ci return; 740704ebd2Sopenharmony_ci} 750704ebd2Sopenharmony_ci 760704ebd2Sopenharmony_ciint readDataFromShm(char* buf) 770704ebd2Sopenharmony_ci{ 780704ebd2Sopenharmony_ci LOG("readDataFromShm begin..."); 790704ebd2Sopenharmony_ci if (shared == nullptr) { 800704ebd2Sopenharmony_ci LOG("%s err:readDataFromShm shared = nullptr", LOGSTR); 810704ebd2Sopenharmony_ci return -1; 820704ebd2Sopenharmony_ci } 830704ebd2Sopenharmony_ci 840704ebd2Sopenharmony_ci if (shared->written != 0) { 850704ebd2Sopenharmony_ci strcpy_s(buf, strlen(shared->data) + 1, shared->data); 860704ebd2Sopenharmony_ci LOG("readDataFromShm buf= %s", buf); 870704ebd2Sopenharmony_ci LOG("readDataFromShm shared->data= %s", shared->data); 880704ebd2Sopenharmony_ci shared->written = 0; 890704ebd2Sopenharmony_ci memset_s(shared->data, MAX_DATA_LENGTH, 0, MAX_DATA_LENGTH); 900704ebd2Sopenharmony_ci } else { 910704ebd2Sopenharmony_ci return -1; 920704ebd2Sopenharmony_ci } 930704ebd2Sopenharmony_ci LOG("SUCCESS: readDataFromShm return 0"); 940704ebd2Sopenharmony_ci return 0; 950704ebd2Sopenharmony_ci} 960704ebd2Sopenharmony_ci 970704ebd2Sopenharmony_ciint readDataFromShmNoClear(char* buf) 980704ebd2Sopenharmony_ci{ 990704ebd2Sopenharmony_ci LOG("readDataFromShmNoClear begin..."); 1000704ebd2Sopenharmony_ci if (shared == nullptr) { 1010704ebd2Sopenharmony_ci return -1; 1020704ebd2Sopenharmony_ci } 1030704ebd2Sopenharmony_ci if (shared->written != 0) { 1040704ebd2Sopenharmony_ci strcpy_s(buf, strlen(shared->data) + 1, shared->data); 1050704ebd2Sopenharmony_ci LOG("readDataFromShmNoClear buf= %s", buf); 1060704ebd2Sopenharmony_ci LOG("readDataFromShmNoClear shared->data= %s", shared->data); 1070704ebd2Sopenharmony_ci } else { 1080704ebd2Sopenharmony_ci return -1; 1090704ebd2Sopenharmony_ci } 1100704ebd2Sopenharmony_ci LOG("SUCCESS: readDataFromShmNoClear return 0"); 1110704ebd2Sopenharmony_ci return 0; 1120704ebd2Sopenharmony_ci} 1130704ebd2Sopenharmony_ci 1140704ebd2Sopenharmony_ciint waitDataWithCode(char* code, char* data) 1150704ebd2Sopenharmony_ci{ 1160704ebd2Sopenharmony_ci LOG("waitDataWithCode begin..."); 1170704ebd2Sopenharmony_ci int i = 0; 1180704ebd2Sopenharmony_ci int timeout = 10; 1190704ebd2Sopenharmony_ci char str[MAX_DATA_LENGTH] = { 0 }; 1200704ebd2Sopenharmony_ci if (code == nullptr || data == nullptr) { 1210704ebd2Sopenharmony_ci LOG("code = nullptr ,data = nullptr"); 1220704ebd2Sopenharmony_ci return RES_FAIL; 1230704ebd2Sopenharmony_ci } 1240704ebd2Sopenharmony_ci while (i < timeout) { 1250704ebd2Sopenharmony_ci if (readDataFromShmNoClear(str) != 0 || strncmp(code, str, CODE_HEAD) != 0) { 1260704ebd2Sopenharmony_ci i++; 1270704ebd2Sopenharmony_ci sleep(1); 1280704ebd2Sopenharmony_ci LOG("while: waitDataWithCode 9999 str= %s, i=%d", str, i); 1290704ebd2Sopenharmony_ci continue; 1300704ebd2Sopenharmony_ci } 1310704ebd2Sopenharmony_ci 1320704ebd2Sopenharmony_ci if (readDataFromShm(str) == 0 && strncmp(code, str, CODE_HEAD) == 0) { 1330704ebd2Sopenharmony_ci if (strncpy_s(data, strlen("0") + 1, str + STR_KEY, 1) != EOK) { 1340704ebd2Sopenharmony_ci LOG("ERR:strncpy_s"); 1350704ebd2Sopenharmony_ci return RES_FAIL; 1360704ebd2Sopenharmony_ci } 1370704ebd2Sopenharmony_ci LOG("waitDataWithCode 9999 str= %s", str); 1380704ebd2Sopenharmony_ci LOG("waitDataWithCode 9999 data= %s", data); 1390704ebd2Sopenharmony_ci LOG("SUCCESS:waitDataWithCode return 0"); 1400704ebd2Sopenharmony_ci return 0; 1410704ebd2Sopenharmony_ci } 1420704ebd2Sopenharmony_ci i++; 1430704ebd2Sopenharmony_ci sleep(1); 1440704ebd2Sopenharmony_ci LOG("while: waitDataWithCode 9999 str= %s, i=%d", str, i); 1450704ebd2Sopenharmony_ci } 1460704ebd2Sopenharmony_ci LOG("ERR :waitDataWithCode "); 1470704ebd2Sopenharmony_ci return RES_FAIL; 1480704ebd2Sopenharmony_ci} 1490704ebd2Sopenharmony_ci 1500704ebd2Sopenharmony_ciint writeCodeDataToShm(int code, char* buf) 1510704ebd2Sopenharmony_ci{ 1520704ebd2Sopenharmony_ci LOG("writeCodeDataToShm, begin"); 1530704ebd2Sopenharmony_ci char* str = (char*)malloc(MAX_DATA_LENGTH); 1540704ebd2Sopenharmony_ci if (str == nullptr) { 1550704ebd2Sopenharmony_ci LOG("malloc fail"); 1560704ebd2Sopenharmony_ci return -1; 1570704ebd2Sopenharmony_ci } 1580704ebd2Sopenharmony_ci (void)memset_s(str, MAX_DATA_LENGTH, 0, MAX_DATA_LENGTH); 1590704ebd2Sopenharmony_ci 1600704ebd2Sopenharmony_ci char codeStr[5] = { 0 }; 1610704ebd2Sopenharmony_ci char* str2 = Int2String(code, codeStr); 1620704ebd2Sopenharmony_ci if (str2 == nullptr) { 1630704ebd2Sopenharmony_ci LOG("ERROR: str2 == nullptr"); 1640704ebd2Sopenharmony_ci return -1; 1650704ebd2Sopenharmony_ci } 1660704ebd2Sopenharmony_ci 1670704ebd2Sopenharmony_ci if (strcpy_s(str, MAX_DATA_LENGTH, codeStr) != EOK) { 1680704ebd2Sopenharmony_ci LOG("ERROR: strcpy_s != EOK"); 1690704ebd2Sopenharmony_ci return -1; 1700704ebd2Sopenharmony_ci } 1710704ebd2Sopenharmony_ci if (strcat_s(str, MAX_DATA_LENGTH, ":") != EOK) { 1720704ebd2Sopenharmony_ci LOG("ERROR: 1. strcat_s!= EOK "); 1730704ebd2Sopenharmony_ci return -1; 1740704ebd2Sopenharmony_ci } 1750704ebd2Sopenharmony_ci 1760704ebd2Sopenharmony_ci if (buf == nullptr) { 1770704ebd2Sopenharmony_ci LOG("ERROR:buf == nullptr "); 1780704ebd2Sopenharmony_ci return -1; 1790704ebd2Sopenharmony_ci } 1800704ebd2Sopenharmony_ci if (strcat_s(str, MAX_DATA_LENGTH, buf) != EOK) { 1810704ebd2Sopenharmony_ci LOG("ERROR:2. strcat_s != EOK"); 1820704ebd2Sopenharmony_ci return -1; 1830704ebd2Sopenharmony_ci } 1840704ebd2Sopenharmony_ci int nres = writeDataToShm(str); 1850704ebd2Sopenharmony_ci if (nres == -1) { 1860704ebd2Sopenharmony_ci return -1; 1870704ebd2Sopenharmony_ci } 1880704ebd2Sopenharmony_ci return 0; 1890704ebd2Sopenharmony_ci} 1900704ebd2Sopenharmony_ciint writeDataToShm(char* buf) 1910704ebd2Sopenharmony_ci{ 1920704ebd2Sopenharmony_ci LOG("%s writeDataToShm, begin", LOGSTR); 1930704ebd2Sopenharmony_ci if (shared == nullptr) { 1940704ebd2Sopenharmony_ci LOG("%s err:writeDataToShm shared == nullptr", LOGSTR); 1950704ebd2Sopenharmony_ci return -1; 1960704ebd2Sopenharmony_ci } 1970704ebd2Sopenharmony_ci if (buf == nullptr) { 1980704ebd2Sopenharmony_ci LOG("%s err: writeDataToShm, buf == nullptr", LOGSTR); 1990704ebd2Sopenharmony_ci return -1; 2000704ebd2Sopenharmony_ci } 2010704ebd2Sopenharmony_ci while (shared->written == 1) { 2020704ebd2Sopenharmony_ci sleep(1); 2030704ebd2Sopenharmony_ci } 2040704ebd2Sopenharmony_ci 2050704ebd2Sopenharmony_ci LOG("writeDataToShm %s", buf); 2060704ebd2Sopenharmony_ci memset_s(shared->data, SHARED_DATA_LEN, 0, SHARED_DATA_LEN); 2070704ebd2Sopenharmony_ci strcpy_s(shared->data, strlen(buf) + 1, buf); 2080704ebd2Sopenharmony_ci shared->written = 1; 2090704ebd2Sopenharmony_ci LOG("writeDataToShm shared->data= %s", shared->data); 2100704ebd2Sopenharmony_ci LOG("writeDataToShm shared->written= %d", shared->written); 2110704ebd2Sopenharmony_ci 2120704ebd2Sopenharmony_ci sleep(WAITTIME); 2130704ebd2Sopenharmony_ci return 0; 2140704ebd2Sopenharmony_ci} 2150704ebd2Sopenharmony_ci 2160704ebd2Sopenharmony_ciint disconnectShm(void) 2170704ebd2Sopenharmony_ci{ 2180704ebd2Sopenharmony_ci if (shmdt(shm) == -1) { 2190704ebd2Sopenharmony_ci return -1; 2200704ebd2Sopenharmony_ci } 2210704ebd2Sopenharmony_ci return 0; 2220704ebd2Sopenharmony_ci} 2230704ebd2Sopenharmony_ci 2240704ebd2Sopenharmony_ciint deleteShm(void) 2250704ebd2Sopenharmony_ci{ 2260704ebd2Sopenharmony_ci if (shmctl(shmid, IPC_RMID, nullptr) == -1) { 2270704ebd2Sopenharmony_ci return -1; 2280704ebd2Sopenharmony_ci } 2290704ebd2Sopenharmony_ci return 0; 2300704ebd2Sopenharmony_ci} 2310704ebd2Sopenharmony_ci 2320704ebd2Sopenharmony_cichar* Int2String(int num, char* str) // 10进制 2330704ebd2Sopenharmony_ci{ 2340704ebd2Sopenharmony_ci if (str == nullptr) { 2350704ebd2Sopenharmony_ci return nullptr; 2360704ebd2Sopenharmony_ci } 2370704ebd2Sopenharmony_ci int i = 0; // 指示填充str 2380704ebd2Sopenharmony_ci if (num < 0) { 2390704ebd2Sopenharmony_ci num = -num; 2400704ebd2Sopenharmony_ci str[i++] = '-'; 2410704ebd2Sopenharmony_ci } 2420704ebd2Sopenharmony_ci // 转换 2430704ebd2Sopenharmony_ci do { 2440704ebd2Sopenharmony_ci str[i++] = num % DECIM_TEN + CALCU_FOUR_AIGHT; 2450704ebd2Sopenharmony_ci num /= DECIM_TEN; 2460704ebd2Sopenharmony_ci } while (num); // num不为0继续循环 2470704ebd2Sopenharmony_ci 2480704ebd2Sopenharmony_ci str[i] = '\0'; 2490704ebd2Sopenharmony_ci 2500704ebd2Sopenharmony_ci // 确定开始调整的位置 2510704ebd2Sopenharmony_ci int j = 0; 2520704ebd2Sopenharmony_ci if (str[0] == '-') { 2530704ebd2Sopenharmony_ci j = 1; // 从第二位开始调整 2540704ebd2Sopenharmony_ci ++i; // 由于有负号,所以交换的对称轴也要后移一位 2550704ebd2Sopenharmony_ci } 2560704ebd2Sopenharmony_ci // 对称交换 2570704ebd2Sopenharmony_ci for (; j < i / CALCU_TWO; j++) { 2580704ebd2Sopenharmony_ci // 对称交换两端的值 其实就是省下中间变量交换a+b的值:a=a+b;b=a-b;a=a-b; 2590704ebd2Sopenharmony_ci str[j] = str[j] + str[i - 1 - j]; 2600704ebd2Sopenharmony_ci str[i - 1 - j] = str[j] - str[i - 1 - j]; 2610704ebd2Sopenharmony_ci str[j] = str[j] - str[i - 1 - j]; 2620704ebd2Sopenharmony_ci } 2630704ebd2Sopenharmony_ci 2640704ebd2Sopenharmony_ci return str; // 返回转换后的值 2650704ebd2Sopenharmony_ci}