void hmp_info_usernet(Monitor *mon, const QDict *qdict);
#ifdef CONFIG_MARU
+int maru_hostfwd_add(Monitor *mon, const char *redir_str);
bool hostfwd_try_add(int is_udp, const char *host_addr_str,
int host_port, const char *guest_addr_str, int guest_port);
bool hostfwd_try_remove(int is_udp, const char *host_addr_str, int host_port);
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "net/slirp.h"
-
+#include "qapi/qmp/qstring.h"
#ifndef _WIN32
#include <pwd.h>
#include "migration/register.h"
#include "migration/qemu-file-types.h"
+#include "tizen/src/debug_ch.h"
+MULTI_DEBUG_CHANNEL(qemu, slirpnet);
+
+
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
{
const char *p, *p1;
return -1;
}
+#ifdef CONFIG_MARU
+
+int maru_hostfwd_add(Monitor *mon, const char *redir_str)
+{
+ int ret = -1; //invalid args
+ if (QTAILQ_EMPTY(&slirp_stacks)) {
+ LOG_INFO("maru_hostfwd_add : slirp_stacks user netdev not available!\n");
+ return -1;
+ }
+
+ if (mon != NULL) {
+ SlirpState *s = QTAILQ_FIRST(&slirp_stacks);
+
+ if (s) {
+ Error *err = NULL;
+
+
+#define TIZEN_BACKWARD_COMPACT_REDIR_FORMAT 1
+#if defined (TIZEN_BACKWARD_COMPACT_REDIR_FORMAT)
+ QString *redir_str_new = qstring_new();
+ bool firstColon = true;
+ bool secondColon = true;
+ for (int i=0; redir_str[i]; i++) {
+ char c = redir_str[i];
+ if (redir_str[i] == ':' && firstColon) {
+ qstring_append_chr(redir_str_new, redir_str[i]);
+ firstColon = false;
+ } else if (redir_str[i] == ':' && secondColon) {
+ c = '-';
+ secondColon = false;
+ }
+ qstring_append_chr(redir_str_new, c);
+ }
+
+ redir_str = qstring_get_str(redir_str_new);
+ LOG_INFO("maru_hostfwd_add : slirp_hostfwd redir : %s\n", redir_str);
+#endif //TIZEN_BACKWARD_COMPACT_REDIR_FORMAT
+ ret = slirp_hostfwd(s, redir_str, &err);
+#if defined (TIZEN_BACKWARD_COMPACT_REDIR_FORMAT)
+ qobject_unref(redir_str_new);
+#endif //TIZEN_BACKWARD_COMPACT_REDIR_FORMAT
+ if (err != NULL) { //free error as we will not report it, user could recover
+ LOG_INFO("maru_hostfwd_add : slirp_hostfwd failed with ret : %d\n", ret);
+ error_report_err(err);
+ }
+ } else {
+ LOG_INFO("maru_hostfwd_add : slirp_stacks first node failed!\n");
+ }
+ }
+ return ret;
+}
+
+
+#endif //CONFIG_MARU
+
void hmp_hostfwd_add(Monitor *mon, const QDict *qdict)
{
const char *redir_str;
void json_lexer_destroy(JSONLexer *lexer)
{
- g_string_free(lexer->token, true);
+ if (lexer->token != NULL) {
+ g_string_free(lexer->token, true);
+ lexer->token = NULL;
+ }
}
qemu_mutex_init(&mon->qmp_queue_lock);
mon->qmp_requests = g_queue_new();
- monitor_list_append(&mon->common);
return mon;
}
static void ecs_close(ECS_State *cs)
{
ECS_Client *clii, *next;
+ Monitor* mon = &cs->mon->common;
LOG_INFO("### Good bye! ECS ###\n");
if (cs == NULL) {
cs->listen_fd = -1;
}
- g_free(cs->mon);
+ //free monitors, this func should clear qmp monitor resources too
+ monitor_data_destroy(mon);
cs->mon = NULL;
g_free(keepalive_buf);
str = "\n";
}
- LOG_INFO("ecs_monitor_puts - data: %s\n", str);
-
for (i = 0; str[i]; i++) {
c = str[i];
+#ifndef _WIN32
if (c == '\n') {
-#ifdef CONFIG_WIN32
qstring_append_chr(mon->outbuf, '\r');
-#endif // CONFIG_WIN32
}
+#endif // CONFIG_WIN32
qstring_append_chr(mon->outbuf, c);
}
return rsp;
}
-#if 0
-static void ecs_json_emitter(Monitor *mon, const QObject *data)
-{
- QString *json;
-
- json = qobject_to_json(data);
-
- assert(json != NULL);
-
- qstring_append_chr(json, '\n');
- ecs_monitor_puts(mon, qstring_get_str(json));
-
- qobject_unref(json);
-}
-
-static void ecs_protocol_emitter(Monitor *mon, const char *type,
- QObject *data, Error *err)
-{
- QDict *qmp = NULL;
- QObject *obj;
-
- TRACE("ecs_protocol_emitter called.\n");
- if (!err) {
- /* success response */
- if (data) {
- qobject_ref(data);
- qmp = qobject_to(QDict, data);
- } else {
- /* return an empty QDict by default */
- qmp = qdict_new();
- qdict_put(qmp, "return", qdict_new());
- }
-
- if (type == NULL) {
- obj = qobject_from_jsonf_nofail("%s", "unknown");
- } else {
- obj = qobject_from_jsonf_nofail("%s", type);
- }
- qdict_put_obj(qmp, "type", obj);
-
- } else {
- /* error response */
- qmp = build_qmp_error_dict(err);
- }
-
- ecs_json_emitter(mon, QOBJECT(qmp));
- qobject_unref(qmp);
-}
-#endif //0
static QDict *qmp_check_input_obj(QObject *input_obj, Error **errp)
{
const QDictEntry *ent;
return input_dict;
}
-static void ecs_monitor_qmp_respond(MonitorQMP *mon, QDict *rsp)
+static void ecs_monitor_qmp_respond(MonitorQMP *mon, QDict *rsp, char* type)
{
- const QObject *data = QOBJECT(rsp);
+ const QObject *data;
QString *json;
- LOG_INFO("ecs_monitor_qmp_respond: qobject_to_json_pretty\n");
+ QObject* obj;
- json = mon->pretty ? qobject_to_json_pretty(data) : qobject_to_json(data);
+ if (type == NULL) {
+ obj = qobject_from_jsonf_nofail("%s", "unknown");
+ } else {
+ obj = qobject_from_jsonf_nofail("%s", type);
+ }
+ qdict_put_obj(rsp, "type", obj);
+
+ data = QOBJECT(rsp);
+
+ json = qobject_to_json(data);
assert(json != NULL);
qstring_append_chr(json, '\n');
ecs_monitor_puts(&mon->common, qstring_get_str(json));
qobject_unref(json);
+ g_free(type);
}
-static void ecs_monitor_qmp_dispatch(MonitorQMP *mon, QObject *req)
+static void ecs_monitor_qmp_dispatch(MonitorQMP *mon, QObject *req, char* type)
{
Monitor *old_mon;
QDict *rsp;
}
}
- ecs_monitor_qmp_respond(mon, rsp);
+ ecs_monitor_qmp_respond(mon, rsp, type);
qobject_unref(rsp);
}
QObject *id = NULL;
QDict *qdict;
Error *local_err = NULL;
+ char* type = NULL;
assert(!req != !err);
assert(mon != NULL);
if (qdict) {
id = qdict_get(qdict, "id");
if (qdict_haskey(qdict, "type")) {
- //TODO: store type in outbuf to return in response
+ type = g_strdup(qdict_get_str(qdict, "type"));
qdict_del(qdict, "type");
}
} /* else will fail qmp_dispatch() */
if (qdict) {
/* Consider all commands OOB, OOB commands are executed immediately */
trace_monitor_qmp_cmd_out_of_band(qobject_get_try_str(id) ?: "");
- ecs_monitor_qmp_dispatch(mon, req);
+ ecs_monitor_qmp_dispatch(mon, req, type);
qobject_unref(req);
return;
}
//emit error response
if (local_err) {
qdict = build_qmp_error_dict(local_err);
- ecs_monitor_qmp_respond(mon, qdict);
+ ecs_monitor_qmp_respond(mon, qdict, type);
error_free(local_err);
}
}
#include "emulator_common.h"
#include "qemu/option.h"
-
+#include "qapi/error.h"
#include "net/slirp.h"
#include "monitor/qdev.h"
#include "hw/virtio/maru_virtio_sensor.h"
#include "ecs_sensor.h"
#include "ecs_hds.h"
#include "ecs_sdcard.h"
-#include "debug_ch.h"
-
#if defined(CONFIG_LIBAV)
#include "ecs_tuner.h"
#endif
-
-
+#include "debug_ch.h"
MULTI_DEBUG_CHANNEL(qemu, ecs);
static void msgproc_device_ans(ECS_Client *ccli, const char *category, bool succeed, const char *data)
#define MSG_NET_ACTION 123
-static int net_slirp_redir(const char *redir_str)
-{
- //TODO call slirp_hostfwd(QTAILQ_FIRST(&slirp_stacks), redir_str, 1); instead
- return 0;
-}
-
-
static void msgproc_device_req_network(ECS_Client *ccli, ECS__DeviceReq *msg, char *cmd)
{
char *data = NULL;
}
if (data != NULL) {
- LOG_TRACE(">>> Network msg: '%s'\n", data);
- if (net_slirp_redir(data) < 0) {
+ MonitorQMP* mon = ccli->cs->mon;
+ LOG_INFO(">>> Network msg: '%s' monitor present: %d\n", data, mon? 1: 0);
+ if (mon == NULL) {
+ LOG_SEVERE("Network redirection failed, monitor is null.\n");
+ goto END;
+ }
+ if (maru_hostfwd_add(&mon->common, data) < 0) {
LOG_SEVERE("redirect [%s] fail\n", data);
make_send_device_ntf(cmd, MSG_NET_GROUP, MSG_NET_ACTION, ret);
} else {
- LOG_TRACE("redirect [%s] success\n", data);
+ LOG_INFO("redirect [%s] success\n", data);
}
} else {
LOG_SEVERE("Network redirection data is null.\n");
+ return;
}
-
+END:
g_free(data);
}