Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Z-wave protocol with C: Questions about Z-wave frame structure & programming in general

(Before I ask my question; I don't really know if anyone is allowed to answer my question since the Z-wave protocol is supposed to be confidential information, but if it does indeed violate against any kind of regulation then feel free to delete this post.)

I am currently trying to write a C program that simply constructs a Z-wave message consisting of raw binary data and then sends that message to a USB interface where a Z-wave controller is connected (I am using the AEOTEC Z-Stick USB dongle by Aeon Labs). I am also using this guide as a reference and trying to re-write the sample code in plain C. However, if you take a look at the guide, specifically the message he is trying to send to the USB controller:

/*
0x01, 0x09, 0x00, 0x13, nodeId, 0x03, 0x20, 0x01, state, 0x05, checksum
*/

... maybe it's just me but it seems like some information from the usual Z-wave frame is missing. My guess is that the first 4 bytes represent the Home ID followed by the node ID, but I can't make out what the '0x03' means after that, supposing that the rest after that byte represent the "Basic" command class ('0x20', 1 byte) and the corresponding "Set" application command ('0x01', 1 byte). And what does the '0x05' stand for before the checksum bit? And what about the transport header information, why isn't it included? It seems like he didn't need to include it... or maybe I'm just interpreting the packet completely wrong. Can someone enlighten me please?

Also, is it correct that you can only retrieve application-layer information fom the USB port if you read from it (f.ex. with a open() & read() command in C)?

Thank you in advance!

like image 734
Trinity92 Avatar asked Jul 09 '15 13:07

Trinity92


2 Answers

I think you'd save considerable time and effort by studying OpenZWave's source code. This is an open source C++ library for working with ZWave which is quite mature and feature-complete. You could easily use it from plain C.

Part of what you're asking can be seen in the Msg class constructor which constructs the start of frame (0x01), followed by message length (0x09 == 9 bytes), message type (0x00 == REQUEST), and function (FUNC_ID_ZW_SEND_DATA == 0x013), then comes the target nodeID, then comes the actual command body, which I suppose is for a basic command:

./src/Defs.h:#define COMMAND_CLASS_BASIC 0x20:

bool Basic::SetValue
...
            Msg* msg = new Msg( "BasicCmd_Set", GetNodeId(), REQUEST, FUNC_ID_ZW_SEND_DATA, true );
            msg->SetInstance( this, _value.GetID().GetInstance() );
            msg->Append( GetNodeId() );
            msg->Append( 3 );
            msg->Append( GetCommandClassId() );
            msg->Append( BasicCmd_Set );
            msg->Append( value->GetValue() );
            msg->Append( GetDriver()->GetTransmitOptions() );
            GetDriver()->SendMsg( msg, Driver::MsgQueue_Send );
            return true;
    }

    return false;
}
like image 196
ekarak Avatar answered Sep 21 '22 16:09

ekarak


Found what I was looking for. In case anyone is interested, here's what I found after days and days of googling...

Huge compilation of Z-Wave information

A bit further down on that page (directly under the Z-Wave frame description) is a description of the frame structure that is used to communicate directly with the USB controller.

like image 33
Trinity92 Avatar answered Sep 21 '22 16:09

Trinity92