/* * Copyright (C) 2020 The Android Open Source Project * * 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 #include #include #include #include #include // struct sockaddr_un #include "fstream" #include #include #include #include #include #include #include #include #include #define DEBUG_PRINT(fmt, ...) \ do { \ ALOGD("DEBUG: file is %s,line is %d, function is %s(): " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ } while (0) int qemud_channel_open(const char* name) { return qemu_pipe_open_ns("qemud", name, O_RDWR); } int qemud_channel_send(int pipe, const void* msg, int size) { char header[5]; if (size < 0) size = strlen((const char*)msg); if (size == 0) return 0; snprintf(header, sizeof(header), "%04x", size); if (!qemu_pipe_write_fully(pipe, header, 4)) { DEBUG_PRINT("can't write qemud frame header: %s", strerror(errno)); return -1; } if (!qemu_pipe_write_fully(pipe, msg, size)) { DEBUG_PRINT("can4t write qemud frame payload: %s", strerror(errno)); return -1; } return 0; } int qemud_channel_recv(int pipe, void* msg, int maxsize) { char header[5]; int size; if (!qemu_pipe_read_fully(pipe, header, 4)) { return -1; } header[4] = 0; if (sscanf(header, "%04x", &size) != 1) { return -1; } if (size > maxsize) { return -1; } //ALOGD("%s:%d recv header = %s ",__FUNCTION__ ,__LINE__,header); if (!qemu_pipe_read_fully(pipe, msg, size)) { return -1; } //ALOGD("%s:%d:recv msg =%s",__FUNCTION__,__LINE__,(char*)msg); return size; } int qemud_channel_open_cloud(const char* pipeName){ union sockaddr2 { struct sockaddr generic; struct sockaddr_un local; }; char buff[256]={0}; memset(buff, 0, sizeof(buff)); union sockaddr2 saddr; int fd = -1; int ret = -1; int len = -1; const char cloud_sun_path[] = "abstractSocketVmhalbox"; if (pipeName == NULL || pipeName[0] == '\0') { errno = EINVAL; return -1; } snprintf(buff, sizeof buff, "pipe:qemud:%s", pipeName); size_t pathLen = strlen(cloud_sun_path); if (pathLen >= sizeof(saddr.local.sun_path)) return -1; memset(&saddr,0,sizeof(saddr) ); saddr.local.sun_family = AF_LOCAL; memcpy(&saddr.local.sun_path[1], cloud_sun_path, pathLen+1); len = pathLen + offsetof(struct sockaddr_un, sun_path)+1; fd = socket(saddr.generic.sa_family, SOCK_STREAM, 0); if (fd < 0) { DEBUG_PRINT("Could not create socket to bind"); return -1; } DEBUG_PRINT("create socket in %s,fd is %d,sock path Name is %s",__FUNCTION__, fd,cloud_sun_path); if (connect(fd, (struct sockaddr*) &saddr.local, len) < 0) { DEBUG_PRINT("connect error , in %s, sock name is %s",__FUNCTION__, cloud_sun_path); close(fd); fd = -1; } if (fd < 0) { DEBUG_PRINT(" connect error: %s", strerror(errno)); return -1; } DEBUG_PRINT("connect success fd is %d,buff write is %s",fd,buff); int buff_len = strlen(buff) + 1; ret = TEMP_FAILURE_RETRY(write(fd, buff, buff_len)); if (ret != buff_len) { DEBUG_PRINT("%s: Could not connect to %s pipe service: %s", __FUNCTION__, pipeName, strerror(errno)); if (ret == 0) { errno = ECONNRESET; DEBUG_PRINT("\n,ret = 0\n"); } else if (ret > 0) { errno = EINVAL; } return -1; } memset(buff, 0, sizeof(buff)); ret = TEMP_FAILURE_RETRY(read(fd, buff, 2)); // 读取返回值 DEBUG_PRINT("read buff is %s", buff); if (ret != 2 || buff[0] != 'O' || buff[1] != 'K') { DEBUG_PRINT("Could not connect to %s pipe service: %s", buff, strerror(errno)); close(fd); return -1; } return fd; }