Commit 2e56afaf authored by Aurelio Colosimo's avatar Aurelio Colosimo

network functions implementation for posix

parent fdd9844d
......@@ -27,19 +27,12 @@ void posix_main_loop(struct pp_instance *ppi)
while (1) {
fd_set set;
int i;
struct timeval tv;
unsigned char packet[1500];
/* Wait for a packet or for the timeout */
tv.tv_sec = delay_ms / 1000;
tv.tv_usec = (delay_ms % 1000) * 1000;
again:
FD_ZERO(&set);
FD_SET(ppi->ch.fd, &set);
i = select(ppi->ch.fd + 1, &set, NULL, NULL, &tv);
if (i < 0 && errno != EINTR)
exit(__LINE__);
i = posix_net_check_pkt(ppi, delay_ms);
if (i < 0)
continue;
......@@ -54,12 +47,16 @@ void posix_main_loop(struct pp_instance *ppi)
*/
i = posix_recv_packet(ppi, packet, sizeof(packet));
/* FIXME
if (i < sizeof(struct pp_packet))
if (i < sizeof(struct pp_packet)) {
delay_ms = -1;
goto again;
}
*/
/* Warning: PP_PROTO_NR is endian-agnostic by design */
if ( ((struct ethhdr *)packet)->h_proto != htons(PP_PROTO_NR))
if ( ((struct ethhdr *)packet)->h_proto != htons(PP_PROTO_NR)) {
delay_ms = -1;
goto again;
}
delay_ms = pp_state_machine(ppi, packet, i);
}
......
......@@ -4,6 +4,7 @@
/* Socket interface for GNU/Linux (and most likely other posix systems */
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
......@@ -17,16 +18,40 @@
#include <pproto/diag.h>
#include "posix.h"
static int ch_check_stat = 0;
/* Receive and send is trivial */
/* Receive and send is *not* so trivial */
int posix_recv_packet(struct pp_instance *ppi, void *pkt, int len)
{
return recv(ppi->ch.fd, pkt, len, 0);
struct pp_channel *ch1 = NULL, *ch2 = NULL;
switch (ch_check_stat) {
case 0:
ch1 = &(ppi->net_path->evt_ch);
ch2 = &(ppi->net_path->gen_ch);
break;
case 1:
ch1 = &(ppi->net_path->gen_ch);
ch2 = &(ppi->net_path->evt_ch);
break;
default:
/* Impossible! */
break;
}
if (ch1->pkt_present)
return recv(ch1->fd, pkt, len, 0);
if (ch2->pkt_present)
return recv(ch2->fd, pkt, len, 0);
ch_check_stat = (ch_check_stat + 1) % 2;
return -1;
}
int posix_send_packet(struct pp_instance *ppi, void *pkt, int len)
{
return send(ppi->ch.fd, pkt, len, 0);
return send(/*FIXME which socket?! ppi->ch.fd*/ -1, pkt, len, 0);
}
int pp_recv_packet(struct pp_instance *ppi, void *pkt, int len)
......@@ -37,6 +62,14 @@ int pp_send_packet(struct pp_instance *ppi, void *pkt, int len)
/* To open a channel we must bind to an interface and so on */
int posix_open_ch(struct pp_instance *ppi, char *ifname)
{
/* TODO. In our first implementation, inherited by ptpd-2.1.0, we
* will handle UDP/IP packets. So, SOCK_DGRAM, IPPROTO_UDP, and all
* of standard UDP must be used when opening a socket. The port number
* should be passed to this function. (see posix-socket file too).
*
* Moreover, ptpd makes use of multicast, so setsockopt with
* IP_ADD_MEMBERSHIP must be called.
*/
int sock, iindex;
struct ifreq ifr;
struct sockaddr_ll addr;
......@@ -63,7 +96,9 @@ int posix_open_ch(struct pp_instance *ppi, char *ifname)
close(sock);
return -1;
}
/* FIXME
memcpy(ppi->ch.addr, ifr.ifr_hwaddr.sa_data, 6);
*/
/* bind and setsockopt */
memset(&addr, 0, sizeof(addr));
......@@ -75,17 +110,27 @@ int posix_open_ch(struct pp_instance *ppi, char *ifname)
close(sock);
return -1;
}
/* FIXME
ppi->ch.fd = sock;
*/
return 0;
}
/*
* Inits all the network stuff
* TODO: check with the posix_open_ch, maybe it's the same
*/
int posix_net_init(struct pp_instance *ppi)
{
char *ifname = "eth0"; /* TODO get it from rt_opts, or find interface if
* not present in cmd line */
/* TODO: how to handle udp ports? current pp_open_ch does not support
* it. Is it arch-specific? Actually, it is net protocol specific.
* We must decide how generic we want to be. Will we ever handle
* non-udp? Probably yes.
*/
posix_open_ch(ppi,ifname); /* FIXME: to be called twice, one for evt,
* one for general ? */
return 0;
}
......@@ -102,5 +147,53 @@ int posix_net_shutdown(struct pp_instance *ppi)
return 0;
}
int posix_net_check_pkt(struct pp_instance *ppi, int delay_ms)
{
fd_set set;
int i;
int ret = 0;
int maxfd;
if (delay_ms != -1) {
/* Wait for a packet or for the timeout */
ppi->tv.tv_sec = delay_ms / 1000;
ppi->tv.tv_usec = (delay_ms % 1000) * 1000;
}
ppi->net_path->gen_ch.pkt_present = 0;
ppi->net_path->evt_ch.pkt_present = 0;
maxfd = (ppi->net_path->gen_ch.fd > ppi->net_path->evt_ch.fd) ?
ppi->net_path->gen_ch.fd : ppi->net_path->evt_ch.fd;
FD_ZERO(&set);
FD_SET(ppi->net_path->gen_ch.fd, &set);
FD_SET(ppi->net_path->evt_ch.fd, &set);
i = select(maxfd + 1, &set, NULL, NULL, &ppi->tv);
if (i < 0 && errno != EINTR)
exit(__LINE__);
if (i < 0) {
ret = i;
goto _end;
}
if (i == 0)
goto _end;
if (FD_ISSET(ppi->net_path->gen_ch.fd,&set)) {
ret++;
ppi->net_path->gen_ch.pkt_present = 1;
}
if (FD_ISSET(ppi->net_path->evt_ch.fd,&set)) {
ret++;
ppi->net_path->evt_ch.pkt_present = 1;
}
_end:
return ret;
}
int pp_net_shutdown(struct pp_instance *ppi)
__attribute__((alias("posix_net_shutdown")));
......@@ -37,9 +37,11 @@ int main(int argc, char **argv)
ppi->parentDS = calloc(1, sizeof(*ppi->parentDS));
ppi->portDS = calloc(1, sizeof(*ppi->portDS));
ppi->timePropertiesDS = calloc(1, sizeof(*ppi->timePropertiesDS));
ppi->net_path = calloc(1, sizeof(*ppi->net_path));
if ((!ppi->defaultDS) || (!ppi->currentDS) || (!ppi->parentDS)
|| (!ppi->portDS) || (!ppi->timePropertiesDS) || (!ppi->sent_seq_id)
|| (!ppi->net_path)
)
exit(__LINE__);
......
......@@ -7,6 +7,7 @@
*/
extern int posix_net_init(struct pp_instance *ppi);
extern int posix_net_check_pkt(struct pp_instance *ppi, int delay_ms);
extern int posix_open_ch(struct pp_instance *ppi, char *name);
......
......@@ -56,4 +56,19 @@
#define PP_PDELAY_RESP_FOLLOW_UP_LENGTH 54
#define PP_MANAGEMENT_LENGTH 48
/* UDP/IPv4 dependent */
#define PP_SUBDOMAIN_ADDRESS_LENGTH 4
#define PP_PORT_ADDRESS_LENGTH 2
#define PP_UUID_LENGTH 6
#define PP_CLOCK_IDENTITY_LENGTH 8
#define PP_FLAG_FIELD_LENGTH 2
#define PP_PACKET_SIZE 300
#define PP_EVENT_PORT 319
#define PP_GENERAL_PORT 320
#define PP_DEFAULT_DOMAIN_ADDRESS "224.0.1.129"
#define PP_PEER_DOMAIN_ADDRESS "224.0.0.107"
#define PP_MM_STARTING_BOUNDARY_HOPS 0x7fff
#endif /* __PTP_CONSTANTS_H__ */
......@@ -64,6 +64,7 @@ struct pp_channel
void *arch_data; /* Other arch-private info, if any */
unsigned char addr[6]; /* Our own MAC address */
unsigned char peer[6]; /* Our peer's MAC address */
int pkt_present;
};
/*
......@@ -88,6 +89,17 @@ struct pp_timer
uint32_t interval;
};
/*
* Net Path
*/
struct pp_net_path
{
struct pp_channel evt_ch;
struct pp_channel gen_ch;
Integer32 ucast_addr;
Integer32 mcast_addr;
Integer32 peer_mcast_addr;
};
/*
* Structure for the standard protocol
......@@ -97,8 +109,9 @@ struct pp_instance {
int next_state, next_delay; /* set by state processing */
void *arch_data; /* if arch needs it */
void *ext_data; /* if protocol ext needs it */
struct pp_channel ch;
struct pp_runtime_opts *rt_opts;
struct pp_net_path *net_path;
struct timeval tv;
/* Data sets */
DSDefault *defaultDS;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment