diff options
author | David Cemin <david.cemin@coveloz.com> | 2015-11-05 09:15:55 -0500 |
---|---|---|
committer | David Cemin <david.cemin@coveloz.com> | 2015-11-05 09:15:55 -0500 |
commit | efb699685e515b4b82d84c4fcd6b2b75a6cbbc37 (patch) | |
tree | 6b0e7584333417f96c5c44304d11136dfd3f8752 | |
parent | fb6f803be77bef42f0cbfe952eac3f7de13882b0 (diff) | |
parent | 01d4ac52885e18bc3f6c37ef5a0e583186b02d17 (diff) | |
download | Open-AVB-efb699685e515b4b82d84c4fcd6b2b75a6cbbc37.tar.gz |
Merge remote-tracking branch 'upstream/open-avb-next' into open-avb-next
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 Binary files differnew file mode 100644 index 00000000..6c4f4105 --- /dev/null +++ b/lib/avtp_pipeline/documents/images/harman_logo.png diff --git a/lib/avtp_pipeline/documents/images/stc_logo_small.png b/lib/avtp_pipeline/documents/images/stc_logo_small.png Binary files differdeleted file mode 100644 index 7a316664..00000000 --- a/lib/avtp_pipeline/documents/images/stc_logo_small.png +++ /dev/null |