Monthly Archives: April 2017

Returning array of C++ wrapped objects to NodeJS and JavaScript using nan

Lately I had a hard time trying to figure out how to properly wrap simple C++ objects (like structs or so) with limited understanding of object-oriented JS. So I took some time (actually not so long, but sill) and found out that there are no classes in JS so constructing objects is quite tricky as it always use prototype function.

Don’t really like the idea, but well…

Anyway, it was not really straightforward at the beginning to wrap C++ object. A bit easier after figuring out all that function for objects creation. It ends up with creating new wrapping object that has a creating function (I have called it “constructor” using the same naming as in the documentation. My objects are read only (in fact it is a representation of serial devices) and all properties are also read only, so I had to create only getters, called accessors:

So the whole “constructor” template function looks like this:

Then for each getter you can create a method (I liked this way) or create one getter and use the name to distinguish return values. For me it looked like this:

So the last thing is to create the JS object from the C++ object and fill the array. First object creation:

When we do have this we just need to create an JavaScript array with nan and v8:

That’s all, final result looks like this in console:

As always you can see the whole code as a commit on the github:

After finally resolving this problems it is time to go on with UART communication and sending some commands to ELM327 😉

Logs panel in Electron and C++ addon

Today I have decided that I need to have a try in merging what I have done in C++ with Electron and JS (and NodeJS) as my prototype lacks currently of any GUI.

The first thing will be most important in my opinion, as I will probably use it later all the time. Let me introduce you logs panel:

It displays all logs messages received from both my addons. Those messages are going to be logged to file (or console) too, but I do like to have them visible in application too for easier debugging.

This is especially important considering that all (or some) of OBD2 communication will be logged here, so I can actually see what is going on with the interface when I try out the buttons without leaving the app window. Later it will be detachable, currently it is enough for me to filter messages by log level.

Actually quite easy to do, the only thing that was important for me was adding jQuery:

Usage is pretty straightforward too:

That’s all for now, next thing might be serial communication 😉

macOS serial devices enumeration and recognition with IOKit

As promised earlier today I will show how serial (or any kind of devices) can be enumerated using IOKit. As currently MacBooks don’t have serial port and most of serial devices are connected using USB or Bluetooth I will also show how can we access informations about what kind of device shares the serial protocol and is visible in /dev.

The easiest way (which I won’t use) is to list tty* devices in dev:

ls /dev/tty*

It is clearly visible that we don’t have a lot of informations about the device, it is limited to the name which may indicate even a disconnected device (for Bluetooth). Also there are virtual devices which are useless for me.

Fortunately Apple has a documentation for serial devices enumeration using IOKit:

So we can create a simple method to enumerate devices:

We enumerate serial devices using flag kIOSerialBSDServiceValue and the device path that we can use is held in kIOCalloutDeviceKey.

I had to create helpers to get string for key and convert to std::string :

This way we do properly have a list of serial devices to connect, but not the information about which connected (or internal) devices are described by the path.

We can see this using ioreg -l  command:

Devices are visible in a tree manner, just like a filesystem directories, and two levels up there is a node of type IOBluetoothSerialClient which has a lot of useful information about the device. The same works for  IOUSBDevice  class.

So we can see that the data is available and seems similar to enumeration we done before. Maybe we can go up level by level using “parent” value and check for this classes?

Indeed we can. In fact there is even a specific function for that:

Which can be used in similar fashion to previous enumeration:

The whole class is available here:

The logger which I use is also part of the project:

That’s all for this post, I hope you will find this useful 😉

Abstracting serial device from an OS layer

Today a bit about serial communication as it will be a base communication layer ELM327 and CAN communication, just like IP is a base layer for TCP/UDP.

Why abstraction though? Application is currently for OS X so this is not really a must have. On the other hand this is how it usually should be done, especially if we consider multiplatform in the future. This is also not a really big change big difference too and makes code a bit cleaner.

So what do we need? Shortly: a common interface and common types for all parameters and return values. I divided it into two parts, may be the same library finally, but can be also easily split in two. Just the matter of preference. It is:

  • Serial devices enumeration and recognition.
  • Serial device access: open, read, write, close with parameters as baud rate, parity control etc.

First thing is a really OS specific thing, but interestingly quite easy to create an interface. I made a decision to support both Bluetooth and USB serial adapters and tested it with:

Enumeration will be explained in next post, now just an interface:

Easy to use, one method that returns a list of SerialDevice objects that describes serial port and parent objects that describes a specific device that handles serial communication: USB. Bluetooth or Other, unknown device type.

For USB and Bluetooth devices I try to get more specific information about name, vendor etc.

Current implementation is here:

Later on I’ve opened the man page for open(): x-man-page://2/open  and made some assumptions for possible errors and parameters:

Man page for open() in Terminal

Next thing, which is currently in progress, is device access and read write. The interface will be much more complicated, as it has to support a lot of open() flags, configuration parameters and errors,

First thing to notice is that we have specific errors in enum, but SerialOpenFlag is a bitmask, so it had to be implemented with consecutive powers of 2: 0x0001, 0x0002, 0x0004, 0x0008… so in a result we might set any bit of the flag without affecting other ones – READ_WRITE and NOBLOCK is for example b’00001100′.

On the other hand the interface cannot be platform specific, so we have to map this later to system specific codes, I decided for it to look like this:

Similar way for error handling for open() operation:

Easy to maintain, easily readable and extendable. Moreover, totally abstract from the OS specific functions 😉

Next post will be about macOS serial devices enumeration and recognition, stay tuned 😉