Esempio n. 1
0
void ethos_send_frame(ethos_t *dev, const uint8_t *data, size_t len, unsigned frame_type)
{
    uint8_t frame_delim = ETHOS_FRAME_DELIMITER;

    if (!irq_is_in()) {
        mutex_lock(&dev->out_mutex);
    }
    else {
        /* Send frame delimiter. This cancels the current frame,
         * but enables in-ISR writes.  */
        uart_write(dev->uart, &frame_delim, 1);
    }

    /* send frame delimiter */
    uart_write(dev->uart, &frame_delim, 1);

    /* set frame type */
    if (frame_type) {
        uint8_t out[2] = { ETHOS_ESC_CHAR, (frame_type ^ 0x20) };
        uart_write(dev->uart, out, 2);
    }

    /* send frame content */
    while(len--) {
        _write_escaped(dev->uart, *(uint8_t*)data++);
    }

    /* end of frame */
    uart_write(dev->uart, &frame_delim, 1);

    if (!irq_is_in()) {
        mutex_unlock(&dev->out_mutex);
    }
}
Esempio n. 2
0
static int _send(netdev_t *netdev, const iolist_t *iolist)
{
    ethos_t * dev = (ethos_t *) netdev;
    (void)dev;

    /* count total packet length */
    size_t pktlen = iolist_count_total(iolist);

    /* lock line in order to prevent multiple writes */
    mutex_lock(&dev->out_mutex);

    /* send start-frame-delimiter */
    uint8_t frame_delim = ETHOS_FRAME_DELIMITER;
    uart_write(dev->uart, &frame_delim, 1);

    /* send iolist */
    for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
        size_t n = iol->iol_len;
        uint8_t *ptr = iol->iol_base;
        while(n--) {
            _write_escaped(dev->uart, *ptr++);
        }
    }

    uart_write(dev->uart, &frame_delim, 1);

    mutex_unlock(&dev->out_mutex);

    return pktlen;
}
Esempio n. 3
0
static int _send(netdev2_t *netdev, const struct iovec *vector, int count)
{
    ethos_t * dev = (ethos_t *) netdev;
    (void)dev;

    /* count total packet length */
    size_t pktlen = iovec_count_total(vector, count);

    /* lock line in order to prevent multiple writes */
    mutex_lock(&dev->out_mutex);

    /* send start-frame-delimiter */
    uint8_t frame_delim = ETHOS_FRAME_DELIMITER;
    uart_write(dev->uart, &frame_delim, 1);

    /* send iovec */
    while(count--) {
        size_t n = vector->iov_len;
        uint8_t *ptr = vector->iov_base;
        while(n--) {
            _write_escaped(dev->uart, *ptr++);
        }
        vector++;
    }

    uart_write(dev->uart, &frame_delim, 1);

    mutex_unlock(&dev->out_mutex);

    return pktlen;
}
Esempio n. 4
0
File: ethos.c Progetto: JMR-b/RIOT
int main(int argc, char *argv[])
{
    char inbuf[MTU];

    serial_t serial = {0};

    if (argc < 3) {
        usage();
        return 1;
    }

    char ifname[IFNAMSIZ];
    strncpy(ifname, argv[1], IFNAMSIZ);
    int tap_fd = tun_alloc(ifname, IFF_TAP | IFF_NO_PI);

    if (tap_fd < 0) {
        return 1;
    }

    int serial_fd = open(argv[2], O_RDWR | O_NOCTTY | O_SYNC);

    if (serial_fd < 0) {
        fprintf(stderr, "Error opening serial device %s\n", argv[2]);
        return 1;
    }

    set_serial_attribs(serial_fd, B115200, 0);
    set_blocking(serial_fd, 1);

    fd_set readfds;
    int max_fd = (serial_fd > tap_fd) ? serial_fd : tap_fd;

    fprintf(stderr, "----> ethos: sending hello.\n");
    _send_hello(serial_fd, &serial, LINE_FRAME_TYPE_HELLO);

    fprintf(stderr, "----> ethos: activating serial pass through.\n");
    _send_hello(serial_fd, &serial, LINE_FRAME_TYPE_HELLO);
    while(1) {
        int activity;
        FD_ZERO(&readfds);
        FD_SET(STDIN_FILENO, &readfds);
        FD_SET(tap_fd, &readfds);
        FD_SET(serial_fd, &readfds);
        activity = select( max_fd + 1 , &readfds , NULL , NULL , NULL);

        if ((activity < 0) && (errno != EINTR))
        {
            perror("select error");
        }

        if (FD_ISSET(serial_fd, &readfds)) {
            ssize_t n = read(serial_fd, inbuf, sizeof(inbuf));
            if (n > 0) {
                char *ptr = inbuf;
                while (n--) {
                    size_t res = _serial_handle_byte(&serial, *ptr++);
                    if (res) {
                        switch (serial.frametype) {
                            case LINE_FRAME_TYPE_DATA:
                                write(tap_fd, serial.frame, serial.framebytes);
                                break;
                            case LINE_FRAME_TYPE_TEXT:
                                write(STDOUT_FILENO, serial.frame, serial.framebytes);
                                break;
                            case LINE_FRAME_TYPE_HELLO:
                            case LINE_FRAME_TYPE_HELLO_REPLY:
                                if (serial.framebytes == 6) {
                                    memcpy(serial.remote_l2_addr, serial.frame, 6);
                                    if (serial.frametype == LINE_FRAME_TYPE_HELLO) {
                                        fprintf(stderr, "----> ethos: hello received\n");
                                        _send_hello(serial_fd, &serial, LINE_FRAME_TYPE_HELLO_REPLY);
                                    } else {
                                        fprintf(stderr, "----> ethos: hello reply received\n");
                                    }
                                    _clear_neighbor_cache(ifname);
                                }
                                break;
                        }
                        memset(&serial, '\0', sizeof(serial));
                    }
                }
            }
            else {
                fprintf(stderr, "lost serial connection.\n");
                exit(1);
            }
        }

        if (FD_ISSET(tap_fd, &readfds)) {
            ssize_t res = read(tap_fd, inbuf, sizeof(inbuf));
            if (res <= 0) {
                fprintf(stderr, "error reading from tap device. res=%zi\n", res);
                continue;
            }
            char delim = LINE_FRAME_DELIMITER;
            write(serial_fd, &delim, 1);
            _write_escaped(serial_fd, inbuf, res);
            write(serial_fd, &delim, 1);
        }

        if (FD_ISSET(STDIN_FILENO, &readfds)) {
            ssize_t res = read(STDIN_FILENO, inbuf, sizeof(inbuf));
            if (res <= 0) {
                fprintf(stderr, "error reading from stdio. res=%zi\n", res);
                continue;
            }

            if (res) {
                char delim = LINE_FRAME_DELIMITER;
                char head[] = { LINE_FRAME_DELIMITER, LINE_ESC_CHAR, (LINE_FRAME_TYPE_TEXT ^ 0x20) };
                write(serial_fd, head, sizeof(head));
                _write_escaped(serial_fd, inbuf, res);
                write(serial_fd, &delim, 1);
            }
        }
    }

    return 0;
}