summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Cemin <david.cemin@coveloz.com>2015-11-05 09:15:55 -0500
committerDavid Cemin <david.cemin@coveloz.com>2015-11-05 09:15:55 -0500
commitefb699685e515b4b82d84c4fcd6b2b75a6cbbc37 (patch)
tree6b0e7584333417f96c5c44304d11136dfd3f8752
parentfb6f803be77bef42f0cbfe952eac3f7de13882b0 (diff)
parent01d4ac52885e18bc3f6c37ef5a0e583186b02d17 (diff)
downloadOpen-AVB-efb699685e515b4b82d84c4fcd6b2b75a6cbbc37.tar.gz
Merge remote-tracking branch 'upstream/open-avb-next' into open-avb-next
-rw-r--r--daemons/gptp/common/avbts_osnet.cpp40
-rw-r--r--daemons/gptp/common/avbts_osnet.hpp2
-rw-r--r--daemons/gptp/common/avbts_port.hpp5
-rw-r--r--daemons/gptp/common/ieee1588.hpp50
-rw-r--r--daemons/gptp/common/ieee1588port.cpp111
-rw-r--r--daemons/gptp/linux/src/daemon_cl.cpp107
-rw-r--r--daemons/gptp/linux/src/linux_hal_common.cpp103
-rw-r--r--daemons/gptp/linux/src/linux_hal_common.hpp46
-rw-r--r--daemons/gptp/linux/src/linux_hal_generic.cpp119
-rw-r--r--examples/common/listener_mrp_client.c261
-rw-r--r--examples/common/listener_mrp_client.h50
-rw-r--r--examples/common/talker_mrp_client.c229
-rw-r--r--examples/common/talker_mrp_client.h90
-rw-r--r--examples/jackd-listener/Makefile2
-rw-r--r--examples/jackd-listener/jack_listener.c113
-rw-r--r--examples/jackd-talker/Makefile3
-rw-r--r--examples/jackd-talker/jack.c29
-rw-r--r--examples/jackd-talker/jack.h3
-rw-r--r--[-rwxr-xr-x]examples/jackd-talker/jackd_talker.c116
-rw-r--r--examples/live_stream/listener.c54
-rw-r--r--examples/live_stream/talker.c73
-rw-r--r--examples/simple_listener/Makefile2
-rw-r--r--examples/simple_listener/simple_listener.c88
-rw-r--r--examples/simple_talker/simple_talker.c155
-rw-r--r--lib/avtp_pipeline/documents/Doxyfile.in2
-rw-r--r--lib/avtp_pipeline/documents/images/harman_logo.pngbin0 -> 3512 bytes
-rw-r--r--lib/avtp_pipeline/documents/images/stc_logo_small.pngbin9614 -> 0 bytes
27 files changed, 1109 insertions, 744 deletions
diff --git a/daemons/gptp/common/avbts_osnet.cpp b/daemons/gptp/common/avbts_osnet.cpp
index 57c751e8..6c930d70 100644
--- a/daemons/gptp/common/avbts_osnet.cpp
+++ b/daemons/gptp/common/avbts_osnet.cpp
@@ -1,31 +1,31 @@
/******************************************************************************
- Copyright (c) 2009-2012, Intel Corporation
+ Copyright (c) 2009-2012, Intel Corporation
All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
+
+ Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
+
+ 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
+
+ 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. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
-
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
diff --git a/daemons/gptp/common/avbts_osnet.hpp b/daemons/gptp/common/avbts_osnet.hpp
index dec9af3b..30552a09 100644
--- a/daemons/gptp/common/avbts_osnet.hpp
+++ b/daemons/gptp/common/avbts_osnet.hpp
@@ -296,7 +296,7 @@ class OSNetworkInterface {
* @return net_result enumeration
*/
virtual net_result nrecv
- (LinkLayerAddress * addr, uint8_t * payload, size_t & length) = 0;
+ (LinkLayerAddress * addr, uint8_t * payload, size_t & length, struct phy_delay *delay) = 0;
/**
* @brief Get Link Layer address (mac address)
diff --git a/daemons/gptp/common/avbts_port.hpp b/daemons/gptp/common/avbts_port.hpp
index 0d2841c2..5d9a4d2c 100644
--- a/daemons/gptp/common/avbts_port.hpp
+++ b/daemons/gptp/common/avbts_port.hpp
@@ -426,7 +426,7 @@ class IEEE1588Port {
* hardware timestamper and create OS locks conditions
* @return FALSE if error during building the interface. TRUE if success
*/
- bool init_port();
+ bool init_port(int delay[4]);
/**
* @brief Currently doesnt do anything. Just returns.
@@ -438,7 +438,7 @@ class IEEE1588Port {
* @brief Receives messages from the network interface
* @return Its an infinite loop. Returns NULL in case of error.
*/
- void *openPort(void);
+ void *openPort(IEEE1588Port *port);
/**
* @brief Get the payload offset inside a packet
@@ -959,4 +959,3 @@ class IEEE1588Port {
};
#endif
-
diff --git a/daemons/gptp/common/ieee1588.hpp b/daemons/gptp/common/ieee1588.hpp
index 531136c2..56e3a585 100644
--- a/daemons/gptp/common/ieee1588.hpp
+++ b/daemons/gptp/common/ieee1588.hpp
@@ -95,6 +95,14 @@ typedef struct {
Event event; //!< Event enumeration
} event_descriptor_t;
+struct phy_delay
+{
+ int mb_tx_phy_delay;
+ int mb_rx_phy_delay;
+ int gb_tx_phy_delay;
+ int gb_rx_phy_delay;
+};
+
/**
* Provides a generic InterfaceLabel class
*/
@@ -441,8 +449,10 @@ static inline void TIMESTAMP_ADD_NS( Timestamp &ts, uint64_t ns ) {
* Provides a generic interface for hardware timestamping
*/
class HWTimestamper {
+
protected:
uint8_t version; //!< HWTimestamper version
+ struct phy_delay delay;
public:
/**
* @brief Initializes the hardware timestamp unit
@@ -478,7 +488,7 @@ public:
{ return false; }
/**
- * @brief Get the cross timestamping information.
+ * @brief Get the cross timestamping information.
* The gPTP subsystem uses these samples to calculate
* ratios which can be used to translate or extrapolate
* one clock into another clock reference. The gPTP service
@@ -501,7 +511,7 @@ public:
* @param sequenceId Sequence ID
* @param timestamp [out] Timestamp value
* @param clock_value [out] Clock value
- * @param last Signalizes that it is the last timestamp to get. When TRUE, releases the lock when its done.
+ * @param last Signalizes that it is the last timestamp to get. When TRUE, releases the lock when its done.
* @return 0 no error, -1 error, -72 try again.
*/
virtual int HWTimestamper_txtimestamp(PortIdentity * identity,
@@ -516,7 +526,7 @@ public:
* @param sequenceId Sequence ID
* @param timestamp [out] Timestamp value
* @param clock_value [out] Clock value
- * @param last Signalizes that it is the last timestamp to get. When TRUE, releases the lock when its done.
+ * @param last Signalizes that it is the last timestamp to get. When TRUE, releases the lock when its done.
* @return 0 no error, -1 error, -72 try again.
*/
virtual int HWTimestamper_rxtimestamp(PortIdentity * identity,
@@ -532,7 +542,7 @@ public:
* @param ppt_freq_offset [inout] Frequency offset in ppts
* @return false
* @todo This code should be removed. It was a hack to get a specific board
- * working.
+ * working.
*/
virtual bool HWTimestamper_get_extclk_offset(Timestamp * local_time,
int64_t * clk_offset,
@@ -570,6 +580,38 @@ public:
int getVersion() {
return version;
}
+ /**
+ * @brief Initializes the PHY delay for TX and RX
+ * @param [input] mb_tx_phy_delay, mb_rx_phy_delay, gb_tx_phy_delay, gb_rx_phy_delay
+ * @return 0
+ **/
+
+ int init_phy_delay(int phy_delay[4])
+ {
+ delay.gb_tx_phy_delay = phy_delay[0];
+ delay.gb_rx_phy_delay = phy_delay[1];
+ delay.mb_tx_phy_delay = phy_delay[2];
+ delay.mb_rx_phy_delay = phy_delay[3];
+
+
+ return 0;
+ }
+
+ /**
+ * @brief Returns the the PHY delay for TX and RX
+ * @param [input] struct phy_delay pointer
+ * @return 0
+ **/
+
+ int get_phy_delay (struct phy_delay *get_delay)
+ {
+ get_delay->mb_tx_phy_delay = delay.mb_tx_phy_delay;
+ get_delay->mb_rx_phy_delay = delay.mb_rx_phy_delay;
+ get_delay->gb_tx_phy_delay = delay.gb_tx_phy_delay;
+ get_delay->gb_rx_phy_delay = delay.gb_rx_phy_delay;
+
+ return 0;
+ }
/**
* Default constructor. Sets version to zero.
diff --git a/daemons/gptp/common/ieee1588port.cpp b/daemons/gptp/common/ieee1588port.cpp
index c9db2207..333589eb 100644
--- a/daemons/gptp/common/ieee1588port.cpp
+++ b/daemons/gptp/common/ieee1588port.cpp
@@ -1,31 +1,31 @@
/******************************************************************************
- Copyright (c) 2009-2012, Intel Corporation
+ Copyright (c) 2009-2012, Intel Corporation
All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
+
+ Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
+
+ 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
+
+ 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. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
-
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
@@ -55,7 +55,7 @@ OSThreadExitCode openPortWrapper(void *arg)
IEEE1588Port *port;
port = (IEEE1588Port *) arg;
- if (port->openPort() == NULL)
+ if (port->openPort(port) == NULL)
return osthread_ok;
else
return osthread_error;
@@ -128,7 +128,7 @@ IEEE1588Port::IEEE1588Port
sync_count = 0;
}
-bool IEEE1588Port::init_port()
+bool IEEE1588Port::init_port(int delay[4])
{
if (!OSNetworkInterfaceFactory::buildInterface
(&net_iface, factory_name_t("default"), net_label, _hw_timestamper))
@@ -146,6 +146,7 @@ bool IEEE1588Port::init_port()
_hw_timestamper = NULL;
}
}
+ _hw_timestamper->init_phy_delay(delay);
pdelay_rx_lock = lock_factory->createLock(oslock_recursive);
port_tx_lock = lock_factory->createLock(oslock_recursive);
@@ -169,7 +170,7 @@ void IEEE1588Port::startAnnounce() {
bool IEEE1588Port::serializeState( void *buf, off_t *count ) {
bool ret = true;
-
+
if( buf == NULL ) {
*count = sizeof(port_state)+sizeof(_peer_rate_offset)+
sizeof(asCapable)+sizeof(one_way_delay);
@@ -236,7 +237,7 @@ bool IEEE1588Port::serializeState( void *buf, off_t *count ) {
bool IEEE1588Port::restoreSerializedState( void *buf, off_t *count ) {
bool ret = true;
-
+
/* asCapable */
if( ret && *count >= (off_t) sizeof( asCapable )) {
memcpy( &asCapable, buf, sizeof( asCapable ));
@@ -288,9 +289,11 @@ bool IEEE1588Port::restoreSerializedState( void *buf, off_t *count ) {
return ret;
}
-void *IEEE1588Port::openPort(void)
+void *IEEE1588Port::openPort(IEEE1588Port *port)
{
port_ready_condition->signal();
+ struct phy_delay get_delay;
+ port->_hw_timestamper->get_phy_delay(&get_delay);
while (1) {
PTPMessageCommon *msg;
@@ -299,7 +302,7 @@ void *IEEE1588Port::openPort(void)
net_result rrecv;
size_t length = sizeof(buf);
- if ((rrecv = net_iface->nrecv(&remote, buf, length)) == net_succeed) {
+ if ((rrecv = net_iface->nrecv(&remote, buf, length,&get_delay)) == net_succeed) {
XPTPD_INFO("Processing network buffer");
msg = buildPTPMessage((char *)buf, (int)length, &remote,
this);
@@ -374,7 +377,7 @@ void IEEE1588Port::processEvent(Event e)
{
bool changed_external_master;
OSTimer *timer = timer_factory->createTimer();
-
+
switch (e) {
case POWERUP:
case INITIALIZE:
@@ -386,11 +389,11 @@ void IEEE1588Port::processEvent(Event e)
unsigned long long interval4;
Event e3 = NULL_EVENT;
Event e4 = NULL_EVENT;
-
+
if( port_state != PTP_MASTER ) {
_accelerated_sync_count = -1;
}
-
+
if( port_state != PTP_SLAVE && port_state != PTP_MASTER ) {
fprintf( stderr, "Starting PDelay\n" );
startPDelay();
@@ -410,7 +413,7 @@ void IEEE1588Port::processEvent(Event e)
(ANNOUNCE_RECEIPT_TIMEOUT_MULTIPLIER*
pow((double)2,getAnnounceInterval())*1000000000.0);
}
-
+
port_ready_condition->wait_prelock();
listening_thread = thread_factory->createThread();
if (!listening_thread->
@@ -420,13 +423,13 @@ void IEEE1588Port::processEvent(Event e)
return;
}
port_ready_condition->wait();
-
+
if (e3 != NULL_EVENT)
clock->addEventTimer(this, e3, interval3);
if (e4 != NULL_EVENT)
clock->addEventTimer(this, e4, interval4);
}
-
+
clock->putTimerQLock();
break;
@@ -439,7 +442,7 @@ void IEEE1588Port::processEvent(Event e)
IEEE1588Port **ports;
clock->getPortList(number_ports, ports);
-
+
/* Find EBest for all ports */
j = 0;
@@ -461,7 +464,7 @@ void IEEE1588Port::processEvent(Event e)
/* Check if we've changed */
{
-
+
uint8_t LastEBestClockIdentity[PTP_CLOCK_IDENTITY_LENGTH];
clock->getLastEBestIdentity().
getIdentityString( LastEBestClockIdentity );
@@ -478,14 +481,14 @@ void IEEE1588Port::processEvent(Event e)
changed_external_master = false;
}
}
-
+
if( clock->isBetterThan( EBest )) {
// We're Grandmaster, set grandmaster info to me
ClockIdentity clock_identity;
unsigned char priority1;
unsigned char priority2;
ClockQuality clock_quality;
-
+
clock_identity = getClock()->getClockIdentity();
getClock()->setGrandmasterClockIdentity( clock_identity );
priority1 = getClock()->getPriority1();
@@ -516,10 +519,10 @@ void IEEE1588Port::processEvent(Event e)
unsigned char priority1;
unsigned char priority2;
ClockQuality *clock_quality;
-
+
ports[j]->recommendState
( PTP_SLAVE, changed_external_master );
-
+
clock_identity = EBest->getGrandmasterClockIdentity();
getClock()->setGrandmasterClockIdentity(clock_identity);
priority1 = EBest->getGrandmasterPriority1();
@@ -529,7 +532,7 @@ void IEEE1588Port::processEvent(Event e)
clock_quality = EBest->getGrandmasterClockQuality();
getClock()->setGrandmasterClockQuality(*clock_quality);
} else {
- /* Otherwise we are the master because we have
+ /* Otherwise we are the master because we have
sync'd to a better clock */
ports[j]->recommendState
(PTP_MASTER, changed_external_master);
@@ -566,7 +569,7 @@ void IEEE1588Port::processEvent(Event e)
|| port_state == PTP_PRE_MASTER) {
fprintf
(stderr,
- "*** %s Timeout Expired - Becoming Master\n",
+ "*** %s Timeout Expired - Becoming Master\n",
e == ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES ? "Announce" :
"Sync" );
{
@@ -575,7 +578,7 @@ void IEEE1588Port::processEvent(Event e)
unsigned char priority1;
unsigned char priority2;
ClockQuality clock_quality;
-
+
clock_identity = getClock()->getClockIdentity();
getClock()->setGrandmasterClockIdentity( clock_identity );
priority1 = getClock()->getPriority1();
@@ -604,7 +607,7 @@ void IEEE1588Port::processEvent(Event e)
clock->addEventTimer
( this, SYNC_INTERVAL_TIMEOUT_EXPIRES, 16000000 );
startAnnounce();
- //
+ //
}
}
@@ -624,7 +627,7 @@ void IEEE1588Port::processEvent(Event e)
PortIdentity dest_id;
getPortIdentity(dest_id);
pdelay_req->setPortIdentity(&dest_id);
-
+
{
Timestamp pending =
PDELAY_PENDING_TIMESTAMP;
@@ -700,8 +703,8 @@ void IEEE1588Port::processEvent(Event e)
timeout : EVENT_TIMER_GRANULARITY;
clock->addEventTimer
(this, PDELAY_RESP_RECEIPT_TIMEOUT_EXPIRES, timeout );
-
- interval =
+
+ interval =
((long long)
(pow((double)2,getPDelayInterval())*1000000000.0)) -
wait_time*1000;
@@ -722,7 +725,7 @@ void IEEE1588Port::processEvent(Event e)
FrequencyRatio local_system_freq_offset;
int64_t local_system_offset;
long long wait_time = 0;
-
+
uint32_t local_clock, nominal_clock_rate;
// Send a sync message and then a followup to broadcast
@@ -734,7 +737,7 @@ void IEEE1588Port::processEvent(Event e)
getTxLock();
sync->sendPort(this, NULL);
XPTPD_INFO("Sent SYNC message");
-
+
int ts_good;
Timestamp sync_timestamp;
unsigned sync_timestamp_counter_value;
@@ -754,12 +757,12 @@ void IEEE1588Port::processEvent(Event e)
"error=%d", ts_good);
ts_good =
getTxTimestamp
- (sync, sync_timestamp,
+ (sync, sync_timestamp,
sync_timestamp_counter_value, iter == 0);
req *= 2;
}
putTxLock();
-
+
if (ts_good != 0) {
char msg
[HWTIMESTAMPER_EXTENDED_MESSAGE_SIZE];
@@ -781,7 +784,7 @@ void IEEE1588Port::processEvent(Event e)
XPTPD_INFO
("*** Unsuccessful Sync timestamp");
}
-
+
PTPMessageFollowUp *follow_up;
if (ts_good == 0) {
follow_up =
@@ -801,12 +804,12 @@ void IEEE1588Port::processEvent(Event e)
causing an update to local/system timestamp */
getDeviceTime
(system_time, device_time, local_clock, nominal_clock_rate);
-
+
XPTPD_INFO
("port::processEvent(): System time: %u,%u Device Time: %u,%u",
system_time.seconds_ls, system_time.nanoseconds,
device_time.seconds_ls, device_time.nanoseconds);
-
+
local_system_offset =
TIMESTAMP_TO_NS(system_time) -
TIMESTAMP_TO_NS(device_time);
@@ -839,7 +842,7 @@ void IEEE1588Port::processEvent(Event e)
clock->addEventTimer
( this, SYNC_INTERVAL_TIMEOUT_EXPIRES, wait_time );
}
-
+
}
break;
case ANNOUNCE_INTERVAL_TIMEOUT_EXPIRES:
@@ -952,7 +955,7 @@ void IEEE1588Port::becomeSlave( bool restart_syntonization ) {
(pow((double)2,getAnnounceInterval())*1000000000.0)));
fprintf( stderr, "Switching to Slave\n" );
if( restart_syntonization ) clock->newSyntonizationSetPoint();
-
+
return;
}
diff --git a/daemons/gptp/linux/src/daemon_cl.cpp b/daemons/gptp/linux/src/daemon_cl.cpp
index e61d1c53..9e0e58f6 100644
--- a/daemons/gptp/linux/src/daemon_cl.cpp
+++ b/daemons/gptp/linux/src/daemon_cl.cpp
@@ -1,31 +1,31 @@
/******************************************************************************
- Copyright (c) 2012 Intel Corporation
+ Copyright (c) 2012 Intel Corporation
All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
+
+ Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
+
+ 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
+
+ 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. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
-
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
@@ -48,11 +48,15 @@
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
+#define PHY_DELAY_GB_TX_I20 184 //1G delay
+#define PHY_DELAY_GB_RX_I20 382 //1G delay
+#define PHY_DELAY_MB_TX_I20 1044//100M delay
+#define PHY_DELAY_MB_RX_I20 2133//100M delay
void print_usage( char *arg0 ) {
fprintf( stderr,
"%s <network interface> [-S] [-P] [-M <filename>] "
- "[-A <count>] [-G <group>] [-R <priority 1>]\n",
+ "[-A <count>] [-G <group>] [-R <priority 1>] [-D <gb_tx_delay,gb_rx_delay,mb_tx_delay,mb_rx_delay>]\n",
arg0 );
fprintf
( stderr,
@@ -60,7 +64,7 @@ void print_usage( char *arg0 ) {
"\t-M <filename> save/restore state\n"
"\t-A <count> initial accelerated sync count\n"
"\t-G <group> group id for shared memory\n"
- "\t-R <priority 1> priority 1 value\n"
+ "\t-R <priority 1> priority 1 value\n"
"\t-T force master\n\t-L force slave\n" );
}
@@ -84,7 +88,7 @@ int main(int argc, char **argv)
off_t restoredatacount;
bool restorefailed = false;
LinuxIPCArg *ipc_arg = NULL;
-
+
int accelerated_sync_count = 0;
// Block SIGUSR1
@@ -97,7 +101,11 @@ int main(int argc, char **argv)
return -1;
}
}
-
+
+ int phy_delay[4]={0,0,0,0};
+ bool input_delay=false;
+
+
LinuxNetworkInterfaceFactory *default_factory =
new LinuxNetworkInterfaceFactory;
OSNetworkInterfaceFactory::registerFactory
@@ -114,7 +122,7 @@ int main(int argc, char **argv)
print_usage( argv[0] );
return -1;
}
- ifname = new InterfaceName( argv[1], strlen(argv[1]) );
+ ifname = new InterfaceName( argv[1], strlen(argv[1]) );
/* Process optional arguments */
for( i = 2; i < argc; ++i ) {
@@ -179,9 +187,40 @@ int main(int argc, char **argv)
}
}
}
+ else if(toupper(argv[i][1]) == 'D'){
+ input_delay=true;
+ int delay_count=0;
+ char *cli_inp_delay = strtok(argv[i+1],",");
+ while (cli_inp_delay != NULL)
+ {
+ if(delay_count>3)
+ {
+ printf("Too many values\n");
+ print_usage( argv[0] );
+ return 0;
+ }
+ phy_delay[delay_count]=atoi(cli_inp_delay);
+ delay_count++;
+ cli_inp_delay = strtok(NULL,",");
+ }
+ if (delay_count != 4)
+ {
+ printf("All four delay values must be specified\n");
+ print_usage( argv[0] );
+ return 0;
+ }
+ }
}
}
-
+
+ if (!input_delay)
+ {
+ phy_delay[0] = PHY_DELAY_GB_TX_I20;
+ phy_delay[1] = PHY_DELAY_GB_RX_I20;
+ phy_delay[2] = PHY_DELAY_MB_TX_I20;
+ phy_delay[3] = PHY_DELAY_MB_RX_I20;
+ }
+
if( !ipc->init( ipc_arg ) ) {
delete ipc;
ipc = NULL;
@@ -209,7 +248,7 @@ int main(int argc, char **argv)
}
}
}
-
+
if (argc < 2)
return -1;
ifname = new InterfaceName(argv[1], strlen(argv[1]));
@@ -231,11 +270,11 @@ int main(int argc, char **argv)
IEEE1588Clock *clock =
new IEEE1588Clock( false, syntonize, priority1, timestamper,
timerq_factory , ipc, lock_factory );
-
+
if( restoredataptr != NULL ) {
if( !restorefailed )
restorefailed =
- !clock->restoreSerializedState( restoredataptr,
+ !clock->restoreSerializedState( restoredataptr,
&restoredatacount );
restoredataptr = ((char *)restoredata) +
(restoredatalength - restoredatacount);
@@ -245,7 +284,7 @@ int main(int argc, char **argv)
new IEEE1588Port
( clock, 1, false, accelerated_sync_count, timestamper, 0, ifname,
condition_factory, thread_factory, timer_factory, lock_factory );
- if (!port->init_port()) {
+ if (!port->init_port(phy_delay)) {
printf("failed to initialize port \n");
return -1;
}
@@ -288,7 +327,7 @@ int main(int argc, char **argv)
restoredatacount += len;
port->serializeState( NULL, &len );
restoredatacount += len;
-
+
if( restoredatacount > restoredatalength ) {
ftruncate( restorefd, restoredatacount );
if( restoredata != ((void *) -1)) {
@@ -303,7 +342,7 @@ int main(int argc, char **argv)
if( restoredata == ((void *) -1 )) goto remap_failed;
restoredatalength = restoredatacount;
}
-
+
restoredataptr = (char *) restoredata;
clock->serializeState( restoredataptr, &restoredatacount );
restoredataptr = ((char *)restoredata) +
@@ -314,8 +353,8 @@ int main(int argc, char **argv)
remap_failed:
;;
}
-
-
+
+
if( restoredata != ((void *) -1 ))
munmap( restoredata, restoredatalength );
}
diff --git a/daemons/gptp/linux/src/linux_hal_common.cpp b/daemons/gptp/linux/src/linux_hal_common.cpp
index 6ae648da..0530da2b 100644
--- a/daemons/gptp/linux/src/linux_hal_common.cpp
+++ b/daemons/gptp/linux/src/linux_hal_common.cpp
@@ -1,31 +1,31 @@
/******************************************************************************
- Copyright (c) 2009-2012, Intel Corporation
+ Copyright (c) 2009-2012, Intel Corporation
All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
+
+ Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
+
+ 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
+
+ 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. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
-
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
@@ -89,7 +89,7 @@ net_result LinuxNetworkInterface::send
addr->toOctetArray( remote->sll_addr );
if( timestamp ) {
-#ifndef ARCH_INTELCE
+#ifndef ARCH_INTELCE
net_lock.lock();
#endif
err = sendto
@@ -113,7 +113,7 @@ void LinuxNetworkInterface::disable_clear_rx_queue() {
struct packet_mreq mr_8021as;
int err;
char buf[256];
-
+
if( !net_lock.lock() ) {
fprintf( stderr, "D rx lock failed\n" );
_exit(0);
@@ -133,9 +133,9 @@ void LinuxNetworkInterface::disable_clear_rx_queue() {
ifindex );
return;
}
-
+
while( recvfrom( sd_event, buf, 256, MSG_DONTWAIT, NULL, 0 ) != -1 );
-
+
return;
}
@@ -193,9 +193,9 @@ void *LinuxTimerQueueHandler( void *arg ) {
sigset_t waitfor;
struct timespec timeout;
timeout.tv_sec = 0; timeout.tv_nsec = 100000000; /* 100 ms */
-
+
sigemptyset( &waitfor );
-
+
while( !timerq->stop ) {
siginfo_t info;
LinuxTimerQueueMap_t::iterator iter;
@@ -255,7 +255,7 @@ OSTimerQueue *LinuxTimerQueueFactory::createOSTimerQueue
return ret;
}
-
+
bool LinuxTimerQueue::addEvent
( unsigned long micros, int type, ostimerq_handler func,
@@ -275,7 +275,7 @@ bool LinuxTimerQueue::addEvent
while( timerQueueMap.find( key ) != timerQueueMap.end() ) {
++key;
}
-
+
{
struct itimerspec its;
memset(&(outer_arg->sevp), 0, sizeof(outer_arg->sevp));
@@ -296,7 +296,7 @@ bool LinuxTimerQueue::addEvent
err = timer_settime( outer_arg->timer_handle, 0, &its, NULL );
if( err < 0 ) {
fprintf
- ( stderr, "Failed to arm timer: %s\n",
+ ( stderr, "Failed to arm timer: %s\n",
strerror( errno ));
return false;
}
@@ -357,7 +357,7 @@ unsigned long LinuxTimer::sleep(unsigned long micros) {
struct TicketingLockPrivate {
pthread_cond_t condition;
- pthread_mutex_t cond_lock;
+ pthread_mutex_t cond_lock;
};
bool TicketingLock::lock( bool *got ) {
@@ -365,7 +365,7 @@ bool TicketingLock::lock( bool *got ) {
bool yield = false;
bool ret = true;
if( !init_flag ) return false;
-
+
if( pthread_mutex_lock( &_private->cond_lock ) != 0 ) {
ret = false;
goto done;
@@ -386,15 +386,15 @@ bool TicketingLock::lock( bool *got ) {
}
if( got != NULL ) *got = true;
-
+
unlock:
if( pthread_mutex_unlock( &_private->cond_lock ) != 0 ) {
ret = false;
goto done;
}
-
+
if( yield ) pthread_yield();
-
+
done:
return ret;
}
@@ -402,7 +402,7 @@ bool TicketingLock::lock( bool *got ) {
bool TicketingLock::unlock() {
bool ret = true;
if( !init_flag ) return false;
-
+
if( pthread_mutex_lock( &_private->cond_lock ) != 0 ) {
ret = false;
goto done;
@@ -437,7 +437,7 @@ bool TicketingLock::init() {
cond_ticket_issue = 0;
cond_ticket_serving = 0;
init_flag = true;
-
+
return true;
}
@@ -485,7 +485,7 @@ OSLockResult LinuxLock::lock() {
int lock_c;
lock_c = pthread_mutex_lock(&_private->mutex);
if(lock_c != 0) {
- fprintf( stderr, "LinuxLock: lock failed %d\n", lock_c );
+ fprintf( stderr, "LinuxLock: lock failed %d\n", lock_c );
return oslock_fail;
}
return oslock_ok;
@@ -502,7 +502,7 @@ OSLockResult LinuxLock::unlock() {
int lock_c;
lock_c = pthread_mutex_unlock(&_private->mutex);
if(lock_c != 0) {
- fprintf( stderr, "LinuxLock: unlock failed %d\n", lock_c );
+ fprintf( stderr, "LinuxLock: unlock failed %d\n", lock_c );
return oslock_fail;
}
return oslock_ok;
@@ -635,7 +635,7 @@ bool LinuxSharedMemoryIPC::init( OS_IPC_ARG *barg ) {
if( grp == NULL ) {
XPTPD_ERROR( "Group %s not found, will try root (0) instead", group_name );
}
-
+
shm_fd = shm_open( SHM_NAME, O_RDWR | O_CREAT, 0660 );
if( shm_fd == -1 ) {
XPTPD_ERROR( "shm_open(): %s", strerror(errno) );
@@ -675,7 +675,7 @@ bool LinuxSharedMemoryIPC::init( OS_IPC_ARG *barg ) {
}
return true;
exit_unlink:
- shm_unlink( SHM_NAME );
+ shm_unlink( SHM_NAME );
exit_error:
return false;
}
@@ -724,20 +724,20 @@ bool LinuxNetworkInterfaceFactory::createInterface
struct packet_mreq mr_8021as;
LinkLayerAddress addr;
int ifindex;
-
+
LinuxNetworkInterface *net_iface_l = new LinuxNetworkInterface();
-
+
if( !net_iface_l->net_lock.init()) {
XPTPD_ERROR( "Failed to initialize network lock");
return false;
}
-
+
InterfaceName *ifname = dynamic_cast<InterfaceName *>(label);
if( ifname == NULL ){
XPTPD_ERROR( "ifname == NULL");
return false;
}
-
+
net_iface_l->sd_general = socket( PF_PACKET, SOCK_DGRAM, 0 );
if( net_iface_l->sd_general == -1 ) {
XPTPD_ERROR( "failed to open general socket: %s", strerror(errno));
@@ -749,7 +749,7 @@ bool LinuxNetworkInterfaceFactory::createInterface
( "failed to open event socket: %s \n", strerror(errno));
return false;
}
-
+
memset( &device, 0, sizeof(device));
ifname->toString( device.ifr_name, IFNAMSIZ );
err = ioctl( net_iface_l->sd_event, SIOCGIFHWADDR, &device );
@@ -758,7 +758,7 @@ bool LinuxNetworkInterfaceFactory::createInterface
( "Failed to get interface address: %s", strerror( errno ));
return false;
}
-
+
addr = LinkLayerAddress( (uint8_t *)&device.ifr_hwaddr.sa_data );
net_iface_l->local_addr = addr;
err = ioctl( net_iface_l->sd_event, SIOCGIFINDEX, &device );
@@ -783,19 +783,19 @@ bool LinuxNetworkInterfaceFactory::createInterface
ifindex );
return false;
}
-
+
memset( &ifsock_addr, 0, sizeof( ifsock_addr ));
ifsock_addr.sll_family = AF_PACKET;
ifsock_addr.sll_ifindex = ifindex;
ifsock_addr.sll_protocol = PLAT_htons( PTP_ETHERTYPE );
err = bind
( net_iface_l->sd_event, (sockaddr *) &ifsock_addr,
- sizeof( ifsock_addr ));
- if( err == -1 ) {
+ sizeof( ifsock_addr ));
+ if( err == -1 ) {
XPTPD_ERROR( "Call to bind() failed: %s", strerror(errno) );
return false;
}
-
+
net_iface_l->timestamper =
dynamic_cast <LinuxTimestamper *>(timestamper);
if(net_iface_l->timestamper == NULL) {
@@ -808,7 +808,6 @@ bool LinuxNetworkInterfaceFactory::createInterface
return false;
}
*net_iface = net_iface_l;
-
+
return true;
}
-
diff --git a/daemons/gptp/linux/src/linux_hal_common.hpp b/daemons/gptp/linux/src/linux_hal_common.hpp
index 681929df..c37bdfaf 100644
--- a/daemons/gptp/linux/src/linux_hal_common.hpp
+++ b/daemons/gptp/linux/src/linux_hal_common.hpp
@@ -1,31 +1,31 @@
/******************************************************************************
- Copyright (c) 2012, Intel Corporation
+ Copyright (c) 2012, Intel Corporation
All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
+
+ Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
+
+ 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
+
+ 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. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
-
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
@@ -68,7 +68,7 @@ struct TicketingLockPrivate;
* Provides the type for the TicketingLock private structure
*/
typedef struct TicketingLockPrivate * TicketingLockPrivate_t;
-
+
/**
* TicketingLock: Implements the ticket lock algorithm.
* A ticket lock consists of two counters, one containing the
@@ -176,7 +176,7 @@ public:
* an error on the transmit side, net_fatal if error on reception
*/
virtual net_result nrecv
- ( LinkLayerAddress *addr, uint8_t *payload, size_t &length );
+ ( LinkLayerAddress *addr, uint8_t *payload, size_t &length, struct phy_delay *delay );
/**
* @brief Disables rx socket descriptor and and clears the rx queue
@@ -448,7 +448,7 @@ public:
/**
* @brief Creates Linux timer queue
* @param clock [in] Pointer to IEEE15588Clock type
- * @return Pointer to OSTimerQueue
+ * @return Pointer to OSTimerQueue
*/
virtual OSTimerQueue *createOSTimerQueue( IEEE1588Clock *clock );
};
diff --git a/daemons/gptp/linux/src/linux_hal_generic.cpp b/daemons/gptp/linux/src/linux_hal_generic.cpp
index c2ee0663..ab958eb9 100644
--- a/daemons/gptp/linux/src/linux_hal_generic.cpp
+++ b/daemons/gptp/linux/src/linux_hal_generic.cpp
@@ -1,31 +1,31 @@
/******************************************************************************
- Copyright (c) 2009-2012, Intel Corporation
+ Copyright (c) 2009-2012, Intel Corporation
All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
+
+ Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
+
+ 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
+
+ 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. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
-
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
@@ -52,7 +52,7 @@
#define RX_PHY_TIME 382
net_result LinuxNetworkInterface::nrecv
-( LinkLayerAddress *addr, uint8_t *payload, size_t &length ) {
+( LinkLayerAddress *addr, uint8_t *payload, size_t &length,struct phy_delay *delay ) {
fd_set readfds;
int err;
struct msghdr msg;
@@ -61,13 +61,13 @@ net_result LinuxNetworkInterface::nrecv
struct cmsghdr cm;
char control[256];
} control;
- struct sockaddr_ll remote;
+ struct sockaddr_ll remote;
struct iovec sgentry;
net_result ret = net_succeed;
bool got_net_lock;
LinuxTimestamperGeneric *gtimestamper;
-
+
struct timeval timeout = { 0, 16000 }; // 16 ms
if( !net_lock.lock( &got_net_lock )) {
@@ -80,8 +80,8 @@ net_result LinuxNetworkInterface::nrecv
FD_ZERO( &readfds );
FD_SET( sd_event, &readfds );
-
- err = select( sd_event+1, &readfds, NULL, NULL, &timeout );
+
+ err = select( sd_event+1, &readfds, NULL, NULL, &timeout );
if( err == 0 ) {
ret = net_trfail;
goto done;
@@ -100,21 +100,21 @@ net_result LinuxNetworkInterface::nrecv
ret = net_trfail;
goto done;
}
-
+
memset( &msg, 0, sizeof( msg ));
-
+
msg.msg_iov = &sgentry;
msg.msg_iovlen = 1;
-
+
sgentry.iov_base = payload;
sgentry.iov_len = length;
-
+
memset( &remote, 0, sizeof(remote));
msg.msg_name = (caddr_t) &remote;
msg.msg_namelen = sizeof( remote );
msg.msg_control = &control;
msg.msg_controllen = sizeof(control);
-
+
err = recvmsg( sd_event, &msg, 0 );
if( err < 0 ) {
if( errno == ENOMSG ) {
@@ -127,7 +127,7 @@ net_result LinuxNetworkInterface::nrecv
goto done;
}
*addr = LinkLayerAddress( remote.sll_addr );
-
+
gtimestamper = dynamic_cast<LinuxTimestamperGeneric *>(timestamper);
if( err > 0 && !(payload[0] & 0x8) && gtimestamper != NULL ) {
/* Retrieve the timestamp */
@@ -136,20 +136,20 @@ net_result LinuxNetworkInterface::nrecv
if
( cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SO_TIMESTAMPING ) {
- Timestamp latency( RX_PHY_TIME, 0, 0 );
+ Timestamp latency( delay->gb_rx_phy_delay, 0, 0 );
struct timespec *ts_device, *ts_system;
- Timestamp device, system;
+ Timestamp device, system;
ts_system = ((struct timespec *) CMSG_DATA(cmsg)) + 1;
system = tsToTimestamp( ts_system );
ts_device = ts_system + 1; device = tsToTimestamp( ts_device );
device = device - latency;
gtimestamper->pushRXTimestamp( &device );
- break;
+ break;
}
cmsg = CMSG_NXTHDR(&msg,cmsg);
}
}
-
+
length = err;
done:
@@ -158,7 +158,7 @@ net_result LinuxNetworkInterface::nrecv
return net_fatal;
}
- return ret;
+ return ret;
}
int findPhcIndex( InterfaceLabel *iface_label ) {
@@ -166,7 +166,7 @@ int findPhcIndex( InterfaceLabel *iface_label ) {
InterfaceName *ifname;
struct ethtool_ts_info info;
struct ifreq ifr;
-
+
if(( ifname = dynamic_cast<InterfaceName *>(iface_label)) == NULL ) {
fprintf( stderr, "findPTPIndex requires InterfaceName\n" );
return -1;
@@ -183,7 +183,7 @@ int findPhcIndex( InterfaceLabel *iface_label ) {
info.cmd = ETHTOOL_GET_TS_INFO;
ifname->toString( ifr.ifr_name, IFNAMSIZ-1 );
ifr.ifr_data = (char *) &info;
-
+
if( ioctl( sd, SIOCETHTOOL, &ifr ) < 0 ) {
fprintf( stderr, "findPTPIndex: ioctl(SIOETHTOOL) failed\n" );
return -1;
@@ -233,7 +233,7 @@ bool LinuxTimestamperGeneric::HWTimestamper_init
fprintf( stderr, "Failed to find PTP device index\n" );
return false;
}
-
+
snprintf
( ptp_device+PTP_DEVICE_IDX_OFFS,
sizeof(ptp_device)-PTP_DEVICE_IDX_OFFS, "%d", phc_index );
@@ -243,7 +243,7 @@ bool LinuxTimestamperGeneric::HWTimestamper_init
fprintf( stderr, "Failed to open PTP clock device\n" );
return false;
}
-
+
if( !resetFrequencyAdjustment() ) {
XPTPD_ERROR( "Failed to reset (zero) frequency adjustment" );
return false;
@@ -253,8 +253,8 @@ bool LinuxTimestamperGeneric::HWTimestamper_init
iface_list.push_front
( (dynamic_cast<LinuxNetworkInterface *>(iface)) );
}
-
- return true;
+
+ return true;
}
int LinuxTimestamperGeneric::HWTimestamper_txtimestamp
@@ -264,23 +264,25 @@ int LinuxTimestamperGeneric::HWTimestamper_txtimestamp
int ret = -72;
struct msghdr msg;
struct cmsghdr *cmsg;
- struct sockaddr_ll remote;
+ struct sockaddr_ll remote;
struct iovec sgentry;
struct {
struct cmsghdr cm;
char control[256];
} control;
- Timestamp latency( TX_PHY_TIME, 0, 0 );
-
- if( sd == -1 ) return -1;
+ struct phy_delay delay_val;
+ get_phy_delay (&delay_val);//gets the phy delay
+
+ Timestamp latency( delay_val.gb_tx_phy_delay, 0, 0 );
+ if( sd == -1 ) return -1;
memset( &msg, 0, sizeof( msg ));
-
+
msg.msg_iov = &sgentry;
msg.msg_iovlen = 1;
-
+
sgentry.iov_base = NULL;
sgentry.iov_len = 0;
-
+
memset( &remote, 0, sizeof(remote));
msg.msg_name = (caddr_t) &remote;
msg.msg_namelen = sizeof( remote );
@@ -298,14 +300,14 @@ int LinuxTimestamperGeneric::HWTimestamper_txtimestamp
goto done;
}
}
-
+
// Retrieve the timestamp
cmsg = CMSG_FIRSTHDR(&msg);
while( cmsg != NULL ) {
if( cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SO_TIMESTAMPING ) {
struct timespec *ts_device, *ts_system;
- Timestamp device, system;
+ Timestamp device, system;
ts_system = ((struct timespec *) CMSG_DATA(cmsg)) + 1;
system = tsToTimestamp( ts_system );
ts_device = ts_system + 1; device = tsToTimestamp( ts_device );
@@ -314,7 +316,7 @@ int LinuxTimestamperGeneric::HWTimestamper_txtimestamp
device._version = version;
timestamp = device;
ret = 0;
- break;
+ break;
}
cmsg = CMSG_NXTHDR(&msg,cmsg);
}
@@ -322,12 +324,12 @@ int LinuxTimestamperGeneric::HWTimestamper_txtimestamp
if( ret != 0 ) {
fprintf( stderr, "Received a error message, but didn't find a valid timestamp\n" );
}
-
+
done:
if( ret == 0 || last ) {
net_lock->unlock();
}
-
+
return ret;
}
@@ -373,9 +375,9 @@ bool LinuxTimestamperGeneric::post_init( int ifindex, int sd, TicketingLock *loc
strerror( errno ));
return false;
}
-
+
return true;
-}
+}
#define MAX_NSEC 1000000000
@@ -390,7 +392,7 @@ static inline ptp_clock_time pct_diff
result.nsec = (MAX_NSEC - b->nsec) + a->nsec;
}
result.sec = a->sec - b->sec;
-
+
return result;
}
@@ -416,7 +418,7 @@ bool LinuxTimestamperGeneric::HWTimestamper_gettime
struct ptp_sys_offset offset;
struct ptp_clock_time *pct;
struct ptp_clock_time *system_time_l, *device_time_l;
-
+
int64_t interval = LLONG_MAX;
if( phc_fd != -1 ) {
@@ -443,4 +445,3 @@ bool LinuxTimestamperGeneric::HWTimestamper_gettime
return false;
}
-
diff --git a/examples/common/listener_mrp_client.c b/examples/common/listener_mrp_client.c
index 1e5652c1..d087a866 100644
--- a/examples/common/listener_mrp_client.c
+++ b/examples/common/listener_mrp_client.c
@@ -26,19 +26,44 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* global variables */
-int control_socket;
-volatile int talker = 0;
-unsigned char stream_id[8];
+//struct listener_context global_struct_listener;
+pthread_t monitor_thread;
+pthread_attr_t monitor_attr;
/*
* private
*/
-int send_msg(char *data, int data_len)
+int mrp_listener_client_init(struct mrp_listener_ctx *ctx)
+{
+ int i;
+ ctx->control_socket=-1;
+ ctx->talker = 0;
+ ctx->halt_tx = 0;
+ ctx->domain_a_valid = 0;
+ ctx->domain_class_a_id = 0;
+ ctx->domain_class_a_priority = 0;
+ ctx->domain_class_a_vid = 0;
+ ctx->domain_b_valid = 0;
+ ctx->domain_class_b_id = 0;
+ ctx->domain_class_b_priority = 0;
+ ctx->domain_class_b_vid = 0;
+ for (i=0;i<8;i++)
+ {
+ ctx->stream_id[i]=0;
+ }
+ for (i=0;i<6;i++)
+ {
+ ctx->dst_mac[i]=0;
+ }
+ return 0;
+}
+
+int send_msg(char *data, int data_len, struct mrp_listener_ctx *ctx)
{
struct sockaddr_in addr;
- if (control_socket == -1)
+ if (ctx->control_socket == -1)
return -1;
if (data == NULL)
return -1;
@@ -48,16 +73,19 @@ int send_msg(char *data, int data_len)
addr.sin_port = htons(MRPD_PORT_DEFAULT);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
inet_aton("127.0.0.1", &addr.sin_addr);
- return sendto(control_socket, data, data_len, 0,
+ return sendto(ctx->control_socket, data, data_len, 0,
(struct sockaddr*)&addr, (socklen_t)sizeof(addr));
}
-int msg_process(char *buf, int buflen)
+int msg_process(char *buf, int buflen, struct mrp_listener_ctx *ctx)
{
uint32_t id;
- int j, l;
+ int j, l=0;
+ unsigned int vid;
+ unsigned int priority;
fprintf(stderr, "Msg: %s\n", buf);
+
if (strncmp(buf, "SNE T:", 6) == 0 || strncmp(buf, "SJO T:", 6) == 0)
{
l = 6; /* skip "Sxx T:" */
@@ -68,67 +96,133 @@ int msg_process(char *buf, int buflen)
for(j = 0; j < 8 ; l+=2, j++)
{
sscanf(&buf[l],"%02x",&id);
- stream_id[j] = (unsigned char)id;
+ ctx->stream_id[j] = (unsigned char)id;
}
- talker = 1;
+ l+=3;
+ for(j = 0; j < 6 ; l+=2, j++)
+ {
+ sscanf(&buf[l],"%02x",&id);
+ ctx->dst_mac[j] = (unsigned char)id;
+ }
+ ctx->talker = 1;
}
- return 0;
-}
-
-int recv_msg()
-{
- char *databuf;
- int bytes = 0;
- int ret;
-
- databuf = (char *)malloc(1500);
- if (NULL == databuf)
- return -1;
- memset(databuf, 0, 1500);
- bytes = recv(control_socket, databuf, 1500, 0);
- if (bytes <= -1)
+ if (strncmp(buf, "SJO D:", 6) == 0)
{
- free(databuf);
- return -1;
- }
- ret = msg_process(databuf, bytes);
- free(databuf);
+ l=8;
+ sscanf(&(buf[l]), "%d", &id);
+ l=l+4;
+ sscanf(&(buf[l]), "%d", &priority);
+ l=l+4;
+ sscanf(&(buf[l]), "%x", &vid);
+
+ if (id == 6)
+ {
+ ctx->domain_class_a_id = id;
+ ctx->domain_class_a_priority = priority;
+ ctx->domain_class_a_vid = vid;
+ ctx->domain_a_valid = 1;
+ }
+ else
+ {
+ ctx->domain_class_b_id = id;
+ ctx->domain_class_b_priority = priority;
+ ctx->domain_class_b_vid = vid;
+ ctx->domain_b_valid = 1;
+ }
+ l+=4;
- return ret;
+ }
+ return 0;
}
/*
* public
*/
-int create_socket() // TODO FIX! =:-|
+int create_socket(struct mrp_listener_ctx *ctx) // TODO FIX! =:-|
{
struct sockaddr_in addr;
- control_socket = socket(AF_INET, SOCK_DGRAM, 0);
-
+ ctx->control_socket = socket(AF_INET, SOCK_DGRAM, 0);
+
/** in POSIX fd 0,1,2 are reserved */
- if (2 > control_socket)
+ if (2 > ctx->control_socket)
{
- if (-1 > control_socket)
- close(control_socket);
+ if (-1 > ctx->control_socket)
+ close(ctx->control_socket);
return -1;
}
-
+
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(0);
-
- if(0 > (bind(control_socket, (struct sockaddr*)&addr, sizeof(addr))))
+
+ if(0 > (bind(ctx->control_socket, (struct sockaddr*)&addr, sizeof(addr))))
{
fprintf(stderr, "Could not bind socket.\n");
- close(control_socket);
+ close(ctx->control_socket);
return -1;
}
return 0;
}
-int report_domain_status()
+void *mrp_monitor_thread(void *arg)
+{
+ char *msgbuf;
+ struct sockaddr_in client_addr;
+ struct msghdr msg;
+ struct iovec iov;
+ int bytes = 0;
+ struct pollfd fds;
+ int rc;
+ struct mrp_listener_ctx *ctx = (struct mrp_listener_ctx*) arg;
+
+ msgbuf = (char *)malloc(MAX_MRPD_CMDSZ);
+ if (NULL == msgbuf)
+ return NULL;
+ while (!ctx->halt_tx) {
+ fds.fd = ctx->control_socket;
+ fds.events = POLLIN;
+ fds.revents = 0;
+ rc = poll(&fds, 1, 100);
+ if (rc < 0) {
+ free(msgbuf);
+ pthread_exit(NULL);
+ }
+ if (rc == 0)
+ continue;
+ if ((fds.revents & POLLIN) == 0) {
+ free(msgbuf);
+ pthread_exit(NULL);
+ }
+ memset(&msg, 0, sizeof(msg));
+ memset(&client_addr, 0, sizeof(client_addr));
+ memset(msgbuf, 0, MAX_MRPD_CMDSZ);
+ iov.iov_len = MAX_MRPD_CMDSZ;
+ iov.iov_base = msgbuf;
+ msg.msg_name = &client_addr;
+ msg.msg_namelen = sizeof(client_addr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ bytes = recvmsg(ctx->control_socket, &msg, 0);
+ if (bytes < 0)
+ continue;
+ msg_process(msgbuf, bytes, ctx);
+ }
+ free(msgbuf);
+ pthread_exit(NULL);
+}
+
+
+int mrp_monitor(struct mrp_listener_ctx *ctx)
+{
+ int rc;
+ rc = pthread_attr_init(&monitor_attr);
+ rc |= pthread_create(&monitor_thread, NULL, mrp_monitor_thread, ctx);
+ return rc;
+}
+
+int report_domain_status(struct mrp_domain_attr *class_a, struct mrp_listener_ctx *ctx)
{
char* msgbuf;
int rc;
@@ -137,8 +231,8 @@ int report_domain_status()
if (NULL == msgbuf)
return -1;
memset(msgbuf, 0, 1500);
- sprintf(msgbuf, "S+D:C=6,P=3,V=0002");
- rc = send_msg(msgbuf, 1500);
+ sprintf(msgbuf, "S+D:C=%d,P=%d,V=%04x", class_a->id, class_a->priority, class_a->vid);
+ rc = send_msg(msgbuf, 1500, ctx);
free(msgbuf);
if (rc != 1500)
@@ -147,7 +241,45 @@ int report_domain_status()
return 0;
}
-int join_vlan()
+int mrp_get_domain(struct mrp_listener_ctx *ctx, struct mrp_domain_attr *class_a, struct mrp_domain_attr *class_b)
+{
+ char *msgbuf;
+ int ret;
+
+ /* we may not get a notification if we are joining late,
+ * so query for what is already there ...
+ */
+ msgbuf = malloc(1500);
+ if (NULL == msgbuf)
+ return -1;
+ memset(msgbuf, 0, 1500);
+ sprintf(msgbuf, "S??");
+ ret = send_msg(msgbuf, 1500, ctx);
+ free(msgbuf);
+ if (ret != 1500)
+ return -1;
+ while (!ctx->halt_tx && (ctx->domain_a_valid == 0) && (ctx->domain_b_valid == 0))
+ usleep(20000);
+ class_a->id = 0;
+ class_a->priority = 0;
+ class_a->vid = 0;
+ class_b->id = 0;
+ class_b->priority = 0;
+ class_b->vid = 0;
+ if (ctx->domain_a_valid) {
+ class_a->id = ctx->domain_class_a_id;
+ class_a->priority = ctx->domain_class_a_priority;
+ class_a->vid = ctx->domain_class_a_vid;
+ }
+ if (ctx->domain_b_valid) {
+ class_b->id = ctx->domain_class_b_id;
+ class_b->priority = ctx->domain_class_b_priority;
+ class_b->vid = ctx->domain_class_b_vid;
+ }
+ return 0;
+}
+
+int join_vlan(struct mrp_domain_attr *class_a, struct mrp_listener_ctx *ctx)
{
char *msgbuf;
int rc;
@@ -156,8 +288,9 @@ int join_vlan()
if (NULL == msgbuf)
return -1;
memset(msgbuf, 0, 1500);
- sprintf(msgbuf, "V++:I=0002");
- rc = send_msg(msgbuf, 1500);
+ sprintf(msgbuf, "V++:I=%04x\n",class_a->vid);
+ printf("Joing VLAN %s\n",msgbuf);
+ rc = send_msg(msgbuf, 1500, ctx);
free(msgbuf);
if (rc != 1500)
@@ -166,14 +299,14 @@ int join_vlan()
return 0;
}
-int await_talker()
+int await_talker(struct mrp_listener_ctx *ctx)
{
- while (0 == talker)
- recv_msg();
+ while (0 == ctx->talker)
+ ;
return 0;
}
-int send_ready()
+int send_ready(struct mrp_listener_ctx *ctx)
{
char *databuf;
int rc;
@@ -183,11 +316,11 @@ int send_ready()
return -1;
memset(databuf, 0, 1500);
sprintf(databuf, "S+L:L=%02x%02x%02x%02x%02x%02x%02x%02x, D=2",
- stream_id[0], stream_id[1],
- stream_id[2], stream_id[3],
- stream_id[4], stream_id[5],
- stream_id[6], stream_id[7]);
- rc = send_msg(databuf, 1500);
+ ctx->stream_id[0], ctx->stream_id[1],
+ ctx->stream_id[2], ctx->stream_id[3],
+ ctx->stream_id[4], ctx->stream_id[5],
+ ctx->stream_id[6], ctx->stream_id[7]);
+ rc = send_msg(databuf, 1500, ctx);
free(databuf);
if (rc != 1500)
@@ -196,7 +329,7 @@ int send_ready()
return 0;
}
-int send_leave()
+int send_leave(struct mrp_listener_ctx *ctx)
{
char *databuf;
int rc;
@@ -206,11 +339,11 @@ int send_leave()
return -1;
memset(databuf, 0, 1500);
sprintf(databuf, "S-L:L=%02x%02x%02x%02x%02x%02x%02x%02x, D=3",
- stream_id[0], stream_id[1],
- stream_id[2], stream_id[3],
- stream_id[4], stream_id[5],
- stream_id[6], stream_id[7]);
- rc = send_msg(databuf, 1500);
+ ctx->stream_id[0], ctx->stream_id[1],
+ ctx->stream_id[2], ctx->stream_id[3],
+ ctx->stream_id[4], ctx->stream_id[5],
+ ctx->stream_id[6], ctx->stream_id[7]);
+ rc = send_msg(databuf, 1500, ctx);
free(databuf);
if (rc != 1500)
@@ -219,7 +352,7 @@ int send_leave()
return 0;
}
-int mrp_disconnect()
+int mrp_disconnect(struct mrp_listener_ctx *ctx)
{
int rc;
char *msgbuf = malloc(1500);
@@ -229,7 +362,7 @@ int mrp_disconnect()
memset(msgbuf, 0, 1500);
sprintf(msgbuf, "BYE");
- rc = send_msg(msgbuf, 1500);
+ rc = send_msg(msgbuf, 1500, ctx);
free(msgbuf);
if (rc != 1500)
diff --git a/examples/common/listener_mrp_client.h b/examples/common/listener_mrp_client.h
index 142d8f39..3646b3c9 100644
--- a/examples/common/listener_mrp_client.h
+++ b/examples/common/listener_mrp_client.h
@@ -34,25 +34,53 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <string.h>
#include <stdio.h> // TODO fprintf, to be removed
#include <unistd.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <poll.h>
#include "mrpd.h"
+#include "mrp.h"
+#include "msrp.h"
/* global variables */
-// TODO move these in a talker_context struct + init func
+struct mrp_listener_ctx
+{
+ int control_socket;
+ volatile int talker;
+ unsigned char stream_id[8];
+ unsigned char dst_mac[6];
+ volatile int halt_tx;
+ volatile int domain_a_valid;
+ int domain_class_a_id;
+ int domain_class_a_priority;
+ u_int16_t domain_class_a_vid;
+ volatile int domain_b_valid;
+ int domain_class_b_id;
+ int domain_class_b_priority;
+ u_int16_t domain_class_b_vid;
+};
+
+struct mrp_domain_attr
+{
+ int id;
+ int priority;
+ u_int16_t vid;
+};
+
-extern int control_socket;
-extern volatile int talker;
-extern unsigned char stream_id[8];
/* functions */
-int create_socket();
-int report_domain_status();
-int join_vlan();
-int await_talker();
-int send_ready();
-int send_leave();
-int mrp_disconnect();
+int create_socket(struct mrp_listener_ctx *ctx);
+int mrp_monitor(struct mrp_listener_ctx *ctx);
+int report_domain_status(struct mrp_domain_attr *class_a, struct mrp_listener_ctx *ctx);
+int join_vlan(struct mrp_domain_attr *class_a, struct mrp_listener_ctx *ctx);
+int await_talker(struct mrp_listener_ctx *ctx);
+int send_ready(struct mrp_listener_ctx *ctx);
+int send_leave(struct mrp_listener_ctx *ctx);
+int mrp_disconnect(struct mrp_listener_ctx *ctx);
+int mrp_get_domain(struct mrp_listener_ctx *ctx, struct mrp_domain_attr *class_a, struct mrp_domain_attr *class_b);
+int mrp_listener_client_init(struct mrp_listener_ctx *ctx);
#endif /* _LISTENER_MRP_CLIENT_H_ */
diff --git a/examples/common/talker_mrp_client.c b/examples/common/talker_mrp_client.c
index 1b42fabb..6959e220 100644
--- a/examples/common/talker_mrp_client.c
+++ b/examples/common/talker_mrp_client.c
@@ -3,30 +3,30 @@
Copyright (c) 2012, Intel Corporation
Copyright (c) 2014, Parrot SA
All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
+
+ Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
+
+ 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
+
+ 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. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
-
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
@@ -36,37 +36,43 @@
/* global variables */
-int control_socket = -1;
-
-volatile int halt_tx = 0;
-volatile int listeners = 0;
volatile int mrp_okay;
volatile int mrp_error = 0;;
-
-volatile int domain_a_valid = 0;
-int domain_class_a_id = 0;
-int domain_class_a_priority = 0;
-u_int16_t domain_class_a_vid = 0;
-
-volatile int domain_b_valid = 0;
-int domain_class_b_id = 0;
-int domain_class_b_priority = 0;
-u_int16_t domain_class_b_vid = 0;
-
pthread_t monitor_thread;
pthread_attr_t monitor_attr;
-unsigned char monitor_stream_id[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
/*
* private
*/
-int send_mrp_msg(char *notify_data, int notify_len)
+int mrp_talker_client_init(struct mrp_talker_ctx *ctx)
+{
+ int i;
+ ctx->control_socket = -1;
+ ctx->halt_tx = 0;
+ ctx->listeners = 0;
+ ctx->domain_a_valid = 0;
+ ctx->domain_class_a_id = 0;
+ ctx->domain_class_a_priority = 0;
+ ctx->domain_class_a_vid = 0;
+ ctx->domain_b_valid = 0;
+ ctx->domain_class_b_id = 0;
+ ctx->domain_class_b_priority = 0;
+ ctx->domain_class_b_vid = 0;
+ for (i=0;i<8;i++)
+ {
+ ctx->monitor_stream_id[i] = 0;
+ }
+ return 0;
+}
+
+int send_mrp_msg(char *notify_data, int notify_len, struct mrp_talker_ctx *ctx)
{
struct sockaddr_in addr;
socklen_t addr_len;
- if (control_socket == -1)
+ if (ctx->control_socket == -1)
return -1;
if (notify_data == NULL)
return -1;
@@ -76,11 +82,11 @@ int send_mrp_msg(char *notify_data, int notify_len)
addr.sin_port = htons(MRPD_PORT_DEFAULT);
inet_aton("127.0.0.1", &addr.sin_addr);
addr_len = sizeof(addr);
- return sendto(control_socket, notify_data, notify_len, 0,
+ return sendto(ctx->control_socket, notify_data, notify_len, 0,
(struct sockaddr *)&addr, addr_len);
}
-int process_mrp_msg(char *buf, int buflen)
+int process_mrp_msg(char *buf, int buflen, struct mrp_talker_ctx *ctx)
{
/*
@@ -151,9 +157,9 @@ int process_mrp_msg(char *buf, int buflen)
}
if (substate > MSRP_LISTENER_ASKFAILED) {
if (memcmp
- (recovered_streamid, monitor_stream_id,
+ (recovered_streamid, ctx->monitor_stream_id,
sizeof(recovered_streamid)) == 0) {
- listeners = 1;
+ ctx->listeners = 1;
printf("added listener\n");
}
}
@@ -184,15 +190,15 @@ int process_mrp_msg(char *buf, int buflen)
i += 2; /* skip the ':' */
sscanf(&(buf[i]), "%x", &vid);
if (id == 6) {
- domain_class_a_id = id;
- domain_class_a_priority = priority;
- domain_class_a_vid = vid;
- domain_a_valid = 1;
+ ctx->domain_class_a_id = id;
+ ctx->domain_class_a_priority = priority;
+ ctx->domain_class_a_vid = vid;
+ ctx->domain_a_valid = 1;
} else {
- domain_class_b_id = id;
- domain_class_b_priority = priority;
- domain_class_b_vid = vid;
- domain_b_valid = 1;
+ ctx->domain_class_b_id = id;
+ ctx->domain_class_b_priority = priority;
+ ctx->domain_class_b_vid = vid;
+ ctx->domain_b_valid = 1;
}
while ((i < buflen) && (buf[i] != '\n') && (buf[i] != '\0'))
i++;
@@ -259,9 +265,9 @@ int process_mrp_msg(char *buf, int buflen)
case 'L':
printf("got a leave indication\n");
if (memcmp
- (recovered_streamid, monitor_stream_id,
+ (recovered_streamid, ctx->monitor_stream_id,
sizeof(recovered_streamid)) == 0) {
- listeners = 0;
+ ctx->listeners = 0;
printf("listener left\n");
}
break;
@@ -271,9 +277,9 @@ int process_mrp_msg(char *buf, int buflen)
if (substate > MSRP_LISTENER_ASKFAILED) {
if (memcmp
(recovered_streamid,
- monitor_stream_id,
+ ctx->monitor_stream_id,
sizeof(recovered_streamid)) == 0)
- listeners = 1;
+ ctx->listeners = 1;
}
break;
}
@@ -299,13 +305,13 @@ void *mrp_monitor_thread(void *arg)
int bytes = 0;
struct pollfd fds;
int rc;
- (void) arg; /* unused */
+ struct mrp_talker_ctx *ctx = (struct mrp_talker_ctx*) arg;
msgbuf = (char *)malloc(MAX_MRPD_CMDSZ);
if (NULL == msgbuf)
return NULL;
- while (!halt_tx) {
- fds.fd = control_socket;
+ while (!ctx->halt_tx) {
+ fds.fd = ctx->control_socket;
fds.events = POLLIN;
fds.revents = 0;
rc = poll(&fds, 1, 100);
@@ -328,10 +334,10 @@ void *mrp_monitor_thread(void *arg)
msg.msg_namelen = sizeof(client_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
- bytes = recvmsg(control_socket, &msg, 0);
+ bytes = recvmsg(ctx->control_socket, &msg, 0);
if (bytes < 0)
continue;
- process_mrp_msg(msgbuf, bytes);
+ process_mrp_msg(msgbuf, bytes, ctx);
}
free(msgbuf);
pthread_exit(NULL);
@@ -341,10 +347,11 @@ void *mrp_monitor_thread(void *arg)
* public
*/
-int mrp_connect(void)
+int mrp_connect(struct mrp_talker_ctx *ctx)
{
struct sockaddr_in addr;
int sock_fd = -1;
+ int rc;
sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock_fd < 0)
goto out;
@@ -353,7 +360,10 @@ int mrp_connect(void)
addr.sin_port = htons(MRPD_PORT_DEFAULT);
inet_aton("127.0.0.1", &addr.sin_addr);
memset(&addr, 0, sizeof(addr));
- control_socket = sock_fd;
+ ctx->control_socket = sock_fd;
+ rc = pthread_attr_init(&monitor_attr);
+ rc |= pthread_create(&monitor_thread, NULL, mrp_monitor_thread, ctx);
+ return rc;
return 0;
out: if (sock_fd != -1)
close(sock_fd);
@@ -361,7 +371,7 @@ int mrp_connect(void)
return -1;
}
-int mrp_disconnect(void)
+int mrp_disconnect(struct mrp_talker_ctx *ctx)
{
char *msgbuf;
int rc;
@@ -372,7 +382,7 @@ int mrp_disconnect(void)
memset(msgbuf, 0, 64);
sprintf(msgbuf, "BYE");
mrp_okay = 0;
- rc = send_mrp_msg(msgbuf, 1500);
+ rc = send_mrp_msg(msgbuf, 1500, ctx);
free(msgbuf);
if (rc != 1500)
@@ -389,7 +399,7 @@ int mrp_monitor(void)
return rc;
}
-int mrp_register_domain(int *class_id, int *priority, u_int16_t * vid)
+int mrp_register_domain(struct mrp_domain_attr *reg_class, struct mrp_talker_ctx *ctx)
{
char *msgbuf;
int rc;
@@ -399,9 +409,9 @@ int mrp_register_domain(int *class_id, int *priority, u_int16_t * vid)
return -1;
memset(msgbuf, 0, 1500);
- sprintf(msgbuf, "S+D:C=%d,P=%d,V=%04x", *class_id, *priority, *vid);
+ sprintf(msgbuf, "S+D:C=%d,P=%d,V=%04x", reg_class->id, reg_class->priority, reg_class->vid);
mrp_okay = 0;
- rc = send_mrp_msg(msgbuf, 1500);
+ rc = send_mrp_msg(msgbuf, 1500, ctx);
free(msgbuf);
if (rc != 1500)
@@ -414,8 +424,7 @@ int mrp_register_domain(int *class_id, int *priority, u_int16_t * vid)
int
mrp_advertise_stream(uint8_t * streamid,
uint8_t * destaddr,
- u_int16_t vlan,
- int pktsz, int interval, int priority, int latency)
+ int pktsz, int interval, int latency, struct mrp_talker_ctx *ctx)
{
char *msgbuf;
int rc;
@@ -434,10 +443,10 @@ mrp_advertise_stream(uint8_t * streamid,
",L=%d", streamid[0], streamid[1], streamid[2],
streamid[3], streamid[4], streamid[5], streamid[6],
streamid[7], destaddr[0], destaddr[1], destaddr[2],
- destaddr[3], destaddr[4], destaddr[5], vlan, pktsz,
- interval, priority << 5, latency);
+ destaddr[3], destaddr[4], destaddr[5], ctx->domain_class_a_vid, pktsz,
+ interval, ctx->domain_class_a_priority << 5, latency);
mrp_okay = 0;
- rc = send_mrp_msg(msgbuf, 1500);
+ rc = send_mrp_msg(msgbuf, 1500, ctx);
free(msgbuf);
if (rc != 1500)
@@ -449,8 +458,7 @@ mrp_advertise_stream(uint8_t * streamid,
int
mrp_unadvertise_stream(uint8_t * streamid,
uint8_t * destaddr,
- u_int16_t vlan,
- int pktsz, int interval, int priority, int latency)
+ int pktsz, int interval, int latency, struct mrp_talker_ctx *ctx)
{
char *msgbuf;
int rc;
@@ -467,10 +475,10 @@ mrp_unadvertise_stream(uint8_t * streamid,
",L=%d", streamid[0], streamid[1], streamid[2],
streamid[3], streamid[4], streamid[5], streamid[6],
streamid[7], destaddr[0], destaddr[1], destaddr[2],
- destaddr[3], destaddr[4], destaddr[5], vlan, pktsz,
- interval, priority << 5, latency);
+ destaddr[3], destaddr[4], destaddr[5], ctx->domain_class_a_vid, pktsz,
+ interval, ctx->domain_class_a_priority << 5, latency);
mrp_okay = 0;
- rc = send_mrp_msg(msgbuf, 1500);
+ rc = send_mrp_msg(msgbuf, 1500, ctx);
free(msgbuf);
if (rc != 1500)
@@ -480,24 +488,24 @@ mrp_unadvertise_stream(uint8_t * streamid,
}
-int mrp_await_listener(unsigned char *streamid)
+int mrp_await_listener(unsigned char *streamid, struct mrp_talker_ctx *ctx)
{
char *msgbuf;
int rc;
- memcpy(monitor_stream_id, streamid, sizeof(monitor_stream_id));
+ memcpy(ctx->monitor_stream_id, streamid, sizeof(ctx->monitor_stream_id));
msgbuf = malloc(1500);
if (NULL == msgbuf)
return -1;
memset(msgbuf, 0, 1500);
sprintf(msgbuf, "S??");
- rc = send_mrp_msg(msgbuf, 1500);
+ rc = send_mrp_msg(msgbuf, 1500, ctx);
free(msgbuf);
if (rc != 1500)
return -1;
/* either already there ... or need to wait ... */
- while (!halt_tx && (listeners == 0))
+ while (!ctx->halt_tx && (ctx->listeners == 0))
usleep(20000);
return 0;
@@ -507,8 +515,7 @@ int mrp_await_listener(unsigned char *streamid)
* actually not used
*/
-int mrp_get_domain(int *class_a_id, int *a_priority, u_int16_t * a_vid,
- int *class_b_id, int *b_priority, u_int16_t * b_vid)
+int mrp_get_domain(struct mrp_talker_ctx *ctx,struct mrp_domain_attr *class_a,struct mrp_domain_attr *class_b)
{
char *msgbuf;
int ret;
@@ -521,32 +528,32 @@ int mrp_get_domain(int *class_a_id, int *a_priority, u_int16_t * a_vid,
return -1;
memset(msgbuf, 0, 1500);
sprintf(msgbuf, "S??");
- ret = send_mrp_msg(msgbuf, 1500);
+ ret = send_mrp_msg(msgbuf, 1500, ctx);
free(msgbuf);
if (ret != 1500)
return -1;
- while (!halt_tx && (domain_a_valid == 0) && (domain_b_valid == 0))
+ while (!ctx->halt_tx && (ctx->domain_a_valid == 0) && (ctx->domain_b_valid == 0))
usleep(20000);
- *class_a_id = 0;
- *a_priority = 0;
- *a_vid = 0;
- *class_b_id = 0;
- *b_priority = 0;
- *b_vid = 0;
- if (domain_a_valid) {
- *class_a_id = domain_class_a_id;
- *a_priority = domain_class_a_priority;
- *a_vid = domain_class_a_vid;
+ class_a->id = 0;
+ class_a->priority = 0;
+ class_a->vid = 0;
+ class_b->id = 0;
+ class_b->priority = 0;
+ class_b->vid = 0;
+ if (ctx->domain_a_valid) {
+ class_a->id = ctx->domain_class_a_id;
+ class_a->priority = ctx->domain_class_a_priority;
+ class_a->vid = ctx->domain_class_a_vid;
}
- if (domain_b_valid) {
- *class_b_id = domain_class_b_id;
- *b_priority = domain_class_b_priority;
- *b_vid = domain_class_b_vid;
+ if (ctx->domain_b_valid) {
+ class_b->id = ctx->domain_class_b_id;
+ class_b->priority = ctx->domain_class_b_priority;
+ class_b->vid = ctx->domain_class_b_vid;
}
return 0;
}
-int mrp_join_vlan()
+int mrp_join_vlan(struct mrp_domain_attr *reg_class, struct mrp_talker_ctx *ctx)
{
char *msgbuf;
int rc;
@@ -555,8 +562,8 @@ int mrp_join_vlan()
if (NULL == msgbuf)
return -1;
memset(msgbuf, 0, 1500);
- sprintf(msgbuf, "V++:I=0002");
- rc = send_mrp_msg(msgbuf, 1500);
+ sprintf(msgbuf, "V++:I=%04x\n",reg_class->vid);
+ rc = send_mrp_msg(msgbuf, 1500, ctx);
free(msgbuf);
if (rc != 1500)
@@ -565,27 +572,6 @@ int mrp_join_vlan()
return 0;
}
-int mrp_join_listener(uint8_t * streamid)
-{
- char *msgbuf;
- int rc;
-
- msgbuf = malloc(1500);
- if (NULL == msgbuf)
- return -1;
- memset(msgbuf, 0, 1500);
- sprintf(msgbuf, "S+L:S=%02X%02X%02X%02X%02X%02X%02X%02X"
- ",D=2", streamid[0], streamid[1], streamid[2], streamid[3],
- streamid[4], streamid[5], streamid[6], streamid[7]);
- mrp_okay = 0;
- rc = send_mrp_msg(msgbuf, 1500);
- free(msgbuf);
-
- if (rc != 1500)
- return -1;
- else
- return 0;
-}
// TODO remove
int recv_mrp_okay()
@@ -594,4 +580,3 @@ int recv_mrp_okay()
usleep(20000);
return 0;
}
-
diff --git a/examples/common/talker_mrp_client.h b/examples/common/talker_mrp_client.h
index 60ced4cd..cea4f227 100644
--- a/examples/common/talker_mrp_client.h
+++ b/examples/common/talker_mrp_client.h
@@ -3,30 +3,30 @@
Copyright (c) 2012, Intel Corporation
Copyright (c) 2014, Parrot SA
All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
+
+ Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
+
+ 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
+
+ 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. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
-
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
@@ -52,31 +52,41 @@
/* global variables */
-// TODO move these in a talker_context struct + init func
+struct mrp_talker_ctx
+{
+ int control_socket;
+ volatile int halt_tx;
+ volatile int domain_a_valid;
+ int domain_class_a_id;
+ int domain_class_a_priority;
+ u_int16_t domain_class_a_vid;
+ volatile int domain_b_valid;
+ int domain_class_b_id;
+ int domain_class_b_priority;
+ u_int16_t domain_class_b_vid;
+ unsigned char monitor_stream_id[8];
+ volatile int listeners;
+};
-extern volatile int halt_tx;
-extern volatile int listeners;
-extern volatile int mrp_error;
+struct mrp_domain_attr
+{
+ int id;
+ int priority;
+ u_int16_t vid;
+};
-extern volatile int domain_a_valid;
-extern int domain_class_a_id;
-extern int domain_class_a_priority;
-extern u_int16_t domain_class_a_vid;
-extern volatile int domain_b_valid;
-extern int domain_class_b_id;
-extern int domain_class_b_priority;
-extern u_int16_t domain_class_b_vid;
+extern volatile int mrp_error;
/* functions */
-int mrp_connect(void);
-int mrp_disconnect(void);
-int mrp_monitor(void);
-int mrp_register_domain(int *class_id, int *priority, u_int16_t *vid);
-int mrp_join_vlan(void);
-int mrp_advertise_stream(uint8_t * streamid, uint8_t * destaddr, u_int16_t vlan, int pktsz, int interval, int priority, int latency);
-int mrp_unadvertise_stream(uint8_t * streamid, uint8_t * destaddr, u_int16_t vlan, int pktsz, int interval, int priority, int latency);
-int mrp_await_listener(unsigned char *streamid);
-
+int mrp_connect(struct mrp_talker_ctx *ctx);
+int mrp_disconnect(struct mrp_talker_ctx *ctx);
+int mrp_register_domain(struct mrp_domain_attr *reg_class, struct mrp_talker_ctx *ctx);
+int mrp_join_vlan(struct mrp_domain_attr *reg_class, struct mrp_talker_ctx *ctx);
+int mrp_advertise_stream(uint8_t * streamid, uint8_t * destaddr, int pktsz, int interval, int latency, struct mrp_talker_ctx *ctx);
+int mrp_unadvertise_stream(uint8_t * streamid, uint8_t * destaddr, int pktsz, int interval, int latency, struct mrp_talker_ctx *ctx);
+int mrp_await_listener(unsigned char *streamid, struct mrp_talker_ctx *ctx);
+int mrp_get_domain(struct mrp_talker_ctx *ctx, struct mrp_domain_attr *class_a, struct mrp_domain_attr *class_b);
+int mrp_talker_client_init(struct mrp_talker_ctx *ctx);
#endif /* _TALKER_MRP_CLIENT_H_ */
diff --git a/examples/jackd-listener/Makefile b/examples/jackd-listener/Makefile
index a9004923..b0208530 100644
--- a/examples/jackd-listener/Makefile
+++ b/examples/jackd-listener/Makefile
@@ -2,7 +2,7 @@ CC ?= gcc
OPT = -O2 -g
CFLAGS = $(OPT) -Wall -Wextra -Wno-parentheses -std=gnu99
INCFLAGS = -I../../daemons/mrpd -I../common -I../../daemons/common
-LDLIBS = -lpcap -lsndfile -ljack
+LDLIBS = -lpcap -lsndfile -ljack -lpthread
all: jack_listener
diff --git a/examples/jackd-listener/jack_listener.c b/examples/jackd-listener/jack_listener.c
index 1b0b51c7..103a52b8 100644
--- a/examples/jackd-listener/jack_listener.c
+++ b/examples/jackd-listener/jack_listener.c
@@ -54,6 +54,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DEFAULT_RINGBUFFER_SIZE (32768)
#define MAX_SAMPLE_VALUE ((1U << ((sizeof(int32_t) * 8) -1)) -1)
+struct mrp_listener_ctx *ctx_sig;//Context pointer for signal handler
+
struct ethernet_header{
u_char dst[6];
u_char src[6];
@@ -95,17 +97,17 @@ void shutdown_and_exit(int sig)
fprintf(stdout,"Received signal %d:", sig);
fprintf(stdout,"Leaving...\n");
- if (0 != talker) {
- ret = send_leave();
+ if (0 != ctx_sig->talker) {
+ ret = send_leave(ctx_sig);
if (ret)
printf("send_leave failed\n");
}
- ret = mrp_disconnect();
+ ret = mrp_disconnect(ctx_sig);
if (ret)
printf("mrp_disconnect failed\n");
- close(control_socket);
+ close(ctx_sig->control_socket);
if (NULL != handle) {
pcap_breakloop(handle);
@@ -140,7 +142,7 @@ void pcap_callback(u_char* args, const struct pcap_pkthdr* packet_header, const
jack_default_audio_sample_t jackframe[CHANNELS];
int cnt;
static int total;
- (void) args; /* unused */
+ struct mrp_listener_ctx *ctx = (struct mrp_listener_ctx*) args;
(void) packet_header; /* unused */
eth_header = (struct ethernet_header*)(packet);
@@ -150,34 +152,34 @@ void pcap_callback(u_char* args, const struct pcap_pkthdr* packet_header, const
}
test_stream_id = (unsigned char*)(packet + ETHERNET_HEADER_SIZE + SEVENTEEN22_HEADER_PART1_SIZE);
- if (0 != memcmp(test_stream_id, stream_id, STREAM_ID_SIZE)) {
+ if (0 != memcmp(test_stream_id, ctx->stream_id, STREAM_ID_SIZE)) {
return;
}
-
+
mybuf = (uint32_t*) (packet + HEADER_SIZE);
-
- for(int i = 0; i < SAMPLES_PER_FRAME * CHANNELS; i+=CHANNELS) {
+
+ for(int i = 0; i < SAMPLES_PER_FRAME * CHANNELS; i+=CHANNELS) {
memcpy(&frame[0], &mybuf[i], sizeof(frame));
for(int j = 0; j < CHANNELS; j++) {
-
+
frame[j] = ntohl(frame[j]); /* convert to host-byte order */
frame[j] &= 0x00ffffff; /* ignore leading label */
frame[j] <<= 8; /* left-align remaining PCM-24 sample */
-
+
jackframe[j] = ((int32_t)frame[j])/(float)(MAX_SAMPLE_VALUE);
}
if ((cnt = jack_ringbuffer_write_space(ringbuffer)) >= SAMPLE_SIZE * CHANNELS) {
jack_ringbuffer_write(ringbuffer, (void*)&jackframe[0], SAMPLE_SIZE * CHANNELS);
-
+
} else {
fprintf(stdout, "Only %i bytes available after %i samples.\n", cnt, total);
}
if (jack_ringbuffer_write_space(ringbuffer) <= SAMPLE_SIZE * CHANNELS * DEFAULT_RINGBUFFER_SIZE / 4) {
- /** Ringbuffer has only 25% or less write space available, it's time to tell jackd
+ /** Ringbuffer has only 25% or less write space available, it's time to tell jackd
to read some data. */
ready = 1;
}
@@ -201,7 +203,7 @@ static int process_jack(jack_nframes_t nframes, void* arg)
}
for(size_t i = 0; i < nframes; i++) {
-
+
if (jack_ringbuffer_read_space(ringbuffer) >= SAMPLE_SIZE * CHANNELS) {
for(int j = 0; j < CHANNELS; j++){
@@ -221,13 +223,13 @@ static int process_jack(jack_nframes_t nframes, void* arg)
void jack_shutdown(void* arg)
{
- (void) arg; /* unused*/
+ (void)arg; /* unused*/
printf("JACK shutdown\n");
shutdown_and_exit(0);
}
-jack_client_t* init_jack(void)
+jack_client_t* init_jack(struct mrp_listener_ctx *ctx)
{
const char* client_name = "simple_listener";
const char* server_name = NULL;
@@ -250,8 +252,8 @@ jack_client_t* init_jack(void)
fprintf (stderr, "unique name `%s' assigned\n", client_name);
}
- jack_set_process_callback(client, process_jack, 0);
- jack_on_shutdown(client, jack_shutdown, 0);
+ jack_set_process_callback(client, process_jack, (void *)ctx);
+ jack_on_shutdown(client, jack_shutdown, (void *)ctx);
outputports = (jack_port_t**) malloc (CHANNELS * sizeof (jack_port_t*));
out = (jack_default_audio_sample_t**) malloc (CHANNELS * sizeof (jack_default_audio_sample_t*));
@@ -262,13 +264,13 @@ jack_client_t* init_jack(void)
memset(ringbuffer->buf, 0, ringbuffer->size);
for(int i = 0; i < CHANNELS; i++) {
-
+
char* portName;
if (asprintf(&portName, "output%d", i) < 0) {
fprintf(stderr, "could not create portname for port %d\n", i);
shutdown_and_exit(0);
- }
-
+ }
+
outputports[i] = jack_port_register (client, portName, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
if (NULL == outputports[i]) {
fprintf (stderr, "cannot register output port \"%d\"!\n", i);
@@ -278,13 +280,13 @@ jack_client_t* init_jack(void)
const char** ports;
if (jack_activate (client)) {
- fprintf (stderr, "cannot activate client\n");
+ fprintf (stderr, "cannot activate client\n");
shutdown_and_exit(0);
}
ports = jack_get_ports(client, NULL, NULL, JackPortIsPhysical|JackPortIsInput);
- if(NULL == ports) {
- fprintf (stderr, "no physical playback ports\n");
+ if(NULL == ports) {
+ fprintf (stderr, "no physical playback ports\n");
shutdown_and_exit(0);
}
@@ -306,17 +308,20 @@ int main(int argc, char *argv[])
char* dev = NULL;
char errbuf[PCAP_ERRBUF_SIZE];
struct bpf_program comp_filter_exp; /** The compiled filter expression */
- char filter_exp[] = "ether dst 91:E0:F0:00:0e:80"; /** The filter expression */
+ char filter_exp[100]; /** The filter expression */
int rc;
-
+ struct mrp_listener_ctx *ctx = malloc(sizeof(struct mrp_listener_ctx));
+ struct mrp_domain_attr *class_a = malloc(sizeof(struct mrp_domain_attr));
+ struct mrp_domain_attr *class_b = malloc(sizeof(struct mrp_domain_attr));
+ ctx_sig = ctx;
signal(SIGINT, shutdown_and_exit);
-
+
int c;
- while((c = getopt(argc, argv, "hi:")) > 0)
+ while((c = getopt(argc, argv, "hi:")) > 0)
{
- switch (c)
+ switch (c)
{
- case 'h':
+ case 'h':
help();
break;
case 'i':
@@ -331,23 +336,51 @@ int main(int argc, char *argv[])
help();
}
- if (create_socket()) {
+ rc = mrp_listener_client_init(ctx);
+ if (rc)
+ {
+ printf("failed to initialize global variables\n");
+ return EXIT_FAILURE;
+ }
+
+ if (create_socket(ctx)) {
fprintf(stderr, "Socket creation failed.\n");
return errno;
}
- rc = report_domain_status();
+ rc = mrp_monitor(ctx);
+ if (rc)
+ {
+ printf("failed creating MRP monitor thread\n");
+ return EXIT_FAILURE;
+ }
+ rc=mrp_get_domain(ctx, class_a, class_b);
+ if (rc)
+ {
+ printf("failed calling mrp_get_domain()\n");
+ return EXIT_FAILURE;
+ }
+
+ printf("detected domain Class A PRIO=%d VID=%04x...\n",class_a->priority,class_a->vid);
+
+ rc = report_domain_status(class_a,ctx);
if (rc) {
printf("report_domain_status failed\n");
return EXIT_FAILURE;
}
- init_jack();
-
+ rc = join_vlan(class_a, ctx);
+ if (rc) {
+ printf("join_vlan failed\n");
+ return EXIT_FAILURE;
+ }
+
+ init_jack(ctx);
+
fprintf(stdout,"Waiting for talker...\n");
- await_talker();
+ await_talker(ctx);
- rc = send_ready();
+ rc = send_ready(ctx);
if (rc) {
printf("send_ready failed\n");
return EXIT_FAILURE;
@@ -382,6 +415,7 @@ int main(int argc, char *argv[])
}
/** compile and apply filter */
+ sprintf(filter_exp,"ether dst %02x:%02x:%02x:%02x:%02x:%02x",ctx->dst_mac[0],ctx->dst_mac[1],ctx->dst_mac[2],ctx->dst_mac[3],ctx->dst_mac[4],ctx->dst_mac[5]);
if (-1 == pcap_compile(handle, &comp_filter_exp, filter_exp, 0, PCAP_NETMASK_UNKNOWN)) {
fprintf(stderr, "Could not parse filter %s: %s.\n", filter_exp, pcap_geterr(handle));
shutdown_and_exit(0);
@@ -391,11 +425,14 @@ int main(int argc, char *argv[])
fprintf(stderr, "Could not install filter %s: %s.\n", filter_exp, pcap_geterr(handle));
shutdown_and_exit(0);
}
-
+
/** loop forever and call callback-function for every received packet */
- pcap_loop(handle, -1, pcap_callback, NULL);
+ pcap_loop(handle, -1, pcap_callback, (u_char*)ctx);
usleep(-1);
+ free(ctx);
+ free(class_a);
+ free(class_b);
return EXIT_SUCCESS;
}
diff --git a/examples/jackd-talker/Makefile b/examples/jackd-talker/Makefile
index 815235f0..1d4a84ba 100644
--- a/examples/jackd-talker/Makefile
+++ b/examples/jackd-talker/Makefile
@@ -1,6 +1,6 @@
CC ?= gcc
OPT = -O2 -g
-CFLAGS = $(OPT) -Wall -Wextra -Wno-parentheses -std=gnu99
+CFLAGS = $(OPT) $(INCFLAGS) -Wall -Wextra -Wno-parentheses -std=gnu99
INCFLAGS = -I../../lib/igb -I../../daemons/mrpd -I../common -I../../daemons/common
LDLIBS = -ligb -lpci -lrt -pthread -ljack
LDFLAGS = -L../../lib/igb
@@ -24,4 +24,3 @@ jackd_talker.o: jackd_talker.c defines.h jack.h
clean:
$(RM) jackd_talker
$(RM) `find . -name "*~" -o -name "*.[oa]" -o -name "\#*\#" -o -name TAGS -o -name core -o -name "*.orig"`
-
diff --git a/examples/jackd-talker/jack.c b/examples/jackd-talker/jack.c
index 214d3d11..dc0d621b 100644
--- a/examples/jackd-talker/jack.c
+++ b/examples/jackd-talker/jack.c
@@ -8,9 +8,8 @@
#include <jack/ringbuffer.h>
#include "jack.h"
#include "defines.h"
+#include "talker_mrp_client.h"
-extern volatile int halt_tx;
-extern volatile int listeners;
extern volatile int glob_unleash_jack;
static jack_port_t** inputports;
@@ -30,18 +29,18 @@ static int process(jack_nframes_t nframes, void* arg)
{
int cnt;
static int total;
- (void) arg; /* unused */
+ struct mrp_talker_ctx *ctx = (struct mrp_talker_ctx *) arg;
/* Do nothing until we're ready to begin. */
if (!glob_unleash_jack) {
printf ("nothing to do\n");
return 0;
}
-
+
for(int i = 0; i < CHANNELS; i++) {
in[i] = jack_port_get_buffer(inputports[i], nframes);
}
-
+
for (size_t i = 0; i < nframes; i++) {
for(int j = 0; j < CHANNELS; j++) {
total++;
@@ -54,7 +53,7 @@ static int process(jack_nframes_t nframes, void* arg)
} else {
printf ("Only %i bytes available after %i samples\n",
cnt, total);
- halt_tx = 1;
+ ctx->halt_tx = 1;
}
}
}
@@ -70,13 +69,13 @@ static int process(jack_nframes_t nframes, void* arg)
void jack_shutdown(void* arg)
{
- (void) arg; /* unused */
+ struct mrp_talker_ctx *ctx = (struct mrp_talker_ctx *) arg;
printf("JACK shutdown\n");
- halt_tx = 1;
+ ctx->halt_tx = 1;
}
-jack_client_t* init_jack(void)
+jack_client_t* init_jack(struct mrp_talker_ctx *ctx)
{
jack_client_t *client;
const char *client_name = "simple_talker";
@@ -98,8 +97,8 @@ jack_client_t* init_jack(void)
fprintf (stderr, "unique name `%s' assigned\n", client_name);
}
- jack_set_process_callback(client, process, 0);
- jack_on_shutdown(client, jack_shutdown, 0);
+ jack_set_process_callback(client, process, (void *)ctx);
+ jack_on_shutdown(client, jack_shutdown, (void *)ctx);
if (jack_activate (client))
fprintf (stderr, "cannot activate client");
@@ -115,15 +114,15 @@ jack_client_t* init_jack(void)
for(int i = 0; i < CHANNELS; i++)
{
char* portName;
- if (asprintf(&portName, "input%d", i) < 0)
+ if (asprintf(&portName, "input%d", i) < 0)
{
fprintf(stderr, "Could not create portname for port %d", i);
exit(EXIT_FAILURE);
- }
-
+ }
+
inputports[i] = jack_port_register (client, portName,
JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
- if (NULL == inputports[i])
+ if (NULL == inputports[i])
{
fprintf (stderr, "cannot register input port \"%d\"!\n", i);
jack_client_close (client);
diff --git a/examples/jackd-talker/jack.h b/examples/jackd-talker/jack.h
index c78dc1ab..1e96bfb0 100644
--- a/examples/jackd-talker/jack.h
+++ b/examples/jackd-talker/jack.h
@@ -2,9 +2,10 @@
#define _AVB_JACK_H
#define DEFAULT_RINGBUFFER_SIZE 32768
+extern struct mrp_talker_ctx *ctx;
/* Prototypes */
-jack_client_t* init_jack(void);
+jack_client_t* init_jack(struct mrp_talker_ctx *ctx);
void stop_jack(jack_client_t* client);
#endif /* _AVB_JACK_H */
diff --git a/examples/jackd-talker/jackd_talker.c b/examples/jackd-talker/jackd_talker.c
index 11005fc7..b3ddac07 100755..100644
--- a/examples/jackd-talker/jackd_talker.c
+++ b/examples/jackd-talker/jackd_talker.c
@@ -1,31 +1,31 @@
/******************************************************************************
- Copyright (c) 2012, Intel Corporation
+ Copyright (c) 2012, Intel Corporation
All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
+
+ Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
+
+ 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
+
+ 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. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
-
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
@@ -64,6 +64,7 @@
#define RENDER_DELAY (XMIT_DELAY+2000000) /* us */
#define PACKET_IPG (125000) /* (1) packet every 125 usec */
#define PKT_SZ (100)
+volatile int *halt_tx_sig;//Global variable for signal handler
typedef long double FrequencyRatio;
@@ -208,7 +209,7 @@ int gptpscaling(char *igb_mmap, gPtpTimeData *td)
void sigint_handler(int signum)
{
printf("got SIGINT\n");
- halt_tx = signum;
+ *halt_tx_sig = signum;
glob_unleash_jack = 0;
}
@@ -291,6 +292,7 @@ static void usage(void)
static void* packetizer_thread(void *arg) {
struct igb_packet *cleaned_packets;
+ struct mrp_talker_ctx *ctx = (struct mrp_talker_ctx *)arg;
six1883_sample *sample;
unsigned total_samples = 0;
int err;
@@ -307,7 +309,7 @@ static void* packetizer_thread(void *arg) {
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_mutex_lock(&threadLock);
- while (listeners && !halt_tx) {
+ while (ctx->listeners && !ctx->halt_tx) {
pthread_cond_wait(&dataReady, &threadLock);
while ((jack_ringbuffer_read_space(ringbuffer) >= bytes_to_read)) {
@@ -405,6 +407,9 @@ int main(int argc, char *argv[])
uint64_t update_8021as;
unsigned delta_8021as, delta_local;
jack_client_t* _jackclient;
+ struct mrp_talker_ctx *ctx = malloc(sizeof(struct mrp_talker_ctx));
+ struct mrp_domain_attr *class_a = malloc(sizeof(struct mrp_domain_attr));
+ struct mrp_domain_attr *class_b = malloc(sizeof(struct mrp_domain_attr));
for (;;) {
c = getopt(argc, argv, "hi:");
@@ -429,7 +434,14 @@ int main(int argc, char *argv[])
if (NULL == interface) {
usage();
}
- rc = mrp_connect();
+ rc = mrp_talker_client_init(ctx);
+ if (rc) {
+ printf("MRP talker client initialization failed\n");
+ return errno;
+ }
+ halt_tx_sig = &ctx->halt_tx;
+
+ rc = mrp_connect(ctx);
if (rc) {
printf("socket creation failed\n");
return errno;
@@ -459,28 +471,24 @@ int main(int argc, char *argv[])
usage();
}
- rc = mrp_monitor();
+ rc = mrp_get_domain(ctx, class_a, class_b);
if (rc) {
- printf("failed creating MRP monitor thread\n");
+ printf("failed calling msp_get_domain()\n");
return EXIT_FAILURE;
}
+ printf("detected domain Class A PRIO=%d VID=%04x...\n",class_a->priority,
+ class_a->vid);
- /*
- * should use mrp_get_domain() above but this is a simplification
- */
-
- domain_a_valid = 1;
- domain_class_a_id = MSRP_SR_CLASS_A;
- domain_class_a_priority = MSRP_SR_CLASS_A_PRIO;
- domain_class_a_vid = 2;
- printf("detected domain Class A PRIO=%d VID=%04x...\n", domain_class_a_priority,
- domain_class_a_vid);
-
- rc = mrp_register_domain(&domain_class_a_id, &domain_class_a_priority, &domain_class_a_vid);
+ rc = mrp_register_domain(class_a, ctx);
if (rc) {
printf("mrp_register_domain failed\n");
return EXIT_FAILURE;
}
+ rc = mrp_join_vlan(class_a, ctx);
+ if (rc) {
+ printf("mrp_join_vlan failed\n");
+ return EXIT_FAILURE;
+ }
igb_set_class_bandwidth(&glob_igb_dev, PACKET_IPG / 125000, 0, PKT_SZ - 22,
0);
@@ -517,9 +525,9 @@ int main(int argc, char *argv[])
((char *)glob_tmp_packet->vaddr)[12] = 0x81;
((char *)glob_tmp_packet->vaddr)[13] = 0x00;
((char *)glob_tmp_packet->vaddr)[14] =
- ((domain_class_a_priority << 13 | domain_class_a_vid)) >> 8;
+ ((ctx->domain_class_a_priority << 13 | ctx->domain_class_a_vid)) >> 8;
((char *)glob_tmp_packet->vaddr)[15] =
- ((domain_class_a_priority << 13 | domain_class_a_vid)) & 0xFF;
+ ((ctx->domain_class_a_priority << 13 | ctx->domain_class_a_vid)) & 0xFF;
((char *)glob_tmp_packet->vaddr)[16] = 0x22; /* 1722 eth type */
((char *)glob_tmp_packet->vaddr)[17] = 0xF0;
@@ -561,31 +569,32 @@ int main(int argc, char *argv[])
glob_free_packets = glob_tmp_packet;
}
- /*
- * subtract 16 bytes for the MAC header/Q-tag - pktsz is limited to the
+ /*
+ * subtract 16 bytes for the MAC header/Q-tag - pktsz is limited to the
* data payload of the ethernet frame .
*
* IPG is scaled to the Class (A) observation interval of packets per 125 usec
*/
- _jackclient = init_jack();
+ _jackclient = init_jack(ctx);
fprintf(stderr, "advertising stream ...\n");
- rc = mrp_advertise_stream(glob_stream_id, glob_dest_addr, domain_class_a_vid, PKT_SZ - 16,
- PACKET_IPG / 125000, domain_class_a_priority, 3900);
+ rc = mrp_advertise_stream(glob_stream_id, glob_dest_addr, PKT_SZ - 16,
+ PACKET_IPG / 125000, 3900, ctx);
if (rc) {
printf("mrp_advertise_stream failed\n");
return EXIT_FAILURE;
}
fprintf(stderr, "awaiting a listener ...\n");
- rc = mrp_await_listener(glob_stream_id);
+ rc = mrp_await_listener(glob_stream_id,ctx);
if (rc) {
printf("mrp_await_listener failed\n");
return EXIT_FAILURE;
}
+ ctx->listeners = 1;
printf("got a listener ...\n");
- halt_tx = 0;
+ ctx->halt_tx = 0;
if(-1 == gptpinit(&igb_shm_fd, &igb_mmap)) {
return EXIT_FAILURE;
@@ -609,28 +618,31 @@ int main(int argc, char *argv[])
rc = nice(-20);
- pthread_create (&glob_packetizer_id, NULL, packetizer_thread, NULL);
+ pthread_create (&glob_packetizer_id, NULL, packetizer_thread, (void *)ctx);
run_packetizer();
rc = nice(0);
stop_jack(_jackclient);
- if (halt_tx == 0)
+ if (ctx->halt_tx == 0)
printf("listener left ...\n");
- halt_tx = 1;
+ ctx->halt_tx = 1;
- rc = mrp_unadvertise_stream(glob_stream_id, glob_dest_addr, domain_class_a_vid, PKT_SZ - 16,
- PACKET_IPG / 125000, domain_class_a_priority, 3900);
+ rc = mrp_unadvertise_stream(glob_stream_id, glob_dest_addr, PKT_SZ - 16,
+ PACKET_IPG / 125000, 3900, ctx);
if (rc)
printf("mrp_unadvertise_stream failed\n");
igb_set_class_bandwidth(&glob_igb_dev, 0, 0, 0, 0); /* disable Qav */
- rc = mrp_disconnect();
+ rc = mrp_disconnect(ctx);
if (rc)
printf("mrp_disconnect failed\n");
+ free(ctx);
+ free(class_a);
+ free(class_b);
igb_dma_free_page(&glob_igb_dev, &a_page);
rc = gptpdeinit(&igb_shm_fd, &igb_mmap);
err = igb_detach(&glob_igb_dev);
diff --git a/examples/live_stream/listener.c b/examples/live_stream/listener.c
index a7ae7dd0..7ce12000 100644
--- a/examples/live_stream/listener.c
+++ b/examples/live_stream/listener.c
@@ -34,6 +34,7 @@
/* globals */
unsigned char glob_dest_addr[] = { 0x91, 0xE0, 0xF0, 0x00, 0x0E, 0x80 };
+struct mrp_listener_ctx *ctx_sig;//Context pointer for signal handler
void sigint_handler(int signum)
{
@@ -41,15 +42,18 @@ void sigint_handler(int signum)
fprintf(stderr, "Received signal %d:leaving...\n", signum);
#if USE_MRPD
- if (0 != talker) {
- ret = send_leave();
+ if (0 != ctx_sig->talker) {
+ ret = send_leave(ctx_sig);
if (ret)
printf("send_leave failed\n");
}
#endif /* USE_MRPD */
- if (2 > control_socket)
+ if (2 > ctx_sig->control_socket)
{
- close(control_socket);
+ close(ctx_sig->control_socket);
+ ret = mrp_disconnect(ctx_sig);
+ if (ret)
+ printf("mrp_disconnect failed\n");
}
exit(EXIT_SUCCESS);
}
@@ -69,6 +73,10 @@ int main(int argc, char *argv[ ])
unsigned char frame[MAX_FRAME_SIZE];
int size, length;
struct sched_param sched;
+ struct mrp_listener_ctx *ctx = malloc(sizeof(struct mrp_listener_ctx));
+ struct mrp_domain_attr *class_a = malloc(sizeof(struct mrp_domain_attr));
+ struct mrp_domain_attr *class_b = malloc(sizeof(struct mrp_domain_attr));
+ ctx_sig = ctx;
int rc;
if (argc < 2) {
@@ -78,20 +86,45 @@ int main(int argc, char *argv[ ])
signal(SIGINT, sigint_handler);
#if USE_MRPD
- if (create_socket()) {
+ rc = mrp_listener_client_init(ctx);
+ if (rc)
+ {
+ printf("failed to initialize global variables\n");
+ return EXIT_FAILURE;
+ }
+ if (create_socket(ctx)) {
fprintf(stderr, "Socket creation failed.\n");
return errno;
}
+ rc = mrp_monitor(ctx);
+ if (rc)
+ {
+ printf("failed creating MRP monitor thread\n");
+ return EXIT_FAILURE;
+ }
+ rc=mrp_get_domain(ctx, class_a, class_b);
+ if (rc)
+ {
+ printf("failed calling mrp_get_domain()\n");
+ return EXIT_FAILURE;
+ }
- rc = report_domain_status();
+ printf("detected domain Class A PRIO=%d VID=%04x...\n",class_a->priority,class_a->vid);
+
+ rc = report_domain_status(class_a,ctx);
if (rc) {
printf("report_domain_status failed\n");
return EXIT_FAILURE;
}
+ rc = join_vlan(class_a, ctx);
+ if (rc) {
+ printf("join_vlan failed\n");
+ return EXIT_FAILURE;
+ }
fprintf(stdout,"Waiting for talker...\n");
- await_talker();
- rc = send_ready();
+ await_talker(ctx);
+ rc = send_ready(ctx);
if (rc) {
printf("send_ready failed\n");
return EXIT_FAILURE;
@@ -174,8 +207,9 @@ int main(int argc, char *argv[ ])
usleep(100);
close(socket_descriptor);
+ free(ctx);
+ free(class_a);
+ free(class_b);
return EXIT_SUCCESS;
}
-
-
diff --git a/examples/live_stream/talker.c b/examples/live_stream/talker.c
index 320d347a..fb787c5d 100644
--- a/examples/live_stream/talker.c
+++ b/examples/live_stream/talker.c
@@ -39,6 +39,7 @@ unsigned char glob_station_addr[] = { 0, 0, 0, 0, 0, 0 };
unsigned char glob_stream_id[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
/* IEEE 1722 reserved address */
unsigned char glob_dest_addr[] = { 0x91, 0xE0, 0xF0, 0x00, 0x0E, 0x80 };
+volatile int *halt_tx_sig;//Global variable for signal handler
uint64_t reverse_64(uint64_t val)
{
@@ -59,7 +60,7 @@ uint64_t reverse_64(uint64_t val)
void sigint_handler(int signum)
{
fprintf(stderr, "got SIGINT\n");
- halt_tx = signum;
+ *halt_tx_sig = signum;
}
int get_mac_addr(int8_t *iface)
@@ -94,6 +95,7 @@ int main(int argc, char *argv[])
struct igb_packet *tmp_packet;
struct igb_packet *cleaned_packets;
struct igb_packet *free_packets;
+ struct mrp_talker_ctx *ctx = malloc(sizeof(struct mrp_talker_ctx));
six1883_header *h61883;
seventeen22_header *h1722;
unsigned i;
@@ -106,6 +108,8 @@ int main(int argc, char *argv[])
void *stream_packet;
long long int frame_sequence = 0;
struct sched_param sched;
+ struct mrp_domain_attr *class_a = malloc(sizeof(struct mrp_domain_attr));
+ struct mrp_domain_attr *class_b = malloc(sizeof(struct mrp_domain_attr));
if (argc < 2) {
fprintf(stderr,"%s <if_name> <payload>\n", argv[0]);
@@ -116,9 +120,14 @@ int main(int argc, char *argv[])
packet_size = atoi(argv[2]);;
glob_payload_length = atoi(argv[2]);;
packet_size += sizeof(six1883_header) + sizeof(seventeen22_header) + sizeof(eth_header);
-
+ err = mrp_talker_client_init(ctx);
+ if (err) {
+ printf("MRP talker client initialization failed\n");
+ return errno;
+ }
+ halt_tx_sig = &ctx->halt_tx;
#ifdef USE_MRPD
- err = mrp_connect();
+ err = mrp_connect(ctx);
if (err) {
fprintf(stderr, "socket creation failed\n");
return errno;
@@ -152,28 +161,24 @@ int main(int argc, char *argv[])
}
#ifdef USE_MRPD
- err = mrp_monitor();
+ err = mrp_get_domain(ctx, class_a, class_b);
if (err) {
- printf("failed creating MRP monitor thread\n");
+ printf("failed calling msp_get_domain()\n");
return EXIT_FAILURE;
}
+ fprintf(stderr, "detected domain Class A PRIO=%d VID=%04x...\n", class_a->priority,
+ class_a->vid);
- domain_a_valid = 1;
- domain_class_a_id = MSRP_SR_CLASS_A;
- domain_class_a_priority = MSRP_SR_CLASS_A_PRIO;
- domain_class_a_vid = 2;
- fprintf(stderr, "detected domain Class A PRIO=%d VID=%04x...\n", domain_class_a_priority,
- domain_class_a_vid);
-
- err = mrp_register_domain(&domain_class_a_id, &domain_class_a_priority, &domain_class_a_vid);
+ err = mrp_register_domain(class_a, ctx);
if (err) {
printf("mrp_register_domain failed\n");
return EXIT_FAILURE;
}
-
- domain_a_valid = 1;
- domain_class_a_vid = 2;
- fprintf(stderr, "detected domain Class A PRIO=%d VID=%04x...\n", domain_class_a_priority, domain_class_a_vid);
+ err = mrp_join_vlan(class_a, ctx);
+ if (err) {
+ printf("mrp_join_vlan failed\n");
+ return EXIT_FAILURE;
+ }
#endif
igb_set_class_bandwidth(&igb_dev, PACKET_IPG / 125000, 0, packet_size - 22, 0);
@@ -205,7 +210,7 @@ int main(int argc, char *argv[])
avb_set_1722_stream_id(h1722,reverse_64(STREAMID));
avb_set_1722_sid_valid(h1722, 0x1);
-
+
/*initalize h61883 header */
avb_initialize_61883_to_defaults(h61883);
avb_set_61883_format_tag(h61883, 0x1);
@@ -242,26 +247,29 @@ int main(int argc, char *argv[])
}
#ifdef USE_MRPD
- /*
- * subtract 16 bytes for the MAC header/Q-tag - pktsz is limited to the
+ /*
+ * subtract 16 bytes for the MAC header/Q-tag - pktsz is limited to the
* data payload of the ethernet frame .
*
* IPG is scaled to the Class (A) observation interval of packets per 125 usec
*/
fprintf(stderr, "advertising stream ...\n");
- err = mrp_advertise_stream(glob_stream_id, glob_dest_addr, domain_class_a_vid, packet_size - 16,
- PACKET_IPG / 125000, domain_class_a_priority, 3900);
+ err = mrp_advertise_stream(glob_stream_id, glob_dest_addr, packet_size - 16,
+ PACKET_IPG / 125000, 3900, ctx);
if (err) {
printf("mrp_advertise_stream failed\n");
return EXIT_FAILURE;
}
fprintf(stderr, "awaiting a listener ...\n");
- err = mrp_await_listener(glob_stream_id);
+ err = mrp_await_listener(glob_stream_id,ctx);
if (err) {
printf("mrp_await_listener failed\n");
return EXIT_FAILURE;
}
+ ctx->listeners = 1;
+ printf("got a listener ...\n");
+ ctx->halt_tx = 0;
#endif
@@ -269,7 +277,7 @@ int main(int argc, char *argv[])
sched.sched_priority = 1;
sched_setscheduler(0, SCHED_RR, &sched);
- while (listeners && !halt_tx)
+ while (ctx->listeners && !ctx->halt_tx)
{
tmp_packet = free_packets;
if (NULL == tmp_packet)
@@ -289,9 +297,9 @@ int main(int argc, char *argv[])
else
avb_set_1722_timestamp_valid(h1722, 1);
- data_ptr = (uint8_t *)((uint8_t*)stream_packet + sizeof(eth_header) + sizeof(seventeen22_header)
+ data_ptr = (uint8_t *)((uint8_t*)stream_packet + sizeof(eth_header) + sizeof(seventeen22_header)
+ sizeof(six1883_header));
-
+
read_bytes = read(0, (void *)data_ptr, glob_payload_length);
/* Error case while reading the input file */
if (read_bytes < 0) {
@@ -325,24 +333,27 @@ cleanup:
}
}
- if (halt_tx == 0)
+ if (ctx->halt_tx == 0)
fprintf(stderr, "listener left ...\n");
- halt_tx = 1;
+ ctx->halt_tx = 1;
sleep(1);
#ifdef USE_MRPD
- err = mrp_unadvertise_stream(glob_stream_id, glob_dest_addr, domain_class_a_vid, packet_size - 16,
- PACKET_IPG / 125000, domain_class_a_priority, 3900);
+ err = mrp_unadvertise_stream(glob_stream_id, glob_dest_addr, packet_size - 16,
+ PACKET_IPG / 125000, 3900, ctx);
if (err)
printf("mrp_unadvertise_stream failed\n");
#endif
/* disable Qav */
igb_set_class_bandwidth(&igb_dev, 0, 0, 0, 0);
#ifdef USE_MRPD
- err = mrp_disconnect();
+ err = mrp_disconnect(ctx);
if (err)
printf("mrp_disconnect failed\n");
#endif
+ free(ctx);
+ free(class_a);
+ free(class_b);
igb_dma_free_page(&igb_dev, &a_page);
err = igb_detach(&igb_dev);
diff --git a/examples/simple_listener/Makefile b/examples/simple_listener/Makefile
index cb863045..9a4b33a6 100644
--- a/examples/simple_listener/Makefile
+++ b/examples/simple_listener/Makefile
@@ -2,7 +2,7 @@ CC ?= gcc
OPT = -O2 -g
CFLAGS = $(OPT) -Wall -Wextra -Wno-parentheses
INCFLAGS = -I../../daemons/mrpd -I../common -I../../daemons/common
-LDLIBS = -lpcap -lsndfile
+LDLIBS = -lpcap -lsndfile -pthread
all: simple_listener
diff --git a/examples/simple_listener/simple_listener.c b/examples/simple_listener/simple_listener.c
index 85f322e8..bd1c1cab 100644
--- a/examples/simple_listener/simple_listener.c
+++ b/examples/simple_listener/simple_listener.c
@@ -49,6 +49,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define SAMPLES_PER_FRAME (6)
#define CHANNELS (2)
+struct mrp_listener_ctx *ctx_sig;//Context pointer for signal handler
+
struct ethernet_header{
u_char dst[6];
u_char src[6];
@@ -73,7 +75,7 @@ static void help()
"Options:\n"
" -h show this message\n"
" -i specify interface for AVB connection\n"
- " -f set the name of the output wav-file\n"
+ " -f set the name of the output wav-file\n"
"\n" "%s" "\n", version_str);
exit(EXIT_FAILURE);
}
@@ -85,7 +87,7 @@ void pcap_callback(u_char* args, const struct pcap_pkthdr* packet_header, const
uint32_t *buf;
uint32_t frame[2] = { 0 , 0 };
int i;
- (void) args; /* unused */
+ struct mrp_listener_ctx *ctx = (struct mrp_listener_ctx*) args;
(void) packet_header; /* unused */
#if DEBUG
@@ -99,7 +101,7 @@ void pcap_callback(u_char* args, const struct pcap_pkthdr* packet_header, const
#endif /* DEBUG*/
if (0 == memcmp(glob_ether_type,eth_header->type,sizeof(eth_header->type)))
- {
+ {
test_stream_id = (unsigned char*)(packet + ETHERNET_HEADER_SIZE + SEVENTEEN22_HEADER_PART1_SIZE);
#if DEBUG
@@ -110,7 +112,7 @@ void pcap_callback(u_char* args, const struct pcap_pkthdr* packet_header, const
test_stream_id[6], test_stream_id[7]);
#endif /* DEBUG*/
- if (0 == memcmp(test_stream_id, stream_id, sizeof(STREAM_ID_SIZE)))
+ if (0 == memcmp(test_stream_id, ctx->stream_id, sizeof(STREAM_ID_SIZE)))
{
#if DEBUG
@@ -118,7 +120,7 @@ void pcap_callback(u_char* args, const struct pcap_pkthdr* packet_header, const
#endif /* DEBUG*/
buf = (uint32_t*) (packet + HEADER_SIZE);
for(i = 0; i < SAMPLES_PER_FRAME * CHANNELS; i += 2)
- {
+ {
memcpy(&frame[0], &buf[i], sizeof(frame));
frame[0] = ntohl(frame[0]); /* convert to host-byte order */
@@ -130,7 +132,7 @@ void pcap_callback(u_char* args, const struct pcap_pkthdr* packet_header, const
sf_writef_int(glob_snd_file, (const int *)frame, 1);
}
- }
+ }
}
}
@@ -140,16 +142,16 @@ void sigint_handler(int signum)
fprintf(stdout,"Received signal %d:leaving...\n", signum);
- if (0 != talker) {
- ret = send_leave();
+ if (0 != ctx_sig->talker) {
+ ret = send_leave(ctx_sig);
if (ret)
printf("send_leave failed\n");
}
- if (2 > control_socket)
+ if (2 > ctx_sig->control_socket)
{
- close(control_socket);
- ret = mrp_disconnect();
+ close(ctx_sig->control_socket);
+ ret = mrp_disconnect(ctx_sig);
if (ret)
printf("mrp_disconnect failed\n");
}
@@ -161,7 +163,7 @@ void sigint_handler(int signum)
pcap_close(glob_pcap_handle);
}
#endif /* PCAP */
-
+
#if LIBSND
sf_write_sync(glob_snd_file);
sf_close(glob_snd_file);
@@ -174,17 +176,19 @@ int main(int argc, char *argv[])
char* dev = NULL;
char errbuf[PCAP_ERRBUF_SIZE];
struct bpf_program comp_filter_exp; /* The compiled filter expression */
- char filter_exp[] = "ether dst 91:E0:F0:00:0e:80"; /* The filter expression */
- int rc;
-
+ char filter_exp[100]; /* The filter expression */
+ struct mrp_listener_ctx *ctx = malloc(sizeof(struct mrp_listener_ctx));
+ struct mrp_domain_attr *class_a = malloc(sizeof(struct mrp_domain_attr));
+ struct mrp_domain_attr *class_b = malloc(sizeof(struct mrp_domain_attr));
+ ctx_sig = ctx;
signal(SIGINT, sigint_handler);
- int c;
- while((c = getopt(argc, argv, "hi:f:")) > 0)
+ int c,rc;
+ while((c = getopt(argc, argv, "hi:f:")) > 0)
{
- switch (c)
+ switch (c)
{
- case 'h':
+ case 'h':
help();
break;
case 'i':
@@ -201,41 +205,63 @@ int main(int argc, char *argv[])
if ((NULL == dev) || (NULL == file_name))
help();
- if (create_socket())
+ rc = mrp_listener_client_init(ctx);
+ if (rc)
+ {
+ printf("failed to initialize global variables\n");
+ return EXIT_FAILURE;
+ }
+
+ if (create_socket(ctx))
{
fprintf(stderr, "Socket creation failed.\n");
return errno;
}
- rc = report_domain_status();
+ rc = mrp_monitor(ctx);
+ if (rc)
+ {
+ printf("failed creating MRP monitor thread\n");
+ return EXIT_FAILURE;
+ }
+ rc=mrp_get_domain(ctx, class_a, class_b);
+ if (rc)
+ {
+ printf("failed calling mrp_get_domain()\n");
+ return EXIT_FAILURE;
+ }
+
+ printf("detected domain Class A PRIO=%d VID=%04x...\n",class_a->priority,class_a->vid);
+
+ rc = report_domain_status(class_a,ctx);
if (rc) {
printf("report_domain_status failed\n");
return EXIT_FAILURE;
}
- rc = join_vlan();
+ rc = join_vlan(class_a, ctx);
if (rc) {
printf("join_vlan failed\n");
return EXIT_FAILURE;
}
fprintf(stdout,"Waiting for talker...\n");
- await_talker();
+ await_talker(ctx);
#if DEBUG
fprintf(stdout,"Send ready-msg...\n");
#endif /* DEBUG */
- rc = send_ready();
+ rc = send_ready(ctx);
if (rc) {
printf("send_ready failed\n");
return EXIT_FAILURE;
}
-
+
#if LIBSND
SF_INFO* sf_info = (SF_INFO*)malloc(sizeof(SF_INFO));
memset(sf_info, 0, sizeof(SF_INFO));
-
+
sf_info->samplerate = SAMPLES_PER_SECOND;
sf_info->channels = CHANNELS;
sf_info->format = SF_FORMAT_WAV | SF_FORMAT_PCM_24;
@@ -245,13 +271,13 @@ int main(int argc, char *argv[])
fprintf(stderr, "Wrong format.");
return EXIT_FAILURE;
}
-
+
if (NULL == (glob_snd_file = sf_open(file_name, SFM_WRITE, sf_info)))
{
fprintf(stderr, "Could not create file.");
return EXIT_FAILURE;
}
- fprintf(stdout,"Created file called %s\n", file_name);
+ fprintf(stdout,"Created file called %s\n", file_name);
#endif /* LIBSND */
#if PCAP
@@ -268,6 +294,7 @@ int main(int argc, char *argv[])
fprintf(stdout,"Got session pcap handler.\n");
#endif /* DEBUG */
/* compile and apply filter */
+ sprintf(filter_exp,"ether dst %02x:%02x:%02x:%02x:%02x:%02x",ctx->dst_mac[0],ctx->dst_mac[1],ctx->dst_mac[2],ctx->dst_mac[3],ctx->dst_mac[4],ctx->dst_mac[5]);
if (-1 == pcap_compile(glob_pcap_handle, &comp_filter_exp, filter_exp, 0, PCAP_NETMASK_UNKNOWN))
{
fprintf(stderr, "Could not parse filter %s: %s\n", filter_exp, pcap_geterr(glob_pcap_handle));
@@ -285,8 +312,11 @@ int main(int argc, char *argv[])
#endif /* DEBUG */
/** loop forever and call callback-function for every received packet */
- pcap_loop(glob_pcap_handle, -1, pcap_callback, NULL);
+ pcap_loop(glob_pcap_handle, -1, pcap_callback, (u_char*)ctx);
#endif /* PCAP */
+ free(ctx);
+ free(class_a);
+ free(class_b);
return EXIT_SUCCESS;
}
diff --git a/examples/simple_talker/simple_talker.c b/examples/simple_talker/simple_talker.c
index e66e8c52..38636b90 100644
--- a/examples/simple_talker/simple_talker.c
+++ b/examples/simple_talker/simple_talker.c
@@ -1,31 +1,31 @@
/******************************************************************************
- Copyright (c) 2012, Intel Corporation
+ Copyright (c) 2012, Intel Corporation
All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
+
+ Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
+
+ 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
+
+ 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. Neither the name of the Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived from
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
-
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
@@ -73,6 +73,7 @@
#define PKT_SZ (100)
typedef long double FrequencyRatio;
+volatile int *halt_tx_sig;//Global variable for signal handler
typedef struct {
int64_t ml_phoffset;
@@ -147,7 +148,7 @@ typedef struct __attribute__ ((packed)) {
uint16_t sequence;
uint32_t timestamp;
uint32_t ssrc;
-
+
uint8_t tag[2];
uint16_t total_length;
uint8_t tag_length;
@@ -183,13 +184,13 @@ uint16_t inet_checksum(uint8_t *ip, int len){
sum = (sum & 0xFFFF) + (sum >> 16);
len -= 2;
}
-
+
if(len) /* take care of left over byte */
sum += (uint16_t) *(uint8_t *)ip;
-
+
while(sum>>16)
sum = (sum & 0xFFFF) + (sum >> 16);
-
+
return ~sum;
}
@@ -241,7 +242,7 @@ uint16_t inet_checksum_sg( struct iovec *buf_iov, size_t buf_iovlen ){
while(sum>>16)
sum = (sum & 0xFFFF) + (sum >> 16);
-
+
return ~sum;
}
@@ -352,7 +353,7 @@ int get_samples(unsigned count, int32_t * buffer)
void sigint_handler(int signum)
{
printf("got SIGINT\n");
- halt_tx = signum;
+ *halt_tx_sig = signum;
}
int pci_connect(device_t *igb_dev)
@@ -452,6 +453,7 @@ int main(int argc, char *argv[])
struct igb_packet *tmp_packet;
struct igb_packet *cleaned_packets;
struct igb_packet *free_packets;
+ struct mrp_talker_ctx *ctx = malloc(sizeof(struct mrp_talker_ctx));
int c;
u_int64_t last_time;
int rc = 0;
@@ -480,6 +482,8 @@ int main(int argc, char *argv[])
unsigned delta_8021as, delta_local;
uint8_t dest_addr[6];
size_t packet_size;
+ struct mrp_domain_attr *class_a = malloc(sizeof(struct mrp_domain_attr));
+ struct mrp_domain_attr *class_b = malloc(sizeof(struct mrp_domain_attr));
for (;;) {
c = getopt(argc, argv, "hi:t:");
@@ -491,8 +495,7 @@ int main(int argc, char *argv[])
break;
case 'i':
if (interface) {
- printf
- ("only one interface per daemon is supported\n");
+ printf("only one interface per daemon is supported\n");
usage();
}
interface = strdup(optarg);
@@ -510,7 +513,16 @@ int main(int argc, char *argv[])
fprintf( stderr, "Must specify valid transport\n" );
usage();
}
- rc = mrp_connect();
+
+ rc = mrp_talker_client_init(ctx);
+ if (rc) {
+ printf("MRP talker client initialization failed\n");
+ return errno;
+ }
+
+ halt_tx_sig = &ctx->halt_tx;
+
+ rc = mrp_connect(ctx);
if (rc) {
printf("socket creation failed\n");
return errno;
@@ -568,32 +580,24 @@ int main(int argc, char *argv[])
( &l4_local_address,
&(( struct sockaddr_in *)&if_request.ifr_addr)->sin_addr,
sizeof( l4_local_address ));
-
+
}
- rc = mrp_monitor();
+ rc = mrp_get_domain(ctx, class_a, class_b);
if (rc) {
- printf("failed creating MRP monitor thread\n");
+ printf("failed calling msp_get_domain()\n");
return EXIT_FAILURE;
}
+ printf("detected domain Class A PRIO=%d VID=%04x...\n",class_a->priority,
+ class_a->vid);
- /*
- * should use mrp_get_domain() but this is a simplification
- */
- domain_a_valid = 1;
- domain_class_a_id = MSRP_SR_CLASS_A;
- domain_class_a_priority = MSRP_SR_CLASS_A_PRIO;
- domain_class_a_vid = 2;
- printf("detected domain Class A PRIO=%d VID=%04x...\n", domain_class_a_priority,
- domain_class_a_vid);
-
- rc = mrp_register_domain(&domain_class_a_id, &domain_class_a_priority, &domain_class_a_vid);
+ rc = mrp_register_domain(class_a, ctx);
if (rc) {
printf("mrp_register_domain failed\n");
return EXIT_FAILURE;
}
- rc = mrp_join_vlan();
+ rc = mrp_join_vlan(class_a, ctx);
if (rc) {
printf("mrp_join_vlan failed\n");
return EXIT_FAILURE;
@@ -649,9 +653,9 @@ int main(int argc, char *argv[])
((char *)tmp_packet->vaddr)[12] = 0x81;
((char *)tmp_packet->vaddr)[13] = 0x00;
((char *)tmp_packet->vaddr)[14] =
- ((domain_class_a_priority << 13 | domain_class_a_vid)) >> 8;
+ ((ctx->domain_class_a_priority << 13 | ctx->domain_class_a_vid)) >> 8;
((char *)tmp_packet->vaddr)[15] =
- ((domain_class_a_priority << 13 | domain_class_a_vid)) & 0xFF;
+ ((ctx->domain_class_a_priority << 13 | ctx->domain_class_a_vid)) & 0xFF;
if( transport == 2 ) {
((char *)tmp_packet->vaddr)[16] = 0x22; /* 1722 eth type */
((char *)tmp_packet->vaddr)[17] = 0xF0;
@@ -703,7 +707,7 @@ int main(int argc, char *argv[])
pseudo_hdr.zero = 0;
pseudo_hdr.protocol = 0x11;
pseudo_hdr.length = htons(packet_size-18-20);
-
+
l4_headers =
(IP_RTP_Header *) (((char *)tmp_packet->vaddr) + 18);
l4_headers->version_length = 0x45;
@@ -734,7 +738,7 @@ int main(int argc, char *argv[])
l4_headers->sequence = 0;
l4_headers->timestamp = 0;
l4_headers->ssrc = 0;
-
+
l4_headers->tag[0] = 0xBE;
l4_headers->tag[1] = 0xDE;
l4_headers->total_length = htons(2);
@@ -748,7 +752,7 @@ int main(int argc, char *argv[])
free_packets = tmp_packet;
}
- /*
+ /*
* subtract 16 bytes for the MAC header/Q-tag - pktsz is limited to the
* data payload of the ethernet frame.
*
@@ -757,9 +761,9 @@ int main(int argc, char *argv[])
fprintf(stderr, "advertising stream ...\n");
if( transport == 2 ) {
rc = mrp_advertise_stream(glob_stream_id, dest_addr,
- domain_class_a_vid, PKT_SZ - 16,
+ PKT_SZ - 16,
L2_PACKET_IPG / 125000,
- domain_class_a_priority, 3900);
+ 3900,ctx);
} else {
/*
* 1 is the wrong number for frame rate, but fractional values
@@ -767,10 +771,9 @@ int main(int argc, char *argv[])
* using it consistently
*/
rc = mrp_advertise_stream(glob_stream_id, dest_addr,
- domain_class_a_vid,
sizeof(*l4_headers) + L4_SAMPLES_PER_FRAME * CHANNELS * 2 + 6,
1,
- domain_class_a_priority, 3900);
+ 3900, ctx);
}
if (rc) {
printf("mrp_advertise_stream failed\n");
@@ -778,14 +781,14 @@ int main(int argc, char *argv[])
}
fprintf(stderr, "awaiting a listener ...\n");
- rc = mrp_await_listener(glob_stream_id);
+ rc = mrp_await_listener(glob_stream_id, ctx);
if (rc) {
printf("mrp_await_listener failed\n");
return EXIT_FAILURE;
}
- listeners = 1;
+ ctx->listeners = 1;
printf("got a listener ...\n");
- halt_tx = 0;
+ ctx->halt_tx = 0;
if(-1 == gptpinit(&igb_shm_fd, &igb_mmap)) {
fprintf(stderr, "GPTP init failed.\n");
@@ -811,13 +814,13 @@ int main(int argc, char *argv[])
rc = nice(-20);
- while (listeners && !halt_tx) {
+ while (ctx->listeners && !ctx->halt_tx) {
tmp_packet = free_packets;
if (NULL == tmp_packet)
goto cleanup;
-
+
free_packets = tmp_packet->next;
-
+
if( transport == 2 ) {
uint32_t timestamp_l;
get_samples( L2_SAMPLES_PER_FRAME, sample_buffer );
@@ -911,13 +914,13 @@ int main(int argc, char *argv[])
}
if (ENOSPC == err) {
-
+
/* put back for now */
tmp_packet->next = free_packets;
free_packets = tmp_packet;
}
-
- cleanup:
+
+ cleanup:
igb_clean(&igb_dev, &cleaned_packets);
i = 0;
while (cleaned_packets) {
@@ -929,35 +932,35 @@ int main(int argc, char *argv[])
}
}
rc = nice(0);
-
- if (halt_tx == 0)
+ if (ctx->halt_tx == 0)
printf("listener left ...\n");
- halt_tx = 1;
-
+ ctx->halt_tx = 1;
if( transport == 2 ) {
rc = mrp_unadvertise_stream
- (glob_stream_id, dest_addr, domain_class_a_vid, PKT_SZ - 16, L2_PACKET_IPG / 125000,
- domain_class_a_priority, 3900);
+ (glob_stream_id, dest_addr, PKT_SZ - 16, L2_PACKET_IPG / 125000,
+ 3900, ctx);
} else {
rc = mrp_unadvertise_stream
- (glob_stream_id, dest_addr, domain_class_a_vid,
+ (glob_stream_id, dest_addr,
sizeof(*l4_headers)+L4_SAMPLES_PER_FRAME*CHANNELS*2 + 6, 1,
- domain_class_a_priority, 3900);
+ 3900, ctx);
}
if (rc)
printf("mrp_unadvertise_stream failed\n");
-
+
igb_set_class_bandwidth(&igb_dev, 0, 0, 0, 0); /* disable Qav */
-
- rc = mrp_disconnect();
+
+ rc = mrp_disconnect(ctx);
if (rc)
printf("mrp_disconnect failed\n");
-
+ free(ctx);
+ free(class_a);
+ free(class_b);
igb_dma_free_page(&igb_dev, &a_page);
rc = gptpdeinit(&igb_shm_fd, &igb_mmap);
err = igb_detach(&igb_dev);
-
+
pthread_exit(NULL);
-
+
return EXIT_SUCCESS;
}
diff --git a/lib/avtp_pipeline/documents/Doxyfile.in b/lib/avtp_pipeline/documents/Doxyfile.in
index 7cc8b5ba..9df638df 100644
--- a/lib/avtp_pipeline/documents/Doxyfile.in
+++ b/lib/avtp_pipeline/documents/Doxyfile.in
@@ -7,7 +7,7 @@ DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "Open-AVB AVTP Pipeline SDK"
PROJECT_NUMBER = 1.4
PROJECT_BRIEF =
-PROJECT_LOGO = @CMAKE_CURRENT_SOURCE_DIR@/images/stc_logo_small.png
+PROJECT_LOGO = @CMAKE_CURRENT_SOURCE_DIR@/images/harman_logo.png
OUTPUT_DIRECTORY =
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
diff --git a/lib/avtp_pipeline/documents/images/harman_logo.png b/lib/avtp_pipeline/documents/images/harman_logo.png
new file mode 100644
index 00000000..6c4f4105
--- /dev/null
+++ b/lib/avtp_pipeline/documents/images/harman_logo.png
Binary files differ
diff --git a/lib/avtp_pipeline/documents/images/stc_logo_small.png b/lib/avtp_pipeline/documents/images/stc_logo_small.png
deleted file mode 100644
index 7a316664..00000000
--- a/lib/avtp_pipeline/documents/images/stc_logo_small.png
+++ /dev/null
Binary files differ