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}