[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lwip-users] [lwip] Code Review requested
From: |
David Haas |
Subject: |
[lwip-users] [lwip] Code Review requested |
Date: |
Thu, 09 Jan 2003 00:10:15 -0000 |
This is a multi-part message in MIME format.
------=_NextPart_000_000D_01C2A52C.35B69F20
Content-Type: multipart/alternative;
boundary="----=_NextPart_001_000E_01C2A52C.35B69F20"
------=_NextPart_001_000E_01C2A52C.35B69F20
Content-Type: text/plain;
charset="Windows-1252"
Content-Transfer-Encoding: quoted-printable
Hi,
I have finished coding for a select() function in the sockets interface. =
I have made sure it compiles, but I have not tested it yet. I am =
attaching the changed files with all changes marked by /* *****Added by =
DJH */ or /* *****Changed by DJH */=20
I did not mark the changes in cc.h since that file is specific to my =
architecture. I added the fd_set definitions to it, but I'm not sure if =
this is the right spot.
I would request that some of you take a look at these changes and do =
some code review to make sure I have solved the problem without breaking =
anything obvious and I have not screwed anything up for anyone else. I =
will submit the changes as a patch later when I have tested it.=20
This implementation does not support exceptset.
It does support timeouts.
David Haas
NBS Card Technology
70 Eisenhower Drive,
Paramus, NJ 07652
Voice: 201-845-7373 x183
Fax: 201-845-3337
email: address@hidden
------=_NextPart_001_000E_01C2A52C.35B69F20
Content-Type: text/html;
charset="Windows-1252"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Dwindows-1252">
<META content=3D"MSHTML 6.00.2800.1126" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT size=3D2>Hi,</FONT></DIV>
<DIV><FONT size=3D2></FONT> </DIV>
<DIV><FONT size=3D2>I have finished coding for a select() function in =
the sockets=20
interface. I have made sure it compiles, but I have not tested it yet. I =
am=20
attaching the changed files with all changes marked by /* *****Added by =
DJH */=20
or /* *****Changed by DJH */ </FONT></DIV>
<DIV><FONT size=3D2>I did not mark the changes in cc.h since that file =
is specific=20
to my architecture. I added the fd_set definitions to it, but I'm not =
sure if=20
this is the right spot.</FONT></DIV>
<DIV><FONT size=3D2></FONT> </DIV>
<DIV><FONT size=3D2>I would request that some of you take a look at =
these changes=20
and do some code review to make sure I have solved the problem without =
breaking=20
anything obvious and I have not screwed anything up for anyone else. I =
will=20
submit the changes as a patch later when I have tested it. </FONT></DIV>
<DIV><FONT size=3D2></FONT> </DIV>
<DIV><FONT size=3D2>This implementation does not support =
exceptset.</FONT></DIV>
<DIV><FONT size=3D2></FONT> </DIV>
<DIV><FONT size=3D2>It does support timeouts.</FONT></DIV>
<DIV><FONT size=3D2></FONT> </DIV>
<DIV><FONT size=3D2></FONT> </DIV>
<DIV><FONT size=3D2></FONT> </DIV>
<DIV><FONT size=3D2></FONT> </DIV>
<DIV><FONT size=3D2>David Haas<BR>NBS Card Technology<BR>70 Eisenhower=20
Drive,<BR>Paramus, NJ 07652<BR>Voice: 201-845-7373 x183<BR>Fax:=20
201-845-3337<BR>email: <A=20
href=3D"mailto:address@hidden">address@hidden</A><BR></FONT></DIV><=
/BODY></HTML>
------=_NextPart_001_000E_01C2A52C.35B69F20--
------=_NextPart_000_000D_01C2A52C.35B69F20
Content-Type: application/octet-stream;
name="api_lib.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="api_lib.c"
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.=20
*=20
* Redistribution and use in source and binary forms, with or without =
modification,=20
* 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.
* 3. The name of the author may not be used to endorse or promote =
products
* derived from this software without specific prior written =
permission.=20
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR =
IMPLIED=20
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF=20
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. =
IN NO EVENT=20
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, =
SPECIAL,=20
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, =
PROCUREMENT=20
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR =
BUSINESS=20
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER =
IN=20
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR =
OTHERWISE) ARISING=20
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE =
POSSIBILITY=20
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*=20
* Author: Adam Dunkels <address@hidden>
*
*/
/* This is the part of the API that is linked with
the application */
#include "lwip/debug.h"
#include "lwip/api.h"
#include "lwip/api_msg.h"
#include "lwip/memp.h"
#include "lwip/debug.h"
/*-----------------------------------------------------------------------=
------------*/
struct
netbuf *netbuf_new(void)
{
struct netbuf *buf;
buf =3D memp_mallocp(MEMP_NETBUF);
if(buf !=3D NULL) {
buf->p =3D NULL;
buf->ptr =3D NULL;
return buf;
} else {
return NULL;
}
}
/*-----------------------------------------------------------------------=
------------*/
void
netbuf_delete(struct netbuf *buf)
{
if(buf !=3D NULL) {
if(buf->p !=3D NULL) {
pbuf_free(buf->p);
buf->p =3D buf->ptr =3D NULL;
}
memp_freep(MEMP_NETBUF, buf);
}
}
/*-----------------------------------------------------------------------=
------------*/
void *
netbuf_alloc(struct netbuf *buf, u16_t size)
{
/* Deallocate any previously allocated memory. */
if(buf->p !=3D NULL) {
pbuf_free(buf->p);
}
buf->p =3D pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
if(buf->p =3D=3D NULL) {
return NULL;
}
buf->ptr =3D buf->p;
return buf->p->payload;
}
/*-----------------------------------------------------------------------=
------------*/
void
netbuf_free(struct netbuf *buf)
{
if(buf->p !=3D NULL) {
pbuf_free(buf->p);
}
buf->p =3D buf->ptr =3D NULL;
}
/*-----------------------------------------------------------------------=
------------*/
void
netbuf_ref(struct netbuf *buf, void *dataptr, u16_t size)
{
if(buf->p !=3D NULL) {
pbuf_free(buf->p);
}
buf->p =3D pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_ROM);
buf->p->payload =3D dataptr;
buf->p->len =3D buf->p->tot_len =3D size;
buf->ptr =3D buf->p;
}
/*-----------------------------------------------------------------------=
------------*/
void
netbuf_chain(struct netbuf *head, struct netbuf *tail)
{
pbuf_chain(head->p, tail->p);
head->ptr =3D head->p;
memp_freep(MEMP_NETBUF, tail);
}
/*-----------------------------------------------------------------------=
------------*/
u16_t
netbuf_len(struct netbuf *buf)
{
return buf->p->tot_len;
}
/*-----------------------------------------------------------------------=
------------*/
err_t
netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len)
{
if(buf->ptr =3D=3D NULL) {
return ERR_BUF;
}
*dataptr =3D buf->ptr->payload;
*len =3D buf->ptr->len;
return ERR_OK;
}
/*-----------------------------------------------------------------------=
------------*/
s8_t
netbuf_next(struct netbuf *buf)
{
if(buf->ptr->next =3D=3D NULL) {
return -1;
}
buf->ptr =3D buf->ptr->next;
if(buf->ptr->next =3D=3D NULL) {
return 1;
}
return 0;
}
/*-----------------------------------------------------------------------=
------------*/
void
netbuf_first(struct netbuf *buf)
{
buf->ptr =3D buf->p;
}
/*-----------------------------------------------------------------------=
------------*/
void
netbuf_copy_partial(struct netbuf *buf, void *dataptr, u16_t len, u16_t =
offset)
{
struct pbuf *p;
u16_t i, left;
left =3D 0;
if(buf =3D=3D NULL) {
return;
}
=20
/* This implementation is bad. It should use bcopy
instead. */
for(p =3D buf->p; left < len && p !=3D NULL; p =3D p->next) {
if(offset !=3D 0 && offset >=3D p->len) {
offset -=3D p->len;
} else { =20
for(i =3D offset; i < p->len; ++i) {
((char *)dataptr)[left] =3D ((char *)p->payload)[i];
if(++left >=3D len) {
return;
}
}
offset =3D 0;
}
}
}
/*-----------------------------------------------------------------------=
------------*/
void
netbuf_copy(struct netbuf *buf, void *dataptr, u16_t len)
{
netbuf_copy_partial(buf, dataptr, len, 0);
}
/*-----------------------------------------------------------------------=
------------*/
struct ip_addr *
netbuf_fromaddr(struct netbuf *buf)
{
return buf->fromaddr;
}
/*-----------------------------------------------------------------------=
------------*/
u16_t
netbuf_fromport(struct netbuf *buf)
{
return buf->fromport;
}
/*-----------------------------------------------------------------------=
------------*/
struct
netconn *netconn_new(enum netconn_type t)
{
struct netconn *conn;
conn =3D memp_mallocp(MEMP_NETCONN);
if(conn =3D=3D NULL) {
return NULL;
}
conn->type =3D t;
conn->pcb.tcp =3D NULL;
if((conn->mbox =3D sys_mbox_new()) =3D=3D SYS_MBOX_NULL) {
memp_freep(MEMP_NETCONN, conn);
return NULL;
}
conn->recvmbox =3D SYS_MBOX_NULL;
conn->acceptmbox =3D SYS_MBOX_NULL;
conn->sem =3D SYS_SEM_NULL;
conn->state =3D NETCONN_NONE;
/* *****Added by DJH */
conn->socket =3D 0;
conn->callback =3D 0;
/* ***** */
return conn;
}
/* *****Added by DJH */
/*-----------------------------------------------------------------------=
------------*/
struct
netconn *netconn_new_with_callback(enum netconn_type t,
void (*callback)(struct netconn *, =
enum netconn_evt))
{
struct netconn *conn;
=20
/* get a netconn and then initialize callback pointer and socket */
conn =3D netconn_new(t);
if (conn)
conn->callback =3D callback;
return conn;
}
/* ***** */
/*-----------------------------------------------------------------------=
------------*/
err_t
netconn_delete(struct netconn *conn)
{
struct api_msg *msg;
void *mem;
=20
if(conn =3D=3D NULL) {
return ERR_OK;
}
=20
if((msg =3D memp_mallocp(MEMP_API_MSG)) =3D=3D NULL) {
return ERR_MEM;
}
=20
msg->type =3D API_MSG_DELCONN;
msg->msg.conn =3D conn;
api_msg_post(msg); =20
sys_mbox_fetch(conn->mbox, NULL);
memp_freep(MEMP_API_MSG, msg);
/* Drain the recvmbox. */
if(conn->recvmbox !=3D SYS_MBOX_NULL) {
while(sys_arch_mbox_fetch(conn->recvmbox, &mem, 1) !=3D 0) {
if(conn->type =3D=3D NETCONN_TCP) {
pbuf_free((struct pbuf *)mem);
} else {
netbuf_delete((struct netbuf *)mem);
}
}
sys_mbox_free(conn->recvmbox);
conn->recvmbox =3D SYS_MBOX_NULL;
}
=20
/* Drain the acceptmbox. */
if(conn->acceptmbox !=3D SYS_MBOX_NULL) {
while(sys_arch_mbox_fetch(conn->acceptmbox, &mem, 1) !=3D 0) {
netconn_delete((struct netconn *)mem);
}
=20
sys_mbox_free(conn->acceptmbox);
conn->acceptmbox =3D SYS_MBOX_NULL;
}
sys_mbox_free(conn->mbox);
conn->mbox =3D SYS_MBOX_NULL;
if(conn->sem !=3D SYS_SEM_NULL) {
sys_sem_free(conn->sem);
}
/* conn->sem =3D SYS_SEM_NULL;*/
memp_free(MEMP_NETCONN, conn);
return ERR_OK;
}
/*-----------------------------------------------------------------------=
------------*/
enum netconn_type
netconn_type(struct netconn *conn)
{
return conn->type;
}
/*-----------------------------------------------------------------------=
------------*/
err_t
netconn_peer(struct netconn *conn, struct ip_addr **addr,
u16_t *port)
{
switch(conn->type) {
case NETCONN_UDPLITE:
case NETCONN_UDPNOCHKSUM:
case NETCONN_UDP:
*addr =3D &(conn->pcb.udp->remote_ip);
*port =3D conn->pcb.udp->remote_port;
break;
case NETCONN_TCP:
*addr =3D &(conn->pcb.tcp->remote_ip);
*port =3D conn->pcb.tcp->remote_port;
break;
}
return (conn->err =3D ERR_OK);
}
/*-----------------------------------------------------------------------=
------------*/
err_t
netconn_addr(struct netconn *conn, struct ip_addr **addr,
u16_t *port)
{
switch(conn->type) {
case NETCONN_UDPLITE:
case NETCONN_UDPNOCHKSUM:
case NETCONN_UDP:
*addr =3D &(conn->pcb.udp->local_ip);
*port =3D conn->pcb.udp->local_port;
break;
case NETCONN_TCP:
*addr =3D &(conn->pcb.tcp->local_ip);
*port =3D conn->pcb.tcp->local_port;
break;
}
return (conn->err =3D ERR_OK);
}
/*-----------------------------------------------------------------------=
------------*/
err_t
netconn_bind(struct netconn *conn, struct ip_addr *addr,
u16_t port)
{
struct api_msg *msg;
if(conn =3D=3D NULL) {
return ERR_VAL;
}
if(conn->type !=3D NETCONN_TCP &&
conn->recvmbox =3D=3D SYS_MBOX_NULL) {
if((conn->recvmbox =3D sys_mbox_new()) =3D=3D SYS_MBOX_NULL) {
return ERR_MEM;
}
}
=20
if((msg =3D memp_mallocp(MEMP_API_MSG)) =3D=3D NULL) {
return (conn->err =3D ERR_MEM);
}
msg->type =3D API_MSG_BIND;
msg->msg.conn =3D conn;
msg->msg.msg.bc.ipaddr =3D addr;
msg->msg.msg.bc.port =3D port;
api_msg_post(msg);
sys_mbox_fetch(conn->mbox, NULL);
memp_freep(MEMP_API_MSG, msg);
return conn->err;
}
/*-----------------------------------------------------------------------=
------------*/
err_t
netconn_connect(struct netconn *conn, struct ip_addr *addr,
u16_t port)
{
struct api_msg *msg;
=20
if(conn =3D=3D NULL) {
return ERR_VAL;
}
if(conn->recvmbox =3D=3D SYS_MBOX_NULL) {
if((conn->recvmbox =3D sys_mbox_new()) =3D=3D SYS_MBOX_NULL) {
return ERR_MEM;
}
}
=20
if((msg =3D memp_mallocp(MEMP_API_MSG)) =3D=3D NULL) {
return ERR_MEM;
}
msg->type =3D API_MSG_CONNECT;
msg->msg.conn =3D conn; =20
msg->msg.msg.bc.ipaddr =3D addr;
msg->msg.msg.bc.port =3D port;
api_msg_post(msg);
sys_mbox_fetch(conn->mbox, NULL);
memp_freep(MEMP_API_MSG, msg);
return conn->err;
}
/*-----------------------------------------------------------------------=
------------*/
err_t
netconn_listen(struct netconn *conn)
{
struct api_msg *msg;
if(conn =3D=3D NULL) {
return ERR_VAL;
}
if(conn->acceptmbox =3D=3D SYS_MBOX_NULL) {
conn->acceptmbox =3D sys_mbox_new();
if(conn->acceptmbox =3D=3D SYS_MBOX_NULL) {
return ERR_MEM;
}
}
=20
if((msg =3D memp_mallocp(MEMP_API_MSG)) =3D=3D NULL) {
return (conn->err =3D ERR_MEM);
}
msg->type =3D API_MSG_LISTEN;
msg->msg.conn =3D conn;
api_msg_post(msg);
sys_mbox_fetch(conn->mbox, NULL);
memp_freep(MEMP_API_MSG, msg);
return conn->err;
}
/*-----------------------------------------------------------------------=
------------*/
struct netconn *
netconn_accept(struct netconn *conn)
{
struct netconn *newconn;
=20
if(conn =3D=3D NULL) {
return NULL;
}
=20
sys_mbox_fetch(conn->acceptmbox, (void **)&newconn);
/* *****Added by DJH */
/* Register event with callback */
if (conn->callback)
(*conn->callback)(conn, NETCONN_EVT_RCVMINUS);
/* ***** */
=20
return newconn;
}
/*-----------------------------------------------------------------------=
------------*/
struct netbuf *
netconn_recv(struct netconn *conn)
{
struct api_msg *msg;
struct netbuf *buf;
struct pbuf *p;
=20
if(conn =3D=3D NULL) {
return NULL;
}
=20
if(conn->recvmbox =3D=3D SYS_MBOX_NULL) {
conn->err =3D ERR_CONN;
return NULL;
}
if(conn->err !=3D ERR_OK) {
return NULL;
}
if(conn->type =3D=3D NETCONN_TCP) {
if(conn->pcb.tcp->state =3D=3D LISTEN) {
conn->err =3D ERR_CONN;
return NULL;
}
buf =3D memp_mallocp(MEMP_NETBUF);
if(buf =3D=3D NULL) {
conn->err =3D ERR_MEM;
return NULL;
}
=20
sys_mbox_fetch(conn->recvmbox, (void **)&p);
/* *****Added by DJH */
/* Register event with callback */
if (conn->callback)
(*conn->callback)(conn, NETCONN_EVT_RCVMINUS);
/* ***** */
/* If we are closed, we indicate that we no longer wish to recieve
data by setting conn->recvmbox to SYS_MBOX_NULL. */
if(p =3D=3D NULL) {
memp_freep(MEMP_NETBUF, buf);
sys_mbox_free(conn->recvmbox);
conn->recvmbox =3D SYS_MBOX_NULL;
return NULL;
}
buf->p =3D p;
buf->ptr =3D p;
buf->fromport =3D 0;
buf->fromaddr =3D NULL;
/* Let the stack know that we have taken the data. */
if((msg =3D memp_mallocp(MEMP_API_MSG)) =3D=3D NULL) {
conn->err =3D ERR_MEM;
return buf;
}
msg->type =3D API_MSG_RECV;
msg->msg.conn =3D conn;
if(buf !=3D NULL) {
msg->msg.msg.len =3D buf->p->tot_len;
} else {
msg->msg.msg.len =3D 1;
}
api_msg_post(msg);
sys_mbox_fetch(conn->mbox, NULL);
memp_freep(MEMP_API_MSG, msg);
} else {
sys_mbox_fetch(conn->recvmbox, (void **)&buf);
/* *****Added by DJH */
/* Register event with callback */
if (conn->callback)
(*conn->callback)(conn, NETCONN_EVT_RCVMINUS);
/* ***** */
}
=20
=20
DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p (err %d)\n", buf, =
conn->err));
return buf;
}
/*-----------------------------------------------------------------------=
------------*/
err_t
netconn_send(struct netconn *conn, struct netbuf *buf)
{
struct api_msg *msg;
if(conn =3D=3D NULL) {
return ERR_VAL;
}
if(conn->err !=3D ERR_OK) {
return conn->err;
}
if((msg =3D memp_mallocp(MEMP_API_MSG)) =3D=3D NULL) {
return (conn->err =3D ERR_MEM);
}
DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %d bytes\n", =
buf->p->tot_len));
msg->type =3D API_MSG_SEND;
msg->msg.conn =3D conn;
msg->msg.msg.p =3D buf->p;
api_msg_post(msg);
sys_mbox_fetch(conn->mbox, NULL);
memp_freep(MEMP_API_MSG, msg);
return conn->err;
}
/*-----------------------------------------------------------------------=
------------*/
err_t
netconn_write(struct netconn *conn, void *dataptr, u16_t size, u8_t =
copy)
{
struct api_msg *msg;
u16_t len;
=20
if(conn =3D=3D NULL) {
return ERR_VAL;
}
if(conn->err !=3D ERR_OK) {
return conn->err;
}
=20
if(conn->sem =3D=3D SYS_SEM_NULL) {
conn->sem =3D sys_sem_new(0);
if(conn->sem =3D=3D SYS_SEM_NULL) {
return ERR_MEM;
}
}
if((msg =3D memp_mallocp(MEMP_API_MSG)) =3D=3D NULL) {
return (conn->err =3D ERR_MEM);
}
msg->type =3D API_MSG_WRITE;
msg->msg.conn =3D conn;
=20
conn->state =3D NETCONN_WRITE;
while(conn->err =3D=3D ERR_OK && size > 0) {
msg->msg.msg.w.dataptr =3D dataptr;
msg->msg.msg.w.copy =3D copy;
=20
if(conn->type =3D=3D NETCONN_TCP) {
if(tcp_sndbuf(conn->pcb.tcp) =3D=3D 0) {
sys_sem_wait(conn->sem);
if(conn->err !=3D ERR_OK) {
goto ret;
}
}
if(size > tcp_sndbuf(conn->pcb.tcp)) {
/* We cannot send more than one send buffer's worth of data at a
time. */
len =3D tcp_sndbuf(conn->pcb.tcp);
} else {
len =3D size;
}
} else {
len =3D size;
}
=20
DEBUGF(API_LIB_DEBUG, ("netconn_write: writing %d bytes (%d)\n", =
len, copy));
msg->msg.msg.w.len =3D len;
api_msg_post(msg);
sys_mbox_fetch(conn->mbox, NULL); =20
if(conn->err =3D=3D ERR_OK) {
dataptr =3D (void *)((char *)dataptr + len);
size -=3D len;
} else if(conn->err =3D=3D ERR_MEM) {
conn->err =3D ERR_OK;
sys_sem_wait(conn->sem);
} else {
goto ret;
}
}
ret:
memp_freep(MEMP_API_MSG, msg);
conn->state =3D NETCONN_NONE;
if(conn->sem !=3D SYS_SEM_NULL) {
sys_sem_free(conn->sem);
conn->sem =3D SYS_SEM_NULL;
}
/* *****Added by DJH */
if (conn->callback)
if (conn->type =3D=3D NETCONN_TCP && conn->err =3D=3D ERR_OK)
{
if (tcp_sndbuf(conn->pcb.tcp) <=3D TCP_SNDLOWAT)
(*conn->callback)(conn, NETCONN_EVT_SENDMINUS);
}
/* ***** */
=20
return conn->err;
}
/*-----------------------------------------------------------------------=
------------*/
err_t
netconn_close(struct netconn *conn)
{
struct api_msg *msg;
if(conn =3D=3D NULL) {
return ERR_VAL;
}
if((msg =3D memp_mallocp(MEMP_API_MSG)) =3D=3D NULL) {
return (conn->err =3D ERR_MEM);
}
conn->state =3D NETCONN_CLOSE;
again:
msg->type =3D API_MSG_CLOSE;
msg->msg.conn =3D conn;
api_msg_post(msg);
sys_mbox_fetch(conn->mbox, NULL);
if(conn->err =3D=3D ERR_MEM &&
conn->sem !=3D SYS_SEM_NULL) {
sys_sem_wait(conn->sem);
goto again;
}
conn->state =3D NETCONN_NONE;
memp_freep(MEMP_API_MSG, msg);
return conn->err;
}
/*-----------------------------------------------------------------------=
------------*/
err_t
netconn_err(struct netconn *conn)
{
return conn->err;
}
/*-----------------------------------------------------------------------=
------------*/
------=_NextPart_000_000D_01C2A52C.35B69F20
Content-Type: application/octet-stream;
name="api_msg.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="api_msg.c"
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.=20
*=20
* Redistribution and use in source and binary forms, with or without =
modification,=20
* 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.
* 3. The name of the author may not be used to endorse or promote =
products
* derived from this software without specific prior written =
permission.=20
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR =
IMPLIED=20
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF=20
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. =
IN NO EVENT=20
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, =
SPECIAL,=20
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, =
PROCUREMENT=20
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR =
BUSINESS=20
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER =
IN=20
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR =
OTHERWISE) ARISING=20
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE =
POSSIBILITY=20
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*=20
* Author: Adam Dunkels <address@hidden>
*
*/
#include "lwip/debug.h"
#include "lwip/arch.h"
#include "lwip/api_msg.h"
#include "lwip/memp.h"
#include "lwip/sys.h"
#include "lwip/tcpip.h"
/*-----------------------------------------------------------------------=
------------*/
static err_t
recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
struct netconn *conn;
conn =3D arg;
if(conn =3D=3D NULL) {
pbuf_free(p);
return ERR_VAL;
}
if(conn->recvmbox !=3D SYS_MBOX_NULL) {
conn->err =3D err;
/* *****Added by DJH */
/* Register event with callback */
if (conn->callback)
(*conn->callback)(conn, NETCONN_EVT_RCVPLUS);
/* ***** */
sys_mbox_post(conn->recvmbox, p);
} =20
return ERR_OK;
}
/*-----------------------------------------------------------------------=
------------*/
#if LWIP_UDP
static void
recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
struct ip_addr *addr, u16_t port)
{
struct netbuf *buf;
struct netconn *conn;
conn =3D arg;
=20
if(conn =3D=3D NULL) {
pbuf_free(p);
return;
}
if(conn->recvmbox !=3D SYS_MBOX_NULL) {
buf =3D memp_mallocp(MEMP_NETBUF);
if(buf =3D=3D NULL) {
pbuf_free(p);
return;
} else {
buf->p =3D p;
buf->ptr =3D p;
buf->fromaddr =3D addr;
buf->fromport =3D port;
}
/* *****Added by DJH */
/* Register event with callback */
if (conn->callback)
(*conn->callback)(conn, NETCONN_EVT_RCVPLUS);
/* ***** */
sys_mbox_post(conn->recvmbox, buf);
}
}
#endif /* LWIP_UDP */
/*-----------------------------------------------------------------------=
------------*/
static err_t
poll_tcp(void *arg, struct tcp_pcb *pcb)
{
struct netconn *conn;
conn =3D arg;
if(conn !=3D NULL &&
(conn->state =3D=3D NETCONN_WRITE || conn->state =3D=3D =
NETCONN_CLOSE) &&
conn->sem !=3D SYS_SEM_NULL) {
sys_sem_signal(conn->sem);
}
return ERR_OK;
}
/*-----------------------------------------------------------------------=
------------*/
static err_t
sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
{
struct netconn *conn;
conn =3D arg;
if(conn !=3D NULL && conn->sem !=3D SYS_SEM_NULL) {
sys_sem_signal(conn->sem);
}
/* *****Added by DJH */
if (conn && conn->callback)
if (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT)
(*conn->callback)(conn, NETCONN_EVT_SENDPLUS);
/* ***** */
=20
return ERR_OK;
}
/*-----------------------------------------------------------------------=
------------*/
static void
err_tcp(void *arg, err_t err)
{
struct netconn *conn;
conn =3D arg;
conn->pcb.tcp =3D NULL;
=20
conn->err =3D err;
if(conn->recvmbox !=3D SYS_MBOX_NULL) {
/* *****Added by DJH */
/* Register event with callback */
if (conn->callback)
(*conn->callback)(conn, NETCONN_EVT_RCVPLUS);
/* ***** */
sys_mbox_post(conn->recvmbox, NULL);
}
if(conn->mbox !=3D SYS_MBOX_NULL) {
sys_mbox_post(conn->mbox, NULL);
}
if(conn->acceptmbox !=3D SYS_MBOX_NULL) {
/* *****Added by DJH */
/* Register event with callback */
if (conn->callback)
(*conn->callback)(conn, NETCONN_EVT_RCVPLUS);
/* ***** */
sys_mbox_post(conn->acceptmbox, NULL);
}
if(conn->sem !=3D SYS_SEM_NULL) {
sys_sem_signal(conn->sem);
}
}
/*-----------------------------------------------------------------------=
------------*/
static void
setup_tcp(struct netconn *conn)
{
struct tcp_pcb *pcb;
=20
pcb =3D conn->pcb.tcp;
tcp_arg(pcb, conn);
tcp_recv(pcb, recv_tcp);
tcp_sent(pcb, sent_tcp);
tcp_poll(pcb, poll_tcp, 4);
tcp_err(pcb, err_tcp);
}
/*-----------------------------------------------------------------------=
------------*/
static err_t
accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
{
/* *****Changed by DJH */
sys_mbox_t mbox;
/* ***** */
struct netconn *newconn;
/* *****Added by DJH */
struct netconn *conn;
/* ***** */
=20
#if API_MSG_DEBUG
#if TCP_DEBUG
tcp_debug_print_state(newpcb->state);
#endif /* TCP_DEBUG */
#endif /* API_MSG_DEBUG */
/* *****Changed by DJH */
conn =3D (struct netconn *)arg;
mbox =3D conn->acceptmbox;
/* ***** */
newconn =3D memp_mallocp(MEMP_NETCONN);
if(newconn =3D=3D NULL) {
return ERR_MEM;
}
newconn->type =3D NETCONN_TCP;
newconn->pcb.tcp =3D newpcb;
setup_tcp(newconn);
newconn->recvmbox =3D sys_mbox_new();
if(newconn->recvmbox =3D=3D SYS_MBOX_NULL) {
memp_free(MEMP_NETCONN, newconn);
return ERR_MEM;
}
newconn->mbox =3D sys_mbox_new();
if(newconn->mbox =3D=3D SYS_MBOX_NULL) {
sys_mbox_free(newconn->recvmbox);
memp_free(MEMP_NETCONN, newconn);
return ERR_MEM;
}
newconn->sem =3D sys_sem_new(0);
if(newconn->sem =3D=3D SYS_SEM_NULL) {
sys_mbox_free(newconn->recvmbox);
sys_mbox_free(newconn->mbox);
memp_free(MEMP_NETCONN, newconn);
return ERR_MEM;
}
newconn->acceptmbox =3D SYS_MBOX_NULL;
newconn->err =3D err;
/* *****Added by DJH */
/* Register event with callback */
if (conn->callback)
(*conn->callback)(conn, NETCONN_EVT_RCVPLUS);
/* ***** */
/* *****Changed by DJH */
sys_mbox_post(mbox, newconn);
/* ***** */
return ERR_OK;
}
/*-----------------------------------------------------------------------=
------------*/
static void
do_newconn(struct api_msg_msg *msg)
{
}
/*-----------------------------------------------------------------------=
------------*/
static void
do_delconn(struct api_msg_msg *msg)
{
if(msg->conn->pcb.tcp !=3D NULL) {
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP:
msg->conn->pcb.udp->recv_arg =3D NULL;
udp_remove(msg->conn->pcb.udp);
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
if(msg->conn->pcb.tcp->state =3D=3D LISTEN) {
tcp_accept(msg->conn->pcb.tcp, NULL);=09
tcp_close(msg->conn->pcb.tcp);
} else {
tcp_arg(msg->conn->pcb.tcp, NULL);
tcp_sent(msg->conn->pcb.tcp, NULL);
tcp_recv(msg->conn->pcb.tcp, NULL);=09
tcp_poll(msg->conn->pcb.tcp, NULL, 0);
tcp_err(msg->conn->pcb.tcp, NULL);
if(tcp_close(msg->conn->pcb.tcp) !=3D ERR_OK) {
tcp_abort(msg->conn->pcb.tcp);
}
}
break;
}
}
if(msg->conn->mbox !=3D SYS_MBOX_NULL) {
sys_mbox_post(msg->conn->mbox, NULL);
}
}
/*-----------------------------------------------------------------------=
------------*/
static void
do_bind(struct api_msg_msg *msg)
{
if(msg->conn->pcb.tcp =3D=3D NULL) {
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
msg->conn->pcb.udp =3D udp_new();
udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
break;
case NETCONN_UDPNOCHKSUM:
msg->conn->pcb.udp =3D udp_new();
udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
break;
case NETCONN_UDP:
msg->conn->pcb.udp =3D udp_new();
udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
msg->conn->pcb.tcp =3D tcp_new();
setup_tcp(msg->conn);
break;
}
}
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP:
udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
msg->conn->err =3D tcp_bind(msg->conn->pcb.tcp,
msg->msg.bc.ipaddr, msg->msg.bc.port);
break;
}
sys_mbox_post(msg->conn->mbox, NULL);
}
/*-----------------------------------------------------------------------=
------------*/
static err_t
do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
{
struct netconn *conn;
conn =3D arg;
if(conn =3D=3D NULL) {
return ERR_VAL;
}
=20
conn->err =3D err;
if(conn->type =3D=3D NETCONN_TCP && err =3D=3D ERR_OK) {
setup_tcp(conn);
} =20
=20
sys_mbox_post(conn->mbox, NULL);
return ERR_OK;
}
/*-----------------------------------------------------------------------=
------------*/
static void
do_connect(struct api_msg_msg *msg)
{
if(msg->conn->pcb.tcp =3D=3D NULL) {
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
msg->conn->pcb.udp =3D udp_new();
if(msg->conn->pcb.udp =3D=3D NULL) {
msg->conn->err =3D ERR_MEM;
sys_mbox_post(msg->conn->mbox, NULL);
return;
}
udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
break;
case NETCONN_UDPNOCHKSUM:
msg->conn->pcb.udp =3D udp_new();
if(msg->conn->pcb.udp =3D=3D NULL) {
msg->conn->err =3D ERR_MEM;
sys_mbox_post(msg->conn->mbox, NULL);
return;
}
udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
break;
case NETCONN_UDP:
msg->conn->pcb.udp =3D udp_new();
if(msg->conn->pcb.udp =3D=3D NULL) {
msg->conn->err =3D ERR_MEM;
sys_mbox_post(msg->conn->mbox, NULL);
return;
}
udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
msg->conn->pcb.tcp =3D tcp_new(); =20
if(msg->conn->pcb.tcp =3D=3D NULL) {
msg->conn->err =3D ERR_MEM;
sys_mbox_post(msg->conn->mbox, NULL);
return;
}
break;
}
}
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP:
udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, =
msg->msg.bc.port);
sys_mbox_post(msg->conn->mbox, NULL);
break;
#endif=20
case NETCONN_TCP:
/* tcp_arg(msg->conn->pcb.tcp, msg->conn);*/
setup_tcp(msg->conn);
tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, =
msg->msg.bc.port,
do_connected);
/*tcp_output(msg->conn->pcb.tcp);*/
break;
}
}
/*-----------------------------------------------------------------------=
------------*/
static void
do_listen(struct api_msg_msg *msg)
{
if(msg->conn->pcb.tcp !=3D NULL) {
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP:
DEBUGF(API_MSG_DEBUG, ("api_msg: listen UDP: cannot listen for =
UDP.\n"));
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
msg->conn->pcb.tcp =3D tcp_listen(msg->conn->pcb.tcp);
if(msg->conn->pcb.tcp =3D=3D NULL) {
msg->conn->err =3D ERR_MEM;
} else {
if(msg->conn->acceptmbox =3D=3D SYS_MBOX_NULL) {
msg->conn->acceptmbox =3D sys_mbox_new();
if(msg->conn->acceptmbox =3D=3D SYS_MBOX_NULL) {
msg->conn->err =3D ERR_MEM;
break;
}
}
tcp_arg(msg->conn->pcb.tcp, (void *)&(msg->conn->acceptmbox));
tcp_accept(msg->conn->pcb.tcp, accept_function);
}
break;
}
}
sys_mbox_post(msg->conn->mbox, NULL);
}
/*-----------------------------------------------------------------------=
------------*/
static void
do_accept(struct api_msg_msg *msg)
{
if(msg->conn->pcb.tcp !=3D NULL) {
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP: =20
DEBUGF(API_MSG_DEBUG, ("api_msg: accept UDP: cannot accept for =
UDP.\n"));
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
break;
}
}
}
/*-----------------------------------------------------------------------=
------------*/
static void
do_send(struct api_msg_msg *msg)
{
if(msg->conn->pcb.tcp !=3D NULL) {
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP:
udp_send(msg->conn->pcb.udp, msg->msg.p);
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
break;
}
}
sys_mbox_post(msg->conn->mbox, NULL);
}
/*-----------------------------------------------------------------------=
------------*/
static void
do_recv(struct api_msg_msg *msg)
{
if(msg->conn->pcb.tcp !=3D NULL) {
if(msg->conn->type =3D=3D NETCONN_TCP) {
tcp_recved(msg->conn->pcb.tcp, msg->msg.len);
}
}
sys_mbox_post(msg->conn->mbox, NULL);
}
/*-----------------------------------------------------------------------=
------------*/
static void
do_write(struct api_msg_msg *msg)
{
err_t err;
if(msg->conn->pcb.tcp !=3D NULL) {
switch(msg->conn->type) {
#if LWIP_UDP=20
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP:
msg->conn->err =3D ERR_VAL;
break;
#endif /* LWIP_UDP */
case NETCONN_TCP: =20
err =3D tcp_write(msg->conn->pcb.tcp, msg->msg.w.dataptr,
msg->msg.w.len, msg->msg.w.copy);
/* This is the Nagle algorithm: inhibit the sending of new TCP
segments when new outgoing data arrives from the user if any
previously transmitted data on the connection remains
unacknowledged. */
if(err =3D=3D ERR_OK && msg->conn->pcb.tcp->unacked =3D=3D NULL) {
tcp_output(msg->conn->pcb.tcp);
}
msg->conn->err =3D err;
break;
}
}
sys_mbox_post(msg->conn->mbox, NULL);
}
/*-----------------------------------------------------------------------=
------------*/
static void
do_close(struct api_msg_msg *msg)
{
err_t err;
err =3D ERR_OK;
if(msg->conn->pcb.tcp !=3D NULL) {
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP:
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
if(msg->conn->pcb.tcp->state =3D=3D LISTEN) {
err =3D tcp_close(msg->conn->pcb.tcp);
}
msg->conn->err =3D err; =20
break;
}
}
sys_mbox_post(msg->conn->mbox, NULL);
}
/*-----------------------------------------------------------------------=
------------*/
typedef void (* api_msg_decode)(struct api_msg_msg *msg);
static api_msg_decode decode[API_MSG_MAX] =3D {
do_newconn,
do_delconn,
do_bind,
do_connect,
do_listen,
do_accept,
do_send,
do_recv,
do_write,
do_close
};
void
api_msg_input(struct api_msg *msg)
{ =20
decode[msg->type](&(msg->msg));
}
/*-----------------------------------------------------------------------=
------------*/
void
api_msg_post(struct api_msg *msg)
{
tcpip_apimsg(msg);
}
/*-----------------------------------------------------------------------=
------------*/
------=_NextPart_000_000D_01C2A52C.35B69F20
Content-Type: application/octet-stream;
name="sockets.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="sockets.c"
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.=20
*=20
* Redistribution and use in source and binary forms, with or without =
modification,=20
* 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.
* 3. The name of the author may not be used to endorse or promote =
products
* derived from this software without specific prior written =
permission.=20
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR =
IMPLIED=20
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF=20
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. =
IN NO EVENT=20
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, =
SPECIAL,=20
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, =
PROCUREMENT=20
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR =
BUSINESS=20
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER =
IN=20
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR =
OTHERWISE) ARISING=20
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE =
POSSIBILITY=20
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*=20
* Author: Adam Dunkels <address@hidden>
*
*/
#include "lwip/debug.h"
#include "lwip/api.h"
#include "lwip/sockets.h"
#define NUM_SOCKETS 10
struct lwip_socket {
struct netconn *conn;
struct netbuf *lastdata;
u16_t lastoffset;
/* *****Added by DJH */
u16_t rcvevent;
u16_t sendevent;
/* ***** */
};
/* *****Added by DJH */
struct lwip_select_cb=20
{
struct lwip_select_cb *next;
fd_set *readset;
fd_set *writeset;
fd_set *exceptset;
int sem_signalled;
sys_sem_t sem;
};
/* ***** */
static struct lwip_socket sockets[NUM_SOCKETS];
/* *****Added by DJH */
static struct lwip_select_cb *select_cb_list =3D 0;
static sys_sem_t socksem =3D 0;
static void
event_callback(struct netconn *conn, enum netconn_evt evt);
/* ***** */
/*-----------------------------------------------------------------------=
------------*/
static struct lwip_socket *
get_socket(int s)
{
struct lwip_socket *sock;
=20
if(s > NUM_SOCKETS) {
/* errno =3D EBADF; */
return NULL;
}
=20
sock =3D &sockets[s];
if(sock->conn =3D=3D NULL) {
/* errno =3D EBADF; */
return NULL;
}
return sock;
}
/*-----------------------------------------------------------------------=
------------*/
static int
alloc_socket(struct netconn *newconn)
{
int i;
/* *****Added by DJH */
if (!socksem)
socksem =3D sys_sem_new(1);
/* Protect socket array */
sys_sem_wait(socksem);
/* ***** */
=20
/* allocate a new socket identifier */
for(i =3D 0; i < NUM_SOCKETS; ++i) {
if(sockets[i].conn =3D=3D NULL) {
sockets[i].conn =3D newconn;
sockets[i].lastdata =3D NULL;
sockets[i].lastoffset =3D 0;
/* *****Added by DJH */
sockets[i].rcvevent =3D 0;
sockets[i].sendevent =3D 1; /* TCP send buf is empty */
sys_sem_signal(socksem);
/* ***** */
return i;
}
}
/* *****Added by DJH */
sys_sem_signal(socksem);
/* ***** */
return -1;
}
/*-----------------------------------------------------------------------=
------------*/
int
lwip_accept(int s, struct sockaddr *addr, int *addrlen)
{
struct lwip_socket *sock;
struct netconn *newconn;
struct ip_addr *naddr;
u16_t port;
int newsock;
sock =3D get_socket(s);
if(sock =3D=3D NULL) {
return -1;
}
=20
newconn =3D netconn_accept(sock->conn);
=20
/* get the IP address and port of the remote host */
netconn_peer(newconn, &naddr, &port);
=20
((struct sockaddr_in *)addr)->sin_addr.s_addr =3D naddr->addr;
((struct sockaddr_in *)addr)->sin_port =3D port;
newsock =3D alloc_socket(newconn);
if(newsock =3D=3D -1) { =20
netconn_delete(newconn);
/* errno =3D ENOBUFS; */
}
return newsock;
}
/*-----------------------------------------------------------------------=
------------*/
int
lwip_bind(int s, struct sockaddr *name, int namelen)
{
struct lwip_socket *sock;
struct ip_addr remote_addr;
u16_t remote_port;
err_t err;
=20
sock =3D get_socket(s);
if(sock =3D=3D NULL) {
return -1;
}
=20
remote_addr.addr =3D ((struct sockaddr_in *)name)->sin_addr.s_addr;
remote_port =3D ((struct sockaddr_in *)name)->sin_port;
=20
err =3D netconn_bind(sock->conn, &remote_addr, ntohs(remote_port));
if(err !=3D ERR_OK) {
/* errno =3D ... */
return -1;
}
return 0;
}
/*-----------------------------------------------------------------------=
------------*/
int
lwip_close(int s)
{
struct lwip_socket *sock;
=20
DEBUGF(SOCKETS_DEBUG, ("close: socket %d\n", s));
sock =3D get_socket(s);
if(sock =3D=3D NULL) {
return -1;
}
=20
=20
netconn_delete(sock->conn);
if(sock->lastdata !=3D NULL) {
netbuf_delete(sock->lastdata);
}
sock->lastdata =3D NULL;
sock->lastoffset =3D 0;
sock->conn =3D NULL;
return 0;
}
/*-----------------------------------------------------------------------=
------------*/
int
lwip_connect(int s, struct sockaddr *name, int namelen)
{
struct lwip_socket *sock;
struct ip_addr remote_addr;
u16_t remote_port;
err_t err;
sock =3D get_socket(s);
if(sock =3D=3D NULL) {
return -1;
}
=20
remote_addr.addr =3D ((struct sockaddr_in *)name)->sin_addr.s_addr;
remote_port =3D ((struct sockaddr_in *)name)->sin_port;
=20
err =3D netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
if(err !=3D ERR_OK) {
/* errno =3D ... */
return -1;
}
return 0;
}
/*-----------------------------------------------------------------------=
------------*/
int
lwip_listen(int s, int backlog)
{
struct lwip_socket *sock; =20
err_t err;
=20
sock =3D get_socket(s);
if(sock =3D=3D NULL) {
return -1;
}
=20
err =3D netconn_listen(sock->conn);
if(err !=3D ERR_OK) {
/* errno =3D ... */
return -1;
}
return 0;
}
/*-----------------------------------------------------------------------=
------------*/
int
lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
struct sockaddr *from, int *fromlen)
{
struct lwip_socket *sock;
struct netbuf *buf;
u16_t buflen, copylen;
struct ip_addr *addr;
u16_t port;
=20
sock =3D get_socket(s);
if(sock =3D=3D NULL) {
return -1;
}
/* Check if there is data left from the last recv operation. */
if(sock->lastdata !=3D NULL) { =20
buf =3D sock->lastdata;
} else {
/* No data was left from the previous operation, so we try to get
some from the network. */
buf =3D netconn_recv(sock->conn);
=20
if(buf =3D=3D NULL) {
/* We should really do some error checking here. */
return 0;
}
}
=20
buflen =3D netbuf_len(buf);
buflen -=3D sock->lastoffset;
=20
if(len > buflen) {
copylen =3D buflen;
} else {
copylen =3D len;
}
=20
/* copy the contents of the received buffer into
the supplied memory pointer mem */
netbuf_copy_partial(buf, mem, copylen, sock->lastoffset);
/* If this is a TCP socket, check if there is data left in the
buffer. If so, it should be saved in the sock structure for next
time around. */
if(netconn_type(sock->conn) =3D=3D NETCONN_TCP && buflen - copylen > =
0) {
sock->lastdata =3D buf;
sock->lastoffset +=3D copylen;
} else {
sock->lastdata =3D NULL;
sock->lastoffset =3D 0;
netbuf_delete(buf);
}
/* Check to see from where the data was. */
if(from !=3D NULL && fromlen !=3D NULL) {
addr =3D netbuf_fromaddr(buf);
port =3D netbuf_fromport(buf); =20
((struct sockaddr_in *)from)->sin_addr.s_addr =3D addr->addr;
((struct sockaddr_in *)from)->sin_port =3D port;
*fromlen =3D sizeof(struct sockaddr_in);
}
=20
return copylen;
}
/*-----------------------------------------------------------------------=
------------*/
int
lwip_read(int s, void *mem, int len)
{
return lwip_recv(s, mem, len, 0);
}
/*-----------------------------------------------------------------------=
------------*/
int
lwip_recv(int s, void *mem, int len, unsigned int flags)
{
return lwip_recvfrom(s, mem, len, flags, NULL, NULL);
}
/*-----------------------------------------------------------------------=
------------*/
int
lwip_send(int s, void *data, int size, unsigned int flags)
{
struct lwip_socket *sock;
struct netbuf *buf;
err_t err;
DEBUGF(SOCKETS_DEBUG, ("send: socket %d, size %d\n", s, size));
sock =3D get_socket(s);
if(sock =3D=3D NULL) {
return -1;
} =20
=20
switch(netconn_type(sock->conn)) {
case NETCONN_UDP:
/* create a buffer */
buf =3D netbuf_new();
if(buf =3D=3D NULL) {
/* errno =3D ENOBUFS; */
return -1;
}
=20
/* make the buffer point to the data that should
be sent */
netbuf_ref(buf, data, size);
/* send the data */
err =3D netconn_send(sock->conn, buf);
/* deallocated the buffer */
netbuf_delete(buf);
break;
case NETCONN_TCP:
err =3D netconn_write(sock->conn, data, size, NETCONN_COPY);
break;
default:
err =3D ERR_ARG;
break;
}
if(err !=3D ERR_OK) {
/* errno =3D ... */
return -1; =20
}
=20
return size;
}
/*-----------------------------------------------------------------------=
------------*/
int
lwip_sendto(int s, void *data, int size, unsigned int flags,
struct sockaddr *to, int tolen)
{
struct lwip_socket *sock;
struct ip_addr remote_addr, *addr;
u16_t remote_port, port;
int ret;
sock =3D get_socket(s);
if(sock =3D=3D NULL) {
return -1;
}
=20
/* get the peer if currently connected */
netconn_peer(sock->conn, &addr, &port);
=20
remote_addr.addr =3D ((struct sockaddr_in *)to)->sin_addr.s_addr;
remote_port =3D ((struct sockaddr_in *)to)->sin_port;
netconn_connect(sock->conn, &remote_addr, remote_port);
=20
ret =3D lwip_send(s, data, size, flags);
/* reset the remote address and port number
of the connection */
netconn_connect(sock->conn, addr, port);
return ret;
}
/*-----------------------------------------------------------------------=
------------*/
int
lwip_socket(int domain, int type, int protocol)
{
struct netconn *conn;
int i;
/* create a netconn */
switch(type) {
case SOCK_DGRAM:
/* *****Changed by DJH */
conn =3D netconn_new_with_callback(NETCONN_UDP, event_callback);
/* ***** */
break;
case SOCK_STREAM:
/* *****Changed by DJH */
conn =3D netconn_new_with_callback(NETCONN_TCP, event_callback);
/* ***** */
break;
default:
/* errno =3D ... */
return -1;
}
if(conn =3D=3D NULL) {
DEBUGF(SOCKETS_DEBUG, ("socket: could not create netconn.\n"));
/* errno =3D ENOBUFS; */
return -1;
}
i =3D alloc_socket(conn);
if(i =3D=3D -1) {
/* errno =3D ENOBUFS; */
netconn_delete(conn);
}
/* *****Added by DJH */
conn->socket =3D i;
/* ***** */
return i;
}
/*-----------------------------------------------------------------------=
------------*/
int
lwip_write(int s, void *data, int size)
{
return lwip_send(s, data, size, 0);
}
/* *****Added by DJH */
/*-----------------------------------------------------------------------=
------------*/
static int
lwip_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set =
*exceptset)
{
int i, nready =3D 0;
fd_set lreadset, lwriteset, lexceptset;
struct lwip_socket *p_sock;
FD_ZERO(&lreadset);
FD_ZERO(&lwriteset);
FD_ZERO(&lexceptset);
=20
/* Go through each socket in each list to count number of sockets =
which
currently match */
for(i =3D 0; i < maxfdp1; i++)
{
if(FD_ISSET(i, readset))
{
/* See if netconn of this socket is ready for read */
p_sock =3D get_socket(i);
if (p_sock && p_sock->rcvevent)
{
FD_SET(i, &lreadset);
nready++;
}
}
if(FD_ISSET(i, writeset))
{
/* See if netconn of this socket is ready for write */
p_sock =3D get_socket(i);
if (p_sock && p_sock->sendevent)
{
FD_SET(i, &lwriteset);
nready++;
}
}
}
*readset =3D lreadset;
*writeset =3D lwriteset;
FD_ZERO(exceptset);
return nready;
}
/*-----------------------------------------------------------------------=
------------*/
int
lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set =
*exceptset,
const struct timeval *timeout)
{
int i;
int nready;
fd_set lreadset, lwriteset, lexceptset;
u16_t msectimeout;
struct lwip_select_cb select_cb;
struct lwip_select_cb *p_selcb;
select_cb.next =3D 0;
select_cb.readset =3D readset;
select_cb.writeset =3D writeset;
select_cb.exceptset =3D exceptset;
select_cb.sem_signalled =3D 0;
=20
/* Protect ourselves searching through the list */
if (!socksem)
socksem =3D sys_sem_new(1);
sys_sem_wait(socksem);
=20
lreadset =3D *readset;
lwriteset =3D *writeset;
lexceptset =3D *exceptset;
/* Go through each socket in each list to count number of sockets =
which
currently match */
nready =3D lwip_selscan(maxfdp1, &lreadset, &lwriteset, =
&lexceptset);
=20
/* If we don't have any current events, then suspend if we are =
supposed to */
if (!nready)
{
if (timeout && timeout->tv_sec =3D=3D 0 && timeout->tv_usec)
{
sys_sem_signal(socksem);
FD_ZERO(readset);
FD_ZERO(writeset);
FD_ZERO(exceptset);
return 0;
}
=20
/* add our semaphore to list */
/* We don't actually need any dynamic memory. Our entry on the
* list is only valid while we are in this function, so it's ok
* to use local variables */
select_cb.sem =3D sys_sem_new(0);
/* Note that we are still protected */
/* Put this select_cb on top of list */
select_cb.next =3D select_cb_list;
select_cb_list =3D &select_cb;
/* Now we can safely unprotect */
sys_sem_signal(socksem);
/* Now just wait to be woken */
if (timeout =3D=3D 0)
/* Wait forever */
msectimeout =3D 0;
else
msectimeout =3D (u16_t) ((timeout->tv_sec * 1000) + =
(timeout->tv_usec /1000));
i =3D sys_sem_wait_timeout(select_cb.sem, msectimeout);
/* Take us off the list */
sys_sem_wait(socksem);
for (p_selcb =3D select_cb_list; p_selcb; p_selcb =3D =
p_selcb->next)
if (p_selcb->next && (p_selcb->next =3D=3D &select_cb))
p_selcb->next =3D select_cb.next;
sys_sem_signal(socksem);
=20
sys_sem_free(select_cb.sem);
if (i =3D=3D 0) /* Timeout */
{
FD_ZERO(readset);
FD_ZERO(writeset);
FD_ZERO(exceptset);
return 0;
}
/* See what's set */
nready =3D lwip_selscan(maxfdp1, &lreadset, &lwriteset, =
&lexceptset);
}
else
sys_sem_signal(socksem);
=20
=20
*readset =3D lreadset;
*writeset =3D lwriteset;
*exceptset =3D lexceptset;
return nready;
}
/*-----------------------------------------------------------------------=
------------*/
static void
event_callback(struct netconn *conn, enum netconn_evt evt)
{
int s;
struct lwip_socket *sock;
struct lwip_select_cb *scb;
=20
/* Get socket */
if (conn)
{
s =3D conn->socket;
sock =3D get_socket(s);
if (!sock)
return;
}
else
return;
=20
/* Set event as required */
switch (evt)
{
case NETCONN_EVT_RCVPLUS:
sock->rcvevent++;
break;
case NETCONN_EVT_RCVMINUS:
sock->rcvevent--;
break;
case NETCONN_EVT_SENDPLUS:
sock->sendevent =3D 1;
break;
case NETCONN_EVT_SENDMINUS:
sock->sendevent =3D 0;
break;
}
/* Now decide if anyone is waiting for this socket */
/* NOTE: This code is written this way to protect the select link =
list
but to avoid a deadlock situation by releasing socksem before
signalling for the select. This means we need to go through the =
list
multiple times ONLY IF a select was actually waiting. We go =
through
the list the number of waiting select calls + 1. This list is
expected to be small. */
while (1)
{
sys_sem_wait(socksem);
for (scb =3D select_cb_list; scb; scb =3D scb->next)
{
if (scb->sem_signalled =3D=3D 0)
{
/* Test this select call for our socket */
if (FD_ISSET(s, scb->readset))
if (sock->rcvevent)
break;
if (FD_ISSET(s, scb->writeset))
if (sock->sendevent)
break;
}
}
sys_sem_signal(socksem);
if (scb)
{
scb->sem_signalled =3D 1;
sys_sem_signal(scb->sem);
}
else
break;
}
=20
}
/* ***** */
/*-----------------------------------------------------------------------=
------------*/
------=_NextPart_000_000D_01C2A52C.35B69F20
Content-Type: application/octet-stream;
name="sys.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="sys.c"
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.=20
*=20
* Redistribution and use in source and binary forms, with or without =
modification,=20
* 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.
* 3. The name of the author may not be used to endorse or promote =
products
* derived from this software without specific prior written =
permission.=20
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR =
IMPLIED=20
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF=20
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. =
IN NO EVENT=20
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, =
SPECIAL,=20
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, =
PROCUREMENT=20
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR =
BUSINESS=20
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER =
IN=20
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR =
OTHERWISE) ARISING=20
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE =
POSSIBILITY=20
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*=20
* Author: Adam Dunkels <address@hidden>
*
*/
#include "lwip/debug.h"
#include "lwip/sys.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/memp.h"
#ifndef NO_SYS
/* *****Added by DJH */
struct sswt_cb
{
int timeflag;
sys_sem_t *psem;
};
/* ***** */
/*-----------------------------------------------------------------------=
------------*/
void
sys_mbox_fetch(sys_mbox_t mbox, void **msg)
{
u16_t time;
struct sys_timeouts *timeouts;
struct sys_timeout *tmptimeout;
sys_timeout_handler h;
void *arg;
=20
again:
timeouts =3D sys_arch_timeouts();
=20
if(timeouts->next =3D=3D NULL) {
sys_arch_mbox_fetch(mbox, msg, 0);
} else {
if(timeouts->next->time > 0) {
time =3D sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);
} else {
time =3D 0;
}
if(time =3D=3D 0) {
/* If time =3D=3D 0, a timeout occured before a message could be
fetched. We should now call the timeout handler and
deallocate the memory allocated for the timeout. */
tmptimeout =3D timeouts->next;
timeouts->next =3D tmptimeout->next;
h =3D tmptimeout->h;
arg =3D tmptimeout->arg;
memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
h(arg);
=20
/* We try again to fetch a message from the mbox. */
goto again;
} else {
/* If time > 0, a message was received before the timeout
occured. The time variable is set to the number of
microseconds we waited for the message. */
if(time <=3D timeouts->next->time) {
timeouts->next->time -=3D time;
} else {
timeouts->next->time =3D 0;
}
}
=20
}
}
/*-----------------------------------------------------------------------=
------------*/
void
sys_sem_wait(sys_sem_t sem)
{
u16_t time;
struct sys_timeouts *timeouts;
struct sys_timeout *tmptimeout;
sys_timeout_handler h;
void *arg;
=20
/* while(sys_arch_sem_wait(sem, 1000) =3D=3D 0);
return;*/
again:
=20
timeouts =3D sys_arch_timeouts();
=20
if(timeouts->next =3D=3D NULL) {
sys_arch_sem_wait(sem, 0);
} else {
if(timeouts->next->time > 0) {
time =3D sys_arch_sem_wait(sem, timeouts->next->time);
} else {
time =3D 0;
}
if(time =3D=3D 0) {
/* If time =3D=3D 0, a timeout occured before a message could be
fetched. We should now call the timeout handler and
deallocate the memory allocated for the timeout. */
tmptimeout =3D timeouts->next;
timeouts->next =3D tmptimeout->next;
h =3D tmptimeout->h;
arg =3D tmptimeout->arg;
memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
h(arg);
=20
=20
/* We try again to fetch a message from the mbox. */
goto again;
} else {
/* If time > 0, a message was received before the timeout
occured. The time variable is set to the number of
microseconds we waited for the message. */
if(time <=3D timeouts->next->time) {
timeouts->next->time -=3D time;
} else {
timeouts->next->time =3D 0;
}
}
=20
}
}
/*-----------------------------------------------------------------------=
------------*/
void
sys_timeout(u16_t msecs, sys_timeout_handler h, void *arg)
{
struct sys_timeouts *timeouts;
struct sys_timeout *timeout, *t;
timeout =3D memp_malloc(MEMP_SYS_TIMEOUT);
if(timeout =3D=3D NULL) {
return;
}
timeout->next =3D NULL;
timeout->h =3D h;
timeout->arg =3D arg;
timeout->time =3D msecs;
=20
timeouts =3D sys_arch_timeouts();
=20
if(timeouts->next =3D=3D NULL) {
timeouts->next =3D timeout;
return;
} =20
=20
if(timeouts->next->time > msecs) {
timeouts->next->time -=3D msecs;
timeout->next =3D timeouts->next;
timeouts->next =3D timeout;
} else {
for(t =3D timeouts->next; t !=3D NULL; t =3D t->next) {
timeout->time -=3D t->time;
if(t->next =3D=3D NULL ||
t->next->time > timeout->time) {
if(t->next !=3D NULL) {
t->next->time -=3D timeout->time;
}
timeout->next =3D t->next;
t->next =3D timeout;
break;
}
}
}
=20
}
/*-----------------------------------------------------------------------=
------------*/
/* *****Added by DJH */
static void
sswt_handler(void *arg)
{
struct sswt_cb *sswt_cb =3D (struct sswt_cb *) arg;
=20
/* Timeout. Set flag to TRUE and signal semephore */
sswt_cb->timeflag =3D TRUE;
sys_sem_signal(*(sswt_cb->psem));
}
/* Wait for a semaphore with timeout (specified in ms) */
/* timeout =3D 0: wait forever */
/* Returns 0 on timeout. 1 otherwise */
/*-----------------------------------------------------------------------=
------------*/
int
sys_sem_wait_timeout(sys_sem_t sem, u16_t timeout)
{
struct sswt_cb sswt_cb;
sswt_cb.psem =3D &sem;
sswt_cb.timeflag =3D FALSE;
=20
/* If timeout is zero, then just wait forever */
if (timeout > 0)
/* Create a timer and pass it the address of our flag */
sys_timeout(timeout, sswt_handler, &sswt_cb);
sys_sem_wait(sem);
/* Was it a timeout? */
if (sswt_cb.timeflag)
return 0;
else
return 1;
}
/*-----------------------------------------------------------------------=
------------*/
/* ***** */
#endif /* NO_SYS */
------=_NextPart_000_000D_01C2A52C.35B69F20
Content-Type: application/octet-stream;
name="sys.h"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="sys.h"
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.=20
*=20
* Redistribution and use in source and binary forms, with or without =
modification,=20
* 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.
* 3. The name of the author may not be used to endorse or promote =
products
* derived from this software without specific prior written =
permission.=20
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR =
IMPLIED=20
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF=20
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. =
IN NO EVENT=20
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, =
SPECIAL,=20
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, =
PROCUREMENT=20
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR =
BUSINESS=20
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER =
IN=20
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR =
OTHERWISE) ARISING=20
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE =
POSSIBILITY=20
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*=20
* Author: Adam Dunkels <address@hidden>
*
*/
#ifndef __LWIP_SYS_H__
#define __LWIP_SYS_H__
#include "arch/cc.h"
#include "lwip/opt.h"
#if NO_SYS
/* For a totally minimal and standalone system, we provide null
definitions of the sys_ functions. */
typedef u8_t sys_sem_t;
typedef u8_t sys_mbox_t;
struct sys_timeout {u8_t dummy;};
#define sys_init()
#define sys_timeout(m,h,a)
#define sys_sem_new(c) c
#define sys_sem_signal(s)
#define sys_sem_wait(s)
#define sys_sem_free(s)
#define sys_mbox_new() 0
#define sys_mbox_fetch(m,d)
#define sys_mbox_post(m,d)
#define sys_mbox_free(m)
#define sys_thread_new(t,a)
#else /* NO_SYS */
#include "arch/sys_arch.h"
typedef void (* sys_timeout_handler)(void *arg);
struct sys_timeout {
struct sys_timeout *next;
u16_t time;
sys_timeout_handler h;
void *arg;
};
struct sys_timeouts {
struct sys_timeout *next;
};
/* sys_init() must be called before anthing else. */
void sys_init(void);
/*
* sys_timeout():
*
* Schedule a timeout a specified amount of milliseconds in the
* future. When the timeout occurs, the specified timeout handler will
* be called. The handler will be passed the "arg" argument when
* called.
*
*/
void sys_timeout(u16_t msecs, sys_timeout_handler h, void *arg);
struct sys_timeouts *sys_arch_timeouts(void);
/* Semaphore functions. */
sys_sem_t sys_sem_new(u8_t count);
void sys_sem_signal(sys_sem_t sem);
u16_t sys_arch_sem_wait(sys_sem_t sem, u16_t timeout);
void sys_sem_free(sys_sem_t sem);
void sys_sem_wait(sys_sem_t sem);
/* *****Added by DJH */
int
sys_sem_wait_timeout(sys_sem_t sem, u16_t timeout);
/* ***** */
/* Mailbox functions. */
sys_mbox_t sys_mbox_new(void);
void sys_mbox_post(sys_mbox_t mbox, void *msg);
u16_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u16_t timeout);
void sys_mbox_free(sys_mbox_t mbox);
void sys_mbox_fetch(sys_mbox_t mbox, void **msg);
/* Thread functions. */
void sys_thread_new(void (* thread)(void *arg), void *arg);
/* The following functions are used only in Unix code, and
can be omitted when porting the stack. */
/* Returns the current time in microseconds. */
unsigned long sys_now(void);
#endif /* NO_SYS */
#endif /* __LWIP_SYS_H__ */
------=_NextPart_000_000D_01C2A52C.35B69F20
Content-Type: application/octet-stream;
name="sockets.h"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="sockets.h"
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.=20
*=20
* Redistribution and use in source and binary forms, with or without =
modification,=20
* 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.
* 3. The name of the author may not be used to endorse or promote =
products
* derived from this software without specific prior written =
permission.=20
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR =
IMPLIED=20
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF=20
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. =
IN NO EVENT=20
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, =
SPECIAL,=20
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, =
PROCUREMENT=20
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR =
BUSINESS=20
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER =
IN=20
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR =
OTHERWISE) ARISING=20
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE =
POSSIBILITY=20
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*=20
* Author: Adam Dunkels <address@hidden>
*
*/
#ifndef __LWIP_SOCKETS_H__
#define __LWIP_SOCKETS_H__
struct in_addr {
u32_t s_addr;
};
struct sockaddr_in {
u8_t sin_len;
u8_t sin_family;
u16_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct sockaddr {
u8_t sa_len;
u8_t sa_family;
char sa_data[14];
};
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define AF_INET 2
#define PF_INET AF_INET
#define IPPROTO_TCP 6
#define IPPROTO_UDP 17
#define INADDR_ANY 0
#define INADDR_BROADCAST 0xffffffff
int lwip_accept(int s, struct sockaddr *addr, int *addrlen);
int lwip_bind(int s, struct sockaddr *name, int namelen);
int lwip_close(int s);
int lwip_connect(int s, struct sockaddr *name, int namelen);
int lwip_listen(int s, int backlog);
int lwip_recv(int s, void *mem, int len, unsigned int flags);
int lwip_read(int s, void *mem, int len);
int lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
struct sockaddr *from, int *fromlen);
int lwip_send(int s, void *dataptr, int size, unsigned int flags);
int lwip_sendto(int s, void *dataptr, int size, unsigned int flags,
struct sockaddr *to, int tolen);
int lwip_socket(int domain, int type, int protocol);
int lwip_write(int s, void *dataptr, int size);
/* *****Added by DJH */
int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set =
*exceptset,
const struct timeval *timeout);
/* ***** */
#ifdef LWIP_COMPAT_SOCKETS
#define accept(a,b,c) lwip_accept(a,b,c)
#define bind(a,b,c) lwip_bind(a,b,c)
#define close(s) lwip_close(s)
#define connect(a,b,c) lwip_connect(a,b,c)
#define listen(a,b) lwip_listen(a,b)
#define recv(a,b,c,d) lwip_recv(a,b,c,d)
#define read(a,b,c) lwip_read(a,b,c)
#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f)
#define send(a,b,c,d) lwip_send(a,b,c,d)
#define sendto(a,b,c,d,e,f) lwip_sendto(a,b,c,d,e,f)
#define socket(a,b,c) lwip_socket(a,b,c)
#define write(a,b,c) lwip_write(a,b,c)
/* *****Added by DJH */
#define select(a,b,c,d,e) lwip_select(a,b,c,d,e)
/* ***** */
#endif /* LWIP_NO_COMPAT_SOCKETS */
#endif /* __LWIP_SOCKETS_H__ */
------=_NextPart_000_000D_01C2A52C.35B69F20
Content-Type: application/octet-stream;
name="api.h"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="api.h"
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.=20
*=20
* Redistribution and use in source and binary forms, with or without =
modification,=20
* 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.
* 3. The name of the author may not be used to endorse or promote =
products
* derived from this software without specific prior written =
permission.=20
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR =
IMPLIED=20
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF=20
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. =
IN NO EVENT=20
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, =
SPECIAL,=20
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, =
PROCUREMENT=20
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR =
BUSINESS=20
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER =
IN=20
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR =
OTHERWISE) ARISING=20
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE =
POSSIBILITY=20
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*=20
* Author: Adam Dunkels <address@hidden>
*
*/
#ifndef __LWIP_API_H__
#define __LWIP_API_H__
#include "lwip/opt.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/ip.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/err.h"
#define NETCONN_NOCOPY 0x00
#define NETCONN_COPY 0x01
enum netconn_type {
NETCONN_TCP,
NETCONN_UDP,
NETCONN_UDPLITE,
NETCONN_UDPNOCHKSUM
};
enum netconn_state {
NETCONN_NONE,
NETCONN_WRITE,
NETCONN_ACCEPT,
NETCONN_RECV,
NETCONN_CONNECT,
NETCONN_CLOSE
};
/* *****Added by DJH */
enum netconn_evt {
NETCONN_EVT_RCVPLUS,
NETCONN_EVT_RCVMINUS,
NETCONN_EVT_SENDPLUS,
NETCONN_EVT_SENDMINUS
};
/* ***** */
struct netbuf {
struct pbuf *p, *ptr;
struct ip_addr *fromaddr;
u16_t fromport;
err_t err;
};
struct netconn {
enum netconn_type type;
enum netconn_state state;
union {
struct tcp_pcb *tcp;
struct udp_pcb *udp;
} pcb;
err_t err;
sys_mbox_t mbox;
sys_mbox_t recvmbox;
sys_mbox_t acceptmbox;
sys_sem_t sem;
/* *****Added by DJH */
int socket;
void (* callback)(struct netconn *, enum netconn_evt); =20
/* ***** */
};
/* Network buffer functions: */
struct netbuf * netbuf_new (void);
void netbuf_delete (struct netbuf *buf);
void * netbuf_alloc (struct netbuf *buf, u16_t size);
void netbuf_free (struct netbuf *buf);
void netbuf_ref (struct netbuf *buf,
void *dataptr, u16_t size);
void netbuf_chain (struct netbuf *head,
struct netbuf *tail);
u16_t netbuf_len (struct netbuf *buf);
err_t netbuf_data (struct netbuf *buf,
void **dataptr, u16_t *len);
s8_t netbuf_next (struct netbuf *buf);
void netbuf_first (struct netbuf *buf);
void netbuf_copy (struct netbuf *buf,
void *dataptr, u16_t len);
struct ip_addr * netbuf_fromaddr (struct netbuf *buf);
u16_t netbuf_fromport (struct netbuf *buf);
/* Network connection functions: */
struct netconn * netconn_new (enum netconn_type type);
/* *****Added by DJH */
struct
netconn *netconn_new_with_callback(enum netconn_type t,
void (*callback)(struct netconn *, =
enum netconn_evt));
/* ***** */
err_t netconn_delete (struct netconn *conn);
enum netconn_type netconn_type (struct netconn *conn);
err_t netconn_peer (struct netconn *conn,
struct ip_addr **addr,
u16_t *port);
err_t netconn_addr (struct netconn *conn,
struct ip_addr **addr,
u16_t *port);
err_t netconn_bind (struct netconn *conn,
struct ip_addr *addr,
u16_t port);
err_t netconn_connect (struct netconn *conn,
struct ip_addr *addr,
u16_t port);
err_t netconn_listen (struct netconn *conn);
struct netconn * netconn_accept (struct netconn *conn);
struct netbuf * netconn_recv (struct netconn *conn);
err_t netconn_send (struct netconn *conn,
struct netbuf *buf);
err_t netconn_write (struct netconn *conn,
void *dataptr, u16_t size,
u8_t copy);
err_t netconn_close (struct netconn *conn);
err_t netconn_err (struct netconn *conn);
#endif /* __LWIP_API_H__ */
------=_NextPart_000_000D_01C2A52C.35B69F20
Content-Type: application/octet-stream;
name="cc.h"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="cc.h"
/*
* Copyright (c) 2001, Swedish Institute of Computer Science.
* All rights reserved.=20
*
* Redistribution and use in source and binary forms, with or without=20
* modification, are permitted provided that the following conditions=20
* are met:=20
* 1. Redistributions of source code must retain the above copyright=20
* notice, this list of conditions and the following disclaimer.=20
* 2. Redistributions in binary form must reproduce the above copyright=20
* notice, this list of conditions and the following disclaimer in =
the=20
* documentation and/or other materials provided with the =
distribution.=20
* 3. Neither the name of the Institute nor the names of its =
contributors=20
* may be used to endorse or promote products derived from this =
software=20
* without specific prior written permission.=20
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' =
AND=20
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE =
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR =
PURPOSE=20
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE =
LIABLE=20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR =
CONSEQUENTIAL=20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE =
GOODS=20
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) =
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, =
STRICT=20
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY =
WAY=20
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY =
OF=20
* SUCH DAMAGE.=20
*
* This file is part of the lwIP TCP/IP stack.
*=20
* Author: Adam Dunkels <address@hidden>
*
* $Id: cc.h,v 1.1 2001/12/12 10:00:56 adam Exp $
*/
#ifndef __CC_H__
#define __CC_H__
#include <types.h>
// typedef unsigned char u8_t;
// typedef signed char s8_t;
// typedef unsigned short u16_t;
// typedef signed short s16_t;
// typedef unsigned long u32_t;
// typedef signed long s32_t;
typedef u32_t mem_ptr_t;
#define PACK_STRUCT_BEGIN #pragma pack(1,1,0)
#define PACK_STRUCT_STRUCT
#define ALIGN_STRUCT_8_BEGIN #pragma pack(1,8,0)
#define ALIGN_STRUCT_END #pragma pack()
#define PACK_STRUCT_END #pragma pack()
#define PACK_STRUCT_FIELD(x) x
#define _SYS_TYPES_FD_SET
#define NBBY 8 /* number of bits in a byte */
#ifndef FD_SETSIZE
#define FD_SETSIZE 64
#endif /* FD_SETSIZE */
typedef long fd_mask;
#define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
#ifndef howmany
#define howmany(x,y) (((x)+((y)-1))/(y))
#endif /* howmany */
typedef struct _types_fd_set {
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
} _types_fd_set;
#define fd_set _types_fd_set
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |=3D (1L << ((n) % =
NFDBITS)))
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &=3D ~(1L << ((n) % =
NFDBITS)))
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1L << ((n) % =
NFDBITS)))
#define FD_ZERO(p) do { \
size_t __i; \
char *__tmp =3D (char *)p; \
for (__i =3D 0; __i < sizeof (*(p)); ++__i) \
*__tmp++ =3D 0; \
} while (0)
#endif /* __CC_H__ */
------=_NextPart_000_000D_01C2A52C.35B69F20--
[This message was sent through the lwip discussion list.]
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [lwip-users] [lwip] Code Review requested,
David Haas <=