1/* 2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 * of conditions and the following disclaimer in the documentation and/or other materials 13 * provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 16 * to endorse or promote products derived from this software without specific prior written 17 * permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include "it_test_liteipc.h" 33#include "signal.h" 34#include "sys/wait.h" 35 36#include "unistd.h" 37#include "liteipc.h" 38#include "stdlib.h" 39#include "stdio.h" 40#include "string.h" 41#include "sys/ioctl.h" 42#include "sys/time.h" 43 44#include "smgr_demo.h" 45 46ServiceName g_serviceNameMap[MAX_SREVICE_NUM]; 47BOOL g_cmsRunningFlag = FALSE; 48 49static void InitCms() 50{ 51 (void)memset_s(g_serviceNameMap, sizeof(g_serviceNameMap), 0, sizeof(g_serviceNameMap)); 52} 53 54uint32_t SetCms(int fd) 55{ 56 return ioctl(fd, IPC_SET_CMS, 200); 57} 58 59void SendReply(int fd, IpcMsg *dataIn, uint32_t result, uint32_t serviceHandle) 60{ 61 IpcContent data1; 62 IpcMsg dataOut; 63 unsigned int ret; 64 uint32_t ptr[2]; 65 66 data1.flag = SEND | BUFF_FREE; 67 data1.buffToFree = dataIn; 68 data1.outMsg = &dataOut; 69 (void)memset_s(data1.outMsg, sizeof(IpcMsg), 0, sizeof(IpcMsg)); 70 data1.outMsg->type = MT_REPLY; 71 data1.outMsg->target.handle = dataIn->taskID; 72 data1.outMsg->target.token = dataIn->target.token; 73 data1.outMsg->code = dataIn->code; 74#if (USE_TIMESTAMP == 1) 75 data1.outMsg->timestamp = dataIn->timestamp; 76#endif 77 ptr[0] = result; 78 ptr[1] = serviceHandle; 79 data1.outMsg->dataSz = 8; 80 data1.outMsg->data = ptr; 81 ret = ioctl(fd, IPC_SEND_RECV_MSG, &data1); 82 if (ret) { 83 printf("SendReply failed\n"); 84 } 85} 86 87void FreeBuffer(int fd, IpcMsg *dataIn) 88{ 89 IpcContent data1; 90 unsigned int ret; 91 data1.flag = BUFF_FREE; 92 data1.buffToFree = dataIn; 93 ret = ioctl(fd, IPC_SEND_RECV_MSG, &data1); 94 if (ret) { 95 printf("FreeBuffer failed\n"); 96 } 97} 98 99static uint32_t SendCmsCmd(int fd, CmsCmdContent *content) 100{ 101 unsigned int ret; 102 ret = ioctl(fd, IPC_CMS_CMD, content); 103 if (ret) { 104 printf("SendCmsCmd failed\n"); 105 } 106 return ret; 107} 108 109uint32_t RegService(int fd, char *serviceName, uint32_t nameLen, uint32_t *serviceHandle) 110{ 111 IpcContent data1; 112 IpcMsg dataIn; 113 IpcMsg dataOut; 114 uint32_t ret; 115 uint32_t *ptr = nullptr; 116 ServiceName name; 117 118 if (nameLen > NAME_LEN_MAX) { 119 return -1; 120 } 121 (void)memcpy_s(name.serviceName, nameLen, serviceName, nameLen); 122 name.nameLen = nameLen; 123 124 data1.flag = SEND | RECV; 125 data1.outMsg = &dataOut; 126 (void)memset_s(data1.outMsg, sizeof(IpcMsg), 0, sizeof(IpcMsg)); 127 data1.outMsg->type = MT_REQUEST; 128 data1.outMsg->target.handle = 0; 129 data1.outMsg->code = REG_CODE; 130 data1.outMsg->dataSz = sizeof(ServiceName); 131 data1.outMsg->data = &name; 132 133 ret = ioctl(fd, IPC_SEND_RECV_MSG, &data1); 134 if (ret != 0) { 135 printf("RegService failed\n"); 136 return ret; 137 } 138 ptr = (uint32_t*)(data1.inMsg->data); 139 *serviceHandle = ptr[1]; 140 FreeBuffer(fd, data1.inMsg); 141 return ptr[0]; 142} 143 144uint32_t GetService(int fd, char *serviceName, uint32_t nameLen, uint32_t *serviceHandle) 145{ 146 IpcContent data1; 147 IpcMsg dataIn; 148 IpcMsg dataOut; 149 uint32_t ret; 150 uint32_t *ptr = nullptr; 151 ServiceName name; 152 153 if (nameLen > NAME_LEN_MAX) { 154 return -1; 155 } 156 (void)memcpy_s(name.serviceName, nameLen, serviceName, nameLen); 157 name.nameLen = nameLen; 158 159 data1.flag = SEND | RECV; 160 data1.outMsg = &dataOut; 161 (void)memset_s(data1.outMsg, sizeof(IpcMsg), 0, sizeof(IpcMsg)); 162 data1.outMsg->type = MT_REQUEST; 163 data1.outMsg->target.handle = 0; 164 data1.outMsg->code = GET_CODE; 165 data1.outMsg->dataSz = sizeof(ServiceName); 166 data1.outMsg->data = &name; 167 168 ret = ioctl(fd, IPC_SEND_RECV_MSG, &data1); 169 if (ret != 0) { 170 return ret; 171 } 172 ptr = (uint32_t*)(data1.inMsg->data); 173 *serviceHandle = ptr[1]; 174 FreeBuffer(fd, data1.inMsg); 175 return ptr[0]; 176} 177 178static void HandleServiceRegAndGet(int fd, IpcMsg *data) 179{ 180 uint32_t ret, i; 181 182 if (data->code == STOP_CODE) { 183 g_cmsRunningFlag = FALSE; 184 return; 185 } 186 187 ServiceName *info = (ServiceName*)(data->data); 188 CmsCmdContent content; 189 if ((info->nameLen == 0) || (info->serviceName == NULL)) { 190 goto ERROR_EXIT; 191 } 192 for (i = 0; i < MAX_SREVICE_NUM; i++) { 193 if (g_serviceNameMap[i].serviceName != NULL && g_serviceNameMap[i].nameLen == info->nameLen) { 194 if(memcmp(g_serviceNameMap[i].serviceName, info->serviceName, info->nameLen) == 0) { 195 break; 196 } 197 } 198 } 199 printf("receive service request, code:%d, service name:%s\n", data->code, info->serviceName); 200 switch (data->code) { 201 case REG_CODE: 202 if (i == MAX_SREVICE_NUM) { 203 content.cmd = CMS_GEN_HANDLE; 204 content.taskID = data->taskID; 205 ret = SendCmsCmd(fd, &content); 206 if (ret) { 207 goto ERROR_EXIT; 208 } 209 if (g_serviceNameMap[content.serviceHandle].serviceName != NULL && g_serviceNameMap[content.serviceHandle].nameLen == info->nameLen) { 210 printf("the task has already a service named:%s\n", g_serviceNameMap[content.serviceHandle].serviceName); 211 goto ERROR_REG; 212 } else { 213 (void)memcpy_s(g_serviceNameMap[content.serviceHandle].serviceName, info->nameLen, 214 info->serviceName, info->nameLen); 215 g_serviceNameMap[content.serviceHandle].nameLen = info->nameLen; 216 SendReply(fd, data, 0, content.serviceHandle); 217 } 218 }else { 219 printf("this service already registered\n"); 220 goto ERROR_EXIT; 221 } 222 break; 223 case GET_CODE: 224 if (i == MAX_SREVICE_NUM) { 225 goto ERROR_EXIT; 226 }else { 227 content.cmd = CMS_ADD_ACCESS; 228 content.taskID = data->taskID; 229 content.serviceHandle = i; 230 SendCmsCmd(fd, &content); 231 SendReply(fd, data, 0, i); 232 } 233 break; 234 default: 235 break; 236 } 237 return; 238ERROR_REG: 239 content.cmd = CMS_REMOVE_HANDLE; 240 SendCmsCmd(fd, &content); 241ERROR_EXIT: 242 SendReply(fd, data, -1, 0); 243} 244 245static uint32_t CmsLoop(int fd) 246{ 247 IpcContent data1; 248 IpcMsg dataIn; 249 IpcMsg dataOut; 250 uint32_t ret; 251 g_cmsRunningFlag = TRUE; 252 while (g_cmsRunningFlag == TRUE) { 253 data1.flag = RECV; 254 ret = ioctl(fd, IPC_SEND_RECV_MSG, &data1); 255 if (ret != 0) { 256 printf("bad request!\n"); 257 continue; 258 } 259 switch (data1.inMsg->type) { 260 case MT_REQUEST: 261 HandleServiceRegAndGet(fd, data1.inMsg); 262 break; 263 default: 264 printf("request not support:%d!\n", data1.inMsg->type); 265 FreeBuffer(fd, data1.inMsg); 266 break; 267 } 268 } 269} 270 271void StartCms(int fd) 272{ 273 InitCms(); 274 CmsLoop(fd); 275} 276 277void StopCms(int fd) 278{ 279 IpcContent data1; 280 IpcMsg dataOut; 281 int ret; 282 283 data1.flag = SEND; 284 data1.outMsg = &dataOut; 285 (void)memset_s(data1.outMsg, sizeof(IpcMsg), 0, sizeof(IpcMsg)); 286 data1.outMsg->type = MT_REQUEST; 287 data1.outMsg->target.handle = 0; 288 data1.outMsg->code = STOP_CODE; 289 data1.outMsg->dataSz = 0; 290 data1.outMsg->data = 0; 291 292 ret = ioctl(fd, IPC_SEND_RECV_MSG, &data1); 293 if (ret != 0) { 294 printf("StopCms failed ioctl ret:%d!\n", ret); 295 } 296} 297 298