1#include "monitor/monitor.h"
2
3#include <stdarg.h>
4#include "hw/hw.h"
5
6struct Monitor {
7    CharDriverState *chr;
8    int mux_out;
9    // int reset_seen;
10    int flags;
11    // int suspend_cnt;
12    uint8_t outbuf[1024];
13    int outbuf_index;
14    // ReadLineState *rs;
15    // CPUOldState *mon_cpu;
16    // BlockDriverCompletionFunc *password_completion_cb;
17    // void *password_opaque;
18    QLIST_ENTRY(Monitor) entry;
19    //int has_quit;
20#ifdef CONFIG_ANDROID
21    void*            fake_opaque;
22    MonitorFakeFunc  fake_func;
23    int64_t          fake_count;
24
25#endif
26};
27
28// Minimalistic / fake implementation of the QEMU Monitor.
29
30Monitor* cur_mon;
31
32/* Return non-zero iff we have a current monitor, and it is in QMP mode.  */
33int monitor_cur_is_qmp(void)
34{
35    return 0;
36}
37
38Monitor*
39monitor_fake_new(void* opaque, MonitorFakeFunc cb)
40{
41    Monitor* mon;
42
43    assert(cb != NULL);
44    mon = g_malloc0(sizeof(*mon));
45    mon->fake_opaque = opaque;
46    mon->fake_func   = cb;
47    mon->fake_count  = 0;
48
49    return mon;
50}
51
52int
53monitor_fake_get_bytes(Monitor* mon)
54{
55    assert(mon->fake_func != NULL);
56    return mon->fake_count;
57}
58
59void
60monitor_fake_free(Monitor* mon)
61{
62    assert(mon->fake_func != NULL);
63    free(mon);
64}
65
66/* This replaces the definition in monitor.c which is in a
67 * #ifndef CONFIG_ANDROID .. #endif block.
68 */
69void monitor_flush(Monitor *mon)
70{
71    if (!mon)
72        return;
73
74    if (mon->fake_func != NULL) {
75        mon->fake_func(mon->fake_opaque, (void*)mon->outbuf, mon->outbuf_index);
76        mon->outbuf_index = 0;
77        mon->fake_count += mon->outbuf_index;
78    } else if (!mon->mux_out) {
79        qemu_chr_write(mon->chr, mon->outbuf, mon->outbuf_index);
80        mon->outbuf_index = 0;
81    }
82}
83
84/* flush at every end of line or if the buffer is full */
85static void monitor_puts(Monitor *mon, const char *str)
86{
87    char c;
88
89    if (!mon)
90        return;
91
92    for(;;) {
93        c = *str++;
94        if (c == '\0')
95            break;
96        if (c == '\n')
97            mon->outbuf[mon->outbuf_index++] = '\r';
98        mon->outbuf[mon->outbuf_index++] = c;
99        if (mon->outbuf_index >= (sizeof(mon->outbuf) - 1)
100            || c == '\n')
101            monitor_flush(mon);
102    }
103}
104
105void monitor_vprintf(Monitor* mon, const char* fmt, va_list args) {
106    char buf[4096];
107    vsnprintf(buf, sizeof(buf), fmt, args);
108    monitor_puts(mon, buf);
109}
110
111void monitor_printf(Monitor *mon, const char *fmt, ...)
112{
113    va_list ap;
114    va_start(ap, fmt);
115    monitor_vprintf(mon, fmt, ap);
116    va_end(ap);
117}
118
119void monitor_print_filename(Monitor *mon, const char *filename)
120{
121    int i;
122
123    for (i = 0; filename[i]; i++) {
124        switch (filename[i]) {
125        case ' ':
126        case '"':
127        case '\\':
128            monitor_printf(mon, "\\%c", filename[i]);
129            break;
130        case '\t':
131            monitor_printf(mon, "\\t");
132            break;
133        case '\r':
134            monitor_printf(mon, "\\r");
135            break;
136        case '\n':
137            monitor_printf(mon, "\\n");
138            break;
139        default:
140            monitor_printf(mon, "%c", filename[i]);
141            break;
142        }
143    }
144}
145
146void monitor_protocol_event(MonitorEvent event, QObject *data)
147{
148    /* XXX: TODO */
149}
150
151void monitor_set_error(Monitor *mon, QError *qerror)
152{
153    QDECREF(qerror);
154}
155
156void monitor_init(CharDriverState* cs, int flags) {
157    // Nothing.
158}
159
160/* boot_set handler */
161static QEMUBootSetHandler *qemu_boot_set_handler = NULL;
162static void *boot_opaque;
163
164void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque)
165{
166    qemu_boot_set_handler = func;
167    boot_opaque = opaque;
168}
169