removed unneeded code

This commit is contained in:
hyung-hwan 2016-04-02 15:25:35 +00:00
parent 116b90fb74
commit e122618f71
15 changed files with 205 additions and 1205 deletions

View File

@ -24,9 +24,6 @@ pkginclude_HEADERS = \
stio-cmn.h \
stio-pro.h \
stio-sck.h \
stio-tcp.h \
stio-udp.h \
stio-arp.h \
stio.h
pkglib_LTLIBRARIES = libstio.la
@ -35,11 +32,8 @@ libstio_la_SOURCES = \
stio.c \
stio-pro.c \
stio-sck.c \
stio-tcp.c \
stio-tim.c \
stio-tmr.c \
stio-udp.c \
stio-arp.c
stio-tmr.c
libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
libstio_la_LIBADD = $(LIBADD_LIB_COMMON)

View File

@ -132,7 +132,7 @@ libstio_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_libstio_la_OBJECTS = libstio_la-stio.lo libstio_la-stio-pro.lo \
libstio_la-stio-sck.lo libstio_la-stio-tcp.lo \
libstio_la-stio-tim.lo libstio_la-stio-tmr.lo \
libstio_la-stio-udp.lo libstio_la-stio-arp.lo
libstio_la-stio-udp.lo
libstio_la_OBJECTS = $(am_libstio_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@ -384,7 +384,6 @@ pkginclude_HEADERS = \
stio-sck.h \
stio-tcp.h \
stio-udp.h \
stio-arp.h \
stio.h
pkglib_LTLIBRARIES = libstio.la
@ -396,8 +395,7 @@ libstio_la_SOURCES = \
stio-tcp.c \
stio-tim.c \
stio-tmr.c \
stio-udp.c \
stio-arp.c
stio-udp.c
libstio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
libstio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
@ -554,7 +552,6 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-arp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-pro.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-sck.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstio_la-stio-tcp.Plo@am__quote@
@ -634,13 +631,6 @@ libstio_la-stio-udp.lo: stio-udp.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libstio_la-stio-udp.lo `test -f 'stio-udp.c' || echo '$(srcdir)/'`stio-udp.c
libstio_la-stio-arp.lo: stio-arp.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libstio_la-stio-arp.lo -MD -MP -MF $(DEPDIR)/libstio_la-stio-arp.Tpo -c -o libstio_la-stio-arp.lo `test -f 'stio-arp.c' || echo '$(srcdir)/'`stio-arp.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstio_la-stio-arp.Tpo $(DEPDIR)/libstio_la-stio-arp.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stio-arp.c' object='libstio_la-stio-arp.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libstio_la-stio-arp.lo `test -f 'stio-arp.c' || echo '$(srcdir)/'`stio-arp.c
stio-main.o: main.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stio-main.o -MD -MP -MF $(DEPDIR)/stio-main.Tpo -c -o stio-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stio-main.Tpo $(DEPDIR)/stio-main.Po

View File

@ -26,9 +26,8 @@
#include <stio.h>
#include <stio-sck.h>
#include <stio-tcp.h>
#include <stio-udp.h>
#include <stio-arp.h>
#include <stdlib.h>
#include <string.h>
@ -93,7 +92,7 @@ struct tcp_server_t
};
typedef struct tcp_server_t tcp_server_t;
static void tcp_on_disconnect (stio_dev_sck_t* tcp)
static void tcp_sck_on_disconnect (stio_dev_sck_t* tcp)
{
if (tcp->state & STIO_DEV_TCP_CONNECTING)
{
@ -116,7 +115,7 @@ static void tcp_on_disconnect (stio_dev_sck_t* tcp)
printf ("TCP DISCONNECTED - THIS MUST NOT HAPPEN (%d - %x)\n", (int)tcp->sck, (unsigned int)tcp->state);
}
}
static int tcp_on_connect (stio_dev_sck_t* tcp)
static int tcp_sck_on_connect (stio_dev_sck_t* tcp)
{
if (tcp->state & STIO_DEV_TCP_CONNECTED)
@ -131,7 +130,7 @@ printf ("device accepted client device... .asdfjkasdfkljasdlfkjasdj...\n");
return stio_dev_sck_write (tcp, "hello", 5, STIO_NULL, STIO_NULL);
}
static int tcp_on_write (stio_dev_sck_t* tcp, stio_len_t wrlen, void* wrctx, const stio_sckadr_t* dstadr)
static int tcp_sck_on_write (stio_dev_sck_t* tcp, stio_iolen_t wrlen, void* wrctx, const stio_sckadr_t* dstadr)
{
tcp_server_t* ts;
@ -154,7 +153,7 @@ printf ("ENABLING READING..............................\n");
return 0;
}
static int tcp_on_read (stio_dev_sck_t* tcp, const void* buf, stio_len_t len, const stio_sckadr_t* srcadr)
static int tcp_sck_on_read (stio_dev_sck_t* tcp, const void* buf, stio_iolen_t len, const stio_sckadr_t* srcadr)
{
if (len <= 0)
{
@ -191,7 +190,7 @@ printf ("DISABLING READING..............................\n");
/* ========================================================================= */
static int arp_sck_on_read (stio_dev_sck_t* dev, const void* data, stio_len_t dlen, const stio_sckadr_t* srcadr)
static int arp_sck_on_read (stio_dev_sck_t* dev, const void* data, stio_iolen_t dlen, const stio_sckadr_t* srcadr)
{
stio_etharp_pkt_t* eap;
struct sockaddr_ll* sll = (struct sockaddr_ll*)srcadr;
@ -208,7 +207,7 @@ static int arp_sck_on_read (stio_dev_sck_t* dev, const void* data, stio_len_t dl
return 0;
}
static int arp_sck_on_write (stio_dev_sck_t* dev, stio_len_t wrlen, void* wrctx)
static int arp_sck_on_write (stio_dev_sck_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_sckadr_t* dstadr)
{
return 0;
}
@ -229,7 +228,7 @@ int main ()
stio_t* stio;
stio_dev_sck_t* sck;
stio_dev_sck_t* tcp[2];
struct sockaddr_in sin;
struct sigaction sigact;
stio_dev_sck_connect_t tcp_conn;
stio_dev_sck_listen_t tcp_lstn;
@ -271,8 +270,8 @@ int main ()
memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make));
tcp_make.type = STIO_DEV_SCK_TCP4;
tcp_make.on_write = tcp_on_write;
tcp_make.on_read = tcp_on_read;
tcp_make.on_write = tcp_sck_on_write;
tcp_make.on_read = tcp_sck_on_read;
tcp[0] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
if (!tcp[0])
{
@ -283,17 +282,15 @@ int main ()
ts = (tcp_server_t*)(tcp[0] + 1);
ts->tally = 0;
memset (&sin, 0, STIO_SIZEOF(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(9999);
inet_pton (sin.sin_family, "192.168.1.119", &sin.sin_addr);
//inet_pton (sin.sin_family, "127.0.0.1", &sin.sin_addr);
memset (&tcp_conn, 0, STIO_SIZEOF(tcp_conn));
memcpy (&tcp_conn.addr, &sin, STIO_SIZEOF(sin));
{
in_addr_t ia = inet_addr("192.168.1.119");
stio_sckadr_initforip4 (&tcp_conn.addr, 9999, (stio_ip4adr_t*)&ia);
}
tcp_conn.tmout.sec = 5;
tcp_conn.on_connect = tcp_on_connect;
tcp_conn.on_disconnect = tcp_on_disconnect;
tcp_conn.on_connect = tcp_sck_on_connect;
tcp_conn.on_disconnect = tcp_sck_on_disconnect;
if (stio_dev_sck_connect (tcp[0], &tcp_conn) <= -1)
{
printf ("stio_dev_sck_connect() failed....\n");
@ -301,8 +298,8 @@ int main ()
}
memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make));
tcp_make.on_write = tcp_on_write;
tcp_make.on_read = tcp_on_read;
tcp_make.on_write = tcp_sck_on_write;
tcp_make.on_read = tcp_sck_on_read;
tcp[1] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
if (!tcp[1])
@ -314,9 +311,7 @@ int main ()
ts->tally = 0;
memset (&tcp_bind, 0, STIO_SIZEOF(tcp_bind));
//memcpy (&tcp_bind.addr, &sin, STIO_SIZEOF(sin));
((struct sockaddr_in*)&tcp_bind.addr)->sin_family = AF_INET;
((struct sockaddr_in*)&tcp_bind.addr)->sin_port = htons(1234);
stio_sckadr_initforip4 (&tcp_bind.addr, 1234, STIO_NULL);
if (stio_dev_sck_bind (tcp[1],&tcp_bind) <= -1)
{
@ -324,9 +319,10 @@ int main ()
goto oops;
}
tcp_lstn.backlogs = 100;
tcp_lstn.on_connect = tcp_on_connect;
tcp_lstn.on_disconnect = tcp_on_disconnect;
tcp_lstn.on_connect = tcp_sck_on_connect;
tcp_lstn.on_disconnect = tcp_sck_on_disconnect;
if (stio_dev_sck_listen (tcp[1], &tcp_lstn) <= -1)
{
printf ("stio_dev_sck_listen() failed....\n");
@ -334,6 +330,12 @@ int main ()
}
#if 1
{
stio_sckadr_t ethdst;
stio_etharp_pkt_t etharp;
memset (&sck_make, 0, STIO_SIZEOF(sck_make));
sck_make.type = STIO_DEV_SCK_ARP;
//sck_make.type = STIO_DEV_SCK_ARP_DGRAM;
@ -346,26 +348,14 @@ int main ()
goto oops;
}
#if 1
{
stio_etharp_pkt_t etharp;
struct sockaddr_ll sll;
//stio_sckadr_initforeth (&ethdst, if_nametoindex("enp0s25.3"), (stio_ethadr_t*)"\xFF\xFF\xFF\xFF\xFF\xFF");
stio_sckadr_initforeth (&ethdst, if_nametoindex("enp0s25.3"), (stio_ethadr_t*)"\xAA\xBB\xFF\xCC\xDD\xFF");
memset (&sll, 0, sizeof(sll));
sll.sll_family = AF_PACKET;
// sll.sll_protocol = STIO_CONST_HTON16(STIO_ETHHDR_PROTO_ARP);
// sll.sll_hatype = STIO_CONST_HTON16(STIO_ARPHDR_HTYPE_ETH);
sll.sll_halen = STIO_ETHADR_LEN;
memcpy (sll.sll_addr, "\xFF\xFF\xFF\xFF\xFF\xFF", sll.sll_halen);
sll.sll_ifindex = if_nametoindex ("enp0s25.3");
/* if unicast ... */
//sll.sll_pkttype = PACKET_OTHERHOST;
// sll.sll_pkttype = PACKET_BROADCAST;
memset (&etharp, 0, sizeof(etharp));
memcpy (etharp.ethhdr.source, "\xB8\x6B\x23\x9C\x10\x76", STIO_ETHADR_LEN);
memcpy (etharp.ethhdr.dest, "\xFF\xFF\xFF\xFF\xFF\xFF", STIO_ETHADR_LEN);
//memcpy (etharp.ethhdr.dest, "\xFF\xFF\xFF\xFF\xFF\xFF", STIO_ETHADR_LEN);
memcpy (etharp.ethhdr.dest, "\xAA\xBB\xFF\xCC\xDD\xFF", STIO_ETHADR_LEN);
etharp.ethhdr.proto = STIO_CONST_HTON16(STIO_ETHHDR_PROTO_ARP);
etharp.arphdr.htype = STIO_CONST_HTON16(STIO_ARPHDR_HTYPE_ETH);
@ -376,8 +366,8 @@ int main ()
memcpy (etharp.arppld.sha, "\xB8\x6B\x23\x9C\x10\x76", STIO_ETHADR_LEN);
if (stio_dev_sck_write (sck, &etharp, sizeof(etharp), NULL, &sll) <= -1)
//if (stio_dev_sck_write (sck, &etharp.arphdr, sizeof(etharp) - sizeof(etharp.ethhdr), NULL, &adr) <= -1)
if (stio_dev_sck_write (sck, &etharp, sizeof(etharp), NULL, &ethdst) <= -1)
//if (stio_dev_sck_write (sck, &etharp.arphdr, sizeof(etharp) - sizeof(etharp.ethhdr), NULL, &ethadr) <= -1)
{
printf ("CANNOT WRITE ARP...\n");
}

View File

@ -74,7 +74,7 @@ static stio_syshnd_t arp_getsyshnd (stio_dev_t* dev)
return (stio_syshnd_t)arp->sck;
}
static int arp_read (stio_dev_t* dev, void* buf, stio_len_t* len)
static int arp_read (stio_dev_t* dev, void* buf, stio_iolen_t* len)
{
stio_dev_arp_t* arp = (stio_dev_arp_t*)dev;
stio_scklen_t addrlen;
@ -98,7 +98,7 @@ printf ("ARP RECVFROM...\n");
return 1;
}
static int arp_write (stio_dev_t* dev, const void* data, stio_len_t* len)
static int arp_write (stio_dev_t* dev, const void* data, stio_iolen_t* len)
{
stio_dev_arp_t* arp = (stio_dev_arp_t*)arp;
ssize_t x;
@ -154,13 +154,13 @@ static int arp_ready (stio_dev_t* dev, int events)
return 0;
}
static int arp_on_read (stio_dev_t* dev, const void* data, stio_len_t len)
static int arp_on_read (stio_dev_t* dev, const void* data, stio_iolen_t len)
{
printf ("dATA received %d bytes\n", (int)len);
return 0;
}
static int arp_on_write (stio_dev_t* dev, stio_len_t wrlen, void* wrctx)
static int arp_on_write (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx)
{
return 0;

View File

@ -30,82 +30,9 @@
#include <stio.h>
#include <stio-sck.h>
#define STIO_ETHHDR_PROTO_IP4 0x0800
#define STIO_ETHHDR_PROTO_ARP 0x0806
#define STIO_ARPHDR_OPCODE_REQUEST 1
#define STIO_ARPHDR_OPCODE_REPLY 2
#define STIO_ARPHDR_HTYPE_ETH 0x0001
#define STIO_ARPHDR_PTYPE_IP4 0x0800
#define STIO_ETHADR_LEN 6
#define STIO_IP4ADR_LEN 4
#define STIO_IP6ADR_LEN 16
#pragma pack(push)
#pragma pack(1)
struct stio_ethadr_t
{
stio_uint8_t v[STIO_ETHADR_LEN];
};
typedef struct stio_ethadr_t stio_ethadr_t;
struct stio_ip4adr_t
{
stio_uint8_t v[STIO_IP4ADR_LEN];
};
typedef struct stio_ip4adr_t stio_ip4adr_t;
struct stio_ip6adr_t
{
stio_uint8_t v[STIO_IP6ADR_LEN];
};
typedef struct stio_ip6adr_t stio_ip6adr_t;
struct stio_ethhdr_t
{
stio_uint8_t dest[STIO_ETHADR_LEN];
stio_uint8_t source[STIO_ETHADR_LEN];
stio_uint16_t proto;
};
typedef struct stio_ethhdr_t stio_ethhdr_t;
struct stio_arphdr_t
{
stio_uint16_t htype; /* hardware type (ethernet: 0x0001) */
stio_uint16_t ptype; /* protocol type (ipv4: 0x0800) */
stio_uint8_t hlen; /* hardware address length (ethernet: 6) */
stio_uint8_t plen; /* protocol address length (ipv4 :4) */
stio_uint16_t opcode; /* operation code */
};
typedef struct stio_arphdr_t stio_arphdr_t;
/* arp payload for ipv4 over ethernet */
struct stio_etharp_t
{
stio_uint8_t sha[STIO_ETHADR_LEN]; /* source hardware address */
stio_uint8_t spa[STIO_IP4ADR_LEN]; /* source protocol address */
stio_uint8_t tha[STIO_ETHADR_LEN]; /* target hardware address */
stio_uint8_t tpa[STIO_IP4ADR_LEN]; /* target protocol address */
};
typedef struct stio_etharp_t stio_etharp_t;
struct stio_etharp_pkt_t
{
stio_ethhdr_t ethhdr;
stio_arphdr_t arphdr;
stio_etharp_t arppld;
};
typedef struct stio_etharp_pkt_t stio_etharp_pkt_t;
#pragma pack(pop)
#if 0
typedef int (*stio_dev_arp_on_read_t) (stio_dev_arp_t* dev, stio_pkt_arp_t* pkt, stio_len_t len);
typedef int (*stio_dev_arp_on_read_t) (stio_dev_arp_t* dev, stio_pkt_arp_t* pkt, stio_iolen_t len);
typedef int (*stio_dev_arp_on_write_t) (stio_dev_arp_t* dev, void* wrctx);
typedef struct stio_dev_arp_make_t stio_dev_arp_make_t;

View File

@ -134,7 +134,7 @@ static void pro_kill (stio_dev_t* dev)
{
}
static int pro_read (stio_dev_t* dev, void* buf, stio_len_t* len)
static int pro_read (stio_dev_t* dev, void* buf, stio_iolen_t* len)
{
stio_dev_pro_t* pro = (stio_dev_pro_t*)dev;
ssize_t x;
@ -152,7 +152,7 @@ static int pro_read (stio_dev_t* dev, void* buf, stio_len_t* len)
return 1;
}
static int pro_write (stio_dev_t* dev, const void* data, stio_len_t* len)
static int pro_write (stio_dev_t* dev, const void* data, stio_iolen_t* len)
{
return -1;
}
@ -205,7 +205,7 @@ printf ("PRO READY...%p\n", dev);
return 1; /* the device is ok. carry on reading or writing */
}
static int pro_on_read (stio_dev_t* dev, const void* data, stio_len_t len, const stio_devadr_t* srcadr)
static int pro_on_read (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_devadr_t* srcadr)
{
stio_dev_pro_t* pro = (stio_dev_pro_t*)dev;
return pro->on_read (pro, data, len);
@ -235,7 +235,7 @@ void stio_dev_pro_kill (stio_dev_pro_t* pro)
}
#if 0
int stio_dev_pro_write (stio_dev_pro_t* pro, const void* data, stio_len_t len, void* wrctx)
int stio_dev_pro_write (stio_dev_pro_t* pro, const void* data, stio_iolen_t len, void* wrctx)
{
return stio_dev_write ((stio_dev_t*)pro, data, len, wrctx);
}

View File

@ -40,7 +40,7 @@ typedef enum stio_dev_pro_type_t stio_dev_pro_type_t;
typedef struct stio_dev_pro_t stio_dev_pro_t;
typedef int (*stio_dev_pro_on_read_t) (stio_dev_pro_t* dev, const void* data, stio_len_t len);
typedef int (*stio_dev_pro_on_read_t) (stio_dev_pro_t* dev, const void* data, stio_iolen_t len);
typedef int (*stio_dev_pro_on_write_t) (stio_dev_pro_t* dev, void* wrctx);
struct stio_dev_pro_t
@ -100,7 +100,7 @@ STIO_EXPORT void stio_dev_pro_kill (
STIO_EXPORT int stio_dev_pro_write (
stio_dev_pro_t* pro,
const void* data,
stio_len_t len,
stio_iolen_t len,
void* wrctx
);

View File

@ -116,18 +116,19 @@ int stio_getsckadrinfo (stio_t* stio, const stio_sckadr_t* addr, stio_scklen_t*
return -1;
}
#if 0
static void stio_initsckadrforip4 (stio_sckadr_t* sckadr, stio_uint16_t port, stio_ip4adr_t* ip4adr)
/* ========================================================================= */
void stio_sckadr_initforip4 (stio_sckadr_t* sckadr, stio_uint16_t port, stio_ip4adr_t* ip4adr)
{
struct sockaddr_in* sin = (struct sockaddr_in*)sckadr;
STIO_MEMSET (sin, 0, STIO_SIZEOF(*sin));
sin->sin_family = AF_INET;
sin->sin_port = htons(port);
STIO_MEMSET (&sin->sin_addr, ip4adr, STIO_IP4ADR_LEN);
if (ip4adr) STIO_MEMCPY (&sin->sin_addr, ip4adr, STIO_IP4ADR_LEN);
}
static void stio_initsckadrforip6 (stio_sckadr_t* sckadr, stio_uint16_t port, stio_ip6adr_t* ip6adr)
void stio_sckadr_initforip6 (stio_sckadr_t* sckadr, stio_uint16_t port, stio_ip6adr_t* ip6adr)
{
struct sockaddr_in6* sin = (struct sockaddr_in6*)sckadr;
@ -135,19 +136,23 @@ static void stio_initsckadrforip6 (stio_sckadr_t* sckadr, stio_uint16_t port, st
STIO_MEMSET (sin, 0, STIO_SIZEOF(*sin));
sin->sin6_family = AF_INET;
sin->sin6_port = htons(port);
STIO_MEMSET (&sin->sin_addr, ip6adr, STIO_IP6ADR_LEN);
if (ip6adr) STIO_MEMCPY (&sin->sin6_addr, ip6adr, STIO_IP6ADR_LEN);
}
stio void stio_intisckadrforeth (stio_sckadr_t* sckadr, int ifindex, stio_ethadr_t* ethadr)
void stio_sckadr_initforeth (stio_sckadr_t* sckadr, int ifindex, stio_ethadr_t* ethadr)
{
struct sockaddr_ll* sll = (struct sockaddr_in*)sckadr;
struct sockaddr_ll* sll = (struct sockaddr_ll*)sckadr;
STIO_MEMSET (sll, 0, STIO_SIZEOF(*sll));
sll->sll_family = AF_PACKET;
sll->sll_ifindex = ifindex;
if (ethadr)
{
sll->sll_halen = STIO_ETHADR_LEN;
STIO_MEMSET (sll->sll_addr, ethadr, STIO_ETHADR_LEN);
STIO_MEMCPY (sll->sll_addr, ethadr, STIO_ETHADR_LEN);
}
}
#endif
/* ========================================================================= */
static stio_devadr_t* sckadr_to_devadr (stio_dev_sck_t* dev, const stio_sckadr_t* sckadr, stio_devadr_t* devadr)
{
@ -168,6 +173,7 @@ static STIO_INLINE stio_sckadr_t* devadr_to_sckadr (stio_dev_sck_t* dev, const s
{
return (stio_sckadr_t*)devadr->ptr;
}
/* ========================================================================= */
#define IS_STATEFUL(sck) ((sck)->dev_capa & STIO_DEV_CAPA_STREAM)
@ -228,8 +234,8 @@ static int dev_sck_make (stio_dev_t* dev, void* ctx)
rdev->on_write = arg->on_write;
rdev->on_read = arg->on_read;
rdev->type = arg->type;
rdev->tmridx_connect = STIO_TMRIDX_INVALID;
return 0;
oops:
@ -288,7 +294,7 @@ static stio_syshnd_t dev_sck_getsyshnd (stio_dev_t* dev)
return (stio_syshnd_t)rdev->sck;
}
static int dev_sck_read_stateful (stio_dev_t* dev, void* buf, stio_len_t* len, stio_devadr_t* srcadr)
static int dev_sck_read_stateful (stio_dev_t* dev, void* buf, stio_iolen_t* len, stio_devadr_t* srcadr)
{
stio_dev_sck_t* tcp = (stio_dev_sck_t*)dev;
ssize_t x;
@ -306,7 +312,7 @@ static int dev_sck_read_stateful (stio_dev_t* dev, void* buf, stio_len_t* len, s
return 1;
}
static int dev_sck_read_stateless (stio_dev_t* dev, void* buf, stio_len_t* len, stio_devadr_t* srcadr)
static int dev_sck_read_stateless (stio_dev_t* dev, void* buf, stio_iolen_t* len, stio_devadr_t* srcadr)
{
stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
stio_scklen_t srcadrlen;
@ -330,7 +336,7 @@ static int dev_sck_read_stateless (stio_dev_t* dev, void* buf, stio_len_t* len,
}
static int dev_sck_write_stateful (stio_dev_t* dev, const void* data, stio_len_t* len, const stio_devadr_t* dstadr)
static int dev_sck_write_stateful (stio_dev_t* dev, const void* data, stio_iolen_t* len, const stio_devadr_t* dstadr)
{
stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
ssize_t x;
@ -366,7 +372,7 @@ static int dev_sck_write_stateful (stio_dev_t* dev, const void* data, stio_len_t
return 1;
}
static int dev_sck_write_stateless (stio_dev_t* dev, const void* data, stio_len_t* len, const stio_devadr_t* dstadr)
static int dev_sck_write_stateless (stio_dev_t* dev, const void* data, stio_iolen_t* len, const stio_devadr_t* dstadr)
{
stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
ssize_t x;
@ -741,25 +747,25 @@ static int dev_evcb_sck_ready_stateless (stio_dev_t* dev, int events)
return 1; /* the device is ok. carry on reading or writing */
}
static int dev_evcb_sck_on_read_stateful (stio_dev_t* dev, const void* data, stio_len_t dlen, const stio_devadr_t* srcadr)
static int dev_evcb_sck_on_read_stateful (stio_dev_t* dev, const void* data, stio_iolen_t dlen, const stio_devadr_t* srcadr)
{
stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
return rdev->on_read (rdev, data, dlen, STIO_NULL);
}
static int dev_evcb_sck_on_write_stateful (stio_dev_t* dev, stio_len_t wrlen, void* wrctx, const stio_devadr_t* dstadr)
static int dev_evcb_sck_on_write_stateful (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_devadr_t* dstadr)
{
stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
return rdev->on_write (rdev, wrlen, wrctx, STIO_NULL);
}
static int dev_evcb_sck_on_read_stateless (stio_dev_t* dev, const void* data, stio_len_t dlen, const stio_devadr_t* srcadr)
static int dev_evcb_sck_on_read_stateless (stio_dev_t* dev, const void* data, stio_iolen_t dlen, const stio_devadr_t* srcadr)
{
stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
return rdev->on_read (rdev, data, dlen, srcadr->ptr);
}
static int dev_evcb_sck_on_write_stateless (stio_dev_t* dev, stio_len_t wrlen, void* wrctx, const stio_devadr_t* dstadr)
static int dev_evcb_sck_on_write_stateless (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_devadr_t* dstadr)
{
stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
return rdev->on_write (rdev, wrlen, wrctx, dstadr->ptr);
@ -818,13 +824,13 @@ int stio_dev_sck_listen (stio_dev_sck_t* dev, stio_dev_sck_listen_t* info)
return stio_dev_ioctl ((stio_dev_t*)dev, STIO_DEV_SCK_LISTEN, info);
}
int stio_dev_sck_write (stio_dev_sck_t* dev, const void* data, stio_len_t dlen, void* wrctx, const stio_sckadr_t* dstadr)
int stio_dev_sck_write (stio_dev_sck_t* dev, const void* data, stio_iolen_t dlen, void* wrctx, const stio_sckadr_t* dstadr)
{
stio_devadr_t devadr;
return stio_dev_write ((stio_dev_t*)dev, data, dlen, wrctx, sckadr_to_devadr(dev, dstadr, &devadr));
}
int stio_dev_sck_timedwrite (stio_dev_sck_t* dev, const void* data, stio_len_t dlen, const stio_ntime_t* tmout, void* wrctx, const stio_sckadr_t* dstadr)
int stio_dev_sck_timedwrite (stio_dev_sck_t* dev, const void* data, stio_iolen_t dlen, const stio_ntime_t* tmout, void* wrctx, const stio_sckadr_t* dstadr)
{
stio_devadr_t devadr;
return stio_dev_timedwrite ((stio_dev_t*)dev, data, dlen, tmout, wrctx, sckadr_to_devadr(dev, dstadr, &devadr));

View File

@ -103,12 +103,12 @@ typedef struct stio_dev_sck_t stio_dev_sck_t;
typedef int (*stio_dev_sck_on_read_t) (
stio_dev_sck_t* dev,
const void* data,
stio_len_t dlen,
stio_iolen_t dlen,
const stio_sckadr_t* srcadr
);
typedef int (*stio_dev_sck_on_write_t) (
stio_dev_sck_t* dev,
stio_len_t wrlen,
stio_iolen_t wrlen,
void* wrctx,
const stio_sckadr_t* dstadr
);
@ -145,8 +145,8 @@ struct stio_dev_sck_make_t
typedef struct stio_dev_sck_bind_t stio_dev_sck_bind_t;
struct stio_dev_sck_bind_t
{
int opts; /* TODO: REUSEADDR , TRANSPARENT, etc or someting?? */
stio_sckadr_t addr;
/*int opts;*/ /* TODO: REUSEADDR , TRANSPARENT, etc or someting?? */
/* TODO: add device name for BIND_TO_DEVICE */
};
@ -178,6 +178,7 @@ struct stio_dev_sck_accept_t
struct stio_dev_sck_t
{
STIO_DEV_HEADERS;
stio_dev_sck_type_t type;
stio_sckhnd_t sck;
@ -231,6 +232,26 @@ STIO_EXPORT int stio_getsckadrinfo (
stio_sckfam_t* family
);
void stio_sckadr_initforip4 (
stio_sckadr_t* sckadr,
stio_uint16_t port,
stio_ip4adr_t* ip4adr
);
void stio_sckadr_initforip6 (
stio_sckadr_t* sckadr,
stio_uint16_t port,
stio_ip6adr_t* ip6adr
);
void stio_sckadr_initforeth (
stio_sckadr_t* sckadr,
int ifindex,
stio_ethadr_t* ethadr
);
/* ========================================================================= */
STIO_EXPORT stio_dev_sck_t* stio_dev_sck_make (
@ -257,7 +278,7 @@ STIO_EXPORT int stio_dev_sck_listen (
STIO_EXPORT int stio_dev_sck_write (
stio_dev_sck_t* dev,
const void* data,
stio_len_t len,
stio_iolen_t len,
void* wrctx,
const stio_sckadr_t* dstadr
);
@ -265,7 +286,7 @@ STIO_EXPORT int stio_dev_sck_write (
STIO_EXPORT int stio_dev_sck_timedwrite (
stio_dev_sck_t* dev,
const void* data,
stio_len_t len,
stio_iolen_t len,
const stio_ntime_t* tmout,
void* wrctx,
const stio_sckadr_t* dstadr
@ -285,12 +306,12 @@ static STIO_INLINE int stio_dev_sck_read (stio_dev_sck_t* sck, int enabled)
}
/*
static STIO_INLINE int stio_dev_sck_write (stio_dev_sck_t* sck, const void* data, stio_len_t len, void* wrctx, const stio_devadr_t* dstadr)
static STIO_INLINE int stio_dev_sck_write (stio_dev_sck_t* sck, const void* data, stio_iolen_t len, void* wrctx, const stio_devadr_t* dstadr)
{
return stio_dev_write ((stio_dev_t*)sck, data, len, wrctx, STIO_NULL);
}
static STIO_INLINE int stio_dev_sck_timedwrite (stio_dev_sck_t* sck, const void* data, stio_len_t len, const stio_ntime_t* tmout, void* wrctx)
static STIO_INLINE int stio_dev_sck_timedwrite (stio_dev_sck_t* sck, const void* data, stio_iolen_t len, const stio_ntime_t* tmout, void* wrctx)
{
return stio_dev_timedwrite ((stio_dev_t*)sck, data, len, tmout, wrctx, STIO_NULL);
}

View File

@ -1,537 +0,0 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "stio-tcp.h"
#include "stio-prv.h"
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
static int tcp_make (stio_dev_t* dev, void* ctx)
{
stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
stio_dev_tcp_make_t* arg = (stio_dev_tcp_make_t*)ctx;
stio_scklen_t len;
stio_sckfam_t family;
int iv;
if (stio_getsckadrinfo(dev->stio, &arg->addr, &len, &family) <= -1) return -1;
tcp->sck = stio_openasyncsck (dev->stio, family, SOCK_STREAM, 0);
if (tcp->sck == STIO_SCKHND_INVALID) goto oops;
/* TODO:
setsockopt (udp->sck, SOL_SOCKET, SO_REUSEADDR, ...);
TRANSPARENT, ETC.
*/
iv = 1;
if (setsockopt (tcp->sck, SOL_SOCKET, SO_REUSEADDR, &iv, STIO_SIZEOF(iv)) == -1 ||
bind (tcp->sck, (struct sockaddr*)&arg->addr, len) == -1)
{
tcp->stio->errnum = stio_syserrtoerrnum(errno);
goto oops;
}
tcp->dev_capa = STIO_DEV_CAPA_IN | STIO_DEV_CAPA_OUT | STIO_DEV_CAPA_OUT_QUEUED | STIO_DEV_CAPA_STREAM;
tcp->on_write = arg->on_write;
tcp->on_read = arg->on_read;
tcp->tmridx_connect = STIO_TMRIDX_INVALID;
return 0;
oops:
if (tcp->sck != STIO_SCKHND_INVALID)
{
stio_closeasyncsck (tcp->stio, tcp->sck);
tcp->sck = STIO_SCKHND_INVALID;
}
return -1;
}
static int tcp_make_accepted (stio_dev_t* dev, void* ctx)
{
stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
stio_syshnd_t* sck = (stio_syshnd_t*)ctx;
tcp->sck = *sck;
if (stio_makesckasync (dev->stio, tcp->sck) <= -1) return -1;
return 0;
}
static void tcp_kill (stio_dev_t* dev)
{
stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
if (tcp->state & (STIO_DEV_TCP_ACCEPTED | STIO_DEV_TCP_CONNECTED | STIO_DEV_TCP_CONNECTING | STIO_DEV_TCP_LISTENING))
{
if (tcp->on_disconnect) tcp->on_disconnect (tcp);
}
if (tcp->tmridx_connect != STIO_TMRIDX_INVALID)
{
stio_deltmrjob (dev->stio, tcp->tmridx_connect);
STIO_ASSERT (tcp->tmridx_connect == STIO_TMRIDX_INVALID);
}
if (tcp->sck != STIO_SCKHND_INVALID)
{
stio_closeasyncsck (tcp->stio, tcp->sck);
tcp->sck = STIO_SCKHND_INVALID;
}
}
static stio_syshnd_t tcp_getsyshnd (stio_dev_t* dev)
{
stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
return (stio_syshnd_t)tcp->sck;
}
static int tcp_read (stio_dev_t* dev, void* buf, stio_len_t* len, void* src_addr)
{
stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
ssize_t x;
x = recv (tcp->sck, buf, *len, 0);
if (x == -1)
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; /* no data available */
if (errno == EINTR) return 0;
tcp->stio->errnum = stio_syserrtoerrnum(errno);
return -1;
}
*len = x;
return 1;
}
static int tcp_write (stio_dev_t* dev, const void* data, stio_len_t* len, const void* dest_addr)
{
stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
ssize_t x;
int flags = 0;
if (*len <= 0)
{
/* it's a writing finish indicator. close the writing end of
* the socket, probably leaving it in the half-closed state */
if (shutdown (tcp->sck, SHUT_WR) == -1)
{
tcp->stio->errnum = stio_syserrtoerrnum(errno);
return -1;
}
return 1;
}
/* TODO: flags MSG_DONTROUTE, MSG_DONTWAIT, MSG_MORE, MSG_OOB, MSG_NOSIGNAL */
#if defined(MSG_NOSIGNAL)
flags |= MSG_NOSIGNAL;
#endif
x = sendto (tcp->sck, data, *len, flags, STIO_NULL, 0);
if (x == -1)
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; /* no data can be written */
if (errno == EINTR) return 0;
tcp->stio->errnum = stio_syserrtoerrnum(errno);
return -1;
}
*len = x;
return 1;
}
static void tmr_connect_handle (stio_t* stio, const stio_ntime_t* now, stio_tmrjob_t* job)
{
stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)job->ctx;
if (tcp->state & STIO_DEV_TCP_CONNECTING)
{
/* the state check for STIO_DEV_TCP_CONNECTING is actually redundant
* as it must not be fired after it gets connected. the timer job
* doesn't need to be deleted when it gets connected for this check
* here. this libarary, however, deletes the job when it gets
* connected. */
stio_dev_tcp_halt (tcp);
}
}
static int tcp_ioctl (stio_dev_t* dev, int cmd, void* arg)
{
stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
switch (cmd)
{
case STIO_DEV_TCP_BIND:
{
stio_dev_tcp_bind_t* bnd = (stio_dev_tcp_bind_t*)arg;
struct sockaddr* sa = (struct sockaddr*)&bnd->addr;
stio_scklen_t sl;
stio_sckfam_t fam;
int x;
if (stio_getsckadrinfo (dev->stio, &bnd->addr, &sl, &fam) <= -1) return -1;
#if defined(_WIN32)
/* TODO */
#else
/* the socket is already non-blocking */
x = bind (tcp->sck, sa, sl);
if (x == -1)
{
tcp->stio->errnum = stio_syserrtoerrnum(errno);
return -1;
}
return 0;
#endif
}
case STIO_DEV_TCP_CONNECT:
{
stio_dev_tcp_connect_t* conn = (stio_dev_tcp_connect_t*)arg;
struct sockaddr* sa = (struct sockaddr*)&conn->addr;
stio_scklen_t sl;
int x;
if (sa->sa_family == AF_INET) sl = STIO_SIZEOF(struct sockaddr_in);
else if (sa->sa_family == AF_INET6) sl = STIO_SIZEOF(struct sockaddr_in6);
else
{
dev->stio->errnum = STIO_EINVAL;
return -1;
}
#if defined(_WIN32)
/* TODO */
#else
/* the socket is already non-blocking */
x = connect (tcp->sck, sa, sl);
if (x == -1)
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK)
{
if (stio_dev_watch ((stio_dev_t*)tcp, STIO_DEV_WATCH_UPDATE, STIO_DEV_EVENT_IN | STIO_DEV_EVENT_OUT) >= 0)
{
stio_tmrjob_t tmrjob;
if (!stio_isnegtime(&conn->tmout))
{
STIO_MEMSET (&tmrjob, 0, STIO_SIZEOF(tmrjob));
tmrjob.ctx = tcp;
stio_gettime (&tmrjob.when);
stio_addtime (&tmrjob.when, &conn->tmout, &tmrjob.when);
tmrjob.handler = tmr_connect_handle;
tmrjob.idxptr = &tcp->tmridx_connect;
STIO_ASSERT (tcp->tmridx_connect == STIO_TMRIDX_INVALID);
tcp->tmridx_connect = stio_instmrjob (tcp->stio, &tmrjob);
if (tcp->tmridx_connect == STIO_TMRIDX_INVALID)
{
stio_dev_watch ((stio_dev_t*)tcp, STIO_DEV_WATCH_UPDATE, STIO_DEV_EVENT_IN);
/* event manipulation failure can't be handled properly. so ignore it.
* anyway, it's already in a failure condition */
return -1;
}
}
tcp->state |= STIO_DEV_TCP_CONNECTING;
tcp->peeradr = conn->addr;
tcp->on_connect = conn->on_connect;
tcp->on_disconnect = conn->on_disconnect;
return 0;
}
}
tcp->stio->errnum = stio_syserrtoerrnum(errno);
return -1;
}
/* connected immediately */
tcp->state |= STIO_DEV_TCP_CONNECTED;
tcp->peeradr = conn->addr;
tcp->on_connect = conn->on_connect;
tcp->on_disconnect = conn->on_disconnect;
return 0;
#endif
}
case STIO_DEV_TCP_LISTEN:
{
stio_dev_tcp_listen_t* lstn = (stio_dev_tcp_listen_t*)arg;
int x;
#if defined(_WIN32)
/* TODO */
#else
x = listen (tcp->sck, lstn->backlogs);
if (x == -1)
{
tcp->stio->errnum = stio_syserrtoerrnum(errno);
return -1;
}
tcp->state |= STIO_DEV_TCP_LISTENING;
tcp->on_connect = lstn->on_connect;
tcp->on_disconnect = lstn->on_disconnect;
return 0;
#endif
}
}
return 0;
}
static stio_dev_mth_t tcp_mth =
{
tcp_make,
tcp_kill,
tcp_getsyshnd,
tcp_read,
tcp_write,
tcp_ioctl,
};
/* accepted tcp socket */
static stio_dev_mth_t tcp_acc_mth =
{
tcp_make_accepted,
tcp_kill,
tcp_getsyshnd,
tcp_read,
tcp_write,
tcp_ioctl
};
/* ------------------------------------------------------------------------ */
static int tcp_ready (stio_dev_t* dev, int events)
{
stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
printf ("TCP READY...%p\n", dev);
if (events & STIO_DEV_EVENT_ERR)
{
int errcode;
stio_scklen_t len;
len = STIO_SIZEOF(errcode);
if (getsockopt (tcp->sck, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len) == -1)
{
/* the error number is set to the socket error code.
* errno resulting from getsockopt() doesn't reflect the actual
* socket error. so errno is not used to set the error number.
* instead, the generic device error STIO_EDEVERRR is used */
tcp->stio->errnum = STIO_EDEVERR;
}
else
{
tcp->stio->errnum = stio_syserrtoerrnum (errcode);
}
return -1;
}
if (tcp->state & STIO_DEV_TCP_CONNECTING)
{
if (events & STIO_DEV_EVENT_HUP)
{
/* device hang-up */
tcp->stio->errnum = STIO_EDEVHUP;
return -1;
}
else if (events & (STIO_DEV_EVENT_PRI | STIO_DEV_EVENT_IN))
{
/* invalid event masks. generic device error */
tcp->stio->errnum = STIO_EDEVERR;
return -1;
}
else if (events & STIO_DEV_EVENT_OUT)
{
int errcode;
stio_scklen_t len;
STIO_ASSERT (!(tcp->state & STIO_DEV_TCP_CONNECTED));
len = STIO_SIZEOF(errcode);
if (getsockopt (tcp->sck, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len) == -1)
{
tcp->stio->errnum = stio_syserrtoerrnum(errno);
return -1;
}
else if (errcode == 0)
{
tcp->state &= ~STIO_DEV_TCP_CONNECTING;
tcp->state |= STIO_DEV_TCP_CONNECTED;
if (stio_dev_watch ((stio_dev_t*)tcp, STIO_DEV_WATCH_RENEW, 0) <= -1) return -1;
if (tcp->tmridx_connect != STIO_TMRIDX_INVALID)
{
stio_deltmrjob (tcp->stio, tcp->tmridx_connect);
STIO_ASSERT (tcp->tmridx_connect == STIO_TMRIDX_INVALID);
}
if (tcp->on_connect (tcp) <= -1)
{
printf ("ON_CONNECTE HANDLER RETURNEF FAILURE...\n");
return -1;
}
}
else if (errcode == EINPROGRESS || errcode == EWOULDBLOCK)
{
/* still in progress */
}
else
{
tcp->stio->errnum = stio_syserrtoerrnum(errcode);
return -1;
}
}
return 0; /* success but don't invoke on_read() */
}
else if (tcp->state & STIO_DEV_TCP_LISTENING)
{
if (events & STIO_DEV_EVENT_HUP)
{
/* device hang-up */
tcp->stio->errnum = STIO_EDEVHUP;
return -1;
}
else if (events & (STIO_DEV_EVENT_PRI | STIO_DEV_EVENT_OUT))
{
tcp->stio->errnum = STIO_EDEVERR;
return -1;
}
else if (events & STIO_DEV_EVENT_IN)
{
stio_sckhnd_t clisck;
stio_sckadr_t peer;
stio_scklen_t addrlen;
stio_dev_tcp_t* clitcp;
/* this is a server(lisening) socket */
addrlen = STIO_SIZEOF(peer);
clisck = accept (tcp->sck, (struct sockaddr*)&peer, &addrlen);
if (clisck == STIO_SCKHND_INVALID)
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0;
if (errno == EINTR) return 0; /* if interrupted by a signal, treat it as if it's EINPROGRESS */
tcp->stio->errnum = stio_syserrtoerrnum(errno);
return -1;
}
/* use tcp->dev_size when instantiating a client tcp device
* instead of STIO_SIZEOF(stio_dev_tcp_t). therefore, the
* extension area as big as that of the master tcp device
* is created in the client tcp device */
clitcp = (stio_dev_tcp_t*)stio_makedev (tcp->stio, tcp->dev_size, &tcp_acc_mth, tcp->dev_evcb, &clisck);
if (!clitcp)
{
close (clisck);
return -1;
}
clitcp->dev_capa |= STIO_DEV_CAPA_IN | STIO_DEV_CAPA_OUT | STIO_DEV_CAPA_STREAM;
clitcp->state |= STIO_DEV_TCP_ACCEPTED;
clitcp->peeradr = peer;
/*clitcp->parent = tcp;*/
/* inherit some event handlers from the parent.
* you can still change them inside the on_connect handler */
clitcp->on_connect = tcp->on_connect;
clitcp->on_disconnect = tcp->on_disconnect;
clitcp->on_write = tcp->on_write;
clitcp->on_read = tcp->on_read;
clitcp->tmridx_connect = STIO_TMRIDX_INVALID;
if (clitcp->on_connect (clitcp) <= -1) stio_dev_tcp_halt (clitcp);
return 0; /* success but don't invoke on_read() */
}
}
else if (events & STIO_DEV_EVENT_HUP)
{
if (events & (STIO_DEV_EVENT_PRI | STIO_DEV_EVENT_IN | STIO_DEV_EVENT_OUT))
{
/* probably half-open? */
return 1;
}
tcp->stio->errnum = STIO_EDEVHUP;
return -1;
}
return 1; /* the device is ok. carry on reading or writing */
}
static int tcp_on_read (stio_dev_t* dev, const void* data, stio_len_t len)
{
stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
return tcp->on_read (tcp, data, len);
}
static int tcp_on_write (stio_dev_t* dev, stio_len_t wrlen, void* wrctx)
{
stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev;
return tcp->on_write (tcp, wrlen, wrctx);
}
static stio_dev_evcb_t tcp_evcb =
{
tcp_ready,
tcp_on_read,
tcp_on_write
};
stio_dev_tcp_t* stio_dev_tcp_make (stio_t* stio, stio_size_t xtnsize, const stio_dev_tcp_make_t* data)
{
return (stio_dev_tcp_t*)stio_makedev (stio, STIO_SIZEOF(stio_dev_tcp_t) + xtnsize, &tcp_mth, &tcp_evcb, (void*)data);
}
int stio_dev_tcp_bind (stio_dev_tcp_t* tcp, stio_dev_tcp_bind_t* bind)
{
return stio_dev_ioctl ((stio_dev_t*)tcp, STIO_DEV_TCP_BIND, bind);
}
int stio_dev_tcp_connect (stio_dev_tcp_t* tcp, stio_dev_tcp_connect_t* conn)
{
return stio_dev_ioctl ((stio_dev_t*)tcp, STIO_DEV_TCP_CONNECT, conn);
}
int stio_dev_tcp_listen (stio_dev_tcp_t* tcp, stio_dev_tcp_listen_t* lstn)
{
return stio_dev_ioctl ((stio_dev_t*)tcp, STIO_DEV_TCP_LISTEN, lstn);
}

View File

@ -1,186 +0,0 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STIO_TCP_H_
#define _STIO_TCP_H_
#include <stio.h>
#include <stio-sck.h>
enum stio_dev_tcp_ioctl_cmd_t
{
STIO_DEV_TCP_BIND,
STIO_DEV_TCP_CONNECT,
STIO_DEV_TCP_LISTEN
};
typedef enum stio_dev_tcp_ioctl_cmd_t stio_dev_tcp_ioctl_cmd_t;
enum stio_dev_tcp_state_t
{
STIO_DEV_TCP_CONNECTING = (1 << 0),
STIO_DEV_TCP_CONNECTED = (1 << 1),
STIO_DEV_TCP_LISTENING = (1 << 2),
STIO_DEV_TCP_ACCEPTED = (1 << 3)
};
typedef enum stio_dev_tcp_state_t stio_dev_tcp_state_t;
typedef struct stio_dev_tcp_t stio_dev_tcp_t;
typedef int (*stio_dev_tcp_on_connect_t) (stio_dev_tcp_t* dev);
typedef void (*stio_dev_tcp_on_disconnect_t) (stio_dev_tcp_t* dev);
typedef int (*stio_dev_tcp_on_read_t) (stio_dev_tcp_t* dev, const void* data, stio_len_t len);
typedef int (*stio_dev_tcp_on_write_t) (stio_dev_tcp_t* dev, stio_len_t wrlen, void* wrctx);
struct stio_dev_tcp_t
{
STIO_DEV_HEADERS;
stio_sckhnd_t sck;
/* bitwised-ORed of #stio_dev_tcp_state_t enumerators */
int state;
/* peer address - valid if one of the followings is set:
* STIO_DEV_TCP_ACCEPTED
* STIO_DEV_TCP_CONNECTED
* STIO_DEV_TCP_CONNECTING */
stio_sckadr_t peeradr;
/** return 0 on succes, -1 on failure/
* called on a new tcp device for an accepted client or
* on a tcp device conntected to a remote server */
stio_dev_tcp_on_connect_t on_connect;
stio_dev_tcp_on_disconnect_t on_disconnect;
stio_dev_tcp_on_read_t on_read;
stio_dev_tcp_on_write_t on_write;
stio_tmridx_t tmridx_connect;
};
typedef struct stio_dev_tcp_make_t stio_dev_tcp_make_t;
struct stio_dev_tcp_make_t
{
/* TODO: options: REUSEADDR for binding?? */
stio_sckadr_t addr; /* binding address. */
stio_dev_tcp_on_write_t on_write;
stio_dev_tcp_on_read_t on_read;
};
typedef struct stio_dev_tcp_bind_t stio_dev_tcp_bind_t;
struct stio_dev_tcp_bind_t
{
int opts; /* TODO: REUSEADDR , TRANSPARENT, etc or someting?? */
stio_sckadr_t addr;
/* TODO: add device name for BIND_TO_DEVICE */
};
typedef struct stio_dev_tcp_connect_t stio_dev_tcp_connect_t;
struct stio_dev_tcp_connect_t
{
stio_sckadr_t addr;
stio_ntime_t tmout; /* connect timeout */
stio_dev_tcp_on_connect_t on_connect;
stio_dev_tcp_on_disconnect_t on_disconnect;
};
typedef struct stio_dev_tcp_listen_t stio_dev_tcp_listen_t;
struct stio_dev_tcp_listen_t
{
int backlogs;
stio_dev_tcp_on_connect_t on_connect; /* optional, but new connections are dropped immediately without this */
stio_dev_tcp_on_disconnect_t on_disconnect; /* should on_discconneted be part of on_accept_t??? */
};
typedef struct stio_dev_tcp_accept_t stio_dev_tcp_accept_t;
struct stio_dev_tcp_accept_t
{
stio_syshnd_t sck;
/* TODO: add timeout */
stio_sckadr_t peeradr;
};
#ifdef __cplusplus
extern "C" {
#endif
STIO_EXPORT stio_dev_tcp_t* stio_dev_tcp_make (
stio_t* stio,
stio_size_t xtnsize,
const stio_dev_tcp_make_t* data
);
STIO_EXPORT int stio_dev_tcp_bind (
stio_dev_tcp_t* tcp,
stio_dev_tcp_bind_t* bind
);
STIO_EXPORT int stio_dev_tcp_connect (
stio_dev_tcp_t* tcp,
stio_dev_tcp_connect_t* conn);
STIO_EXPORT int stio_dev_tcp_listen (
stio_dev_tcp_t* tcp,
stio_dev_tcp_listen_t* lstn
);
#if defined(STIO_HAVE_INLINE)
static STIO_INLINE int stio_dev_tcp_read (stio_dev_tcp_t* tcp, int enabled)
{
return stio_dev_read ((stio_dev_t*)tcp, enabled);
}
static STIO_INLINE int stio_dev_tcp_write (stio_dev_tcp_t* tcp, const void* data, stio_len_t len, void* wrctx)
{
return stio_dev_write ((stio_dev_t*)tcp, data, len, wrctx, STIO_NULL);
}
static STIO_INLINE int stio_dev_tcp_timedwrite (stio_dev_tcp_t* tcp, const void* data, stio_len_t len, const stio_ntime_t* tmout, void* wrctx)
{
return stio_dev_timedwrite ((stio_dev_t*)tcp, data, len, tmout, wrctx, STIO_NULL);
}
static STIO_INLINE void stio_dev_tcp_halt (stio_dev_tcp_t* tcp)
{
stio_dev_halt ((stio_dev_t*)tcp);
}
#else
#define stio_dev_tcp_read(tcp,enabled) stio_dev_read((stio_dev_t*)tcp, enabled)
#define stio_dev_tcp_write(tcp,data,len,wrctx) stio_dev_write((stio_dev_t*)tcp, data, len, wrctx, STIO_NULL)
#define stio_dev_tcp_timedwrite(tcp,data,len,tmout,wrctx) stio_dev_timedwrite((stio_dev_t*)tcp, data, len, tmout, wrctx, STIO_NULL)
#define stio_dev_tcp_halt(tcp) stio_dev_halt((stio_dev_t*)tcp)
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,189 +0,0 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if 0
#include "stio-udp.h"
#include "stio-prv.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
static int udp_make (stio_dev_t* dev, void* ctx)
{
stio_dev_udp_t* udp = (stio_dev_udp_t*)dev;
stio_dev_udp_make_t* arg = (stio_dev_udp_make_t*)ctx;
stio_scklen_t len;
stio_sckfam_t family;
if (stio_getsckadrinfo(dev->stio, &arg->addr, &len, &family) <= -1) return -1;
udp->sck = stio_openasyncsck (dev->stio, family, SOCK_DGRAM, 0);
if (udp->sck == STIO_SCKHND_INVALID) goto oops;
/* some socket options? */
if (bind (udp->sck, (struct sockaddr*)&arg->addr, len) == -1)
{
udp->stio->errnum = stio_syserrtoerrnum(errno);
goto oops;
}
udp->on_write = arg->on_write;
udp->on_read = arg->on_read;
return 0;
oops:
if (udp->sck != STIO_SCKHND_INVALID)
{
stio_closeasyncsck (udp->stio, udp->sck);
udp->sck = STIO_SCKHND_INVALID;
}
return -1;
}
static void udp_kill (stio_dev_t* dev)
{
stio_dev_udp_t* udp = (stio_dev_udp_t*)dev;
if (udp->sck != STIO_SCKHND_INVALID)
{
stio_closeasyncsck (udp->stio, udp->sck);
udp->sck = STIO_SCKHND_INVALID;
}
}
static stio_syshnd_t udp_getsyshnd (stio_dev_t* dev)
{
stio_dev_udp_t* udp = (stio_dev_udp_t*)dev;
return (stio_syshnd_t)udp->sck;
}
static int udp_read (stio_dev_t* dev, void* buf, stio_len_t* len, stio_devadr_t* adr)
{
stio_dev_udp_t* udp = (stio_dev_udp_t*)dev;
stio_scklen_t addrlen;
int x;
/* TODO: udp_read need source address ... have to extend the send callback to accept the source address */
printf ("UDP RECVFROM...\n");
addrlen = STIO_SIZEOF(udp->peeradr);
x = recvfrom (udp->sck, buf, *len, 0, (struct sockaddr*)&udp->peeradr, &addrlen);
if (x <= -1)
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; /* no data available */
if (errno == EINTR) return 0;
udp->stio->errnum = stio_syserrtoerrnum(errno);
return -1;
}
*len = x;
return 1;
}
static int udp_write (stio_dev_t* dev, const void* data, stio_len_t* len, const stio_devadr_t* adr)
{
stio_dev_udp_t* udp = (stio_dev_udp_t*)udp;
ssize_t x;
#if 0
/* TODO: udp_write need target address ... have to extend the send callback to accept the target address */
x = sendto (udp->sck, data, *len, skad, stio_getskadlen(skad));
if (x <= -1)
{
if (errno == EINPROGRESS || errno == EWOULDBLOCK) return 0; /* no data can be written */
if (errno == EINTR) return 0;
udp->stio->errnum = stio_syserrtoerrnum(errno);
return -1;
}
/* for UDP, if the data chunk can't be written at one go, it's actually a failure */
if (x != *len) return -1; /* TODO: can i hava an indicator for this in stio? */
*len = x;
#endif
return 1;
}
static int udp_ioctl (stio_dev_t* dev, int cmd, void* arg)
{
return 0;
}
/* ------------------------------------------------------------------------ */
static stio_dev_mth_t udp_mth =
{
udp_make,
udp_kill,
udp_getsyshnd,
udp_read,
udp_write,
udp_ioctl, /* ioctl */
};
static int udp_ready (stio_dev_t* dev, int events)
{
/* TODO: ... */
if (events & STIO_DEV_EVENT_ERR) printf ("UDP READY ERROR.....\n");
if (events & STIO_DEV_EVENT_HUP) printf ("UDP READY HANGUP.....\n");
if (events & STIO_DEV_EVENT_PRI) printf ("UDP READY PRI.....\n");
if (events & STIO_DEV_EVENT_IN) printf ("UDP READY IN.....\n");
if (events & STIO_DEV_EVENT_OUT) printf ("UDP READY OUT.....\n");
return 0;
}
static int udp_on_read (stio_dev_t* dev, const void* data, stio_len_t len)
{
printf ("dATA received %d bytes\n", (int)len);
return 0;
}
static int udp_on_write (stio_dev_t* dev, stio_len_t wrlen, void* wrctx)
{
return 0;
}
static stio_dev_evcb_t udp_evcb =
{
udp_ready,
udp_on_read,
udp_on_write
};
stio_dev_udp_t* stio_dev_udp_make (stio_t* stio, stio_size_t xtnsize, const stio_dev_udp_make_t* data)
{
return (stio_dev_udp_t*)stio_makedev (stio, STIO_SIZEOF(stio_dev_udp_t) + xtnsize, &udp_mth, &udp_evcb, (void*)data);
}
#endif

View File

@ -1,103 +0,0 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STIO_UDP_H_
#define _STIO_UDP_H_
#include <stio.h>
#include <stio-sck.h>
typedef struct stio_dev_udp_t stio_dev_udp_t;
typedef int (*stio_dev_udp_on_read_t) (stio_dev_udp_t* dev, const void* data, stio_len_t len);
typedef int (*stio_dev_udp_on_write_t) (stio_dev_udp_t* dev, void* wrctx);
typedef struct stio_dev_udp_make_t stio_dev_udp_make_t;
struct stio_dev_udp_make_t
{
/* TODO: options: REUSEADDR for binding?? */
stio_sckadr_t addr; /* binding address. */
stio_dev_udp_on_write_t on_write;
stio_dev_udp_on_read_t on_read;
};
struct stio_dev_udp_t
{
STIO_DEV_HEADERS;
stio_sckhnd_t sck;
stio_sckadr_t peer;
stio_dev_udp_on_write_t on_write;
stio_dev_udp_on_read_t on_read;
};
#ifdef __cplusplus
extern "C" {
#endif
STIO_EXPORT stio_dev_udp_t* stio_dev_udp_make (
stio_t* stio,
stio_size_t xtnsize,
const stio_dev_udp_make_t* data
);
#if defined(STIO_HAVE_INLINE)
static STIO_INLINE int stio_dev_udp_read (stio_dev_udp_t* udp, int enabled)
{
return stio_dev_read ((stio_dev_t*)udp, enabled);
}
static STIO_INLINE int stio_dev_udp_write (stio_dev_udp_t* udp, const void* data, stio_len_t len, void* wrctx, const stio_devadr_t* dstadr)
{
return stio_dev_write ((stio_dev_t*)udp, data, len, wrctx, dstadr);
}
static STIO_INLINE int stio_dev_udp_timedwrite (stio_dev_udp_t* udp, const void* data, stio_len_t len, const stio_ntime_t* tmout, void* wrctx, const stio_devadr_t* dstadr)
{
return stio_dev_timedwrite ((stio_dev_t*)udp, data, len, tmout, wrctx, dstadr);
}
static STIO_INLINE void stio_dev_udp_halt (stio_dev_udp_t* udp)
{
stio_dev_halt ((stio_dev_t*)udp);
}
#else
#define stio_dev_udp_read(udp,enabled) stio_dev_read((stio_dev_t*)udp, enabled)
#define stio_dev_udp_write(udp,data,len,wrctx,dstadr) stio_dev_write((stio_dev_t*)udp, data, len, wrctx, dstadr)
#define stio_dev_udp_timedwrite(udp,data,len,tmout,wrctx,dstadr) stio_dev_timedwrite((stio_dev_t*)udp, data, len, tmout, wrctx, dstadr)
#define stio_dev_udp_halt(udp) stio_dev_halt((stio_dev_t*)udp)
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -177,7 +177,7 @@ printf ("has urgent data...\n");
{
stio_wq_t* q;
const stio_uint8_t* uptr;
stio_len_t urem, ulen;
stio_iolen_t urem, ulen;
int x;
q = STIO_WQ_HEAD(&dev->wq);
@ -267,7 +267,7 @@ printf ("has urgent data...\n");
if (dev && stio->revs[i].events & EPOLLIN)
{
stio_devadr_t srcadr;
stio_len_t len;
stio_iolen_t len;
int x;
/* the devices are all non-blocking. read as much as possible
@ -516,6 +516,12 @@ stio_dev_t* stio_makedev (stio_t* stio, stio_size_t dev_size, stio_dev_mth_t* de
goto oops;
}
/* the make callback must not change these fields */
STIO_ASSERT (dev->dev_mth == dev_mth);
STIO_ASSERT (dev->dev_evcb == dev_evcb);
STIO_ASSERT (dev->dev_prev == STIO_NULL);
STIO_ASSERT (dev->dev_next == STIO_NULL);
/* set some internal capability bits according to the capabilities
* removed by the device making callback for convenience sake. */
if (!(dev->dev_capa & STIO_DEV_CAPA_IN)) dev->dev_capa |= STIO_DEV_CAPA_IN_CLOSED;
@ -750,10 +756,10 @@ static void on_write_timeout (stio_t* stio, const stio_ntime_t* now, stio_tmrjob
if (x <= -1) stio_dev_halt (dev);
}
static int __dev_write (stio_dev_t* dev, const void* data, stio_len_t len, const stio_ntime_t* tmout, void* wrctx, const stio_devadr_t* dstadr)
static int __dev_write (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_ntime_t* tmout, void* wrctx, const stio_devadr_t* dstadr)
{
const stio_uint8_t* uptr;
stio_len_t urem, ulen;
stio_iolen_t urem, ulen;
stio_wq_t* q;
int x;
@ -810,6 +816,7 @@ static int __dev_write (stio_dev_t* dev, const void* data, stio_len_t len, const
else
{
ulen = urem;
x = dev->dev_mth->write (dev, data, &ulen, dstadr);
if (x <= -1) return -1;
else if (x == 0) goto enqueue_data;
@ -894,12 +901,12 @@ enqueue_data:
return 0; /* request pused to a write queue. */
}
int stio_dev_write (stio_dev_t* dev, const void* data, stio_len_t len, void* wrctx, const stio_devadr_t* dstadr)
int stio_dev_write (stio_dev_t* dev, const void* data, stio_iolen_t len, void* wrctx, const stio_devadr_t* dstadr)
{
return __dev_write (dev, data, len, STIO_NULL, wrctx, dstadr);
}
int stio_dev_timedwrite (stio_dev_t* dev, const void* data, stio_len_t len, const stio_ntime_t* tmout, void* wrctx, const stio_devadr_t* dstadr)
int stio_dev_timedwrite (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_ntime_t* tmout, void* wrctx, const stio_devadr_t* dstadr)
{
return __dev_write (dev, data, len, tmout, wrctx, dstadr);
}

View File

@ -86,7 +86,7 @@ typedef struct stio_dev_mth_t stio_dev_mth_t;
typedef struct stio_dev_evcb_t stio_dev_evcb_t;
typedef struct stio_wq_t stio_wq_t;
typedef stio_intptr_t stio_len_t; /* NOTE: this is a signed type */
typedef stio_intptr_t stio_iolen_t; /* NOTE: this is a signed type */
enum stio_errnum_t
{
@ -143,10 +143,10 @@ struct stio_dev_mth_t
/* return -1 on failure, 0 if no data is availble, 1 otherwise.
* when returning 1, *len must be sent to the length of data read.
* if *len is set to 0, it's treated as EOF. */
int (*read) (stio_dev_t* dev, void* data, stio_len_t* len, stio_devadr_t* srcadr);
int (*read) (stio_dev_t* dev, void* data, stio_iolen_t* len, stio_devadr_t* srcadr);
/* ------------------------------------------------------------------ */
int (*write) (stio_dev_t* dev, const void* data, stio_len_t* len, const stio_devadr_t* dstadr);
int (*write) (stio_dev_t* dev, const void* data, stio_iolen_t* len, const stio_devadr_t* dstadr);
/* ------------------------------------------------------------------ */
int (*ioctl) (stio_dev_t* dev, int cmd, void* arg);
@ -163,13 +163,13 @@ struct stio_dev_evcb_t
/* return -1 on failure, 0 or 1 on success.
* when 0 is returned, the main loop stops the attempt to read more data.
* when 1 is returned, the main loop attempts to read more data without*/
int (*on_read) (stio_dev_t* dev, const void* data, stio_len_t len, const stio_devadr_t* srcadr);
int (*on_read) (stio_dev_t* dev, const void* data, stio_iolen_t len, const stio_devadr_t* srcadr);
/* return -1 on failure, 0 on success.
* wrlen is the length of data written. it is the length of the originally
* posted writing request for a stream device. For a non stream device, it
* may be shorter than the originally posted length. */
int (*on_write) (stio_dev_t* dev, stio_len_t wrlen, void* wrctx, const stio_devadr_t* dstadr);
int (*on_write) (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_devadr_t* dstadr);
};
struct stio_wq_t
@ -177,9 +177,9 @@ struct stio_wq_t
stio_wq_t* next;
stio_wq_t* prev;
stio_len_t olen; /* original data length */
stio_iolen_t olen; /* original data length */
stio_uint8_t* ptr; /* pointer to data */
stio_len_t len; /* remaining data length */
stio_iolen_t len; /* remaining data length */
void* ctx;
stio_dev_t* dev; /* back-pointer to the device */
@ -286,6 +286,86 @@ enum stio_dev_event_t
typedef enum stio_dev_event_t stio_dev_event_t;
/* ========================================================================= */
/* TOOD: move these to a separte file */
#define STIO_ETHHDR_PROTO_IP4 0x0800
#define STIO_ETHHDR_PROTO_ARP 0x0806
#define STIO_ARPHDR_OPCODE_REQUEST 1
#define STIO_ARPHDR_OPCODE_REPLY 2
#define STIO_ARPHDR_HTYPE_ETH 0x0001
#define STIO_ARPHDR_PTYPE_IP4 0x0800
#define STIO_ETHADR_LEN 6
#define STIO_IP4ADR_LEN 4
#define STIO_IP6ADR_LEN 16
#pragma pack(push)
#pragma pack(1)
struct stio_ethadr_t
{
stio_uint8_t v[STIO_ETHADR_LEN];
};
typedef struct stio_ethadr_t stio_ethadr_t;
struct stio_ip4adr_t
{
stio_uint8_t v[STIO_IP4ADR_LEN];
};
typedef struct stio_ip4adr_t stio_ip4adr_t;
struct stio_ip6adr_t
{
stio_uint8_t v[STIO_IP6ADR_LEN];
};
typedef struct stio_ip6adr_t stio_ip6adr_t;
struct stio_ethhdr_t
{
stio_uint8_t dest[STIO_ETHADR_LEN];
stio_uint8_t source[STIO_ETHADR_LEN];
stio_uint16_t proto;
};
typedef struct stio_ethhdr_t stio_ethhdr_t;
struct stio_arphdr_t
{
stio_uint16_t htype; /* hardware type (ethernet: 0x0001) */
stio_uint16_t ptype; /* protocol type (ipv4: 0x0800) */
stio_uint8_t hlen; /* hardware address length (ethernet: 6) */
stio_uint8_t plen; /* protocol address length (ipv4 :4) */
stio_uint16_t opcode; /* operation code */
};
typedef struct stio_arphdr_t stio_arphdr_t;
/* arp payload for ipv4 over ethernet */
struct stio_etharp_t
{
stio_uint8_t sha[STIO_ETHADR_LEN]; /* source hardware address */
stio_uint8_t spa[STIO_IP4ADR_LEN]; /* source protocol address */
stio_uint8_t tha[STIO_ETHADR_LEN]; /* target hardware address */
stio_uint8_t tpa[STIO_IP4ADR_LEN]; /* target protocol address */
};
typedef struct stio_etharp_t stio_etharp_t;
struct stio_etharp_pkt_t
{
stio_ethhdr_t ethhdr;
stio_arphdr_t arphdr;
stio_etharp_t arppld;
};
typedef struct stio_etharp_pkt_t stio_etharp_pkt_t;
#pragma pack(pop)
/* ========================================================================= */
#ifdef __cplusplus
extern "C" {
#endif
@ -366,7 +446,7 @@ STIO_EXPORT int stio_dev_read (
STIO_EXPORT int stio_dev_write (
stio_dev_t* dev,
const void* data,
stio_len_t len,
stio_iolen_t len,
void* wrctx,
const stio_devadr_t* dstadr
);
@ -375,7 +455,7 @@ STIO_EXPORT int stio_dev_write (
STIO_EXPORT int stio_dev_timedwrite (
stio_dev_t* dev,
const void* data,
stio_len_t len,
stio_iolen_t len,
const stio_ntime_t* tmout,
void* wrctx,
const stio_devadr_t* dstadr