$ pnxmit -a 0x10 -s 0x6c # send from host 0x10 to device 0x6c
$ pnxmit -a 0x6c -r # on the device, receive

Signed-off-by: Andrzej Pietrasiewicz <andrze...@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.p...@samsung.com>
---
/*
 * Test program for phonet
 *
 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
 *              http://www.samsung.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

/*
 * TODO:
 *
 * Many values (e.g. object IDs) are hardcoded. Convert them into
 * proper commandline parameters.
 *
 */

#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <getopt.h>
#include <limits.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/phonet.h>
#include <linux/if_ether.h>


#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

#define exit_error(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)
#define do_exit(...)    do { fprintf(stderr, __VA_ARGS__); } while (0)

/*
struct sockaddr_pn {
        sa_family_t     spn_family;    // AF_PHONET
        uint8_t         spn_obj;       // Object ID
        uint8_t         spn_dev;       // Device ID
        uint8_t         spn_resource;  // Resource or function
        uint8_t         spn_zero[...]; // Padding
};

struct phonethdr {
        uint8_t         pn_media;  // Media type (link-layer identifier)
        uint8_t         pn_rdev;   // Receiver device ID
        uint8_t         pn_sdev;   // Sender device ID
        uint8_t         pn_res;    // Resource ID or function
        uint16_t        pn_length; // Big-endian message byte length (minus 6)
        uint8_t         pn_robj;   // Receiver object ID
        uint8_t         pn_sobj;   // Sender object ID
};
*/

static void usage(char *prog)
{
        fprintf(stderr, "Usage: %s\n"
                "       --address=<n>, -a <n>   use this local address\n"
                "       --send=<n>, -s <n>      send data to <n>\n"
                "       --receive, -r           receive data\n"
                "       --help, -h              this help\n", prog);
}

static struct option pnxmit_opts[] = {
        {
                .name           = "address",
                .has_arg        = 1,
                .val            = 'a',
        },
        {
                .name           = "send",
                .has_arg        = 1,
                .val            = 's',
        },
        {
                .name           = "receive",
                .val            = 'r',
        },
        {
                .name           = "help",
                .val            = 'h',
        },
        {
                .name           = '\0',
        },
};

int get_addr(const char *optarg)
{
        long int val;

        val = strtol(optarg, NULL, 0);
        if (val == LONG_MIN || val == LONG_MAX || val < 0 || val > INT_MAX)
                do_exit("value %ld out of range", val);
        

        return (uint8_t)val;
}

int main(int argc, char *argv[])
{
        static struct sockaddr_pn local_addr = {
                .spn_family     = AF_PHONET,
                .spn_obj        = 0xab,
                .spn_resource   = 0xee,
        };
        static struct sockaddr_pn remote_addr = {
                .spn_family     = AF_PHONET,
                .spn_obj        = 0xab,
                .spn_resource   = 0xee,
        };
        static struct my_msg {
                struct phonethdr phonet_msg;
                char data[256];
        } phonet_msg;
        ssize_t len;
        socklen_t addrlen = sizeof(remote_addr);
        bool receive = false;
        int res = 1;
        int fd;

        while (ARRAY_SIZE(pnxmit_opts)) {
                int optidx = 0;
                int opt;

                opt = getopt_long(argc, argv, "a:s:rh", pnxmit_opts, &optidx);
                if (opt < 0)
                        break;

                switch (opt) {
                case 'a':
                        local_addr.spn_dev = get_addr(optarg);
                        phonet_msg.phonet_msg.pn_sdev = local_addr.spn_dev;
                        break;
                case 's':
                        remote_addr.spn_dev = get_addr(optarg);
                        phonet_msg.phonet_msg.pn_rdev = remote_addr.spn_dev;
                        break;
                case 'r':
                        receive = true;
                        break;
                case 'h': /* intentional */
                default:
                        usage(argv[0]);
                        return 1;
                }
        }

        fd = socket(PF_PHONET, SOCK_DGRAM, 0);
        if (fd == -1)
                exit_error("socket");
        if (bind(fd, (struct sockaddr*)&local_addr, sizeof(local_addr)))
                exit_error("bind");
        
        /*if (ioctl(fd, SIOCPNADDRESOURCE, &res) < 0)
                exit_error("ioctl");*/

        phonet_msg.phonet_msg.pn_res = 0xee;
        phonet_msg.phonet_msg.pn_robj = 0xab;
        phonet_msg.phonet_msg.pn_sobj = 0xab;
        if (receive) {
                len = recvfrom(fd, (char*)&phonet_msg, sizeof(phonet_msg), 0,
                        (struct sockaddr *)&remote_addr, &addrlen);
                if (len < 0)
                        exit_error("recvfrom");
                printf("Received %d bytes from %02x%02x\n", len,
                        remote_addr.spn_dev, remote_addr.spn_obj);
        } else {
                len = sendto(fd, (char*)&phonet_msg, sizeof(phonet_msg), 0,
                        (struct sockaddr *)&remote_addr, sizeof(remote_addr));
                if (len < 0)
                        exit_error("sendto");
                printf("Sent %d bytes to %02x%02x\n", len,
                        remote_addr.spn_dev, remote_addr.spn_obj);
        }

        return 0;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to