summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbohu2017-02-28 16:58:36 -0600
committerbohu2017-03-28 11:27:00 -0500
commitff87855e10423a1ad6f764f378b8182f86c6f738 (patch)
tree32e166bf783b496f439f8ac70e349ea4a954b9ee /qemu_pipe
parent449682a6c384678e7701ee94d257f2aaf71bc336 (diff)
downloadplatform-system-core-ff87855e10423a1ad6f764f378b8182f86c6f738.tar.gz
platform-system-core-ff87855e10423a1ad6f764f378b8182f86c6f738.tar.xz
platform-system-core-ff87855e10423a1ad6f764f378b8182f86c6f738.zip
Qemu-pipe: refactor qemu_pipe.h into libqemu_pipe
Traditionally, qemu_pipe has both the declaration and implentation of each function in one header file--qemu_pipe.h, and it is getting incovenient to maintain. This CL separates the implementation of functions from the header file, and makes qemu_pipe a static library for other modules to link to. Note that the interface and implementation of qemu_pipe are kept unchanged, and future CLs will enhance the implementation to make it more reliable and more compatible with old and new API levels. Following projects are affected by this refactoring, and they are modified accordingly: hardware/ril/reference-ril Change-Id: I541ecbf0cc7eadeef9d4e37ffd9ca7bfcc5c94c0 (cherry picked from aosp 294d44be33bf6ad6d7d53189d38202a4911f2bd7)
Diffstat (limited to 'qemu_pipe')
-rw-r--r--qemu_pipe/Android.mk19
-rw-r--r--qemu_pipe/include/qemu_pipe.h62
-rw-r--r--qemu_pipe/qemu_pipe.cpp132
3 files changed, 213 insertions, 0 deletions
diff --git a/qemu_pipe/Android.mk b/qemu_pipe/Android.mk
new file mode 100644
index 000000000..6e0144ce1
--- /dev/null
+++ b/qemu_pipe/Android.mk
@@ -0,0 +1,19 @@
1# Copyright 2011 The Android Open Source Project
2
3LOCAL_PATH:= $(call my-dir)
4
5common_static_libraries := \
6 libbase
7include $(CLEAR_VARS)
8LOCAL_CLANG := true
9LOCAL_SANITIZE := integer
10LOCAL_SRC_FILES:= \
11 qemu_pipe.cpp
12LOCAL_C_INCLUDES := \
13 $(LOCAL_PATH)/include \
14 system/base/include
15LOCAL_MODULE:= libqemu_pipe
16LOCAL_STATIC_LIBRARIES := $(common_static_libraries)
17LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
18LOCAL_CFLAGS := -Werror
19include $(BUILD_STATIC_LIBRARY)
diff --git a/qemu_pipe/include/qemu_pipe.h b/qemu_pipe/include/qemu_pipe.h
new file mode 100644
index 000000000..16486c087
--- /dev/null
+++ b/qemu_pipe/include/qemu_pipe.h
@@ -0,0 +1,62 @@
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#ifndef ANDROID_CORE_INCLUDE_QEMU_PIPE_H
17#define ANDROID_CORE_INCLUDE_QEMU_PIPE_H
18
19#include <stddef.h>
20
21#ifdef __cplusplus
22extern "C" {
23#endif
24// Try to open a new Qemu fast-pipe. This function returns a file descriptor
25// that can be used to communicate with a named service managed by the
26// emulator.
27//
28// This file descriptor can be used as a standard pipe/socket descriptor.
29//
30// 'pipeName' is the name of the emulator service you want to connect to,
31// and must begin with 'pipe:' (e.g. 'pipe:camera' or 'pipe:opengles').
32//
33// On success, return a valid file descriptor, or -1/errno on failure. E.g.:
34//
35// EINVAL -> unknown/unsupported pipeName
36// ENOSYS -> fast pipes not available in this system.
37//
38// ENOSYS should never happen, except if you're trying to run within a
39// misconfigured emulator.
40//
41// You should be able to open several pipes to the same pipe service,
42// except for a few special cases (e.g. GSM modem), where EBUSY will be
43// returned if more than one client tries to connect to it.
44int qemu_pipe_open(const char* pipeName);
45
46// Send a framed message |buff| of |len| bytes through the |fd| descriptor.
47// This really adds a 4-hexchar prefix describing the payload size.
48// Returns 0 on success, and -1 on error.
49int qemu_pipe_frame_send(int fd, const void* buff, size_t len);
50
51// Read a frame message from |fd|, and store it into |buff| of |len| bytes.
52// If the framed message is larger than |len|, then this returns -1 and the
53// content is lost. Otherwise, this returns the size of the message. NOTE:
54// empty messages are possible in a framed wire protocol and do not mean
55// end-of-stream.
56int qemu_pipe_frame_recv(int fd, void* buff, size_t len);
57
58#ifdef __cplusplus
59}
60#endif
61
62#endif /* ANDROID_CORE_INCLUDE_QEMU_PIPE_H */
diff --git a/qemu_pipe/qemu_pipe.cpp b/qemu_pipe/qemu_pipe.cpp
new file mode 100644
index 000000000..a4529deb8
--- /dev/null
+++ b/qemu_pipe/qemu_pipe.cpp
@@ -0,0 +1,132 @@
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "qemu_pipe.h"
18
19#include <unistd.h>
20#include <fcntl.h>
21#include <string.h>
22#include <errno.h>
23#include <stdio.h>
24
25
26// Define QEMU_PIPE_DEBUG if you want to print error messages when an error
27// occurs during pipe operations. The macro should simply take a printf-style
28// formatting string followed by optional arguments.
29#ifndef QEMU_PIPE_DEBUG
30# define QEMU_PIPE_DEBUG(...) (void)0
31#endif
32
33// Try to open a new Qemu fast-pipe. This function returns a file descriptor
34// that can be used to communicate with a named service managed by the
35// emulator.
36//
37// This file descriptor can be used as a standard pipe/socket descriptor.
38//
39// 'pipeName' is the name of the emulator service you want to connect to,
40// and must begin with 'pipe:' (e.g. 'pipe:camera' or 'pipe:opengles').
41//
42// On success, return a valid file descriptor, or -1/errno on failure. E.g.:
43//
44// EINVAL -> unknown/unsupported pipeName
45// ENOSYS -> fast pipes not available in this system.
46//
47// ENOSYS should never happen, except if you're trying to run within a
48// misconfigured emulator.
49//
50// You should be able to open several pipes to the same pipe service,
51// except for a few special cases (e.g. GSM modem), where EBUSY will be
52// returned if more than one client tries to connect to it.
53int qemu_pipe_open(const char* pipeName) {
54 // Sanity check.
55 if (!pipeName || memcmp(pipeName, "pipe:", 5) != 0) {
56 errno = EINVAL;
57 return -1;
58 }
59
60 int fd = TEMP_FAILURE_RETRY(open("/dev/qemu_pipe", O_RDWR));
61 if (fd < 0) {
62 QEMU_PIPE_DEBUG("%s: Could not open /dev/qemu_pipe: %s", __FUNCTION__,
63 strerror(errno));
64 return -1;
65 }
66
67 // Write the pipe name, *including* the trailing zero which is necessary.
68 size_t pipeNameLen = strlen(pipeName);
69 ssize_t ret = TEMP_FAILURE_RETRY(write(fd, pipeName, pipeNameLen + 1U));
70 if (ret != (ssize_t)pipeNameLen + 1) {
71 QEMU_PIPE_DEBUG("%s: Could not connect to %s pipe service: %s",
72 __FUNCTION__, pipeName, strerror(errno));
73 if (ret == 0) {
74 errno = ECONNRESET;
75 } else if (ret > 0) {
76 errno = EINVAL;
77 }
78 return -1;
79 }
80 return fd;
81}
82
83// Send a framed message |buff| of |len| bytes through the |fd| descriptor.
84// This really adds a 4-hexchar prefix describing the payload size.
85// Returns 0 on success, and -1 on error.
86int qemu_pipe_frame_send(int fd, const void* buff, size_t len) {
87 char header[5];
88 snprintf(header, sizeof(header), "%04zx", len);
89 ssize_t ret = TEMP_FAILURE_RETRY(write(fd, header, 4));
90 if (ret != 4) {
91 QEMU_PIPE_DEBUG("Can't write qemud frame header: %s", strerror(errno));
92 return -1;
93 }
94 ret = TEMP_FAILURE_RETRY(write(fd, buff, len));
95 if (ret != (ssize_t)len) {
96 QEMU_PIPE_DEBUG("Can't write qemud frame payload: %s", strerror(errno));
97 return -1;
98 }
99 return 0;
100}
101
102// Read a frame message from |fd|, and store it into |buff| of |len| bytes.
103// If the framed message is larger than |len|, then this returns -1 and the
104// content is lost. Otherwise, this returns the size of the message. NOTE:
105// empty messages are possible in a framed wire protocol and do not mean
106// end-of-stream.
107int qemu_pipe_frame_recv(int fd, void* buff, size_t len) {
108 char header[5];
109 ssize_t ret = TEMP_FAILURE_RETRY(read(fd, header, 4));
110 if (ret != 4) {
111 QEMU_PIPE_DEBUG("Can't read qemud frame header: %s", strerror(errno));
112 return -1;
113 }
114 header[4] = '\0';
115 size_t size;
116 if (sscanf(header, "%04zx", &size) != 1) {
117 QEMU_PIPE_DEBUG("Malformed qemud frame header: [%.*s]", 4, header);
118 return -1;
119 }
120 if (size > len) {
121 QEMU_PIPE_DEBUG("Oversized qemud frame (% bytes, expected <= %)", size,
122 len);
123 return -1;
124 }
125 ret = TEMP_FAILURE_RETRY(read(fd, buff, size));
126 if (ret != (ssize_t)size) {
127 QEMU_PIPE_DEBUG("Could not read qemud frame payload: %s",
128 strerror(errno));
129 return -1;
130 }
131 return size;
132}