* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstring>
#include "shm_utils.h"
using namespace std;
const int MAX_DATA_LENGTH = 1024;
const int PERMISSION = 0666;
const int CODE_HEAD = 4;
const int STR_KEY = 5;
const int SHARED_DATA_LEN = 5;
const int WAITTIME = 2;
const int DECIM_TEN = 10;
const int CALCU_TWO = 2;
const int CALCU_FOUR_AIGHT = 48;
const int RES_FAIL = -1;
const char LOGSTR[20] = "LOG_SHM::----";
static void* shm = nullptr;
static struct shared_use_st* shared;
static int shmid;
int createShm(int key)
{
LOG("%s createShm begin...", LOGSTR);
int a = sizeof(struct shared_use_st);
LOG("a=%d", a);
shmid = shmget(static_cast<key_t>(key), sizeof(struct shared_use_st), PERMISSION | IPC_CREAT);
LOG("shmget shmid=%d", shmid);
if (shmid == -1) {
LOG("%s err: shmget, shmid = -1", LOGSTR);
return -1;
}
shm = shmat(shmid, nullptr, 0);
int n = -1;
if (shm == static_cast<void*>(&n)) {
LOG("%s err: shmat, shm = -1", LOGSTR);
return -1;
}
shared = (struct shared_use_st*)shm;
initShm();
LOG("%s createShm end...", LOGSTR);
return 0;
}
void initShm(void)
{
LOG("%s initShm begin...", LOGSTR);
memset_s(shm, sizeof(struct shared_use_st), 0, sizeof(struct shared_use_st));
if (shared == nullptr) {
LOG("%s err:initShm shared = nullptr", LOGSTR);
return;
}
shared->written = 0;
memset_s(shared->data, MAX_DATA_LENGTH, 0, MAX_DATA_LENGTH);
LOG("%s initShm end...", LOGSTR);
return;
}
int readDataFromShm(char* buf)
{
LOG("readDataFromShm begin...");
if (shared == nullptr) {
LOG("%s err:readDataFromShm shared = nullptr", LOGSTR);
return -1;
}
if (shared->written != 0) {
strcpy_s(buf, strlen(shared->data) + 1, shared->data);
LOG("readDataFromShm buf= %s", buf);
LOG("readDataFromShm shared->data= %s", shared->data);
shared->written = 0;
memset_s(shared->data, MAX_DATA_LENGTH, 0, MAX_DATA_LENGTH);
} else {
return -1;
}
LOG("SUCCESS: readDataFromShm return 0");
return 0;
}
int readDataFromShmNoClear(char* buf)
{
LOG("readDataFromShmNoClear begin...");
if (shared == nullptr) {
return -1;
}
if (shared->written != 0) {
strcpy_s(buf, strlen(shared->data) + 1, shared->data);
LOG("readDataFromShmNoClear buf= %s", buf);
LOG("readDataFromShmNoClear shared->data= %s", shared->data);
} else {
return -1;
}
LOG("SUCCESS: readDataFromShmNoClear return 0");
return 0;
}
int waitDataWithCode(char* code, char* data)
{
LOG("waitDataWithCode begin...");
int i = 0;
int timeout = 10;
char str[MAX_DATA_LENGTH] = { 0 };
if (code == nullptr || data == nullptr) {
LOG("code = nullptr ,data = nullptr");
return RES_FAIL;
}
while (i < timeout) {
if (readDataFromShmNoClear(str) != 0 || strncmp(code, str, CODE_HEAD) != 0) {
i++;
sleep(1);
LOG("while: waitDataWithCode 9999 str= %s, i=%d", str, i);
continue;
}
if (readDataFromShm(str) == 0 && strncmp(code, str, CODE_HEAD) == 0) {
if (strncpy_s(data, strlen("0") + 1, str + STR_KEY, 1) != EOK) {
LOG("ERR:strncpy_s");
return RES_FAIL;
}
LOG("waitDataWithCode 9999 str= %s", str);
LOG("waitDataWithCode 9999 data= %s", data);
LOG("SUCCESS:waitDataWithCode return 0");
return 0;
}
i++;
sleep(1);
LOG("while: waitDataWithCode 9999 str= %s, i=%d", str, i);
}
LOG("ERR :waitDataWithCode ");
return RES_FAIL;
}
int writeCodeDataToShm(int code, char* buf)
{
LOG("writeCodeDataToShm, begin");
char* str = (char*)malloc(MAX_DATA_LENGTH);
if (str == nullptr) {
LOG("malloc fail");
return -1;
}
(void)memset_s(str, MAX_DATA_LENGTH, 0, MAX_DATA_LENGTH);
char codeStr[5] = { 0 };
char* str2 = Int2String(code, codeStr);
if (str2 == nullptr) {
LOG("ERROR: str2 == nullptr");
return -1;
}
if (strcpy_s(str, MAX_DATA_LENGTH, codeStr) != EOK) {
LOG("ERROR: strcpy_s != EOK");
return -1;
}
if (strcat_s(str, MAX_DATA_LENGTH, ":") != EOK) {
LOG("ERROR: 1. strcat_s!= EOK ");
return -1;
}
if (buf == nullptr) {
LOG("ERROR:buf == nullptr ");
return -1;
}
if (strcat_s(str, MAX_DATA_LENGTH, buf) != EOK) {
LOG("ERROR:2. strcat_s != EOK");
return -1;
}
int nres = writeDataToShm(str);
if (nres == -1) {
return -1;
}
return 0;
}
int writeDataToShm(char* buf)
{
LOG("%s writeDataToShm, begin", LOGSTR);
if (shared == nullptr) {
LOG("%s err:writeDataToShm shared == nullptr", LOGSTR);
return -1;
}
if (buf == nullptr) {
LOG("%s err: writeDataToShm, buf == nullptr", LOGSTR);
return -1;
}
while (shared->written == 1) {
sleep(1);
}
LOG("writeDataToShm %s", buf);
memset_s(shared->data, SHARED_DATA_LEN, 0, SHARED_DATA_LEN);
strcpy_s(shared->data, strlen(buf) + 1, buf);
shared->written = 1;
LOG("writeDataToShm shared->data= %s", shared->data);
LOG("writeDataToShm shared->written= %d", shared->written);
sleep(WAITTIME);
return 0;
}
int disconnectShm(void)
{
if (shmdt(shm) == -1) {
return -1;
}
return 0;
}
int deleteShm(void)
{
if (shmctl(shmid, IPC_RMID, nullptr) == -1) {
return -1;
}
return 0;
}
char* Int2String(int num, char* str)
{
if (str == nullptr) {
return nullptr;
}
int i = 0;
if (num < 0) {
num = -num;
str[i++] = '-';
}
do {
str[i++] = num % DECIM_TEN + CALCU_FOUR_AIGHT;
num /= DECIM_TEN;
} while (num);
str[i] = '\0';
int j = 0;
if (str[0] == '-') {
j = 1;
++i;
}
for (; j < i / CALCU_TWO; j++) {
str[j] = str[j] + str[i - 1 - j];
str[i - 1 - j] = str[j] - str[i - 1 - j];
str[j] = str[j] - str[i - 1 - j];
}
return str;
}