You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					154 lines
				
				4.2 KiB
			
		
		
			
		
	
	
					154 lines
				
				4.2 KiB
			| 
								 
											6 years ago
										 
									 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Copyright (C) 2008 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.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef ANDROID_INCLUDE_HARDWARE_QEMUD_H
							 | 
						||
| 
								 | 
							
								#define ANDROID_INCLUDE_HARDWARE_QEMUD_H
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <cutils/sockets.h>
							 | 
						||
| 
								 | 
							
								#include "qemu_pipe.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* the following is helper code that is used by the QEMU-specific
							 | 
						||
| 
								 | 
							
								 * hardware HAL modules to communicate with the emulator program
							 | 
						||
| 
								 | 
							
								 * through the 'qemud' multiplexing daemon, or through the qemud
							 | 
						||
| 
								 | 
							
								 * pipe.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * see the documentation comments for details in
							 | 
						||
| 
								 | 
							
								 * development/emulator/qemud/qemud.c
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * all definitions here are built into the HAL module to avoid
							 | 
						||
| 
								 | 
							
								 * having to write a tiny shared library for this.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* we expect the D macro to be defined to a function macro
							 | 
						||
| 
								 | 
							
								 * that sends its formatted string argument(s) to the log.
							 | 
						||
| 
								 | 
							
								 * If not, ignore the traces.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								#ifndef D
							 | 
						||
| 
								 | 
							
								#  define  D(...)  ((void)0)
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static __inline__ int
							 | 
						||
| 
								 | 
							
								qemud_fd_write(int  fd, const void*  buff, int  len)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int  len2;
							 | 
						||
| 
								 | 
							
								    do {
							 | 
						||
| 
								 | 
							
								        len2 = write(fd, buff, len);
							 | 
						||
| 
								 | 
							
								    } while (len2 < 0 && errno == EINTR);
							 | 
						||
| 
								 | 
							
								    return len2;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static __inline__ int
							 | 
						||
| 
								 | 
							
								qemud_fd_read(int  fd, void*  buff, int  len)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int  len2;
							 | 
						||
| 
								 | 
							
								    do {
							 | 
						||
| 
								 | 
							
								        len2 = read(fd, buff, len);
							 | 
						||
| 
								 | 
							
								    } while (len2 < 0 && errno == EINTR);
							 | 
						||
| 
								 | 
							
								    return len2;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static __inline__ int
							 | 
						||
| 
								 | 
							
								qemud_channel_open(const char*  name)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int  fd;
							 | 
						||
| 
								 | 
							
								    int  namelen = strlen(name);
							 | 
						||
| 
								 | 
							
								    char answer[2];
							 | 
						||
| 
								 | 
							
								    char pipe_name[256];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* First, try to connect to the pipe. */
							 | 
						||
| 
								 | 
							
								    snprintf(pipe_name, sizeof(pipe_name), "qemud:%s", name);
							 | 
						||
| 
								 | 
							
								    fd = qemu_pipe_open(pipe_name);
							 | 
						||
| 
								 | 
							
								    if (fd < 0) {
							 | 
						||
| 
								 | 
							
								        D("QEMUD pipe is not available for %s: %s", name, strerror(errno));
							 | 
						||
| 
								 | 
							
								        /* If pipe is not available, connect to qemud control socket */
							 | 
						||
| 
								 | 
							
								        fd = socket_local_client( "qemud",
							 | 
						||
| 
								 | 
							
								                                  ANDROID_SOCKET_NAMESPACE_RESERVED,
							 | 
						||
| 
								 | 
							
								                                  SOCK_STREAM );
							 | 
						||
| 
								 | 
							
								        if (fd < 0) {
							 | 
						||
| 
								 | 
							
								            D("no qemud control socket: %s", strerror(errno));
							 | 
						||
| 
								 | 
							
								            return -1;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /* send service name to connect */
							 | 
						||
| 
								 | 
							
								        if (qemud_fd_write(fd, name, namelen) != namelen) {
							 | 
						||
| 
								 | 
							
								            D("can't send service name to qemud: %s",
							 | 
						||
| 
								 | 
							
								               strerror(errno));
							 | 
						||
| 
								 | 
							
								            close(fd);
							 | 
						||
| 
								 | 
							
								            return -1;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /* read answer from daemon */
							 | 
						||
| 
								 | 
							
								        if (qemud_fd_read(fd, answer, 2) != 2 ||
							 | 
						||
| 
								 | 
							
								            answer[0] != 'O' || answer[1] != 'K') {
							 | 
						||
| 
								 | 
							
								            D("cant' connect to %s service through qemud", name);
							 | 
						||
| 
								 | 
							
								            close(fd);
							 | 
						||
| 
								 | 
							
								            return -1;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return fd;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static __inline__ int
							 | 
						||
| 
								 | 
							
								qemud_channel_send(int  fd, const void*  msg, int  msglen)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    char  header[5];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (msglen < 0)
							 | 
						||
| 
								 | 
							
								        msglen = strlen((const char*)msg);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (msglen == 0)
							 | 
						||
| 
								 | 
							
								        return 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    snprintf(header, sizeof header, "%04x", msglen);
							 | 
						||
| 
								 | 
							
								    if (qemud_fd_write(fd, header, 4) != 4) {
							 | 
						||
| 
								 | 
							
								        D("can't write qemud frame header: %s", strerror(errno));
							 | 
						||
| 
								 | 
							
								        return -1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (qemud_fd_write(fd, msg, msglen) != msglen) {
							 | 
						||
| 
								 | 
							
								        D("can4t write qemud frame payload: %s", strerror(errno));
							 | 
						||
| 
								 | 
							
								        return -1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static __inline__ int
							 | 
						||
| 
								 | 
							
								qemud_channel_recv(int  fd, void*  msg, int  msgsize)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    char  header[5];
							 | 
						||
| 
								 | 
							
								    int   size, avail;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (qemud_fd_read(fd, header, 4) != 4) {
							 | 
						||
| 
								 | 
							
								        D("can't read qemud frame header: %s", strerror(errno));
							 | 
						||
| 
								 | 
							
								        return -1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    header[4] = 0;
							 | 
						||
| 
								 | 
							
								    if (sscanf(header, "%04x", &size) != 1) {
							 | 
						||
| 
								 | 
							
								        D("malformed qemud frame header: '%.*s'", 4, header);
							 | 
						||
| 
								 | 
							
								        return -1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (size > msgsize)
							 | 
						||
| 
								 | 
							
								        return -1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (qemud_fd_read(fd, msg, size) != size) {
							 | 
						||
| 
								 | 
							
								        D("can't read qemud frame payload: %s", strerror(errno));
							 | 
						||
| 
								 | 
							
								        return -1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return size;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif /* ANDROID_INCLUDE_HARDWARE_QEMUD_H */
							 |