1d9f0492fSopenharmony_ci/*
2d9f0492fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License.
5d9f0492fSopenharmony_ci * You may obtain a copy of the License at
6d9f0492fSopenharmony_ci *
7d9f0492fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8d9f0492fSopenharmony_ci *
9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and
13d9f0492fSopenharmony_ci * limitations under the License.
14d9f0492fSopenharmony_ci */
15d9f0492fSopenharmony_ci#include "param_message.h"
16d9f0492fSopenharmony_ci
17d9f0492fSopenharmony_ci#include <sys/socket.h>
18d9f0492fSopenharmony_ci#include <sys/un.h>
19d9f0492fSopenharmony_ci
20d9f0492fSopenharmony_ci#include "param_utils.h"
21d9f0492fSopenharmony_ci#include "securec.h"
22d9f0492fSopenharmony_ci
23d9f0492fSopenharmony_ciint ConnectServer(int fd, const char *servername)
24d9f0492fSopenharmony_ci{
25d9f0492fSopenharmony_ci    PARAM_CHECK(fd >= 0, return -1, "Invalid fd %d", fd);
26d9f0492fSopenharmony_ci    PARAM_CHECK(servername != NULL, return -1, "Invalid servername");
27d9f0492fSopenharmony_ci    int opt = 1;
28d9f0492fSopenharmony_ci    int ret = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt));
29d9f0492fSopenharmony_ci    PARAM_CHECK(ret == 0, return -1, "Failed to set socket option");
30d9f0492fSopenharmony_ci    struct sockaddr_un addr;
31d9f0492fSopenharmony_ci    /* fill socket address structure with server's address */
32d9f0492fSopenharmony_ci    ret = memset_s(&addr, sizeof(addr), 0, sizeof(addr));
33d9f0492fSopenharmony_ci    PARAM_CHECK(ret == 0, return -1, "Failed to memset server address");
34d9f0492fSopenharmony_ci    addr.sun_family = AF_UNIX;
35d9f0492fSopenharmony_ci    ret = sprintf_s(addr.sun_path, sizeof(addr.sun_path) - 1, "%s", servername);
36d9f0492fSopenharmony_ci    PARAM_CHECK(ret > EOK, return -1, "Failed to sprintf_s server address");
37d9f0492fSopenharmony_ci    socklen_t len = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path);
38d9f0492fSopenharmony_ci    ret = connect(fd, (struct sockaddr *)&addr, len);
39d9f0492fSopenharmony_ci    PARAM_CHECK(ret != -1, return -1, "Failed to connect server %s %d", servername, errno);
40d9f0492fSopenharmony_ci    PARAM_LOGV("ConnectServer %s success", servername);
41d9f0492fSopenharmony_ci    return 0;
42d9f0492fSopenharmony_ci}
43d9f0492fSopenharmony_ci
44d9f0492fSopenharmony_ciint FillParamMsgContent(const ParamMessage *request, uint32_t *start, int type, const char *value, uint32_t length)
45d9f0492fSopenharmony_ci{
46d9f0492fSopenharmony_ci    PARAM_CHECK(request != NULL && start != NULL, return -1, "Invalid param");
47d9f0492fSopenharmony_ci    PARAM_CHECK(value != NULL, return -1, "Invalid value");
48d9f0492fSopenharmony_ci    uint32_t bufferSize = request->msgSize - sizeof(ParamMessage);
49d9f0492fSopenharmony_ci    uint32_t offset = *start;
50d9f0492fSopenharmony_ci    PARAM_CHECK((offset + sizeof(ParamMsgContent) + length) <= bufferSize,
51d9f0492fSopenharmony_ci        return -1, "Invalid msgSize %u offset %u %d", request->msgSize, offset, type);
52d9f0492fSopenharmony_ci    ParamMsgContent *content = (ParamMsgContent *)(request->data + offset);
53d9f0492fSopenharmony_ci    content->type = type;
54d9f0492fSopenharmony_ci    content->contentSize = length + 1;
55d9f0492fSopenharmony_ci    if (length > 0) {
56d9f0492fSopenharmony_ci        int ret = memcpy_s(content->content, content->contentSize - 1, value, length);
57d9f0492fSopenharmony_ci        PARAM_CHECK(ret == EOK, return -1, "Failed to copy value for %d", type);
58d9f0492fSopenharmony_ci    }
59d9f0492fSopenharmony_ci    content->content[length] = '\0';
60d9f0492fSopenharmony_ci    offset += sizeof(ParamMsgContent) + PARAM_ALIGN(content->contentSize);
61d9f0492fSopenharmony_ci    *start = offset;
62d9f0492fSopenharmony_ci    return 0;
63d9f0492fSopenharmony_ci}
64d9f0492fSopenharmony_ci
65d9f0492fSopenharmony_ciParamMessage *CreateParamMessage(int type, const char *name, uint32_t msgSize)
66d9f0492fSopenharmony_ci{
67d9f0492fSopenharmony_ci    PARAM_CHECK(name != NULL, return NULL, "Invalid name");
68d9f0492fSopenharmony_ci    PARAM_CHECK(msgSize < PARAM_BUFFER_MAX, return NULL, "Invalid msg size %u", msgSize);
69d9f0492fSopenharmony_ci    uint32_t size = msgSize;
70d9f0492fSopenharmony_ci    if (msgSize < sizeof(ParamMessage)) {
71d9f0492fSopenharmony_ci        size = sizeof(ParamMessage);
72d9f0492fSopenharmony_ci    }
73d9f0492fSopenharmony_ci    ParamMessage *msg = (ParamMessage *)calloc(1, size);
74d9f0492fSopenharmony_ci    PARAM_CHECK(msg != NULL, return NULL, "Failed to malloc message");
75d9f0492fSopenharmony_ci    msg->type = type;
76d9f0492fSopenharmony_ci    msg->id.msgId = 0;
77d9f0492fSopenharmony_ci    msg->msgSize = size;
78d9f0492fSopenharmony_ci    int ret = strcpy_s(msg->key, sizeof(msg->key) - 1, name);
79d9f0492fSopenharmony_ci    PARAM_CHECK(ret == EOK, free(msg);
80d9f0492fSopenharmony_ci        return NULL, "Failed to fill name");
81d9f0492fSopenharmony_ci    return msg;
82d9f0492fSopenharmony_ci}
83d9f0492fSopenharmony_ci
84d9f0492fSopenharmony_ciParamMsgContent *GetNextContent(const ParamMessage *request, uint32_t *offset)
85d9f0492fSopenharmony_ci{
86d9f0492fSopenharmony_ci    PARAM_CHECK(request != NULL, return NULL, "Invalid request");
87d9f0492fSopenharmony_ci    PARAM_CHECK(offset != NULL, return NULL, "Invalid offset");
88d9f0492fSopenharmony_ci    ParamMessage *msg = (ParamMessage *)request;
89d9f0492fSopenharmony_ci    if ((*offset + sizeof(ParamMessage) + sizeof(ParamMsgContent)) >= msg->msgSize) {
90d9f0492fSopenharmony_ci        return NULL;
91d9f0492fSopenharmony_ci    }
92d9f0492fSopenharmony_ci    ParamMsgContent *content = (ParamMsgContent *)(msg->data + *offset);
93d9f0492fSopenharmony_ci    *offset += sizeof(ParamMsgContent) + PARAM_ALIGN(content->contentSize);
94d9f0492fSopenharmony_ci    return content;
95d9f0492fSopenharmony_ci}
96