[[TOC(Software/d*, depth=3)]] = Measurements Collection = As introduced in the [wiki:Tutorial/Testbed testbed overview], the '''ORBIT Measurement Framework (OML)''' is a distributed client-server software framework, which enables real-time collection of data from the various applications being executed during an experiment. Figure 1 illustrates this framework. [[Image(OML-overview.png)]] [[BR]] Figure 1. OML Framework [[BR]] On the experimenter's side, the Node Handler starts an instance of the ''OML Collection Server'', which will listen and collect experimental results from the various nodes involved in the experiment. It then archives these data in a SQL database. On each experimental node, the ''OML Collection Client'' interfaces with each experimental applications. It will collect any required measurements or outputs from these applications, optionally apply some filter/processing to these measurements/outputs, and then sends them to the ''OML Server''. The communication from the multiple ''OML Clients'' on all the experimental nodes towards the ''OML Server'' on the experimenter side is currently done over one multicast channel per experiment (for logical segregation of data and for scalability). There are two alternative methods for the user to implement this ''interface'' between their experimental applications and the OML Collection Clients. These two alternative methods are: * '''Method based on dynamic OML client library''' [[BR]] This method is the appropriate one for experimenters who write their own experimental application in C or C++. * '''Method based on OML client daemon''' [[BR]] This method is the appropriate one for experimenters who use existing applciations with no access to their source code, or who develop their own experimental applications in another language than C/C++. [[BR]] '''-- NOTE:''' this method is currently under development, and will be available soon '''--''' [[BR]] [[BR]] == OML Client Dynamic Library == This Interface scheme assumes that the experimenter is developing its own experimental application(s) in C or C++. This method is illustrated in figure 2. [[Image(OML-Library-Method.png)]] [[BR]] Figure 2. Interface Application/OML Client using Dynamic Library [[BR]] Within this scheme, the user defines in a XML format the measurement points and frequencies he/she is interested to collect from his/her application. Optionally, the user can also define some filtering rules to apply on these measurements. Using this XML definition, an ORBIT web service will then automatically generates the source and compiled code for a specific ''OML Measurement API''. This specific API provides application-specific methods that handle type-safe data collection. The user can call these methods within its C/C++ application code, whenever he/she wants to pass on measurement data to the OML collection service. These methods within the ''OML Measurement API'' relies on a set of Dynamic OML Libraries to format these measurement data and forward them to the ''OML Collection Server''. This set of dynamic OML libraries are part of the standard system libraries that are installed on all the ORBIT ''baseline'' disk images. === Example of Interface using OML Client Dynamic Library === * First, the user needs to define in a XML format the measurement points, the frequencies and any optional data filtering for the measurements to collect from the application. This definition is saved as an XML-based configuration file as shown below. {{{ }}} * Then, the user calls the ORBIT Web Service ''OML Generator'' to automatically generate the source and compiled C/C++ code of the ''OML Measurement API'' which corresponds to the above XML definition. The URL of this web service is "http://oml.orbit-lab.org/generator/wrapper" and it can be called using wget as shown below. As a result of this command, the user will get a TAR+GZIP file ''myDef.tgz'', which contains the source/header code and the compiled binary (as a static library) of the ''OML Measurement API''. The source code need not to be used, as the user can directly compile his/her code against the provided static library. {{{ wget -q http://oml.orbit-lab.org/generator/wrapper --post-file MyMeasureDefinition.xml -O myDef.tgz }}} * The generated ''OML Measurement API'' provides two application-specific methods: ''oml_group1()'' and ''oml_group2()''. The user can then call these methods inside his/her application code to pass on collected data to the client side of the OML Collection framework. In this example, the above XML definition will result in generated application-specific methods which will have the following signatures: {{{ int oml_group1(float rssi, float noise); int oml_group2(int throughput); }}} * The following code sample shows an example of the use of these methods within the user's application: {{{ #!ruby // Application Code Sample // // needs to be called only once initialize_oml(&argc, argv, NULL); // ... // 1st point of Measurement Collection if (r_data->send_option == 1) { buffer->rssi = recv_packet_params.rssi ; buffer->noise = recv_packet_params.noise; oml_group1(buffer->rssi, buffer->noise); } else { log(LOG_ERR, "Unknown receive option! \n"); } // ... // 2nd point of Measuremenr Collection lost_packets = pck_id.seqnum - old - 1; oml_group2(lost_packets); // ... }}} * Although the user could execute all the above steps manually, it is more practical to use a custom ''Makefile'' to automatically handle the compilation and linkage of applications. In this case, such a ''Makefile'' can also be used to handle the call to the ORBIT web service which will generate the ''Measurement API''. An example of such ''Makefile'' is given below. A good introduction to Makefile can be found [http://www.gnu.org/software/make/manual/make.html#Introduction here]. {{{ # # Makefile example for Interface Application/OML Client via Dynamic Library # # In the Makefile, note that the autogenerated filenames include the application id (foo) # from the xml file above. Also note how we use the include and lib directories in # CFLAGS and LDFLAGS and then link to the oml_client and the client_api libs in LIBS # variable. The oml_client library is installed on the gateway machine and is part of # the baseline image. # APP = foo CC = gcc CFLAGS = -g -Wall -I./include LDFLAGS = -L./lib/i386-linux LIBS = -loml_client -loml_$(APP) SRCS = app.c app: $(SRCS) oml_$(APP).h $(CC) -o app $(CFLAGS) $(SRCS) $(LDFLAGS) $(LIBS) oml_$(APP).h: $(APP)-def.xml wget -q http://oml.orbit-lab.org/generator/wrapper --post-file $< -O -\ | tar -xzf - }}} === More on Interface Application/OML Client using Dynamic Library === * Sometimes, an experimenter does not require all measurement samples for a given metric, or he/she require some higher level information (e.g. average, min/max, etc...). '''OML''' supports measurement pre-processing or filtering at source to reduce the amount of reported and recorded data. These filters are specified by experimenter within the ''prototype'' of their application. ''Prototypes'' were first introduced in the [wiki:Tutorial/HelloWorld previous part] of this tutorial, and an example on using them is given [wiki:HowTo/LaunchApp here]. Figure 3 illustrates the client-side data flow with filters. [[Image(clientsidedataflow.PNG)]] [[BR]]Figure 3. Client-side Data Flow with Filters. * On the ''OML Collection Server'' side, the XML definition presented in the first steps above will be used to generate a database schema as illustrated in figure 4 below. [[Image(serversideschema.PNG)]] [[BR]]Figure 4. Server-side Database Schema Generation. [[BR]] [[BR]] == OML Client Daemon == This method is the appropriate one for experimenters who use existing applciations with no access to their source code, or who develop their own experimental applications in another language than C/C++. [[BR]] '''-- NOTE:''' this method is currently under development, and will be available soon '''---''' [[BR]] [[BR]]