Tuesday, January 17, 2017

Mask Calculator

Tuesday, December 20, 2016

Centos 7 Install Realtime kernel using yum

Wanted to try out an rt kernel for my asterisk box. One option is to build a patched kernel.. The other option I am trying out now is to install using the Cern repo. I am using a plain Centos 7 installation and not the Cern version. At the time of writing this I had to install an older version of tuned in order to successfully finish the process:
yum install http://ftp.ntua.gr/mirror/centos/7.2.1511/updates/x86_64/Packages/tuned-2.5.1-4.el7_2.6.noarch.rpm
Install the repo in /etc/yum.repos.d/Centos-RT.repo:
name=CentOS-$releasever - RealTime
Finally yum groupinstall RT should install the rt kernel. Reboot to use. I am currently trying it on a VM and so far no issues.

Some initial tests:

RT Version (VM):
chrt -f 99 ./cyclictest -t1 -p 80 -i 10000 -n -l 100000
# /dev/cpu_dma_latency set to 0us
policy: fifo: loadavg: 0.12 0.16 0.10 1/120 10969

T: 0 (10960) P:80 I:10000 C:  16390 Min:      6 Act:   20 Avg:   70 Max:   12866

hdparm -t /dev/sda2
Timing buffered disk reads: 976 MB in  3.07 seconds = 317.71 MB/sec

Normal Version (VM):
chrt -f 99 ./cyclictest -t1 -p 80 -i 10000 -n -l 100000
# /dev/cpu_dma_latency set to 0us
policy: fifo: loadavg: 0.95 0.37 0.14 1/108 10165

T: 0 ( 8828) P:80 I:10000 C:   4838 Min:      5 Act:  413 Avg:  210 Max:    7676

hdparm -t /dev/sda2
Timing buffered disk reads: 1014 MB in  3.01 seconds = 336.37 MB/sec

After repeating the VM tests, I concluded that the VM is not the proper way to test. I will try it on real hardware later and post the results.

Normal Version (E5140 - 2 Cores):
chrt -f 99 ./cyclictest -t1 -p 80 -i 10000 -n -l 100000
# /dev/cpu_dma_latency set to 0us
policy: fifo: loadavg: 0.10 0.04 0.05 1/332 9408

T: 0 ( 9339) P:80 I:10000 C:   6901 Min:      3 Act:    3 Avg:    6 Max:    4503
hdparm -t /dev/sda2
Timing buffered disk reads: 526 MB in  3.01 seconds = 175.04 MB/sec

Tuesday, August 2, 2016

Alcatel OneTouch L850V

This dongle is recognized out of the box under Centos 7. You get a usbX device. You need to run a dhcp client on the device or there is the option to set an address 192.168.2.[2-254] cause the dongle WUI has There is a hidden menu to access and disable the dhcpd server  on the dongle so that you won't need to use dhcp client hooks to avoid your rooting table and dns settings getting changed.


Tuesday, February 9, 2016

Compile deluged in Centos 7 x86_64

In a proper build environment:

yum install boost-devel libgeoip

Get the latest libtorrent (1.0.8 at the time). To build it use b2. I had problems with autotools.

cd /usr/local/src/
mkdir deluge
cd deluge
wget https://github.com/arvidn/libtorrent/releases/download/libtorrent-1_0_8/libtorrent-rasterbar-1.0.8.tar.gz
tar -xvf  libtorrent-rasterbar-1.0.8.tar.gz
cd  libtorrent-rasterbar-1.0.8

#build libtorrent
b2 toolset=gcc link=shared variant=release target-os=linux address-model=64 geoip=shared
 # produces  bin/gcc-4.8.5/release/address-model-64/boost-link-shared/libtorrent-python-pic-on/threading-multi/visibility-hidden/libtorrent.so.1.0.8

cp bin/gcc-4.8.5/release/address-model-64/boost-link-shared/libtorrent-python-pic-on/threading-multi/visibility-hidden/libtorrent.so.1.0.8 /usr/local/lib

cd bindings/python/

#build python bindings
b2 toolset=gcc link=shared variant=release target-os=linux address-model=64 libtorrent-link=shared

# produces: bin/gcc-4.8.5/release/address-model-64/libtorrent-python-pic-on/visibility-hidden/libtorrent.so

# we need to set the this otherwise deluge setup will try to build libtorrent in a way that does not work


cd /usr/local/src/deluge/
wget http://download.deluge-torrent.org/source/deluge-1.3.12.tar.bz2 # or get from git or whatever
 tar -xvf deluge-1.3.12.tar.bz2

cd deluge-1.3.12
ln -s  /usr/local/src/delug/libtorrent-rasterbar-1.0.8 libtorrent

python setup.py build
python setup.py install # or bdist if you wise and did that in a virtual environmentli etc

You need to copy libtorrent python binding somewhere (like under deluge in /usr/lib/python/site-packages/deluge-1.3.12/deluge) or set the PYTHONPATH in order for the module to be found in runtime.

Friday, May 1, 2015

Cygwin/X forwarding issues after upgrade

A quick note if you are using Cygwin/X with putty or an ssh client not running within the cygwin environment:

Since X server 1.17, by default the server does not listen for TCP/IP connections, only accepting local connections on a unix domain socket.

That's from the FAQ.

A solution is to create a shortcut to Xwin.exe (located in the bin directory of cygwin installation path) either to the desktop or task bar and edit the Target in the shortcut's properties to:

C:\cygwin64\bin\XWin.exe -multiwindow -listen tcp -silent-dup-error

The listen option is the one that resolves errors like "Cannot open display XX:0".

There is also a script which sets up more stuff, check the FAQ above.

Monday, March 9, 2015

Multicast communication between Arduino (Ethernet library W5100) and a Java application

Multicast is not supported by the Arduino Ethernet library but is supported by the underlying W5100 module. So to start off, this patch should be applied to the library (usually located in the arduino IDE directory under libraries\Ethernet\src).

Note that you may want to update the IP ranges below, I have used the network for my tests and multicast group.

Here is a modified version of the UDPSendReceive example:
 This sketch receives Multicast UDP message strings, prints them to the serial port
 and sends an "acknowledge" string back to the group.

 created 21 Aug 2010
 by Michael Margolis
 modified 09 Mar 2015
 by Panos Gkikakis

 This code is in the public domain.

#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED

// Arduino's IP
IPAddress ip(192, 168, 100, 177);

// Multicast group IP
IPAddress mip(239, 100, 100, 100);

// Port 
unsigned int localPort = 9999;      // local port to listen on

// buffers for receiving and sending data
char packetBuffer[50]; //buffer to hold incoming packet,
char  ReplyBuffer[] = "acknowledged";       // a string to send back
char  hiBuffer[] = "0:Client ready";       // a string to send back

int c = 0;
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

void setup() {
  // start the Ethernet and UDP:
  Ethernet.begin(mac, ip);
  Udp.beginMulti(mip, localPort);


void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  int n = 0;
  if (packetSize)
    Serial.print("Received packet of size ");
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i = 0; i < 4; i++)
      Serial.print(remote[i], DEC);
      if (i < 3)
    Serial.print(", port ");

    // read the packet into packetBufffer
    n = Udp.read(packetBuffer, 50);
    packetBuffer[n] = 0;
    // send a reply, to the IP address and port that sent us the packet we received
    Udp.beginPacket(mip, Udp.remotePort());
    Udp.write(ReplyBuffer, sizeof(ReplyBuffer));
  if( c == 0 ) {
    hiBuffer[0] = (hiBuffer[0] > 56) ?  48 : (hiBuffer[0] + 1);
    Udp.beginPacket(mip, localPort);
    Udp.write(hiBuffer, sizeof(hiBuffer));
  } else if( c > 600) {
    c = -1;

And here is a corresponding "server" written in java (MLTestServer.java):

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MulticastSocket;
import java.net.InetAddress;
import java.net.DatagramPacket;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.concurrent.atomic.AtomicReference;

public class MLTestServer {

 public static void main(String[] args)  {
  String msg = "Server online. Keep 'em coming!\0";
  String myIP = "";
  String multiAddress = "";
  int port = 9999;
  byte[] buf = new byte[100];  
  ConsoleReader cr = new ConsoleReader();
  String ack = "acknowledged";
  try {
   new Thread(cr).start();
   InetAddress group = InetAddress.getByName(multiAddress);

   // Q: Why use two sockets one for sending and one for receiving?
   // A: There are issues when sending and receiving, namely some messages were not received. If you know why or if that's expected behavior pls let me know.   
   // Q: Why use the long version of MulticastSocket constructor and joinGroup?
   // A: We need to specify the Network interface to get reliable results on  multihomed hosts. 
   MulticastSocket s = new MulticastSocket(new InetSocketAddress(InetAddress.getByName(myIP),port));
   MulticastSocket r = new MulticastSocket(new InetSocketAddress(InetAddress.getByName(myIP),port));

   s.joinGroup(new InetSocketAddress(group,port), NetworkInterface.getByInetAddress(InetAddress.getByName(myIP)));
   r.joinGroup(new InetSocketAddress(group,port), NetworkInterface.getByInetAddress(InetAddress.getByName(myIP)));
   // say hello
   DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(),group, port);
   System.out.println("Started server: IP " + s.getLocalAddress() + " port " + s.getLocalPort());
   System.out.println("\tMulticast: " + group.getAddress() + " port " + port);

   DatagramPacket recv = new DatagramPacket(buf, buf.length);
   // server loop
   while(!ConsoleReader.exit) {
    try { 
     java.util.Arrays.fill(buf, (byte) 0);
    } catch(SocketTimeoutException te) {
     msg = cr.send.get();    
     if(msg != null && (msg.length() > 0)) {
      System.out.println("Sending: " + '"' + msg + '"');
      hi = new DatagramPacket(msg.getBytes(), msg.length(),group, port);
    msg = new String(recv.getData());
    System.out.println("Message from: " + recv.getAddress() + ":" + recv.getPort() +  ":\n" + msg);  
  } catch (Exception e) {
   // TODO Auto-generated catch block


// thread to read console input 
class ConsoleReader implements Runnable {

 public static boolean exit = false;
 public AtomicReference<String> send = new AtomicReference<String>();
 public void run() {
  String cmd;
  BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
  System.out.println("Commands:\t\nsend msg: sends a message (msg) to clients\t\nexit : end program");
  while(true) {
   try {
    cmd = console.readLine();
    if(cmd.compareToIgnoreCase("exit") == 0) {
    } else if (cmd.toLowerCase().startsWith("send ")) {
     this.send.set(cmd.substring(5) + "\0");
    } else {
     System.out.println("Unknown command");
   } catch (IOException e) {
    // TODO Auto-generated catch block
  ConsoleReader.exit = true;


 The code should be self explanatory, I have included comments for some gotchas. To compile the  java code simply run:

javac MLTestServer.java

java -cp . MLTestServer

assuming off course javac and java is in the PATH.

Tuesday, March 3, 2015

Openldap 2.4 on Centos 7 using mdb

A bit confusing to set up especially for people used to the older slapd.conf. This is not used, do not try to set it, it will be ignored.

My setup uses the new back-end mdb.

The very basics is to install the server and client libraries (yum install openldap openldap-clients)

Configuration is stored under /etc/openldap/slapd.d/. You can view the contents but do not edit the files directly.

Remove the default configuration rm -rf /etc/openldap/slapd.d/*

Create a file for the initial configuration, let's say main.ldif:

#global configuration
dn: cn=config
objectClass: olcGlobal
cn: config
olcArgsFile: /var/run/openldap/slapd.args
olcPidFile: /var/run/openldap/slapd.pid
olcTLSCACertificatePath: /etc/openldap/certs
olcTLSCertificateFile: "OpenLDAP Server"
olcTLSCertificateKeyFile: /etc/openldap/certs/password
structuralObjectClass: olcGlobal
entryUUID: 0ca4a796-53e8-1034-90ac-5fa43e938d62
creatorsName: cn=config
createTimestamp: 20150228225117Z
entryCSN: 20150228225117.358858Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20150228225117Z

# Load the mdb backend
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulepath: /usr/lib64/openldap
olcModuleload: back_mdb

# Load external definitions
dn: cn=schema,cn=config
objectClass: olcSchemaConfig
cn: schema

# You may want to add more, make sure to satisfy any dependencies though
include: file:///etc/openldap/schema/core.ldif
include: file:///etc/openldap/schema/cosine.ldif
include: file:///etc/openldap/schema/nis.ldif
include: file:///etc/openldap/schema/inetorgperson.ldif
include: file:///etc/openldap/schema/openldap.ldif

# front end db
dn: olcDatabase=frontend,cn=config
objectClass: olcDatabaseConfig
objectClass: olcFrontendConfig
olcDatabase: frontend
olcAccess: to * by * read
olcSizelimit: size.soft=10000 size.hard=1000000
olcTimelimit: time.soft=300 time.hard=3600

# configuration db, we define a separate RootDN and passwd, use this one to change the config
dn: olcDatabase=config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: config
olcRootDN: cn=Manager,cn=config
# generate a password by running slappasswd
olcMonitoring: FALSE
olcAccess: to * by * none
dn: olcDatabase=monitor,cn=config
objectClass: olcDatabaseConfig
olcDatabase: monitor
olcAddContentAcl: FALSE
olcLastMod: TRUE
olcMaxDerefDepth: 15
olcReadOnly: FALSE
olcSyncUseSubentry: FALSE
olcMonitoring: FALSE
olcAccess: to dn.subtree="cn=monitor"
  by dn.exact="cn=Manager,cn=config" read
  by dn.exact="cn=Manager,dc=example,dc=com" read
  by * none
dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: mdb
olcMonitoring: TRUE
olcDbMaxSize: 42949672960
olcSuffix: dc=example,dc=com
olcDbDirectory: /var/lib/ldap
olcRootDN: cn=Manager,dc=example,dc=com
# generate a password by running slappasswd
olcDbIndex: uid pres,eq
olcDbIndex: cn,sn pres,eq,approx,sub
olcDbIndex: mail pres,eq,sub
olcDbIndex: objectClass pres,eq
olcDbIndex: loginShell pres,eq

# Tuning, not sure what these do maybe test them
#olcDbConfig: set_cachesize 0 2097152 0
#olcDbConfig: set_lk_max_objects 1500
#olcDbConfig: set_lk_max_locks 1500
#olcDbConfig: set_lk_max_lockers 1500
#olcLastMod: TRUE
#olcMonitoring: TRUE
#olcDbCheckpoint: 512 30
olcAccess: to attrs=userPassword
   by self write
   by anonymous auth
   by dn.base="cn=Manager,dc=example,dc=com" write
   by * none
olcAccess: to attrs=shadowLastChange
   by self write
   by * read
olcAccess: to *
   by dn.exact="cn=Manager,dc=example,dc=com" write
   by * read
Now add it to the configuration:

cat main.ldif | slapadd -v -F /etc/openldap/slapd.d -n 0

Start the server:

systemctl start slapd

Add a root object:

ldapadd -h localhost -D "cn=Manager,dc=example,dc=com" -w YOURPASSWORDHERE <<EOF
dn: dc=example,dc=com
objectClass: dcobject
o: Your organization's name

You should now install phpldapadmin or a client of your liking to add more data. A note for phpldapadmin, if you want to connect as the manager you should edit the configuration (/usr/share/phpldapadmin/config/config.php) and make sure


is set. The default seems to be 'uid' which does not work with our manager definition.

To add to the configuration, for instance to define a custom object, attributes and so on you should use an LDAP client,  with the base dn cn=config and the user/pass combination specified for the config database, in our example user name is  cn=Manager,cn=config.

Useful links (somewhat contradicted info though):
  1. http://www.server-world.info/en/note?os=CentOS_7&p=openldap 
  2. http://www.nies.ch/doc/openldap-replication.en.php 
  3. Fixes for the OpenLDAP example config and deployment tips
  4. Admin Guide (clearly not uptodate, still useful though)