17746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine/* Copyright (C) 2010 The Android Open Source Project
27746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine**
37746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine** This software is licensed under the terms of the GNU General Public
47746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine** License version 2, as published by the Free Software Foundation, and
57746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine** may be copied, distributed, and modified under those terms.
67746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine**
77746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine** This program is distributed in the hope that it will be useful,
87746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine** but WITHOUT ANY WARRANTY; without even the implied warranty of
97746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
107746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine** GNU General Public License for more details.
117746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine*/
127746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
137746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine/*
147746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine * Contains implementation of routines and that are used in the course
157746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine * of the emulator's core initialization.
167746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine */
177746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
187746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#include <stdio.h>
197746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#include <stdlib.h>
207746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#include <errno.h>
217746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#include "qemu-common.h"
227746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#include "sockets.h"
237746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#include "android/android.h"
247746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#include "android/core-init-utils.h"
257746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#include "android/utils/bufprint.h"
267746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
277746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkineextern char* android_op_ui_port;
287746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
297746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine/* Sends core initialization status message back to the UI that started this
307746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine * core process.
317746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine * Param:
327746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine *  msg - Message to send. On success, message must begin with "ok:", followed
337746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine *      by "port=<console port number>". On initialization failure, message must
347746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine *      begin with "ko:", followed by a string describing the reason of failure.
357746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine */
367746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkinestatic void
377746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkineandroid_core_send_init_response(const char* msg)
387746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine{
397746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    int fd;
407746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    int ui_port;
417746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
427746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    if (android_op_ui_port == NULL) {
437746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        // No socket - no reply.
447746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        return;
457746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    }
467746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
477746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    ui_port = atoi(android_op_ui_port);
487746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    if (ui_port >= 0) {
497746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        // At this point UI always starts the core on the same workstation.
507746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        fd = socket_loopback_client(ui_port, SOCKET_STREAM);
517746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        if (fd == -1) {
527746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            fprintf(stderr, "Unable to create UI socket client for port %s: %s\n",
537746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    android_op_ui_port, errno_str);
547746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            return;
557746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        }
567746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        socket_send(fd, msg, strlen(msg) + 1);
577746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        socket_close(fd);
587746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    } else {
597746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        fprintf(stderr, "Invalid -ui-port parameter: %s\n", android_op_ui_port);
607746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    }
617746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine}
627746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
637746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkinevoid
647746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkineandroid_core_init_completed(void)
657746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine{
667746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    char msg[32];
677746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    snprintf(msg, sizeof(msg), "ok:port=%d", android_base_port);
687746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    android_core_send_init_response(msg);
697746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine}
707746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
717746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkinevoid
727746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkineandroid_core_init_failure(const char* fmt, ...)
737746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine{
747746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    va_list  args;
757746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    char msg[4096];
767746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
777746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    // Format "ko" message to send back to the UI.
787746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    snprintf(msg, sizeof(msg), "ko:");
797746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
807746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    va_start(args, fmt);
817746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    vbufprint(msg + strlen(msg), msg + sizeof(msg), fmt, args);
827746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    va_end(args);
837746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
847746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    // Send message back to the UI, print it to the error stdout, and exit the
857746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    // process.
867746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    android_core_send_init_response(msg);
877746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    fprintf(stderr, "%s\n", msg);
887746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    exit(1);
897746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine}
907746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
917746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkinevoid
927746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkineandroid_core_init_exit(int exit_status)
937746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine{
947746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    char msg[32];
957746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    // Build "ok" message with the exit status, and send it back to the UI.
967746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    snprintf(msg, sizeof(msg), "ok:status=%d", exit_status);
977746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    android_core_send_init_response(msg);
987746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    exit(exit_status);
997746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine}
100