Changeset 3b3c689 in mainline


Ignore:
Timestamp:
2012-03-12T23:17:57Z (12 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8bf672d
Parents:
6428115
Message:

Repeated ping mode.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/ping/ping.c

    r6428115 r3b3c689  
    3333 */
    3434
     35#include <async.h>
     36#include <bool.h>
    3537#include <errno.h>
    3638#include <fibril_synch.h>
    3739#include <inet/inetping.h>
     40#include <io/console.h>
    3841#include <stdio.h>
    3942#include <stdlib.h>
     
    4245#define NAME "ping"
    4346
     47/** Delay between subsequent ping requests in microseconds */
     48#define PING_DELAY (1000 * 1000)
     49
    4450/** Ping request timeout in microseconds */
    4551#define PING_TIMEOUT (1000 * 1000)
    4652
    4753static int ping_ev_recv(inetping_sdu_t *);
     54
     55static bool done = false;
    4856static FIBRIL_CONDVAR_INITIALIZE(done_cv);
    4957static FIBRIL_MUTEX_INITIALIZE(done_lock);
     
    5361};
    5462
     63static inet_addr_t src_addr;
     64static inet_addr_t dest_addr;
     65
     66static bool ping_repeat = false;
     67
    5568static void print_syntax(void)
    5669{
    57         printf("syntax: " NAME " <addr>\n");
     70        printf("syntax: " NAME " [-r] <addr>\n");
    5871}
    5972
     
    99112}
    100113
     114static void ping_signal_done(void)
     115{
     116        fibril_mutex_lock(&done_lock);
     117        done = true;
     118        fibril_mutex_unlock(&done_lock);
     119        fibril_condvar_broadcast(&done_cv);
     120}
     121
    101122static int ping_ev_recv(inetping_sdu_t *sdu)
    102123{
     
    116137            "payload size %zu\n", asrc, adest, sdu->seq_no, sdu->size);
    117138
    118         fibril_condvar_broadcast(&done_cv);
     139        if (!ping_repeat) {
     140                ping_signal_done();
     141        }
    119142
    120143        free(asrc);
     
    123146}
    124147
     148static int ping_send(uint16_t seq_no)
     149{
     150        inetping_sdu_t sdu;
     151        int rc;
     152
     153        sdu.src = src_addr;
     154        sdu.dest = dest_addr;
     155        sdu.seq_no = seq_no;
     156        sdu.data = (void *) "foo";
     157        sdu.size = 3;
     158
     159        rc = inetping_send(&sdu);
     160        if (rc != EOK) {
     161                printf(NAME ": Failed sending echo request (%d).\n", rc);
     162                return rc;
     163        }
     164
     165        return EOK;
     166}
     167
     168static int transmit_fibril(void *arg)
     169{
     170        uint16_t seq_no = 0;
     171
     172        while (true) {
     173                fibril_mutex_lock(&done_lock);
     174                if (done) {
     175                        fibril_mutex_unlock(&done_lock);
     176                        return 0;
     177                }
     178                fibril_mutex_unlock(&done_lock);
     179
     180                (void) ping_send(++seq_no);
     181                async_usleep(PING_DELAY);
     182        }
     183
     184        return 0;
     185}
     186
     187static int input_fibril(void *arg)
     188{
     189        console_ctrl_t *con;
     190        kbd_event_t ev;
     191
     192        con = console_init(stdin, stdout);
     193        printf("[Press Ctrl-Q to quit]\n");
     194
     195        while (true) {
     196                if (!console_get_kbd_event(con, &ev))
     197                        break;
     198
     199                if (ev.type == KEY_PRESS && (ev.mods & (KM_ALT | KM_SHIFT)) ==
     200                    0 && (ev.mods & KM_CTRL) != 0) {
     201                        /* Ctrl+key */
     202                        if (ev.key == KC_Q) {
     203                                ping_signal_done();
     204                                return 0;
     205                        }
     206                }
     207        }
     208
     209        return 0;
     210}
     211
    125212int main(int argc, char *argv[])
    126213{
    127214        int rc;
    128         inetping_sdu_t sdu;
     215        int argi;
    129216
    130217        rc = inetping_init(&ev_ops);
     
    135222        }
    136223
    137         if (argc != 2) {
     224        argi = 1;
     225        if (argi < argc && str_cmp(argv[argi], "-r") == 0) {
     226                ping_repeat = true;
     227                ++argi;
     228        } else {
     229                ping_repeat = false;
     230        }
     231
     232        if (argc - argi != 1) {
    138233                print_syntax();
    139234                return 1;
     
    141236
    142237        /* Parse destination address */
    143         rc = addr_parse(argv[1], &sdu.dest);
     238        rc = addr_parse(argv[argi], &dest_addr);
    144239        if (rc != EOK) {
    145240                printf(NAME ": Invalid address format.\n");
     
    148243        }
    149244
    150         sdu.seq_no = 1;
    151         sdu.data = (void *) "foo";
    152         sdu.size = 3;
    153 
    154245        /* Determine source address */
    155         rc = inetping_get_srcaddr(&sdu.dest, &sdu.src);
     246        rc = inetping_get_srcaddr(&dest_addr, &src_addr);
    156247        if (rc != EOK) {
    157248                printf(NAME ": Failed determining source address.\n");
     
    159250        }
    160251
    161         rc = inetping_send(&sdu);
    162         if (rc != EOK) {
    163                 printf(NAME ": Failed sending echo request (%d).\n", rc);
    164                 return 1;
     252        fid_t fid;
     253
     254        if (ping_repeat) {
     255                fid = fibril_create(transmit_fibril, NULL);
     256                if (fid == 0) {
     257                        printf(NAME ": Failed creating transmit fibril.\n");
     258                        return 1;
     259                }
     260
     261                fibril_add_ready(fid);
     262
     263                fid = fibril_create(input_fibril, NULL);
     264                if (fid == 0) {
     265                        printf(NAME ": Failed creating input fibril.\n");
     266                        return 1;
     267                }
     268
     269                fibril_add_ready(fid);
     270        } else {
     271                ping_send(1);
    165272        }
    166273
    167274        fibril_mutex_lock(&done_lock);
    168         rc = fibril_condvar_wait_timeout(&done_cv, &done_lock, PING_TIMEOUT);
     275        rc = EOK;
     276        while (!done && rc != ETIMEOUT) {
     277                rc = fibril_condvar_wait_timeout(&done_cv, &done_lock,
     278                        ping_repeat ? 0 : PING_TIMEOUT);
     279        }
    169280        fibril_mutex_unlock(&done_lock);
    170281
Note: See TracChangeset for help on using the changeset viewer.