diff options
-rw-r--r-- | serial/manager.c | 153 | ||||
-rw-r--r-- | serial/serial-api.txt | 11 |
2 files changed, 160 insertions, 4 deletions
diff --git a/serial/manager.c b/serial/manager.c index 9f3fe8d9..9043cc0c 100644 --- a/serial/manager.c +++ b/serial/manager.c @@ -1226,6 +1226,10 @@ static gboolean connect_event(GIOChannel *chan, return TRUE; } + if (tcsetattr(tty_sk, TCSANOW, &prx->proxy_ti) < 0) + error("Can't change serial settings: %s(%d)", + strerror(errno), errno); + node_io = g_io_channel_unix_new(nsk); g_io_channel_set_close_on_unref(node_io, TRUE); tty_io = g_io_channel_unix_new(tty_sk); @@ -1374,10 +1378,153 @@ static DBusHandlerResult proxy_get_info(DBusConnection *conn, return send_message_and_unref(conn, reply); } +static struct { + const char *str; + speed_t speed; +} supported_speed[] = { + {"50", B50 }, + {"300", B300 }, + {"600", B600 }, + {"1200", B1200 }, + {"1800", B1800 }, + {"2400", B2400 }, + {"4800", B4800 }, + {"9600", B9600 }, + {"19200", B19200 }, + {"38400", B38400 }, + {"57600", B57600 }, + {"115200", B115200 }, + { NULL, B0 } +}; + +static speed_t str2speed(const char *str, speed_t *speed) +{ + int i; + + for (i = 0; supported_speed[i].str; i++) { + if (strcmp(supported_speed[i].str, str) != 0) + continue; + + if (speed) + *speed = supported_speed[i].speed; + + return supported_speed[i].speed; + } + + return B0; +} + +static int set_parity(const char *str, tcflag_t *ctrl) +{ + if (strcasecmp("even", str) == 0) { + *ctrl |= PARENB; + *ctrl &= ~PARODD; + } else if (strcasecmp("odd", str) == 0) { + *ctrl |= PARENB; + *ctrl |= PARODD; + } else if (strcasecmp("mark", str) == 0) + *ctrl |= PARENB; + else if ((strcasecmp("none", str) == 0) || + (strcasecmp("space", str) == 0)) + *ctrl &= ~PARENB; + else + return -1; + + return 0; +} + +static int set_databits(uint8_t databits, tcflag_t *ctrl) +{ + if (databits < 5 || databits > 8) + return -EINVAL; + + *ctrl &= ~CSIZE; + switch (databits) { + case 5: + *ctrl |= CS5; + break; + case 6: + *ctrl |= CS6; + break; + case 7: + *ctrl |= CS7; + break; + case 8: + *ctrl |= CS8; + break; + } + + return 0; +} + +static int set_stopbits(uint8_t stopbits, tcflag_t *ctrl) +{ + /* 1.5 will not be allowed */ + switch (stopbits) { + case 1: + *ctrl &= ~CSTOPB; + return 0; + case 2: + *ctrl |= CSTOPB; + return 0; + } + + return -EINVAL; +} + +static DBusHandlerResult proxy_set_serial_params(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + DBusError derr; + struct proxy *prx = data; + const char *ratestr, *paritystr; + uint8_t databits, stopbits; + tcflag_t ctrl; /* Control mode flags */ + speed_t speed = B0; /* In/Out speed */ + + /* Don't allow change TTY settings if it is open */ + if (prx->tty_watch) + return err_failed(conn, msg, "Not allowed"); + + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, + DBUS_TYPE_STRING, &ratestr, + DBUS_TYPE_BYTE, &databits, + DBUS_TYPE_BYTE, &stopbits, + DBUS_TYPE_STRING, &paritystr, + DBUS_TYPE_INVALID)) { + err_invalid_args(conn, msg, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } + + if (str2speed(ratestr, &speed) == B0) + return err_invalid_args(conn, msg, "Invalid baud rate"); + + ctrl = prx->proxy_ti.c_cflag; + if (set_databits(databits, &ctrl) < 0) + return err_invalid_args(conn, msg, "Invalid data bits"); + + if (set_stopbits(stopbits, &ctrl) < 0) + return err_invalid_args(conn, msg, "Invalid stop bits"); + + if (set_parity(paritystr, &ctrl) < 0) + return err_invalid_args(conn, msg, "Invalid parity"); + + prx->proxy_ti.c_cflag = ctrl; + prx->proxy_ti.c_cflag |= (CLOCAL | CREAD); + cfsetispeed(&prx->proxy_ti, speed); + cfsetospeed(&prx->proxy_ti, speed); + + return send_message_and_unref(conn, + dbus_message_new_method_return(msg)); +} + static DBusMethodVTable proxy_methods[] = { - { "Enable", proxy_enable, "", "" }, - { "Disable", proxy_disable, "", "" }, - { "GetInfo", proxy_get_info, "", "{sv}" }, + { "Enable", proxy_enable, "", "" }, + { "Disable", proxy_disable, "", "" }, + { "GetInfo", proxy_get_info, "", "{sv}" }, + { "SetSerialParams", proxy_set_serial_params, "syys", "" }, { NULL, NULL, NULL, NULL }, }; diff --git a/serial/serial-api.txt b/serial/serial-api.txt index b02786e7..70e8983f 100644 --- a/serial/serial-api.txt +++ b/serial/serial-api.txt @@ -118,5 +118,14 @@ Methods: string Enable() [experimental] Unregister the service record and stop listenning. - String GetInfo() [experimental] + string GetInfo() [experimental] Returns the proxy properties + + void SetSerialParams(string rate, byte databits, + byte stopbits, string parity) [experimental] + + Change the TTY settings. Available rates: "50", "300", + "600", "1200", "1800", "2400", "4800", "9600", "19200", + "38400", "57600" and "115200". Available data bits: 5, + 6, 7 and 8. Available stop bits: 1 and 2. Available + parity: "even", "odd", "mark", "space" and "none". |