diff options
author | Brant Thomsen <brant.thomsen@harman.com> | 2017-04-28 10:19:46 -0600 |
---|---|---|
committer | Brant Thomsen <brant.thomsen@harman.com> | 2017-04-28 10:19:46 -0600 |
commit | 05061026a88554dc4e8e0e608071c85535ef5419 (patch) | |
tree | 02e417a27a54c19a0a5eeb726e645d357445e260 /daemons | |
parent | 65ebc5de71cd6bfc27e4d09007dcede285b44aa2 (diff) | |
parent | 76413ddd9e921445c9e775169fc07babd0b8530d (diff) | |
download | Open-AVB-05061026a88554dc4e8e0e608071c85535ef5419.tar.gz |
Merge branch 'open-avb-next' of https://github.com/AVnu/Open-AVB into maap_ver2
lib/avtp_pipeline changes not included. They will need to be handled later.
Diffstat (limited to 'daemons')
31 files changed, 2880 insertions, 2250 deletions
diff --git a/daemons/gptp/README_SYSTEMD_WATCHDOG.txt b/daemons/gptp/README_SYSTEMD_WATCHDOG.txt new file mode 100644 index 00000000..7cf002b8 --- /dev/null +++ b/daemons/gptp/README_SYSTEMD_WATCHDOG.txt @@ -0,0 +1,28 @@ +## Introduction +This readme covers the **optional** feature to update systemd watchdog during gPTP daemon operation. +System on which the feature will be used must support systemd. + +The solution reads WatchdogSec parameter from service configuration file and notifies watchdog +every 0.5*WatchdogSec that gPTP daemon is alive. +If there is no watchdog configuration available or WatchdogSec == 0, watchdog notification won't run. + +Watchdog configuration is read once during gPTP daemon startup. + + +## Build Related + +Systemd watchdog support in gPTP is a build time option. + +### Systemd headers and library must be present in the system while building gPTP with this feature enabled. + + +### Building gPTP with Systemd watchdog handling enabled. +- SYSTEMD_WATCHDOG=1 make gptp + + +## Running + +### gPTP +- Run as normal. + + diff --git a/daemons/gptp/common/avbts_port.hpp b/daemons/gptp/common/avbts_port.hpp index 739389bd..5752670d 100644 --- a/daemons/gptp/common/avbts_port.hpp +++ b/daemons/gptp/common/avbts_port.hpp @@ -237,6 +237,9 @@ typedef struct { /* Set to true if the port is the grandmaster. Used for fixed GM in the the AVnu automotive profile */ bool testMode; + /* Set to true if the port's network interface is up. Used to filter false LINKUP/LINKDOWN events */ + bool linkUp; + /* gPTP 10.2.4.4 */ char initialLogSyncInterval; @@ -306,6 +309,7 @@ class IEEE1588Port { unsigned sync_count; // 0 for master, ++ for each sync receive as slave // set to 0 when asCapable is false, increment for each pdelay recvd unsigned pdelay_count; + bool linkUp; /* Port Configuration */ unsigned char delay_mechanism; @@ -1519,6 +1523,23 @@ class IEEE1588Port { } /** + * @brief Sets the linkUp status + * @param bool of the linkUp status + * @return void + */ + void setLinkUpState(bool state) { + linkUp = state; + } + + /** + * @brief Gets the linkUp status + * @return bool of the linkUp status + */ + bool getLinkUpState(void) { + return linkUp; + } + + /** * @brief Increment IEEE Port counter: * ieee8021AsPortStatRxSyncCount * @return void diff --git a/daemons/gptp/common/ieee1588port.cpp b/daemons/gptp/common/ieee1588port.cpp index 25e9cda4..441ebbd6 100644 --- a/daemons/gptp/common/ieee1588port.cpp +++ b/daemons/gptp/common/ieee1588port.cpp @@ -96,6 +96,7 @@ IEEE1588Port::IEEE1588Port(IEEE1588PortInit_t *portInit) automotive_profile = portInit->automotive_profile; isGM = portInit->isGM; testMode = portInit->testMode; + linkUp = portInit->linkUp; initialLogSyncInterval = portInit->initialLogSyncInterval; initialLogPdelayReqInterval = portInit->initialLogPdelayReqInterval; operLogPdelayReqInterval = portInit->operLogPdelayReqInterval; diff --git a/daemons/gptp/common/ptp_message.cpp b/daemons/gptp/common/ptp_message.cpp index 77e68437..371987a9 100644 --- a/daemons/gptp/common/ptp_message.cpp +++ b/daemons/gptp/common/ptp_message.cpp @@ -1014,7 +1014,7 @@ void PTPMessageFollowUp::processMessage(IEEE1588Port * port) scalar_offset -= TIMESTAMP_TO_NS( preciseOriginTimestamp ); GPTP_LOG_VERBOSE - ("Followup Correction Field: %Ld,%lu", correctionField >> 16, + ("Followup Correction Field: %Ld, Link Delay: %lu", correctionField, delay); GPTP_LOG_VERBOSE ("FollowUp Scalar = %lld", scalar_offset); diff --git a/daemons/gptp/linux/build/Makefile b/daemons/gptp/linux/build/Makefile index c270847f..4ab409be 100644 --- a/daemons/gptp/linux/build/Makefile +++ b/daemons/gptp/linux/build/Makefile @@ -118,6 +118,13 @@ ifeq ($(GENIVI_DLT),1) LDFLAGS_G += -ldlt -L$(GENIVI_DLT_LIB_PATH) endif +ifeq ($(SYSTEMD_WATCHDOG),1) + CFLAGS_G += -DSYSTEMD_WATCHDOG + LDFLAGS_G += -lsystemd + OBJ_FILES += $(OBJ_DIR)/watchdog.o + HEADER_FILES += $(SRC_DIR)/watchdog.hpp +endif + LDFLAGS_G += -lpthread -lrt CFLAGS = $(CFLAGS_G) @@ -176,6 +183,8 @@ $(OBJ_DIR)/gptp_cfg.o: $(COMMON_DIR)/gptp_cfg.cpp $(HEADER_FILES) $(OBJ_DIR)/ini.o: $(COMMON_DIR)/ini.c $(HEADER_FILES) $(CC) $(CFLAGS) -c $(COMMON_DIR)/ini.c -o $(OBJ_DIR)/ini.o +$(OBJ_DIR)/watchdog.o: $(SRC_DIR)/watchdog.cpp $(HEADER_FILES) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/watchdog.cpp -o $(OBJ_DIR)/watchdog.o clean: $(RM) *~ $(OBJ_DIR)/*.o $(OBJ_DIR)/daemon_cl diff --git a/daemons/gptp/linux/src/daemon_cl.cpp b/daemons/gptp/linux/src/daemon_cl.cpp index 33abcaec..d6a74cee 100644 --- a/daemons/gptp/linux/src/daemon_cl.cpp +++ b/daemons/gptp/linux/src/daemon_cl.cpp @@ -56,6 +56,10 @@ #include <unistd.h> #include <string.h> +#ifdef SYSTEMD_WATCHDOG +#include <watchdog.hpp> +#endif + #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 @@ -94,6 +98,32 @@ void print_usage( char *arg0 ) { ); } +int watchdog_setup(OSThreadFactory *thread_factory) +{ +#ifdef SYSTEMD_WATCHDOG + SystemdWatchdogHandler *watchdog = new SystemdWatchdogHandler(); + OSThread *watchdog_thread = thread_factory->createThread(); + int watchdog_result; + long unsigned int watchdog_interval; + watchdog_interval = watchdog->getSystemdWatchdogInterval(&watchdog_result); + if (watchdog_result) { + GPTP_LOG_INFO("Watchtog interval read from service file: %lu us", watchdog_interval); + watchdog->update_interval = watchdog_interval / 2; + GPTP_LOG_STATUS("Starting watchdog handler (Update every: %lu us)", watchdog->update_interval); + watchdog_thread->start(watchdogUpdateThreadFunction, watchdog); + return 0; + } else if (watchdog_result < 0) { + GPTP_LOG_ERROR("Watchdog settings read error."); + return -1; + } else { + GPTP_LOG_STATUS("Watchdog disabled"); + return 0; + } +#else + return 0; +#endif +} + static IEEE1588Clock *pClock = NULL; static IEEE1588Port *pPort = NULL; @@ -111,7 +141,6 @@ int main(int argc, char **argv) uint8_t priority1 = 248; bool override_portstate = false; PortState port_state = PTP_SLAVE; - char *restoredata = NULL; char *restoredataptr = NULL; off_t restoredatalength = 0; @@ -123,6 +152,7 @@ int main(int argc, char **argv) memset(config_file_path, 0, 512); GPTPPersist *pGPTPPersist = NULL; + LinuxThreadFactory *thread_factory = new LinuxThreadFactory(); // Block SIGUSR1 { @@ -137,7 +167,10 @@ int main(int argc, char **argv) GPTP_LOG_REGISTER(); GPTP_LOG_INFO("gPTP starting"); - + if (watchdog_setup(thread_factory) != 0) { + GPTP_LOG_ERROR("Watchdog handler setup error"); + return -1; + } int phy_delay[4]={0,0,0,0}; bool input_delay=false; @@ -150,6 +183,7 @@ int main(int argc, char **argv) portInit.automotive_profile = false; portInit.isGM = false; portInit.testMode = false; + portInit.linkUp = false; portInit.initialLogSyncInterval = LOG2_INTERVAL_INVALID; portInit.initialLogPdelayReqInterval = LOG2_INTERVAL_INVALID; portInit.operLogPdelayReqInterval = LOG2_INTERVAL_INVALID; @@ -163,7 +197,6 @@ int main(int argc, char **argv) new LinuxNetworkInterfaceFactory; OSNetworkInterfaceFactory::registerFactory (factory_name_t("default"), default_factory); - LinuxThreadFactory *thread_factory = new LinuxThreadFactory(); LinuxTimerQueueFactory *timerq_factory = new LinuxTimerQueueFactory(); LinuxLockFactory *lock_factory = new LinuxLockFactory(); LinuxTimerFactory *timer_factory = new LinuxTimerFactory(); diff --git a/daemons/gptp/linux/src/linux_hal_common.cpp b/daemons/gptp/linux/src/linux_hal_common.cpp index 18142633..55ed47ad 100644 --- a/daemons/gptp/linux/src/linux_hal_common.cpp +++ b/daemons/gptp/linux/src/linux_hal_common.cpp @@ -56,7 +56,6 @@ #include <sys/stat.h> #include <sys/socket.h> -#include <net/if.h> #include <netinet/in.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> @@ -105,7 +104,7 @@ net_result LinuxNetworkInterface::send err = sendto ( sd_general, payload, length, 0, (sockaddr *) remote, sizeof( *remote )); - } + } delete remote; if( err == -1 ) { GPTP_LOG_ERROR( "Failed to send: %s(%d)", strerror(errno), errno ); @@ -205,11 +204,18 @@ static void x_readEvent(int sockint, IEEE1588Port *pPort, int ifindex) if (msgHdr->nlmsg_type == RTM_NEWLINK) { ifi = (struct ifinfomsg *)NLMSG_DATA(msgHdr); if (ifi->ifi_index == ifindex) { - if ((ifi->ifi_flags & IFF_RUNNING)) { - pPort->processEvent(LINKUP); + bool linkUp = ifi->ifi_flags & IFF_RUNNING; + if (linkUp != pPort->getLinkUpState()) { + pPort->setLinkUpState(linkUp); + if (linkUp) { + pPort->processEvent(LINKUP); + } + else { + pPort->processEvent(LINKDOWN); + } } else { - pPort->processEvent(LINKDOWN); + GPTP_LOG_DEBUG("False (repeated) %s event for the interface", linkUp ? "LINKUP" : "LINKDOWN"); } } } @@ -217,11 +223,41 @@ static void x_readEvent(int sockint, IEEE1588Port *pPort, int ifindex) return; } +static void x_initLinkUpStatus(IEEE1588Port *pPort, int ifindex) +{ + struct ifreq device; + memset(&device, 0, sizeof(device)); + device.ifr_ifindex = ifindex; + + int inetSocket = socket (AF_INET, SOCK_STREAM, 0); + if (inetSocket < 0) { + GPTP_LOG_ERROR("initLinkUpStatus error opening socket: %s", strerror(errno)); + return; + } + + int r = ioctl(inetSocket, SIOCGIFNAME, &device); + if (r < 0) { + GPTP_LOG_ERROR("initLinkUpStatus error reading interface name: %s", strerror(errno)); + close(inetSocket); + return; + } + r = ioctl(inetSocket, SIOCGIFFLAGS, &device); + if (r < 0) { + GPTP_LOG_ERROR("initLinkUpStatus error reading flags: %s", strerror(errno)); + close(inetSocket); + return; + } + if (device.ifr_flags && IFF_RUNNING) { + GPTP_LOG_DEBUG("Interface %s is up", device.ifr_name); + pPort->setLinkUpState(true); + } //linkUp == false by default + close(inetSocket); +} + void LinuxNetworkInterface::watchNetLink(IEEE1588Port *pPort) { fd_set netLinkFD; int netLinkSocket; - struct sockaddr_nl addr; netLinkSocket = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); @@ -241,6 +277,8 @@ void LinuxNetworkInterface::watchNetLink(IEEE1588Port *pPort) return; } + x_initLinkUpStatus(pPort, ifindex); + while (1) { FD_ZERO(&netLinkFD); FD_CLR(netLinkSocket, &netLinkFD); @@ -327,7 +365,7 @@ void *LinuxTimerQueueHandler( void *arg ) { void LinuxTimerQueue::LinuxTimerQueueAction( LinuxTimerQueueActionArg *arg ) { arg->func( arg->inner_arg ); - return; + return; } OSTimerQueue *LinuxTimerQueueFactory::createOSTimerQueue @@ -424,10 +462,10 @@ bool LinuxTimerQueue::cancelEvent( int type, unsigned *event ) { void* OSThreadCallback( void* input ) { - OSThreadArg *arg = (OSThreadArg*) input; + OSThreadArg *arg = (OSThreadArg*) input; - arg->ret = arg->func( arg->arg ); - return 0; + arg->ret = arg->func( arg->arg ); + return 0; } bool LinuxTimestamper::post_init( int ifindex, int sd, TicketingLock *lock ) { @@ -437,8 +475,10 @@ bool LinuxTimestamper::post_init( int ifindex, int sd, TicketingLock *lock ) { LinuxTimestamper::~LinuxTimestamper() {} unsigned long LinuxTimer::sleep(unsigned long micros) { - struct timespec req = { 0, (long int)(micros * 1000) }; + struct timespec req; struct timespec rem; + req.tv_sec = micros / 1000000; + req.tv_nsec = micros % 1000000 * 1000; int ret = nanosleep( &req, &rem ); while( ret == -1 && errno == EINTR ) { req = rem; @@ -548,7 +588,7 @@ TicketingLock::~TicketingLock() { } struct LinuxLockPrivate { - pthread_t thread_id; + pthread_t thread_id; pthread_mutexattr_t mta; pthread_mutex_t mutex; pthread_cond_t port_ready_signal; diff --git a/daemons/gptp/linux/src/watchdog.cpp b/daemons/gptp/linux/src/watchdog.cpp new file mode 100644 index 00000000..1406fb55 --- /dev/null +++ b/daemons/gptp/linux/src/watchdog.cpp @@ -0,0 +1,46 @@ +#include "watchdog.hpp" +#include "avbts_osthread.hpp" +#include "gptp_log.hpp" +#include <systemd/sd-daemon.h> + + +OSThreadExitCode watchdogUpdateThreadFunction(void *arg) +{ + SystemdWatchdogHandler *watchdog = (SystemdWatchdogHandler*) arg; + watchdog->run_update(); + return osthread_ok; +} + + +SystemdWatchdogHandler::SystemdWatchdogHandler() +{ + GPTP_LOG_INFO("Creating Systemd watchdog handler."); + LinuxTimerFactory timer_factory = LinuxTimerFactory(); + timer = timer_factory.createTimer(); +} + +SystemdWatchdogHandler::~SystemdWatchdogHandler() +{ + //Do nothing +} + +long unsigned int +SystemdWatchdogHandler::getSystemdWatchdogInterval(int *result) +{ + long unsigned int watchdog_interval; //in microseconds + *result = sd_watchdog_enabled(0, &watchdog_interval); + return watchdog_interval; +} + +void SystemdWatchdogHandler::run_update() +{ + while(1) + { + GPTP_LOG_DEBUG("NOTIFYING WATCHDOG."); + sd_notify(0, "WATCHDOG=1"); + GPTP_LOG_DEBUG("GOING TO SLEEP %lld", update_interval); + timer->sleep(update_interval); + GPTP_LOG_DEBUG("WATCHDOG WAKE UP"); + } +} + diff --git a/daemons/gptp/linux/src/watchdog.hpp b/daemons/gptp/linux/src/watchdog.hpp new file mode 100644 index 00000000..b2e05ccf --- /dev/null +++ b/daemons/gptp/linux/src/watchdog.hpp @@ -0,0 +1,21 @@ +#ifndef SYSTEMDWATCHDOGHANDLER_H +#define SYSTEMDWATCHDOGHANDLER_H +#include <linux_hal_common.hpp> +#include <avbts_ostimer.hpp> + + +OSThreadExitCode watchdogUpdateThreadFunction(void *arg); + +class SystemdWatchdogHandler +{ +public: + long unsigned int update_interval; + long unsigned int getSystemdWatchdogInterval(int *result); + void run_update(); + SystemdWatchdogHandler(); + virtual ~SystemdWatchdogHandler(); +private: + OSTimer *timer; +}; + +#endif // SYSTEMDWATCHDOGHANDLER_H diff --git a/daemons/maap/README.rst b/daemons/maap/README.rst index 4615ffbc..1832705a 100644 --- a/daemons/maap/README.rst +++ b/daemons/maap/README.rst @@ -1,3 +1,20 @@ +OpenAvnu MAAP +============= + +.. contents:: +.. + 1 Introduction + 2 MAAP Server and Client + 2.1 Implementation Details + 2.2 Linux Specific + 2.3 Windows Specific + 2.4 Tests + 2.5 Known Issues and Future Enhancements + 3 API Documentation + 4 Client/Server Protocol + 4.1 Commands + 4.2 Notifications + Introduction ------------ @@ -8,59 +25,373 @@ addresses dynamically. MAAP is designed to provide a way to allocate dynamically the multicast MAC addresses needed by AVTP. MAAP is not designed to allocate locally administered unicast addresses. -A block of Multicast MAC addresses has been reserved for the use of AVTP. These addresses are listed in -MAAP Dynamic Allocation Pool below shown. These addresses are available for dynamic allocation by the MAAP. -91:E0:F0:00:00:00 – 91:E0:F0:00:FD:FF +A block of Multicast MAC addresses has been reserved for the use of AVTP. These +addresses are listed in MAAP Dynamic Allocation Pool below shown. These +addresses are available for dynamic allocation by MAAP: ``91:E0:F0:00:00:00`` – +``91:E0:F0:00:FD:FF``. + +When you initialize the MAAP server, it will use the reserved range by default, +but you can override this if your network administration has set aside a +different range for dynamic allocation to streams. + +MAAP Server and Client +---------------------- +Implementation Details +++++++++++++++++++++++ + +This implementation provides a binary that runs in two modes, *client* and +*server*. A single server instance manages the MAAP protocol for a single +network interface. The server, which must have sufficient access rights, listens +for raw network frames matching the MAAP destination MAC address. It also opens +a local stream socket and listens for client connections. If the server is not +asked to daemonize itself, it will also listen for commands from the console. + +The client opens a socket connection to the server, after which it can send +commands to the server and receive notifications from it. The binary version of +this communication protocol is outlined in the ``maap_iface.h`` file in the +``common`` source directory. Commands and notifications on the console (of +either the server or client binary) operate in the plain text version of the +protocol; the client binary translates these to the binary version before +sending them over the socket to the server. + +**Note:** Socket clients may send plain text commands directly to the server, +but currently the server will only send binary notifications back to socket +clients. If you build a client into your application, you should include +``maap_iface.h`` and use the binary protocol. Linux Specific ++++++++++++++ -To build, execute the linux makefile. +The MAAP programs can be built in several ways. -To execute(in root), go to build directory(where binary is created) and run - maap_daemon [-d] -i interface-name -such as - ./maap_daemon -i eth0 +First, the top-level makefile of the OpenAvnu repository will build them as part +of the ``daemons_all`` and ``maap`` targets. -The daemon creates a 6 bytes shared memory segment with the key 1234 and writes the allocated mac-addr there. -The client applications will have to use this key value 1234 in the applications and read the allocated mac-addr -and use it as dest mac-addr for the packets transmission. +Second, the makefile can be used directly from the build directory:: + $ cd daemons/maap/linux/build + $ make -Execute Command : ------------- +There is also support for building with ``cmake``, both from the top-level +``CMakeLists.txt`` of the OpenAvnu repository and from the ``CMakeLists.txt`` of +the ``maap`` directory. The ``cmake`` build rules include testing targets for +automatically running unit tests. - sudo ./maap_daemon -i eth0 +Command Line Usage:: + maap_daemon [ -c | -i interface_name [-d log_file] ] [-p port_num] -OUTPUT : ------------- +Command Line Options: + + -c Run as a client (sends commands to the daemon) + -i Run as a server monitoring *interface_name* + -d Daemonize the server and log to *log_file* + -p Specify the control port to connect to (client) or + listen to (server). The default *port_num* is ``15364``. + +When running the ``maap_daemon`` binary, you select the client mode with the +``-c`` flag or server mode with ``-i interface_name``. For either case, the ``-p +port_num`` option will allow changing the client/server communication port. The +client and server must have the same port selected to communicate. + +Without the ``-d log_file`` option, the server will stay in the foreground. It +will accept plain text commands from ``stdin`` and write plain text +notifications and log messages to ``stdout``. It will also listen for and accept +socket clients. + +With the ``-d log_file`` option, the server will *daemonize*, i.e. it will +disassociate itself from the process environment in which it was launched and +run in the background. Its ``stdin`` and ``stdout`` will go to ``/dev/null`` and +its ``stderr`` will go to the file named by *log_file*. In this mode, it can +only be controlled via socket clients. + +With the ``-c`` option, the binary runs in *client* mode. It opens a local +socket on *port_num* to the server process and listens on ``stdin`` for plain +text commands. The commands a translated to the binary protocol and sent to the +server. When the server sends notifications, they are translated from binary to +plain text and they are printed to ``stdout``. + +Windows Specific +++++++++++++++++ + +A Windows build of the ``common`` code and unit tests has been implemented, but +platform-specific client and server code still needs to be written. + +The Windows build must be performed with ``cmake``, either from the top-level +``CMakeLists.txt`` of the OpenAvnu repository or from the ``CMakeLists.txt`` of +the ``maap`` directory. The ``cmake`` build rules include testing targets for +automatically running unit tests. + +Tests ++++++ + +The code includes unit tests and an integration test program for testing basic +protocol operation. The unit tests are found in the ``tests`` subdirectory, and +they are integrated into the ``cmake`` builds. Some support code for the unit +tests can be found in the files matching the pattern ``test/maap_*_dummy.*``. + +A stress test for the interval tree library is also built and run by the +``cmake`` test rules; the code for this is in ``test/test_intervals.c``. + +The integration test program is in the ``test/maap_test.c`` file. This will +listen on an interface using the *pcap* library and run a series of scripted +interactions against a MAAP implementation on the other side of the network +interface. This code is currently Linux-only, and is built by the Linux +makefile. + +Known Issues and Future Enhancements +++++++++++++++++++++++++++++++++++++ + +- The server currently only tracks its own reservations. Tracking the + ``ANNOUNCE`` messages of other servers on the network would allow us to rule + out overlapping request ranges without sending ``PROBE`` messages. + +- The server always sends binary protocol notifications to socket clients; + sending plain text notifications when commands are sent in plain text would + allow using ``telnet`` or ``netcat`` for command line clients instead of the + ``-c`` flag to the binary. + +- The Windows platform-specific code is incomplete and nonfunctional. + +API Documentation +----------------- + +The ``doc`` directory contains a ``CMakeLists.txt`` file that, when included, +adds the custom target ``doc`` when the build option ``BUILD_DOCUMENTATION`` is +set. It is not currently included from any higher-level ``CMakeLists.txt``. + +A manual documentation build can be achieved by executing the following command +from the ``doc`` directory:: + + $ doxygen Doxyfile.in + +The resulting html documentation will be in the ``build`` subdirectory. + +Client/Server Protocol +---------------------- + +Clients communicate with the server over a binary protocol based on *commands*, +which are sent from the client to the server; and *notifications*, which are +sent from the server to the client. This section gives an overview of how the +commands and responses work; for code-level detail on constructing or +interpreting them, see the ``common/maap_iface.h`` file. + +The supplied client and server binaries also support a plain text version of the +protocol for testing at the command line; the command *kinds* will be described +below with their plain text names instead of ther *enum* symbols for the sake of +readability and to provide some reference for command line usage. When an +invalid command is given on the plain text console interface, the following +usage statement will be given:: + + init [<range_base> <range_size>] - Initialize the MAAP daemon to recognize + the specified range of addresses. If not specified, it uses + range_base=0x91e0f0000000, range_size=0xfe00. + reserve [<addr_base>] <addr_size> - Reserve a range of addresses of size + <addr_size> in the initialized range. If <addr_base> is specified, + that address base will be attempted first. + release <id> - Release the range of addresses with identifier ID + status <id> - Get the range of addresses associated with identifier ID + exit - Shutdown the MAAP daemon + +Commands +++++++++ + +The commands accepted by the server are identified by the ``kind`` field of the +``Maap_Cmd`` structure, and the fields ``id``, ``start``, and ``count`` contain +command parameters. The exact meaning of the fields depends on the command, but +``start`` typically identifies a base MAC address, ``count`` determines the size +of the range that begins with the address in ``start``, and ``id`` is used to +reference an existing range allocation. + +The following are the command parameter fields: + +``kind`` + This field holds the command kind identifier, which are described below. + +``start`` + This field holds an unsigned 64-bit integer, which should contain a MAC + address converted to a native integer with the first-to-transmit bytes of the + address in the most significant bits of the 48-bit integer and then + zero-extended to 64-bits; e.g. the default MAAP range uses a ``start`` + parameter of ``0x000091E0F0000000ULL`` for the MAC address + ``91:E0:F0:00:00:00``. This way of interpreting an address as an integer + corresponds to the ordering rule that SRP uses to determine contiguous ranges. + +``count`` + This field holds an unsigned 32-bit integer, which represents the number of + addresses in a range. The default MAAP range uses ``0x0000FE00UL`` as the + count, which means that the range extends from ``91:E0:F0:00:00:00`` to + ``91:E0:F0:00:FD:FF``. + +``id`` + This field holds a signed 32-bit integer, but all current commands expect a + positive value. + +In the plain text interface to the protocol, numbers are parsed via the +``strtol`` family with ``base`` parameter ``16`` for ``start`` and ``0`` for the +others. This means that for ``base``, all digits are interpreted as hexadecimal +digits and the ``"0x"`` prefix is optional. For the other parameters, digits are +parsed as decimal digits unless the ``"0"`` prefix for octal or the ``"0x"`` +prefix for hexadecimal are used. + +The following are the current set of command kinds: + +``init`` + This command must be run before any ranges can be reserved. It accepts + ``start`` and ``count`` parameters, but default values will be supplied if the + plain text interface is being used and no parameters are given. When + initialization is complete, a notification will be sent. Initialization only + needs to happen once per start of the server. + +``reserve`` + This command requests the server to reserve a range of multicast MAC addresses + from the range specified by the ``init`` command, which must have been + previously executed. It accepts an optional ``start`` value, which will cause + it to use that address as the initial request base, and a mandatory ``count`` + parameter for the number of contiguous addresses to reserve. If ``start`` is + not supplied, a random one will be chosen. When the server receives a valid + request for reservation, it immediately sends a notification to indicate it is + querying. That notification and all further notifications about the status of + the request will include the reservation ``id``, which can be used in other + commands to identify it. + +``release`` + This command requests that the server release the reservation, or to stop + attempting to acquire it if it has not yet completed the reservation process. + The only parameter is ``id``, which is the identifier given in response to a + ``reserve`` command. A notification will be sent by the server when the + release is completed. + +``status`` + This command asks the server to supply the ``start`` and ``count`` values + associated with a particular reservation. The only parameter is ``id``, which + is the identifier given in response to a ``reserve`` command. A notification + with the requested information will be sent by the server if the ``id`` value + corresponds to an active reservation being managed by the server. + +``exit`` + This command asks the server to shut itself down and exit. It takes no + parameters. Note that this stops the entire server, not just the current + connection to the server. + +Notifications ++++++++++++++ + +Notifications are sent asynchronously by the server to clients to inform them +about relevant changes to the server's state. The ``kind`` field of the +``Maap_Notify`` structure identifies the kind of notification, the ``result`` +field contains a general status code, and the ``id``, ``start``, and ``count`` +fields contain extra notification-specific data. + +The following are the notification fields: + +``kind`` + This field determines the kind of notification; the different kinds are listed + below. + +``id`` + This field contains a signed 32-bit integer; if positive, it represents the + identifer of a reservation range. There are no current uses for negative + values in the protocol. + +``start`` + This field holds an unsigned 64-bit integer, which should contain a MAC + address converted to a native integer with the first-to-transmit bytes of the + address in the most significant bits of the 48-bit integer and then + zero-extended to 64-bits; e.g. the default MAAP range uses a ``start`` + parameter of ``0x000091E0F0000000ULL`` for the MAC address + ``91:E0:F0:00:00:00``. This way of interpreting an address as an integer + corresponds to the ordering rule that SRP uses to determine contiguous ranges. + +``count`` + This field holds an unsigned 32-bit integer, which represents the number of + addresses in a range. The default MAAP range uses ``0x0000FE00UL`` as the + count, which means that the range extends from ``91:E0:F0:00:00:00`` to + ``91:E0:F0:00:FD:FF``. + +``result`` + This field contains a general result code, which may either indicate no error + occurred or specify which kind of error occurred. The different result codes + are listed below after the kinds of notifications. + +The following are the kinds of notifications: + +``initialized`` + This kind of notification is sent in response to receiving an initialization + request from a client. The ``start`` and ``count`` fields will contain the + range which the MAAP server has been initialized to use for reservations. The + ``result`` field will indicate whether the server had been previously + initialized before the latest request or not. + +``acquiring`` + This kind of notification is sent immediately in response to a ``reserve`` + command. If ``result`` does not indicate an error, then ``start`` and + ``count`` will indicate the address range that the server is currently + attempting to reserve. These should *not* be used for streams yet, as a + conflict may yet be detected that could force a different range selection. + Most importantly, the ``id`` field will contain the identifier that must be + used by the client to refer to this reservation in ``release`` or ``status`` + commands. + +``acquired`` + This kind of notification is sent to indicate either successful or + unsuccessful completion of a particular ``reserve`` command that has gone + through the ``acquiring`` phase. If there is no error indicated in ``result``, + then ``start`` and ``count`` contain the reserved address range that can now + be used for streams. The ``id`` field will contain the identifier that must be + used by the client to refer to this reservation in ``release`` or ``status`` + commands. + +``released`` + This kind of notification indicates that the reservation identified in a + ``release`` command has now been released. The ``start`` and ``count`` fields + contain the address range that the reservation previously held; they must no + longer be used for streams. The ``id`` field holds the identifer that was + associated with this reservation; it is no longer valid as an identifier. + +``status`` + This kind of notification describes the reservation identified in a ``status`` + command without changing it. The ``id`` field holds the identifier that was + given to the ``status`` command. The ``start`` and ``count`` fields describe + the range of addresses held by the reservation. + +``yielded`` + This kind of notification is not sent in response to a command, but when the + network protocol forced the server to yield a previously-acquired address + range. The ``id`` field has the same value as when the server sent the + ``acquiring`` and ``acquired`` notifications for the range, and the actual + range values are held in ``start`` and ``count``. Any usage of the addresses + in the yielded range must be immediately stopped. Unless the ``status`` code + indicates an error, the server will attempt to reserve a new range with the + same size. This new range (if successfully acquired) will use the same ``id`` + field value. + +The following are the result codes: -$ sudo ./maap_daemon -i eth0 +``none`` + This value indicates that there were no errors associated with this + notification. -SENT MAAP_PROBE +``requires initialization`` + This value indicates that the server has not yet been initialized. -SENT MAAP_PROBE +``already initialized`` + This value indicates that the server was already initialized when the latest + ``init`` command was received. -SENT MAAP_PROBE +``reserve not available`` + This value indicates that no block of addresses of the requested size was + available. A smaller request may be necessary. -SENT MAAP_ANNOUNCE +``release invalid id`` + This value indicates that a ``release`` command was given with an invalid + ``id`` field. -ANNOUNCED ADDRESS: -0x91 0xe0 0xf0 0 0x95 0x18 +``out of memory`` + This value indicates that the request could not be completed because the + server is out of memory. -STATE change to DEFEND: - -SENT MAAP_ANNOUNCE -SENT MAAP_ANNOUNCE -SENT MAAP_ANNOUNCE +``internal`` + This value indicates that an unspecified internal server error occurred. -Here in the case the allocated address which starts from 0x91 0xe0 0xf0 0 0x95 0x18 -This mac-addr is assigned to Dest-Mac for packets transfer. -ADDR[0] = 0x91 -ADDR[1] = 0xe0 -ADDR[2] = 0xf0 -ADDR[3] = 0 -ADDR[4] = 0x95 -ADDR[5] = 0x18 diff --git a/daemons/maap/common/intervals.c b/daemons/maap/common/intervals.c index b7f847ee..3efd6870 100644 --- a/daemons/maap/common/intervals.c +++ b/daemons/maap/common/intervals.c @@ -27,191 +27,194 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "intervals.h" static int check_overlap(Interval *a, Interval *b) { - return (a->low <= b->high && b->low <= a->high); + return (a->low <= b->high && b->low <= a->high); } Interval *alloc_interval(uint32_t start, uint32_t count) { - Interval *i; - i = calloc(1, sizeof (Interval)); - if (i) { - i->low = start; - i->high = start + count - 1; - } - return i; + Interval *i; + i = calloc(1, sizeof (Interval)); + if (i) { + i->low = start; + i->high = start + count - 1; + } + return i; } void free_interval(Interval *node) { - free(node); + free(node); } int insert_interval(Interval **root, Interval *node) { - Interval *current; - - if (*root == NULL) { - *root = node; - return INTERVAL_SUCCESS; - } - current = *root; - while (1) { - if (check_overlap(current, node)) { - return INTERVAL_OVERLAP; - } - if (node->low < current->low) { - if (current->left_child == NULL) { - current->left_child = node; - node->parent = current; - break; - } else { - current = current->left_child; - } - } else { - if (current->right_child == NULL) { - current->right_child = node; - node->parent = current; - break; - } else { - current = current->right_child; - } - } - } - - return INTERVAL_SUCCESS; + Interval *current; + + if (*root == NULL) { + *root = node; + return INTERVAL_SUCCESS; + } + current = *root; + while (1) { + if (check_overlap(current, node)) { + return INTERVAL_OVERLAP; + } + if (node->low < current->low) { + if (current->left_child == NULL) { + current->left_child = node; + node->parent = current; + break; + } else { + current = current->left_child; + } + } else { + if (current->right_child == NULL) { + current->right_child = node; + node->parent = current; + break; + } else { + current = current->right_child; + } + } + } + + return INTERVAL_SUCCESS; } Interval *remove_interval(Interval **root, Interval *node) { - Interval *snip, *child; - - /* If the node to remove does not have two children, we will snip it, - otherwise we will swap it with its successor and snip that one */ - if (!node->left_child || !node->right_child) { - snip = node; - } else { - snip = next_interval(node); - } - - /* If the node to snip has a child, make its parent link point to the snipped - node's parent */ - if (snip->left_child) { - child = snip->left_child; - } else { - child = snip->right_child; - } - if (child) { - child->parent = snip->parent; - } - - /* If the snipped node has no parent, it is the root node and we use the - provided root pointer to point to the child. Otherwise, we find if the - snipped node was a left or right child and set the appropriate link in the - parent node */ - if (!snip->parent) { - *root = child; - } else if (snip == snip->parent->left_child) { - snip->parent->left_child = child; - } else { - snip->parent->right_child = child; - } - - /* Swap the contents of the node passed in to remove with the one chosen to be - snipped */ - if (snip != node) { - void *old_data = node->data; - node->low = snip->low; - node->high = snip->high; - node->data = snip->data; - snip->data = old_data; - } - - return snip; + Interval *snip, *child; + + /* If the node to remove does not have two children, we will snip it, + otherwise we will swap it with its successor and snip that one */ + if (!node->left_child || !node->right_child) { + snip = node; + } else { + snip = next_interval(node); + } + + /* If the node to snip has a child, make its parent link point to the snipped + node's parent */ + if (snip->left_child) { + child = snip->left_child; + } else { + child = snip->right_child; + } + if (child) { + child->parent = snip->parent; + } + + /* If the snipped node has no parent, it is the root node and we use the + provided root pointer to point to the child. Otherwise, we find if the + snipped node was a left or right child and set the appropriate link in the + parent node */ + if (!snip->parent) { + *root = child; + } else if (snip == snip->parent->left_child) { + snip->parent->left_child = child; + } else { + snip->parent->right_child = child; + } + + /* Swap the contents of the node passed in to remove with the one chosen to be + snipped */ + if (snip != node) { + void *old_data = node->data; + node->low = snip->low; + node->high = snip->high; + node->data = snip->data; + snip->data = old_data; + } + + return snip; } Interval *minimum_interval(Interval *root) { - Interval *current = root; - - while (1) { - if (current && current->left_child) { - current = current->left_child; - } else { - return current; - } - } + Interval *current = root; + + while (1) { + if (current && current->left_child) { + current = current->left_child; + } else { + return current; + } + } } Interval *maximum_interval(Interval *root) { - Interval *current = root; - - while (1) { - if (current && current->right_child) { - current = current->right_child; - } else { - return current; - } - } + Interval *current = root; + + while (1) { + if (current && current->right_child) { + current = current->right_child; + } else { + return current; + } + } } Interval *next_interval(Interval *node) { - Interval *parent, *child; - - if (node->right_child) { - return minimum_interval(node->right_child); - } - - child = node; - parent = node->parent; - while (parent && child == parent->right_child) { - child = parent; - parent = parent->parent; - } - return parent; + Interval *parent, *child; + + if (node->right_child) { + return minimum_interval(node->right_child); + } + + child = node; + parent = node->parent; + while (parent && child == parent->right_child) { + child = parent; + parent = parent->parent; + } + return parent; } Interval *prev_interval(Interval *node) { - Interval *parent, *child; - - if (node->left_child) { - return maximum_interval(node->left_child); - } - - child = node; - parent = node->parent; - while (parent && child == parent->left_child) { - child = parent; - parent = parent->parent; - } - return parent; + Interval *parent, *child; + + if (node->left_child) { + return maximum_interval(node->left_child); + } + + child = node; + parent = node->parent; + while (parent && child == parent->left_child) { + child = parent; + parent = parent->parent; + } + return parent; } Interval *search_interval(Interval *root, uint32_t start, uint32_t count) { - Interval *current, *test; - Interval i; - - i.low = start; - i.high = start + count - 1; - current = root; - - while (current && !check_overlap(current, &i)) { - if (current->low > i.low) { - current = current->left_child; - } else { - current = current->right_child; - } - } - - /* Make sure we really are returning the first (lowest) matching interval. */ - if (current) { - for (test = prev_interval(current); test != NULL && check_overlap(test, &i); test = prev_interval(test)) { - /* We found a lower interval that also matches the search parameters. */ - current = test; - } - } - - return current; + Interval *current, *test; + Interval i; + + i.low = start; + i.high = start + count - 1; + current = root; + + while (current && !check_overlap(current, &i)) { + if (current->low > i.low) { + current = current->left_child; + } else { + current = current->right_child; + } + } + + /* Make sure we really are returning the first (lowest) matching interval. */ + if (current) { + for (test = prev_interval(current); + test != NULL && check_overlap(test, &i); + test = prev_interval(test)) + { + /* We found a lower interval that also matches the search parameters. */ + current = test; + } + } + + return current; } void traverse_interval(Interval *root, Visitor action) { - if (root) { - traverse_interval(root->left_child, action); - action(root); - traverse_interval(root->right_child, action); - } + if (root) { + traverse_interval(root->left_child, action); + action(root); + traverse_interval(root->right_child, action); + } } diff --git a/daemons/maap/common/intervals.h b/daemons/maap/common/intervals.h index c89b3e07..7bedac74 100644 --- a/daemons/maap/common/intervals.h +++ b/daemons/maap/common/intervals.h @@ -72,12 +72,12 @@ typedef void (*Visitor)(Interval *); * Structure for each node of the interval tree */ struct interval_node { - uint32_t low; /**< Low value of this interval */ - uint32_t high; /**< High value of this interval */ - void *data; /**< Pointer to the data associated with this interval */ - Interval *parent; /**< Pointer to the parent of the current tree, or NULL if this is the root node */ - Interval *left_child; /**< Pointer to a subtree with smaller intervals, or NULL if none */ - Interval *right_child; /**< Pointer to a subtree with larger intervals, or NULL if none */ + uint32_t low; /**< Low value of this interval */ + uint32_t high; /**< High value of this interval */ + void *data; /**< Pointer to the data associated with this interval */ + Interval *parent; /**< Pointer to the parent of the current tree, or NULL if this is the root node */ + Interval *left_child; /**< Pointer to a subtree with smaller intervals, or NULL if none */ + Interval *right_child; /**< Pointer to a subtree with larger intervals, or NULL if none */ }; /** @@ -89,8 +89,8 @@ struct interval_node { * * @return TRUE if the interval overlaps the supplied integers, FALSE otherwise */ -#define interval_check_overlap(inter, start, count) \ - (((inter)->low <= (start) + (count) - 1) && ((start) <= (inter)->high)) +#define interval_check_overlap(inter, start, count) \ + (((inter)->low <= (start) + (count) - 1) && ((start) <= (inter)->high)) /** diff --git a/daemons/maap/common/maap.c b/daemons/maap/common/maap.c index 5a25d967..87f78ef0 100644 --- a/daemons/maap/common/maap.c +++ b/daemons/maap/common/maap.c @@ -35,272 +35,272 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <assert.h> #ifdef _WIN32 -/* Windows-specific header values */ + /* Windows-specific header values */ #define random() rand() #define srandom(s) srand(s) #else -/* Linux-specific header files */ + /* Linux-specific header files */ #include <linux/if_ether.h> #endif #define MAAP_LOG_COMPONENT "Main" #include "maap_log.h" -/* Uncomment the DEBUG_TIMER_MSG define to display timer debug messages. */ + /* Uncomment the DEBUG_TIMER_MSG define to display timer debug messages. */ #define DEBUG_TIMER_MSG -/* Uncomment the DEBUG_NEGOTIATE_MSG define to display negotiation debug messages. */ + /* Uncomment the DEBUG_NEGOTIATE_MSG define to display negotiation debug messages. */ #define DEBUG_NEGOTIATE_MSG static int get_count(Maap_Client *mc, Range *range) { - (void)mc; - return range->interval->high - range->interval->low + 1; -} + (void)mc; + return range->interval->high - range->interval->low + 1; + } static unsigned long long int get_start_address(Maap_Client *mc, Range *range) { - return mc->address_base + range->interval->low; + return mc->address_base + range->interval->low; } static unsigned long long int get_end_address(Maap_Client *mc, Range *range) { - return mc->address_base + range->interval->high; + return mc->address_base + range->interval->high; } static int send_packet(Maap_Client *mc, MAAP_Packet *p) { - uint8_t *pbuf = NULL; - int ret = 0; - (void)mc; + uint8_t *pbuf = NULL; + int ret = 0; + (void)mc; - pbuf = Net_getPacketBuffer(mc->net); + pbuf = Net_getPacketBuffer(mc->net); - pack_maap(p, pbuf); + pack_maap(p, pbuf); - ret = Net_queuePacket(mc->net, pbuf); - return ret; + ret = Net_queuePacket(mc->net, pbuf); + return ret; } static int send_probe(Maap_Client *mc, Range *range) { - MAAP_Packet p; + MAAP_Packet p; - init_packet(&p, mc->dest_mac, mc->src_mac); + init_packet(&p, mc->dest_mac, mc->src_mac); - p.message_type = MAAP_PROBE; - p.requested_start_address = get_start_address(mc, range); - p.requested_count = get_count(mc, range); + p.message_type = MAAP_PROBE; + p.requested_start_address = get_start_address(mc, range); + p.requested_count = get_count(mc, range); #ifdef DEBUG_NEGOTIATE_MSG - if (MAAP_LOG_LEVEL_DEBUG <= MAAP_LOG_LEVEL) { - Time t; - Time_setFromMonotonicTimer(&t); - MAAP_LOGF_DEBUG("Sending probe at %s", Time_dump(&t)); - } + if (MAAP_LOG_LEVEL_DEBUG <= MAAP_LOG_LEVEL) { + Time t; + Time_setFromMonotonicTimer(&t); + MAAP_LOGF_DEBUG("Sending probe at %s", Time_dump(&t)); + } #endif - return send_packet(mc, &p); + return send_packet(mc, &p); } static int send_announce(Maap_Client *mc, Range *range) { - MAAP_Packet p; + MAAP_Packet p; - init_packet(&p, mc->dest_mac, mc->src_mac); + init_packet(&p, mc->dest_mac, mc->src_mac); - p.message_type = MAAP_ANNOUNCE; - p.requested_start_address = get_start_address(mc, range); - p.requested_count = get_count(mc, range); + p.message_type = MAAP_ANNOUNCE; + p.requested_start_address = get_start_address(mc, range); + p.requested_count = get_count(mc, range); #ifdef DEBUG_NEGOTIATE_MSG - if (MAAP_LOG_LEVEL_DEBUG <= MAAP_LOG_LEVEL) { - Time t; - Time_setFromMonotonicTimer(&t); - MAAP_LOGF_DEBUG("Sending announce at %s", Time_dump(&t)); - } + if (MAAP_LOG_LEVEL_DEBUG <= MAAP_LOG_LEVEL) { + Time t; + Time_setFromMonotonicTimer(&t); + MAAP_LOGF_DEBUG("Sending announce at %s", Time_dump(&t)); + } #endif - return send_packet(mc, &p); + return send_packet(mc, &p); } static int send_defend(Maap_Client *mc, Range *range, uint64_t start, - uint16_t count, uint64_t destination) { - MAAP_Packet p; - uint64_t conflict_start, conflict_end; - - init_packet(&p, mc->dest_mac, mc->src_mac); - - /* Determine the range of addresses where the conflict occurred - * (the union of the requested and allocated ranges). */ - conflict_start = get_start_address(mc, range); - if (conflict_start < start) { conflict_start = start; } - conflict_end = get_end_address(mc, range); - if (conflict_end > start + count - 1) { conflict_end = start + count - 1; } - - p.DA = destination; - p.message_type = MAAP_DEFEND; - p.requested_start_address = start; - p.requested_count = count; - p.conflict_start_address = conflict_start; - p.conflict_count = (uint16_t)(conflict_end - conflict_start + 1); + uint16_t count, uint64_t destination) { + MAAP_Packet p; + uint64_t conflict_start, conflict_end; + + init_packet(&p, mc->dest_mac, mc->src_mac); + + /* Determine the range of addresses where the conflict occurred + * (the union of the requested and allocated ranges). */ + conflict_start = get_start_address(mc, range); + if (conflict_start < start) { conflict_start = start; } + conflict_end = get_end_address(mc, range); + if (conflict_end > start + count - 1) { conflict_end = start + count - 1; } + + p.DA = destination; + p.message_type = MAAP_DEFEND; + p.requested_start_address = start; + p.requested_count = count; + p.conflict_start_address = conflict_start; + p.conflict_count = (uint16_t)(conflict_end - conflict_start + 1); #ifdef DEBUG_NEGOTIATE_MSG - if (MAAP_LOG_LEVEL_DEBUG <= MAAP_LOG_LEVEL) { - Time t; - Time_setFromMonotonicTimer(&t); - MAAP_LOGF_DEBUG("Sending defend at %s", Time_dump(&t)); - } + if (MAAP_LOG_LEVEL_DEBUG <= MAAP_LOG_LEVEL) { + Time t; + Time_setFromMonotonicTimer(&t); + MAAP_LOGF_DEBUG("Sending defend at %s", Time_dump(&t)); + } #endif - return send_packet(mc, &p); + return send_packet(mc, &p); } static int inform_initialized(Maap_Client *mc, const void *sender, Maap_Notify_Error result) { - Maap_Notify note; + Maap_Notify note; - note.kind = MAAP_NOTIFY_INITIALIZED; - note.id = -1; /* Not used */ - note.start = mc->address_base; - note.count = mc->range_len; - note.result = result; + note.kind = MAAP_NOTIFY_INITIALIZED; + note.id = -1; /* Not used */ + note.start = mc->address_base; + note.count = mc->range_len; + note.result = result; - add_notify(mc, sender, ¬e); - return 0; + add_notify(mc, sender, ¬e); + return 0; } static int inform_acquiring(Maap_Client *mc, Range *range) { - Maap_Notify note; + Maap_Notify note; - note.kind = MAAP_NOTIFY_ACQUIRING; - note.id = range->id; - note.start = get_start_address(mc, range); - note.count = get_count(mc, range); - note.result = MAAP_NOTIFY_ERROR_NONE; + note.kind = MAAP_NOTIFY_ACQUIRING; + note.id = range->id; + note.start = get_start_address(mc, range); + note.count = get_count(mc, range); + note.result = MAAP_NOTIFY_ERROR_NONE; - add_notify(mc, range->sender, ¬e); - return 0; + add_notify(mc, range->sender, ¬e); + return 0; } static int inform_acquired(Maap_Client *mc, Range *range, Maap_Notify_Error result) { - Maap_Notify note; + Maap_Notify note; - note.kind = MAAP_NOTIFY_ACQUIRED; - note.id = range->id; - note.start = get_start_address(mc, range); - note.count = get_count(mc, range); - note.result = result; + note.kind = MAAP_NOTIFY_ACQUIRED; + note.id = range->id; + note.start = get_start_address(mc, range); + note.count = get_count(mc, range); + note.result = result; - add_notify(mc, range->sender, ¬e); - return 0; + add_notify(mc, range->sender, ¬e); + return 0; } static int inform_not_acquired(Maap_Client *mc, const void *sender, int id, int range_size, Maap_Notify_Error result) { - Maap_Notify note; + Maap_Notify note; - note.kind = MAAP_NOTIFY_ACQUIRED; - note.id = id; - note.start = 0; - note.count = range_size; - note.result = result; + note.kind = MAAP_NOTIFY_ACQUIRED; + note.id = id; + note.start = 0; + note.count = range_size; + note.result = result; - add_notify(mc, sender, ¬e); - return 0; + add_notify(mc, sender, ¬e); + return 0; } static int inform_released(Maap_Client *mc, const void *sender, int id, Range *range, Maap_Notify_Error result) { - Maap_Notify note; + Maap_Notify note; - note.kind = MAAP_NOTIFY_RELEASED; - note.id = id; - note.start = (range ? get_start_address(mc, range) : 0); - note.count = (range ? get_count(mc, range) : 0); - note.result = result; + note.kind = MAAP_NOTIFY_RELEASED; + note.id = id; + note.start = (range ? get_start_address(mc, range) : 0); + note.count = (range ? get_count(mc, range) : 0); + note.result = result; - add_notify(mc, sender, ¬e); - return 0; + add_notify(mc, sender, ¬e); + return 0; } static int inform_status(Maap_Client *mc, const void *sender, int id, Range *range, Maap_Notify_Error result) { - Maap_Notify note; + Maap_Notify note; - note.kind = MAAP_NOTIFY_STATUS; - note.id = id; - note.start = (range ? get_start_address(mc, range) : 0); - note.count = (range ? get_count(mc, range) : 0); - note.result = result; + note.kind = MAAP_NOTIFY_STATUS; + note.id = id; + note.start = (range ? get_start_address(mc, range) : 0); + note.count = (range ? get_count(mc, range) : 0); + note.result = result; - add_notify(mc, sender, ¬e); - return 0; + add_notify(mc, sender, ¬e); + return 0; } static int inform_yielded(Maap_Client *mc, Range *range, int result) { - Maap_Notify note; + Maap_Notify note; - note.kind = MAAP_NOTIFY_YIELDED; - note.id = range->id; - note.start = get_start_address(mc, range); - note.count = get_count(mc, range); - note.result = result; + note.kind = MAAP_NOTIFY_YIELDED; + note.id = range->id; + note.start = get_start_address(mc, range); + note.count = get_count(mc, range); + note.result = result; - add_notify(mc, range->sender, ¬e); - return 0; + add_notify(mc, range->sender, ¬e); + return 0; } static void start_timer(Maap_Client *mc) { - if (mc->timer_queue) { - Time_setTimer(mc->timer, &mc->timer_queue->next_act_time); - } + if (mc->timer_queue) { + Time_setTimer(mc->timer, &mc->timer_queue->next_act_time); + } } static void remove_range_interval(Interval **root, Interval *node) { - Range *old_range = node->data; - Interval *free_inter, *test_inter; - - /* Remove and free the interval from the set of intervals. - * Note that the interval freed may not be the same one supplied. */ - assert(!old_range || old_range->interval == node); - free_inter = remove_interval(root, node); - assert(free_inter->data == old_range); - free_interval(free_inter); - - /* Make sure the remaining ranges point to the intervals that hold them. - * This is necessary as the Range object may have moved to a different node. */ - for (test_inter = minimum_interval(*root); test_inter != NULL; test_inter = next_interval(test_inter)) { - Range *range = test_inter->data; - assert(range); - assert(range != old_range); - if (range->interval != test_inter) { - range->interval = test_inter; - } - } + Range *old_range = node->data; + Interval *free_inter, *test_inter; + + /* Remove and free the interval from the set of intervals. + * Note that the interval freed may not be the same one supplied. */ + assert(!old_range || old_range->interval == node); + free_inter = remove_interval(root, node); + assert(free_inter->data == old_range); + free_interval(free_inter); + + /* Make sure the remaining ranges point to the intervals that hold them. + * This is necessary as the Range object may have moved to a different node. */ + for (test_inter = minimum_interval(*root); test_inter != NULL; test_inter = next_interval(test_inter)) { + Range *range = test_inter->data; + assert(range); + assert(range != old_range); + if (range->interval != test_inter) { + range->interval = test_inter; + } + } } void add_notify(Maap_Client *mc, const void *sender, const Maap_Notify *mn) { - Maap_Notify_List *tmp, *li = calloc(1, sizeof (Maap_Notify_List)); - memcpy(&li->notify, mn, sizeof (Maap_Notify)); - li->sender = sender; - - if (mc->notifies == NULL) { - mc->notifies = li; - } else { - tmp = mc->notifies; - while (tmp->next) { - tmp = tmp->next; - } - tmp->next = li; - } + Maap_Notify_List *tmp, *li = calloc(1, sizeof (Maap_Notify_List)); + memcpy(&li->notify, mn, sizeof (Maap_Notify)); + li->sender = sender; + + if (mc->notifies == NULL) { + mc->notifies = li; + } else { + tmp = mc->notifies; + while (tmp->next) { + tmp = tmp->next; + } + tmp->next = li; + } } int get_notify(Maap_Client *mc, const void **sender, Maap_Notify *mn) { - Maap_Notify_List *tmp; - - if (mc->notifies) { - tmp = mc->notifies; - if (mn) { memcpy(mn, &(tmp->notify), sizeof (Maap_Notify)); } - if (sender) { *sender = tmp->sender; } - mc->notifies = tmp->next; - free(tmp); - return 1; - } - return 0; + Maap_Notify_List *tmp; + + if (mc->notifies) { + tmp = mc->notifies; + if (mn) { memcpy(mn, &(tmp->notify), sizeof (Maap_Notify)); } + if (sender) { *sender = tmp->sender; } + mc->notifies = tmp->next; + free(tmp); + return 1; + } + return 0; } static void log_print_notify_result(Maap_Output_Type outputType, int logLevel, const char *szOutput) @@ -375,725 +375,727 @@ static void log_print_notify_result(Maap_Output_Type outputType, int logLevel, c void print_notify(Maap_Notify *mn, Maap_Output_Type outputType) { - char szOutput[300]; - - assert(mn); - - switch (mn->result) - { - case MAAP_NOTIFY_ERROR_NONE: - /* No error. Don't display anything. */ - break; - case MAAP_NOTIFY_ERROR_REQUIRES_INITIALIZATION: - log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, - "MAAP is not initialized, so the command cannot be performed."); - break; - case MAAP_NOTIFY_ERROR_ALREADY_INITIALIZED: - log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, - "MAAP is already initialized, so the values cannot be changed."); - break; - case MAAP_NOTIFY_ERROR_RESERVE_NOT_AVAILABLE: - log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, - "The MAAP reservation is not available, or yield cannot allocate a replacement block. Try again with a smaller address block size."); - break; - case MAAP_NOTIFY_ERROR_RELEASE_INVALID_ID: - log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, - "The MAAP reservation ID is not valid, so cannot be released or report its status."); - break; - case MAAP_NOTIFY_ERROR_OUT_OF_MEMORY: - log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, - "The MAAP application is out of memory."); - break; - case MAAP_NOTIFY_ERROR_INTERNAL: - log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, - "The MAAP application experienced an internal error."); - break; - default: - sprintf(szOutput, "The MAAP application returned an unknown error %d.", mn->result); - log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, szOutput); - break; - } - - switch (mn->kind) - { - case MAAP_NOTIFY_INITIALIZED: - if (mn->result == MAAP_NOTIFY_ERROR_NONE) { - sprintf(szOutput, "MAAP initialized: 0x%012llx-0x%012llx (Size: %d)", - (unsigned long long) mn->start, - (unsigned long long) mn->start + mn->count - 1, - (unsigned int) mn->count); - log_print_notify_result(outputType, MAAP_LOG_LEVEL_INFO, szOutput); - } else { - sprintf(szOutput, "MAAP previously initialized to 0x%012llx-0x%012llx (Size: %d)", - (unsigned long long) mn->start, - (unsigned long long) mn->start + mn->count - 1, - (unsigned int) mn->count); - log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, szOutput); - } - break; - case MAAP_NOTIFY_ACQUIRING: - if (mn->result == MAAP_NOTIFY_ERROR_NONE) { - sprintf(szOutput, "Address range %d querying: 0x%012llx-0x%012llx (Size %d)", - mn->id, - (unsigned long long) mn->start, - (unsigned long long) mn->start + mn->count - 1, - mn->count); - log_print_notify_result(outputType, MAAP_LOG_LEVEL_INFO, szOutput); - } else { - sprintf(szOutput, "Unknown address range %d acquisition error", mn->id); - log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, szOutput); - } - break; - case MAAP_NOTIFY_ACQUIRED: - if (mn->result == MAAP_NOTIFY_ERROR_NONE) { - sprintf(szOutput, "Address range %d acquired: 0x%012llx-0x%012llx (Size %d)", - mn->id, - (unsigned long long) mn->start, - (unsigned long long) mn->start + mn->count - 1, - mn->count); - log_print_notify_result(outputType, MAAP_LOG_LEVEL_INFO, szOutput); - } else if (mn->id != -1) { - sprintf(szOutput, "Address range %d of size %d not acquired", - mn->id, mn->count); - log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, szOutput); - } else { - sprintf(szOutput, "Address range of size %d not acquired", - mn->count); - log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, szOutput); - } - break; - case MAAP_NOTIFY_RELEASED: - if (mn->result == MAAP_NOTIFY_ERROR_NONE) { - sprintf(szOutput, "Address range %d released: 0x%012llx-0x%012llx (Size %d)", - mn->id, - (unsigned long long) mn->start, - (unsigned long long) mn->start + mn->count - 1, - mn->count); - log_print_notify_result(outputType, MAAP_LOG_LEVEL_INFO, szOutput); - } else { - sprintf(szOutput, "Address range %d not released", - mn->id); - log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, szOutput); - } - break; - case MAAP_NOTIFY_STATUS: - if (mn->result == MAAP_NOTIFY_ERROR_NONE) { - sprintf(szOutput, "ID %d is address range 0x%012llx-0x%012llx (Size %d)", - mn->id, - (unsigned long long) mn->start, - (unsigned long long) mn->start + mn->count - 1, - mn->count); - log_print_notify_result(outputType, MAAP_LOG_LEVEL_INFO, szOutput); - } else { - sprintf(szOutput, "ID %d is not valid", - mn->id); - log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, szOutput); - } - break; - case MAAP_NOTIFY_YIELDED: - sprintf(szOutput, "Address range %d yielded: 0x%012llx-0x%012llx (Size %d)", - mn->id, - (unsigned long long) mn->start, - (unsigned long long) mn->start + mn->count - 1, - mn->count); - log_print_notify_result(outputType, MAAP_LOG_LEVEL_WARNING, szOutput); - if (mn->result != MAAP_NOTIFY_ERROR_NONE) { - log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, - "A new address range will not be allocated"); - } - break; - default: - sprintf(szOutput, "Notification type %d not recognized", mn->kind); - log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, szOutput); - break; - } + char szOutput[300]; + + assert(mn); + + switch (mn->result) + { + case MAAP_NOTIFY_ERROR_NONE: + /* No error. Don't display anything. */ + break; + case MAAP_NOTIFY_ERROR_REQUIRES_INITIALIZATION: + log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, + "MAAP is not initialized, so the command cannot be performed."); + break; + case MAAP_NOTIFY_ERROR_ALREADY_INITIALIZED: + log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, + "MAAP is already initialized, so the values cannot be changed."); + break; + case MAAP_NOTIFY_ERROR_RESERVE_NOT_AVAILABLE: + log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, + "The MAAP reservation is not available, or yield cannot allocate a replacement block. " + "Try again with a smaller address block size."); + break; + case MAAP_NOTIFY_ERROR_RELEASE_INVALID_ID: + log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, + "The MAAP reservation ID is not valid, so cannot be released or report its status."); + break; + case MAAP_NOTIFY_ERROR_OUT_OF_MEMORY: + log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, + "The MAAP application is out of memory."); + break; + case MAAP_NOTIFY_ERROR_INTERNAL: + log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, + "The MAAP application experienced an internal error."); + break; + default: + sprintf(szOutput, "The MAAP application returned an unknown error %d.", mn->result); + log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, szOutput); + break; + } + + switch (mn->kind) + { + case MAAP_NOTIFY_INITIALIZED: + if (mn->result == MAAP_NOTIFY_ERROR_NONE) { + sprintf(szOutput, "MAAP initialized: 0x%012llx-0x%012llx (Size: %d)", + (unsigned long long) mn->start, + (unsigned long long) mn->start + mn->count - 1, + (unsigned int) mn->count); + log_print_notify_result(outputType, MAAP_LOG_LEVEL_INFO, szOutput); + } else { + sprintf(szOutput, "MAAP previously initialized to 0x%012llx-0x%012llx (Size: %d)", + (unsigned long long) mn->start, + (unsigned long long) mn->start + mn->count - 1, + (unsigned int) mn->count); + log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, szOutput); + } + break; + case MAAP_NOTIFY_ACQUIRING: + if (mn->result == MAAP_NOTIFY_ERROR_NONE) { + sprintf(szOutput, "Address range %d querying: 0x%012llx-0x%012llx (Size %d)", + mn->id, + (unsigned long long) mn->start, + (unsigned long long) mn->start + mn->count - 1, + mn->count); + log_print_notify_result(outputType, MAAP_LOG_LEVEL_INFO, szOutput); + } else { + sprintf(szOutput, "Unknown address range %d acquisition error", mn->id); + log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, szOutput); + } + break; + case MAAP_NOTIFY_ACQUIRED: + if (mn->result == MAAP_NOTIFY_ERROR_NONE) { + sprintf(szOutput, "Address range %d acquired: 0x%012llx-0x%012llx (Size %d)", + mn->id, + (unsigned long long) mn->start, + (unsigned long long) mn->start + mn->count - 1, + mn->count); + log_print_notify_result(outputType, MAAP_LOG_LEVEL_INFO, szOutput); + } else if (mn->id != -1) { + sprintf(szOutput, "Address range %d of size %d not acquired", + mn->id, mn->count); + log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, szOutput); + } else { + sprintf(szOutput, "Address range of size %d not acquired", + mn->count); + log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, szOutput); + } + break; + case MAAP_NOTIFY_RELEASED: + if (mn->result == MAAP_NOTIFY_ERROR_NONE) { + sprintf(szOutput, "Address range %d released: 0x%012llx-0x%012llx (Size %d)", + mn->id, + (unsigned long long) mn->start, + (unsigned long long) mn->start + mn->count - 1, + mn->count); + log_print_notify_result(outputType, MAAP_LOG_LEVEL_INFO, szOutput); + } else { + sprintf(szOutput, "Address range %d not released", + mn->id); + log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, szOutput); + } + break; + case MAAP_NOTIFY_STATUS: + if (mn->result == MAAP_NOTIFY_ERROR_NONE) { + sprintf(szOutput, "ID %d is address range 0x%012llx-0x%012llx (Size %d)", + mn->id, + (unsigned long long) mn->start, + (unsigned long long) mn->start + mn->count - 1, + mn->count); + log_print_notify_result(outputType, MAAP_LOG_LEVEL_INFO, szOutput); + } else { + sprintf(szOutput, "ID %d is not valid", + mn->id); + log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, szOutput); + } + break; + case MAAP_NOTIFY_YIELDED: + sprintf(szOutput, "Address range %d yielded: 0x%012llx-0x%012llx (Size %d)", + mn->id, + (unsigned long long) mn->start, + (unsigned long long) mn->start + mn->count - 1, + mn->count); + log_print_notify_result(outputType, MAAP_LOG_LEVEL_WARNING, szOutput); + if (mn->result != MAAP_NOTIFY_ERROR_NONE) { + log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, + "A new address range will not be allocated"); + } + break; + default: + sprintf(szOutput, "Notification type %d not recognized", mn->kind); + log_print_notify_result(outputType, MAAP_LOG_LEVEL_ERROR, szOutput); + break; + } } int maap_init_client(Maap_Client *mc, const void *sender, uint64_t range_address_base, uint32_t range_len) { - if (mc->initialized) { - /* If the desired values are the same as the initialized values, pretend the command succeeded. - * Otherwise, let the sender know the range that was already specified and cannot change. */ - int matches = (range_address_base == mc->address_base && range_len == mc->range_len); - inform_initialized(mc, sender, (matches ? MAAP_NOTIFY_ERROR_NONE : MAAP_NOTIFY_ERROR_ALREADY_INITIALIZED)); - - return (matches ? 0 : -1); - } - - mc->timer = Time_newTimer(); - if (!mc->timer) { - MAAP_LOG_ERROR("Failed to create Timer"); - return -1; - } - - mc->net = Net_newNet(); - if (!mc->net) { - MAAP_LOG_ERROR("Failed to create Net"); - Time_delTimer(mc->timer); - return -1; - } - - mc->address_base = range_address_base; - mc->range_len = range_len; - mc->ranges = NULL; - mc->timer_queue = NULL; - mc->maxid = 0; - mc->notifies = NULL; - - mc->initialized = 1; - - /* Let the sender know the range is now specified. */ - inform_initialized(mc, sender, MAAP_NOTIFY_ERROR_NONE); - - return 0; + if (mc->initialized) { + /* If the desired values are the same as the initialized values, pretend the command succeeded. + * Otherwise, let the sender know the range that was already specified and cannot change. */ + int matches = (range_address_base == mc->address_base && range_len == mc->range_len); + inform_initialized(mc, sender, (matches ? MAAP_NOTIFY_ERROR_NONE : MAAP_NOTIFY_ERROR_ALREADY_INITIALIZED)); + + return (matches ? 0 : -1); + } + + mc->timer = Time_newTimer(); + if (!mc->timer) { + MAAP_LOG_ERROR("Failed to create Timer"); + return -1; + } + + mc->net = Net_newNet(); + if (!mc->net) { + MAAP_LOG_ERROR("Failed to create Net"); + Time_delTimer(mc->timer); + return -1; + } + + mc->address_base = range_address_base; + mc->range_len = range_len; + mc->ranges = NULL; + mc->timer_queue = NULL; + mc->maxid = 0; + mc->notifies = NULL; + + mc->initialized = 1; + + /* Let the sender know the range is now specified. */ + inform_initialized(mc, sender, MAAP_NOTIFY_ERROR_NONE); + + return 0; } void maap_deinit_client(Maap_Client *mc) { - if (mc->initialized) { - while (mc->timer_queue) { - Range * pDel = mc->timer_queue; - mc->timer_queue = mc->timer_queue->next_timer; - if (pDel->state == MAAP_STATE_RELEASED) { free(pDel); } - } - - while (mc->ranges) { - Range *range = mc->ranges->data; - remove_range_interval(&mc->ranges, mc->ranges); - if (range) { free(range); } - } - - if (mc->timer) { - Time_delTimer(mc->timer); - mc->timer = NULL; - } - - if (mc->net) { - Net_delNet(mc->net); - mc->net = NULL; - } - - while (get_notify(mc, NULL, NULL)) { /* Do nothing with the result */ } - - mc->initialized = 0; - } + if (mc->initialized) { + while (mc->timer_queue) { + Range * pDel = mc->timer_queue; + mc->timer_queue = mc->timer_queue->next_timer; + if (pDel->state == MAAP_STATE_RELEASED) { free(pDel); } + } + + while (mc->ranges) { + Range *range = mc->ranges->data; + remove_range_interval(&mc->ranges, mc->ranges); + if (range) { free(range); } + } + + if (mc->timer) { + Time_delTimer(mc->timer); + mc->timer = NULL; + } + + if (mc->net) { + Net_delNet(mc->net); + mc->net = NULL; + } + + while (get_notify(mc, NULL, NULL)) { /* Do nothing with the result */ } + + mc->initialized = 0; + } } int rand_ms(int variation) { - /* Return a value between 1 and variation-1, inclusive. - * This is to adhere to IEEE 1722-2016 B.3.4.1 and B.3.4.2. */ - return random() % (variation - 1) + 1; + /* Return a value between 1 and variation-1, inclusive. + * This is to adhere to IEEE 1722-2016 B.3.4.1 and B.3.4.2. */ + return random() % (variation - 1) + 1; } int schedule_timer(Maap_Client *mc, Range *range) { - Range *rp, *prev_rp; - unsigned long long int ns; - Time ts; + Range *rp, *prev_rp; + unsigned long long int ns; + Time ts; - assert(mc); - assert(range); + assert(mc); + assert(range); #ifdef DEBUG_TIMER_MSG - if (MAAP_LOG_LEVEL_DEBUG <= MAAP_LOG_LEVEL) { - Time_setFromMonotonicTimer(&ts); - MAAP_LOGF_DEBUG("schedule_timer called at: %s", Time_dump(&ts)); - } + if (MAAP_LOG_LEVEL_DEBUG <= MAAP_LOG_LEVEL) { + Time_setFromMonotonicTimer(&ts); + MAAP_LOGF_DEBUG("schedule_timer called at: %s", Time_dump(&ts)); + } #endif - if (range->state == MAAP_STATE_PROBING) { - ns = MAAP_PROBE_INTERVAL_BASE + rand_ms(MAAP_PROBE_INTERVAL_VARIATION); - ns = ns * 1000000; + if (range->state == MAAP_STATE_PROBING) { + ns = MAAP_PROBE_INTERVAL_BASE + rand_ms(MAAP_PROBE_INTERVAL_VARIATION); + ns = ns * 1000000; #ifdef DEBUG_TIMER_MSG - MAAP_LOGF_DEBUG("Scheduling probe timer for %llu ns from now", ns); + MAAP_LOGF_DEBUG("Scheduling probe timer for %llu ns from now", ns); #endif - Time_setFromNanos(&ts, ns); - Time_setFromMonotonicTimer(&range->next_act_time); - Time_add(&range->next_act_time, &ts); + Time_setFromNanos(&ts, ns); + Time_setFromMonotonicTimer(&range->next_act_time); + Time_add(&range->next_act_time, &ts); #ifdef DEBUG_TIMER_MSG - MAAP_LOGF_DEBUG("Expiration time is: %s", Time_dump(&range->next_act_time)); + MAAP_LOGF_DEBUG("Expiration time is: %s", Time_dump(&range->next_act_time)); #endif - } else if (range->state == MAAP_STATE_DEFENDING) { - ns = MAAP_ANNOUNCE_INTERVAL_BASE + rand_ms(MAAP_ANNOUNCE_INTERVAL_VARIATION); - ns = ns * 1000000; + } else if (range->state == MAAP_STATE_DEFENDING) { + ns = MAAP_ANNOUNCE_INTERVAL_BASE + rand_ms(MAAP_ANNOUNCE_INTERVAL_VARIATION); + ns = ns * 1000000; #ifdef DEBUG_TIMER_MSG - MAAP_LOGF_DEBUG("Scheduling defend timer for %llu ns from now", ns); + MAAP_LOGF_DEBUG("Scheduling defend timer for %llu ns from now", ns); #endif - Time_setFromNanos(&ts, (uint64_t)ns); - Time_setFromMonotonicTimer(&range->next_act_time); - Time_add(&range->next_act_time, &ts); + Time_setFromNanos(&ts, (uint64_t)ns); + Time_setFromMonotonicTimer(&range->next_act_time); + Time_add(&range->next_act_time, &ts); #ifdef DEBUG_TIMER_MSG - MAAP_LOGF_DEBUG("Expiration time is: %s", Time_dump(&range->next_act_time)); + MAAP_LOGF_DEBUG("Expiration time is: %s", Time_dump(&range->next_act_time)); #endif - } - - /* Remove the range from the timer queue, if it is already in it. */ - if (mc->timer_queue == range) { - /* Range was at the front of the queue. */ - mc->timer_queue = range->next_timer; - } else if (mc->timer_queue) { - /* Search the rest of the queue. */ - prev_rp = mc->timer_queue; - rp = prev_rp->next_timer; - while (rp && rp != range) { - prev_rp = rp; - rp = rp->next_timer; - } - if (rp) { - /* Range was found. Remove it. */ - prev_rp->next_timer = rp->next_timer; - rp->next_timer = NULL; - } - } - - /* Add the range to the timer queue. */ - if (mc->timer_queue == NULL || - Time_cmp(&range->next_act_time, &mc->timer_queue->next_act_time) < 0) { - range->next_timer = mc->timer_queue; - mc->timer_queue = range; - } else { - rp = mc->timer_queue; - while (rp->next_timer && - Time_cmp(&rp->next_timer->next_act_time, &range->next_act_time) <= 0) { - rp = rp->next_timer; - } - range->next_timer = rp->next_timer; - rp->next_timer = range; - } + } + + /* Remove the range from the timer queue, if it is already in it. */ + if (mc->timer_queue == range) { + /* Range was at the front of the queue. */ + mc->timer_queue = range->next_timer; + } else if (mc->timer_queue) { + /* Search the rest of the queue. */ + prev_rp = mc->timer_queue; + rp = prev_rp->next_timer; + while (rp && rp != range) { + prev_rp = rp; + rp = rp->next_timer; + } + if (rp) { + /* Range was found. Remove it. */ + prev_rp->next_timer = rp->next_timer; + rp->next_timer = NULL; + } + } + + /* Add the range to the timer queue. */ + if (mc->timer_queue == NULL || + Time_cmp(&range->next_act_time, &mc->timer_queue->next_act_time) < 0) { + range->next_timer = mc->timer_queue; + mc->timer_queue = range; + } else { + rp = mc->timer_queue; + while (rp->next_timer && + Time_cmp(&rp->next_timer->next_act_time, &range->next_act_time) <= 0) + { + rp = rp->next_timer; + } + range->next_timer = rp->next_timer; + rp->next_timer = range; + } #ifdef DEBUG_TIMER_MSG - /* Perform a sanity test on the timer queue. */ - { - Range *test = mc->timer_queue; - int i; - for (i = 0; test && i < 100000; ++i) { - assert(test->next_timer != test); - assert(test->next_timer == NULL || Time_cmp(&test->next_act_time, &test->next_timer->next_act_time) <= 0); - test = test->next_timer; - } - if (test) { - MAAP_LOG_ERROR("Timer infinite loop detected!"); - assert(0); - } - } + /* Perform a sanity test on the timer queue. */ + { + Range *test = mc->timer_queue; + int i; + for (i = 0; test && i < 100000; ++i) { + assert(test->next_timer != test); + assert(test->next_timer == NULL || Time_cmp(&test->next_act_time, &test->next_timer->next_act_time) <= 0); + test = test->next_timer; + } + if (test) { + MAAP_LOG_ERROR("Timer infinite loop detected!"); + assert(0); + } + } #endif - return 0; + return 0; } static int assign_interval(Maap_Client *mc, Range *range, uint64_t attempt_base, uint16_t len) { - Interval *iv; - int i, rv = INTERVAL_OVERLAP; - uint32_t range_max; - - if (len > mc->range_len) { return -1; } - range_max = mc->range_len - 1; - - /* If we were supplied with a base address to attempt, try that first. */ - if (attempt_base >= mc->address_base && - attempt_base + len - 1 <= mc->address_base + mc->range_len - 1) - { - iv = alloc_interval((uint32_t) (attempt_base - mc->address_base), len); - assert(iv->high <= range_max); - rv = insert_interval(&mc->ranges, iv); - if (rv == INTERVAL_OVERLAP) { - free_interval(iv); - } - } - - /** @todo Use the saved MAAP_ANNOUNCE message ranges to search for addresses likely to be available. - * Old announced ranges (e.g. older than 1.75 minutes) can be deleted if there are no ranges available. */ - - for (i = 0; i < 1000 && rv == INTERVAL_OVERLAP; ++i) { - iv = alloc_interval(random() % (mc->range_len + 1 - len), len); - assert(iv->high <= range_max); - rv = insert_interval(&mc->ranges, iv); - if (rv == INTERVAL_OVERLAP) { - free_interval(iv); - } - } - if (i >= 1000) { - /* There don't appear to be any options! */ - return -1; - } - - iv->data = range; - range->interval = iv; - - return 0; + Interval *iv; + int i, rv = INTERVAL_OVERLAP; + uint32_t range_max; + + if (len > mc->range_len) { return -1; } + range_max = mc->range_len - 1; + + /* If we were supplied with a base address to attempt, try that first. */ + if (attempt_base >= mc->address_base && + attempt_base + len - 1 <= mc->address_base + mc->range_len - 1) + { + iv = alloc_interval((uint32_t) (attempt_base - mc->address_base), len); + assert(iv->high <= range_max); + rv = insert_interval(&mc->ranges, iv); + if (rv == INTERVAL_OVERLAP) { + free_interval(iv); + } + } + + /** @todo Use the saved MAAP_ANNOUNCE message ranges to search for addresses likely to be available. + * Old announced ranges (e.g. older than 1.75 minutes) can be deleted if there are no ranges available. */ + + for (i = 0; i < 1000 && rv == INTERVAL_OVERLAP; ++i) { + iv = alloc_interval(random() % (mc->range_len + 1 - len), len); + assert(iv->high <= range_max); + rv = insert_interval(&mc->ranges, iv); + if (rv == INTERVAL_OVERLAP) { + free_interval(iv); + } + } + if (i >= 1000) { + /* There don't appear to be any options! */ + return -1; + } + + iv->data = range; + range->interval = iv; + + return 0; } int maap_reserve_range(Maap_Client *mc, const void *sender, uint64_t attempt_base, uint32_t length) { - int id; - Range *range; - - if (!mc->initialized) { - MAAP_LOG_DEBUG("Reserve not allowed, as MAAP not initialized"); - inform_not_acquired(mc, sender, -1, length, MAAP_NOTIFY_ERROR_REQUIRES_INITIALIZATION); - return -1; - } - - if (length > 0xFFFF || length > mc->range_len) { - /* Range size cannot be more than 16 bits in size, due to the MAAP packet format */ - inform_not_acquired(mc, sender, -1, length, MAAP_NOTIFY_ERROR_RESERVE_NOT_AVAILABLE); - return -1; - } - - range = malloc(sizeof(Range)); - if (range == NULL) { - inform_not_acquired(mc, sender, -1, length, MAAP_NOTIFY_ERROR_OUT_OF_MEMORY); - return -1; - } - - id = ++(mc->maxid); - range->id = id; - range->state = MAAP_STATE_PROBING; - range->counter = MAAP_PROBE_RETRANSMITS; - range->overlapping = 0; - Time_setFromMonotonicTimer(&range->next_act_time); - range->interval = NULL; - range->sender = sender; - range->next_timer = NULL; - - if (assign_interval(mc, range, attempt_base, length) < 0) - { - /* Cannot find any available intervals of the requested size. */ - inform_not_acquired(mc, sender, -1, length, MAAP_NOTIFY_ERROR_RESERVE_NOT_AVAILABLE); - free(range); - return -1; - } + int id; + Range *range; + + if (!mc->initialized) { + MAAP_LOG_DEBUG("Reserve not allowed, as MAAP not initialized"); + inform_not_acquired(mc, sender, -1, length, MAAP_NOTIFY_ERROR_REQUIRES_INITIALIZATION); + return -1; + } + + if (length > 0xFFFF || length > mc->range_len) { + /* Range size cannot be more than 16 bits in size, due to the MAAP packet format */ + inform_not_acquired(mc, sender, -1, length, MAAP_NOTIFY_ERROR_RESERVE_NOT_AVAILABLE); + return -1; + } + + range = malloc(sizeof(Range)); + if (range == NULL) { + inform_not_acquired(mc, sender, -1, length, MAAP_NOTIFY_ERROR_OUT_OF_MEMORY); + return -1; + } + + id = ++(mc->maxid); + range->id = id; + range->state = MAAP_STATE_PROBING; + range->counter = MAAP_PROBE_RETRANSMITS; + range->overlapping = 0; + Time_setFromMonotonicTimer(&range->next_act_time); + range->interval = NULL; + range->sender = sender; + range->next_timer = NULL; + + if (assign_interval(mc, range, attempt_base, length) < 0) + { + /* Cannot find any available intervals of the requested size. */ + inform_not_acquired(mc, sender, -1, length, MAAP_NOTIFY_ERROR_RESERVE_NOT_AVAILABLE); + free(range); + return -1; + } #ifdef DEBUG_NEGOTIATE_MSG - MAAP_LOGF_DEBUG("Requested address range, id %d", id); - MAAP_LOGF_DEBUG("Selected address range 0x%012llx-0x%012llx", get_start_address(mc, range), get_end_address(mc, range)); + MAAP_LOGF_DEBUG("Requested address range, id %d", id); + MAAP_LOGF_DEBUG("Selected address range 0x%012llx-0x%012llx", get_start_address(mc, range), get_end_address(mc, range)); #endif - inform_acquiring(mc, range); + inform_acquiring(mc, range); - schedule_timer(mc, range); - start_timer(mc); - send_probe(mc, range); + schedule_timer(mc, range); + start_timer(mc); + send_probe(mc, range); - return id; + return id; } int maap_release_range(Maap_Client *mc, const void *sender, int id) { - Interval *iv; - Range *range; - - if (!mc->initialized) { - MAAP_LOG_DEBUG("Release not allowed, as MAAP not initialized"); - inform_released(mc, sender, id, NULL, MAAP_NOTIFY_ERROR_REQUIRES_INITIALIZATION); - return -1; - } - - range = mc->timer_queue; - while (range) { - if (range->id == id && range->state != MAAP_STATE_RELEASED) { - inform_released(mc, sender, id, range, MAAP_NOTIFY_ERROR_NONE); - if (sender != range->sender) - { - /* Also inform the sender that originally reserved this range. */ - inform_released(mc, range->sender, id, range, MAAP_NOTIFY_ERROR_NONE); - } - - iv = range->interval; - remove_range_interval(&mc->ranges, iv); - /* memory for range will be freed the next time its timer elapses */ - range->state = MAAP_STATE_RELEASED; - - return 0; - } - range = range->next_timer; - } - - MAAP_LOGF_DEBUG("Range id %d does not exist to release", id); - inform_released(mc, sender, id, NULL, MAAP_NOTIFY_ERROR_RELEASE_INVALID_ID); - return -1; + Interval *iv; + Range *range; + + if (!mc->initialized) { + MAAP_LOG_DEBUG("Release not allowed, as MAAP not initialized"); + inform_released(mc, sender, id, NULL, MAAP_NOTIFY_ERROR_REQUIRES_INITIALIZATION); + return -1; + } + + range = mc->timer_queue; + while (range) { + if (range->id == id && range->state != MAAP_STATE_RELEASED) { + inform_released(mc, sender, id, range, MAAP_NOTIFY_ERROR_NONE); + if (sender != range->sender) + { + /* Also inform the sender that originally reserved this range. */ + inform_released(mc, range->sender, id, range, MAAP_NOTIFY_ERROR_NONE); + } + + iv = range->interval; + remove_range_interval(&mc->ranges, iv); + /* memory for range will be freed the next time its timer elapses */ + range->state = MAAP_STATE_RELEASED; + + return 0; + } + range = range->next_timer; + } + + MAAP_LOGF_DEBUG("Range id %d does not exist to release", id); + inform_released(mc, sender, id, NULL, MAAP_NOTIFY_ERROR_RELEASE_INVALID_ID); + return -1; } void maap_range_status(Maap_Client *mc, const void *sender, int id) { - Range *range; - - if (!mc->initialized) { - MAAP_LOG_DEBUG("Status not allowed, as MAAP not initialized"); - inform_status(mc, sender, id, NULL, MAAP_NOTIFY_ERROR_REQUIRES_INITIALIZATION); - return; - } - - range = mc->timer_queue; - while (range) { - if (range->id == id && range->state == MAAP_STATE_DEFENDING) { - inform_status(mc, sender, id, range, MAAP_NOTIFY_ERROR_NONE); - return; - } - range = range->next_timer; - } - - MAAP_LOGF_DEBUG("Range id %d does not exist", id); - inform_status(mc, sender, id, NULL, MAAP_NOTIFY_ERROR_RELEASE_INVALID_ID); + Range *range; + + if (!mc->initialized) { + MAAP_LOG_DEBUG("Status not allowed, as MAAP not initialized"); + inform_status(mc, sender, id, NULL, MAAP_NOTIFY_ERROR_REQUIRES_INITIALIZATION); + return; + } + + range = mc->timer_queue; + while (range) { + if (range->id == id && range->state == MAAP_STATE_DEFENDING) { + inform_status(mc, sender, id, range, MAAP_NOTIFY_ERROR_NONE); + return; + } + range = range->next_timer; + } + + MAAP_LOGF_DEBUG("Range id %d does not exist", id); + inform_status(mc, sender, id, NULL, MAAP_NOTIFY_ERROR_RELEASE_INVALID_ID); } int maap_handle_packet(Maap_Client *mc, const uint8_t *stream, int len) { - MAAP_Packet p; - Interval *iv; - uint32_t start; - Range *range; - int rv, num_overlaps; - unsigned long long int own_base, own_max, incoming_base, incoming_max; - - if (len < MAAP_PKT_SIZE) { - MAAP_LOGF_ERROR("Truncated MAAP packet of length %d received, discarding", len); - return -1; - } - rv = unpack_maap(&p, stream); - if (rv != 0) { - MAAP_LOG_ERROR("Error unpacking the MAAP packet"); - return -1; - } - - if (p.Ethertype != MAAP_TYPE || - p.subtype != MAAP_SUBTYPE || - p.control_data_length != 16 ) - { - /* This is not a MAAP packet. Ignore it. */ + MAAP_Packet p; + Interval *iv; + uint32_t start; + Range *range; + int rv, num_overlaps; + unsigned long long int own_base, own_max, incoming_base, incoming_max; + + if (len < MAAP_PKT_SIZE) { + MAAP_LOGF_ERROR("Truncated MAAP packet of length %d received, discarding", len); + return -1; + } + rv = unpack_maap(&p, stream); + if (rv != 0) { + MAAP_LOG_ERROR("Error unpacking the MAAP packet"); + return -1; + } + + if (p.Ethertype != MAAP_TYPE || + p.subtype != MAAP_SUBTYPE || + p.control_data_length != 16 ) + { + /* This is not a MAAP packet. Ignore it. */ #ifdef DEBUG_NEGOTIATE_MSG - MAAP_LOGF_DEBUG("Ignoring non-MAAP packet of length %d", len); + MAAP_LOGF_DEBUG("Ignoring non-MAAP packet of length %d", len); #endif - return -1; - } + return -1; + } - if (p.version != 0) { - MAAP_LOGF_ERROR("AVTP version %u not supported", p.version); - return -1; - } + if (p.version != 0) { + MAAP_LOGF_ERROR("AVTP version %u not supported", p.version); + return -1; + } - if (p.message_type < MAAP_PROBE || p.message_type > MAAP_ANNOUNCE) { - MAAP_LOGF_ERROR("MAAP packet message type %u not recognized", p.message_type); - return -1; - } + if (p.message_type < MAAP_PROBE || p.message_type > MAAP_ANNOUNCE) { + MAAP_LOGF_ERROR("MAAP packet message type %u not recognized", p.message_type); + return -1; + } - own_base = mc->address_base; - own_max = mc->address_base + mc->range_len - 1; - incoming_base = p.requested_start_address; - incoming_max = p.requested_start_address + p.requested_count - 1; + own_base = mc->address_base; + own_max = mc->address_base + mc->range_len - 1; + incoming_base = p.requested_start_address; + incoming_max = p.requested_start_address + p.requested_count - 1; #ifdef DEBUG_NEGOTIATE_MSG - if (p.message_type == MAAP_PROBE) { - MAAP_LOGF_DEBUG("Received PROBE for range 0x%012llx-0x%012llx (Size %u)", incoming_base, incoming_max, p.requested_count); - } - if (p.message_type == MAAP_DEFEND) { - MAAP_LOGF_DEBUG("Received DEFEND for range 0x%012llx-0x%012llx (Size %u),", - incoming_base, incoming_max, p.requested_count); - MAAP_LOGF_DEBUG("conflicting with range 0x%012llx-0x%012llx (Size %u)", - (unsigned long long) p.conflict_start_address, - (unsigned long long) p.conflict_start_address + p.conflict_count - 1, - p.conflict_count); - } - if (p.message_type == MAAP_ANNOUNCE) { - MAAP_LOGF_DEBUG("Received ANNOUNCE for range 0x%012llx-0x%012llx (Size %u)", incoming_base, incoming_max, p.requested_count); - } + if (p.message_type == MAAP_PROBE) { + MAAP_LOGF_DEBUG("Received PROBE for range 0x%012llx-0x%012llx (Size %u)", incoming_base, incoming_max, p.requested_count); + } + if (p.message_type == MAAP_DEFEND) { + MAAP_LOGF_DEBUG("Received DEFEND for range 0x%012llx-0x%012llx (Size %u),", + incoming_base, incoming_max, p.requested_count); + MAAP_LOGF_DEBUG("conflicting with range 0x%012llx-0x%012llx (Size %u)", + (unsigned long long) p.conflict_start_address, + (unsigned long long) p.conflict_start_address + p.conflict_count - 1, + p.conflict_count); + } + if (p.message_type == MAAP_ANNOUNCE) { + MAAP_LOGF_DEBUG("Received ANNOUNCE for range 0x%012llx-0x%012llx (Size %u)", incoming_base, incoming_max, p.requested_count); + } #endif - if (incoming_max < own_base || own_max < incoming_base) { + if (incoming_max < own_base || own_max < incoming_base) { #ifdef DEBUG_NEGOTIATE_MSG - MAAP_LOG_DEBUG("Packet refers to a range outside of our concern:"); - MAAP_LOGF_DEBUG(" 0x%012llx < 0x%012llx || 0x%012llx < 0x%012llx", incoming_max, own_base, own_max, incoming_base); + MAAP_LOG_DEBUG("Packet refers to a range outside of our concern:"); + MAAP_LOGF_DEBUG(" 0x%012llx < 0x%012llx || 0x%012llx < 0x%012llx", incoming_max, own_base, own_max, incoming_base); #endif - return 0; - } - - /** @todo If this is a MAAP_ANNOUNCE message, save the announced range and time received for later reference. */ - - /* Flag all the range items that overlap with the incoming packet. */ - num_overlaps = 0; - start = (uint32_t) (p.requested_start_address - mc->address_base); - for (iv = search_interval(mc->ranges, start, p.requested_count); iv != NULL && interval_check_overlap(iv, start, p.requested_count); iv = next_interval(iv)) { - range = iv->data; - range->overlapping = 1; - num_overlaps++; - } - - while (num_overlaps-- > 0) { - /* Find the first item that is still flagged. */ - for (iv = search_interval(mc->ranges, start, p.requested_count); iv != NULL; iv = next_interval(iv)) { - range = iv->data; - if (range->overlapping) { break; } - } - if (!iv) { - /* We reached the end of the list. */ - assert(0); /* We should never get here! */ - break; - } - range->overlapping = 0; - - if (range->state == MAAP_STATE_PROBING) { - - if (p.message_type == MAAP_PROBE && compare_mac_addresses(mc->src_mac, p.SA)) { - /* We won with the lower MAC Address. Do nothing. */ + return 0; + } + + /** @todo If this is a MAAP_ANNOUNCE message, save the announced range and time received for later reference. */ + + /* Flag all the range items that overlap with the incoming packet. */ + num_overlaps = 0; + start = (uint32_t) (p.requested_start_address - mc->address_base); + for (iv = search_interval(mc->ranges, start, p.requested_count); iv != NULL && interval_check_overlap(iv, start, p.requested_count); iv = next_interval(iv)) { + range = iv->data; + range->overlapping = 1; + num_overlaps++; + } + + while (num_overlaps-- > 0) { + /* Find the first item that is still flagged. */ + for (iv = search_interval(mc->ranges, start, p.requested_count); iv != NULL; iv = next_interval(iv)) { + range = iv->data; + if (range->overlapping) { break; } + } + if (!iv) { + /* We reached the end of the list. */ + assert(0); /* We should never get here! */ + break; + } + range->overlapping = 0; + + if (range->state == MAAP_STATE_PROBING) { + + if (p.message_type == MAAP_PROBE && compare_mac_addresses(mc->src_mac, p.SA)) { + /* We won with the lower MAC Address. Do nothing. */ #ifdef DEBUG_NEGOTIATE_MSG - MAAP_LOG_DEBUG("Ignoring conflicting probe request"); + MAAP_LOG_DEBUG("Ignoring conflicting probe request"); #endif - } else { - /* Find an alternate interval, remove old interval, - and restart probe counter */ - int range_size = iv->high - iv->low + 1; - iv->data = NULL; /* Range is moving to a new interval */ - if (assign_interval(mc, range, 0, range_size) < 0) { - /* No interval is available, so stop probing and report an error. */ - MAAP_LOG_WARNING("Unable to find an available address block to probe"); - inform_not_acquired(mc, range->sender, range->id, range_size, MAAP_NOTIFY_ERROR_RESERVE_NOT_AVAILABLE); - remove_range_interval(&mc->ranges, iv); - /* memory will be freed the next time its timer elapses */ - range->state = MAAP_STATE_RELEASED; - } else { + } else { + /* Find an alternate interval, remove old interval, + and restart probe counter */ + int range_size = iv->high - iv->low + 1; + iv->data = NULL; /* Range is moving to a new interval */ + if (assign_interval(mc, range, 0, range_size) < 0) { + /* No interval is available, so stop probing and report an error. */ + MAAP_LOG_WARNING("Unable to find an available address block to probe"); + inform_not_acquired(mc, range->sender, range->id, range_size, MAAP_NOTIFY_ERROR_RESERVE_NOT_AVAILABLE); + remove_range_interval(&mc->ranges, iv); + /* memory will be freed the next time its timer elapses */ + range->state = MAAP_STATE_RELEASED; + } else { #ifdef DEBUG_NEGOTIATE_MSG - MAAP_LOGF_DEBUG("Selected new address range 0x%012llx-0x%012llx", - get_start_address(mc, range), get_end_address(mc, range)); + MAAP_LOGF_DEBUG("Selected new address range 0x%012llx-0x%012llx", + get_start_address(mc, range), get_end_address(mc, range)); #endif - inform_acquiring(mc, range); + inform_acquiring(mc, range); - remove_range_interval(&mc->ranges, iv); - range->counter = MAAP_PROBE_RETRANSMITS; + remove_range_interval(&mc->ranges, iv); + range->counter = MAAP_PROBE_RETRANSMITS; - schedule_timer(mc, range); - send_probe(mc, range); - } - } + schedule_timer(mc, range); + send_probe(mc, range); + } + } - } else if (range->state == MAAP_STATE_DEFENDING) { + } else if (range->state == MAAP_STATE_DEFENDING) { - MAAP_LOGF_INFO("Conflict detected with our range (id %d)!", range->id); + MAAP_LOGF_INFO("Conflict detected with our range (id %d)!", range->id); #ifdef DEBUG_NEGOTIATE_MSG - MAAP_LOGF_DEBUG(" Request of 0x%012llx-0x%012llx conflicts with our range of 0x%012llx-0x%012llx", - incoming_base, incoming_max, - get_start_address(mc, range), get_end_address(mc, range)); + MAAP_LOGF_DEBUG(" Request of 0x%012llx-0x%012llx conflicts with our range of 0x%012llx-0x%012llx", + incoming_base, incoming_max, + get_start_address(mc, range), get_end_address(mc, range)); #endif - if (p.message_type == MAAP_PROBE) { - MAAP_LOG_INFO("DEFEND!"); - send_defend(mc, range, p.requested_start_address, p.requested_count, p.SA); - } else if (compare_mac_addresses(mc->src_mac, p.SA)) { - /* We won with the lower MAC Address. Do nothing. */ - MAAP_LOG_INFO("IGNORE"); - } else { - Range *new_range; - int range_size = iv->high - iv->low + 1; - - MAAP_LOG_INFO("YIELD"); - - /* Start a new reservation request for the owner of the yielded reservation. - * Use the same ID as the yielded range, so the owner can easily track it. - * - * Note: Because our previous range is still in our range list, - * the new range selected will not overlap it. - */ - new_range = malloc(sizeof(Range)); - if (new_range == NULL) { - inform_yielded(mc, range, MAAP_NOTIFY_ERROR_OUT_OF_MEMORY); - } else { - new_range->id = range->id; - new_range->state = MAAP_STATE_PROBING; - new_range->counter = MAAP_PROBE_RETRANSMITS; - new_range->overlapping = 0; - Time_setFromMonotonicTimer(&new_range->next_act_time); - new_range->interval = NULL; - new_range->sender = range->sender; - new_range->next_timer = NULL; - if (assign_interval(mc, new_range, 0, range_size) < 0) - { - /* Cannot find any available intervals of the requested size. */ - inform_yielded(mc, range, MAAP_NOTIFY_ERROR_RESERVE_NOT_AVAILABLE); - free(new_range); - } else { + if (p.message_type == MAAP_PROBE) { + MAAP_LOG_INFO("DEFEND!"); + send_defend(mc, range, p.requested_start_address, p.requested_count, p.SA); + } else if (compare_mac_addresses(mc->src_mac, p.SA)) { + /* We won with the lower MAC Address. Do nothing. */ + MAAP_LOG_INFO("IGNORE"); + } else { + Range *new_range; + int range_size = iv->high - iv->low + 1; + + MAAP_LOG_INFO("YIELD"); + + /* Start a new reservation request for the owner of the yielded reservation. + * Use the same ID as the yielded range, so the owner can easily track it. + * + * Note: Because our previous range is still in our range list, + * the new range selected will not overlap it. + */ + new_range = malloc(sizeof(Range)); + if (new_range == NULL) { + inform_yielded(mc, range, MAAP_NOTIFY_ERROR_OUT_OF_MEMORY); + } else { + new_range->id = range->id; + new_range->state = MAAP_STATE_PROBING; + new_range->counter = MAAP_PROBE_RETRANSMITS; + new_range->overlapping = 0; + Time_setFromMonotonicTimer(&new_range->next_act_time); + new_range->interval = NULL; + new_range->sender = range->sender; + new_range->next_timer = NULL; + if (assign_interval(mc, new_range, 0, range_size) < 0) + { + /* Cannot find any available intervals of the requested size. */ + inform_yielded(mc, range, MAAP_NOTIFY_ERROR_RESERVE_NOT_AVAILABLE); + free(new_range); + } else { #ifdef DEBUG_NEGOTIATE_MSG - MAAP_LOGF_DEBUG("Requested replacement address range, id %d", new_range->id); - MAAP_LOGF_DEBUG("Selected replacement address range 0x%012llx-0x%012llx", get_start_address(mc, new_range), get_end_address(mc, new_range)); + MAAP_LOGF_DEBUG("Requested replacement address range, id %d", new_range->id); + MAAP_LOGF_DEBUG("Selected replacement address range 0x%012llx-0x%012llx", get_start_address(mc, new_range), get_end_address(mc, new_range)); #endif - inform_acquiring(mc, range); + inform_acquiring(mc, range); - /* Send a probe for the replacement address range to try. */ - schedule_timer(mc, new_range); - send_probe(mc, new_range); + /* Send a probe for the replacement address range to try. */ + schedule_timer(mc, new_range); + send_probe(mc, new_range); - inform_yielded(mc, range, MAAP_NOTIFY_ERROR_NONE); - } - } + inform_yielded(mc, range, MAAP_NOTIFY_ERROR_NONE); + } + } - /* We are done with the old range. */ - remove_range_interval(&mc->ranges, iv); - /* memory will be freed the next time its timer elapses */ - range->state = MAAP_STATE_RELEASED; - } + /* We are done with the old range. */ + remove_range_interval(&mc->ranges, iv); + /* memory will be freed the next time its timer elapses */ + range->state = MAAP_STATE_RELEASED; + } - } - } + } + } - start_timer(mc); + start_timer(mc); - return 0; + return 0; } int handle_probe_timer(Maap_Client *mc, Range *range) { - if (range->counter == 0) { - inform_acquired(mc, range, MAAP_NOTIFY_ERROR_NONE); - range->state = MAAP_STATE_DEFENDING; - schedule_timer(mc, range); - send_announce(mc, range); - } else { - range->counter--; - schedule_timer(mc, range); - send_probe(mc, range); - } - - return 0; + if (range->counter == 0) { + inform_acquired(mc, range, MAAP_NOTIFY_ERROR_NONE); + range->state = MAAP_STATE_DEFENDING; + schedule_timer(mc, range); + send_announce(mc, range); + } else { + range->counter--; + schedule_timer(mc, range); + send_probe(mc, range); + } + + return 0; } int handle_defend_timer(Maap_Client *mc, Range *range) { - schedule_timer(mc, range); - send_announce(mc, range); + schedule_timer(mc, range); + send_announce(mc, range); - return 0; + return 0; } int maap_handle_timer(Maap_Client *mc) { - Time currenttime; - Range *range; + Time currenttime; + Range *range; - /* Get the current time. */ - Time_setFromMonotonicTimer(¤ttime); + /* Get the current time. */ + Time_setFromMonotonicTimer(¤ttime); #ifdef DEBUG_TIMER_MSG - MAAP_LOGF_DEBUG("maap_handle_timer called at: %s", Time_dump(¤ttime)); + MAAP_LOGF_DEBUG("maap_handle_timer called at: %s", Time_dump(¤ttime)); #endif - while ((range = mc->timer_queue) && Time_passed(¤ttime, &range->next_act_time)) { + while ((range = mc->timer_queue) && Time_passed(¤ttime, &range->next_act_time)) { #ifdef DEBUG_TIMER_MSG - MAAP_LOGF_DEBUG("Due timer: %s", Time_dump(&range->next_act_time)); + MAAP_LOGF_DEBUG("Due timer: %s", Time_dump(&range->next_act_time)); #endif - mc->timer_queue = range->next_timer; - range->next_timer = NULL; + mc->timer_queue = range->next_timer; + range->next_timer = NULL; - if (range->state == MAAP_STATE_PROBING) { + if (range->state == MAAP_STATE_PROBING) { #ifdef DEBUG_TIMER_MSG - MAAP_LOG_DEBUG("Handling probe timer"); + MAAP_LOG_DEBUG("Handling probe timer"); #endif - handle_probe_timer(mc, range); - } else if (range->state == MAAP_STATE_DEFENDING) { + handle_probe_timer(mc, range); + } else if (range->state == MAAP_STATE_DEFENDING) { #ifdef DEBUG_TIMER_MSG - MAAP_LOG_DEBUG("Handling defend timer"); + MAAP_LOG_DEBUG("Handling defend timer"); #endif - handle_defend_timer(mc, range); - } else if (range->state == MAAP_STATE_RELEASED) { + handle_defend_timer(mc, range); + } else if (range->state == MAAP_STATE_RELEASED) { #ifdef DEBUG_TIMER_MSG - MAAP_LOG_DEBUG("Freeing released timer"); + MAAP_LOG_DEBUG("Freeing released timer"); #endif - free(range); - } + free(range); + } - } + } - start_timer(mc); + start_timer(mc); - return 0; + return 0; } int64_t maap_get_delay_to_next_timer(Maap_Client *mc) diff --git a/daemons/maap/common/maap.h b/daemons/maap/common/maap.h index 34359bf9..3abce59d 100644 --- a/daemons/maap/common/maap.h +++ b/daemons/maap/common/maap.h @@ -59,13 +59,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define MAAP_SUBTYPE 0xFE /**< AVTP MAAP subtype - Defined in IEEE 1722-2016 Table 6 */ #define MAAP_PKT_SIZE 42 /**< Number of bytes for a raw MAAP Ethernet packet */ -/** MAAP Range States */ + /** MAAP Range States */ typedef enum { - MAAP_STATE_INVALID = 0, - MAAP_STATE_PROBING, /**< Probing to determine if the address interval is available */ - MAAP_STATE_DEFENDING, /**< The address interval has been reserved, and defend if conflicts detected */ - MAAP_STATE_RELEASED, /**< The address interval has been released, and is waiting to be freed */ -} Maap_State; + MAAP_STATE_INVALID = 0, + MAAP_STATE_PROBING, /**< Probing to determine if the address interval is available */ + MAAP_STATE_DEFENDING, /**< The address interval has been reserved, and defend if conflicts detected */ + MAAP_STATE_RELEASED, /**< The address interval has been released, and is waiting to be freed */ + } Maap_State; /** Wrapper for struct maap_notify */ @@ -73,9 +73,9 @@ typedef struct maap_notify_list Maap_Notify_List; /** Structure for each queued notification */ struct maap_notify_list { - Maap_Notify notify; /**< Notification information to send */ - const void *sender; /**< Sender information pointer for the entity that requested the original command */ - Maap_Notify_List *next; /**< Next notification in the queue */ + Maap_Notify notify; /**< Notification information to send */ + const void *sender; /**< Sender information pointer for the entity that requested the original command */ + Maap_Notify_List *next; /**< Next notification in the queue */ }; @@ -84,31 +84,31 @@ typedef struct range Range; /** Structure for each range in use */ struct range { - int id; /**< Unique identifier for this range */ - Maap_State state; /**< State of this range */ - int counter; /**< Counter used to limit the number of probes for this range */ - int overlapping; /**< Temporary flag used to keep track of ranges that require overlap processing */ - Time next_act_time; /**< Next time to perform an action for this range */ - Interval *interval; /**< Interval information for the range */ - const void *sender; /**< Sender information pointer for the entity that requested the range */ - Range *next_timer; /**< Next range in the list */ + int id; /**< Unique identifier for this range */ + Maap_State state; /**< State of this range */ + int counter; /**< Counter used to limit the number of probes for this range */ + int overlapping; /**< Temporary flag used to keep track of ranges that require overlap processing */ + Time next_act_time; /**< Next time to perform an action for this range */ + Interval *interval; /**< Interval information for the range */ + const void *sender; /**< Sender information pointer for the entity that requested the range */ + Range *next_timer; /**< Next range in the list */ }; /** MAAP Initialization Information */ typedef struct { - uint64_t dest_mac; /**< Multicast address for MAAP packets */ - uint64_t src_mac; /**< Local adapter interface MAC Address */ - uint64_t address_base; /**< Starting address of the recognized range of addresses (typically #MAAP_DYNAMIC_POOL_BASE) */ - uint32_t range_len; /**< Number of recognized addresses (typically #MAAP_DYNAMIC_POOL_SIZE) */ - Interval *ranges; /**< Pointer to the root of the #Interval tree, which contains all the Range structures */ - Range *timer_queue; /**< Pointer to a linked list of ranges that need timer support, - * with the first timer to expire being first in the list */ - Timer *timer; /**< Pointer to the platform-specific timing support (initialized by calling #Time_newTimer) */ - Net *net; /**< Pointer to the platform-specific networking support (initialized by calling #Net_newNet) */ - int maxid; /**< Identifier value of the latest reservation */ - Maap_Notify_List *notifies; /**< Pointer to a linked list of queued notification */ - int initialized; /**< 1 if the structure has been initialized, 0 otherwise */ + uint64_t dest_mac; /**< Multicast address for MAAP packets */ + uint64_t src_mac; /**< Local adapter interface MAC Address */ + uint64_t address_base; /**< Starting address of the recognized range of addresses (typically #MAAP_DYNAMIC_POOL_BASE) */ + uint32_t range_len; /**< Number of recognized addresses (typically #MAAP_DYNAMIC_POOL_SIZE) */ + Interval *ranges; /**< Pointer to the root of the #Interval tree, which contains all the Range structures */ + Range *timer_queue; /**< Pointer to a linked list of ranges that need timer support, + * with the first timer to expire being first in the list */ + Timer *timer; /**< Pointer to the platform-specific timing support (initialized by calling #Time_newTimer) */ + Net *net; /**< Pointer to the platform-specific networking support (initialized by calling #Net_newNet) */ + int maxid; /**< Identifier value of the latest reservation */ + Maap_Notify_List *notifies; /**< Pointer to a linked list of queued notification */ + int initialized; /**< 1 if the structure has been initialized, 0 otherwise */ } Maap_Client; diff --git a/daemons/maap/common/maap_iface.h b/daemons/maap/common/maap_iface.h index 6381ab07..0ebe24aa 100644 --- a/daemons/maap/common/maap_iface.h +++ b/daemons/maap/common/maap_iface.h @@ -40,13 +40,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** MAAP Commands */ typedef enum { - MAAP_CMD_INVALID = 0, - MAAP_CMD_INIT, /**< Initialize the daemon to support a range of values */ - MAAP_CMD_RESERVE, /**< Preserve a block of addresses within the initialized range */ - MAAP_CMD_RELEASE, /**< Release a previously-reserved block of addresses */ - MAAP_CMD_STATUS, /**< Return the block of reserved addresses associated with the supplied ID */ - MAAP_CMD_EXIT, /**< Have the daemon exit */ -} Maap_Cmd_Tag; + MAAP_CMD_INVALID = 0, + MAAP_CMD_INIT, /**< Initialize the daemon to support a range of values */ + MAAP_CMD_RESERVE, /**< Preserve a block of addresses within the initialized range */ + MAAP_CMD_RELEASE, /**< Release a previously-reserved block of addresses */ + MAAP_CMD_STATUS, /**< Return the block of reserved addresses associated with the supplied ID */ + MAAP_CMD_EXIT, /**< Have the daemon exit */ + } Maap_Cmd_Tag; /** MAAP Command Request Format * @@ -54,34 +54,34 @@ typedef enum { * Not all values are used for all commands. */ typedef struct { - Maap_Cmd_Tag kind; /**< Type of command to perform */ - int32_t id; /**< ID to use for #MAAP_CMD_RELEASE or #MAAP_CMD_STATUS */ - uint64_t start; /**< Address range start for #MAAP_CMD_INIT */ - uint32_t count; /**< Address range size for #MAAP_CMD_INIT, or address block size for #MAAP_CMD_RESERVE */ + Maap_Cmd_Tag kind; /**< Type of command to perform */ + int32_t id; /**< ID to use for #MAAP_CMD_RELEASE or #MAAP_CMD_STATUS */ + uint64_t start; /**< Address range start for #MAAP_CMD_INIT */ + uint32_t count; /**< Address range size for #MAAP_CMD_INIT, or address block size for #MAAP_CMD_RESERVE */ } Maap_Cmd; /** MAAP Notifications */ typedef enum { - MAAP_NOTIFY_INVALID = 0, - MAAP_NOTIFY_INITIALIZED, /**< Notification sent in response to a #MAAP_CMD_INIT command */ - MAAP_NOTIFY_ACQUIRING, /**< Notification sent in response to a #MAAP_CMD_RESERVE command indicating that the reservation is in progress */ - MAAP_NOTIFY_ACQUIRED, /**< Notification sent in response to a #MAAP_CMD_RESERVE command indicating that the reservation is complete (either succeeded or failed) */ - MAAP_NOTIFY_RELEASED, /**< Notification sent in response to a #MAAP_CMD_RELEASE command */ - MAAP_NOTIFY_STATUS, /**< Notification sent in response to a #MAAP_CMD_STATUS command */ - MAAP_NOTIFY_YIELDED, /**< Notification that an address block was yielded to another device on the network */ + MAAP_NOTIFY_INVALID = 0, + MAAP_NOTIFY_INITIALIZED, /**< Notification sent in response to a #MAAP_CMD_INIT command */ + MAAP_NOTIFY_ACQUIRING, /**< Notification sent in response to a #MAAP_CMD_RESERVE command indicating that the reservation is in progress */ + MAAP_NOTIFY_ACQUIRED, /**< Notification sent in response to a #MAAP_CMD_RESERVE command indicating that the reservation is complete (either succeeded or failed) */ + MAAP_NOTIFY_RELEASED, /**< Notification sent in response to a #MAAP_CMD_RELEASE command */ + MAAP_NOTIFY_STATUS, /**< Notification sent in response to a #MAAP_CMD_STATUS command */ + MAAP_NOTIFY_YIELDED, /**< Notification that an address block was yielded to another device on the network */ } Maap_Notify_Tag; /** MAAP Notification Errors */ typedef enum { - MAAP_NOTIFY_ERROR_NONE = 0, /**< Command was successful */ - MAAP_NOTIFY_ERROR_REQUIRES_INITIALIZATION, /**< MAAP is not initialized, so the command cannot be performed */ - MAAP_NOTIFY_ERROR_ALREADY_INITIALIZED, /**< MAAP is already initialized, so the values cannot be changed */ - MAAP_NOTIFY_ERROR_RESERVE_NOT_AVAILABLE, /**< The MAAP reservation is not available, or yield cannot allocate a replacement block. - * Try again with a smaller address block size. */ - MAAP_NOTIFY_ERROR_RELEASE_INVALID_ID, /**< The MAAP reservation ID is not valid, so cannot be released or report its status */ - MAAP_NOTIFY_ERROR_OUT_OF_MEMORY, /**< The MAAP application is out of memory */ - MAAP_NOTIFY_ERROR_INTERNAL, /**< The MAAP application experienced an internal error */ + MAAP_NOTIFY_ERROR_NONE = 0, /**< Command was successful */ + MAAP_NOTIFY_ERROR_REQUIRES_INITIALIZATION, /**< MAAP is not initialized, so the command cannot be performed */ + MAAP_NOTIFY_ERROR_ALREADY_INITIALIZED, /**< MAAP is already initialized, so the values cannot be changed */ + MAAP_NOTIFY_ERROR_RESERVE_NOT_AVAILABLE, /**< The MAAP reservation is not available, or yield cannot allocate a replacement block. + * Try again with a smaller address block size. */ + MAAP_NOTIFY_ERROR_RELEASE_INVALID_ID, /**< The MAAP reservation ID is not valid, so cannot be released or report its status */ + MAAP_NOTIFY_ERROR_OUT_OF_MEMORY, /**< The MAAP application is out of memory */ + MAAP_NOTIFY_ERROR_INTERNAL, /**< The MAAP application experienced an internal error */ } Maap_Notify_Error; /** MAAP Notification Response Format @@ -90,21 +90,21 @@ typedef enum { * Not all values are used for all notifications. */ typedef struct { - Maap_Notify_Tag kind; /**< Type of notification being returned */ - int32_t id; /**< ID assigned for #MAAP_NOTIFY_ACQUIRING and #MAAP_NOTIFY_ACQUIRED, or used for #MAAP_NOTIFY_RELEASED, - * #MAAP_NOTIFY_STATUS, or #MAAP_NOTIFY_YIELDED */ - uint64_t start; /**< Address range start for #MAAP_NOTIFY_INITIALIZED, or address block start for #MAAP_NOTIFY_ACQUIRING, - * #MAAP_NOTIFY_ACQUIRED, #MAAP_NOTIFY_RELEASED, #MAAP_NOTIFY_STATUS, or #MAAP_NOTIFY_YIELDED */ - uint32_t count; /**< Address range size for #MAAP_NOTIFY_INITIALIZED, or address block size for #MAAP_NOTIFY_ACQUIRING, - * #MAAP_NOTIFY_ACQUIRED, #MAAP_NOTIFY_RELEASED, #MAAP_NOTIFY_STATUS, or #MAAP_NOTIFY_YIELDED */ - Maap_Notify_Error result; /**< #MAAP_NOTIFY_ERROR_NONE if the command succeeded, or another value if an error occurred */ + Maap_Notify_Tag kind; /**< Type of notification being returned */ + int32_t id; /**< ID assigned for #MAAP_NOTIFY_ACQUIRING and #MAAP_NOTIFY_ACQUIRED, or used for #MAAP_NOTIFY_RELEASED, + * #MAAP_NOTIFY_STATUS, or #MAAP_NOTIFY_YIELDED */ + uint64_t start; /**< Address range start for #MAAP_NOTIFY_INITIALIZED, or address block start for #MAAP_NOTIFY_ACQUIRING, + * #MAAP_NOTIFY_ACQUIRED, #MAAP_NOTIFY_RELEASED, #MAAP_NOTIFY_STATUS, or #MAAP_NOTIFY_YIELDED */ + uint32_t count; /**< Address range size for #MAAP_NOTIFY_INITIALIZED, or address block size for #MAAP_NOTIFY_ACQUIRING, + * #MAAP_NOTIFY_ACQUIRED, #MAAP_NOTIFY_RELEASED, #MAAP_NOTIFY_STATUS, or #MAAP_NOTIFY_YIELDED */ + Maap_Notify_Error result; /**< #MAAP_NOTIFY_ERROR_NONE if the command succeeded, or another value if an error occurred */ } Maap_Notify; /** MAAP Output Type Desired Flags */ typedef enum { - MAAP_OUTPUT_LOGGING = 0x01, /**< Send the results to the logging engine */ - MAAP_OUTPUT_USER_FRIENDLY = 0x02, /**< Send the results to stdout in user-friendly format */ + MAAP_OUTPUT_LOGGING = 0x01, /**< Send the results to the logging engine */ + MAAP_OUTPUT_USER_FRIENDLY = 0x02, /**< Send the results to stdout in user-friendly format */ } Maap_Output_Type; #endif diff --git a/daemons/maap/common/maap_log_queue.c b/daemons/maap/common/maap_log_queue.c index 5072b36a..ef6f3289 100644 --- a/daemons/maap/common/maap_log_queue.c +++ b/daemons/maap/common/maap_log_queue.c @@ -26,7 +26,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdio.h> #include <stdlib.h> #include <string.h> + +#if defined(_WIN32) && (_MSC_VER < 1800) +/* Visual Studio 2012 and earlier */ +typedef unsigned __int8 uint8_t; +typedef unsigned __int32 uint32_t; +#else #include <inttypes.h> +#endif #include "maap_log_queue.h" @@ -63,10 +70,12 @@ struct maap_log_queue { maap_log_queue_t maapLogQueueNewQueue(uint32_t elemSize, uint32_t queueSize) { + maap_log_queue_t retQueue; + if (elemSize < 1 || queueSize < 1) return NULL; - maap_log_queue_t retQueue = calloc(1, sizeof(struct maap_log_queue)); + retQueue = calloc(1, sizeof(struct maap_log_queue)); if (retQueue) { retQueue->elemArray = calloc(queueSize, sizeof(struct maap_log_queue_elem)); if (retQueue->elemArray) { diff --git a/daemons/maap/common/maap_net.c b/daemons/maap/common/maap_net.c index bb502e84..90e90e6f 100644 --- a/daemons/maap/common/maap_net.c +++ b/daemons/maap/common/maap_net.c @@ -42,11 +42,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. typedef enum { - BUFFER_FREE = 0, - BUFFER_SUPPLIED, - BUFFER_QUEUED, - BUFFER_SENDING, -} Buffer_State; + BUFFER_FREE = 0, + BUFFER_SUPPLIED, + BUFFER_QUEUED, + BUFFER_SENDING, + } Buffer_State; struct maap_buffer { char buffer[MAAP_NET_BUFFER_SIZE]; diff --git a/daemons/maap/common/maap_packet.c b/daemons/maap/common/maap_packet.c index b988738e..55a30110 100644 --- a/daemons/maap/common/maap_packet.c +++ b/daemons/maap/common/maap_packet.c @@ -35,171 +35,171 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "maap_log.h" int unpack_maap(MAAP_Packet *packet, const uint8_t *stream) { - uint64_t tmp64; - uint16_t tmp16; - uint8_t tmp8; + uint64_t tmp64; + uint16_t tmp16; + uint8_t tmp8; - assert(packet); - assert(stream); + assert(packet); + assert(stream); - memcpy(&tmp64, stream, 6); - packet->DA = BE64TOH(tmp64) >> 16; - stream += 6; + memcpy(&tmp64, stream, 6); + packet->DA = BE64TOH(tmp64) >> 16; + stream += 6; - memcpy(&tmp64, stream, 6); - packet->SA = BE64TOH(tmp64) >> 16; - stream += 6; + memcpy(&tmp64, stream, 6); + packet->SA = BE64TOH(tmp64) >> 16; + stream += 6; - memcpy(&tmp16, stream, 2); - packet->Ethertype = BE16TOH(tmp16); - stream += 2; + memcpy(&tmp16, stream, 2); + packet->Ethertype = BE16TOH(tmp16); + stream += 2; - tmp8 = *stream; - packet->subtype = tmp8; - stream++; + tmp8 = *stream; + packet->subtype = tmp8; + stream++; - tmp8 = *stream; - packet->SV = (tmp8 & 0x80) >> 7; - packet->version = (tmp8 & 0x70) >> 4; - packet->message_type = tmp8 & 0x0f; - stream++; + tmp8 = *stream; + packet->SV = (tmp8 & 0x80) >> 7; + packet->version = (tmp8 & 0x70) >> 4; + packet->message_type = tmp8 & 0x0f; + stream++; - memcpy(&tmp8, stream, 1); - packet->maap_version = (tmp8 & 0xf8) >> 3; + memcpy(&tmp8, stream, 1); + packet->maap_version = (tmp8 & 0xf8) >> 3; - memcpy(&tmp16, stream, 2); - packet->control_data_length = BE16TOH(tmp16) & 0x07ff; - stream += 2; + memcpy(&tmp16, stream, 2); + packet->control_data_length = BE16TOH(tmp16) & 0x07ff; + stream += 2; - memcpy(&tmp64, stream, 8); - packet->stream_id = BE64TOH(tmp64); - stream += 8; + memcpy(&tmp64, stream, 8); + packet->stream_id = BE64TOH(tmp64); + stream += 8; - memcpy(&tmp64, stream, 6); - packet->requested_start_address = BE64TOH(tmp64) >> 16; - stream += 6; + memcpy(&tmp64, stream, 6); + packet->requested_start_address = BE64TOH(tmp64) >> 16; + stream += 6; - memcpy(&tmp16, stream, 2); - packet->requested_count = BE16TOH(tmp16); - stream += 2; + memcpy(&tmp16, stream, 2); + packet->requested_count = BE16TOH(tmp16); + stream += 2; - memcpy(&tmp64, stream, 6); - packet->conflict_start_address = BE64TOH(tmp64) >> 16; - stream += 6; + memcpy(&tmp64, stream, 6); + packet->conflict_start_address = BE64TOH(tmp64) >> 16; + stream += 6; - memcpy(&tmp16, stream, 2); - packet->conflict_count = BE16TOH(tmp16); + memcpy(&tmp16, stream, 2); + packet->conflict_count = BE16TOH(tmp16); - return 0; -} + return 0; + } int pack_maap(const MAAP_Packet *packet, uint8_t *stream) { - uint64_t tmp64; - uint16_t tmp16; - uint8_t tmp8; + uint64_t tmp64; + uint16_t tmp16; + uint8_t tmp8; - assert(packet); - assert(stream); + assert(packet); + assert(stream); - tmp64 = HTOBE64(packet->DA << 16); - memcpy(stream, &tmp64, 6); - stream += 6; + tmp64 = HTOBE64(packet->DA << 16); + memcpy(stream, &tmp64, 6); + stream += 6; - tmp64 = HTOBE64(packet->SA << 16); - memcpy(stream, &tmp64, 6); - stream += 6; + tmp64 = HTOBE64(packet->SA << 16); + memcpy(stream, &tmp64, 6); + stream += 6; - tmp16 = HTOBE16(packet->Ethertype); - memcpy(stream, &tmp16, 2); - stream += 2; + tmp16 = HTOBE16(packet->Ethertype); + memcpy(stream, &tmp16, 2); + stream += 2; - tmp8 = (uint8_t) packet->subtype; - *stream = tmp8; - stream++; + tmp8 = (uint8_t) packet->subtype; + *stream = tmp8; + stream++; - tmp8 = (packet->SV << 7) | ((packet->version & 0x07) << 4) | - (packet->message_type & 0x0f); - *stream = tmp8; - stream++; + tmp8 = (packet->SV << 7) | ((packet->version & 0x07) << 4) | + (packet->message_type & 0x0f); + *stream = tmp8; + stream++; - tmp16 = HTOBE16(((packet->maap_version & 0x001f) << 11) | - (packet->control_data_length & 0x07ff)); - memcpy(stream, &tmp16, 2); - stream += 2; + tmp16 = HTOBE16(((packet->maap_version & 0x001f) << 11) | + (packet->control_data_length & 0x07ff)); + memcpy(stream, &tmp16, 2); + stream += 2; - tmp64 = HTOBE64(packet->stream_id); - memcpy(stream, &tmp64, 8); - stream += 8; + tmp64 = HTOBE64(packet->stream_id); + memcpy(stream, &tmp64, 8); + stream += 8; - tmp64 = HTOBE64(packet->requested_start_address << 16); - memcpy(stream, &tmp64, 6); - stream += 6; + tmp64 = HTOBE64(packet->requested_start_address << 16); + memcpy(stream, &tmp64, 6); + stream += 6; - tmp16 = HTOBE16(packet->requested_count); - memcpy(stream, &tmp16, 2); - stream += 2; + tmp16 = HTOBE16(packet->requested_count); + memcpy(stream, &tmp16, 2); + stream += 2; - tmp64 = HTOBE64(packet->conflict_start_address << 16); - memcpy(stream, &tmp64, 6); - stream += 6; + tmp64 = HTOBE64(packet->conflict_start_address << 16); + memcpy(stream, &tmp64, 6); + stream += 6; - tmp16 = HTOBE16(packet->conflict_count); - memcpy(stream, &tmp16, 2); + tmp16 = HTOBE16(packet->conflict_count); + memcpy(stream, &tmp16, 2); - return 0; + return 0; } void init_packet(MAAP_Packet *packet, uint64_t dest_mac, uint64_t src_mac) { - assert(packet); - assert(dest_mac != 0); - assert(src_mac != 0); - - packet->DA = dest_mac; - packet->SA = src_mac; - packet->Ethertype = MAAP_TYPE; - packet->subtype = MAAP_SUBTYPE; - packet->SV = 0; /* SV is 0 - Defined in IEEE 1722-2016 Table F.23 */ - packet->version = 0; /* AVTP version is 0 - Defined in IEEE 1722-2016 4.4.3.4 */ - packet->message_type = 0; - packet->maap_version = 1; /* MAAP version is 1 - Defined in IEEE 1722-2016 B.2.3.1 */ - packet->control_data_length = 16; /* Control data length is 16 - Defined in IEEE 1722-2016 B.2.1 */ - packet->stream_id = 0; /* MAAP stream_id is 0 - Defined in IEEE 1722-2016 B.2.4 */ - packet->requested_start_address = 0; - packet->requested_count = 0; - packet->conflict_start_address = 0; - packet->conflict_count = 0; + assert(packet); + assert(dest_mac != 0); + assert(src_mac != 0); + + packet->DA = dest_mac; + packet->SA = src_mac; + packet->Ethertype = MAAP_TYPE; + packet->subtype = MAAP_SUBTYPE; + packet->SV = 0; /* SV is 0 - Defined in IEEE 1722-2016 Table F.23 */ + packet->version = 0; /* AVTP version is 0 - Defined in IEEE 1722-2016 4.4.3.4 */ + packet->message_type = 0; + packet->maap_version = 1; /* MAAP version is 1 - Defined in IEEE 1722-2016 B.2.3.1 */ + packet->control_data_length = 16; /* Control data length is 16 - Defined in IEEE 1722-2016 B.2.1 */ + packet->stream_id = 0; /* MAAP stream_id is 0 - Defined in IEEE 1722-2016 B.2.4 */ + packet->requested_start_address = 0; + packet->requested_count = 0; + packet->conflict_start_address = 0; + packet->conflict_count = 0; } uint64_t convert_mac_address(const uint8_t macaddr[]) { - uint64_t retVal; + uint64_t retVal; - assert(macaddr); - retVal = BE64TOH(*(uint64_t *)macaddr) >> 16; - return retVal; + assert(macaddr); + retVal = BE64TOH(*(uint64_t *)macaddr) >> 16; + return retVal; } int compare_mac_addresses(uint64_t local_mac, uint64_t remote_mac) { - int i; - uint8_t local_byte, remote_byte; - - for (i = 0; i < 6; ++i) - { - /* Test the next least-significant byte. */ - local_byte = (uint8_t)(local_mac & 0xFF); - remote_byte = (uint8_t)(remote_mac & 0xFF); - - /* See if we have a difference. */ - if (local_byte < remote_byte) return 1; - if (local_byte > remote_byte) return 0; - - /* Try the next lowest-byte in the next iteration. */ - local_mac = local_mac >> 8; - remote_mac = remote_mac >> 8; - } - - /* Assume that our own packet was somehow reflected back at us. - * Return 1 to ignore this packet. */ - return 1; + int i; + uint8_t local_byte, remote_byte; + + for (i = 0; i < 6; ++i) + { + /* Test the next least-significant byte. */ + local_byte = (uint8_t)(local_mac & 0xFF); + remote_byte = (uint8_t)(remote_mac & 0xFF); + + /* See if we have a difference. */ + if (local_byte < remote_byte) return 1; + if (local_byte > remote_byte) return 0; + + /* Try the next lowest-byte in the next iteration. */ + local_mac = local_mac >> 8; + remote_mac = remote_mac >> 8; + } + + /* Assume that our own packet was somehow reflected back at us. + * Return 1 to ignore this packet. */ + return 1; } diff --git a/daemons/maap/common/maap_packet.h b/daemons/maap/common/maap_packet.h index 7ce42943..b1d9095d 100644 --- a/daemons/maap/common/maap_packet.h +++ b/daemons/maap/common/maap_packet.h @@ -44,22 +44,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** MAAP Packet contents - Defined in IEEE 1722-2016 Figure B.1 */ typedef struct { - uint64_t DA; /**< Destination Address */ - uint64_t SA; /**< Source Address */ - uint16_t Ethertype; /**< AVTB Ethertype (i.e. @p MAAP_TYPE) */ - uint16_t subtype; /**< AVTP Subtype (i.e. @p MAAP_SUBTYPE) */ - uint8_t SV; /**< 1 if stream_id is valid, 0 otherwise. Always 0 for MAAP. */ - uint8_t version; /**< AVTP Version. Always 0 for MAAP */ - uint8_t message_type; /**< MAAP message type (MAAP_PROBE, MAAP_DEFEND, or MAAP_ANNOUNCE) */ - uint8_t maap_version; /**< MAAP Version. Currently 1 for MAAP. */ - uint16_t control_data_length; /**< Control Data Length in Bytes. Always 16 for MAAP. */ - uint64_t stream_id; /**< MAAP stream_id. Always 0 for MAAP. */ - uint64_t requested_start_address; /**< Starting address for a MAAP_PROBE or MAAP_ANNOUNCE. + uint64_t DA; /**< Destination Address */ + uint64_t SA; /**< Source Address */ + uint16_t Ethertype; /**< AVTB Ethertype (i.e. @p MAAP_TYPE) */ + uint16_t subtype; /**< AVTP Subtype (i.e. @p MAAP_SUBTYPE) */ + uint8_t SV; /**< 1 if stream_id is valid, 0 otherwise. Always 0 for MAAP. */ + uint8_t version; /**< AVTP Version. Always 0 for MAAP */ + uint8_t message_type; /**< MAAP message type (MAAP_PROBE, MAAP_DEFEND, or MAAP_ANNOUNCE) */ + uint8_t maap_version; /**< MAAP Version. Currently 1 for MAAP. */ + uint16_t control_data_length; /**< Control Data Length in Bytes. Always 16 for MAAP. */ + uint64_t stream_id; /**< MAAP stream_id. Always 0 for MAAP. */ + uint64_t requested_start_address; /**< Starting address for a MAAP_PROBE or MAAP_ANNOUNCE. * For a MAAP_DEFEND, the same address as the MAAP_PROBE or MAAP_ANNOUNCE that initiated the defend. */ - uint16_t requested_count; /**< Number of addresses for a MAAP_PROBE or MAAP_ANNOUNCE. + uint16_t requested_count; /**< Number of addresses for a MAAP_PROBE or MAAP_ANNOUNCE. * For a MAAP_DEFEND, the same number of addresses as the MAAP_PROBE or MAAP_ANNOUNCE that initiated the defend. */ - uint64_t conflict_start_address; /**< For a MAAP_DEFEND, the starting address of the block that conflicts with the MAAP_PROBE or MAAP_ANNOUNCE. */ - uint16_t conflict_count; /**< For a MAAP_DEFEND, the number of addresses in the block that conflicts with the MAAP_PROBE or MAAP_ANNOUNCE. */ + uint64_t conflict_start_address; /**< For a MAAP_DEFEND, the starting address of the block that conflicts with the MAAP_PROBE or MAAP_ANNOUNCE. */ + uint16_t conflict_count; /**< For a MAAP_DEFEND, the number of addresses in the block that conflicts with the MAAP_PROBE or MAAP_ANNOUNCE. */ } MAAP_Packet; /** diff --git a/daemons/maap/common/maap_parse.c b/daemons/maap/common/maap_parse.c index 0c475ca6..0468f0a8 100644 --- a/daemons/maap/common/maap_parse.c +++ b/daemons/maap/common/maap_parse.c @@ -27,6 +27,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdlib.h> #include <string.h> +#if defined(_WIN32) && (_MSC_VER < 1800) +/* Visual Studio 2012 and earlier */ +#define strtoull(x,y,z) _strtoui64(x,y,z) +#endif + #include "maap.h" #include "maap_parse.h" @@ -38,153 +43,153 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. int parse_text_cmd(char *buf, Maap_Cmd *cmd) { - char *argv[5]; - int argc = 0; - char *p; - int set_cmd = 0; - - p = strtok(buf, " \r\n"); - while ((p != NULL) && (argc < sizeof(argv) / sizeof(*argv))) { - argv[argc++] = p; - p = strtok(NULL, " \r\n"); - } - - if (argc >= 1 && argc <= 3) - { - /* Give all parameters default values. */ - cmd->kind = MAAP_CMD_INVALID; - cmd->id = -1; /* N/A */ - cmd->start = 0; /* N/A */ - cmd->count = 0; /* N/A */ - - if (strncmp(argv[0], "init", 4) == 0) { - if (argc == 1) { - cmd->kind = MAAP_CMD_INIT; - cmd->start = MAAP_DYNAMIC_POOL_BASE; - cmd->count = MAAP_DYNAMIC_POOL_SIZE; - set_cmd = 1; - } else if (argc == 3) { - cmd->kind = MAAP_CMD_INIT; - cmd->start = strtoull(argv[1], NULL, 16); - cmd->count = strtoul(argv[2], NULL, 0); - set_cmd = 1; - } - } else if (strncmp(argv[0], "reserve", 7) == 0) { - if (argc == 2) { - cmd->kind = MAAP_CMD_RESERVE; - cmd->count = strtoul(argv[1], NULL, 0); - set_cmd = 1; - } else if (argc == 3) { - cmd->kind = MAAP_CMD_RESERVE; - cmd->start = strtoull(argv[1], NULL, 16); - cmd->count = strtoul(argv[2], NULL, 0); - set_cmd = 1; - } - } else if (strncmp(argv[0], "release", 7) == 0 && argc == 2) { - cmd->kind = MAAP_CMD_RELEASE; - cmd->id = (int)strtoul(argv[1], NULL, 0); - set_cmd = 1; - } else if (strncmp(argv[0], "status", 7) == 0 && argc == 2) { - cmd->kind = MAAP_CMD_STATUS; - cmd->id = (int)strtoul(argv[1], NULL, 0); - set_cmd = 1; - } else if (strncmp(argv[0], "exit", 4) == 0 && argc == 1) { - cmd->kind = MAAP_CMD_EXIT; - set_cmd = 1; - } else { - printf("Invalid command type\n"); - } - } - - if (!set_cmd) - { - printf("input usage:\n"); - printf(" init [<range_base> <range_size>] - Initialize the MAAP daemon to recognize\n" - " the specified range of addresses. If not specified, it uses\n" - " range_base=0x%llx, range_size=0x%04x.\n", MAAP_DYNAMIC_POOL_BASE, MAAP_DYNAMIC_POOL_SIZE); - printf(" reserve [<addr_base>] <addr_size> - Reserve a range of addresses of size\n" - " <addr_size> in the initialized range. If <addr_base> is specified,\n" - " that address base will be attempted first.\n"); - printf(" release <id> - Release the range of addresses with identifier ID\n"); - printf(" status <id> - Get the range of addresses associated with identifier ID\n"); - printf(" exit - Shutdown the MAAP daemon\n\n"); - return 0; - } - - return 1; -} + char *argv[5]; + int argc = 0; + char *p; + int set_cmd = 0; + + p = strtok(buf, " \r\n"); + while ((p != NULL) && (argc < sizeof(argv) / sizeof(*argv))) { + argv[argc++] = p; + p = strtok(NULL, " \r\n"); + } + + if (argc >= 1 && argc <= 3) + { + /* Give all parameters default values. */ + cmd->kind = MAAP_CMD_INVALID; + cmd->id = -1; /* N/A */ + cmd->start = 0; /* N/A */ + cmd->count = 0; /* N/A */ + + if (strncmp(argv[0], "init", 4) == 0) { + if (argc == 1) { + cmd->kind = MAAP_CMD_INIT; + cmd->start = MAAP_DYNAMIC_POOL_BASE; + cmd->count = MAAP_DYNAMIC_POOL_SIZE; + set_cmd = 1; + } else if (argc == 3) { + cmd->kind = MAAP_CMD_INIT; + cmd->start = strtoull(argv[1], NULL, 16); + cmd->count = strtoul(argv[2], NULL, 0); + set_cmd = 1; + } + } else if (strncmp(argv[0], "reserve", 7) == 0) { + if (argc == 2) { + cmd->kind = MAAP_CMD_RESERVE; + cmd->count = strtoul(argv[1], NULL, 0); + set_cmd = 1; + } else if (argc == 3) { + cmd->kind = MAAP_CMD_RESERVE; + cmd->start = strtoull(argv[1], NULL, 16); + cmd->count = strtoul(argv[2], NULL, 0); + set_cmd = 1; + } + } else if (strncmp(argv[0], "release", 7) == 0 && argc == 2) { + cmd->kind = MAAP_CMD_RELEASE; + cmd->id = (int)strtoul(argv[1], NULL, 0); + set_cmd = 1; + } else if (strncmp(argv[0], "status", 7) == 0 && argc == 2) { + cmd->kind = MAAP_CMD_STATUS; + cmd->id = (int)strtoul(argv[1], NULL, 0); + set_cmd = 1; + } else if (strncmp(argv[0], "exit", 4) == 0 && argc == 1) { + cmd->kind = MAAP_CMD_EXIT; + set_cmd = 1; + } else { + printf("Invalid command type\n"); + } + } + + if (!set_cmd) + { + printf("input usage:\n"); + printf(" init [<range_base> <range_size>] - Initialize the MAAP daemon to recognize\n" + " the specified range of addresses. If not specified, it uses\n" + " range_base=0x%llx, range_size=0x%04x.\n", MAAP_DYNAMIC_POOL_BASE, MAAP_DYNAMIC_POOL_SIZE); + printf(" reserve [<addr_base>] <addr_size> - Reserve a range of addresses of size\n" + " <addr_size> in the initialized range. If <addr_base> is specified,\n" + " that address base will be attempted first.\n"); + printf(" release <id> - Release the range of addresses with identifier ID\n"); + printf(" status <id> - Get the range of addresses associated with identifier ID\n"); + printf(" exit - Shutdown the MAAP daemon\n\n"); + return 0; + } + + return 1; + } int parse_write(Maap_Client *mc, const void *sender, char *buf, Maap_Output_Type outputType) { - Maap_Cmd *bufcmd, cmd; - int rv = 0; - int retVal = 0; - - bufcmd = (Maap_Cmd *)buf; - - switch (bufcmd->kind) { - case MAAP_CMD_INIT: - case MAAP_CMD_RESERVE: - case MAAP_CMD_RELEASE: - case MAAP_CMD_STATUS: - case MAAP_CMD_EXIT: - memcpy(&cmd, bufcmd, sizeof (Maap_Cmd)); - rv = 1; - break; - default: - memset(&cmd, 0, sizeof (Maap_Cmd)); - rv = parse_text_cmd(buf, &cmd); - break; - } - - if (rv) { - switch(cmd.kind) { - case MAAP_CMD_INIT: + Maap_Cmd *bufcmd, cmd; + int rv = 0; + int retVal = 0; + + bufcmd = (Maap_Cmd *)buf; + + switch (bufcmd->kind) { + case MAAP_CMD_INIT: + case MAAP_CMD_RESERVE: + case MAAP_CMD_RELEASE: + case MAAP_CMD_STATUS: + case MAAP_CMD_EXIT: + memcpy(&cmd, bufcmd, sizeof (Maap_Cmd)); + rv = 1; + break; + default: + memset(&cmd, 0, sizeof (Maap_Cmd)); + rv = parse_text_cmd(buf, &cmd); + break; + } + + if (rv) { + switch(cmd.kind) { + case MAAP_CMD_INIT: #ifdef DEBUG_CMD_MSG - MAAP_LOGF_DEBUG("Got cmd MAAP_CMD_INIT, range_base: 0x%016llx, range_size: 0x%04x", - (unsigned long long)cmd.start, cmd.count); + MAAP_LOGF_DEBUG("Got cmd MAAP_CMD_INIT, range_base: 0x%016llx, range_size: 0x%04x", + (unsigned long long)cmd.start, cmd.count); #endif - rv = maap_init_client(mc, sender, cmd.start, cmd.count); - break; - case MAAP_CMD_RESERVE: + rv = maap_init_client(mc, sender, cmd.start, cmd.count); + break; + case MAAP_CMD_RESERVE: #ifdef DEBUG_CMD_MSG - if (cmd.start != 0) { - MAAP_LOGF_DEBUG("Got cmd MAAP_CMD_RESERVE, start: 0x%016llx, length: %u", - (unsigned long long)cmd.start, (unsigned) cmd.count); - } else { - MAAP_LOGF_DEBUG("Got cmd MAAP_CMD_RESERVE, length: %u", (unsigned) cmd.count); - } + if (cmd.start != 0) { + MAAP_LOGF_DEBUG("Got cmd MAAP_CMD_RESERVE, start: 0x%016llx, length: %u", + (unsigned long long)cmd.start, (unsigned) cmd.count); + } else { + MAAP_LOGF_DEBUG("Got cmd MAAP_CMD_RESERVE, length: %u", (unsigned) cmd.count); + } #endif - rv = maap_reserve_range(mc, sender, cmd.start, cmd.count); - break; - case MAAP_CMD_RELEASE: + rv = maap_reserve_range(mc, sender, cmd.start, cmd.count); + break; + case MAAP_CMD_RELEASE: #ifdef DEBUG_CMD_MSG - MAAP_LOGF_DEBUG("Got cmd MAAP_CMD_RELEASE, id: %d", (int) cmd.id); + MAAP_LOGF_DEBUG("Got cmd MAAP_CMD_RELEASE, id: %d", (int) cmd.id); #endif - rv = maap_release_range(mc, sender, cmd.id); - break; - case MAAP_CMD_STATUS: + rv = maap_release_range(mc, sender, cmd.id); + break; + case MAAP_CMD_STATUS: #ifdef DEBUG_CMD_MSG - MAAP_LOGF_DEBUG("Got cmd MAAP_CMD_STATUS, id: %d", (int) cmd.id); + MAAP_LOGF_DEBUG("Got cmd MAAP_CMD_STATUS, id: %d", (int) cmd.id); #endif - maap_range_status(mc, sender, cmd.id); - break; - case MAAP_CMD_EXIT: + maap_range_status(mc, sender, cmd.id); + break; + case MAAP_CMD_EXIT: #ifdef DEBUG_CMD_MSG - MAAP_LOG_DEBUG("Got cmd MAAP_CMD_EXIT"); + MAAP_LOG_DEBUG("Got cmd MAAP_CMD_EXIT"); #endif - retVal = 1; /* Indicate that we should exit. */ - break; - default: - if ((outputType & MAAP_OUTPUT_LOGGING)) { - MAAP_LOG_ERROR("Unrecognized input to parse_write"); - } - if ((outputType & MAAP_OUTPUT_USER_FRIENDLY)) { - printf("Unrecognized input to parse_write\n"); - } - rv = 0; - break; - } - } - - return retVal; + retVal = 1; /* Indicate that we should exit. */ + break; + default: + if ((outputType & MAAP_OUTPUT_LOGGING)) { + MAAP_LOG_ERROR("Unrecognized input to parse_write"); + } + if ((outputType & MAAP_OUTPUT_USER_FRIENDLY)) { + printf("Unrecognized input to parse_write\n"); + } + rv = 0; + break; + } + } + + return retVal; } diff --git a/daemons/maap/linux/build/Makefile b/daemons/maap/linux/build/Makefile index bd2d0567..f066defc 100644 --- a/daemons/maap/linux/build/Makefile +++ b/daemons/maap/linux/build/Makefile @@ -2,7 +2,7 @@ COMMON_DIR=../../common LINUX_DIR=../src TEST_DIR=../../test -OPT=-O2 +OPT?=-O2 CFLAGS=$(OPT) -Wall CPPFLAGS=-I$(COMMON_DIR) CC?=gcc diff --git a/daemons/maap/linux/src/maap_daemon.c b/daemons/maap/linux/src/maap_daemon.c index a04153eb..2ebd6f82 100644 --- a/daemons/maap/linux/src/maap_daemon.c +++ b/daemons/maap/linux/src/maap_daemon.c @@ -37,11 +37,13 @@ #include <string.h> #include <stdlib.h> #include <unistd.h> +#include <signal.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> +#include <sys/stat.h> #include <linux/if_ether.h> #include <linux/if_packet.h> @@ -66,6 +68,8 @@ static int init_maap_networking(const char *iface, uint8_t src_mac[ETH_ALEN], uint8_t dest_mac[ETH_ALEN]); static int get_listener_socket(const char *listenport); static int act_as_client(const char *listenport); +static int act_as_server(const char *listenport, char *iface, int daemonize); +static int do_daemonize(void); static const char *version_str = @@ -78,14 +82,14 @@ static void usage(void) fprintf(stderr, "\n" "%s" "\n" - "usage: maap_daemon [-c | [-d] -i interface-name] [-p port_num]" + "usage: maap_daemon [ -c | -i interface-name [-d log_file] ] [-p port_num]" "\n" "options:\n" "\t-c Run as a client (sends commands to the daemon)\n" - "\t-d Run daemon in the background\n" - "\t-i Specify daemon interface to monitor\n" + "\t-i Run as a server monitoring the specified interface\n" + "\t-d Daemonize the server and log to log_file\n" "\t-p Specify the control port to connect to (client) or\n" - "\t listen to (daemon). The default port is " DEFAULT_PORT ".\n" + "\t listen to (server). The default port is " DEFAULT_PORT ".\n" "\n", version_str); exit(1); @@ -104,42 +108,19 @@ static void *get_in_addr(struct sockaddr *sa) int main(int argc, char *argv[]) { - Maap_Client mc; - int c; int as_client = 0, daemonize = 0; char *iface = NULL; char *listenport = NULL; + char *logfile = NULL; int ret; - int socketfd; - uint8_t dest_mac[ETH_ALEN] = MAAP_DEST_MAC; - uint8_t src_mac[ETH_ALEN]; - - int listener; - - int clientfd[MAX_CLIENT_CONNECTIONS]; - int i, nextclientindex; - - fd_set master, read_fds; - int fdmax; - - void *packet_data; - int64_t waittime; - struct timeval tv; - char recvbuffer[1600]; - int recvbytes; - Maap_Cmd recvcmd; - Maap_Notify recvnotify; - uintptr_t notifysocket; - int exit_received = 0; - /* * Parse the arguments */ - while ((c = getopt(argc, argv, "hcdi:p:")) >= 0) + while ((c = getopt(argc, argv, "hcd:i:p:")) >= 0) { switch (c) { @@ -148,14 +129,25 @@ int main(int argc, char *argv[]) break; case 'd': + if (daemonize) + { + fprintf(stderr, "Only one log file per server is supported\n"); + usage(); + if (logfile) + { + free(logfile); + } + } daemonize = 1; + logfile = strdup(optarg); break; case 'i': if (iface) { - fprintf(stderr, "Only one interface per daemon is supported\n"); + fprintf(stderr, "Only one interface per server is supported\n"); usage(); + free(iface); } iface = strdup(optarg); break; @@ -163,8 +155,9 @@ int main(int argc, char *argv[]) case 'p': if (listenport) { - fprintf(stderr, "Only one port per daemon is supported\n"); + fprintf(stderr, "Only one port per server is supported\n"); usage(); + free(listenport); } listenport = strdup(optarg); break; @@ -198,11 +191,14 @@ int main(int argc, char *argv[]) } if (daemonize) { - ret = daemon(1, 0); + ret = do_daemonize(); if (ret) { fprintf(stderr, "Error: Failed to daemonize\n"); return -1; } + open("/dev/null", O_RDONLY); + open("/dev/null", O_WRONLY); + open(logfile, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); } if (listenport == NULL) @@ -211,21 +207,57 @@ int main(int argc, char *argv[]) listenport = strdup(DEFAULT_PORT); } + /* + * Initialize the logging support. + */ + + maapLogInit(); + + if (as_client) { /* Run as a client instead of a server. */ ret = act_as_client(listenport); - free(listenport); - return ret; + } + else + { + ret = act_as_server(listenport, iface, daemonize); } + maapLogExit(); - /* - * Initialize the logging support. - */ + free(listenport); + return ret; +} - maapLogInit(); +/* Local function to server side of network command & control. */ +static int act_as_server(const char *listenport, char *iface, int daemonize) +{ + Maap_Client mc; + + int socketfd; + uint8_t dest_mac[ETH_ALEN] = MAAP_DEST_MAC; + uint8_t src_mac[ETH_ALEN]; + int listener; + + int clientfd[MAX_CLIENT_CONNECTIONS]; + int i, nextclientindex; + + fd_set master, read_fds; + int fdmax; + + void *packet_data; + int64_t waittime; + struct timeval tv; + char recvbuffer[1600]; + int recvbytes; + Maap_Cmd recvcmd; + Maap_Notify recvnotify; + uintptr_t notifysocket; + int exit_received = 0; + + int ret; /* * Initialize the networking support. @@ -242,7 +274,9 @@ int main(int argc, char *argv[]) FD_ZERO(&read_fds); FD_ZERO(&master); - FD_SET(STDIN_FILENO, &master); + if (!daemonize) { + FD_SET(STDIN_FILENO, &master); + } FD_SET(socketfd, &master); fdmax = socketfd; @@ -258,9 +292,6 @@ int main(int argc, char *argv[]) return -1; } - free(listenport); - listenport = NULL; - /* Add the listener to the master set */ FD_SET(listener, &master); @@ -294,7 +325,7 @@ int main(int argc, char *argv[]) * Main event loop */ - printf("Daemon started\n"); + MAAP_LOG_STATUS("Server started"); while (!exit_received) { /* Send any queued packets. */ @@ -442,7 +473,7 @@ int main(int argc, char *argv[]) } /* Handle any commands received via stdin. */ - if (FD_ISSET(STDIN_FILENO, &read_fds)) + if (!daemonize && FD_ISSET(STDIN_FILENO, &read_fds)) { recvbytes = read(STDIN_FILENO, recvbuffer, sizeof(recvbuffer) - 1); if (recvbytes <= 0) @@ -515,6 +546,8 @@ int main(int argc, char *argv[]) maap_deinit_client(&mc); + MAAP_LOG_STATUS("Server stopped"); + maapLogExit(); return (exit_received ? 0 : -1); @@ -592,7 +625,7 @@ static int init_maap_networking(const char *iface, uint8_t src_mac[ETH_ALEN], ui /* Initializes the listener socket, and returns a socket handle for that socket. */ static int get_listener_socket(const char *listenport) { - int listener; + int listener = -1; struct addrinfo hints, *ai, *p; int yes=1; int ret; @@ -629,7 +662,9 @@ static int get_listener_socket(const char *listenport) /* If we got here, it means we didn't get bound */ if (p == NULL) { MAAP_LOGF_ERROR("Socket failed to bind error %d (%s)", errno, strerror(errno)); - close(listener); + if (listener != -1) { + close(listener); + } return -1; } @@ -642,7 +677,6 @@ static int get_listener_socket(const char *listenport) return listener; } - /* Local function to handle client side of network command & control. */ static int act_as_client(const char *listenport) { @@ -658,13 +692,6 @@ static int act_as_client(const char *listenport) Maap_Cmd recvcmd; int exit_received = 0; - /* - * Initialize the logging support. - */ - - maapLogInit(); - - /* Create a localhost socket. */ memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; @@ -678,24 +705,21 @@ static int act_as_client(const char *listenport) for(p = ai; p != NULL; p = p->ai_next) { socketfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); - if (socketfd != -1) { + if (socketfd == -1) { + continue; + } + ret = connect(socketfd, p->ai_addr, p->ai_addrlen); + if (ret == -1) { + close(socketfd); + continue; + } else { break; } } if (p == NULL) { - MAAP_LOGF_ERROR("Socket creation error %d (%s)", errno, strerror(errno)); - freeaddrinfo(ai); - maapLogExit(); - return -1; - } - - /* Connect to the MAAP daemon. */ - if (connect(socketfd, p->ai_addr, p->ai_addrlen) < 0) - { MAAP_LOGF_ERROR("Unable to connect to the daemon, error %d (%s)", errno, strerror(errno)); freeaddrinfo(ai); - close(socketfd); maapLogExit(); return -1; } @@ -816,3 +840,39 @@ static int act_as_client(const char *listenport) return (exit_received ? 0 : -1); } + +static int do_daemonize(void) +{ + int x; + pid_t pid; + + pid = fork(); + if (pid < 0) { + exit(EXIT_FAILURE); + } else if (pid > 0) { + /* Let the controlling terminal know the first fork worked. */ + exit(EXIT_SUCCESS); + } + + /* Make child process session leader */ + if (setsid() < 0) { + exit(EXIT_FAILURE); + } + + signal(SIGCHLD, SIG_IGN); + signal(SIGHUP, SIG_IGN); + + if (fork() != 0) { + exit(EXIT_FAILURE); + } + + umask(0); + x = chdir("/"); + + /* Close all open file descriptors */ + for (x = sysconf(_SC_OPEN_MAX); x>=0; x--) { + close(x); + } + + return 0; +} diff --git a/daemons/maap/linux/src/maap_helper_linux.h b/daemons/maap/linux/src/maap_helper_linux.h index e929be41..e5b3b3d1 100644 --- a/daemons/maap/linux/src/maap_helper_linux.h +++ b/daemons/maap/linux/src/maap_helper_linux.h @@ -49,14 +49,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /// Number of nanoseconds in microsecond #define NANOSECONDS_PER_USEC (1000L) /// Number of microseconds in second -#define MICROSECONDS_PER_SECOND (1000000L) +#define MICROSECONDS_PER_SECOND (1000000L) /// Number of microseconds in millisecond #define MICROSECONDS_PER_MSEC (1000L) -#define SLEEP(sec) sleep(sec) -#define SLEEP_MSEC(mSec) usleep(mSec * 1000) -#define SLEEP_NSEC(nSec) usleep(nSec / 1000) -#define SLEEP_UNTIL_NSEC(nSec) xSleepUntilNSec(nSec) +#define SLEEP(sec) sleep(sec) +#define SLEEP_MSEC(mSec) usleep(mSec * 1000) +#define SLEEP_NSEC(nSec) usleep(nSec / 1000) +#define SLEEP_UNTIL_NSEC(nSec) xSleepUntilNSec(nSec) inline static void xSleepUntilNSec(uint64_t nSec) { struct timespec tmpTime; @@ -65,86 +65,86 @@ inline static void xSleepUntilNSec(uint64_t nSec) clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &tmpTime, NULL); } -#define RAND() random() -#define SRAND(seed) srandom(seed) +#define RAND() random() +#define SRAND(seed) srandom(seed) #define PRAGMA_ALIGN_8 -#define SIGNAL_CALLBACK_SETUP(__NAM, __CB) \ - struct sigaction __NAM; \ +#define SIGNAL_CALLBACK_SETUP(__NAM, __CB) \ + struct sigaction __NAM; \ __NAM.sa_handler = __CB -#define SIGNAL_SIGNAL_SETUP(__SIG, __NAM, __CB, __ERR) \ +#define SIGNAL_SIGNAL_SETUP(__SIG, __NAM, __CB, __ERR) \ sigemptyset(&__NAM.sa_mask); \ - __NAM.sa_flags = 0; \ + __NAM.sa_flags = 0; \ __ERR = sigaction(__SIG, &__NAM, NULL) // the following macros define thread related items -#define THREAD_TYPE(thread) \ +#define THREAD_TYPE(thread) \ typedef struct \ -{ \ +{ \ pthread_t pthread; \ int err; \ } thread##_type; #define THREAD_DEFINITON(thread) \ -thread##_type thread##_ThreadData + thread##_type thread##_ThreadData -#define THREAD_CREATE(threadName, threadhandle, thread_attr_name, thread_function, thread_function_arg) \ +#define THREAD_CREATE(threadName, threadhandle, thread_attr_name, thread_function, thread_function_arg) \ { \ - pthread_attr_t thread_attr; \ + pthread_attr_t thread_attr; \ do { \ threadhandle##_ThreadData.err = pthread_attr_init(&thread_attr); \ if (threadhandle##_ThreadData.err) break; \ threadhandle##_ThreadData.err = pthread_attr_setstacksize(&thread_attr, threadName##_THREAD_STK_SIZE); \ if (threadhandle##_ThreadData.err) break; \ - threadhandle##_ThreadData.err = pthread_create( \ - (pthread_t*)&threadhandle##_ThreadData.pthread, \ - &thread_attr, \ + threadhandle##_ThreadData.err = pthread_create( \ + (pthread_t*)&threadhandle##_ThreadData.pthread, \ + &thread_attr, \ thread_function, \ (void*)thread_function_arg); \ } while (0); \ - pthread_attr_destroy(&thread_attr); \ + pthread_attr_destroy(&thread_attr); \ } -#define THREAD_SET_RT_PRIORITY(threadhandle, priority) \ - { \ - struct sched_param param; \ - param.__sched_priority = priority; \ - pthread_setschedparam(threadhandle##_ThreadData.pthread, SCHED_RR, ¶m); \ +#define THREAD_SET_RT_PRIORITY(threadhandle, priority) \ + { \ + struct sched_param param; \ + param.__sched_priority = priority; \ + pthread_setschedparam(threadhandle##_ThreadData.pthread, SCHED_RR, ¶m); \ } -#define THREAD_PIN(threadhandle, affinity) \ - { \ - cpu_set_t cpuset; \ - int i1; \ - CPU_ZERO(&cpuset); \ - for (i1 = 0; i1 < 32; i1++) { \ - if (affinity & (1 << i1)) CPU_SET(i1, &cpuset); \ - } \ - pthread_setaffinity_np(threadhandle##_ThreadData.pthread, sizeof(cpu_set_t), &cpuset); \ +#define THREAD_PIN(threadhandle, affinity) \ + { \ + cpu_set_t cpuset; \ + int i1; \ + CPU_ZERO(&cpuset); \ + for (i1 = 0; i1 < 32; i1++) { \ + if (affinity & (1 << i1)) CPU_SET(i1, &cpuset); \ + } \ + pthread_setaffinity_np(threadhandle##_ThreadData.pthread, sizeof(cpu_set_t), &cpuset); \ } #define THREAD_CHECK_ERROR(threadhandle, message, error) \ do { \ error=FALSE; \ - if (threadhandle##_ThreadData.err != 0) \ - { \ - MAAP_LOGF_ERROR("Thread error: %s code: %d", message, threadhandle##_ThreadData.err); \ - error=TRUE; \ - break; \ - } \ + if (threadhandle##_ThreadData.err != 0) \ + { \ + MAAP_LOGF_ERROR("Thread error: %s code: %d", message, threadhandle##_ThreadData.err); \ + error=TRUE; \ + break; \ + } \ } while (0) #define THREAD_STARTTHREAD(err) -#define THREAD_KILL(threadhandle, signal) pthread_kill(threadhandle##_ThreadData.pthread, signal) +#define THREAD_KILL(threadhandle, signal) pthread_kill(threadhandle##_ThreadData.pthread, signal) #define THREAD_JOINABLE(threadhandle) -#define THREAD_JOIN(threadhandle, signal) pthread_join(threadhandle##_ThreadData.pthread, (void**)signal) -#define THREAD_SLEEP(threadhandle, secs) sleep(secs) +#define THREAD_JOIN(threadhandle, signal) pthread_join(threadhandle##_ThreadData.pthread, (void**)signal) +#define THREAD_SLEEP(threadhandle, secs) sleep(secs) -#define THREAD_SELF() pthread_self() -#define GET_PID() getpid() +#define THREAD_SELF() pthread_self() +#define GET_PID() getpid() #define SEM_T(sem) sem_t sem; #define SEM_ERR_T(err) int err; @@ -156,20 +156,20 @@ thread##_type thread##_ThreadData #define SEM_IS_ERR_TIMEOUT(err) (ETIMEDOUT == err || ((-1 == err) && (ETIMEDOUT == errno))) #define SEM_LOG_ERR(err) if (0 != err) MAAP_LOGF_ERROR("Semaphore error code: %d", err); -#define MUTEX_ATTR_TYPE_DEFAULT PTHREAD_MUTEX_DEFAULT -#define MUTEX_ATTR_TYPE_RECURSIVE PTHREAD_MUTEX_RECURSIVE +#define MUTEX_ATTR_TYPE_DEFAULT PTHREAD_MUTEX_DEFAULT +#define MUTEX_ATTR_TYPE_RECURSIVE PTHREAD_MUTEX_RECURSIVE #define MUTEX_HANDLE(mutex_handle) pthread_mutex_t mutex_handle #define MUTEX_ATTR_HANDLE(mutex_attr_name) pthread_mutexattr_t mutex_attr_name #define MUTEX_ATTR_CREATE_ERR() static mutex_err #define MUTEX_ATTR_INIT(mutex_attr_name) pthread_mutexattr_init(&mutex_attr_name) -#define MUTEX_ATTR_SET_TYPE(mutex_attr_name,type) pthread_mutexattr_settype(&mutex_attr_name, type) +#define MUTEX_ATTR_SET_TYPE(mutex_attr_name,type) pthread_mutexattr_settype(&mutex_attr_name, type) #define MUTEX_ATTR_SET_NAME(mutex_attr_name, name) #define MUTEX_CREATE_ERR() int mutex_err #define MUTEX_CREATE(mutex_handle,mutex_attr_name) mutex_err=pthread_mutex_init(&mutex_handle, &mutex_attr_name) #define MUTEX_LOCK(mutex_handle) mutex_err=pthread_mutex_lock(&mutex_handle) #define MUTEX_UNLOCK(mutex_handle) mutex_err=pthread_mutex_unlock(&mutex_handle) #define MUTEX_DESTROY(mutex_handle) mutex_err=pthread_mutex_destroy(&mutex_handle) -#define MUTEX_LOG_ERR(message) if (mutex_err) MAAP_LOG_ERROR(message); +#define MUTEX_LOG_ERR(message) if (mutex_err) MAAP_LOG_ERROR(message); #define MUTEX_IS_ERR (mutex_err != 0) // Alternate simplified mutex mapping diff --git a/daemons/maap/linux/src/maap_log_linux.c b/daemons/maap/linux/src/maap_log_linux.c index d8b8e498..2d6f02b3 100644 --- a/daemons/maap/linux/src/maap_log_linux.c +++ b/daemons/maap/linux/src/maap_log_linux.c @@ -403,7 +403,7 @@ void maapLogBuffer( { char szDataLine[ 400 ]; char *pszOut; - int i, j; + size_t i, j; if (level > MAAP_LOG_LEVEL) { return; } diff --git a/daemons/maap/linux/src/maap_timer_linux.c b/daemons/maap/linux/src/maap_timer_linux.c index 227ed1f0..a8d894e2 100644 --- a/daemons/maap/linux/src/maap_timer_linux.c +++ b/daemons/maap/linux/src/maap_timer_linux.c @@ -32,7 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <errno.h> struct maap_timer { - timer_t timer_id; + timer_t timer_id; }; #include "maap_timer.h" @@ -43,39 +43,39 @@ struct maap_timer { Timer *Time_newTimer(void) { - struct sigevent sev; - Timer * newTimer = malloc(sizeof (Timer)); - if (newTimer) - { - sev.sigev_notify = SIGEV_NONE; - sev.sigev_signo = 0; - sev.sigev_value.sival_ptr = NULL; - if (timer_create(CLOCK_MONOTONIC, &sev, &(newTimer->timer_id)) < 0) - { - newTimer->timer_id = (timer_t)(-1); - } - } - return newTimer; + struct sigevent sev; + Timer * newTimer = malloc(sizeof (Timer)); + if (newTimer) + { + sev.sigev_notify = SIGEV_NONE; + sev.sigev_signo = 0; + sev.sigev_value.sival_ptr = NULL; + if (timer_create(CLOCK_MONOTONIC, &sev, &(newTimer->timer_id)) < 0) + { + newTimer->timer_id = (timer_t)(-1); + } + } + return newTimer; } void Time_delTimer(Timer *timer) { - assert(timer); - if (timer && timer->timer_id != (timer_t)(-1)) - { - timer_delete(timer->timer_id); - } - free(timer); + assert(timer); + if (timer && timer->timer_id != (timer_t)(-1)) + { + timer_delete(timer->timer_id); + } + free(timer); } void Time_setTimer(Timer *timer, const Time *t) { - struct itimerspec tspec; - tspec.it_value.tv_sec = t->tv_sec; - tspec.it_value.tv_nsec = t->tv_nsec; - tspec.it_interval.tv_sec = 0; - tspec.it_interval.tv_nsec = 0; - timer_settime(timer->timer_id, TIMER_ABSTIME, &tspec, NULL); + struct itimerspec tspec; + tspec.it_value.tv_sec = t->tv_sec; + tspec.it_value.tv_nsec = t->tv_nsec; + tspec.it_interval.tv_sec = 0; + tspec.it_interval.tv_nsec = 0; + timer_settime(timer->timer_id, TIMER_ABSTIME, &tspec, NULL); } int64_t Time_remaining(Timer *timer) @@ -95,63 +95,63 @@ int64_t Time_remaining(Timer *timer) void Time_add(Time *a, const Time *b) { - a->tv_sec = a->tv_sec + b->tv_sec; - a->tv_nsec = a->tv_nsec + b->tv_nsec; - if (a->tv_nsec > 1000000000L) { - a->tv_sec++; - a->tv_nsec = a->tv_nsec - 1000000000L; - } + a->tv_sec = a->tv_sec + b->tv_sec; + a->tv_nsec = a->tv_nsec + b->tv_nsec; + if (a->tv_nsec > 1000000000L) { + a->tv_sec++; + a->tv_nsec = a->tv_nsec - 1000000000L; + } } int64_t Time_diff(const Time *a, const Time *b) { - int64_t a_ns = (int64_t) a->tv_sec * 1000000000LL + (int64_t) a->tv_nsec; - int64_t b_ns = (int64_t) b->tv_sec * 1000000000LL + (int64_t) b->tv_nsec; - return b_ns - a_ns; + int64_t a_ns = (int64_t) a->tv_sec * 1000000000LL + (int64_t) a->tv_nsec; + int64_t b_ns = (int64_t) b->tv_sec * 1000000000LL + (int64_t) b->tv_nsec; + return b_ns - a_ns; } -int Time_cmp(const Time *a, const Time *b) +int Time_cmp(const Time *a, const Time *b) { - if (a->tv_sec < b->tv_sec) { - return -1; - } - if (a->tv_sec > b->tv_sec) { - return 1; - } - if (a->tv_nsec < b->tv_nsec) { - return -1; - } - if (a->tv_nsec > b->tv_nsec) { - return 1; - } - return 0; + if (a->tv_sec < b->tv_sec) { + return -1; + } + if (a->tv_sec > b->tv_sec) { + return 1; + } + if (a->tv_nsec < b->tv_nsec) { + return -1; + } + if (a->tv_nsec > b->tv_nsec) { + return 1; + } + return 0; } -int Time_passed(const Time *current, const Time *target) +int Time_passed(const Time *current, const Time *target) { - if (current->tv_sec < target->tv_sec) { - return 0; - } - if (current->tv_sec == target->tv_sec && current->tv_nsec < target->tv_nsec) { - return 0; - } - return 1; + if (current->tv_sec < target->tv_sec) { + return 0; + } + if (current->tv_sec == target->tv_sec && current->tv_nsec < target->tv_nsec) { + return 0; + } + return 1; } void Time_setFromNanos(Time *t, uint64_t nsec) { - t->tv_sec = nsec / 1000000000LL; - t->tv_nsec = nsec - t->tv_sec * 1000000000LL; + t->tv_sec = nsec / 1000000000LL; + t->tv_nsec = nsec - t->tv_sec * 1000000000LL; } void Time_setFromMonotonicTimer(Time *t) { - clock_gettime(CLOCK_MONOTONIC, t); + clock_gettime(CLOCK_MONOTONIC, t); } const char * Time_dump(const Time *t) { - static char buffer[40]; - sprintf(buffer, "%lu sec, %09lu nsec", (unsigned long)t->tv_sec, (unsigned long)t->tv_nsec); - return buffer; + static char buffer[40]; + sprintf(buffer, "%lu sec, %09lu nsec", (unsigned long)t->tv_sec, (unsigned long)t->tv_nsec); + return buffer; } diff --git a/daemons/maap/test/maap_log_dummy.c b/daemons/maap/test/maap_log_dummy.c index 6caab3c0..7ac240de 100644 --- a/daemons/maap/test/maap_log_dummy.c +++ b/daemons/maap/test/maap_log_dummy.c @@ -26,7 +26,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdio.h> #include <stdarg.h> #include <string.h> + +#if defined(_WIN32) && (_MSC_VER < 1800) +/* Visual Studio 2012 and earlier */ +typedef unsigned __int8 uint8_t; +typedef unsigned __int32 uint32_t; +#else #include <inttypes.h> +#endif + #include <assert.h> #include "platform.h" diff --git a/daemons/maap/test/maap_test.c b/daemons/maap/test/maap_test.c index 3557c860..28f11daa 100644 --- a/daemons/maap/test/maap_test.c +++ b/daemons/maap/test/maap_test.c @@ -51,255 +51,254 @@ void delay_setup(void); #define MAAP_ANNOUNCE 3 typedef struct maap_packet { - uint64_t DA; - uint64_t SA; - uint16_t Ethertype; - uint16_t subtype; - uint8_t SV; - uint8_t version; - uint8_t message_type; - uint8_t status; - uint16_t control_data_length; - uint64_t stream_id; - uint64_t requested_start_address; - uint16_t requested_count; - uint64_t start_address; - uint16_t count; + uint64_t DA; + uint64_t SA; + uint16_t Ethertype; + uint16_t subtype; + uint8_t SV; + uint8_t version; + uint8_t message_type; + uint8_t status; + uint16_t control_data_length; + uint64_t stream_id; + uint64_t requested_start_address; + uint16_t requested_count; + uint64_t start_address; + uint16_t count; } maap_packet_t; void dump_raw_stream(uint8_t *stream) { - int i; - for (i = 0; i < 42; i++) { - printf("%02x ", stream[i]); - if ((i+1) % 16 == 0) { - printf("\n"); - } - } + int i; + for (i = 0; i < 42; i++) { + printf("%02x ", stream[i]); + if ((i+1) % 16 == 0) { + printf("\n"); + } + } } void dump_packed_packet(maap_packet_t *packet) { - printf("\n\n"); - printf("DA: %012llx\n", (unsigned long long)packet->DA); - printf("SA: %012llx\n", (unsigned long long)packet->SA); - printf("Ethertype: 0x%04x\n", packet->Ethertype); - printf("subtype: 0x%02x\n", packet->subtype); - printf("SV: %d\n", packet->SV); - printf("version: %d\n", packet->version); - printf("message_type: %d\n", packet->message_type); - printf("status: %d\n", packet->status); - printf("control_data_length: %d\n", packet->control_data_length); - printf("stream_id: %016llx\n", (unsigned long long)packet->stream_id); - printf("requested_start_address: %012llx\n", (unsigned long long)packet->requested_start_address); - printf("requested_count: %d\n", packet->requested_count); - printf("start_address: %012llx\n", (unsigned long long)packet->start_address); - printf("count: %d\n", packet->count); + printf("\n\n"); + printf("DA: %012llx\n", (unsigned long long)packet->DA); + printf("SA: %012llx\n", (unsigned long long)packet->SA); + printf("Ethertype: 0x%04x\n", packet->Ethertype); + printf("subtype: 0x%02x\n", packet->subtype); + printf("SV: %d\n", packet->SV); + printf("version: %d\n", packet->version); + printf("message_type: %d\n", packet->message_type); + printf("status: %d\n", packet->status); + printf("control_data_length: %d\n", packet->control_data_length); + printf("stream_id: %016llx\n", (unsigned long long)packet->stream_id); + printf("requested_start_address: %012llx\n", (unsigned long long)packet->requested_start_address); + printf("requested_count: %d\n", packet->requested_count); + printf("start_address: %012llx\n", (unsigned long long)packet->start_address); + printf("count: %d\n", packet->count); } int unpack_maap(maap_packet_t *packet, uint8_t *stream) { - - packet->DA = be64toh(*(uint64_t *)stream) >> 16; - stream += 6; - packet->SA = be64toh(*(uint64_t *)stream) >> 16; - stream += 6; - packet->Ethertype = be16toh(*(uint16_t *)stream); - stream += 2; - packet->subtype = *stream; - stream++; - packet->SV = (*stream & 0x80) >> 7; - packet->version = (*stream & 0x70) >> 4; - packet->message_type = *stream & 0x0f; - stream++; - packet->status = (*stream & 0xf8) >> 3; - packet->control_data_length = be16toh(*(uint16_t *)stream) & 0x07ff; - stream += 2; - packet->stream_id = be64toh(*(uint64_t *)stream); - stream += 8; - packet->requested_start_address = be64toh(*(uint64_t *)stream) >> 16; - stream += 6; - packet->requested_count = be16toh(*(uint16_t *)stream); - stream += 2; - packet->start_address = be64toh(*(uint64_t *)stream) >> 16; - stream += 6; - packet->count = be16toh(*(uint16_t *)stream); - return 0; + packet->DA = be64toh(*(uint64_t *)stream) >> 16; + stream += 6; + packet->SA = be64toh(*(uint64_t *)stream) >> 16; + stream += 6; + packet->Ethertype = be16toh(*(uint16_t *)stream); + stream += 2; + packet->subtype = *stream; + stream++; + packet->SV = (*stream & 0x80) >> 7; + packet->version = (*stream & 0x70) >> 4; + packet->message_type = *stream & 0x0f; + stream++; + packet->status = (*stream & 0xf8) >> 3; + packet->control_data_length = be16toh(*(uint16_t *)stream) & 0x07ff; + stream += 2; + packet->stream_id = be64toh(*(uint64_t *)stream); + stream += 8; + packet->requested_start_address = be64toh(*(uint64_t *)stream) >> 16; + stream += 6; + packet->requested_count = be16toh(*(uint16_t *)stream); + stream += 2; + packet->start_address = be64toh(*(uint64_t *)stream) >> 16; + stream += 6; + packet->count = be16toh(*(uint16_t *)stream); + return 0; } int pack_maap(maap_packet_t *packet, uint8_t *stream) { - *(uint64_t *)stream = htobe64(packet->DA << 16); - stream += 6; - *(uint64_t *)stream = htobe64(packet->SA << 16); - stream += 6; - *(uint16_t *)stream = htobe16(packet->Ethertype); - stream += 2; - *stream = packet->subtype; - stream++; - *stream = (packet->SV << 7) | ((packet->version & 0x07) << 4) | - (packet->message_type & 0x0f); - stream++; - *(uint16_t *)stream = htobe16(((packet->status & 0x001f) << 11) | - (packet->control_data_length & 0x07ff)); - stream += 2; - *(uint64_t *)stream = htobe64(packet->stream_id); - stream += 8; - *(uint64_t *)stream = htobe64(packet->requested_start_address << 16); - stream += 6; - *(uint16_t *)stream = htobe16(packet->requested_count); - stream += 2; - *(uint64_t *)stream = htobe64(packet->start_address << 16); - stream += 6; - *(uint16_t *)stream = htobe16(packet->count); - return 0; + *(uint64_t *)stream = htobe64(packet->DA << 16); + stream += 6; + *(uint64_t *)stream = htobe64(packet->SA << 16); + stream += 6; + *(uint16_t *)stream = htobe16(packet->Ethertype); + stream += 2; + *stream = packet->subtype; + stream++; + *stream = (packet->SV << 7) | ((packet->version & 0x07) << 4) | + (packet->message_type & 0x0f); + stream++; + *(uint16_t *)stream = htobe16(((packet->status & 0x001f) << 11) | + (packet->control_data_length & 0x07ff)); + stream += 2; + *(uint64_t *)stream = htobe64(packet->stream_id); + stream += 8; + *(uint64_t *)stream = htobe64(packet->requested_start_address << 16); + stream += 6; + *(uint16_t *)stream = htobe16(packet->requested_count); + stream += 2; + *(uint64_t *)stream = htobe64(packet->start_address << 16); + stream += 6; + *(uint16_t *)stream = htobe16(packet->count); + return 0; } /* callback for pcap when packets arrive */ void parse_packet(u_char *args, const struct pcap_pkthdr *header, - const u_char *packet); + const u_char *packet); struct maap_test_state { - int (*pkt_handler)(maap_packet_t *); - int state; - int rawsock; - uint64_t hwaddr; + int (*pkt_handler)(maap_packet_t *); + int state; + int rawsock; + uint64_t hwaddr; }; struct maap_test_state test_state = {NULL, 0, 0, 0}; int get_raw_sock(int ethertype) { - int rawsock; + int rawsock; - if((rawsock = socket(PF_PACKET, SOCK_RAW, htons(ethertype))) == -1) { - perror("Error creating raw sock: "); - exit(-1); - } + if((rawsock = socket(PF_PACKET, SOCK_RAW, htons(ethertype))) == -1) { + perror("Error creating raw sock: "); + exit(-1); + } - return rawsock; + return rawsock; } int bind_sock(char *device, int rawsock, int protocol) { - struct sockaddr_ll sll; - struct ifreq ifr; - - bzero(&sll, sizeof(sll)); - bzero(&ifr, sizeof(ifr)); - - /* First, get the interface index */ - strncpy((char *)ifr.ifr_name, device, IFNAMSIZ); - if((ioctl(rawsock, SIOCGIFINDEX, &ifr)) == -1) { - printf("Error getting Interface index !\n"); - printf("Problem interface: %s\n", device); - exit(-1); - } - - /* Bind our raw socket to this interface */ - sll.sll_family = AF_PACKET; - sll.sll_ifindex = ifr.ifr_ifindex; - sll.sll_protocol = htons(protocol); - - /* Get the mac address */ - if ((ioctl(rawsock, SIOCGIFHWADDR, &ifr)) == -1) { - printf("Error getting HW address\n"); - exit(-1); - } - bcopy(ifr.ifr_hwaddr.sa_data, &test_state.hwaddr, 6); - test_state.hwaddr = be64toh(test_state.hwaddr) >> 16; - printf("Our MAC is %012llx\n", (unsigned long long int)test_state.hwaddr); - - if((bind(rawsock, (struct sockaddr*)&sll, sizeof(sll))) == -1) { - perror("Error binding raw socket to interface\n"); - exit(-1); - } - - return 1; + struct sockaddr_ll sll; + struct ifreq ifr; + + bzero(&sll, sizeof(sll)); + bzero(&ifr, sizeof(ifr)); + + /* First, get the interface index */ + strncpy((char *)ifr.ifr_name, device, IFNAMSIZ); + if((ioctl(rawsock, SIOCGIFINDEX, &ifr)) == -1) { + printf("Error getting Interface index !\n"); + printf("Problem interface: %s\n", device); + exit(-1); + } + + /* Bind our raw socket to this interface */ + sll.sll_family = AF_PACKET; + sll.sll_ifindex = ifr.ifr_ifindex; + sll.sll_protocol = htons(protocol); + + /* Get the mac address */ + if ((ioctl(rawsock, SIOCGIFHWADDR, &ifr)) == -1) { + printf("Error getting HW address\n"); + exit(-1); + } + bcopy(ifr.ifr_hwaddr.sa_data, &test_state.hwaddr, 6); + test_state.hwaddr = be64toh(test_state.hwaddr) >> 16; + printf("Our MAC is %012llx\n", (unsigned long long int)test_state.hwaddr); + + if((bind(rawsock, (struct sockaddr*)&sll, sizeof(sll))) == -1) { + perror("Error binding raw socket to interface\n"); + exit(-1); + } + + return 1; } int send_packet(int rawsock, maap_packet_t *mp) { - int sent = 0; - unsigned char pkt[60]; + int sent = 0; + unsigned char pkt[60]; - mp->SA = test_state.hwaddr; + mp->SA = test_state.hwaddr; - pack_maap(mp, pkt); - if((sent = write(rawsock, pkt, 60)) != 60) { - return 0; - } - return 1; + pack_maap(mp, pkt); + if((sent = write(rawsock, pkt, 60)) != 60) { + return 0; + } + return 1; } int main(int argc, char *argv[]) { - char *dev, errbuf[PCAP_ERRBUF_SIZE]; - pcap_t *handle; - struct bpf_program fp; - char filter_exp[] = "ether proto 0x22F0"; - bpf_u_int32 mask; - bpf_u_int32 net; - - if (argc < 2) { - dev = pcap_lookupdev(errbuf); - if (dev == NULL) { - fprintf(stderr, "Couldn't find default device: %s\n", errbuf); - fprintf(stderr, "Try specifying the device you want: %s <device>\n", argv[0]); - return 2; - } - } else { - dev = argv[1]; - } - - if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) { - fprintf(stderr, "Couldn't get netmask for device: %s\n", dev); - net = 0; - mask = 0; - } - - handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf); - if (handle == NULL) { - fprintf(stderr, "Couldn't open device: %s\n", dev); - return 2; - } - - printf("Listening on device: %s\n", dev); - - if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) { - fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, - pcap_geterr(handle)); - return 2; - } - - if (pcap_setfilter(handle, &fp) == -1) { - fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, - pcap_geterr(handle)); - return 2; - } - - test_state.rawsock = get_raw_sock(0x22F0); - bind_sock(dev, test_state.rawsock, 0x22F0); - - test1_setup(); - - pcap_loop(handle, -1, parse_packet, NULL); - - return 0; + char *dev, errbuf[PCAP_ERRBUF_SIZE]; + pcap_t *handle; + struct bpf_program fp; + char filter_exp[] = "ether proto 0x22F0"; + bpf_u_int32 mask; + bpf_u_int32 net; + + if (argc < 2) { + dev = pcap_lookupdev(errbuf); + if (dev == NULL) { + fprintf(stderr, "Couldn't find default device: %s\n", errbuf); + fprintf(stderr, "Try specifying the device you want: %s <device>\n", argv[0]); + return 2; + } + } else { + dev = argv[1]; + } + + if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) { + fprintf(stderr, "Couldn't get netmask for device: %s\n", dev); + net = 0; + mask = 0; + } + + handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf); + if (handle == NULL) { + fprintf(stderr, "Couldn't open device: %s\n", dev); + return 2; + } + + printf("Listening on device: %s\n", dev); + + if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) { + fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, + pcap_geterr(handle)); + return 2; + } + + if (pcap_setfilter(handle, &fp) == -1) { + fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, + pcap_geterr(handle)); + return 2; + } + + test_state.rawsock = get_raw_sock(0x22F0); + bind_sock(dev, test_state.rawsock, 0x22F0); + + test1_setup(); + + pcap_loop(handle, -1, parse_packet, NULL); + + return 0; } -void parse_packet(u_char *args, const struct pcap_pkthdr *header, - const u_char *packet) { - maap_packet_t mp; +void parse_packet(u_char *args, const struct pcap_pkthdr *header, + const u_char *packet) { + maap_packet_t mp; - (void)args; (void)header; + (void)args; (void)header; - unpack_maap(&mp, (uint8_t *)packet); + unpack_maap(&mp, (uint8_t *)packet); - dump_packed_packet(&mp); + dump_packed_packet(&mp); - /* Ignore messages from us */ - if (mp.SA == test_state.hwaddr) { - return; - } + /* Ignore messages from us */ + if (mp.SA == test_state.hwaddr) { + return; + } - if (test_state.pkt_handler) { - test_state.pkt_handler(&mp); - } + if (test_state.pkt_handler) { + test_state.pkt_handler(&mp); + } - return; + return; } /************************************************************************* @@ -314,113 +313,113 @@ void parse_packet(u_char *args, const struct pcap_pkthdr *header, #define WAITING_FOR_3RD_PROBE 2 int test1_handler(maap_packet_t *mp) { - static uint64_t start; - static uint16_t count; + static uint64_t start; + static uint16_t count; - switch (test_state.state) { + switch (test_state.state) { - case WAITING_FOR_1ST_PROBE: + case WAITING_FOR_1ST_PROBE: - /* Make sure we're getting PROBE packets */ - if (mp->message_type != MAAP_PROBE) { - fprintf(stderr, "Test 1: Error: Received a non-probe MAAP packet. Please start the test suite before starting the MAAP client to be tested.\n"); - exit(2); - } - printf("Received a probe from %012llx for %d addresses starting at %012llx\n", - (long long unsigned int)mp->SA, mp->requested_count, - (long long unsigned int)mp->requested_start_address); + /* Make sure we're getting PROBE packets */ + if (mp->message_type != MAAP_PROBE) { + fprintf(stderr, "Test 1: Error: Received a non-probe MAAP packet. Please start the test suite before starting the MAAP client to be tested.\n"); + exit(2); + } + printf("Received a probe from %012llx for %d addresses starting at %012llx\n", + (long long unsigned int)mp->SA, mp->requested_count, + (long long unsigned int)mp->requested_start_address); - /* Store the range from the PROBE so we can conflict with it and compare - later */ - start = mp->requested_start_address; - count = mp->requested_count; + /* Store the range from the PROBE so we can conflict with it and compare + later */ + start = mp->requested_start_address; + count = mp->requested_count; - /* Send a defense of this range */ - mp->DA = mp->SA; - mp->SA = 0; - mp->message_type = MAAP_DEFEND; - mp->start_address = start; - mp->count = count; - send_packet(test_state.rawsock, mp); - printf("Sent defend packet\n"); + /* Send a defense of this range */ + mp->DA = mp->SA; + mp->SA = 0; + mp->message_type = MAAP_DEFEND; + mp->start_address = start; + mp->count = count; + send_packet(test_state.rawsock, mp); + printf("Sent defend packet\n"); - /* Update testing state */ - test_state.state = WAITING_FOR_2ND_PROBE; + /* Update testing state */ + test_state.state = WAITING_FOR_2ND_PROBE; - break; + break; - case WAITING_FOR_2ND_PROBE: + case WAITING_FOR_2ND_PROBE: - /* Make sure we got a probe in response */ - if (mp->message_type != MAAP_PROBE) { - fprintf(stderr, "Test 1: FAIL - Got a non-probe packet, type %d.\n", - mp->message_type); - exit(2); - } + /* Make sure we got a probe in response */ + if (mp->message_type != MAAP_PROBE) { + fprintf(stderr, "Test 1: FAIL - Got a non-probe packet, type %d.\n", + mp->message_type); + exit(2); + } - printf("Received a probe from %012llx for %d addresses starting at %012llx\n", - (long long unsigned int)mp->SA, mp->requested_count, - (long long unsigned int)mp->requested_start_address); + printf("Received a probe from %012llx for %d addresses starting at %012llx\n", + (long long unsigned int)mp->SA, mp->requested_count, + (long long unsigned int)mp->requested_start_address); - /* See if the address range has changed */ - if (mp->requested_start_address == start) { - /* They may have sent before we did; give them one more try */ - mp->DA = mp->SA; - mp->SA = 0; - mp->message_type = MAAP_DEFEND; - mp->start_address = start; - mp->count = count; - send_packet(test_state.rawsock, mp); - printf("Sent another defend packet\n"); + /* See if the address range has changed */ + if (mp->requested_start_address == start) { + /* They may have sent before we did; give them one more try */ + mp->DA = mp->SA; + mp->SA = 0; + mp->message_type = MAAP_DEFEND; + mp->start_address = start; + mp->count = count; + send_packet(test_state.rawsock, mp); + printf("Sent another defend packet\n"); - /* Update testing state */ - test_state.state = WAITING_FOR_3RD_PROBE; + /* Update testing state */ + test_state.state = WAITING_FOR_3RD_PROBE; - } else { + } else { - /* Success! */ - printf("Test 1: PASS\n"); + /* Success! */ + printf("Test 1: PASS\n"); - test2_setup(); + test2_setup(); - } + } - break; + break; - case WAITING_FOR_3RD_PROBE: + case WAITING_FOR_3RD_PROBE: - /* Make sure we got a probe in response */ - if (mp->message_type != MAAP_PROBE) { - fprintf(stderr, "Test 1: FAIL - Got a non-probe packet, type %d.\n", - mp->message_type); - exit(2); - } + /* Make sure we got a probe in response */ + if (mp->message_type != MAAP_PROBE) { + fprintf(stderr, "Test 1: FAIL - Got a non-probe packet, type %d.\n", + mp->message_type); + exit(2); + } - printf("Received a probe from %012llx for %d addresses starting at %012llx\n", - (long long unsigned int)mp->SA, mp->requested_count, - (long long unsigned int)mp->requested_start_address); + printf("Received a probe from %012llx for %d addresses starting at %012llx\n", + (long long unsigned int)mp->SA, mp->requested_count, + (long long unsigned int)mp->requested_start_address); - /* Make sure the address range has changed */ - if (mp->requested_start_address == start) { - fprintf(stderr, "Test 1: FAIL - Got a probe for the same range.\n"); - exit(2); - } + /* Make sure the address range has changed */ + if (mp->requested_start_address == start) { + fprintf(stderr, "Test 1: FAIL - Got a probe for the same range.\n"); + exit(2); + } - /* Success! */ - printf("Test 1: PASS\n"); + /* Success! */ + printf("Test 1: PASS\n"); - test2_setup(); + test2_setup(); - break; - } + break; + } - return 0; + return 0; } void test1_setup(void) { - test_state.state = WAITING_FOR_1ST_PROBE; - test_state.pkt_handler = test1_handler; - printf("Starting test 1: responding to a defend packet while probing\n"); + test_state.state = WAITING_FOR_1ST_PROBE; + test_state.pkt_handler = test1_handler; + printf("Starting test 1: responding to a defend packet while probing\n"); } /* @@ -434,84 +433,84 @@ void test1_setup(void) { #define WAITING_FOR_DEFEND 1 int test2_handler(maap_packet_t *mp) { - static uint64_t start; - static uint16_t count; - - switch (test_state.state) { - - case WAITING_FOR_ANNOUNCE: - if (mp->message_type != MAAP_ANNOUNCE) { - /* Ignore non-announce packets */ - break; - } - printf("Received an announce from %012llx for %d addresses starting at %012llx\n", - (long long unsigned int)mp->SA, mp->requested_count, - (long long unsigned int)mp->requested_start_address); - - /* Store the range from the ANNOUNCE so we can check the defense of this - range */ - start = mp->requested_start_address; - count = mp->requested_count; - - /* Send a probe for this range */ - mp->message_type = MAAP_PROBE; - send_packet(test_state.rawsock, mp); - printf("Sent probe packet\n"); - - /* Update testing state */ - test_state.state = WAITING_FOR_DEFEND; - - break; - - case WAITING_FOR_DEFEND: - if (mp->message_type != MAAP_DEFEND) { - fprintf(stderr, "Test 2: FAIL - Got a non-defend packet, type %d.\n", - mp->message_type); - exit(2); - } - if (mp->requested_start_address != start) { - fprintf(stderr, "Test 2: FAIL - Requested start address wasn't filled out with the value from the probe.\n"); - fprintf(stderr, "Req start address: %012llx Probe address: %012llx\n", - (unsigned long long)mp->requested_start_address, - (unsigned long long)start); - exit(2); - } - if (mp->requested_count != count) { - fprintf(stderr, "Test 2: FAIL - Requested count wasn't filled out with the value from the probe.\n"); - fprintf(stderr, "Requested count: %d Probe count: %d\n", - mp->requested_count, count); - exit(2); - } - if (mp->start_address != start) { - fprintf(stderr, "Test 2: FAIL - Start address wasn't filled out with the first conflicting address from the probe.\n"); - fprintf(stderr, "Start address: %012llx Conflicting address: %012llx\n", - (unsigned long long)mp->start_address, - (unsigned long long)start); - exit(2); - } - if (mp->count != count) { - fprintf(stderr, "Test 2: FAIL - Count wasn't filled out with the number of addresses conflicting with the probe.\n"); - fprintf(stderr, "Defend count: %d Conflicting count: %d\n", mp->count, count); - exit(2); - } - - /* Success! */ - printf("Test 2: PASS\n"); - - test3_setup(); - - break; - - } - - return 0; + static uint64_t start; + static uint16_t count; + + switch (test_state.state) { + + case WAITING_FOR_ANNOUNCE: + if (mp->message_type != MAAP_ANNOUNCE) { + /* Ignore non-announce packets */ + break; + } + printf("Received an announce from %012llx for %d addresses starting at %012llx\n", + (long long unsigned int)mp->SA, mp->requested_count, + (long long unsigned int)mp->requested_start_address); + + /* Store the range from the ANNOUNCE so we can check the defense of this + range */ + start = mp->requested_start_address; + count = mp->requested_count; + + /* Send a probe for this range */ + mp->message_type = MAAP_PROBE; + send_packet(test_state.rawsock, mp); + printf("Sent probe packet\n"); + + /* Update testing state */ + test_state.state = WAITING_FOR_DEFEND; + + break; + + case WAITING_FOR_DEFEND: + if (mp->message_type != MAAP_DEFEND) { + fprintf(stderr, "Test 2: FAIL - Got a non-defend packet, type %d.\n", + mp->message_type); + exit(2); + } + if (mp->requested_start_address != start) { + fprintf(stderr, "Test 2: FAIL - Requested start address wasn't filled out with the value from the probe.\n"); + fprintf(stderr, "Req start address: %012llx Probe address: %012llx\n", + (unsigned long long)mp->requested_start_address, + (unsigned long long)start); + exit(2); + } + if (mp->requested_count != count) { + fprintf(stderr, "Test 2: FAIL - Requested count wasn't filled out with the value from the probe.\n"); + fprintf(stderr, "Requested count: %d Probe count: %d\n", + mp->requested_count, count); + exit(2); + } + if (mp->start_address != start) { + fprintf(stderr, "Test 2: FAIL - Start address wasn't filled out with the first conflicting address from the probe.\n"); + fprintf(stderr, "Start address: %012llx Conflicting address: %012llx\n", + (unsigned long long)mp->start_address, + (unsigned long long)start); + exit(2); + } + if (mp->count != count) { + fprintf(stderr, "Test 2: FAIL - Count wasn't filled out with the number of addresses conflicting with the probe.\n"); + fprintf(stderr, "Defend count: %d Conflicting count: %d\n", mp->count, count); + exit(2); + } + + /* Success! */ + printf("Test 2: PASS\n"); + + test3_setup(); + + break; + + } + + return 0; } void test2_setup(void) { - test_state.state = WAITING_FOR_ANNOUNCE; - test_state.pkt_handler = test2_handler; - printf("Starting test 2: defending a reservation from a probe\n"); - printf("Waiting for an announce packet..."); + test_state.state = WAITING_FOR_ANNOUNCE; + test_state.pkt_handler = test2_handler; + printf("Starting test 2: defending a reservation from a probe\n"); + printf("Waiting for an announce packet..."); } /* @@ -521,129 +520,129 @@ void test2_setup(void) { #define WAITING_FOR_PROBE 2 int test3_handler(maap_packet_t *mp) { - static uint64_t start; - static uint16_t count; - static maap_packet_t saved_announce; - - switch (test_state.state) { - - case WAITING_FOR_ANNOUNCE: - if (mp->message_type != MAAP_ANNOUNCE) { - /* Ignore non-announce packets */ - break; - } - printf("Received an announce from %012llx for %d addresses starting at %012llx\n", - (long long unsigned int)mp->SA, mp->requested_count, - (long long unsigned int)mp->requested_start_address); - - /* Store the range from the ANNOUNCE so we can check the defense of this - range */ - start = mp->requested_start_address; - count = mp->requested_count; - - /* Send an announce for this range (send the same packet right back) */ - send_packet(test_state.rawsock, mp); - printf("Sent announce packet\n"); - - /* Save a copy so we can send it again */ - memcpy(&saved_announce, mp, sizeof (maap_packet_t)); - - /* Update testing state */ - test_state.state = WAITING_FOR_DEFEND; - - break; - - case WAITING_FOR_DEFEND: - if (mp->message_type != MAAP_DEFEND) { - fprintf(stderr, "test 3: FAIL - Got a non-defend packet, type %d.\n", - mp->message_type); - exit(2); - } - if (mp->requested_start_address != start) { - fprintf(stderr, "test 3: FAIL - Requested start address wasn't filled out with the value from the probe.\n"); - fprintf(stderr, "Req start address: %012llx Probe address: %012llx\n", - (unsigned long long)mp->requested_start_address, - (unsigned long long)start); - exit(2); - } - if (mp->requested_count != count) { - fprintf(stderr, "test 3: FAIL - Requested count wasn't filled out with the value from the probe.\n"); - fprintf(stderr, "Requested count: %d Probe count: %d\n", - mp->requested_count, count); - exit(2); - } - if (mp->start_address != start) { - fprintf(stderr, "test 3: FAIL - Start address wasn't filled out with the first conflicting address from the probe.\n"); - fprintf(stderr, "Start address: %012llx Conflicting address: %012llx\n", - (unsigned long long)mp->start_address, - (unsigned long long)start); - exit(2); - } - if (mp->count != count) { - fprintf(stderr, "test 3: FAIL - Count wasn't filled out with the number of addresses conflicting with the probe.\n"); - fprintf(stderr, "Defend count: %d Conflicting count: %d\n", mp->count, count); - exit(2); - } - - /* Send out the same announce again */ - send_packet(test_state.rawsock, &saved_announce); - printf("Sent second announce\n"); - - /* Update testing state */ - test_state.state = WAITING_FOR_PROBE; - - break; - - case WAITING_FOR_PROBE: - /* Make sure we got a probe in response */ - if (mp->message_type != MAAP_PROBE) { - fprintf(stderr, "Test 3: FAIL - Got a non-probe packet, type %d.\n", - mp->message_type); - exit(2); - } - - printf("Received a probe from %012llx for %d addresses starting at %012llx\n", - (long long unsigned int)mp->SA, mp->requested_count, - (long long unsigned int)mp->requested_start_address); - - /* Make sure the address range has changed */ - if (mp->requested_start_address == start) { - fprintf(stderr, "Test 3: FAIL - Got a probe for the same range.\n"); - exit(2); - } - - /* Success! */ - printf("Test 3: PASS\n"); - - delay_setup(); - - break; - - } - - return 0; + static uint64_t start; + static uint16_t count; + static maap_packet_t saved_announce; + + switch (test_state.state) { + + case WAITING_FOR_ANNOUNCE: + if (mp->message_type != MAAP_ANNOUNCE) { + /* Ignore non-announce packets */ + break; + } + printf("Received an announce from %012llx for %d addresses starting at %012llx\n", + (long long unsigned int)mp->SA, mp->requested_count, + (long long unsigned int)mp->requested_start_address); + + /* Store the range from the ANNOUNCE so we can check the defense of this + range */ + start = mp->requested_start_address; + count = mp->requested_count; + + /* Send an announce for this range (send the same packet right back) */ + send_packet(test_state.rawsock, mp); + printf("Sent announce packet\n"); + + /* Save a copy so we can send it again */ + memcpy(&saved_announce, mp, sizeof (maap_packet_t)); + + /* Update testing state */ + test_state.state = WAITING_FOR_DEFEND; + + break; + + case WAITING_FOR_DEFEND: + if (mp->message_type != MAAP_DEFEND) { + fprintf(stderr, "test 3: FAIL - Got a non-defend packet, type %d.\n", + mp->message_type); + exit(2); + } + if (mp->requested_start_address != start) { + fprintf(stderr, "test 3: FAIL - Requested start address wasn't filled out with the value from the probe.\n"); + fprintf(stderr, "Req start address: %012llx Probe address: %012llx\n", + (unsigned long long)mp->requested_start_address, + (unsigned long long)start); + exit(2); + } + if (mp->requested_count != count) { + fprintf(stderr, "test 3: FAIL - Requested count wasn't filled out with the value from the probe.\n"); + fprintf(stderr, "Requested count: %d Probe count: %d\n", + mp->requested_count, count); + exit(2); + } + if (mp->start_address != start) { + fprintf(stderr, "test 3: FAIL - Start address wasn't filled out with the first conflicting address from the probe.\n"); + fprintf(stderr, "Start address: %012llx Conflicting address: %012llx\n", + (unsigned long long)mp->start_address, + (unsigned long long)start); + exit(2); + } + if (mp->count != count) { + fprintf(stderr, "test 3: FAIL - Count wasn't filled out with the number of addresses conflicting with the probe.\n"); + fprintf(stderr, "Defend count: %d Conflicting count: %d\n", mp->count, count); + exit(2); + } + + /* Send out the same announce again */ + send_packet(test_state.rawsock, &saved_announce); + printf("Sent second announce\n"); + + /* Update testing state */ + test_state.state = WAITING_FOR_PROBE; + + break; + + case WAITING_FOR_PROBE: + /* Make sure we got a probe in response */ + if (mp->message_type != MAAP_PROBE) { + fprintf(stderr, "Test 3: FAIL - Got a non-probe packet, type %d.\n", + mp->message_type); + exit(2); + } + + printf("Received a probe from %012llx for %d addresses starting at %012llx\n", + (long long unsigned int)mp->SA, mp->requested_count, + (long long unsigned int)mp->requested_start_address); + + /* Make sure the address range has changed */ + if (mp->requested_start_address == start) { + fprintf(stderr, "Test 3: FAIL - Got a probe for the same range.\n"); + exit(2); + } + + /* Success! */ + printf("Test 3: PASS\n"); + + delay_setup(); + + break; + + } + + return 0; } void test3_setup(void) { - test_state.state = WAITING_FOR_ANNOUNCE; - test_state.pkt_handler = test3_handler; - printf("Starting Test 3: yielding a reservation after 2 announces\n"); - printf("Waiting for an announce packet...\n"); + test_state.state = WAITING_FOR_ANNOUNCE; + test_state.pkt_handler = test3_handler; + printf("Starting Test 3: yielding a reservation after 2 announces\n"); + printf("Waiting for an announce packet...\n"); } int delay_handler(maap_packet_t *mp) { - if (mp->message_type == MAAP_ANNOUNCE) { - test_state.state += 1; - if (test_state.state == 10) { - printf("Received 10 Announce messages.\n"); - test3_setup(); - } - } - return 0; + if (mp->message_type == MAAP_ANNOUNCE) { + test_state.state += 1; + if (test_state.state == 10) { + printf("Received 10 Announce messages.\n"); + test3_setup(); + } + } + return 0; } void delay_setup(void) { - test_state.state = 0; - test_state.pkt_handler = delay_handler; - printf("Waiting for ~5min (10 Announces)\n"); + test_state.state = 0; + test_state.pkt_handler = delay_handler; + printf("Waiting for ~5min (10 Announces)\n"); } diff --git a/daemons/maap/test/maap_timer_dummy.c b/daemons/maap/test/maap_timer_dummy.c index 6081c6c7..243b3265 100644 --- a/daemons/maap/test/maap_timer_dummy.c +++ b/daemons/maap/test/maap_timer_dummy.c @@ -31,8 +31,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "platform.h" struct testtime { - unsigned long sec; - unsigned long nsec; + unsigned long sec; + unsigned long nsec; }; /* Use our local time structure rather than the OS-specific one. */ @@ -43,8 +43,8 @@ struct testtime { struct maap_timer { - int timer_id; - struct testtime expires; + int timer_id; + struct testtime expires; }; static unsigned long long s_basetime = 1000000000LL; @@ -52,114 +52,114 @@ static unsigned long long s_basetime = 1000000000LL; Timer *Time_newTimer(void) { - static int s_new_timer_id = 0; - - Timer *newTimer = malloc(sizeof (Timer)); - if (newTimer) { - newTimer->timer_id = ++s_new_timer_id; - newTimer->expires.sec = newTimer->expires.nsec = 0; - } - return newTimer; + static int s_new_timer_id = 0; + + Timer *newTimer = malloc(sizeof (Timer)); + if (newTimer) { + newTimer->timer_id = ++s_new_timer_id; + newTimer->expires.sec = newTimer->expires.nsec = 0; + } + return newTimer; } void Time_delTimer(Timer *timer) { - assert(timer); - assert(timer->timer_id); - free(timer); + assert(timer); + assert(timer->timer_id); + free(timer); } void Time_setTimer(Timer *timer, const Time *t) { - assert(timer); - assert(timer->timer_id); - assert(t); - timer->expires.sec = t->sec; - timer->expires.nsec = t->nsec; + assert(timer); + assert(timer->timer_id); + assert(t); + timer->expires.sec = t->sec; + timer->expires.nsec = t->nsec; } int64_t Time_remaining(Timer *timer) { - Time timeCurrent; - int64_t timeRemaining; - - assert(timer); - assert(timer->timer_id); - assert(timer->expires.sec || timer->expires.nsec); - Time_setFromMonotonicTimer(&timeCurrent); - timeRemaining = ((int64_t) timer->expires.sec - (int64_t) timeCurrent.sec) * 1000000000LL + ((int64_t) timer->expires.nsec - (int64_t) timeCurrent.nsec); - return (timeRemaining > 0LL ? timeRemaining : 0LL); + Time timeCurrent; + int64_t timeRemaining; + + assert(timer); + assert(timer->timer_id); + assert(timer->expires.sec || timer->expires.nsec); + Time_setFromMonotonicTimer(&timeCurrent); + timeRemaining = ((int64_t) timer->expires.sec - (int64_t) timeCurrent.sec) * 1000000000LL + ((int64_t) timer->expires.nsec - (int64_t) timeCurrent.nsec); + return (timeRemaining > 0LL ? timeRemaining : 0LL); } void Time_add(Time *a, const Time *b) { - a->sec = a->sec + b->sec; - a->nsec = a->nsec + b->nsec; - if (a->nsec > 1000000000L) { - a->sec++; - a->nsec = a->nsec - 1000000000L; - } + a->sec = a->sec + b->sec; + a->nsec = a->nsec + b->nsec; + if (a->nsec > 1000000000L) { + a->sec++; + a->nsec = a->nsec - 1000000000L; + } } int64_t Time_diff(const Time *a, const Time *b) { - int64_t a_ns = (int64_t) a->sec * 1000000000LL + (int64_t) a->nsec; - int64_t b_ns = (int64_t) b->sec * 1000000000LL + (int64_t) b->nsec; - return b_ns - a_ns; + int64_t a_ns = (int64_t) a->sec * 1000000000LL + (int64_t) a->nsec; + int64_t b_ns = (int64_t) b->sec * 1000000000LL + (int64_t) b->nsec; + return b_ns - a_ns; } int Time_cmp(const Time *a, const Time *b) { - if (a->sec < b->sec) { - return -1; - } - if (a->sec > b->sec) { - return 1; - } - if (a->nsec < b->nsec) { - return -1; - } - if (a->nsec > b->nsec) { - return 1; - } - return 0; + if (a->sec < b->sec) { + return -1; + } + if (a->sec > b->sec) { + return 1; + } + if (a->nsec < b->nsec) { + return -1; + } + if (a->nsec > b->nsec) { + return 1; + } + return 0; } int Time_passed(const Time *current, const Time *target) { - if (current->sec < target->sec) { - return 0; - } - if (current->sec == target->sec && current->nsec < target->nsec) { - return 0; - } - return 1; + if (current->sec < target->sec) { + return 0; + } + if (current->sec == target->sec && current->nsec < target->nsec) { + return 0; + } + return 1; } void Time_setFromNanos(Time *t, uint64_t nsec) { - t->sec = (unsigned long) (nsec / 1000000000LL); - t->nsec = (unsigned long) (nsec % 1000000000LL); + t->sec = (unsigned long) (nsec / 1000000000LL); + t->nsec = (unsigned long) (nsec % 1000000000LL); } void Time_setFromMonotonicTimer(Time *t) { - /* Use a hard-wired value. */ - t->sec = (unsigned long) (s_basetime / 1000000000LL); - t->nsec = (unsigned long) (s_basetime % 1000000000LL); + /* Use a hard-wired value. */ + t->sec = (unsigned long) (s_basetime / 1000000000LL); + t->nsec = (unsigned long) (s_basetime % 1000000000LL); } const char * Time_dump(const Time *t) { - static char buffer[40]; - sprintf(buffer, "%lu sec, %09lu nsec", t->sec, t->nsec); - return buffer; + static char buffer[40]; + sprintf(buffer, "%lu sec, %09lu nsec", t->sec, t->nsec); + return buffer; } /* Special function used for testing only. */ void Time_increaseNanos(uint64_t nsec) { - assert(nsec < 60LL * 1000000000LL); - s_basetime += nsec; + assert(nsec < 60LL * 1000000000LL); + s_basetime += nsec; } diff --git a/daemons/maap/test/test_intervals.c b/daemons/maap/test/test_intervals.c index 5ef96c11..f09934cd 100644 --- a/daemons/maap/test/test_intervals.c +++ b/daemons/maap/test/test_intervals.c @@ -42,182 +42,182 @@ uint32_t last_high = 0; int total = 0; void print_node(Interval *node) { - printf("[%d,%d] ", node->low, node->high); - if (node->low <= last_high || - node->high < node->low) { - fprintf(stderr, "\nError: <%d,%d>\n", node->low, node->high); - exit(1); - } - last_high = node->high; - total++; + printf("[%d,%d] ", node->low, node->high); + if (node->low <= last_high || + node->high < node->low) { + fprintf(stderr, "\nError: <%d,%d>\n", node->low, node->high); + exit(1); + } + last_high = node->high; + total++; } int main(void) { - Interval *set = NULL, *inter, *over, *prev; - int i, rv, count; - - srandom((unsigned int) time(NULL)); - - printf("Testing duplicate values\n"); - inter = alloc_interval(1, 10); - rv = insert_interval(&set, inter); - if (rv != INTERVAL_SUCCESS) { - fprintf(stderr, "Error: Insert of [%d,%d] failed unexpectedly\n", inter->low, inter->high); - return 1; /* Error */ - } else { - printf("Inserted [%d,%d]\n", inter->low, inter->high); - } - inter = alloc_interval(1, 10); - rv = insert_interval(&set, inter); - if (rv != INTERVAL_OVERLAP) { - fprintf(stderr, "Error: Insert of [%d,%d] should have failed, but didn't\n", inter->low, inter->high); - return 1; /* Error */ - } else { - printf("Repeat insert of [%d,%d] failed, so the test passed\n", inter->low, inter->high); - } - - while (set) { - inter = remove_interval(&set, set); - free_interval(inter); - } - - count = INTERVALS_TO_ADD; - printf("\nInserting %d random intervals into a set\n", count); - - for (i = 0; i < count;) { - inter = alloc_interval(random() % 0xfffff, random() % 128 + 1); - rv = insert_interval(&set, inter); - if (rv == INTERVAL_OVERLAP) { - over = search_interval(set, inter->low, inter->high - inter->low + 1); - printf("[%d,%d] overlapped existing entry [%d,%d]\n", - inter->low, inter->high, over->low, over->high); - free_interval(inter); - } else { - printf("Inserted [%d,%d]:\n", inter->low, inter->high); - i++; - } - } - - count = INTERVALS_TO_REPLACE; - printf("\nReplacing %d random intervals\n", count); - - for (i = 0, over = NULL; i < count;) { - if (over) { - inter = alloc_interval(random() % 0xfffff, random() % 128 + 1); - rv = insert_interval(&set, inter); - if (rv == INTERVAL_SUCCESS) { - printf("Replaced [%d,%d] with [%d,%d]\n", - over->low, over->high, inter->low, inter->high); - free_interval(over); - over = NULL; - i++; - } else { - printf("Overlapping replacement interval\n"); - free_interval(inter); - } - } else { - over = search_interval(set, random() % 0xfffff, random() % 128 + 1); - if (over) over = remove_interval(&set, over); - } - } - - /* Test that searches always return the first match */ - for (i = 0; i < INTERVALS_TO_SEARCH; i++) { - uint32_t search_base = random() % 0xfffff; - uint32_t search_size = random() % 2048 + 1; - inter = search_interval(set, search_base, search_size); - if (inter && !interval_check_overlap(inter, search_base, search_size)) { - fprintf(stderr, "Error: Search compare failure\n"); - return 1; /* Error */ - } - if (inter && (prev = prev_interval(inter)) != NULL) { - if (prev->high >= search_base) { - fprintf(stderr, "Error: Search lowest item failure\n"); - return 1; /* Error */ - } - if (interval_check_overlap(prev, search_base, search_size)) { - fprintf(stderr, "Error: interval_check_overlap compare failure\n"); - return 1; /* Error */ - } - } - } - printf("\n" "search_interval testing passed\n"); - - /* Test next_interval and search_interval */ - i = 0; - count = INTERVALS_TO_ADD; - inter = minimum_interval(set); - prev = NULL; - while (inter) { - i++; - if (prev && prev->high >= inter->low) { - fprintf(stderr, "Error: Overlapping or out-of-order interval detected\n"); - return 1; /* Error */ - } - if (search_interval(set, inter->low, 1) != inter) { - fprintf(stderr, "Error: Search for interval [%d,%d] failed\n", inter->low, inter->high); - return 1; /* Error */ - } - prev = inter; - inter = next_interval(inter); - } - if (i != count) { - fprintf(stderr, "Error: Found %d intervals during next_interval interation\n", i); - return 1; /* Error */ - } - if (prev != maximum_interval(set)) { - fprintf(stderr, "Error: next_interval iteration didn't end at maximum_interval\n"); - return 1; /* Error */ - } - printf("\n" "next_interval testing passed\n"); - - /* Test previous_interval and search_interval */ - i = 0; - count = INTERVALS_TO_ADD; - inter = maximum_interval(set); - prev = NULL; - while (inter) { - i++; - if (prev && prev->low <= inter->high) { - fprintf(stderr, "Error: Overlapping or out-of-order interval detected\n"); - return 1; /* Error */ - } - if (search_interval(set, inter->high, 1) != inter) { - fprintf(stderr, "Error: Search for interval [%d,%d] failed\n", inter->low, inter->high); - return 1; /* Error */ - } - prev = inter; - inter = prev_interval(inter); - } - if (i != count) { - fprintf(stderr, "Error: Found %d intervals during next_interval interation\n", i); - return 1; /* Error */ - } - if (prev != minimum_interval(set)) { - fprintf(stderr, "Error: prev_interval iteration didn't end at minimum_interval\n"); - return 1; /* Error */ - } - printf("\n" "previous_interval testing passed\n"); - - inter = minimum_interval(set); - printf("\nMinimum Interval: [%d,%d]\n", inter->low, inter->high); - inter = maximum_interval(set); - printf("Maximum Interval: [%d,%d]\n", inter->low, inter->high); - - printf("\nFinal set:\n"); - traverse_interval(set, print_node); - printf("\n\nTotal members: %d\n\n", total); - - if (total != INTERVALS_TO_ADD) { - fprintf(stderr, "Error: Had %d intervals, rather an the expected %d\n", total, INTERVALS_TO_ADD); - return 1; /* Error */ - } - - while (set) { - inter = remove_interval(&set, set); - free_interval(inter); - } - - fprintf(stderr, "Tests passed.\n"); - return 0; + Interval *set = NULL, *inter, *over, *prev; + int i, rv, count; + + srandom((unsigned int) time(NULL)); + + printf("Testing duplicate values\n"); + inter = alloc_interval(1, 10); + rv = insert_interval(&set, inter); + if (rv != INTERVAL_SUCCESS) { + fprintf(stderr, "Error: Insert of [%d,%d] failed unexpectedly\n", inter->low, inter->high); + return 1; /* Error */ + } else { + printf("Inserted [%d,%d]\n", inter->low, inter->high); + } + inter = alloc_interval(1, 10); + rv = insert_interval(&set, inter); + if (rv != INTERVAL_OVERLAP) { + fprintf(stderr, "Error: Insert of [%d,%d] should have failed, but didn't\n", inter->low, inter->high); + return 1; /* Error */ + } else { + printf("Repeat insert of [%d,%d] failed, so the test passed\n", inter->low, inter->high); + } + + while (set) { + inter = remove_interval(&set, set); + free_interval(inter); + } + + count = INTERVALS_TO_ADD; + printf("\nInserting %d random intervals into a set\n", count); + + for (i = 0; i < count;) { + inter = alloc_interval(random() % 0xfffff, random() % 128 + 1); + rv = insert_interval(&set, inter); + if (rv == INTERVAL_OVERLAP) { + over = search_interval(set, inter->low, inter->high - inter->low + 1); + printf("[%d,%d] overlapped existing entry [%d,%d]\n", + inter->low, inter->high, over->low, over->high); + free_interval(inter); + } else { + printf("Inserted [%d,%d]:\n", inter->low, inter->high); + i++; + } + } + + count = INTERVALS_TO_REPLACE; + printf("\nReplacing %d random intervals\n", count); + + for (i = 0, over = NULL; i < count;) { + if (over) { + inter = alloc_interval(random() % 0xfffff, random() % 128 + 1); + rv = insert_interval(&set, inter); + if (rv == INTERVAL_SUCCESS) { + printf("Replaced [%d,%d] with [%d,%d]\n", + over->low, over->high, inter->low, inter->high); + free_interval(over); + over = NULL; + i++; + } else { + printf("Overlapping replacement interval\n"); + free_interval(inter); + } + } else { + over = search_interval(set, random() % 0xfffff, random() % 128 + 1); + if (over) over = remove_interval(&set, over); + } + } + + /* Test that searches always return the first match */ + for (i = 0; i < INTERVALS_TO_SEARCH; i++) { + uint32_t search_base = random() % 0xfffff; + uint32_t search_size = random() % 2048 + 1; + inter = search_interval(set, search_base, search_size); + if (inter && !interval_check_overlap(inter, search_base, search_size)) { + fprintf(stderr, "Error: Search compare failure\n"); + return 1; /* Error */ + } + if (inter && (prev = prev_interval(inter)) != NULL) { + if (prev->high >= search_base) { + fprintf(stderr, "Error: Search lowest item failure\n"); + return 1; /* Error */ + } + if (interval_check_overlap(prev, search_base, search_size)) { + fprintf(stderr, "Error: interval_check_overlap compare failure\n"); + return 1; /* Error */ + } + } + } + printf("\n" "search_interval testing passed\n"); + + /* Test next_interval and search_interval */ + i = 0; + count = INTERVALS_TO_ADD; + inter = minimum_interval(set); + prev = NULL; + while (inter) { + i++; + if (prev && prev->high >= inter->low) { + fprintf(stderr, "Error: Overlapping or out-of-order interval detected\n"); + return 1; /* Error */ + } + if (search_interval(set, inter->low, 1) != inter) { + fprintf(stderr, "Error: Search for interval [%d,%d] failed\n", inter->low, inter->high); + return 1; /* Error */ + } + prev = inter; + inter = next_interval(inter); + } + if (i != count) { + fprintf(stderr, "Error: Found %d intervals during next_interval interation\n", i); + return 1; /* Error */ + } + if (prev != maximum_interval(set)) { + fprintf(stderr, "Error: next_interval iteration didn't end at maximum_interval\n"); + return 1; /* Error */ + } + printf("\n" "next_interval testing passed\n"); + + /* Test previous_interval and search_interval */ + i = 0; + count = INTERVALS_TO_ADD; + inter = maximum_interval(set); + prev = NULL; + while (inter) { + i++; + if (prev && prev->low <= inter->high) { + fprintf(stderr, "Error: Overlapping or out-of-order interval detected\n"); + return 1; /* Error */ + } + if (search_interval(set, inter->high, 1) != inter) { + fprintf(stderr, "Error: Search for interval [%d,%d] failed\n", inter->low, inter->high); + return 1; /* Error */ + } + prev = inter; + inter = prev_interval(inter); + } + if (i != count) { + fprintf(stderr, "Error: Found %d intervals during next_interval interation\n", i); + return 1; /* Error */ + } + if (prev != minimum_interval(set)) { + fprintf(stderr, "Error: prev_interval iteration didn't end at minimum_interval\n"); + return 1; /* Error */ + } + printf("\n" "previous_interval testing passed\n"); + + inter = minimum_interval(set); + printf("\nMinimum Interval: [%d,%d]\n", inter->low, inter->high); + inter = maximum_interval(set); + printf("Maximum Interval: [%d,%d]\n", inter->low, inter->high); + + printf("\nFinal set:\n"); + traverse_interval(set, print_node); + printf("\n\nTotal members: %d\n\n", total); + + if (total != INTERVALS_TO_ADD) { + fprintf(stderr, "Error: Had %d intervals, rather an the expected %d\n", total, INTERVALS_TO_ADD); + return 1; /* Error */ + } + + while (set) { + inter = remove_interval(&set, set); + free_interval(inter); + } + + fprintf(stderr, "Tests passed.\n"); + return 0; } diff --git a/daemons/maap/tests/maap_packet_tests.cpp b/daemons/maap/tests/maap_packet_tests.cpp index 71afbb77..a9104ac5 100644 --- a/daemons/maap/tests/maap_packet_tests.cpp +++ b/daemons/maap/tests/maap_packet_tests.cpp @@ -95,12 +95,12 @@ static void dump_maap_packet(MAAP_Packet *packet) { printf("maap_version: %d\n", packet->maap_version); printf("control_data_length: %d\n", packet->control_data_length); printf("stream_id: 0x%016llx\n", - (unsigned long long int)packet->stream_id); + (unsigned long long int)packet->stream_id); printf("requested_start_address: 0x%012llx\n", - (unsigned long long int)packet->requested_start_address); + (unsigned long long int)packet->requested_start_address); printf("requested_count: %d\n", packet->requested_count); printf("conflict_start_address: 0x%012llx\n", - (unsigned long long int)packet->conflict_start_address); + (unsigned long long int)packet->conflict_start_address); printf("conflict_count: %d\n", packet->conflict_count); } diff --git a/daemons/maap/windows/src/maap_log_windows.c b/daemons/maap/windows/src/maap_log_windows.c index 2fc90bd2..12180a28 100644 --- a/daemons/maap/windows/src/maap_log_windows.c +++ b/daemons/maap/windows/src/maap_log_windows.c @@ -26,7 +26,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdio.h> #include <stdarg.h> #include <string.h> + +#if defined(_WIN32) && (_MSC_VER < 1800) +/* Visual Studio 2012 and earlier */ +typedef __int8 int8_t; +typedef __int16 int16_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +#else #include <inttypes.h> +#endif #include "platform.h" #include "maap_log_queue.h" @@ -36,7 +49,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. typedef struct { uint8_t msg[LOG_QUEUE_MSG_SIZE]; - int bRT; // TRUE = Details are in RT queue + int bRT; // TRUE = Details are in RT queue } log_queue_item_t; typedef struct { @@ -72,7 +85,7 @@ static int loggingThreadRunning = FALSE; DWORD WINAPI loggingThreadFn(LPVOID pv); static HANDLE loggingThread = NULL; -#define THREAD_STACK_SIZE 65536 +#define THREAD_STACK_SIZE 65536 static HANDLE gLogMutex = NULL; #define MUTEX_CREATE_ALT(h) h = CreateMutex(NULL, FALSE, NULL) @@ -83,8 +96,8 @@ static HANDLE gLogMutex = NULL; void maapLogRTRender(log_queue_item_t *pLogItem) { if (logRTQueue) { - pLogItem->msg[0] = 0x00; int bMore = TRUE; + pLogItem->msg[0] = 0x00; while (bMore) { maap_log_queue_elem_t elem = maapLogQueueTailLock(logRTQueue); if (elem) { @@ -167,13 +180,13 @@ uint32_t maapLogGetMsg(uint8_t *pBuf, uint32_t bufSize) DWORD WINAPI loggingThreadFn(LPVOID pv) { while (loggingThreadRunning) { - Sleep(LOG_QUEUE_SLEEP_MSEC); - int more = TRUE; + Sleep(LOG_QUEUE_SLEEP_MSEC); + while (more) { - more = FALSE; maap_log_queue_elem_t elem = maapLogQueueTailLock(logQueue); + more = FALSE; if (elem) { log_queue_item_t *pLogItem = (log_queue_item_t *)maapLogQueueData(elem); @@ -243,7 +256,7 @@ void maapLogFn( vsprintf(msg, fmt, args); if (MAAP_LOG_FILE_INFO && path) { - char* file = strrchr(path, '/'); + const char* file = strrchr(path, '/'); if (!file) file = strrchr(path, '\\'); if (file) @@ -302,9 +315,10 @@ void maapLogRT(int level, int bBegin, int bItem, int bEnd, char *pFormat, log_rt if (level <= MAAP_LOG_LEVEL) { if (logRTQueue) { if (bBegin) { + maap_log_queue_elem_t elem; LOG_LOCK(); - maap_log_queue_elem_t elem = maapLogQueueHeadLock(logRTQueue); + elem = maapLogQueueHeadLock(logRTQueue); if (elem) { log_rt_queue_item_t *pLogRTItem = (log_rt_queue_item_t *)maapLogQueueData(elem); pLogRTItem->bEnd = FALSE; |