diff options
-rw-r--r-- | examples/common/Makefile | 8 | ||||
-rw-r--r-- | examples/jackd-listener/Makefile | 18 | ||||
-rw-r--r-- | examples/jackd-talker/Makefile | 32 | ||||
-rw-r--r-- | examples/live_stream/Makefile | 39 | ||||
-rw-r--r-- | examples/simple_listener/Makefile | 18 | ||||
-rw-r--r-- | examples/simple_rx/Makefile | 28 | ||||
-rw-r--r-- | examples/simple_talker/Makefile | 31 | ||||
-rw-r--r-- | lib/common/Makefile | 23 | ||||
-rw-r--r-- | lib/common/avb.h | 201 | ||||
-rw-r--r-- | lib/common/avb_avtp.c (renamed from lib/common/avb.c) | 360 | ||||
-rw-r--r-- | lib/common/avb_avtp.h | 151 | ||||
-rw-r--r-- | lib/common/avb_gptp.c | 149 | ||||
-rw-r--r-- | lib/common/avb_gptp.h | 50 | ||||
-rw-r--r-- | lib/common/avb_igb.c | 77 | ||||
-rw-r--r-- | lib/common/avb_igb.h | 10 | ||||
-rw-r--r-- | lib/common/avb_srp.h | 6 |
16 files changed, 667 insertions, 534 deletions
diff --git a/examples/common/Makefile b/examples/common/Makefile index 5e42ddbd..68a313fd 100644 --- a/examples/common/Makefile +++ b/examples/common/Makefile @@ -1,14 +1,16 @@ +DAEMONS_DIR = ../../daemons + CC ?= gcc OPT = -O2 -g -CFLAGS = $(OPT) -Wall -Wextra -Wno-parentheses +WARN = -Wall -Wextra -Wno-parentheses +CFLAGS = $(OPT) $(WARN) +CPPFLAGS = -I$(DAEMONS_DIR)/mrpd -I$(DAEMONS_DIR)/common all: talker_mrp_client.o listener_mrp_client.o talker_mrp_client.o: talker_mrp_client.c talker_mrp_client.h - $(CC) $(CFLAGS) -I../../daemons/mrpd -I../../daemons/common -c talker_mrp_client.c listener_mrp_client.o: listener_mrp_client.c listener_mrp_client.h - $(CC) $(CFLAGS) -I../../daemons/mrpd -I../../daemons/common -c listener_mrp_client.c clean: $(RM) talker_mrp_client.o listener_mrp_client.o diff --git a/examples/jackd-listener/Makefile b/examples/jackd-listener/Makefile index b0208530..4a526b91 100644 --- a/examples/jackd-listener/Makefile +++ b/examples/jackd-listener/Makefile @@ -1,18 +1,24 @@ +MRPCLIENT_DIR = ../common +MRPLISTENER_OBJS = listener_mrp_client.o +MRPLISTENER_TARGETS = $(addprefix $(MRPCLIENT_DIR)/,$(MRPLISTENER_OBJS)) + +DAEMONS_DIR = ../../daemons + CC ?= gcc OPT = -O2 -g -CFLAGS = $(OPT) -Wall -Wextra -Wno-parentheses -std=gnu99 -INCFLAGS = -I../../daemons/mrpd -I../common -I../../daemons/common +WARN = -Wall -Wextra -Wno-parentheses +CFLAGS = $(OPT) $(WARN) -std=gnu99 +CPPFLAGS = -I$(DAEMONS_DIR)/mrpd -I$(MRPCLIENT_DIR) -I$(DAEMONS_DIR)/common LDLIBS = -lpcap -lsndfile -ljack -lpthread all: jack_listener -jack_listener: jack_listener.o ../common/listener_mrp_client.o +jack_listener: jack_listener.o $(MRPLISTENER_TARGETS) jack_listener.o: jack_listener.c - $(CC) $(CFLAGS) $(INCFLAGS) -c jack_listener.c -../common/listener_mrp_client.o: - make -C ../common/ listener_mrp_client.o +$(MRPCLIENT_DIR)/%.o: $(MRPCLIENT_DIR)/%.c $(MRPCLIENT_DIR)/%.h + make -C $(MRPCLIENT_DIR) $@ %: %.o $(CC) $^ $(LDLIBS) -o $@ diff --git a/examples/jackd-talker/Makefile b/examples/jackd-talker/Makefile index f76bf2e0..9a6187e2 100644 --- a/examples/jackd-talker/Makefile +++ b/examples/jackd-talker/Makefile @@ -1,25 +1,37 @@ +AVBLIB_DIR = ../../lib/common +AVBLIB_OBJS = avb_avtp.o avb_gptp.o avb_igb.o +AVBLIB_TARGETS = $(addprefix $(AVBLIB_DIR)/,$(AVBLIB_OBJS)) + +MRPCLIENT_DIR = ../common +MRPTALKER_OBJS = talker_mrp_client.o +MRPTALKER_TARGETS = $(addprefix $(MRPCLIENT_DIR)/,$(MRPTALKER_OBJS)) + +IGBLIB_DIR = ../../lib/igb +DAEMONS_DIR = ../../daemons + CC ?= gcc OPT = -O2 -g -CFLAGS = $(OPT) $(INCFLAGS) -Wall -Wextra -Wno-parentheses -std=gnu99 -INCFLAGS = -I../../lib/igb -I../../daemons/mrpd -I../common -I../../lib/common -I../../daemons/common +WARN = -Wall -Wextra -Wno-parentheses +CFLAGS = $(OPT) $(WARN) -std=gnu99 +CPPFLAGS = -I$(IGBLIB_DIR) -I$(DAEMONS_DIR)/mrpd -I$(MRPCLIENT_DIR) -I$(AVBLIB_DIR) -I$(DAEMONS_DIR)/common LDLIBS = -ligb -lpci -lrt -pthread -ljack -LDFLAGS = -L../../lib/igb +LDFLAGS = -L$(IGBLIB_DIR) + +.PHONY: all clean all: jackd_talker -jackd_talker: jackd_talker.o jack.o ../common/talker_mrp_client.o ../../lib/common/avb.o +jackd_talker: jackd_talker.o jack.o $(MRPTALKER_TARGETS) $(AVBLIB_TARGETS) jack.o: jack.c jack.h defines.h - $(CC) $(CFLAGS) -c jack.c jackd_talker.o: jackd_talker.c defines.h jack.h - $(CC) -c $(INCFLAGS) -I../../daemons/mrpd $(CFLAGS) jackd_talker.c -../../lib/common/avb.o: ../../lib/common/avb.c ../../lib/common/avb.h - make -C ../../lib/common/ avb.o +$(AVBLIB_DIR)/%.o: $(AVBLIB_DIR)/%.h $(AVBLIB_DIR)/%.c + make -C $(AVBLIB_DIR) $@ -../common/talker_mrp_client.o: - make -C ../common/ talker_mrp_client.o +$(MRPCLIENT_DIR)/%.o: $(MRPCLIENT_DIR)/%.c $(MRPCLIENT_DIR)/%.h + make -C $(MRPCLIENT_DIR) $@ %: %.o $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ diff --git a/examples/live_stream/Makefile b/examples/live_stream/Makefile index 4eb4feed..b5c96957 100644 --- a/examples/live_stream/Makefile +++ b/examples/live_stream/Makefile @@ -1,30 +1,41 @@ +AVBLIB_DIR = ../../lib/common +AVBLIB_OBJS = avb_avtp.o avb_gptp.o avb_igb.o +AVBLIB_TARGETS = $(addprefix $(AVBLIB_DIR)/,$(AVBLIB_OBJS)) + +MRPCLIENT_DIR = ../common +MRPTALKER_OBJS = talker_mrp_client.o +MRPTALKER_TARGETS = $(addprefix $(MRPCLIENT_DIR)/,$(MRPTALKER_OBJS)) +MRPLISTENER_OBJS = listener_mrp_client.o +MRPLISTENER_TARGETS = $(addprefix $(MRPCLIENT_DIR)/,$(MRPLISTENER_OBJS)) + +IGBLIB_DIR = ../../lib/igb +DAEMONS_DIR = ../../daemons + CC?=gcc OPT=-O2 -g -CFLAGS=$(OPT) -Wall -Wextra -Wno-parentheses -INCFLAGS=-I ../../lib/igb/ -I../../daemons/mrpd -I../common -I../../lib/common -I../../daemons/common +WARN=-Wall -Wextra -Wno-parentheses +CFLAGS=$(OPT) $(WARN) +CPPFLAGS=-I$(IGBLIB_DIR) -I$(DAEMONS_DIR)/mrpd -I$(MRPCLIENT_DIR) -I$(AVBLIB_DIR) -I$(DAEMONS_DIR)/common LDLIBS=-ligb -lpci -lrt -lpthread -LDFLAGS=-L ../../lib/igb/ +LDFLAGS=-L$(IGBLIB_DIR) + +.PHONY: all clean all: talker listener -talker: talker.o ../../lib/common/avb.o ../common/talker_mrp_client.o +talker: talker.o $(MRPTALKER_TARGETS) $(AVBLIB_TARGETS) talker.o: talker.c - $(CC) $(CFLAGS) $(INCFLAGS) $(EXTRA_FLAGS) -c talker.c - -../common/talker_mrp_client.o: ../common/talker_mrp_client.c ../common/talker_mrp_client.h - make -C ../common/ talker_mrp_client.o -listener: listener.o ../../lib/common/avb.o ../common/listener_mrp_client.o +listener: listener.o $(MRPLISTENER_TARGETS) $(AVBLIB_TARGETS) listener.o: listener.c - $(CC) $(CFLAGS) $(INCFLAGS) $(EXTRA_FLAGS) -c listener.c -../common/listener_mrp_client.o: ../common/listener_mrp_client.c ../common/listener_mrp_client.h - make -C ../common/ listener_mrp_client.o +$(AVBLIB_DIR)/%.o: $(AVBLIB_DIR)/%.h $(AVBLIB_DIR)/%.c + make -C $(AVBLIB_DIR) $@ -../../lib/common/avb.o: ../../lib/common/avb.c ../../lib/common/avb.h - make -C ../../lib/common/ avb.o +$(MRPCLIENT_DIR)/%.o: $(MRPCLIENT_DIR)/%.c $(MRPCLIENT_DIR)/%.h + make -C $(MRPCLIENT_DIR) $@ %: %.o $(CC) $(LDFLAGS) $^ $(LDLIBS) $(EXTRA_FLAGS) -o $@ diff --git a/examples/simple_listener/Makefile b/examples/simple_listener/Makefile index 9a4b33a6..02d66fa8 100644 --- a/examples/simple_listener/Makefile +++ b/examples/simple_listener/Makefile @@ -1,18 +1,24 @@ +MRPCLIENT_DIR = ../common +MRPLISTENER_OBJS = listener_mrp_client.o +MRPLISTENER_TARGETS = $(addprefix $(MRPCLIENT_DIR)/,$(MRPLISTENER_OBJS)) + +DAEMONS_DIR = ../../daemons + CC ?= gcc OPT = -O2 -g -CFLAGS = $(OPT) -Wall -Wextra -Wno-parentheses -INCFLAGS = -I../../daemons/mrpd -I../common -I../../daemons/common +WARN=-Wall -Wextra -Wno-parentheses +CFLAGS=$(OPT) $(WARN) +CPPFLAGS = -I$(DAEMONS_DIR)/mrpd -I$(MRPCLIENT_DIR) -I$(DAEMONS_DIR)/common LDLIBS = -lpcap -lsndfile -pthread all: simple_listener -simple_listener: simple_listener.o ../common/listener_mrp_client.o +simple_listener: simple_listener.o $(MRPLISTENER_TARGETS) simple_listener.o: simple_listener.c - $(CC) $(CFLAGS) $(INCFLAGS) -c simple_listener.c -../common/listener_mrp_client.o: ../common/listener_mrp_client.c ../common/listener_mrp_client.h - make -C ../common/ listener_mrp_client.o +$(MRPCLIENT_DIR)/%.o: $(MRPCLIENT_DIR)/%.c $(MRPCLIENT_DIR)/%.h + make -C $(MRPCLIENT_DIR) $@ %: %.o $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ diff --git a/examples/simple_rx/Makefile b/examples/simple_rx/Makefile index bf83a484..c27e811b 100644 --- a/examples/simple_rx/Makefile +++ b/examples/simple_rx/Makefile @@ -1,23 +1,33 @@ + +MRPCLIENT_DIR = ../common +MRPLISTENER_OBJS = listener_mrp_client.o +MRPLISTENER_TARGETS = $(addprefix $(MRPCLIENT_DIR)/,$(MRPLISTENER_OBJS)) + +IGBLIB_DIR = ../../lib/igb +IGBLIB_OBJS = igb.o +IGBLIB_TARGETS = $(addprefix $(IGBLIB_DIR)/,$(IGBLIB_OBJS)) + +DAEMONS_DIR = ../../daemons + CC ?= gcc OPT = -O2 -g -CFLAGS = $(OPT) -Wall -Wextra -Wno-parentheses -IGBDIR = ../../lib/igb -INCFLAGS = -I../../daemons/mrpd -I../common -I../../daemons/common -I$(IGBDIR) +WARN=-Wall -Wextra -Wno-parentheses +CFLAGS=$(OPT) $(WARN) +CPPFLAGS = -I$(DAEMONS_DIR)/mrpd -I$(MRPCLIENT_DIR) -I$(DAEMONS_DIR)/common -I$(IGBLIB_DIR) # GLIBC versions starting with 2.17 don't need -lrt anymore LDLIBS = -lpcap -lsndfile -pthread -lpci -lrt all: simple_rx -simple_rx: simple_rx.o ../common/listener_mrp_client.o $(IGBDIR)/igb.o +simple_rx: simple_rx.o $(MRPLISTENER_TARGETS) $(IGBLIB_TARGETS) simple_rx.o: simple_rx.c - $(CC) $(CFLAGS) $(INCFLAGS) -c simple_rx.c -../common/listener_mrp_client.o: ../common/listener_mrp_client.c ../common/listener_mrp_client.h - make -C ../common/ listener_mrp_client.o +$(MRPCLIENT_DIR)/%.o: $(MRPCLIENT_DIR)/%.c $(MRPCLIENT_DIR)/%.h + make -C $(MRPCLIENT_DIR) $@ -$(IGBDIR)/igb.o: $(IGBDIR)/igb.c - make -C $(IGBDIR) igb.o +$(IGBLIB_DIR)/%.o: $(IGBLIB_DIR)/%.c $(IGBLIB_DIR)/%.h + make -C $(IGBLIB_DIR) $@ %: %.o $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ diff --git a/examples/simple_talker/Makefile b/examples/simple_talker/Makefile index bba47b03..aef9c541 100644 --- a/examples/simple_talker/Makefile +++ b/examples/simple_talker/Makefile @@ -1,22 +1,35 @@ +AVBLIB_DIR = ../../lib/common +AVBLIB_OBJS = avb_avtp.o avb_gptp.o avb_igb.o +AVBLIB_TARGETS = $(addprefix $(AVBLIB_DIR)/,$(AVBLIB_OBJS)) + +MRPCLIENT_DIR = ../common +MRPTALKER_OBJS = talker_mrp_client.o +MRPTALKER_TARGETS = $(addprefix $(MRPCLIENT_DIR)/,$(MRPTALKER_OBJS)) + +IGBLIB_DIR = ../../lib/igb +DAEMONS_DIR = ../../daemons + CC?=gcc OPT=-O2 -g -CFLAGS=$(OPT) -Wall -Wextra -Wno-parentheses -INCFLAGS=-I../../lib/igb -I../../daemons/mrpd -I../common -I../../lib/common -I../../daemons/common +WARN=-Wall -Wextra -Wno-parentheses +CFLAGS=$(OPT) $(WARN) +CPPFLAGS=-I$(IGBLIB_DIR) -I$(DAEMONS_DIR)/mrpd -I$(MRPCLIENT_DIR) -I$(AVBLIB_DIR) -I$(DAEMONS_DIR)/common LDLIBS=-ligb -lpci -lrt -lm -pthread -LDFLAGS=-L../../lib/igb +LDFLAGS=-L$(IGBLIB_DIR) + +.PHONY: all clean all: simple_talker -simple_talker: simple_talker.o ../common/talker_mrp_client.o ../../lib/common/avb.o +simple_talker: simple_talker.o $(MRPTALKER_TARGETS) $(AVBLIB_TARGETS) simple_talker.o: simple_talker.c - $(CC) $(CFLAGS) $(INCFLAGS) -c simple_talker.c -../../lib/common/avb.o: ../../lib/common/avb.h ../../lib/common/avb.c - make -C ../../lib/common/ avb.o +$(AVBLIB_DIR)/%.o: $(AVBLIB_DIR)/%.h $(AVBLIB_DIR)/%.c + make -C $(AVBLIB_DIR) $@ -../common/talker_mrp_client.o: ../common/talker_mrp_client.c ../common/talker_mrp_client.h - make -C ../common/ talker_mrp_client.o +$(MRPCLIENT_DIR)/%.o: $(MRPCLIENT_DIR)/%.c $(MRPCLIENT_DIR)/%.h + make -C $(MRPCLIENT_DIR) $@ %: %.o $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ diff --git a/lib/common/Makefile b/lib/common/Makefile index 4621bbf2..5b50f708 100644 --- a/lib/common/Makefile +++ b/lib/common/Makefile @@ -1,12 +1,25 @@ +AVB_FEATURE_IGB ?= 1 + +ifeq ($(AVB_FEATURE_IGB),1) +AVB_IGB_OBJ = avb_igb.o +EXTRA_CFLAGS = -DAVB_FEATURE_IGB=1 +endif + CC ?= gcc OPT = -O2 -g -CFLAGS = $(OPT) -Wall -Wextra -Wno-parentheses +WARN = -Wall -Wextra -Wno-parentheses +CFLAGS = $(OPT) $(WARN) $(EXTRA_CFLAGS) +ALL_OBJS = avb_avtp.o avb_gptp.o $(AVB_IGB_OBJ) + +.PHONY: all clean -all: avb.o +all: $(ALL_OBJS) -avb.o: avb.c avb.h - $(CC) $(CFLAGS) -I../igb -c avb.c +avb_igb.o: CPPFLAGS = -I../igb +avb_igb.o: avb_igb.c avb_igb.h +avb_avtp.o: avb_avtp.c avb_avtp.h +avb_gptp.o: avb_gptp.c avb_gptp.h clean: - $(RM) avb.o talker_mrp_client.o listener_mrp_client.o + $(RM) $(ALL_OBJS) $(RM) `find . -name "*~" -o -name "*.[oa]" -o -name "\#*\#" -o -name TAGS -o -name core -o -name "*.orig"` diff --git a/lib/common/avb.h b/lib/common/avb.h index e5b9f8b6..0cf2d4e7 100644 --- a/lib/common/avb.h +++ b/lib/common/avb.h @@ -16,195 +16,16 @@ * */ -#ifndef __AVBTP_H__ -#define __AVBTP_H__ - -#include <inttypes.h> - -#include <igb.h> - -#define VALID 1 -#define INVALID 0 - -#define MAC_ADDR_LEN 6 - -#define IGB_BIND_NAMESZ 24 - -#define SHM_SIZE (4*8 + sizeof(pthread_mutex_t)) /* 3 - 64 bit and 2 - 32 bits */ -#define SHM_NAME "/ptp" - -#define MAX_SAMPLE_VALUE ((1U << ((sizeof(int32_t)*8)-1))-1) - -#define IEEE_61883_IIDC_SUBTYPE 0x0 - -#define MRPD_PORT_DEFAULT 7500 - -#define STREAM_ID_SIZE 8 - -#define ETHER_TYPE_AVTP 0x22f0 - -typedef struct __attribute__ ((packed)) { - uint64_t subtype:7; - uint64_t cd_indicator:1; - uint64_t timestamp_valid:1; - uint64_t gateway_valid:1; - uint64_t reserved0:1; - uint64_t reset:1; - uint64_t version:3; - uint64_t sid_valid:1; - uint64_t seq_number:8; - uint64_t timestamp_uncertain:1; - uint64_t reserved1:7; - uint64_t stream_id; - uint64_t timestamp:32; - uint64_t gateway_info:32; - uint64_t length:16; - -} seventeen22_header; - -/* 61883 CIP with SYT Field */ -typedef struct { - uint16_t packet_channel:6; - uint16_t format_tag:2; - uint16_t app_control:4; - uint16_t packet_tcode:4; - uint16_t source_id:6; - uint16_t reserved0:2; - uint16_t data_block_size:8; - uint16_t reserved1:2; - uint16_t source_packet_header:1; - uint16_t quadlet_padding_count:3; - uint16_t fraction_number:2; - uint16_t data_block_continuity:8; - uint16_t format_id:6; - uint16_t eoh:2; - uint16_t format_dependent_field:8; - uint16_t syt; -} six1883_header; - -typedef struct { - uint8_t label; - uint8_t value[3]; -} six1883_sample; - -#define ETH_ALEN 6 /* Size of Ethernet address */ - -typedef struct __attribute__ ((packed)) { - /* Destination MAC address. */ - uint8_t h_dest [ETH_ALEN]; - /* Destination MAC address. */ - uint8_t h_source [ETH_ALEN]; - /* Protocol ID. */ - uint8_t h_protocol[2]; -} eth_header; - -typedef long double FrequencyRatio; - -typedef struct { - int64_t ml_phoffset; - int64_t ls_phoffset; - FrequencyRatio ml_freqoffset; - FrequencyRatio ls_freqoffset; - uint64_t local_time; -} gPtpTimeData; - -/*TODO fix this*/ -#ifndef false -typedef enum { false = 0, true = 1 } bool; +#ifndef __AVB_H__ +#define __AVB_H__ + +#include "avb_gptp.h" +#include "avb_srp.h" +#include "avb_avtp.h" +#ifndef AVB_FEATURE_IGB +/* IGB has not been disabled, so assume it is enabled. */ +#define AVB_FEATURE_IGB 1 +#include "avb_igb.h" #endif -int pci_connect(device_t * igb_dev); - -int gptpinit(int *shm_fd, char **shm_map); -int gptpdeinit(int *shm_fd, char **shm_map); -int gptpgetdata(char *shm_mmap, gPtpTimeData *td); -int gptpscaling(char *shm_mmap, gPtpTimeData *td); -bool gptplocaltime(const gPtpTimeData * td, uint64_t* now_local); -bool gptpmaster2local(const gPtpTimeData *td, const uint64_t master, uint64_t *local); - -void avb_set_1722_cd_indicator(seventeen22_header *h1722, uint64_t cd_indicator); -uint64_t avb_get_1722_cd_indicator(seventeen22_header *h1722); -void avb_set_1722_subtype(seventeen22_header *h1722, uint64_t subtype); -uint64_t avb_get_1722_subtype(seventeen22_header *h1722); -void avb_set_1722_sid_valid(seventeen22_header *h1722, uint64_t sid_valid); -uint64_t avb_get_1722_sid_valid(seventeen22_header *h1722); -void avb_set_1722_version(seventeen22_header *h1722, uint64_t version); -uint64_t avb_get_1722_version(seventeen22_header *h1722); -void avb_set_1722_reset(seventeen22_header *h1722, uint64_t reset); -uint64_t avb_get_1722_reset(seventeen22_header *h1722); -void avb_set_1722_reserved0(seventeen22_header *h1722, uint64_t reserved0); -uint64_t avb_get_1722_reserved0(seventeen22_header *h1722); -void avb_set_1722_reserved1(seventeen22_header *h1722, uint64_t reserved1); -uint64_t avb_get_1722_reserved1(seventeen22_header *h1722); -void avb_set_1722_timestamp_uncertain(seventeen22_header *h1722, uint64_t timestamp_uncertain); -uint64_t avb_get_1722_timestamp_uncertain(seventeen22_header *h1722); -void avb_set_1722_timestamp(seventeen22_header *h1722, uint64_t timestamp); -uint64_t avb_get_1722_reset(seventeen22_header *h1722); -void avb_set_1722_reserved0(seventeen22_header *h1722, uint64_t reserved0); -uint64_t avb_get_1722_reserved0(seventeen22_header *h1722); -void avb_set_1722_gateway_valid(seventeen22_header *h1722, uint64_t gateway_valid); -uint64_t avb_get_1722_gateway_valid(seventeen22_header *h1722); -void avb_set_1722_timestamp_valid(seventeen22_header *h1722, uint64_t timestamp_valid); -uint64_t avb_get_1722_timestamp_valid(seventeen22_header *h1722); -void avb_set_1722_reserved1(seventeen22_header *h1722, uint64_t reserved1); -uint64_t avb_get_1722_reserved1(seventeen22_header *h1722); -void avb_set_1722_timestamp_uncertain(seventeen22_header *h1722, uint64_t timestamp_uncertain); -uint64_t avb_get_1722_timestamp_uncertain(seventeen22_header *h1722); -void avb_set_1722_timestamp(seventeen22_header *h1722, uint64_t timestamp); -uint64_t avb_get_1722_timestamp(seventeen22_header *h1722); -void avb_set_1722_gateway_info(seventeen22_header *h1722, uint64_t gateway_info); -uint64_t avb_get_1722_gateway_info(seventeen22_header *h1722); -void avb_set_1722_length(seventeen22_header *h1722, uint64_t length); -uint64_t avb_get_1722_length(seventeen22_header *h1722); -void avb_set_1722_stream_id(seventeen22_header *h1722, uint64_t stream_id); -uint64_t avb_get_1722_stream_id(seventeen22_header *h1722); -void avb_set_1722_seq_number(seventeen22_header *h1722, uint64_t seq_number); -uint64_t avb_get_1722_seq_number(seventeen22_header *h1722); - -void avb_set_61883_packet_channel(six1883_header *h61883, uint16_t packet_channel); -uint16_t avb_get_61883_length(six1883_header *h61883); -void avb_set_61883_format_tag(six1883_header *h61883, uint16_t format_tag); -uint16_t avb_get_61883_format_tag(six1883_header *h61883); -void avb_set_61883_app_control(six1883_header *h61883, uint16_t app_control); -uint16_t avb_get_61883_app_control(six1883_header *h61883); -void avb_set_61883_packet_tcode(six1883_header *h61883, uint16_t packet_tcode); -uint16_t avb_get_61883_packet_tcode(six1883_header *h61883); -void avb_set_61883_source_id(six1883_header *h61883, uint16_t source_id); -uint16_t avb_get_61883_source_id(six1883_header *h61883); -void avb_set_61883_reserved0(six1883_header *h61883, uint16_t reserved0); -uint16_t avb_get_61883_reserved0(six1883_header *h61883); -void avb_set_61883_data_block_size(six1883_header *h61883, uint16_t data_block_size); -uint16_t avb_get_61883_data_block_size(six1883_header *h61883); -void avb_set_61883_reserved1(six1883_header *h61883, uint16_t reserved1); -uint16_t avb_get_61883_reserved1(six1883_header *h61883); -void avb_set_61883_source_packet_header(six1883_header *h61883, uint16_t source_packet_header); -uint16_t avb_get_61883_source_packet_header(six1883_header *h61883); -void avb_set_61883_quadlet_padding_count(six1883_header *h61883, uint16_t quadlet_padding_count); -uint16_t avb_get_61883_quadlet_padding_count(six1883_header *h61883); -void avb_set_61883_fraction_number(six1883_header *h61883, uint16_t fraction_number); -uint16_t avb_get_61883_fraction_number(six1883_header *h61883); -void avb_set_61883_data_block_continuity(six1883_header *h61883, uint16_t data_block_continuity); -uint16_t avb_get_61883_data_block_continuity(six1883_header *h61883); -void avb_set_61883_format_id(six1883_header *h61883, uint16_t format_id); -uint16_t avb_get_61883_format_id(six1883_header *h61883); -void avb_set_61883_eoh(six1883_header *h61883, uint16_t eoh); -uint16_t avb_get_61883_eoh(six1883_header *h61883); -void avb_set_61883_format_dependent_field(six1883_header *h61883, uint16_t format_dependent_field); -uint16_t avb_get_61883_format_dependent_field(six1883_header *h61883); -void avb_set_61883_syt(six1883_header *h61883, uint16_t syt); -uint16_t avb_get_61883_syt(six1883_header *h61883); - -void * avb_create_packet(uint32_t payload_len); - -void avb_initialize_h1722_to_defaults(seventeen22_header *h1722); - -void avb_initialize_61883_to_defaults(six1883_header *h61883); - -int32_t avb_get_iface_mac_address(int8_t *iface, uint8_t *addr); - -int32_t -avb_eth_header_set_mac(eth_header *ethernet_header, uint8_t *addr, int8_t *iface); - -void avb_1722_set_eth_type(eth_header *eth_header); - -#endif /* __AVBTP_H__ */ +#endif /* __AVB_H__ */ diff --git a/lib/common/avb.c b/lib/common/avb_avtp.c index 7c413c14..c8749d29 100644 --- a/lib/common/avb.c +++ b/lib/common/avb_avtp.c @@ -1,235 +1,96 @@ - /* - * Copyright (c) <2013>, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU Lesser General Public License, - * version 2.1, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ +/* + * Copyright (c) <2013>, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "avb_avtp.h" -#include <errno.h> -#include <fcntl.h> -#include <math.h> -#include <pthread.h> -#include <stdio.h> #include <stdlib.h> #include <string.h> +#include <errno.h> #include <unistd.h> #include <arpa/inet.h> - #include <linux/if.h> - -#include <netinet/in.h> - -#include <pci/pci.h> - #include <sys/ioctl.h> -#include <sys/mman.h> #include <sys/socket.h> -#include <sys/stat.h> - -#include "avb.h" -/** - * @brief Connect to the network card - * @param igb_dev [inout] Device handle - * @return 0 for success, ENXIO for failure - */ - -int pci_connect(device_t *igb_dev) -{ - char devpath[IGB_BIND_NAMESZ]; - struct pci_access *pacc; - struct pci_dev *dev; - int err; - - memset(igb_dev, 0, sizeof(device_t)); - pacc = pci_alloc(); - pci_init(pacc); - pci_scan_bus(pacc); - - for (dev = pacc->devices; dev; dev = dev->next) { - pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_CLASS); - igb_dev->pci_vendor_id = dev->vendor_id; - igb_dev->pci_device_id = dev->device_id; - igb_dev->domain = dev->domain; - igb_dev->bus = dev->bus; - igb_dev->dev = dev->dev; - igb_dev->func = dev->func; - snprintf(devpath, IGB_BIND_NAMESZ, "%04x:%02x:%02x.%d", - dev->domain, dev->bus, dev->dev, dev->func); - err = igb_probe(igb_dev); - if (err) { - continue; - } - printf("attaching to %s\n", devpath); - err = igb_attach(devpath, igb_dev); - if (err) { - printf("attach failed! (%s)\n", strerror(err)); - continue; - } - err = igb_attach_tx(igb_dev); - if (err) { - printf("attach_tx failed! (%s)\n", strerror(err)); - igb_detach(igb_dev); - continue; - } - goto out; - } - pci_cleanup(pacc); - return ENXIO; -out: - pci_cleanup(pacc); - return 0; -} - -/** - * @brief Open the memory mapping used for IPC - * @param shm_fd [inout] File descriptor for mapping - * @param shm_map [inout] Pointer to mapping - * @return 0 for success, negative for failure - */ - -int gptpinit(int *shm_fd, char **shm_map) +int32_t avb_get_iface_mac_address(int8_t *iface, uint8_t *addr) { - if (NULL == shm_fd || NULL == shm_map) { - return -1; - } - *shm_fd = shm_open(SHM_NAME, O_RDWR, 0); - if (*shm_fd == -1) { - perror("shm_open()"); - return -1; - } - *shm_map = (char *)mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, - MAP_SHARED, *shm_fd, 0); - if ((char*)-1 == *shm_map) { - perror("mmap()"); - *shm_map = NULL; - shm_unlink(SHM_NAME); - return -1; - } - return 0; -} - -/** - * @brief Free the memory mapping used for IPC - * @param shm_fd [in] File descriptor for mapping - * @param shm_map [in] Pointer to mapping - * @return 0 for success, negative for failure - * -1 = close failed - * -2 = munmap failed - * -3 = close and munmap failed - */ + struct ifreq ifreq; + int fd, ret; -int gptpdeinit(int *shm_fd, char **shm_map) -{ - int ret = 0; - if (NULL == shm_fd || -1 == *shm_fd) { - ret -= 1; - } else { - if(close(*shm_fd) == -1) { - ret -= 1; - } - *shm_fd = -1; - } - if (NULL == shm_map || NULL == *shm_map) { - ret -= 2; - } else { - if (munmap(*shm_map, SHM_SIZE) == -1) { - ret -= 2; - } - *shm_map = NULL; - } - return ret; -} + /* Create a socket */ + fd = socket(PF_PACKET, SOCK_RAW, htons(0x800)); + if (fd < 0) + return -1; -/** - * @brief Read the ptp data from IPC memory - * @param shm_map [in] Pointer to mapping - * @param td [inout] Struct to read the data into - * @return 0 for success, negative for failure - */ + memset(&ifreq, 0, sizeof(ifreq)); -int gptpgetdata(char *shm_map, gPtpTimeData *td) -{ - if (NULL == shm_map || NULL == td) { + strncpy(ifreq.ifr_name, (const char*)iface, sizeof(ifreq.ifr_name)); + ret = ioctl(fd, SIOCGIFHWADDR, &ifreq); + if (ret < 0) { + close(fd); return -1; } - pthread_mutex_lock((pthread_mutex_t *) shm_map); - memcpy(td, shm_map + sizeof(pthread_mutex_t), sizeof(*td)); - pthread_mutex_unlock((pthread_mutex_t *) shm_map); - return 0; -} - -/** - * @brief Read the ptp data from IPC memory and print its contents - * @param shm_map [in] Pointer to mapping - * @param td [inout] Struct to read the data into - * @return 0 for success, negative for failure - */ - -int gptpscaling(char *shm_map, gPtpTimeData *td) //change this function name ?? -{ - int i; - if ((i = gptpgetdata(shm_map, td)) < 0) { - return i; - } - fprintf(stderr, "ml_phoffset = %" PRId64 ", ls_phoffset = %" PRId64 "\n", - td->ml_phoffset, td->ls_phoffset); - fprintf(stderr, "ml_freqffset = %Lf, ls_freqoffset = %Lf\n", - td->ml_freqoffset, td->ls_freqoffset); + memcpy(addr, ifreq.ifr_hwaddr.sa_data, ETH_ALEN); + close(fd); return 0; } -bool gptplocaltime(const gPtpTimeData * td, uint64_t* now_local) +void *avb_create_packet(uint32_t payload_len) { - struct timespec sys_time; - uint64_t now_system; - uint64_t system_time; - int64_t delta_local; - int64_t delta_system; + void *avb_packet = NULL; + uint32_t size; + + size = sizeof(six1883_header); + size += sizeof(eth_header) + sizeof(seventeen22_header) + payload_len; - if (!td || !now_local) - return false; + avb_packet = calloc(size, sizeof(uint8_t)); + if (!avb_packet) + return NULL; - if (clock_gettime(CLOCK_REALTIME, &sys_time) != 0) - return false; + return avb_packet; +} - now_system = (uint64_t)sys_time.tv_sec * 1000000000ULL + (uint64_t)sys_time.tv_nsec; +void avb_1722_set_eth_type(eth_header *eth_header) { - system_time = td->local_time + td->ls_phoffset; - delta_system = now_system - system_time; - delta_local = td->ls_freqoffset * delta_system; - *now_local = td->local_time + delta_local; + eth_header->h_protocol[0] = 0x22; + eth_header->h_protocol[1] = 0xf0; - return true; + return; } -bool gptpmaster2local(const gPtpTimeData *td, const uint64_t master, uint64_t *local) +int32_t +avb_eth_header_set_mac(eth_header *ethernet_header, uint8_t *addr, int8_t *iface) { - int64_t delta_8021as; - int64_t delta_local; + uint8_t source_mac[ETH_ALEN]; - if (!td || !local) - return false; + if (!addr || !iface) + return -EINVAL; - delta_8021as = master - td->local_time + td->ml_phoffset; - delta_local = delta_8021as / td->ml_freqoffset; - *local = td->local_time + delta_local; + if (avb_get_iface_mac_address(iface, source_mac)) + return -EINVAL; - return true; + memcpy(ethernet_header->h_dest, addr, ETH_ALEN); + memcpy(ethernet_header->h_source, source_mac, ETH_ALEN); + + return 0; } /* setters & getters for seventeen22_header */ @@ -383,6 +244,24 @@ uint64_t avb_get_1722_length(seventeen22_header *h1722) return h1722->length; } +void avb_initialize_h1722_to_defaults(seventeen22_header *h1722) +{ + avb_set_1722_subtype(h1722, 0x0); + avb_set_1722_cd_indicator(h1722, 0x0); + avb_set_1722_timestamp_valid(h1722, 0x0); + avb_set_1722_gateway_valid(h1722, 0x0); + avb_set_1722_reserved0(h1722, 0x0); + avb_set_1722_sid_valid(h1722, 0x0); + avb_set_1722_reset(h1722, 0x0); + avb_set_1722_version(h1722, 0x0); + avb_set_1722_seq_number(h1722, 0x0); + avb_set_1722_timestamp_uncertain(h1722, 0x0); + avb_set_1722_reserved1(h1722, 0x0); + avb_set_1722_timestamp(h1722, 0x0); + avb_set_1722_gateway_info(h1722, 0x0); + avb_set_1722_length(h1722, 0x0); +} + /* setters & getters for six1883_header */ void avb_set_61883_packet_channel(six1883_header *h61883, uint16_t packet_channel) @@ -545,39 +424,6 @@ uint16_t avb_get_61883_syt(six1883_header *h61883) return h61883->syt; } -void * avb_create_packet(uint32_t payload_len) -{ - void *avb_packet = NULL; - uint32_t size; - - size = sizeof(six1883_header); - size += sizeof(eth_header) + sizeof(seventeen22_header) + payload_len; - - avb_packet = calloc(size, sizeof(uint8_t)); - if (!avb_packet) - return NULL; - - return avb_packet; -} - -void avb_initialize_h1722_to_defaults(seventeen22_header *h1722) -{ - avb_set_1722_subtype(h1722, 0x0); - avb_set_1722_cd_indicator(h1722, 0x0); - avb_set_1722_timestamp_valid(h1722, 0x0); - avb_set_1722_gateway_valid(h1722, 0x0); - avb_set_1722_reserved0(h1722, 0x0); - avb_set_1722_sid_valid(h1722, 0x0); - avb_set_1722_reset(h1722, 0x0); - avb_set_1722_version(h1722, 0x0); - avb_set_1722_seq_number(h1722, 0x0); - avb_set_1722_timestamp_uncertain(h1722, 0x0); - avb_set_1722_reserved1(h1722, 0x0); - avb_set_1722_timestamp(h1722, 0x0); - avb_set_1722_gateway_info(h1722, 0x0); - avb_set_1722_length(h1722, 0x0); -} - void avb_initialize_61883_to_defaults(six1883_header *h61883) { avb_set_61883_packet_channel(h61883, 0x0); @@ -597,53 +443,3 @@ void avb_initialize_61883_to_defaults(six1883_header *h61883) avb_set_61883_format_dependent_field(h61883, 0x0); avb_set_61883_syt(h61883, 0x0); } - -int32_t avb_get_iface_mac_address(int8_t *iface, uint8_t *addr) -{ - struct ifreq ifreq; - int fd, ret; - - /* Create a socket */ - fd = socket(PF_PACKET, SOCK_RAW, htons(0x800)); - if (fd < 0) - return -1; - - memset(&ifreq, 0, sizeof(ifreq)); - - strncpy(ifreq.ifr_name, (const char*)iface, sizeof(ifreq.ifr_name)); - ret = ioctl(fd, SIOCGIFHWADDR, &ifreq); - if (ret < 0) { - close(fd); - return -1; - } - - memcpy(addr, ifreq.ifr_hwaddr.sa_data, ETH_ALEN); - close(fd); - - return 0; -} - -void avb_1722_set_eth_type(eth_header *eth_header) { - - eth_header->h_protocol[0] = 0x22; - eth_header->h_protocol[1] = 0xf0; - - return; -} - -int32_t -avb_eth_header_set_mac(eth_header *ethernet_header, uint8_t *addr, int8_t *iface) -{ - uint8_t source_mac[ETH_ALEN]; - - if (!addr || !iface) - return -EINVAL; - - if (avb_get_iface_mac_address(iface, source_mac)) - return -EINVAL; - - memcpy(ethernet_header->h_dest, addr, ETH_ALEN); - memcpy(ethernet_header->h_source, source_mac, ETH_ALEN); - - return 0; -} diff --git a/lib/common/avb_avtp.h b/lib/common/avb_avtp.h new file mode 100644 index 00000000..23ceab2b --- /dev/null +++ b/lib/common/avb_avtp.h @@ -0,0 +1,151 @@ +#ifndef __AVB_AVTP_H__ +#define __AVB_AVTP_H__ + +#include <inttypes.h> + +#define MAX_SAMPLE_VALUE ((1U << ((sizeof(int32_t)*8)-1))-1) + +#define IEEE_61883_IIDC_SUBTYPE 0x0 + +#define ETHER_TYPE_AVTP 0x22f0 + +#define ETH_ALEN 6 /* Size of Ethernet address */ + +typedef struct __attribute__ ((packed)) { + /* Destination MAC address. */ + uint8_t h_dest [ETH_ALEN]; + /* Destination MAC address. */ + uint8_t h_source [ETH_ALEN]; + /* Protocol ID. */ + uint8_t h_protocol[2]; +} eth_header; + +typedef struct __attribute__ ((packed)) { + uint64_t subtype:7; + uint64_t cd_indicator:1; + uint64_t timestamp_valid:1; + uint64_t gateway_valid:1; + uint64_t reserved0:1; + uint64_t reset:1; + uint64_t version:3; + uint64_t sid_valid:1; + uint64_t seq_number:8; + uint64_t timestamp_uncertain:1; + uint64_t reserved1:7; + uint64_t stream_id; + uint64_t timestamp:32; + uint64_t gateway_info:32; + uint64_t length:16; +} seventeen22_header; + +/* 61883 CIP with SYT Field */ +typedef struct { + uint16_t packet_channel:6; + uint16_t format_tag:2; + uint16_t app_control:4; + uint16_t packet_tcode:4; + uint16_t source_id:6; + uint16_t reserved0:2; + uint16_t data_block_size:8; + uint16_t reserved1:2; + uint16_t source_packet_header:1; + uint16_t quadlet_padding_count:3; + uint16_t fraction_number:2; + uint16_t data_block_continuity:8; + uint16_t format_id:6; + uint16_t eoh:2; + uint16_t format_dependent_field:8; + uint16_t syt; +} six1883_header; + +typedef struct { + uint8_t label; + uint8_t value[3]; +} six1883_sample; + +void avb_set_1722_cd_indicator(seventeen22_header *h1722, uint64_t cd_indicator); +uint64_t avb_get_1722_cd_indicator(seventeen22_header *h1722); +void avb_set_1722_subtype(seventeen22_header *h1722, uint64_t subtype); +uint64_t avb_get_1722_subtype(seventeen22_header *h1722); +void avb_set_1722_sid_valid(seventeen22_header *h1722, uint64_t sid_valid); +uint64_t avb_get_1722_sid_valid(seventeen22_header *h1722); +void avb_set_1722_version(seventeen22_header *h1722, uint64_t version); +uint64_t avb_get_1722_version(seventeen22_header *h1722); +void avb_set_1722_reset(seventeen22_header *h1722, uint64_t reset); +uint64_t avb_get_1722_reset(seventeen22_header *h1722); +void avb_set_1722_reserved0(seventeen22_header *h1722, uint64_t reserved0); +uint64_t avb_get_1722_reserved0(seventeen22_header *h1722); +void avb_set_1722_reserved1(seventeen22_header *h1722, uint64_t reserved1); +uint64_t avb_get_1722_reserved1(seventeen22_header *h1722); +void avb_set_1722_timestamp_uncertain(seventeen22_header *h1722, uint64_t timestamp_uncertain); +uint64_t avb_get_1722_timestamp_uncertain(seventeen22_header *h1722); +void avb_set_1722_timestamp(seventeen22_header *h1722, uint64_t timestamp); +uint64_t avb_get_1722_reset(seventeen22_header *h1722); +void avb_set_1722_reserved0(seventeen22_header *h1722, uint64_t reserved0); +uint64_t avb_get_1722_reserved0(seventeen22_header *h1722); +void avb_set_1722_gateway_valid(seventeen22_header *h1722, uint64_t gateway_valid); +uint64_t avb_get_1722_gateway_valid(seventeen22_header *h1722); +void avb_set_1722_timestamp_valid(seventeen22_header *h1722, uint64_t timestamp_valid); +uint64_t avb_get_1722_timestamp_valid(seventeen22_header *h1722); +void avb_set_1722_reserved1(seventeen22_header *h1722, uint64_t reserved1); +uint64_t avb_get_1722_reserved1(seventeen22_header *h1722); +void avb_set_1722_timestamp_uncertain(seventeen22_header *h1722, uint64_t timestamp_uncertain); +uint64_t avb_get_1722_timestamp_uncertain(seventeen22_header *h1722); +void avb_set_1722_timestamp(seventeen22_header *h1722, uint64_t timestamp); +uint64_t avb_get_1722_timestamp(seventeen22_header *h1722); +void avb_set_1722_gateway_info(seventeen22_header *h1722, uint64_t gateway_info); +uint64_t avb_get_1722_gateway_info(seventeen22_header *h1722); +void avb_set_1722_length(seventeen22_header *h1722, uint64_t length); +uint64_t avb_get_1722_length(seventeen22_header *h1722); +void avb_set_1722_stream_id(seventeen22_header *h1722, uint64_t stream_id); +uint64_t avb_get_1722_stream_id(seventeen22_header *h1722); +void avb_set_1722_seq_number(seventeen22_header *h1722, uint64_t seq_number); +uint64_t avb_get_1722_seq_number(seventeen22_header *h1722); + +void avb_set_61883_packet_channel(six1883_header *h61883, uint16_t packet_channel); +uint16_t avb_get_61883_length(six1883_header *h61883); +void avb_set_61883_format_tag(six1883_header *h61883, uint16_t format_tag); +uint16_t avb_get_61883_format_tag(six1883_header *h61883); +void avb_set_61883_app_control(six1883_header *h61883, uint16_t app_control); +uint16_t avb_get_61883_app_control(six1883_header *h61883); +void avb_set_61883_packet_tcode(six1883_header *h61883, uint16_t packet_tcode); +uint16_t avb_get_61883_packet_tcode(six1883_header *h61883); +void avb_set_61883_source_id(six1883_header *h61883, uint16_t source_id); +uint16_t avb_get_61883_source_id(six1883_header *h61883); +void avb_set_61883_reserved0(six1883_header *h61883, uint16_t reserved0); +uint16_t avb_get_61883_reserved0(six1883_header *h61883); +void avb_set_61883_data_block_size(six1883_header *h61883, uint16_t data_block_size); +uint16_t avb_get_61883_data_block_size(six1883_header *h61883); +void avb_set_61883_reserved1(six1883_header *h61883, uint16_t reserved1); +uint16_t avb_get_61883_reserved1(six1883_header *h61883); +void avb_set_61883_source_packet_header(six1883_header *h61883, uint16_t source_packet_header); +uint16_t avb_get_61883_source_packet_header(six1883_header *h61883); +void avb_set_61883_quadlet_padding_count(six1883_header *h61883, uint16_t quadlet_padding_count); +uint16_t avb_get_61883_quadlet_padding_count(six1883_header *h61883); +void avb_set_61883_fraction_number(six1883_header *h61883, uint16_t fraction_number); +uint16_t avb_get_61883_fraction_number(six1883_header *h61883); +void avb_set_61883_data_block_continuity(six1883_header *h61883, uint16_t data_block_continuity); +uint16_t avb_get_61883_data_block_continuity(six1883_header *h61883); +void avb_set_61883_format_id(six1883_header *h61883, uint16_t format_id); +uint16_t avb_get_61883_format_id(six1883_header *h61883); +void avb_set_61883_eoh(six1883_header *h61883, uint16_t eoh); +uint16_t avb_get_61883_eoh(six1883_header *h61883); +void avb_set_61883_format_dependent_field(six1883_header *h61883, uint16_t format_dependent_field); +uint16_t avb_get_61883_format_dependent_field(six1883_header *h61883); +void avb_set_61883_syt(six1883_header *h61883, uint16_t syt); +uint16_t avb_get_61883_syt(six1883_header *h61883); + +void * avb_create_packet(uint32_t payload_len); + +void avb_initialize_h1722_to_defaults(seventeen22_header *h1722); + +void avb_initialize_61883_to_defaults(six1883_header *h61883); + +int32_t avb_get_iface_mac_address(int8_t *iface, uint8_t *addr); + +int32_t +avb_eth_header_set_mac(eth_header *ethernet_header, uint8_t *addr, int8_t *iface); + +void avb_1722_set_eth_type(eth_header *eth_header); + +#endif diff --git a/lib/common/avb_gptp.c b/lib/common/avb_gptp.c new file mode 100644 index 00000000..fddf97f5 --- /dev/null +++ b/lib/common/avb_gptp.c @@ -0,0 +1,149 @@ +#include "avb_gptp.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <sys/mman.h> +#include <fcntl.h> +#include <pthread.h> + +/** + * @brief Open the memory mapping used for IPC + * @param shm_fd [inout] File descriptor for mapping + * @param shm_map [inout] Pointer to mapping + * @return 0 for success, negative for failure + */ + +int gptpinit(int *shm_fd, char **shm_map) +{ + if (NULL == shm_fd || NULL == shm_map) { + return -1; + } + *shm_fd = shm_open(SHM_NAME, O_RDWR, 0); + if (*shm_fd == -1) { + perror("shm_open()"); + return -1; + } + *shm_map = (char *)mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, + MAP_SHARED, *shm_fd, 0); + if ((char*)-1 == *shm_map) { + perror("mmap()"); + *shm_map = NULL; + shm_unlink(SHM_NAME); + return -1; + } + return 0; +} + +/** + * @brief Free the memory mapping used for IPC + * @param shm_fd [in] File descriptor for mapping + * @param shm_map [in] Pointer to mapping + * @return 0 for success, negative for failure + * -1 = close failed + * -2 = munmap failed + * -3 = close and munmap failed + */ + +int gptpdeinit(int *shm_fd, char **shm_map) +{ + int ret = 0; + if (NULL == shm_fd || -1 == *shm_fd) { + ret -= 1; + } else { + if(close(*shm_fd) == -1) { + ret -= 1; + } + *shm_fd = -1; + } + if (NULL == shm_map || NULL == *shm_map) { + ret -= 2; + } else { + if (munmap(*shm_map, SHM_SIZE) == -1) { + ret -= 2; + } + *shm_map = NULL; + } + return ret; +} + +/** + * @brief Read the ptp data from IPC memory + * @param shm_map [in] Pointer to mapping + * @param td [inout] Struct to read the data into + * @return 0 for success, negative for failure + */ + +int gptpgetdata(char *shm_map, gPtpTimeData *td) +{ + if (NULL == shm_map || NULL == td) { + return -1; + } + pthread_mutex_lock((pthread_mutex_t *) shm_map); + memcpy(td, shm_map + sizeof(pthread_mutex_t), sizeof(*td)); + pthread_mutex_unlock((pthread_mutex_t *) shm_map); + + return 0; +} + +/** + * @brief Read the ptp data from IPC memory and print its contents + * @param shm_map [in] Pointer to mapping + * @param td [inout] Struct to read the data into + * @return 0 for success, negative for failure + */ + +int gptpscaling(char *shm_map, gPtpTimeData *td) //change this function name ?? +{ + int i; + if ((i = gptpgetdata(shm_map, td)) < 0) { + return i; + } + fprintf(stderr, "ml_phoffset = %" PRId64 ", ls_phoffset = %" PRId64 "\n", + td->ml_phoffset, td->ls_phoffset); + fprintf(stderr, "ml_freqffset = %Lf, ls_freqoffset = %Lf\n", + td->ml_freqoffset, td->ls_freqoffset); + + return 0; +} + +bool gptplocaltime(const gPtpTimeData * td, uint64_t* now_local) +{ + struct timespec sys_time; + uint64_t now_system; + uint64_t system_time; + int64_t delta_local; + int64_t delta_system; + + if (!td || !now_local) + return false; + + if (clock_gettime(CLOCK_REALTIME, &sys_time) != 0) + return false; + + now_system = (uint64_t)sys_time.tv_sec * 1000000000ULL + (uint64_t)sys_time.tv_nsec; + + system_time = td->local_time + td->ls_phoffset; + delta_system = now_system - system_time; + delta_local = td->ls_freqoffset * delta_system; + *now_local = td->local_time + delta_local; + + return true; +} + +bool gptpmaster2local(const gPtpTimeData *td, const uint64_t master, uint64_t *local) +{ + int64_t delta_8021as; + int64_t delta_local; + + if (!td || !local) + return false; + + delta_8021as = master - td->local_time + td->ml_phoffset; + delta_local = delta_8021as / td->ml_freqoffset; + *local = td->local_time + delta_local; + + return true; +} diff --git a/lib/common/avb_gptp.h b/lib/common/avb_gptp.h new file mode 100644 index 00000000..9652a5a1 --- /dev/null +++ b/lib/common/avb_gptp.h @@ -0,0 +1,50 @@ +#ifndef __AVB_GPTP_H__ +#define __AVB_GPTP_H__ + +#include <inttypes.h> + +#define SHM_SIZE (4*8 + sizeof(pthread_mutex_t)) /* 3 - 64 bit and 2 - 32 bits */ +#define SHM_NAME "/ptp" + +typedef long double FrequencyRatio; + +typedef struct { + int64_t ml_phoffset; + int64_t ls_phoffset; + FrequencyRatio ml_freqoffset; + FrequencyRatio ls_freqoffset; + uint64_t local_time; + + /* Current grandmaster information */ + /* Referenced by the IEEE Std 1722.1-2013 AVDECC Discovery Protocol Data Unit (ADPDU) */ + uint8_t gptp_grandmaster_id[8]; /* Current grandmaster id (all 0's if no grandmaster selected) */ + uint8_t gptp_domain_number; /* gPTP domain number */ + + /* Grandmaster support for the network interface */ + /* Referenced by the IEEE Std 1722.1-2013 AVDECC AVB_INTERFACE descriptor */ + uint8_t clock_identity[8]; /* The clock identity of the interface */ + uint8_t priority1; /* The priority1 field of the grandmaster functionality of the interface, or 0xFF if not supported */ + uint8_t clock_class; /* The clockClass field of the grandmaster functionality of the interface, or 0xFF if not supported */ + int16_t offset_scaled_log_variance; /* The offsetScaledLogVariance field of the grandmaster functionality of the interface, or 0x0000 if not supported */ + uint8_t clock_accuracy; /* The clockAccuracy field of the grandmaster functionality of the interface, or 0xFF if not supported */ + uint8_t priority2; /* The priority2 field of the grandmaster functionality of the interface, or 0xFF if not supported */ + uint8_t domain_number; /* The domainNumber field of the grandmaster functionality of the interface, or 0 if not supported */ + int8_t log_sync_interval; /* The currentLogSyncInterval field of the grandmaster functionality of the interface, or 0 if not supported */ + int8_t log_announce_interval; /* The currentLogAnnounceInterval field of the grandmaster functionality of the interface, or 0 if not supported */ + int8_t log_pdelay_interval; /* The currentLogPDelayReqInterval field of the grandmaster functionality of the interface, or 0 if not supported */ + uint16_t port_number; /* The portNumber field of the interface, or 0x0000 if not supported */ +} gPtpTimeData; + +/*TODO fix this*/ +#ifndef false +typedef enum { false = 0, true = 1 } bool; +#endif + +int gptpinit(int *shm_fd, char **shm_map); +int gptpdeinit(int *shm_fd, char **shm_map); +int gptpgetdata(char *shm_mmap, gPtpTimeData *td); +int gptpscaling(char *shm_mmap, gPtpTimeData *td); +bool gptplocaltime(const gPtpTimeData * td, uint64_t* now_local); +bool gptpmaster2local(const gPtpTimeData *td, const uint64_t master, uint64_t *local); + +#endif diff --git a/lib/common/avb_igb.c b/lib/common/avb_igb.c new file mode 100644 index 00000000..e83ab411 --- /dev/null +++ b/lib/common/avb_igb.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) <2013>, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "avb_igb.h" + +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include <pci/pci.h> + +/** + * @brief Connect to the network card + * @param igb_dev [inout] Device handle + * @return 0 for success, ENXIO for failure + */ + +int pci_connect(device_t *igb_dev) +{ + char devpath[IGB_BIND_NAMESZ]; + struct pci_access *pacc; + struct pci_dev *dev; + int err; + + memset(igb_dev, 0, sizeof(device_t)); + pacc = pci_alloc(); + pci_init(pacc); + pci_scan_bus(pacc); + + for (dev = pacc->devices; dev; dev = dev->next) { + pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_CLASS); + igb_dev->pci_vendor_id = dev->vendor_id; + igb_dev->pci_device_id = dev->device_id; + igb_dev->domain = dev->domain; + igb_dev->bus = dev->bus; + igb_dev->dev = dev->dev; + igb_dev->func = dev->func; + snprintf(devpath, IGB_BIND_NAMESZ, "%04x:%02x:%02x.%d", + dev->domain, dev->bus, dev->dev, dev->func); + err = igb_probe(igb_dev); + if (err) { + continue; + } + printf("attaching to %s\n", devpath); + err = igb_attach(devpath, igb_dev); + if (err) { + printf("attach failed! (%s)\n", strerror(err)); + continue; + } + err = igb_attach_tx(igb_dev); + if (err) { + printf("attach_tx failed! (%s)\n", strerror(err)); + igb_detach(igb_dev); + continue; + } + goto out; + } + pci_cleanup(pacc); + return ENXIO; +out: + pci_cleanup(pacc); + return 0; +} diff --git a/lib/common/avb_igb.h b/lib/common/avb_igb.h new file mode 100644 index 00000000..1de3fa69 --- /dev/null +++ b/lib/common/avb_igb.h @@ -0,0 +1,10 @@ +#ifndef __AVB_IGB_H__ +#define __AVB_IGB_H__ + +#include <igb.h> + +#define IGB_BIND_NAMESZ 24 + +int pci_connect(device_t * igb_dev); + +#endif diff --git a/lib/common/avb_srp.h b/lib/common/avb_srp.h new file mode 100644 index 00000000..f4e4ab08 --- /dev/null +++ b/lib/common/avb_srp.h @@ -0,0 +1,6 @@ +#ifndef __AVB_SRP_H__ +#define __AVB_SRP_H__ + +#define MRPD_PORT_DEFAULT 7500 + +#endif |