Echelon OpenLDV User Manual

OpenLDV Programmer’s Guide
078-0275-01D
Echelon, i.LON, LonMaker, LONMAR K, LonTalk, LONWORKS, LNS, Neuron, NodeBuilder, 3120, 3150, and the Echelon logo are trademarks of Echelon Corporation registered in the United States and other countries. LonScanner and OpenLDV are trademarks of the Echelon Corporation.
Smart Transceivers, Neuron Chips, and other OEM Products were not designed for use in equipment or systems, which involve danger to human health or safety, or a risk of property damage and Echelon assumes no responsibility or liability for use of the Smart Transceivers or Neuron Chips in such applications.
Parts manufactured by vendors other than Echelon and referenced in this document have been described for illustrative purposes only, and may not have been tested by Echelon. It is the responsibility of the customer to determine the suitability of these parts for each application.
ECHELON MAKES AND YOU RECEIVE NO WARRANTIES OR CONDITIONS, EXPRESS, IMPLIED, STATUTORY OR IN ANY COMMUNICATION WITH YOU, AND ECHELON SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior written permission of Echelon Corporation.
Printed in the United States of America. Copyright © 2004, 2011 Echelon Corporation.
Echelon Corporation
www.echelon.com

Welcome

This document describes Echelon’s OpenLDV™ Release 4.0 Network Driver and Software Development Kit (SDK). The OpenLDV driver is an open driver for Microsoft send and receive low-level ISO/IEC 14908-1 messages through compatible Echelon and third-party network interfaces. The OpenLDV SDK provides example source code that demonstrates how to use the OpenLDV driver. Supported network interfaces include local network interfaces (such as the Echelon U10 or U20 USB Network Interface, PCC-10 PC Card, PCLTA-21 PC LonTalk Echelon SmartServer and i.LON
The OpenLDV driver includes an extensible remote network interface (RNI) component, called xDriver. The OpenLDV driver uses xDriver to connect an OpenLDV application, such as an LNS This document describes how to configure and extend xDriver, including descriptions of the software tools that you use to configure and extend xDriver, and provides programming samples.
The OpenLDV SDK provides a low-level application programming interface (API) for network applications. For most L Echelon’s LNS Network Operating System software provides an interface to the OpenLDV driver that is easier to use and that significantly reduces the time required to develop L Network tools that use LNS software generally have much higher performance than those that use only the OpenLDV API. You can find out more about LNS software on Echelon’s Web site at www.echelon.com/lns at www.echelon.com/sales if you would like assistance in determining whether you should develop your network tools with LNS software or with the OpenLDV API.
®
Windows® operating systems that enables Windows applications to
®
Adapter), and Internet-enabled network interfaces (such as the
ONWORKS applications and tools for Windows environments.
®
600 IP-852 Router).
®
Server, to remote LONWORKS® networks.
ONWORKS application developers, using
. Contact Echelon Sales
Programming with the OpenLDV API requires knowledge of the ISO/IEC 14908­1 Control Network Protocol. Echelon’s implementation of the ISO/IEC 14908 Control Network Protocol is called the LonTalk protocol. Echelon has implementations of the LonTalk protocol in several product offerings, including the Neuron firmware, LNS Server, i.LON 600 IP-852 Router, and SmartServer Energy Managers. This document refers to the ISO/IEC 14908 Control Network Protocol as the “LonTalk protocol”, although other interoperable implementations exist.

Audience

This guide is intended for software developers creating OpenLDV applications for use with OpenLDV compatible network interface products. Readers of this guide should be familiar with L
This guide is also intended for software developers creating xDriver extensions. Programming samples in this document are written in C++ and Microsoft
®
Basic
.NET. However, extensions for xDriver can be written in any language
that supports Component Object Model (COM) components or ActiveX
Developers of xDriver extensions should have programming experience in such a language, as well as familiarity with L
OpenLDV Programmer’s Guide iii
ONWORKS technology.
ONWORKS technology and COM concepts.
®
Visual
®
controls.

Examples

Throughout this guide, C++, Visual Basic, and other language programming samples are used to illustrate concepts. To make these samples more easily understood, they have been simplified. Error checking has generally been removed, and in some cases, the examples are only fragments that might not compile without errors or warnings.

Related Documentation

The following manuals are available from the Echelon Web site (www.echelon.com LONWORKS and LNS applications:
Introduction to the LONWORKS Platform (078-0391-01B). This manual provides an introduction to the ISO/IEC 14908 (ANSI/CEA-709.1 and EN14908) Control Network Protocol, and provides a high-level introduction to L are used for developing, installing, operating, and maintaining them.
LNS Programmer's Guide (078-0177-01F). This manual describes how to write powerful LNS applications, and how to get those applications to market quickly.
All of the Echelon documentation is available in Adobe PDF files, you must have a current version of the Adobe Reader download from Adobe at: get.adobe.com/reader
) and provide additional information that can help you develop
ONWORKS networks and the tools and components that
.
PDF format. To view the
, which you can
In addition to the Echelon documentation, the following specification can help you develop L
International Organization for Standardization (ISO) and International
You can purchase copies of ISO standards from the Information Handling Services (IHS) Global page at: global.ihs.com
ONWORKS and LNS applications:
Electrotechnical Commission (IEC) standard ISO/IEC 14908 Control Network Protocol
.
iv
Table of Contents
Welcome ......................................................................................................... iii
Audience ........................................................................................................ iii
Examples ....................................................................................................... iv
Related Documentation ................................................................................ iv
Chapter 1. Introduction ................................................................................... 1
Introduction to OpenLDV Networking ......................................................... 2
Client Applications .................................................................................. 3
OpenLDV Driver ...................................................................................... 3
Network Interfaces .................................................................................. 4
Installing the OpenLDV Software ................................................................ 5
Hardware and Software Requirements.................................................. 5
Downloading the OpenLDV Software .................................................... 5
Installing the OpenLDV Driver .............................................................. 6
Installing the OpenLDV SDK ................................................................. 6
Getting Started with the OpenLDV Driver .................................................. 7
Getting Started with the xDriver Component ............................................. 8
Chapter 2. Using the OpenLDV API ............................................................. 9
Introduction to OpenLDV Programming .................................................... 10
OpenLDV Application Architecture ............................................................ 11
Application Layer .................................................................................. 12
Presentation Layer ................................................................................ 13
Overview of the OpenLDV API ................................................................... 13
Referencing the OpenLDV Component ................................................ 14
Using Multiple Threads or Multiple Processes ................................... 14
The OpenLDV API ....................................................................................... 15
Working with Devices and Drivers ....................................................... 16
Using the OpenLDV API ....................................................................... 17
ldv_close() ............................................................................................... 18
ldv_free_device_info() ............................................................................ 18
ldv_free_driver_info() ............................................................................ 19
ldv_free_matching_devices() ................................................................. 20
ldv_get_device_info() ............................................................................. 20
ldv_get_driver_info() .............................................................................. 21
ldv_get_matching_devices() .................................................................. 22
ldv_get_version ...................................................................................... 22
ldv_locate_sicb() ..................................................................................... 23
ldv_open() ............................................................................................... 24
ldv_open_cap()........................................................................................ 25
ldv_read() ............................................................................................... 27
ldv_register_event() ............................................................................... 29
ldv_set_device_info() .............................................................................. 30
ldv_set_driver_info() .............................................................................. 31
ldv_write() .............................................................................................. 32
ldv_xlate_device_name() ....................................................................... 33
ldvx_open() ............................................................................................. 34
ldvx_register_window() ......................................................................... 36
ldvx_shutdown() ..................................................................................... 37
Structures and Enumerations for the Device API ..................................... 37
LDVDeviceInfo Structure ..................................................................... 37
LDVDevices Structure........................................................................... 38
OpenLDV Programmer’s Guide v
LdvCombineFlags Enumeration ........................................................... 39
LdvDeviceCaps Enumeration ............................................................... 40
Structures and Enumerations for the Driver API ..................................... 42
LDVDriverInfo Structure ...................................................................... 42
LdvDriverID Enumeration ................................................................... 43
LdvDriverType Enumeration ............................................................... 44
Windows Messages for Session Notifications ............................................. 44
OpenLDV API Return Codes ....................................................................... 45
Example: A Simple OpenLDV Application ................................................ 52
Chapter 3. Sending/Receiving Messages with the OpenLDV API ....... 57
Constructing Messages ................................................................................ 58
Application Buffer Structure ....................................................................... 58
Layer 2 Buffer Structure ....................................................................... 61
Application Layer Header .............................................................. 61
Layer 2 Header ................................................................................ 61
NPDU ............................................................................................... 61
CRC .................................................................................................. 62
Layer 5 Buffer Structure ....................................................................... 62
Application Layer Header .............................................................. 62
Message Header .............................................................................. 62
Network Address ............................................................................. 67
Message Data .................................................................................. 73
Sending Messages to the Network Interface ....................................... 75
Receiving Messages from the Network Interface ................................ 75
Using the Network Interface Command Interface .................................... 76
Downlink Commands ............................................................................ 76
Uplink Commands ................................................................................. 77
Immediate Commands .......................................................................... 77
Network Interface Commands .............................................................. 77
Chapter 4. The OpenLDV Developer Example ........................................ 89
Overview ....................................................................................................... 90
Common Definitions .................................................................................... 90
COpenLDVapi and COpenLDVtrace .......................................................... 90
COpenLDVni, Message Pumps, and Message Dispatchers ...................... 90
Toolkits and User Interface ......................................................................... 91
Developer Example Diagram ...................................................................... 92
Chapter 5. Using the xDriver Default Profile .......................................... 93
Configuring an xDriver Profile.................................................................... 94
LNS Applications for xDriver ...................................................................... 98
Chapter 6. Extending xDriver ...................................................................... 99
Extending xDriver ...................................................................................... 100
xDriver Sessions ......................................................................................... 100
Downlink Sessions ............................................................................... 100
Uplink Sessions ................................................................................... 104
Session Control Object ........................................................................ 108
Authentication Key Handling ................................................................... 111
Setting the Current Authentication Key ........................................... 111
Changing the Current Authentication Key ....................................... 112
Creating a Custom Lookup Extension in C++ ......................................... 113
Create a New Visual Studio Project ................................................... 114
Add a COM Object ............................................................................... 116
vi
Implement the ILdvxLookup Interface .............................................. 119
Add the Extension to the Component Category ................................ 121
Build and Register the COM Server .................................................. 121
Create a Custom xDriver Profile ........................................................ 122
Test the Lookup Extension ................................................................. 124
Optional Steps ..................................................................................... 124
Creating a Custom Lookup Extension in Visual Basic ............................ 125
Create a New Visual Studio Project ................................................... 125
Add a Reference to the xDriver Type Library ................................... 127
Add a COM Class ................................................................................. 127
Delete the Project Default Class ......................................................... 128
Import xDriver Types to Your System Namespace ........................... 129
Implement the ILdvxLookup Interface .............................................. 129
Build and Register the Lookup Extension ......................................... 130
Create a Custom xDriver Profile ........................................................ 130
Test the Lookup Extension ................................................................. 132
Sample Lookup Extension Component ..................................................... 132
xDriver Profiles .......................................................................................... 134
Starting the Connection Broker ......................................................... 135
Chapter 7. LNS Programming with xDriver .......................................... 137
Downlink Sample Applications ................................................................. 138
Opening a Single Remote Network With xDriver ............................. 138
Opening Multiple Remote Networks for Downlink ........................... 139
Uplink Sample Application ....................................................................... 142
Appendix A. Custom Network Interfaces................................................ 147
Overview ..................................................................................................... 148
Working with a Custom Network Interface ............................................. 148
Windows Registry Entries ......................................................................... 150
Appendix B. LNS Methods and Events for xDriver Support ............. 153
xDriver Methods and Events ..................................................................... 154
AcceptIncomingSession ....................................................................... 154
BeginIncomingSessionEvents ............................................................. 155
EndIncomingSessionEvents................................................................ 155
NetworkInterfaces.Item( ) ................................................................... 156
OnIncomingSessionEvent ................................................................... 157
ReleasePendingUpdates ...................................................................... 158
Appendix C. Custom Lookup Extension Programming ...................... 161
Overview ..................................................................................................... 162
ILdvxConfigure Interface .......................................................................... 162
SetInstance Method ............................................................................. 162
SetOptions Method .............................................................................. 163
ILdvxLookup Interface .............................................................................. 164
DownlinkLookup Method .................................................................... 164
UpdateLookup Method ........................................................................ 165
UplinkLookup Method ........................................................................ 165
ILdvxSCO Interface ................................................................................... 166
GetAdditionalDownlinkPacketHeader Method ................................. 167
GetAdditionalDownlinkPacketTrailer Method ................................. 167
GetAuthenticationFlag Method .......................................................... 168
GetCurrentAuthenticationKey Method ............................................. 168
GetDownlinkKey Method .................................................................... 169
OpenLDV Programmer’s Guide vii
GetEncryptionType Method ................................................................ 170
GetLNSNetworkName Method .......................................................... 170
GetNextAuthenticationKey Method ................................................... 171
GetSessionControlObjectID Method .................................................. 171
GetUplinkKey Method ........................................................................ 172
SetAdditionalDownlinkPacketHeader Method ................................. 172
SetAdditionalDownlinkPacketTrailer Method .................................. 173
SetAuthenticationFlag Method .......................................................... 173
SetCurrentAuthenticationKey Method .............................................. 174
SetDownlinkKey Method .................................................................... 175
SetEncryptionType Method ................................................................ 175
SetLNSNetworkName Method ........................................................... 176
SetNextAuthenticationKey Method ................................................... 177
SetUplinkKey Method ......................................................................... 178
ILdvxSCO_TCP Interface .......................................................................... 178
GetRemoteTCPAddress Method ......................................................... 179
GetRemoteTCPPort Method ............................................................... 179
SetRemoteTCPAddress Method ......................................................... 180
SetRemoteTCPPort Method ................................................................ 180
ILdvxSCO2 Interface ................................................................................. 181
GetNeuronID Method .......................................................................... 181
Index ................................................................................................................. 183
viii
1

Introduction

This chapter introduces the OpenLDV driver and how you can use it to send and receive LonTalk messages through any OpenLDV compatible network interface.
This chapter also introduces the xDriver component.
OpenLDV Programmer’s Guide 1

Introduction to OpenLDV Networking

OpenLDV Driver
Your LNS
Application
Your
OpenLDV
Application
LonScanner
Protocol
Analyzer
Windows
Device Drivers
OpenLDV Client Applications
Using the OpenLDV API
SLTA
PCC-10 PCLTA-22
U10 or U20
xDriver
Component
i.LON 10
i.LON 100 i.LON 600
SmartServer
Remote
Network Interfaces
Local Network Interfaces
The OpenLDV driver allows a Windows application to communicate with a
ONWORKS network through a locally attached network interface or a remote
L network interface. Figure 1 shows the basic components for communicating with a L
ONWORKS network:
One or more OpenLDV client applications (for example, an LNS Server with one or more LNS clients, the Echelon LonScanner™ Protocol Analyzer, or some other client that does not use an LNS Server), which use the OpenLDV API
The OpenLDV driver
One or more local network interfaces, which use a Windows device driver
provided with the network interface
One or more remote network interfaces (usually Internet enabled), which use the xDriver component of the OpenLDV driver
2 Introduction
Figure 1. OpenLDV Programming Model

Client Applications

OpenLDV applications, such as the LNS Server and the LonScanner Protocol Analyzer, use the OpenLDV application programming interface (API) to communicate with L
ONWORKS network interfaces.
Echelon’s LNS software provides a high-level interface to L that simplifies managing network interfaces. The LNS software is a powerful, flexible network management platform you can use with high-performance Layer-2 or Layer-5 network interfaces, as well as with IP-852 routers (such as the i.LON 600 or SmartServer). The LNS Server provides a wide variety of network management and monitor and control services, and allows multiple client access to the same network interface.
For most customers, choosing the LNS software platform will result in a high­quality application that can be developed more quickly, requiring less knowledge of low-level details, than with other network management platforms, including the OpenLDV platform. However, the OpenLDV API provides a low-level interface for writing Windows based L
ONWORKS network interfaces.
L
You can use the OpenLDV API to write your own application that sends and receives messages through L LonTalk Layer 2 or Layer 5 interface. These messages can initialize and terminate communications with the network interface, retrieve incoming messages, or transmit outgoing messages. See Chapter 2, Using the OpenLDV
API, on page 9, and Chapter 3, Sending and Receiving Messages with the OpenLDV API, on page 57, for information about these topics.

OpenLDV Driver

ONWORKS networks
ONWORKS software for use with
ONWORKS network interfaces, using either a
You can use the OpenLDV runtime with network management or monitoring and control applications. For example, for a self-installed system with fixed network addresses, you can use the OpenLDV API to create an application that sends messages to test the devices on your network. This diagnostic application could periodically send request messages to devices in the system to check their status. You can also use the OpenLDV API to create a data logging application to monitor and retrieve network variable values from the various devices on your network.
The OpenLDV 4.0 driver and API are backward-compatible with previous versions of the driver and the API (but see Hardware and Software Requirements on page 5 for the OpenLDV 4.0 requirements, which differ from those of prior releases).
To develop an OpenLDV application, you must understand LonTalk message formats and network interface state management. You also need to be able to manage low-level LonTalk messaging details, such as LonTalk reference IDs. Chapters 3 and 4 of this document describe some of the LonTalk message formats that you can use with the OpenLDV API. In addition, the section Message Header on page 62 includes some discussion of LonTalk reference IDs. See the ISO/IEC 14908 Control Network Protocol specification for detailed information about the LonTalk protocol.
OpenLDV Programmer’s Guide 3

Network Interfaces

TCP/IP
LonWorks Channel
LonWorks Channel
LonWorks Devices
LonWorks Devices
OpenLDV Application
with xDriver
A local network interface (one that is physically connected to the computer running the OpenLDV driver) uses its own Windows device driver. Echelon and third parties provide a number of network interface products; see the specific documentation about the network interface for more information.
You can also develop your own custom OpenLDV compatible local network interface. To make your network interface compatible with the OpenLDV driver, you must also develop a Windows device driver for it; see Appendix A, Custom Network Interfaces, on page 147, for additional information about working with a custom network interface.
A remote network interface (one that is connected to the computer through an IP network, typically the Internet) uses the xDriver component of the OpenLDV driver as a virtual device driver. The xDriver component is an extensible network driver that uses IP to establish connections between OpenLDV applications and network interfaces (such as an Echelon SmartServer).
xDriver can provide authenticated connections from an OpenLDV application to hundreds or even thousands of remote L (such as a SmartServer). As shown in Figure 2, the OpenLDV application accesses the SmartServer, and the L connected to, through an IP connection.
ONWORKS networks through RNI devices
ONWORKS channel that the SmartServer is
Figure 2. An OpenLDV Application Using xDriver to Manage LonWorks Devices
You configure the xDrvier component with an xDriver profile. An xDriver profile is a set of configuration parameters that determines how xDriver manages
4 Introduction
connections with a group of remote networks. For example, you could have hundreds of remote networks, each of which has a SmartServer attached. At your service center, your monitoring tool could use the OpenLDV driver to listen for session requests from these networks and send messages to remote devices.
The OpenLDV driver includes a default xDriver profile. You can use the default xDriver profile for your OpenLDV applications, or you can use the xDriver Profile Editor to create a custom xDriver profile for your OpenLDV applications; see Chapter 5, Using the xDriver Default Profile, on page 93.
You can configure each xDriver profile to provide your application with information identifying the network interface that has requested a network session. Thus, you can program your application to quickly identify the source of the session request, and respond to a variety of different alarm conditions. See Configuring an xDriver Profile on page 94 for more information about the xDriver profile.

Installing the OpenLDV Software

The following sections describe the requirements for downloading the OpenLDV software, installing it, and using the OpenLDV software.

Hardware and Software Requirements

To install and use the OpenLDV 4.0 software, your computer must meet the following minimum requirements, in addition to those imposed by your operating system:
512 MB RAM (or the Windows operating system minimum requirement)
Microsoft Windows 7 (32-bit or 64-bit), Windows Server 2008 R2 (64-bit),
Windows Vista SP3
Microsoft .NET Framework 3.5 SP1
50 MB of available hard-disk space
1024x768 screen resolution
®
(32-bit), Windows Server 2003 (32-bit), or Windows XP

Downloading the OpenLDV Software

You can download the OpenLDV driver and SDK from Echelon’s Web site at
www.echelon.com/downloads
The OpenLDV driver installer (OpenLDV400.exe) installs the OpenLDV driver,
ONWORKS Interfaces application in the Windows Control Panel, and the
the L xDriver Profile Editor.
You can incorporate the OpenLDV driver installer into your OpenLDV application’s installation, either as a standalone component that your end-users will install, or as a component that your overall software installer will install. The OpenLDV runtime installer is based on Microsoft Installer 3.1. If the computer onto which you are installing the OpenLDV driver uses an older version of Microsoft Installer, the OpenLDV driver installation will update the computer to use version 3.1.
.
OpenLDV Programmer’s Guide 5
See the OpenLDV 4.0 ReadMe document for updates to the OpenLDV driver documentation.
To develop an OpenLDV application or xDriver extension, install the OpenLDV SDK (OpenLDV400-SDK.exe) in addition to the OpenLDV driver. The OpenLDV SDK contains documentation, source files, and several examples, which you can use when developing your own OpenLDV application or xDriver extension.
See the OpenLDV SDK 4.0 ReadMe document for updates to the OpenLDV SDK documentation.

Installing the OpenLDV Driver

To install and use the OpenLDV driver, perform the following steps:
1. Download the OpenLDV Driver OpenLDV400.exe file from Echelon’s Web site at www.echelon.com/downloads
2. Double-click the OpenLDV400.exe file to begin the OpenLDV driver installation. The OpenLDV driver installer window opens.
3. Follow the installation dialogs to install the OpenLDV driver onto your computer.
If you are using a SmartServer or i.LON network interface:
.
1. Use the L to specify the IP network addresses of the SmartServer or i.LON network interface. See the online help for the L for information about how to use it.
2. If you are using a SmartServer or i.LON network interface and you are developing a custom xDriver profile, use the xDriver Profile Editor in the OpenLDV program folder to configure an xDriver profile for use with your OpenLDV application. For more information on the xDriver Profile Editor, see Chapter 5, Using the xDriver Default Profile, on page 93.
3. See the installation instructions for your network interface for any additional instructions for configuring the network interface.
ONWORKS Interfaces application in the Windows Control Panel

Installing the OpenLDV SDK

To install and use the OpenLDV SDK, perform the following steps:
1. Download and install the OpenLDV driver, as described in Installing the OpenLDV Driver.
2. Download the OpenLDV SDK OpenLDV400-SDK.exe file from Echelon’s Web site at www.echelon.com/downloads
3. Double-click the OpenLDV400-SDK.exe file to begin the OpenLDV SDK installation. The OpenLDV SDK installer window opens.
ONWORKS Interfaces application
.
4. Follow the installation dialogs to install the OpenLDV SDK onto your computer.
5. You can now use the OpenLDV SDK to write applications that use the OpenLDV API or create xDriver extensions. For information about the OpenLDV API, see Chapter 2, Using the OpenLDV API, on page 9. For
6 Introduction
information about xDriver extensions, see Chapter 6, Extending xDriver, on page 99.

Getting Started with the OpenLDV Driver

An OpenLDV application can use a Layer 2 network interface or a Layer 5 network interface:
Layer 2 Network Interface – A network interface that communicates at Layer 2 of the LonTalk protocol. This type of interface transports LonTalk packets without processing them, and does not filter by network address. It is typically used for applications that implement layers 3 through 7 of the LonTalk protocol, such as an LNS Server, and is also used for protocol analyzers that log and display network traffic. Implementing layers 3 through 7 on a Windows computer, rather than in the Neuron core or other processor of a local network interface, can provide significantly higher performance. For example, the LNS Server includes an implementation of layers 3 through 7 that provides significantly higher performance when used with a Layer 2 network interface.
Layer 5 Network Interface – A network interface that communicates at Layer 5 of the LonTalk protocol. This type of interface transports incoming LonTalk packets that are addressed to the network interface, and transports outgoing packets that are addressed to other devices. It is typically used for remote network interfaces (such as a SmartServer or an i.LON network interface) because these interfaces typically implement layers 3 through 5 on a high performance processor within the network interface, and it allows an uplink session to be initiated when the host receives a particular message addressed to it. This type of interface requires handling of NI resources, such as reference IDs, at a software layer above the OpenLDV layer. For example, the LNS Server manages NI resources when used with a Layer 5 network interface.
A typical OpenLDV application uses Layer 5 interfaces so that it need not implement layer 3-5.
You can use the L to determine if your network interface provides a Layer 2 or Layer 5 image or supports switching between Layer 2 and Layer 5:
Echelon U10 and U20 USB Network Interfaces can operate as either a Layer 2 or Layer 5 interface, switchable within an OpenLDV application
Remote Network Interfaces (SmartServer or i.LON) can be configured to operate as a Layer 5 interface or as a read-only Layer 2 interface (for use with protocol analyzers, such as the LonScanner Protocol Analyzer)
IP-852 devices always operate as Layer 2 interfaces, as defined by the ISO/IEC 14908-4 standard
For PCC-10, PCLTA-20, or PCLTA-21 network interfaces, Table 1 on page 8 lists the application image that you can select to operate at either Layer 2 or Layer 5, as needed. See the documentation for your network interface for additional information.
OpenLDV Programmer’s Guide 7
ONWORKS Interfaces application in the Windows Control Panel
Table 1. NI Application Settings
Network Interface
PCC-10 PCC10VNI NSIPCC
PCLTA-20 PCL10VNI NSIPCLTA
PCLTA-21 PCLTA21VNI PCLTA21NSI
The LONWORKS Interfaces application is installed with the OpenLDV driver.
For additional information about developing an OpenLDV application, see the following chapters:
Chapter 2, Using the OpenLDV API, on page 9. This chapter describes each function that is included in the OpenLDV API. It also defines guidelines for writing applications that use the OpenLDV API to access multiple network interfaces.
Chapter 3, Sending and Receiving Messages with the OpenLDV API, on page 57. You can use the ldv_write() and ldv_read() functions described in Chapter 2 to send and receive message commands through a network interface. This chapter describes the various network interface commands that your OpenLDV application can send and receive with these functions, as well as the application buffer structure for each type of message.
NI Application Setting for Layer 2 Image
NI Application Setting for Layer 5 Image
Chapter 4, The OpenLDV Developer Example, on page 89. This chapter introduces the OpenLDV Developer Example, which is installed with the OpenLDV SDK. It describes various classes implemented in the OpenLDV Developer Example. In addition to reviewing the code, you should also review the code comments in the example.

Getting Started with the xDriver Component

The xDriver component is included with the OpenLDV driver. xDriver supports scalable access to many network interfaces. The default xDriver implementation uses a Lookup component that uses the Windows Registry to store a database containing the information that it requires to connect to each device. For small­scale deployments, the Windows Registry is an efficient information store for the xDriver database.
However, for larger deployments (more than 50 network interfaces), you can improve performance by extending the default xDriver component to use a database as your information store.
If you do not plan to extend the default xDriver component to use a database, you can begin using the default xDriver component, as described in Chapter 5, Using the xDriver Default Profile, on page 93.
If you plan to extend the default xDriver component, see Chapter 6, Extending xDriver, on page 99. Most developers will not need to extend xDriver.
8 Introduction
2

Using the OpenLDV API

This chapter describes the OpenLDV API functions and types, including the input and output parameters associated with each function, and the return codes returned by each function.
OpenLDV Programmer’s Guide 9

Introduction to OpenLDV Programming

An application that uses the OpenLDV API is called an OpenLDV application. The communications protocol used for OpenLDV applications is the ISO/IEC 14908-1 (ANSI/CEA 709.1-B and EN14908.1) Control Network Protocol. This protocol is an international standard seven-layer protocol that has been optimized for control applications, and is based on the Open Systems Interconnection (OSI) Basic Reference Model (the OSI Model, ISO standard 7498-
1). The OSI Model describes computer network communications through the seven abstract layers described in Table 2. The implementation of these layers
ONWORKS device provides standardized interconnectivity for devices within
in a L
ONWORKS network.
a L
Table 2. L
OSI Layer Purpose Services Provided
7 Application Application compatibility Network configuration, self-installation,
6 Presentation Data interpretation Network variables, application messages,
5 Session Control Request/response, authentication
4 Transport End-to-end
communication reliability
3 Network Destination addressing Unicast and multicast addressing,
2 Data Link Media access and framing Framing, data encoding, CRC error
ONWORKS Network Protocol Layers
network diagnostics, file transfer, application configuration, application specification, alarms, data logging, scheduling
foreign frame transmission
Acknowledged and unacknowledged message delivery, common ordering, duplicate detection
routers
checking, predictive carrier sense multiple access (CSMA), collision avoidance, priority, collision detection
1 Physical Electrical interconnect Media-specific interfaces and modulation
schemes
Echelon’s implementation of the ISO/IEC 14908 Control Network Protocol is called the LonTalk protocol. Echelon has implementations of the LonTalk protocol in several product offerings, including the Neuron firmware, LNS Server, SmartServers, and various network interfaces. This document refers to the ISO/IEC 14908-1 Control Network Protocol as the “LonTalk protocol”, although other interoperable implementations exist.
An OpenLDV application can work with Layer 2 network interfaces, Layer 5 network interfaces, or LonScanner Protocol Analyzer interfaces. Figure 3 shows
10 Using the OpenLDV API
Physical Layer
Data Link Layer
Network Layer
Transport Layer
Session Layer
Presentation Layer
Application Layer
Layer 5
Network
Interface
Layer 2 Network Interface
the seven layers of the OSI Model and which OSI layers a Layer 2 or Layer 5 network interface handles.
Figure 3. Network Interfaces and the Seven Layers of the OSI Model
A Layer 2 network interface handles only the first two layers of the OSI Model, and thus only sends and receives network packets; an application must implement the rest of the ISO/IEC 14908-1 protocol to communicate with the network.
A LonScanner Protocol Analyzer uses a Layer 2 network interface. The LonScanner Protocol Analyzer implements the rest of the ISO/IEC 14908-1 protocol to communicate with and analyze the network.
A Layer 5 network interface handles the first five layers of the OSI Model, and thus not only sends and receives network packets, but also implements layers 1 through 5 of the ISO/IEC 14908-1 protocol to communicate with the network.
Most OpenLDV applications use Layer 5 network interfaces so that they need not implement Layers 3 to 5 of the ISO/IEC 14908-1 protocol.

OpenLDV Application Architecture

The OpenLDV application architecture also uses the OSI Model, and provides a programming framework for communicating with the network, as shown in Figure 4 on page 12.
OpenLDV Programmer’s Guide 11

Application Layer

OpenLDV API
Presentation Layer
OpenLDV Application
OpenLDV Driver (Ldv32.dll)
SLTA
Link Layer
PCLTA
Link Layer
PCC
Link Layer
USB
Link Layer
SLTA-10
PCLTA-10 PCLTA-20
PCC-10
U10 U20
LONW
ORKS
Network
xDriver
Link Layer
SmartServer
i.LON
Interfaces
Compatible
with
OpenLDV
API
OpenLDV
Interface
and Driver
Software
OpenLDV
Application
Figure 4. OpenLDV Application Architecture
An OpenLDV application implements the application and presentation layers, and uses the OpenLDV API (with the OpenLDV driver, Ldv32.dll) as an interface layer to communicate with a network interface. The network interfaces communicate with the L network interfaces, most third-party network interfaces can also use the OpenLDV driver.
An OpenLDV application that uses the OpenLDV API can establish downlink connections (session initiation from the application to the local or remote network interface), and it can accept uplink session requests (session initiation from the remote network interface, using the xDriver Broker service, to the application).
Application Layer
The application layer is responsible for sending data to the LONWORKS network through output network variables and outgoing application messages, and receiving L
ONWORKS network data through input network variables and
incoming application messages. Typically, the bulk of an OpenLDV application’s code is at the application layer.
ONWORKS network. Although the figure shows Echelon
12 Using the OpenLDV API
The OpenLDV API does not include an application layer. However, the OpenLDV Developer Example demonstrates how to integrate an application layer (which dispatches incoming messages to an application-specific message dispatcher) with the OpenLDV API. For more information about the OpenLDV Developer Example and the message dispatcher it employs, see Chapter 4, The OpenLDV Developer Example, on page 89.

Presentation Layer

The presentation layer is responsible for translating messages between the lower layers, providing an easier-to-use presentation format used by the application layer. For example, all incoming network variable update messages from a network interface are recognized by this layer, updating the application’s network variable values and notifying the application layer of the change.
The presentation layer can also manage network management messages and diagnostics services, such as the responses to Query SI network management commands (see Receiving Messages from the Network Interface on page 75).
The OpenLDV API does not include a presentation layer. However, the OpenLDV Developer Example demonstrates how to integrate a presentation layer with the OpenLDV API. The OpenLDV Developer Example also includes code that handles several network management commands and diagnostics.

Overview of the OpenLDV API

The OpenLDV API is implemented by a 32-bit C DLL that is compatible with both 64- and 32-bit versions of Windows. All data types defined for the API assume a 32-bit compiler; for example, pointers reference 32-bit addresses, each enum is a 32-bit type, size_t is an unsigned 32-bit type, and so on. The OpenLDV header file, ldv32.h, includes the following type definitions for native data types, rather than using compiler-dependent types:
typedef void* PVOID; typedef short SHORT; /* signed 16-bit */ typedef long LONG; /* signed 32-bit */ typedef unsigned char BYTE; /* unsigned 8-bit */ typedef unsigned short WORD; /* unsigned 16-bit */ typedef unsigned long DWORD; /* unsigned 32-bit */ typedef char* LPSTR; typedef const char* LPCSTR; typedef void* HANDLE;
Each function of the OpenLDV API uses extern “C” and __stdcall calling conventions.
An alternative to the OpenLDV API is the COpenLDVapi class provided with the OpenLDV developer example described in Chapter 4. This class provides a COM interface with thread-safe, synchronized, access to downlink messages (ldv_write()). The same interface also implements a reader thread, COpenLDVreader, which queries uplink messages (ldv_read()) and supplies data to a protected queue. The COpenLDVapi::Read() function queries that queue, thereby providing coordinated access to both uplink and downlink messages.
OpenLDV Programmer’s Guide 13

Referencing the OpenLDV Component

You can develop applications that use the OpenLDV API with any Windows application development environment that supports the use of standard Windows DLL components and (for xDriver Extensions) COM components. Echelon has tested the OpenLDV software with Microsoft Visual Studio 2008, using the Microsoft Visual C++
To develop an applicatikon with the OpenLDV API, first install the OpenLDV driver and the OpenLDV SDK. During the installation, the ldv32.h and
ldv32.lib files are copied to the L \OpenLDV SDK\Lib folders.
To develop your OpenLDV application, include the ldv32.h header file in your application and link it with the ldv32.lib library. See your development environment’s documentation for information about linking to external libraries. End users of your OpenLDV application do not need to install any of the files included in the OpenLDV SDK; they need only install the OpenLDV driver.
The OpenLDV SDK includes the OpenLDV Developer Example, which uses many of the functions described in this chapter. To compile and debug the OpenLDV Developer Example, install Microsoft Visual Studio 2008 (or later), with the Microsoft Visual C++ component. The example application is available from the Examples & Tutorials folder in the Echelon OpenLDV 4.0 SDK program folder; it is also installed as a ZIP file to the \LonWorks\OpenLDV SDK\SourceArchive folder. The OpenLDV Developer Example contains numerous helpful comments. See Chapter 4, The OpenLDV Developer Example, on page 89, for a description of the architecture of the OpenLDV Developer Example and of the different classes that it contains.
®
, Visual C#®, and Visual Basic® components.
ONWORKS \OpenLDV SDK\Include and

Using Multiple Threads or Multiple Processes

The OpenLDV software supports communication with multiple network interfaces at the same time, with the following restrictions:
1. A single process can access multiple network interfaces simultaneously. However, a single process should access a network interface with at most one writer thread and one reader thread. You must program your application to enforce this restriction, because it is not enforced by the OpenLDV software. See the OpenLDV Developer Example for a demonstration of the proper use of separate reader and writer threads.
2. Multiple processes cannot access the same network interface simultaneously. Attempts to access the same network interface by more than one process result in the LDVX_ACCESS_DENIED failure code from the ldv_open() functions.
3. The SmartServer and i.LON network interfaces allow a single session at a time. If you attempt to open such a network interface while another session is active (usually from another computer), the call to ldv_open() might initially appear to have succeeded (the connection is established in the background). However, when you call ldv_read() or ldv_write() to read or write a message to the network interface, the functions return the LDVX_READ_FAILED or LDVX_WRITE_FAILED return codes, which indicate that the session has failed. See ldv_open() on page 24 for more information.
14 Using the OpenLDV API

The OpenLDV API

This section describes the functions included in the OpenLDV API. Table 3 summarizes these functions. See Structures and Enumerations for the Driver API on page 42 for descriptions of the structures and enumerations used by the OpenLDV API. See OpenLDV API Return Codes on page 44 for descriptions of the return codes.
Table 3. OpenLDV API Functions
Added in OpenLDV
Function Description
ldv_close() Closes an open session. 1.0
Version
ldv_free_device_info() Releases the resources allocated by a
call to ldv_get_device_info() or ldv_get_matching_devices().
ldv_free_driver_info() Releases the resources allocated by a
call to ldv_get_driver_info().
ldv_free_matching_devices() Releases the resources allocated by a
call to
ldv_get_matching_devices().
ldv_get_device_info() Retrieves information about a
ONWORKS interface device.
L
ldv_get_driver_info() Retrieves information about a
ONWORKS interface device driver
L class.
ldv_get_matching_devices() Retrieves information about the
ONWORKS interface devices that
L match a set of capabilities.
ldv_get_version() Retrieves the version number of the
OpenLDV API.
2.0
2.0
2.0
2.0
2.0
2.0
1.0
ldv_locate_sicb() Locates the SICB portion of the data
within an LdvEx (or SICB) formatted message, if present.
ldv_open() Opens a network interface device. 1.0
ldv_open_cap() An extended version of ldv_open()
and ldvx_open() that additionally allows the caller to request specific capabilities for the device.
OpenLDV Programmer’s Guide 15
2.0
2.0
Function Description
Added in OpenLDV Version
ldv_read() Reads a message from an open
session.
ldv_register_event() Registers a Windows Event object to
receive notification of the availability of new messages.
ldv_set_device_info() Creates or modifies the information
about a L
ldv_set_driver_info() Creates or modifies the information
about a L driver class.
ldv_write() Writes a message to an open session. 1.0
ldv_xlate_device_name() Translates a device’s logical name to
its physical name, that is, from the device’s L “LON1”) to its Windows device name (such as “\\.\LON1.0”).
ldvx_open() Opens a network interface device,
registers a Windows HWND object for receiving session change notifications.
ONWORKS interface device.
ONWORKS interface device
ONWORKS name (such as
1.0
1.0
2.0
2.0
1.0
1.0
ldvx_register_window() Registers a Windows HWND object
for receiving session change notifications.
ldvx_shutdown() Cleanly shuts down OpenLDV and
xDriver subsystem.
1.0
1.0

Working with Devices and Drivers

The OpenLDV API includes a number of functions that assist in working with devices and device drivers, for example:
The ldv_get_driver_info() function allows you to identify the device driver for a particular device. With this function, an application could display a list of devices associated with a specific device driver.
The ldv_get_device_info() function allows you to retrieve device information (such as the transceiver ID of the Smart Transceiver or Neuron Chip). For example, the transceiver ID allows an application to determine appropriate timer and channel settings for the device based on the available hardware.
16 Using the OpenLDV API
The ldv_set_device_info() function allows you to modify certain information for a device.
The ldv_get_matching_devices() function allows you retrieve a list of devices that match a specified set of capabilities. For example, you can determine which devices operate at Layer 2 or Layer 5, you can determine which devices are IP-852 devices or channels, or you can determine which devices are protocol analyzers.
The ldv_free_device_info(), ldv_free_driver_info(), and ldv_free_matching_devices() functions release resources allocated by the ldv_get_device_info(), ldv_get_driver_info(), and ldv_get_matching_devices() functions.
The ldv_open_cap() function allows you to open a device with a specified capability enabled, if the capability is supported by the device. For example, you could open a U10 USB network interface with Layer 2 operation or with Layer 5 operation. However, only local devices and static xDriver RNI devices that use the default xDriver lookup extension can supply their device capabilities. xDriver RNIs that use a custom lookup extension are either not available or report as having unknown capabilities.
See The OpenLDV API on page 15 for a description of these functions and the rest of the OpenLDV functions.

Using the OpenLDV API

The basic code flow for an OpenLDV application includes the following four functions, which comprise the basis of all OpenLDV applications:
ldv_open()
ldv_read()
ldv_write()
ldv_close()
An application can call the ldv_read() and ldv_write() functions in any order, and at any time after opening the network interface, but before closing the network interface.
The following sections describe each of the API functions in detail. The syntax for each function includes a table that describes the following information:
Each parameter required for the function. The parameter data type does not appear in the table, but is shown in the syntax for the function.
The direction for each parameter:
o Input: Input parameters provide data to the OpenLDV function.
You must supply an appropriate value for each input parameter.
o Output: Output parameters provide data to your application
from the OpenLDV function. You must supply an appropriately sized variable or buffer for each output parameter.
A description of each parameter.
OpenLDV Programmer’s Guide 17
See Structures and Enumerations for the Driver API on page 42 for descriptions of the structures and enumerations used by the OpenLDV API. See OpenLDV API Return Codes on page 44 for descriptions of the return codes.

ldv_close()

Call this function to close a network interface that has been previously opened with the ldv_open() function.
Syntax
LDVCode ldv_close( LdvHandle handle )
Table 4. ldv_close() Parameters
Parameter Direction Description
handle
Input The network interface to be closed. This value was returned
as the handle parameter when you opened the network interface with one of the open functions (ldv_open(), ldv_open_cap(), or ldvx_open()).
Remarks
Use this function to close an OpenLDV session and end communication between your application and the network interface involved in the session. This function also frees any resources assigned to the network interface and the handle assigned to the session. This function returns LDV_OK if the network interface is successfully closed; if so, other processes on your computer can access the network interface.
Each successful ldv_open(), ldv_open_cap(), or ldvx_open() call (including nested ones) must have a matching ldv_close() call. The OpenLDV driver does not close a network interface until the last ldv_close() function is called. See also ldvx_shutdown() on page 37.
If you attempt to close a network interface that has not been previously opened, or has already been closed, the LDV_NOT_OPEN code is returned. If the handle parameter is not valid, the LDV_INVALID_DEVICE_ID code is returned.
Recommendation: Add a delay of at least one second before you call the ldv_open() function after calling ldv_close() for a particular network interface.

ldv_free_device_info()

Call this function to release resources allocated by the ldv_get_device_info() function.
18 Using the OpenLDV API
function) to be freed.
Syntax
LDVCode ldv_free_device_info( const LDVDeviceInfo* pDeviceInfo )
Table 5. ldv_free_device_info() Parameters
Parameter Direction Description
pDeviceInfo Input A pointer to an LDVDeviceInfo structure (that was
returned by the ldv_get_device_info()
Remarks
Use this function to release resources allocated by the ldv_get_driver_info() function. This function returns LDV_OK if the resources are successfully released.
See Structures and Enumerations for the Device API on page 37 for a description of the LDVDeviceInfo structure.

ldv_free_driver_info()

Call this function to release resources allocated by the ldv_get_driver_info() function.
Syntax
LDVCode ldv_free_driver_info( LDVDriverInfo* pDriverInfo )
Table 6. ldv_free_driver_info() Parameters
Parameter Direction Description
pDriverInfo Input A pointer to an LDVDriverInfo structure (that was
returned by the ldv_get_driver_info() function) to be freed.
Remarks
Use this function to release resources allocated by the ldv_get_driver_info() function. This function returns LDV_OK if the resources are successfully released.
See Structures and Enumerations for the Driver API on page 42 for a description of the LDVDriverInfo structure.
OpenLDV Programmer’s Guide 19

ldv_free_matching_devices()

Call this function to release resources allocated by the ldv_get_matching_devices() function.
Syntax
LDVCode ldv_free_matching_devices( LDVDevices* pDevices )
Table 7. ldv_free_matching_devices() Parameters
Parameter Direction Description
pDevices Input A pointer to an LDVDevices structure (that was returned
by the ldv_get_matching_devices() function) to be freed.
Remarks
Use this function to release resources allocated by the ldv_get_matching_devices() function. This function returns LDV_OK if the resources are successfully released.
See Structures and Enumerations for the Device API on page 37 for a description of the LDVDevices structure.

ldv_get_device_info()

Call this function to retrieve device information about a LONWORKS interface device.
Syntax
LDVCode ldv_get_device_info( LPCSTR szDevice, const LDVDeviceInfo** ppDeviceInfo )
Table 8. ldv_get_device_info() Parameters
Parameter Direction Description
szDevice
ppDeviceInfo Output A pointer to an LDVDeviceInfo pointer that receives the
Input The name of the LONWORKS interface device for which you
are requesting information.
information of the requested device.
20 Using the OpenLDV API
Remarks
Use this function to retrieve device information about a LONWORKS interface device. This function returns LDV_OK if the device information is successfully retrieved. After you retrieve the device information and no longer need it, you must free the device information resources by calling the ldv_free_device_info() function.
The contents of the returned structure is constant (read-only) and cannot be modified.
See Structures and Enumerations for the Device API on page 37 for a description of the LDVDeviceInfo structure.

ldv_get_driver_info()

Call this function to retrieve driver information about a LONWORKS interface device driver.
Syntax
LDVCode ldv_get_driver_info( LDVDriverID nDriverId, LDVDriverInfo** ppDriverInfo )
Table 9. ldv_get_driver_info() Parameters
Parameter Direction Description
nDriverId Input The driver ID of the driver for which you are requesting
information.
ppDriverInfo Output A pointer to an LDVDriverInfo pointer that receives the
information of the requested driver.
Remarks
Use this function to retrieve driver information about a LONWORKS interface device driver. This function returns LDV_OK if the driver information is successfully retrieved. After you retrieve the driver information and no longer need it, you must free the driver information resources by calling the ldv_free_driver_info() function.
The contents of the returned structure should be treated as constant (read-only) and cannot be modified.
See Structures and Enumerations for the Driver API on page 42 for a description of the LDVDriverID enumeration values and the LDVDriverInfo structure.
OpenLDV Programmer’s Guide 21

ldv_get_matching_devices()

Call this function to retrieve information about all LONWORKS interface devices that match a set of capabilities.
Syntax
LDVCode ldv_get_matching_devices( LDVDeviceCaps nCaps, LDVCombineFlags nCombine, LDVDevices* pDevices )
Table 10. ldv_get_matching_devices() Parameters
Parameter Direction Description
nCaps Input An LDVDeviceCaps value for the device capabilities to
match.
nCombine Input The criterion for how the match should be performed. The
criterion is a bitwise combination of one of the LdvCombineFlags values.
pDevices Output A pointer to an LDVDevices structure for the devices whose
capabilities match those requested.
Remarks
Use this function to retrieve information about all LONWORKS interface devices that match a specified set of device capabilities. This function returns LDV_OK if the device information is successfully retrieved. After you retrieve the device information, you must free the device information resources by calling the
ldv_free_matching_devices() function. Do not call the ldv_free_device_info() function for each retrieved device.
The contents of the returned structure should be treated as constant (read-only) and cannot be modified.
See Structures and Enumerations for the Device API on page 37 for a description of the LDVDevices and LDVDeviceCaps structures and the LdvCombineFlags enumeration.

ldv_get_version

Call this function to read the version number of the OpenLDV driver.
Syntax
LPCSTR ldv_get_version( VOID )
22 Using the OpenLDV API
Remarks
This function returns a string for the version number of the OpenLDV driver being used:
OpenLDV 1.0 5.308.09
OpenLDV/LNS 5.320.122
OpenLDV 2.0 5.321.034
OpenLDV 2.1 5.322.002
OpenLDV 3.3 5.330.036
OpenLDV 3.4 5.340.016
OpenLDV 4.0 5.400.102

ldv_locate_sicb()

Call this function to locate the serial interface control block (SICB) portion of the data within an LdvEx (or SICB) formatted message, if present.
Syntax
LDVCode ldv_locate_sicb( PVOID pData, WORD nDataLen, WORD* pnSicbOff, WORD* pnSicbLen )
Table 11. ldv_locate_sicb() Parameters
Parameter Direction Description
pData Input A pointer to a buffer containing an LdvEx (or SICB)
message.
nDataLen Input The length of the buffer containing the LdvEx (or SICB)
message.
pnSicbOff Output A pointer to a variable to receive the offset (in bytes) of the
start of the SICB portion of the specified message.
pnSicbLen Output A pointer to a variable to receive the length (in bytes) of the
SICB portion of the specified message.
Remarks
Use this function to locate the SICB portion of the data within an LdvEx (or SICB) formatted message, if present. Data processed by most OpenLDV
functions use the SICB format; data processed by the ldv_open_cap() function can request to use the extended LdvEx format (which includes the SICB data,
OpenLDV Programmer’s Guide 23
along with other data, such as timestamp data, that could be useful for some applications). See Application Buffer Structure on page 58 for a description of the SICB and LdvEx formats.
This function returns LDV_OK if the SICB data could be located and returned. If an LdvEx packet does not contain an SICB message, the error LDV_NOT_FOUND is returned. If the packet is not well formed (for example, too short), the error LDV_INVALID_DATA_FORMAT is returned.
This function accepts either LdvEx or SICB formatted messages. For an SICB formatted message, this function returns a zero offset and a decoded length.

ldv_open()

Call this function to establish communications between your application and a network interface. This function returns a unique handle that you can provide to the other OpenLDV functions to identify this network session.
Syntax
LDVCode ldv_open( LPCSTR id, LdvHandle* handle )
Table 12. ldv_open() Parameters
Parameter Direction Description
id Input The network interface with which to establish
communication. For example, “LON1” could be used to identify a U10, PCLTA-10, or PCLTA-21 network interface. Or, “X.Default.1MainStreet” could be used to identify a SmartServer that will be opened through xDriver.
handle Output A pointer to a variable that receives a handle which you can
use to identify the network interface with the other OpenLDV functions. This handle is valid only if the function returns LDV_OK. Note that zero is a valid handle.
Remarks
This function returns LDV_OK if the network interface is successfully opened. In this case, the function also returns a handle that you can use to identify the network interface with the other OpenLDV functions. To close the session with the network interface, use the ldv_close() function.
Each successful ldv_open(), ldv_open_cap(), or ldvx_open() call (including nested ones) must have a matching ldv_close() call.
For local network interfaces, after the ldv_open() function returns the LDV_OK success code, the network interface device has been initialized (see below for information about remote network interfaces). For some network interface types,
24 Using the OpenLDV API
the network interface enters an initial quiet mode (flush state) after a reset. To start using such a network interface, the OpenLDV application must cancel the quiet mode with the niFLUSH_CANCEL immediate network interface command. For more information about immediate commands, see Immediate Commands on page 77.
The OpenLDV API clears old data from internal buffers during processing of the ldv_open() function before retrieving new data. Thus, your application does not need to perform this task.
For xDriver-based remote network interfaces that use the xDriver default lookup extension, the name specified as the id parameter should match an entry created for a device with the L Panel. See Chapter 5, Using the xDriver Default Profile, on page 93, for more information. For xDriver-based remote network interfaces that use a custom (non-default) xDriver profile with a custom lookup extension, the name specified as the id parameter must exist in the custom database. See Chapter 6, Extending xDriver, on page 99, for more information.
If you do not specify a valid network interface name as the id parameter when you call this function, or if the network interface referenced by the id parameter cannot be found, the LDV_INVALID_DEVICE_ID or LDVX_INVALID_XDRIVER return code is returned.
ONWORKS Interfaces application in the Windows Control
Each network interface can only be part of one OpenLDV session at a time on a particular computer. If you call this function for a network interface that is being used by another process on your computer, the function will fail, and the LDV_ACCESS_DENIED return code is returned.
If you use xDriver to open a remote network interface while a remote client on another computer is using it, the call to ldv_open() might initially appear to succeed. However, when you call ldv_read() or ldv_write() to read or write a message to the network interface later, the LDVX_READ_FAILED or LDVX_WRITE_FAILED failure code is returned, indicating that the session has failed. The timing of the failure depends on the setting of the Synchronous Timeout field of the xDriver profile that is handling the session. For more information about xDriver profiles, see xDriver Profiles on page 134.

ldv_open_cap()

Call this function to establish communications between your application and a network interface. Additionally, you can request an operational mode for the network interface so that it opens in the specified mode. This function returns a unique handle that you can provide to the other OpenLDV functions to identify this instance of the network interface.
Syntax
LDVCode ldv_open_cap( LPCSTR szDevice, LdvHandle* pHandle, LDVDeviceCaps nDeviceCaps, HWND hWnd, LONG tag )
OpenLDV Programmer’s Guide 25
Table 13. ldv_open_cap() Parameters
Parameter Direction Description
szDevice Input The network interface with which to establish
communication. For example, “LON1” could be used to identify a U10, PCLTA-10, or PCLTA-21 network interface. Or, “X.Default.1MainStreet” could be used to identify a SmartServer that will be opened through xDriver.
pHandle Output A pointer to a variable that you can use to identify the
network interface with the other OpenLDV functions. This handle is valid only if the function returns LDV_OK.
nDeviceCaps Input The requested operational mode for the network interface.
For example, a USB network interface can be opened as a Layer 2 or a Layer 5 network interface by specifying the appropriate LDVDeviceCaps value (LDV_DEVCAP_L2 or LDV_DEVCAP_L5).
hWnd Input The Windows handle for the session state change or
attachment notification messages, where available (for example, from an xDriver device or a USB network interface).
If NULL, no notification messages are sent.
tag Input Correlates notification messages with sessions. This tag is
supplied as the LPARAM parameter of all session state change messages.
Remarks
This function is an extended version of the ldv_open() and ldvx_open() functions that additionally allows you to request the operational mode in which to open the specified device. If supported by the network interface, this function allows you to request Layer 2 or Layer 5 operational mode, or request that communications with the device (the ldv_read() and ldv_write() functions) use the SICB format or the extended LdvEx format (which includes the SICB data). See Application Buffer Structure on page 58 for a description of the SICB and LdvEx formats.
This function returns LDV_OK if the network interface is successfully opened. In this case, the function also returns a handle that you can use to identify the network interface with the other OpenLDV functions. Use the ldv_close() function to close the session with the network interface.
If the device does not support the requested capability, the error LDV_CAPABILITY_NOT_SUPPORTED is returned, and the device is not opened. Note that remote network interfaces (RNIs) are Layer 5 only. Protocol analyzer usage (supported by SmartServers and i.LON 600 RNI devices) is similar to Layer 2 (but receive-only). IP-852 channels cannot be opened by an OpenLDV application.
26 Using the OpenLDV API
For local network interfaces, after the ldv_open_cap() function returns the LDV_OK success code, the network interface device has been initialized (see below for information about remote network interfaces). For some network interface types, the network interface enters an initial quiet mode (flush state) after reset. To start using the network interface, the OpenLDV application must cancel the quiet mode with the niFLUSH_CANCEL immediate network interface command. For more information about immediate commands, see Immediate Commands on page 77.
Each successful ldv_open(), ldv_open_cap(), or ldvx_open() call (including nested ones) must have a matching ldv_close() call.
For xDriver-based remote network interfaces that use the xDriver default lookup extension, the name specified as the szDevice parameter should match an entry created for a device with the L Control Panel. See Chapter 5, Using the xDriver Default Profile, on page 93, for more information. For xDriver-based remote network interfaces that use a custom (non-default) xDriver profile with a custom lookup extension, the name specified as the id parameter must exist in the custom database. See Chapter 6, Extending xDriver, on page 99, for more information.
If you do not specify a valid network interface name as the szDevice parameter when you call this function, or if the network interface referenced by the szDevice parameter cannot be found, the LDV_INVALID_DEVICE_ID or LDVX_INVALID_XDRIVER return code is returned.
ONWORKS Interfaces application in the Windows
Each network interface can only be part of one OpenLDV session at a time on a particular computer. If you call this function for a network interface that is being used by another process on your computer, the function will fail, and the LDV_ACCESS_DENIED return code is returned.
If you use xDriver to open a remote network interface while a remote client on another computer is using it, the call to ldv_open_cap() might initially appear to succeed. However, when you call ldv_read() or ldv_write() to read or write a message to the network interface later, the LDVX_READ_FAILED or LDVX_WRITE_FAILED failure code is returned, indicating that the session has failed. The timing of the failure depends on the setting of the Synchronous Timeout field of the xDriver profile that is handling the session, as well as the setting of the TcpMaxConnectRetransmissions parameter on the computer that is running the application. For more information about xDriver profiles, see xDriver Profiles on page 134.

ldv_read()

Call this function to read an uplink message from a network interface.
Syntax
LDVCode ldv_read( LdvHandle handle,
PVOID msg_p, SHORT len
)
OpenLDV Programmer’s Guide 27
Table 14. ldv_read() Parameters
Parameter Direction Description
handle
msg_p Output A pointer to a buffer allocated by your application that will
len Input The length of the application buffer to receive the message,
Input The network interface device to be read. This value was
returned as the handle parameter when you opened the network interface with one of the open functions (ldv_open(), ldv_open_cap(), or ldvx_open()).
receive the next uplink message. You must provide a sufficiently large buffer to receive each message. The length of this buffer is specified by the len parameter.
For information about the different uplink messages you might read with this function, and descriptions of the application buffer structure that each one uses, see Chapter 3, Sending and Receiving Messages with the OpenLDV API, on page 57.
in bytes.
For communications that use the SICB format, the maximum length of a message is 257 bytes. When possible, use a buffer length of at least 257 bytes. For communications that use the LdvEx format, allocate additional buffer space.
Remarks
All messages from a network interface are buffered by the OpenLDV runtime until a client application reads them with this function. You can program your application to poll the network interface for incoming messages by periodically calling this function. The function returns LDV_OK when it has successfully read a message from the network interface, or returns LDV_NO_MSG_AVAIL if no messages are currently available. Alternatively, you can use the ldv_register_event() function to set up an event to signal the receipt of each new message. For each poll loop within your application, you should call the ldv_read() function until you receive LDV_NO_MSG_AVAIL.
Most incoming messages will be responses to prior requests or unsolicited messages (such as network variable updates or application messages). Although incoming messages are buffered, the OpenLDV application must process these messages and provide suitable responses to the L fashion. The acceptable duration for providing these responses depends on the arrival rate of messages from the network, the number of buffers in the network interface driver involved, and the speed and current processing load of the computer running the application. Therefore, the OpenLDV application must process all incoming messages promptly, and with high priority.
The ldv_read() function returns LDV_INVALID_BUF_LEN if the specified buffer is too small to contain the next incoming message. In this case, allocate a larger buffer to receive the message, and call the function again, specifying a larger value for the len input parameter. For communications that use the SICB
ONWORKS network, in a timely
28 Using the OpenLDV API
format, the maximum length of a message is 257 bytes, and so you should use a buffer length of at least 257 bytes to guarantee that any message can be buffered. If your device uses the LdvEx format, you must allocate additional buffer space.
If the handle parameter is not valid, the LDV_INVALID_DEVICE_ID code is returned. If the network interface referenced by the handle parameter has not been opened by your process, then the LDV_NOT_OPEN code is returned if the handle references a local network interface. If the handle references a failed remote network interface, or if the session has failed, the LDVX_READ_FAILED code is returned.

ldv_register_event()

Call this function to register a Windows event object to be signaled whenever a message is available to be read from a network interface.
Syntax
LDVCode ldv_register_event( LdvHandle handle, HANDLE event )
Table 15. ldv_register_event() Parameters
Parameter Direction Description
handle
event Input The Windows event object to be signaled each time a
Input The network interface device that will cause the Windows
event object to be signaled. This value was returned as the handle parameter when you opened the network interface with one of the open functions (ldv_open(), ldv_open_cap(), or ldvx_open()).
message is received. You can use the Windows CreateEvent() and CloseHandle() functions to create and destroy a Windows event object suitable for use with the ldv_register_event() function.
Remarks
Use this function to register for notification of incoming messages from the network interface. When the network interface receives a message, the Windows event object referenced by the event parameter is signaled.
This event signals the availability of one or more messages to be read. When the Windows event object is signaled, the OpenLDV application should call the ldv_read() function repeatedly until all available uplink messages have been read.
OpenLDV Programmer’s Guide 29
To de-register a current event and register a new event, call
ldv_register_event()with a new event parameter. You can also call the ldv_register_event() function and specify NULL as the event parameter to
disable event notifications for a network interface.
If the handle parameter is not valid, the LDV_INVALID_DEVICE_ID code is returned. If the network interface referenced by the handle parameter is not open, then the LDV_NOT_OPEN code is returned. If the function fails to register the Windows event object, the LDVX_REGISTER_FAILED code is returned.

ldv_set_device_info()

Call this function to create or modify the information for a specified LONWORKS interface device. Applications that configure network interfaces (such as the Echelon L
ONWORKS Interfaces control panel application) can use this function.
Syntax
LDVCode ldv_set_device_info( LPCSTR szDevice, const LDVDeviceInfo* pDeviceInfo )
Table 16. ldv_set_device_info() Parameters
Parameter Direction Description
szDevice Input The name of the LONWORKS interface device that you are
creating or modifying.
pDeviceInfo Input A pointer to an LDVDeviceInfo structure that contains the
information for the created or modified device.
Remarks
Use this function to create or modify information for a LONWORKS interface device. This function returns LDV_OK if the device information is successfully updated. Otherwise, it returns a failure code (such as LDV_DEVICE_INFO_INVALID).
Before you call this function, you must initialize the LDVDeviceInfo structure:
Set the size field equal to the size of the LDVDeviceInfo structure.
The driver field is ignored by this function. Use the driverId field to
specify the driver for the device.
The name field is ignored by this function. The logical name of the device is read only and cannot be modified by this function.
Set the physName field to the physical name of the new device, or set it to NULL or an empty string if the physical device name is not to be modified. For a custom network interface that uses a Windows driver,
30 Using the OpenLDV API
specify the Windows device path, for example, \\.\MYLON1.0. See Appendix A, Custom Network Interfaces, on page147, for more information about custom network interfaces.
Set the desc field to the description of the new device, or set it to NULL or an empty string if the device description is not to be modified.
Set the caps and capsMask fields according to the capabilities of the device.
Set the transId field to the transceiver ID for the device.
Set the driverId field to an LdvDriverID value that corresponds to the
driver ID of the device that you are creating or modifying, or set it to
-1 if the driver ID is not to be modified.
See Structures and Enumerations for the Device API on page 37 for a description of the LDVDeviceInfo structure. See Structures and Enumerations for the Driver API on page 42 for a description of the LDVDriverID enumeration values.
To modify individual fields (read-modify-write) for an existing device, perform the following steps:
1. Retrieve the current information using the ldv_get_device_info() function.
2. Allocate and initialize a new LDVDeviceInfo structure.
3. Copy unchanging fields from the old structure into the new. For strings that are not being modified, set them to NULL.
4. Set the fields to be changed in the new structure.
5. Call the ldv_set_device_info() function.
6. Deallocate the new structure.
7. Release the old resources by calling the ldv_free_device_info() function.
See Working with a Custom Network Interface on page 148 for an example of how to use this function.

ldv_set_driver_info()

Call this function to create or modify the information for a specified LONWORKS interface device driver.
Syntax
LDVCode ldv_set_driver_info( LDVDriverID nDriverId, const LDVDriverInfo* pDriverInfo )
OpenLDV Programmer’s Guide 31
Table 17. ldv_set_driver_info() Parameters
Parameter Direction Description
nDriverId Input The driver ID of the driver that you are creating or
modifying.
pDriverInfo Input A pointer to an LDVDriverInfo structure that contains the
information for the created or modified driver.
Remarks
Use this function to create or modify information for a LONWORKS interface device driver. This function returns LDV_OK if the driver information is successfully updated. Otherwise, it returns a failure code (such as
LDV_DRIVER_INFO_INVALID, LDV_DRIVER_UPDATE_FAILED, or LDV_STD_DRIVER_TYPE_READ_ONLY).
Before you call this function, you must initialize the LDVDriverInfo structure:
Set the size field equal to the size of the LDVDriverInfo structure.
The id field is ignored by this function. The driver ID is read only, and
cannot be modified using this function.
Set the type field to an LdvDriverType value that corresponds to the new driver type, or set it to -1 if the driver type is not to be modified. The driver type is read-only for standard driver IDs, and cannot be modified using this function; however, non-standard drivers can have their driver type set.
Set the name field to the name of the new driver type, or set it to NULL
Set the desc field to the description of the new driver type, or set it to
See Structures and Enumerations for the Driver API on page 42 for a description of the LDVDriverID enumeration values and the LDVDriverInfo structure.
See Working with a Custom Network Interface on page 148 for an example of how to use this function.

ldv_write()

Call this function to write a message to the network interface, or to send a message through the network interface to a device on the network.
Syntax
LDVCode ldv_write( LdvHandle handle,
PVOID msg_p, SHORT len
)
or an empty string if the driver name is not to be modified.
NULL or an empty string if the driver description is not to be modified.
32 Using the OpenLDV API
Table 18. ldv_write() Parameters
Parameter Direction Description
handle
msg_p Input A pointer to a buffer that contains the message to be written
len Input The length of the message to be written. This length might
Input The LONWORKS interface device to be written. This value
was returned as the handle parameter when you opened the network interface with one of the open functions (ldv_open(), ldv_open_cap(), or ldvx_open()).
to the network interface.
For information about the different message commands that you can send with this function, and descriptions of the application buffer structure that each one requires, see Chapter 3, Sending and Receiving Messages with the OpenLDV API, on page 57.
not match the length of buffer referenced by the msg_p parameter. The len parameter should reflect how many bytes will be written to the network interface, and should therefore be less than or equal to the length of the buffer referenced by the msg_p parameter.
Remarks
This function returns LDV_OK if the message is successfully written to the network interface.
If the handle parameter is not valid, the LDV_INVALID_DEVICE_ID code is returned. If the network interface referenced by the handle parameter is not open, then the LDV_NOT_OPEN code is returned if it is a local network interface. If it is a remote network interface, the LDVX_WRITE_FAILED code is returned.
Be sure to use the message format (SICB or LdvEx) that corresponds to the format specified when the network interface was opened.

ldv_xlate_device_name()

Call this function to retrieves the physical name of the Windows device that is associated with a (logical) network interface name.
Legacy device drivers (for example, for PCC-10 or PCLTA-21 network interfaces) can use the translated name to access the driver directly. In general, however, using the translated name is not recommended.
OpenLDV Programmer’s Guide 33
Syntax
LDVCode ldv_xlate_device_name( LPCSTR device_name,
LPSTR driver_name, int* driver_name_len
)
Table 19. ldv_xlate_device_name() Parameters
Parameter Direction Description
device_name Input The name of the network interface.
driver_name Output A pointer to a buffer to receive the physical name.
driver_name_len Input
Output
Remarks
This function returns LDV_OK if the physical name for the network interface is successfully retrieved.

ldvx_open()

Call this function to establish communications between your application and a network interface. This function also registers a Windows HWND object for receiving session state change notifications and returns a unique handle that you can provide to the other OpenLDV functions to identify this instance of the network interface.
Syntax
LDVCode ldvx_open( LPCSTR id, LdvHandle* handle, HWND hWnd, LONG tag )
A pointer to the length of the buffer that will receive the physical name.
On return, set to the length of the returned name.
34 Using the OpenLDV API
Table 20. ldvx_open() Parameters
Parameter Direction Description
id Input The LONWORKS interface device with which to establish
communication. For example, “LON1” could be used to identify a U10, PCLTA-10, or PCLTA-21 network interface. Or, “X.Default.1MainStreet” could be used to identify a SmartServer that will be opened through xDriver.
handle Output A pointer to a variable that you can use to identify the
network interface with the other OpenLDV functions. This handle is valid only if the function returns LDV_OK.
hWnd Input The Windows handle for the session state change or
attachment notification messages, where available (for example, from an xDriver device or a USB network interface).
If NULL, no notification messages are sent.
See Windows Messages for Session Notifications on page 44.
tag Input Correlates notification messages with sessions. This tag is
supplied as the LPARAM parameter of all session state change messages.
Remarks
This function is an extended version of the ldv_open() function that additionally allows you to specify a Windows handle and tag for session state change or attachment notificatgion messages. This function returns LDV_OK if the network interface is successfully opened. In this case, the function also returns a handle that you can use to identify the network interface with the other OpenLDV functions. You can use the ldv_close() function to close the session with the network interface.
For local network interfaces, after the ldvx_open() function returns the LDV_OK success code, the network interface device has been initialized (see below for information about remote network interfaces). For some network interface types, the network interface enters an initial quiet mode (flush state) after reset. To start using the network interface, the OpenLDV application must cancel the flush state with the niFLUSH_CANCEL immediate network interface command. For more information about immediate commands, see Immediate Commands on page 77.
Each successful ldv_open(), ldv_open_cap(), or ldvx_open() call (including nested ones) must have a matching ldv_close() call.
For xDriver-based remote network interfaces that use the default xDriver lookup extension, the name specified as the id parameter must match an entry created for a device with the L Panel. See Chapter 5, Using the xDriver Default Profile, on page 93, for more
OpenLDV Programmer’s Guide 35
ONWORKS Interfaces application in the Windows Control
information. If you do not specify a valid network interface name as the id parameter when you call this function, or if the network interface referenced by the id parameter cannot be found, the LDV_INVALID_DEVICE_ID or LDVX_INVALID_XDRIVER return code is returned.
Each network interface can only be part of one OpenLDV session at a time on a particular computer. If you call this function for a network interface that is being used by another process on your computer, the function will fail, and the LDV_ACCESS_DENIED return code is returned.
If you use xDriver to open a remote network interface while a remote client on another computer is using it, the call to ldvx_open() might initially appear to succeed. However, when you call ldv_read() or ldv_write() to read or write a message to the network interface later, the LDVX_READ_FAILED or LDVX_WRITE_FAILED failure code is returned, indicating that the session has failed. The timing of the failure depends on the setting of the Synchronous Timeout field of the xDriver profile that is handling the session, as well as the setting of the TcpMaxConnectRetransmissions parameter on the computer that is running the application. For more information about xDriver profiles, see xDriver Profiles on page 134.

ldvx_register_window()

Call this function to register a Windows HWND object for receiving session change notifications.
Syntax
LDVCode ldvx_register_window( LdvHandle handle, HWND hWnd, LONG tag )
Table 21. ldvx_register_window() Parameters
Parameter Direction Description
handle
hWnd Input The Windows handle for the session state change or
Input The session handle for the network interface. This value
was returned as the handle parameter when you opened the network interface with one of the open functions (ldv_open(), ldv_open_cap(), or ldvx_open()).
attachment notification messages, where available (for example, from an xDriver device or a USB network interface). This handle replaces any previously set handle (such as one from one of the open functions).
If NULL, OpenLDV stops sending notifications.
See Windows Messages for Session Notifications on page 44.
36 Using the OpenLDV API
Parameter Direction Description
tag Input Correlates notification messages with sessions. This tag is
supplied as the LPARAM parameter of all session state change messages.
Remarks
Use this function to register a Windows HWND object for receiving session change notifications. This handle is the same as that passed to one of the open functions (ldv_open(), ldv_open_cap(), or ldvx_open()).

ldvx_shutdown()

Call this function to cleanly shut down the OpenLDV driver before exiting your application.
Syntax
LPCSTR LDVAPI ldvx_shutdown( VOID )
Remarks
Call this function once before allowing the application to exit to avoid delays on shutdown. After you call this function, you cannot access the OpenLDV driver again.

Structures and Enumerations for the Device API

This section describes the structures and enumerations defined for the OpenLDV device API.

LDVDeviceInfo Structure

The device API functions refer to the LDVDeviceInfo structured data type:
typedef struct LDVDeviceInfo { DWORD size; const LDVDriverInfo* driver; LPCSTR name; LPCSTR physName; LPCSTR desc; LDVDeviceCaps caps; LDVDeviceCaps capsMask; BYTE transId; LDVDriverID driverId; } LDVDeviceInfo;
OpenLDV Programmer’s Guide 37
/* (read-only) */ typedef const LDVDeviceInfo* LDVDeviceInfoPtr;
The LDVDeviceInfo structure contains information that describes a specific
ONWORKS interface device (identified by its name). Table 22 describes the
L
LDVDeviceInfo structure’s fields.
Table 22. LDVDeviceInfo Structure
Field Description
size The size (in bytes) of this structure. This field must be set
before calling any of the set functions that pass this structure as a parameter.
driver A pointer to a driver information object that describe the driver
for the device. See the LDVDriverInfo in Structures and Enumerations for the Driver API on page 42.
Ignored by the ldv_set_device_info() function.
name A string that contains the name of the logical device.
physName A string that contains the name of the physical device, if
applicable. If not applicable, returns the logical name.
desc A string that contains the description of the device driver, if
available.
caps A combination of LDVDeviceCaps values that describes the
capabilities of this device, where known. See LDVDeviceCaps in Table 25.
capsMask A combination of LDVDeviceCaps values that describes which
of the capability bits are valid. See LDVDeviceCaps in Table
25.
transId The transceiver ID of the device, if known.
A value of -1 signifies “unknown” or “don’t change”.
driverId The device driver ID of the associated driver. See LdvDriverID
in Table 27.
See the following functions for their use of this structure: ldv_get_device_info() on page 20, ldv_set_device_info() on page 30, and ldv_free_device_info() on page
18.

LDVDevices Structure

The device API functions refer to the LDVDevices structured data type:
38 Using the OpenLDV API
typedef struct LDVDevices { DWORD nInfos; LDVDeviceInfoPtr* pInfos;
} LDVDevices;
The LDVDevices structure contains information that describes a set of
ONWORKS interface devices. Table 23 describes the LDVDevices structure’s
L fields.
Table 23. LDVDevices Structure
Field Description
nInfos The number of Device Info pointers in the array.
pInfos An array of Device Info pointers. See LDVDeviceInfo Structure
on page 37 for information about the LDVDeviceInfo structure.
See the following functions for their use of this structure: ldv_get_matching_devices() on page 22 and ldv_free_matching_devices() on page
20.

LdvCombineFlags Enumeration

Table 24 describes the enumerated values for the LdvCombineFlags device capability combination flags. The device capability combination flags specify how multiple bits are combined when determining device capability support.
Table 24. OpenLDV Device Capability Combination Flags (LdvCombineFlags)
Numeric
Driver Type
LDV_COMBINE_DEFINITELY_ALL 0 All of the specified capabilities must
LDV_COMBINE_POSSIBLY_ALL 1 All of the specified capabilities must
LDV_COMBINE_DEFINITELY_ANY 2 Any of the specified capabilities must
LDV_COMBINE_POSSIBLY_ANY 3 Any of the specified capabilities must
The two enumeration values *_ALL specify an AND of the device capabilities, whereas the two *_ANY values specify an OR of the device capabilities.
Value Description
definitely exist
possibly exist
definitely exist
possibly exist
See the ldv_free_matching_devices() function on page 20 for its use of this enumeration.
Example: To return all devices that are currently defined as protocol analyzers, use the ldv_get_matching_devices() function:
OpenLDV Programmer’s Guide 39
1. Set the nCaps to LDV_DEVCAP_PA to specify protocol analyzer capability.
2. Set nCombine to LDV_COMBINE_DEFINITELY_ALL (or LDV_COMBINE_DEFINITELY_ANY) to specify that the function should return all devices that definitely are defined as protocol analyzers.
If you want the function to return all devices that are definitely protocol analyzers along with devices that might be protocol analyzers (devices with multiple capabilities), specify LDV_COMBINE_POSSIBLY_ALL (or LDV_COMBINE_POSSIBLY_ANY).
3. Prepare the pDevices output buffer for the returned results.
LDVCode rc = ldv_get_matching_devices( LDV_DEVCAP_PA, LDV_COMBINE_DEFINITELY_ALL, *myPA_List);

LdvDeviceCaps Enumeration

Table 25 describes the enumerated values for the LdvDeviceCaps device capabilities, which describes the capabilities of a L These constants can be OR’ed together for L support multiple capabilities.
ONWORKS interface device.
ONWORKS interface devices that
See ldv_open_cap() on page 25 for information about how to specify device capabilities.
Table 25. OpenLDV Device Capabilities (LdvDeviceCaps)
Numeric
Device Capability
LDV_DEVCAP_UNKNOWN 0x00000000 An unknown device, or a
LDV_DEVCAP_L5 0x00000001 The device can operate as a
LDV_DEVCAP_L2 0x00000002 The device can operate as a
LDV_DEVCAP_LWIP 0x00000010 The device can operate as an
Value Description
device whose capabilities cannot be determined
Layer 5 network interface.
Layer 2 network interface.
IP-852 device or channel.
These types of devices are implemented within the LNS Server and cannot be opened using the OpenLDV API.
LDV_DEVCAP_PA 0x00000020 The device can operate as a
protocol analyzer interface.
40 Using the OpenLDV API
Numeric
Device Capability
LDV_DEVCAP_XDRIVER 0x00000040 The device is an xDriver-based
LDV_DEVCAP_SICB 0x00000100 The device uses SICB-
LDV_DEVCAP_LDVEX 0x00000200 The device uses LdvEx-
LDV_DEVCAP_NOSTATUS 0x00000800 The device does not support
LDV_DEVCAP_SWITCHABLE 0x00001000 The device can switch between
Value Description
device.
The network interface is physically remote from the host computer.
formatted packets.
formatted packets.
the niSTATUS command.
operations as a Layer 5 or a Layer 2 network interface.
LDV_DEVCAP_ATTACHABLE 0x00002000 The device can be attached or
detached from the host computer, for example, by connecting to or disconnecting from a USB hub.
You can receive attachment and detachment notifications for this device by registering a Windows handle using the ldvx_register_window() function.
LDV_DEVCAP_CURRENTLY_L5 0x00010000 The device is currently
operating as a Layer 5 network interface.
LDV_DEVCAP_CURRENTLY_L2 0x00020000 The device is currently
operating as a Layer 2 network interface.
LDV_DEVCAP_CURRENTLY_ATTACHED 0x20000000 The device is currently
attached to the host computer.
This capability applies to devices that can be physically removed and maintain their device entries remain. Such devices include U10 and U20 USB network interfaces.
OpenLDV Programmer’s Guide 41
Numeric
Device Capability
LDV_DEVCAP_CURRENTLY_AVAILABLE 0x40000000 The device is currently not in
Value Description
use by any process on this computer. If it is not is use by another computer, the device is available for use.

Structures and Enumerations for the Driver API

This section describes the structure and enumerations defined for the OpenLDV driver API.

LDVDriverInfo Structure

The driver API functions refer to the LDVDriverInfo structured data type:
typedef struct LDVDriverInfo { DWORD size; LDVDriverID id; LDVDriverType type; LPCSTR name; LPCSTR desc; } LDVDriverInfo;
/* (read-only) */ typedef const LDVDriverInfo* LDVDriverInfoPtr;
The LDVDriverInfo structure contains information that describes a specific
ONWORKS interface device driver (identified by its driver ID). Table 26
L describes the LDVDriverInfo structure’s fields.
Table 26. LDVDriverInfo Structure
Field Description
size The size (in bytes) of this structure. This field must be set
before calling any of the set functions that pass this structure as a parameter.
id The LONWORKS interface device driver ID. See LdvDriverID
Enumeration on page 43.
type The device driver type. See LdvDriverType Enumeration on
page 44.
name A string that contains the name of the device driver.
desc A string that contains the description of the device driver, if
available.
42 Using the OpenLDV API
See the following functions for their use of this structure: ldv_get_driver_info() on page 21, ldv_set_driver_info() on page 31, and ldv_free_driver_info() on page
19.

LdvDriverID Enumeration

Table 27 describes the enumerated values for the LdvDriverID driver identifier (ID). The driver ID describes the driver class of an associated network interface.
LdvDriverID enumeration values less than 127 define Echelon network interfaces. To define your own network interface type, use an enumeration value greater than 128.
Table 27. OpenLDV Driver Identifier (LdvDriverID)
Numeric
Driver ID
LDV_DRIVERID_UNKNOWN 0 An unknown network interface type, or a
LDV_DRIVERID_ILON 1 An undetermined i.LON Ethernet Adapter
Value Description
type that cannot be determined
LDV_DRIVERID_ILON10 2 An i.LON 10 Ethernet Adapter
LDV_DRIVERID_ILON100 3 A SmartServer or i.LON 100 Internet
Server
LDV_DRIVERID_ILON600 4 An i.LON 600 IP-852 Router
LDV_DRIVERID_LWIP 5 An IP-852 device or channel implemented
by an LNS Server
LDV_DRIVERID_USBLTA 6 A U10 or U20 USB Network Interface
LDV_DRIVERID_SLTA10 7 An SLTA-10 Serial LonTalk Adapter
LDV_DRIVERID_PCC10 8 A PCC-10 PC Card Network Interface
LDV_DRIVERID_PCLTA10 9 A PCLTA-10 PC LonTalk Adapter
LDV_DRIVERID_PCLTA20 10 A PCLTA-20/SMX PCI Network Interface
LDV_DRIVERID_PCLTA21 11 A PCLTA-21 PCI Network Interface
LDV_DRIVERID_TA 12 A turnaround channel
LDV_DRIVERID_RNISIM 13 A remote network interface (RNI)
simulator
LDV_DRIVERID_STD_MAX 127 The maximum enumeration value for
Echelon network interface types
OpenLDV Programmer’s Guide 43

LdvDriverType Enumeration

Table 28 describes the enumerated values for the LdvDriverType driver type. The driver type describes the driver type of an associated network interface.
LdvDriverType enumeration values less than 127 define types of Echelon network interface drivers. To define your own network interface type, use an enumeration value greater than 128.
Table 28. OpenLDV Driver Type (LdvDriverType)
Numeric
Driver Type
LDV_DRIVERTYPE_UNKNOWN 0 An unknown network interface type, or a
LDV_DRIVERTYPE_LNI 1 A local network interface driver
LDV_DRIVERTYPE_RNI 2 A remote network interface driver
LDV_DRIVERTYPE_USB 3 A USB LonTalk Adapter driver
LDV_DRIVERTYPE_STD_MAX 127 The maximum enumeration value for
Value Description
type that cannot be determined
(Windows)
(xDriver)
Echelon network interface types

Windows Messages for Session Notifications

Table 29 describes the defined values for the Windows messages for session change notifications used by the ldvx_open() and ldvx_register_window() functions.
Table 29. Windows Messages for Session Change Notifications
Message Definition Value
LDVX_WM_CLOSED LDVX_APP + 0 34408
LDVX_WM_CONNECTING LDVX_APP + 1 34409
LDVX_WM_ESTABLISHED LDVX_APP + 2 34410
LDVX_WM_FAILED LDVX_APP + 3 34411
LDVX_WM_DETACHED LDVX_APP + 4 34412
LDVX_WM_ATTACHED LDVX_APP + 5 34413
Note: LDVX_APP is defined as 34408 (WM_APP + 1640).
44 Using the OpenLDV API

OpenLDV API Return Codes

Table 30 describes the return codes that can be returned by the OpenLDV API functions. These codes are defined in the LDVCode enumeration.
Table 30. OpenLDV Return Codes
Numeric
Return Code
LDV_OK 0 The operation completed
LDV_NOT_FOUND 1 This code is returned if you
Value Description
successfully.
call any of the open functions to open a L device, but you do not specify a valid device name as the id parameter, or the device referenced by the id parameter cannot be found.
ONWORKS interface
This code is also returned for the ldv_locate_sicb() function if an LdvEX packet does not contain an SICB message.
LDV_ALREADY_OPEN 2 This return code is obsolete.
LDV_NOT_OPEN 3 The LONWORKS interface
device is not open. This code is returned if you use the ldv_read() or ldv_write() functions to read or write a message to a network interface device, or if you use the ldv_close() function to close a session with a network interface, and the network interface has not yet been opened with the ldv_open() function (or the network interface has already been closed).
OpenLDV Programmer’s Guide 45
Numeric
Return Code
Value Description
LDV_DEVICE_ERR 4 This code is returned if a
function fails to execute as a result of a failure to communicate with the network driver. Call ldv_close() to close the network interface and release the resources assigned to the network driver. Then, re-open the network interface with one of the open functions.
LDV_INVALID_DEVICE_ID 5 This code is returned if you
specify an invalid device name when opening a L
ONWORKS
interface device with one of the open functions, or an invalid handle when using any of the other OpenLDV functions. Ensure that the id input parameter for the name of the device is valid.
LDV_NO_MSG_AVAIL 6 No message is available to be
read. This code is returned if you call ldv_read(), and there are no uplink messages from the network interface that have not yet been read. You can use the ldv_register_event() function to receive notification events when messages are available to be read from the network interface.
LDV_NO_BUFF_AVAIL 7 No buffer is available. This
code is returned if you call ldv_write(), and there is no available buffer on the local network interface to which to write the message. Wait until a buffer becomes available and try writing the message again.
46 Using the OpenLDV API
Numeric
Return Code
LDV_NO_RESOURCES 8 No resources are available.
LDV_INVALID_BUF_LEN 9 This code is returned if you
Value Description
This code is returned if the OpenLDV API has assigned too many session handles, or if the computer running your application has memory allocation problems. Close any non-essential processes running on your computer and try the operation again.
call ldv_read() to read a message from a L interface device, and the specified buffer is not big enough to contain the next incoming message. Allocate a larger buffer to receive the message and then call ldv_read() again with a larger value for the len input parameter. The message remains as the next incoming message until you successfully read it with the ldv_read() function.
ONWORKS
Recommendation: Allocate a buffer of at least 257 bytes (the maximum size of an SICB format incoming message) each time you call ldv_read(). If your device uses the LdvEx format, you must allocate additional buffer space.
LDV_NOT_ENABLED 10 This return code is obsolete.
LDVX_INITIALIZATION_FAILED 11 The remote network interface
(RNI) could not be initialized. Generally, this code is returned if there are configuration problems on the network interface that you are opening or on the computer that is running your application.
OpenLDV Programmer’s Guide 47
Numeric
Return Code
LDVX_OPEN_FAILED 12 The remote network interface
LDVX_CLOSE_FAILED 13 The remote network interface
LDVX_READ_FAILED 14 The application failed to read
LDVX_WRITE_FAILED 15 The application failed to write
Value Description
(RNI) could not be opened.
(RNI) could not be closed.
the message as a result of a generic failure during the call to ldv_read(). If you encounter this return code persistently, close the current session and start a new one, because the current session might have failed.
the message as a result of a generic failure during the call to ldv_write(). If you encounter this return code persistently, close the current session and start a new one, because the current session might have failed.
LDVX_REGISTER_FAILED 16 The application failed to
register the Windows event object for event notification.
48 Using the OpenLDV API
Numeric
Return Code
LDVX_INVALID_XDRIVER 17 This code is returned if you
Value Description
attempt to open an xDriver
ONWORKS interface device
L with the ldv_open() function, and the xDriver lookup extension component fails to find that network interface.
For devices that use the default profile, use the
ONWORKS Interfaces
L application in the Windows Control Panel to verify that the network interface referenced by the id parameter exists. For information about lookup extension components, see Appendix C, Custom Lookup
Extension Component Programming, on page 161.
LDVX_DEBUG_FAILED 18 This return code is reserved.
LDVX_ACCESS_DENIED 19 This code is returned if you
call ldv_open() to initialize a
ONWORKS interface device
L that is already opened by another process on your computer. OpenLDV does not support concurrent access to network interfaces between multiple processes on the same computer. For more information on this, see Using
Multiple Threads or Multiple Processes on page 14.
LDV_CAPABLE_DEVICE_NOT_FOUND 20 No OpenLDV LONWORKS
interface device was found for the ldv_get_matching_devices() or ldv_open_cap() function.
LDV_NO_MORE_CAPABLE_DEVICES 21 No additional OpenLDV
devices were found for the ldv_get_matching_devices() function.
OpenLDV Programmer’s Guide 49
Numeric
Return Code
Value Description
LDV_CAPABILITY_NOT_SUPPORTED 22 The capability specified for the
ldv_open_cap() function is not supported by the device.
LDV_INVALID_DRIVER_INFO 23 The driver information
specified for the ldv_set_driver_info() function is not valid.
LDV_INVALID_DEVICE_INFO 24 The device information
specified for the ldv_set_device_info() function is not valid.
LDV_DEVICE_IN_USE 25 The device is in use and
cannot be opened with any of the open functions.
LDV_NOT_IMPLEMENTED 26 The OpenLDV interface is not
implemented on the
ONWORKS interface device
L being opened.
LDV_INVALID_PARAMETER 27 An invalid parameter was
specified.
LDV_INVALID_DRIVER_ID 28 The driver identifier is not
valid.
LDV_INVALID_DATA_FORMAT 29 This code is returned for the
ldv_locate_sicb() function if the data packet is not well formed (for example, too short).
LDV_INTERNAL_ERROR 30 The OpenLDV API
experienced in an internal error. Contact Echelon Support.
LDV_EXCEPTION 31 The OpenLDV API
experienced in an internal error. Contact Echelon Support.
LDV_DRIVER_UPDATE_FAILED 32 The driver information
specified for the ldv_set_driver_info() function could not be updated.
50 Using the OpenLDV API
Numeric
Return Code
LDV_DEVICE_UPDATE_FAILED 33 The device information
LDV_STD_DRIVER_TYPE_READ_ONLY 34 The driver information
LDV_OUTPUT_BUFFER_SIZE_MISMATCH 40 Output buffer sizes (for both
Value Description
specified for the ldv_set_device_info() function could not be updated.
specified for the ldv_set_driver_info() function could not be updated because the driver type is read only.
priority and non-priority buffers) must be the same.
Applies to APP/NET buffers on the network interface.
LDV_INVALID_BUFFER_PARAMETER 41 The specified buffer parameter
is not valid (for example, the specified size is too large).
Applies to APP/NET buffers on the network interface.
LDV_INVALID_BUFFER_COUNT 42 The specified buffer count is
not valid.
Applies to APP/NET buffers on the network interface.
LDV_PRIORITY_BUFFER_COUNT_MISMATCH 43 All priority buffers must have
the same count. For example, if one of the priority output buffer counts is zero, then both must be zero.
Applies to APP/NET buffers on the network interface.
LDV_BUFFER_SIZE_TOO_SMALL 44 The specified buffer size is too
small to support subsequent buffer configuration changes.
Applies to APP/NET buffers on the network interface.
OpenLDV Programmer’s Guide 51
Numeric
Return Code
Value Description
LDV_BUFFER_CONFIGURATION_TOO_LARGE 45 The specified buffer
configuration is too large to fit in the available space.
Applies to APP/NET buffers on the network interface.
LDV_WARNING_APP_BUFFER_SIZE_MISMATCH 46 Warning message that the
buffer size mismatch might cause problems.
Applies to APP/NET buffers on the network interface.

Example: A Simple OpenLDV Application

The following code sample shows a very simple OpenLDV application that works with an Echelon USB Network Interface. In this example, the application performs the following tasks:
1. Opens the network interface
2. Writes a Query Status command to the interface to retrieve the interface’s current state; from the current state, extracts the network interface’s error log and prints a message
3. Reads the response to the Query Status command
4. Closes the network interface
5. Shuts down the OpenLDV driver
A real application would perform the same basic set of tasks, but typically for additional devices beyond just the network interface. Also, a real application would query the local device database to determine which network interface to use; this example simply uses LON1. An application might also define the network address for the network interface and for network devices; this example uses local network addressing.
This example uses definitions found in the OpenLDVdefinitions.h header file, which is included with the OpenLDV Developer Example; see Chapter 4, The OpenLDV Developer Example, on page 89. It also includes the NetMgmt.h header file, which is installed to the L
ONWORKS \NeuronC\Include directory
with the NodeBuilder FX Developer’s Kit or the Mini FX Evaluation Kit.
// Include Windows header file #include <windows.h>
// Include OpenLDV header file #include “ldv32.h”
// Include Neuron C Network Management header file // (contains definition for ND_query_status_response) #include “netmgmt.h”
52 Using the OpenLDV API
// Include the header file from the OpenLDV API Example // (contains definitions for ExpMsgHdr, ExpAppBuffer, niNTQ, niNETMGMT) #include "OpenLdvDefinitions.h"
// Define Network Management commands // from ISO/IEC 14908 Control Networking Protocol spec #define LonNdQueryStatus 0x51 // Query Status command #define LonNdQueryStatusSuccess 0x31 // Success Response for Query Status
// // Variable Definitions //
// Handle for Windows event calls HANDLE hEvent = NULL;
// Return code for ldv_* calls. LDVCode rc = LDV_OK; // Assume OK result
// Handle used for ldv_* calls. -1 (minus 1) if not valid. short m_OpenLdvHandle;
// Flag to signal whether it’s Ok to work with the network interface Bool ldvCmdOk = TRUE; // Assume OK result
// Input and output buffers: ExpAppBuffer m_msgIn; // Incoming message buffer ExpAppBuffer m_msgOut; // Outgoing message buffer
// Size of the message to send short msgsize = sizeof(m_msgOut.data.code);
// // Set Up Windows Event // hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
// // Application Code //
// Open the network interface; assume LON1 rc = ldv_open(“LON1”, &m_OpenLdvHandle);
if (rc != LDV_OK) { m_OpenLdvHandle = -1; // Mark handle invalid ldvCmdOk = FALSE; // Don’t try to work with the network interface printf(“Could not open the network interface.\n”); } else { // Register Windows event with this network interface rc = ldv_register_event(m_OpenLdvHandle, hEvent);
if (rc != LDV_OK) { ldvCmdOk = FALSE; // Don’t try to work with the network interface printf(“Could not register an event for the network interface.\n”); } else { ldvCmdOk = TRUE; // Ok to work with the network interface } }
OpenLDV Programmer’s Guide 53
if (ldvCmdOk) {
// Build message to send to NI m_msgOut.ni_hdr.q.queue = niNTQ; m_msgOut.ni_hdr.q.q_cmd = niNETMGMT; m_msgOut.ni_hdr.q.length = sizeof(ExpMsgHdr) + sizeof(ExplicitAddr) +
msgSize;
m_msgOut.msg_hdr.exp.tag = 1; // Assume message tag 1 m_msgOut.msg_hdr.exp.auth = 0; m_msgOut.msg_hdr.exp.response = 1; // Make it a response m_msgOut.msg_hdr.exp.st = 3; // Make it a REQUEST m_msgOut.msg_hdr.exp.pool = 0; // Must be zero m_msgOut.msg_hdr.exp.alt_path = 0; // Use default path m_msgOut.msg_hdr.exp.addr_mode = 0; // Implicit addressing m_msgOut.msg_hdr.exp.cmpl_code = 0; // MSG_NOT_COMPL m_msgOut.msg_hdr.exp.path = 0; // Use primary path m_msgOut.msg_hdr.exp.priority = 0; m_msgOut.msg_hdr.exp.length =
m_msgOut.addr.snd. m_msgOut.data.code = LonNdQueryStatus; // Omitting “m_msgOut.data.data” because Query Status command has no data
// Write query status command to the network interface rc = ldv_write(m_OpenLdvHandle, m_msgOut, offsetof(ExpAppBuffer, code) + msgSize);
if (rc != LDV_OK) { ldvCmdOk = FALSE; // Don’t try to read from the network interface printf(“Could not write to network interface.\n”); } else { ldvCmdOk = TRUE; // Ok to read from the network interface } }
if (ldvCmdOk) { // Wait for network interface event WaitForSingleObject (hEvent, 1000); // Wait 1 second
// Read response to query status command rc = ldv_read(m_OpenLdvHandle, &m_msgIn, sizeof(m_msgIn));
if (rc != LDV_OK) { printf(“Could not read from network interface.\n”); } else { // Read return code from the LonNdQueryStatus command if (m_msgIn.data.code == LonNdQueryStatusSuccess) { // Success response from Query Status command; // Read error log as something interesting to do BYTE errLog = (
if (errLog == 0) printf(“No error in network interface.\n”); else printf(“Network interface error was: %d\n”, errLog); } else { // Failure response from Query Status command; do something else printf(“Failure response from Query Status cmd: %d\n”,m_msgIn.data.code); } } }
lc = NI_LOCAL;
ND_query_status_response *)(&m_msgIn.data.data)->
error_log;
msgSize;
54 Using the OpenLDV API
// Perform the following tasks regardless of ldvCmdOk value:
// Deregister event for NI ldv_register_event(m_OpenLdvHandle, NULL);
// Close the network interface rc = ldv_close(m_OpenLdvHandle);
if (rc != LDV_OK) { printf(“Could not close network interface.\n”); } else { m_OpenLdvHandle = -1; // Mark handle invalid }
Close(hEvent); // Close the event
ldvx_shutdown(); // Cleanly shutdown the OpenLDV driver
OpenLDV Programmer’s Guide 55
Sending and Receiving Messages
with the OpenLDV API
This chapter describes the network interface message commands that your OpenLDV application can send and receive through a network interface, as well as the application buffer structure that each type of message requires.
3
OpenLDV Programmer’s Guide 57

Constructing Messages

You can construct outgoing messages for OpenLDV application using application buffer structures, and send that data to the network interface using the ldv_write() function. Use the ldv_read() function to retrieve data from the network interface, using the same application buffer structures. The following section describes the application buffer structure.
The OpenLDVdefinitions.h header file contains example code that defines the formats of these application buffer structures for Layer 5 devices. This header file is included with the OpenLDV Developer Example; see Chapter 4, The OpenLDV Developer Example, on page 89.
The ldv_read() and ldv_write() functions take a msg_p parameter, which is a pointer to a buffer for the data that is to be received or sent. These functions also take a len parameter, which specifies the size (in bytes) of the buffer or data to write. See The OpenLDV API on page 15 for a description of these functions.

Application Buffer Structure

Figure 5 on page 59 shows the application buffer structures used by OpenLDV
ONWORKS interface devices. All OpenLDV LONWORKS interface devices support
L the serial interface control block (SICB) buffer format. Some L interface devices also support an extended (LdvEx) buffer format. You can use the ldv_open_cap() function to specify which format to use; see ldv_open_cap() on page 25.
ONWORKS
The SICB buffer format begins with a simple header, the Network Interface Header. The structure of this header depends on the type of command being processed:
For commands that use a message queue, the header includes 4 bits for the queue type, four bits for the command, and a byte for the length of the payload.
For commands that do not use a message queue (such as the immediate commands), the header includes a byte for the command and a byte for the length of the payload.
For some commands, the value of the length byte can be zero. An optional, variable-length data field (as indicated by the header’s length byte) follows the header.
The LdvEx buffer format encapsulates the SICB format; it adds extra timestamp information and extended data (where applicable; this extended data is not interpreted by the OpenLDV software). Unless specifically stated, an “application buffer” refers to the SICB format buffer.
58 Sending and Receiving Messages with the OpenLDV API
Extended Header
Extended Data Type
Extended Data Version
Extended Data
BF
Packet Size
Flags
Extended Header Size
Absolute Timestamp
In Seconds
Absolute Timestamp
In Milliseconds
Differential Timestamp
In Microseconds
SICB
Timestamps
Header
SICB
Extension
Command
Length N
Data[0]
Data[1]
Data[N-1]
Data
Payload
NI Header
Queue
Command
Buffer Structure for
Commands That Do Not Use
a Message Queue
Buffer Structure for
Commands That Use
a Message Queue
Length N
Data[0]
Data[1]
Data[N-1]
Data
Payload
NI Header
LdvEx Buffer
Format
SICB Buffer
Formats
Figure 5. Application Buffer High-Level Structure
For commands that use a message queue, the queue bits in the SICB buffer indicate the path by which an incoming message was received, or by which an outgoing message should leave the network interface. For example, an outgoing message can use the standard, non-priority, output queue or the priority output queue. Likewise, an incoming message might be received as a response to a pending request, or it might be a normal incoming message. See Network Interface Commands on page 77 for a description of the queue and command-code values.
The OpenLDV Developer Example contains relevant data type definitions, constants, and enumerations for messaging using the SICB buffer. The complete
OpenLDV Programmer’s Guide 59
SICB application buffer structure is defined as a structure of type ExpAppBuffer
Queue
Length
ExpMsgHdr
SendAddrDtl
or
RcvAddrDtl
or
RespAddrDtl
Command
UnprocessedNV
or
ExplicitMsg
Length
Application Layer Header Size=2
Message Header Size=3
Network Address Size=11
Message Data Size=variable
Queue
Length
Layer 2 Header
NPDU
Command
CRC
Length
Application Layer Header Size=2
Layer 2 Header Size=1
Network Protocol Data Unit Size=variable
CRC Size=2
Layer 5 Buffer StructureLayer 2 Buffer Structure
in the OpenLDVdefinitions.h header file.
Some immediate commands use only the first byte of the SICB buffer—the cmd field—of the application buffer, with no data payload. Other immediate commands also include a data payload.
All other downlink and uplink message commands use the complete SICB application buffer structure, as shown in Figure 6. The following sections describe the application buffer structures.
Figure 6. SICB Application Buffer Detailed Structure
As described in Getting Started with the OpenLDV Driver on page 7, an OpenLDV application can use a Layer 2 network interface or a Layer 5 network interface:
Layer 2 Network Interface – A network interface that communicates at Layer 2 of the LonTalk protocol. This type of interface transports LonTalk packets without processing them, and does not filter by network address.
Layer 5 Network Interface – A network interface that communicates at Layer 5 of the LonTalk protocol. This type of interface transports incoming LonTalk packets that are addressed to the network interface, and transports outgoing packets that are addressed to other devices.
60 Sending and Receiving Messages with the OpenLDV API

Layer 2 Buffer Structure

The following sections provide an overview of the Layer 2 buffer structure shown in Figure 6. Bit transmission order within a byte is “most significant first”, meaning that the most significant bit is transmitted first. Byte transmission order is also “most significant first”, meaning that the most significant byte of a field is transmitted first.
A Layer 2 network interface uses the Layer 2 buffer structure for most messages. However, local network management messages use the Layer 5 buffer structure, regardless of which layer the network interface uses for network messages.
For a more complete description of the Layer 2 buffer structure, see the
ISO/IEC 14908-1 Interconnection of information technology equipment – Control Network Protocol - Part 1: Protocol Stack.
Application Layer Header
The application layer header contains the network interface command (and queue) and a byte that indicates the length of the rest of the message. The most significant nibble of the network interface command contains the command code (for example, niCOMM for network messages), and the least significant nibble contains the queue code, if any. These nibbles combine to form the command/queue byte, which is the network interface command.
An OpenLDV application sends these commands using the ldv_write() function, and receives them using the ldv_read() function. See Network Interface Commands on page 76 for a description of the network interface commands.
Layer 2 Header
The Layer 2 header is a single byte that includes the following fields:
A 1-bit field to specify the priority of the data packet. 0 = Normal; 1 = Priority.
A 1-bit field to specify the channel to use, primary or alternate. This field allows transceivers that have the ability to transmit on two different channels and receive on either one, without the need to instruct the transceiver to explicitly receive on a specific channel. The transport layer sets this bit.
A 6-bit unsigned field (≥ 0) to specify the channel backlog increment to be generated as a result of delivering this packet. The backlog represents the number of messages that the packet shall cause to be generated upon reception. This value is used by the Smart Transceiver or Neuron Chip MAC algorithm.
NPDU
The Network Protocol Data Unit (NPDU) encapsulates the physical packet data. The NPDU includes the following fields:
Protocol version (2 bits)
Physical packet type (2 bits)
Address format (2 bits)
OpenLDV Programmer’s Guide 61
Domain length (2 bits)
Data (variable length, depending on the packet type and the data)
CRC
The cyclic redundancy check (CRC) is computed over the NPDU and the Layer 2 Header. The CRC is generated using the ITU-T (CCITT) CRC-16 standard polynomial. When the link layer receives a packet with a CRC error, or a packet that is less than 8 bytes in length, a transmission error statistic is incremented; if a packet is received that is too long for the input buffer, or if there are no input buffers, the missed packet statistic is incremented.

Layer 5 Buffer Structure

The following sections describe the Layer 5 buffer structure shown in Figure 6. Bit transmission order within a byte is “most significant first”, meaning that the most significant bit is transmitted first. Byte transmission order is also “most significant first”, meaning that the most significant byte of a field is transmitted first.
For a more complete description of the Layer 5 buffer structure, see the ISO/IEC
14908-1 Interconnection of information technology equipment – Control Network Protocol - Part 1: Protocol Stack.
Application Layer Header
The application layer header contains the network interface command (and queue) and a byte that indicates the length of the rest of the message. The most significant nibble of the network interface command contains the command code (niCOMM for network messages or niNETMGMT for local network interfaces messages), and the least significant nibble contains the queue code. These nibbles combine to form the command/queue byte, which is the network interface command.
An OpenLDV application sends these commands using the ldv_write() function, and receives them using the ldv_read() function. The OpenLDV Developer Example contains an example implementation of a network interface API. You can use the NiSendMsgWait() and NiSendResponse() functions, included as part of this example API, to send enqueued commands more conveniently. You can also use the application-specific message dispatcher, also implemented as part of the OpenLDV Developer Example, to receive these messages.
See Network Interface Commands on page 76 for a description of the network interface commands.
Message Header
The message header describes the various attributes of the LonTalk message contained in the data field. The message header field is defined by the union of two structures:
ExpMsgHdr for sending and receiving explicit messages that are not processed by the network interface
62 Sending and Receiving Messages with the OpenLDV API
compl
NetVarHdr for sending and receiving network variables that are processed by the network interface
ExpMsgHdr
7 6 5 4 3 2 1 0
msgtype service type auth tag
Priority Path
length
msgtype
The msgtype field is set to 0 for the ExpMsgHdr.
service type
The service type field contains one of the following values, depending on which LonTalk protocol messaging service is to be used for delivery of the message:
ACKD (0) for the acknowledged messaging service
UNACKD_RPT (1) for the repeated messaged service
UNACKD (2) for the unacknowledged messaging service
REQUEST (3) for the request/response messaging service
auth
The auth field is set to 1 for a downlink message (sent to a network interface) if the receiver must authenticate the message using LonTalk authentication. A network interfaces might require authentication for local network management commands.
code
addr
mode
alt path pool resp
It is set to 1 for an uplink message (read from a network interface) if the message has been authenticated by the network interface.
If authentication is not enabled on the network interface, this field should be set to 0.
tag
The OpenLDV application uses the tag field for a downlink message (sent to a network interface) to correlate returned responses and completion events. For explicitly addressed messages (those that use the full 3-layer address), you can segt the tag to any value in the range 0-14, and the same value is returned with the corresponding responses and completion events. In this case, the tag is also known as the reference ID. For a downlink implicitly addressed message (one that specifies an entry in the address table), the tag field is used as an index into the address table of the Smart Transceiver or Neuron Chip in the network interface to indicate the destination address of the message. For more information about the address table, see the ISO/IEC 14908-1 protocol specification.
OpenLDV Programmer’s Guide 63
For an uplink message (read from a network interface), the tag field indicates the index into the receive transaction database for acknowledged, repeated and request messages. When an OpenLDV application generates a response to an uplink request message, it must save the tag value from the request, and set the same tag value in the downlink response message.
priority
The priority field is set to indicate a message delivered with priority media access, either uplink or downlink. When an OpenLDV application generates a response to an uplink request message, it must save the priority attribute from the request, and sets the response with the same priority. If the network interface is configured without priority buffers, and a priority request is received, the OpenLDV application sets the priority bit in the response, but sends the response in a non-priority buffer.
path
The path field is set to 1 if the message should use the alternate path, and 0 if it should use the primary path. This feature is enabled only if the alternate path bit is set. Alternate path is a feature of certain special-purpose mode
ONWORKS transceivers, such as power line (PL) transceivers.
L
completion code
The completion code field is set for an uplink completion event. Completion code events are returned to the OpenLDV application for every downlink (niCOMM) network message sent:
The MSG_SUCCEEDS (1) value indicates that the message was
successfully delivered.
The MSG_FAILS (2) value indicates that the message failed to be
delivered.
Set the completion code field to MSG_NOT_COMPL (0) for
application layer buffers that are not completion events.
Messages sent to the network driver with the niNETMGMT network interface command do not have associated completion events.
address mode
Set the address mode bit to 1 for an explicitly addressed downlink message, and specify the network address field as a SendAddrDtl structure (see SendAddrDtl on page 67).
Set the address mode field to 0 for an implicitly addressed downlink message, in which case the network address field is ignored, although it must be present. In this case, use the tag field as the index into the address table of the Smart Transceiver or Neuron Chip in the network interface for the destination address. For more information about the address table, see the ISO/IEC 14908-1 protocol specification.
Set the address mode to 0 for downlink responses to uplink request messages and network variable polls.
The address mode bit is ignored for local network management (niNETMGMT) messages.
64 Sending and Receiving Messages with the OpenLDV API
compl
alternate path
If the alternate path bit is set, the message is delivered on the path specified in the path bit, otherwise it is delivered on the default path.
pool
Set the pool bit to 0 for a downlink message.
response
Set the response bit to 1 for a downlink response message, and 0 otherwise. If it is set for an uplink message, the message is a response to a previously sent request.
length
The length field in the message header is distinct from the length field in the application layer header. The length field the message header indicates the number of bytes for the message data.
NetVarHdr
7 6 5 4 3 2 1 0
msgtype poll resvd
Priority Path
length
msgtype
The msgtype field is set to 1 for the NetVarHdr.
poll
The poll field is set to 1 for a network variable poll message. For other network variable messages, it is set to 0 (zero).
reserved
The NetVarHdr includes two bits that are reserved for future use. Set this field to 0 for downlink messages.
tag
The OpenLDV application uses the tag field for a downlink message (sent to a network interface) to correlate returned responses and completion events. For explicitly addressed messages, the tag can be set to any value in the range 0-14, and the same value is returned with the corresponding responses and completion events. In this case, the tag is also known as the reference ID. For a downlink implicitly addressed message, the tag field is used as an index into the address table of the Smart Transceiver or Neuron Chip in the network interface to indicate the destination address of the message. For more information about the address table, see the ISO/IEC 14908-1 protocol specification.
tag
code
addr
mode
trnarnd pool resp
For an uplink message (read from a network interface), the tag field indicates the index into the receive transaction database for acknowledged, repeated
OpenLDV Programmer’s Guide 65
and request messages. When the OpenLDV application generates a response to an uplink request message, it must save the tag value from the request, and return the same tag value in the downlink response message.
priority
The priority field is set to indicate a message delivered with priority media access, either uplink or downlink. When the OpenLDV application generates a response to an uplink request message, it saves the priority attribute from the request, and returns the response with the same priority. If the network interface is configured without priority buffers, and a priority request is received, the OpenLDV application sets the priority bit in the response, but sends the response in a non-priority buffer.
path
The path field is set to 1 if the message should use the alternate path, and 0 (zero) if it should use the primary path. This feature is enabled only if the alternate path bit is set. Alternate path is a feature of certain special­purpose mode L
ONWORKS transceivers.
completion code
The completion code field is set for an uplink completion event. Completion code events are returned to the OpenLDV application for every downlink (niCOMM) network message sent:
The MSG_SUCCEEDS (1) value indicates that the message was
successfully delivered.
The MSG_FAILS (2) value indicates that the message failed to be
delivered.
Set the completion code field to MSG_NOT_COMPL (0) for
application layer buffers that are not completion events.
Messages sent to the network driver with the niNETMGMT network interface command do not have associated completion events.
address mode
Set the address mode bit to 1 for an explicitly addressed downlink message, and specify the network address field as a SendAddrDtl structure (see SendAddrDtl on page 67).
Set the address mode field to 0 for an implicitly addressed downlink message, in which case the network address field is ignored, although it must be present. In this case, the tag field is used as the index into the address table of the Smart Transceiver or Neuron Chip in the network interface for the destination address. For more information about the address table, see the ISO/IEC 14908-1 protocol specification.
Set the address mode to 0 for downlink responses to uplink request messages and network variable polls.
The address mode bit is ignored for local network management (niNETMGMT) messages.
66 Sending and Receiving Messages with the OpenLDV API
turnaround
If the turnaround bit is set, the message is a turnaround message, that is, a message sent from one network variable to another network variable on the same device.
pool
Set the pool bit should 0 for a downlink message.
response
Set the response bit to 1 for a downlink response message, and 0 otherwise. If it is set for an uplink message, the message is a response to a previously sent request.
length
The length field in the message header is distinct from the length field in the application layer header. The length field the message header indicates the number of bytes for the message data.
Network Address
The network address specifies the address for network (niCOMM) messages, which includes application messages as well as network variable messages. The network address is not used for local (niNETMGMT) messages or for implicitly addressed downlink messages, but it must be present in the application buffer. The type definition for ExplicitAddr is a union of three structures, depending on the type of message buffer. For more information about address modes and the corresponding structures, see the ISO/IEC 14908-1 protocol specification.
The OpenLDV Developer Example also contains an example definition of the related structures in the OpenLDVdefinitions.h header file.
SendAddrDtl
This structure is used for a downlink, explicitly addressed message, and contains the destination address of the downlink message in one of four formats, depending on the address mode. The address modes for sending explicitly addressed messages are broadcast, group, subnet/node, Neuron ID, local, and implicit. The SendAddrDtl formats for downlink messages sent using each of these address modes are displayed below.
OpenLDV Programmer’s Guide 67
msb lsb
Format
SendAddrDtl
Destination Address For Broadcast
Addressing
0
Domain
tx_timer
Retryrpt_timer
Subnet
Reserved
Destimation
Address
0 0 0 0 0 1 1
Backlog
msb lsb
Format
SendAddrDtl
Destination Address For Group
Addressing
Size1
Domain Member
tx_timer
Retryrpt_timer
Group
Reserved
Destimation
Address
68 Sending and Receiving Messages with the OpenLDV API
msb lsb
Format
SendAddrDtl
Destination Address For Subnet/Node
Addressing
0
Domain Node
tx_timer
Retry
rpt_timer
Subnet
Reserved
Destimation
Address
0 0 0 0 0 0 1
msb lsb
Format
SendAddrDtl
Destination Address For Neuron ID
Addressing
0
Domain
tx_timer
Retryrpt_timer
Subnet
Neuron ID
Destimation
Address
0 0 0 0 0 1 0
OpenLDV Programmer’s Guide 69
0 1 1 1
1
1 1 1
msb lsb
Format
Reserved
SendAddrDtl
Destination Address For Local
Addressing
Destination
Address
0 1
1
1 1
1
1 0
msb lsb
Format
Reserved
SendAddrDtl
Destination Address For Implicit
Addressing
Destination
Address
msg_tag
RcvAddrDtl
This structure is used for uplink messages addressed to the network interface and intended for the OpenLDV application. The structure contains the source address of the device sending the message and the destination address of the uplink message in one of four formats, depending on the address mode. The address modes for received addresses are broadcast, group, subnet/node, and Neuron ID. The RcvAddrDtl structures for uplink messages sent using each of these address modes are displayed below.
70 Sending and Receiving Messages with the OpenLDV API
msb lsb
Format
RcvAddrDtl
Received Address For Broadcast
Addressing
Domain
Node
Subnet
Reserved
Source
Address
0 0 0 0 0 0
flex_domain
Destination
Address
Subnet
msb lsb
Format
RcvAddrDtl
Received Address For Group Addressing
Domain
Node
Subnet
Reserved
Source
Address
0 0 0 0 0 1
flex_domain
Destination
Address
Group
OpenLDV Programmer’s Guide 71
msb lsb
Format
RcvAddrDtl
Received Address For Subnet/Node
Addressing
Domain
Node
Subnet
Reserved
Source
Address
0 0 0 0 1 0
flex_domain
Destination
Address
Subnet
Node
msb lsb
Format
RcvAddrDtl
Received Address For Neuron ID
Addressing
Domain
Node
Subnet
Neuron ID
Source
Address
0 0 0 0 1 1
flex_domain
Destination
Address
Subnet
Reserved
RespAddrDtl
This structure is used for an uplink message in response to a previous downlink request. This field contains the source address of the device sending the response and the destination address of the uplink message in one of two formats, depending on the address mode. The address modes for received responses are group and subnet/node. The RespAddrDtl structures for response messages sent using each of these address modes are displayed below.
72 Sending and Receiving Messages with the OpenLDV API
msb lsb
Format
RespAddrDtl
Response Address For Group
Addressing
Domain
Node
Subnet
Reserved
Source
Address
flex_domain
Destination
Address
Subnet
Node
0
Group
Member
msb lsb
Format
RespAddrDtl
Response Address For Subnet/Node
Addressing
Domain
Node
Subnet
Reserved
Source
Address
flex_domain
Destination
Address
Subnet
Node
1
1
Message Data
The data field contains the application data to be transferred within a message. The format depends on the type of message, and is defined by either the UnprocessedNV or ExplicitMsg structures.
OpenLDV Programmer’s Guide 73
UnprocessedNV
NV
NV
NV
7 6 5 4 3 2 1 0
1 dir
Depending on the context, this form of the data field is used for network-variable update messages, poll messages, poll responses, or completion events. A network-variable update message or a poll response contains 1-31 bytes of network-variable data. A network-variable poll request message or a completion event contains no data, only the selector in the first two bytes.
Set the direction bit to 1 for polling an output network variable, and 0 for updating or polling an input network variable.
An OpenLDV application that sends a downlink network-variable message must retrieve the appropriate network variable selector from its network variable configuration table or alias table. Similarly, when an uplink network-variable message arrives, the OpenLDV application looks up the network variable selector from the message in its network variable configuration table or alias table to determine which network variable was addressed.
For more information about network variable configuration, messages, and alias tables, see the ISO/IEC 14908-1 protocol specification.
selector hi
selector lo
data
ExplicitMsg
7 6 5 4 3 2 1 0
0 Message
Message
Depending on the context, this form of the data field is used for downlink messages, uplink messages, or completion events. A downlink or uplink message contains 0-228 bytes of data. A completion event contains only the message code and the first byte of the data. Message codes for non-response messages are allocated as listed in Table 31.
Table 31. Message Codes for Application Messages
Message Type Message Codes (Hex)
User application message 00 .. 2F
Standard application message 30 .. 3E
Responder offline 3F
Foreign message 40 .. 4E
code
code
74 Sending and Receiving Messages with the OpenLDV API
Message Type Message Codes (Hex)
Foreign responder offline 4F
Network diagnostic message 50 .. 5F
Network management message 60 .. 73
Router configuration message (not used by the network interface)
Network management escape code 7D
Router far side escape code (not used by the network interface)
Service pin message 7F
74 .. 7C
7E

Sending Messages to the Network Interface

Some messages can be sent to the network interface itself. For example, the NM_update_domain (0x63) message can be sent to the network interface using the niNETMGMT network interface command. This message sets the network address (domain ID, subnet ID and node ID) used by the network interface.
Some network interfaces require authentication for local network management commands. Thus, you should always set the auth bit of the ExpMsgHdr to 1 for local network management commands. See ExpMsgHdr on page 63 for information about the message header.

Receiving Messages from the Network Interface

Incoming application, foreign frame, and network variable messages are passed unchanged to the OpenLDV application. Most network management messages received are handled by the network interface itself. However, the network management messages listed in Table 32 can be passed to the OpenLDV application, which must respond appropriately. See the ISO/IEC 14908-1 protocol specification for information about these network management and diagnostics messages.
The OpenLDV Developer Example contains an example framework for recognizing and processing these messages.
Table 32. Network Management Messages Passed to the OpenLDV Application
Message Code Comments
Query NV Config 0x68 OpenLDV application should respond with data from the
network variable configuration table or alias table.
Update NV Config 0x6B OpenLDV application should write its own network variable
configuration or alias table, respectively.
OpenLDV Programmer’s Guide 75
Message Code Comments
Set Node Mode 0x6C On-line and off-line only. OpenLDV application should send
corresponding immediate command (niONLINE or niOFFLINE) to the network interface.
Wink 0x70 OpenLDV application should indicate receipt of message to user,
or handles a request to manage its self-documentation data.
Query SI 0x72 OpenLDV application should respond with self-identification and
self-documentation data.
NV Fetch 0x73 OpenLDV application should respond with network variable
data.

Using the Network Interface Command Interface

The following sections describe the OpenLDV command interface.

Downlink Commands

A downlink command is a message sent to a network interface from an OpenLDV application with the ldv_write() function:
The OpenLDV application sends application messages, network management and diagnostics messages, network variable updates, and network variable poll requests on the network through the network interface using the niCOMM network interface command.
The OpenLDV application also sends messages to the OpenLDV interface that it generates in response to uplink request messages, including responses to uplink network variable poll messages.
The OpenLDV application sends messages to the OpenLDV interface in response to certain uplink network management messages that it receives for processing.
There are two categories of downlink communication:
Immediate commands do not require an application output buffer in the network interface, and are used to control the operation of the network interface itself. Immediate commands are sent with all queue selection bits cleared.
Local network management commands are used to configure and control the Smart Transceiver or Neuron Chip that is part of the network interface. They are sent with the niNETMGMT network interface command, and are not sent on the L
Commands for Layer 5 devices that can be used with a specified queue include niCOMM for messages sent to the network, and niNETMGMT for local network management operation messages sent to the network interface. Local network management messages use the Layer 5 buffer structure, regardless of which layer the network interface uses for network messages.
ONWORKS network.
76 Sending and Receiving Messages with the OpenLDV API

Uplink Commands

An uplink command is a message read from a network interface by an OpenLDV application with the ldv_read() function:
The OpenLDV interface passes certain network management messages to the OpenLDV application for processing.
The network interface passes uplink application messages, network variable updates, and network variable poll requests to the OpenLDV interface when they are received from the network.
The network interface also passes completion events to the OpenLDV interface at the conclusion of every downlink message initiated with the niCOMM network interface command. If the downlink message was a request message, the network driver also passes up any responses it might have received from the network.
Layer 2 network interfaces send error codes for physical packet errors.
There are two classes of uplink communication:
Immediate commands are sent to the OpenLDV application by the network interface to indicate the current operational status of the network interface.
Local network management responses are sent to the OpenLDV application when it issues a local network management request to the network interface.
Commands for Layer 5 devices that can be used with a specified queue include niCOMM for messages received from the network, and niNETMGMT for local network management operation messages received from the network interface. Local network management messages use the Layer 5 buffer structure, regardless of which layer the network interface uses for network messages.

Immediate Commands

Immediate commands can be sent to the OpenLDV interface using the ldv_write() function, and received using the ldv_read() function. Most immediate commands are just two bytes long. This includes a command byte followed by a trailing zero, which indicates there is no data payload for the command. However, some commands, such as niXDRVESC (xDriver escape command), do require a data payload.
The OpenLDV Developer Example also includes an example implementation of a network interface API. The NiSendImmediate() function, which is part of this example API, can be used to send immediate commands.

Network Interface Commands

Table 33 on page 78 lists the network interface commands. Unless specifically described otherwise, the commands in the table apply to Layer 5 network interfaces only.
The command names listed in the table are suggestions; for the Layer 5 device commands, they are defined in the OpenLDV Developer Example by the
OpenLDV Programmer’s Guide 77
enumeration type definition NI_QueueCmd used in the field NI_Hdr.q.q_cmd of the application layer header, and the queue codes are defined by the enumeration type definition NI_Queue used in the field NI_Hdr.q.queue. The OpenLDV Developer Example contains a utility function, COpenLDVni::msgHdrInit(), that computes the correct value for the command/queue byte based on the address type (local or remote), the service type, and the priority attribute of the message.
Literals for the supported immediate commands are defined in the OpenLDV Developer Example by the enumeration type definition NI_NoQueueCmd used in the field NI_Hdr.q of the application layer header.
Table 33. Network Interface Commands
Network Interface Command Value Direction Description
niL2_INCOMING 0x1A Uplink Specifies a Layer 2 incoming
packet.
niL2_INC_M1 0x1B Uplink Specifies a Layer 2 Mode 1
incoming packet.
niL2_INC_M2 0x1C Uplink Specifies a Layer 2 Mode 2
incoming packet.
niCOMM + niTQ 0x12 Downlink Used for downlink non-priority
messages using acknowledged, request and repeated services. For Layer 2 devices, also used for unacknowledged messages.
This command specifies niCOMM (for messages sent to and received from the network) as the queue value and niTQ as the command value.
Applies to Layer 2 or Layer 5 devices. The command format is different for Layer 2 and Layer 5.
78 Sending and Receiving Messages with the OpenLDV API
Network Interface Command Value Direction Description
niCOMM + niTQ_P 0x13 Downlink Used for downlink priority
messages using acknowledged, request and repeated services. For Layer 2 devices, also used for unacknowledged messages.
This command specifies niCOMM (for messages sent to and received from the network) as the queue value and niTQ_P as the command value.
Applies to Layer 2 or Layer 5 devices. The command format is different for Layer 2 and Layer 5.
niCOMM + niNTQ 0x14 Downlink Used for downlink non-priority
messages using unacknowledged service, as well as responses.
This command specifies niCOMM (for messages sent to and received from the network) as the queue value and niNTQ as the command value.
niCOMM + niNTQ_P 0x15 Downlink Used for downlink priority
messages using unacknowledged service, as well as responses.
This command specifies niCOMM (for messages sent to and received from the network) as the queue value and niNTQ_P as the command value.
niCOMM + niRESPONSE 0x16 Uplink Used for uplink response messages
and completion codes.
This command specifies niCOMM (for messages sent to and received from the network) as the queue value and niRESPONSE as the command value.
OpenLDV Programmer’s Guide 79
Network Interface Command Value Direction Description
niCOMM + niINCOMING 0x18 Uplink Used for uplink messages received
from the network or the network interface.
This command specifies niCOMM (for messages sent to and received from the network) as the queue value and niINCOMING as the command value.
niNETMGMT + niTQ 0x22 Downlink Used for downlink non-priority
messages using acknowledged, request and repeated services. Also used for a Layer 2 network interface to issue a local network management command.
This command specifies niNETMGMT (for messages sent to and received from the network interface) as the queue value and niTQ as the command value.
niNETMGMT + niTQ_P 0x23 Downlink Used for downlink priority
messages using acknowledged, request and repeated services. Also used for a Layer 2 network interface to issue a local network management command.
This command specifies niNETMGMT (for messages sent to and received from the network interface) as the queue value and niTQ_P as the command value.
niNETMGMT + niNTQ 0x24 Downlink Used for downlink non-priority
messages using unacknowledged service, as well as responses. Also used for a Layer 2 network interface to issue a local network management command.
This command specifies niNETMGMT (for messages sent to and received from the network interface) as the queue value and niNTQ as the command value.
80 Sending and Receiving Messages with the OpenLDV API
Network Interface Command Value Direction Description
niNETMGMT + niNTQ_P 0x25 Downlink Used for downlink priority
messages using unacknowledged service, as well as responses. Also used for a Layer 2 network interface to issue a local network management command.
This command specifies niNETMGMT (for messages sent to and received from the network interface) as the queue value and niNTQ_P as the command value.
niNETMGMT + niRESPONSE 0x26 Uplink Used for uplink response messages
and completion codes. Also used by a Layer 2 network interface to respond to a local network management command.
This command specifies niNETMGMT (for messages sent to and received from the network interface) as the queue value and niRESPONSE as the command value.
niNETMGMT + niINCOMING 0x28 Uplink Used for uplink messages received
from the network or the network interface.
This command specifies niNETMGMT (for messages sent to and received from the network interface) as the queue value and niINCOMING as the command value.
niL2_PKT_TIMEOUT 0x30 Uplink Specifies a timeout error condition
for a Layer 2 network interface.
niL2_PKT_CRC 0x31 Uplink Specifies a CRC error condition for
a Layer 2 network interface.
niL2_PKT_LONG 0x32 Uplink Specifies a “Packet Too Long” error
condition for a Layer 2 network interface.
niL2_PRE_LONG 0x33 Uplink Specifies a “Preamble Too Long”
error condition for a Layer 2 network interface.
OpenLDV Programmer’s Guide 81
Network Interface Command Value Direction Description
niL2_PRE_SHORT 0x34 Uplink Specifies a “Preamble Too Short”
error condition for a Layer 2 network interface.
niL2_PKT_SHORT 0x35 Uplink Specifies a “Packet Too Short” error
condition for a Layer 2 network interface.
niL2_FREQ_RPT 0x40 Uplink Specifies an incoming frequency
report from a Layer 2 network interface.
niRESET 0x50 Uplink
Downlink
niFLUSH_CANCEL 0x60 Downlink Requests that the network interface
niFLUSH_COMPLETE 0x60 Uplink Specifies that a flush operation
Uplink: Specifies that the network interface has executed a hardware or software reset.
Downlink: Requests a reset of the network interface.
Applies to both Layer 2 and Layer 5 network interfaces.
cancel any flush operation posted with the niFLUSH command or caused by device reset.
The OpenLDV application must issue this command after a successful completion of the ldv_open() function.
You can use the NiInit() function, which is part of the OpenLDV Developer Example to open a connection to a network interface more conveniently.
posted with the niFLUSH command has completed.
82 Sending and Receiving Messages with the OpenLDV API
Network Interface Command Value Direction Description
niONLINE 0x70 Downlink Requests that the network interface
set its online flag and enter the online state.
The OpenLDV application must send this command whenever it goes online.
Generally, the OpenLDV application receives an uplink network management message from a network management tool or plug-in requesting that the application go online and send the niONLINE command. The uplink message is a standard Set Node Mode network management command (message code 0x6C) with mode set to ONLINE.
niOFFLINE 0x80 Downlink Requests that the network interface
clear its online flag and enter the offline state.
The OpenLDV application must send this command whenever it goes offline.
Generally, the OpenLDV application receives an uplink network management message from a network management tool or plug-in requesting that the application go offline and send the niOFFLINE command. The uplink message is a standard Set Node Mode network management command (message code 0x6C) with mode set to OFFLINE.
OpenLDV Programmer’s Guide 83
Network Interface Command Value Direction Description
niFLUSH 0x90 Downlink Requests that the network interface
enter quiet mode (the FLUSH state), which causes it to send any pending downlink messages.
After all pending downlink messages are completed, the network interface responds with the niFLUSH_COMPLETE command.
No further downlink messages can be processed until the OpenLDV application cancels the flush state with the niFLUSH_CANCEL command.
niFLUSH_IGN 0xA0 Downlink Obsolete.
niSLEEP 0xB0 Downlink Obsolete.
niLAYER 0xE5 Downlink
Uplink
Sets the top-most protocol layer processed by the network interface.
This command is used only for network interfaces that support switching between a Layer 2 and a Layer 5 interface, such as the Echelon U10 and U20 USB Network Interfaces.
This message can contain a single­byte data payload to specify the top­most protocol layer for the network interface:
0 specifies Layer 5
1 specifies Layer 2
If no data payload is included, the network interface responds with two bytes: 0xE5 followed by 0 (if the interface is operating as a Layer 5 network interface) or 1 (if the interface is operating as a Layer 2 network interface).
84 Sending and Receiving Messages with the OpenLDV API
Network Interface Command Value Direction Description
niSERVICE 0xE6 Downlink Requests that the network interface
send a service pin message. This command has the same effect as activating the device’s service pin.
Some network interfaces might not support this command.
niXDRVESC
Table 34 on page 86 describes the xDriver-specific commands that you can use with the niXDRVESC immediate command. The niXDRVESC immediate command is described in Table 33 above.
0xEF Uplink
Downlink
This command applies to xDriver network interfaces only.
This message must contain a data payload in addition to the command and length bytes. The first byte of the data field denotes an xDriver­specific command; see Table 34.
For information about other immediate commands that are specific to a particular network interface, see the documentation for that network interface. For example, the Power Line SLTA
Adapter and Power Line PSG/3 User’s Guide contains descriptions
of commands specific to the SLTA/PSG interface products that can be used to control dial-up connections through a modem.
OpenLDV Programmer’s Guide 85
Table 34. xDriver Specific Commands
xDriver Command Description
LDVX_NICMD_ENCRYPTION_ON_SEND=0x02 Use this command to enable RC4
encryption on the IP connection to the RNI for all subsequent messages sent to the network interface. All subsequent messages are encrypted until the
LDVX_NICMD_ENCRYPTION_ OFF_SEND command is sent, or
the session is terminated.
This command is ignored if encryption has already been enabled.
The xDriver subsystem determines if the network interface supports RC4 encryption. If it does not, this command is silently ignored.
LDVX_NICMD_ENCRYPTION_OFF_SEND=0x03 Use this command to disable RC4
encryption on the IP connection to the RNI for all subsequent messages sent to the network interface.
This command is ignored if encryption has already been disabled.
LDVX_NICMD_ENCRYPTION_ON_RECEIVE=0x04 Use this command to enable RC4
encryption on the IP connection to the RNI for all subsequent messages sent from the network interface. All subsequent messages are encrypted until the
LDVX_NICMD_ENCRYPTION_ OFF_RECEIVE command is sent,
or the session is terminated.
This command is ignored if encryption has already been enabled.
The xDriver subsystem determines if the network interface supports RC4 encryption. If it does not, this command is silently ignored.
86 Sending and Receiving Messages with the OpenLDV API
xDriver Command Description
LDVX_NICMD_ENCRYPTION_OFF_RECEIVE=0x05 Use this command to disable RC4
encryption on the IP connection to the RNI for all subsequent messages sent from the network interface.
This command is ignored if encryption has already been disabled.
OpenLDV Programmer’s Guide 87

The OpenLDV Developer Example

4
This chapter describes the OpenLDV Developer Example introduced with OpenLDV Release 2.1, and describes the various classes implemented in the example.
OpenLDV Programmer’s Guide 89

Overview

The OpenLDV Developer Example is an example application that uses the OpenLDV API. The example application is available from the Examples & Tutorials folder in the Echelon OpenLDV 4.0 SDK program folder.
The example application is also installed as a ZIP file in the L \OpenLDV SDK\SourceArchive folder on your computer. The ZIP file is named LdvApiExamplesSource_vn.nn.nnn.ZIP, where the n.nn.nnn represents the version and build number for the OpenLDV release.
The OpenLDV Developer Example is a simple dialog-based Windows application written in C++ with Microsoft Foundation Classes (MFC). It is distributed in Microsoft Visual Studio 2008 project format. The example illustrates how a Windows application can access the OpenLDV API, and demonstrates a wide range of simple to complex network operations.
The example application contains comments that should assist you when reviewing the code. This chapter describes the structure of the example application and the different classes that it contains.

Common Definitions

The OpenLDV API functions are specified in the ldv32.h header file. The OpenLDV Developer Example provides additional definitions of constants, enumerations, and aggregated types in the OpenLDVdefinitions.h header file. These definitions are used throughout the remainder of the example application.

COpenLDVapi and COpenLDVtrace

The example application implements a COpenLDVapi class to wrap the OpenLDV API functions. The COpenLDVapi class provides a simple interface through four methods: Open, Close, Read, and Write.
ONWORKS
This class provides thread-safe, synchronized, access to downlink messages (ldv_write()), and implements a reader thread COpenLDVreader, which reads uplink messages (ldv_read()) and supplies data to a protected queue. The COpenLDVapi::Read() function reads that queue, thereby providing coordinated access to both uplink and downlink messages.
The example application also implements a COpenLDVtrace class. This class illustrates how an OpenLDV application can provide hooks for debugging or tracing into the low-level portion of the OpenLDV application. The example implementation provides a packet dump of all incoming and outgoing packets.
The related header files, OpenLDVapi.h and OpenLDVtrace.h, contain details about these classes and their usage.

COpenLDVni, Message Pumps, and Message Dispatchers

The COpenLDVni class implements the core functions of a network interface API. The functions included in this class are NiInit(), NiSendMsgWait(),
90 The OpenLDV Developer Example
NiSendImmediate(), NiGetNextResponse(), NiSendResponse(), NiClose(), and NiEncryption().
The OpenLDVni.h header file contains details about this class and its usage.
The COpenLDVni class also implements and controls a worker thread, COpenLDVmessagePump. This thread operates as a message pump, receiving and dispatching uplink messages from the COpenLDVapi class.
To dispatch an incoming message, a message dispatcher decodes the message, takes appropriate action local to the OpenLDV application, and responds accordingly to the network. For example, the incoming message might describe an update to an input network variable. The message dispatcher for the application receiving this message must recognize the message as a network­variable update message, and route the new network-variable data to the relevant application storage. Other message types might also cause interaction with the network. For example, the application might receive a network-variable fetch message. In this case, the dispatcher must obtain the current value of the network variable in question, and report the value to the network by constructing an appropriate response message.
The message pump thread in this example application uses the functions provided by the COpenLDVni and COpenLDVapi classes to retrieve and dispatch messages. These messages are sent using an NiDispatch method. The COpenLDVni class specifies, but does not implement, such a NiDispatch method. Therefore, the COpenLDVni class is an abstract C++ class.
The OpenLDV Developer Example implements an example for an application­specific message dispatcher (COpenLDVexampleDispatcher), derived from the COpenLDVni class, which implements the NiDispatch method.
The example dispatcher implements handlers for a variety of messages, including handlers for selected network management and diagnostics messages such as HandleQuerySnvt, HandleSetNodeMode, or HandleServicePin.
You can use the COpenLDVexampleDispatcher class as an example for your OpenLDV application, but you must adapt and rewrite the dispatcher for the application.
The OpenLDVexampleDispatcher.h header file and the OpenLDVexampleDispatcher.cpp implementation file contain comments that describe the details of the implementation.

Toolkits and User Interface

The OpenLDV Developer Example provides a simple user interface based on a single dialog. The OpenLDV ExampleDlg.cpp implementation file contains event handlers related to that user interface, such as the various click-event handlers related to buttons. The same COpenLDV ExampleDlg class also provides example instantiation of the above classes.
For most operations, however, the dialog uses the COpenLDVtools class as a toolkit. This class provides a simple interface that implements selected operations such as QueryDomain, LeaveDomain, or UpdateDomain. The COpenLDvtools class also implements a FindDevices() function that demonstrates the implementation of multi-transaction sequences within the context of this framework.
OpenLDV Programmer’s Guide 91

Developer Example Diagram

Figure 7 shows the hierarchy of the classes described in this chapter.
COpenLDVtools
QueryDomain, LeaveDomain, ...
COpenLDVexampleDispatcher
COpenLDVni
COpenLDVmessagePump
(Un-)RegisterEvent ::SetEvent
COpenLDVtrace
COpenLDVapi
NiInit, NiClose, NiSendMsgWait, NiSendResponse,
NiPauseMessagePump, NiContinueMessagePump
Start, Stop, Pause
RegisterEvent, UnregisterEvent
RegisterEvent, UnregisterEvent
PQueue<>
push, front, pop
NiDispatch
NiDispatch
NiSendImmediate, …
NiDispatch
Open, Close, Read, Write,
Open, Close, Read, Write,
Application-specific
implementation and extensions
Abstract class
(NiDispatch is pure virtual)
virtuals in
Overriding
COpenLDVapi
OpenLDV extended framework and network interface API
COpenLDVreader
Start, Stop, Pause
ldv_register_event ::SetEvent
ldv32.dll
ldv_open, ldv_close, ldv_read, ldv_write,
ldv_register_event
OpenLDV
base functions
Figure 7. OpenLDV Developer Example Class Hierarchy
92 The OpenLDV Developer Example
Loading...