Name Date Size #Lines LOC





MakefileH A D14-Feb-20211.7 KiB6527

Makefile.comH A D14-Feb-20211.6 KiB6829

READMEH A D12-Jul-202223.9 KiB537446

libnwam.xclH A D14-Feb-20214.2 KiB201176


4# The contents of this file are subject to the terms of the
5# Common Development and Distribution License (the "License").
6# You may not use this file except in compliance with the License.
8# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9# or
10# See the License for the specific language governing permissions
11# and limitations under the License.
13# When distributing Covered Code, include this CDDL HEADER in each
14# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15# If applicable, add the following below this CDDL HEADER, with the
16# fields enclosed by brackets "[]" replaced with your own identifying
17# information: Portions Copyright [yyyy] [name of copyright owner]
22# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23# Use is subject to license terms.
25# lib/libnwam/README
29	libnwam - Network Auto-Magic (NWAM) configuration and event
30	management library
34The libnwam library is provided so that the various consumers of
35Network Auto-Magic (NWAM) configuration information - i.e. the NWAM
36GUI, the nwamcfg CLI and the NWAM daemon - have a consistent interface
37for retrieving and updating NWAM-related configuration data, abstracted
38from the actual manner in which the data is persistently stored. It
39provides functionality to interact with the key components of NWAM
40configuration, as described below.  Additionally the library provides
41functionality for system events to flow from the NWAM daemon to a
42client (like the GUI panel applet).
44Each of these configuration components is referred to as an 'entity'.
46Network Configuration Units (NCUs): units that specify either link or
47interface (IP) configuration. An NCP consists of a set of NCUs, one for
48each datalink (physical, tunnel, aggregation etc), and one for each IP
51Network Configuration Profiles (NCPs): A network configuration profile (NCP)
52comprises of a set of NCUs specifying configuration preferences to be applied
53when that profile is active.
55Locations: A location consists of additional configuration preferences
56to be applied when basic IP configuration is complete.  Information
57such as name service specification, proxies, etc. can be specified.
59External Network Modifiers (ENMs): units that specify an external service
60or executable that modifies the network configuration.  Properties of an
61ENM include an FMRI or Start and Stop exec strings, an optional environment
62which will be activated when the ENM is started, an activation type specifying
63when the ENM should be started (e.g. on user input, dependent on an NCU--
64either requiring or excluding a particular NCU, or always-on).  Each ENM
65also has a read-only state property, which indicates whether or not the
66ENM has been activated by nwam.
68Known WiFi Networks (known WLANs): units that specify configuration
69data associated with known WiFi access points that the user visits.  If
70a WLAN found by scanning is one of the known WLANs, NWAM will automatically
71connect.  Priorities associated with known WLANs can also be manipulated
72allowing users to prioritize particular WLANs.
76The event interface allows a client of NWAM (usu. the GUI) to subscribe
77to a stream of system events such as link and interface up/down,
78wireless scans, and times when NWAM needs the user to be queried.
80Events types are in libnwam.h as NWAM_EVENTS_* and the actual bodies of
81the events are in nwam_events_msg_t.  The semantics of the events have
82been simplified so that none require response.  They are all
85NWAM_EVENTS_SOURCE_{DEAD,BACK} provide notification that the nwam
86daemon has died or has reappeared.  These are synthetic events in that
87they come from the library and not from nwamd.
89NWAM_EVENTS_NO_MAGIC provides notification that nwam couldn't make a
90determination of what to do without user guidance.  This event provides
91information that can be used to ask the user if he wants to pick a
92wireless lan although in some cases nwam might have no idea what is
95NWAM_EVENTS_IF_{STATE,REMOVED} provide information about changes in
96interface state or the removal of an interface.
98NWAM_EVENTS_LINK_{STATE, REMOVED} provides information about changes in
99link state or the removal of a link.
101NWAM_EVENTS_SCAN_REPORT is used to communicate information about
102wireless networks encountered.
104Persistent configuration state of entities is stored in project-private
105/etc/nwam configuration files, and the details of storage are hidden
106from libnwam consumers.
108Access to entities is attained via an entity-specific handle. These
109handles can be obtained via calls to nwam_<entity>_create() or
110nwam_<entity>_read(), and freed (in memory) via calls to nwam_<entity>_free().
111nwam_<entity>_create() will create an in-memory representation of the
112entity, but that entity will not be stored until nwam_<entity>_commit() is
113called.  Persistently stored entitites are retrieved via nwam_<entity>_read(),
114can be modified in-memory, and later persistently committed to storage
115via nwam_<entity>_commit().  Entities can also be copied with
118All changes made after binding a handle to an entity, and prior to calling
119nwam_<entity>_commit() are carried out on the in-memory representation of that
120entity. nwam_<entity>_commit() updates persistent storage in an all-or-none
121transactional manner, applying the (possibly changed) in-memory representation
122to persistent storage atomically.
124To destroy an entity in persistent storage, nwam_<entity>_destroy() is
125used. This is distinct from nwam_<entity>_free(), which simply frees
126the in-memory representation - destroy both removes the object from
127persistent storage, and frees it in memory.
129To summarize, the pattern of interactions with an entity is
130 - nwam_<entity>_read(), nwam_<entity>_create() or nwam_<entity>_copy()
131 - possibly modify entity properties
132 - nwam_<entity>_commit() or nwam_<entity>_destroy()
133 - nwam_<entity>_handle_free()
135Unless otherwise stated functions in libnwam are MT-safe.  The
136atomicity of _commit() and _read() operations is guaranteed - i.e.
137_commit() is guaranteed to deliver all property changes to persistent
138storage, while _read() is guaranteed to read a consistent view of the
139entity (i.e. _read() cannot collide with another entity _commit()ting
140changes). However, it is possible that a _read() will retrieve an
141outdated view of an entity, if after the _read() completes, another
142entity _commit()s changes. In other words, lost updates are possible.
143These are permitted given the nature of the entities changing NWAM
144configuration (the CLI and GUI) - it seems intuitive that the most
145recent update best captures user intent.
147Entity validation on an in-memory representation can be explicitly requested
148via a call to nwam_<entity>_validate(), and individual property values
149can be validated via nwam_<entity>_validate_prop().
151Storage and retrieval of properties is done via nwam_<entity>_set_prop_value()
152and nwam_<entity>_get_prop_value().  These functions require an nwam_value_t as
153a parameter,  which is created via the nwam_value_create_<type>() family
154of functions.  Data can be retrieved from the nwam_value_t via the
155nwam_value_get_<type>() family of functions.  Once a property has been
156set, the associated nwam_value_t can be immediately freed.  For retrieval,
157the nwam_value_t should be freed when the value(s) are no longer needed.
158A property can also be delete with nwam_<entity>_delete_prop().
160Implicit validation occurs as part of the nwam_<entity>_set_prop_value()
161and nwam_<entity>_commit() functions.
165For error handling:
167const char *nwam_strerror(nwam_error_t error);
169For values:
171Values can be any of the following types:
178and are possibly multi-valued. An nwam_value_t must be created in order
179to set property values in libnwam, this is done via the follwing functions:
181nwam_error_t nwam_value_create_boolean(boolean_t, nwam_value_t *);
182nwam_error_t nwam_value_create_boolean_array(boolean_t *, uint_t,
183    nwam_value_t *);
184nwam_error_t nwam_value_create_uint64(uint64_t, nwam_value_t *);
185nwam_error_t nwam_value_create_uint64_array(uint64_t *, uint_t, nwam_value_t *);
186nwam_error_t nwam_value_create_int64(int64_t, nwam_value_t *);
187nwam_error_t nwam_value_create_int64_array(int64_t *, uint_t, nwam_value_t *);
188nwam_error_t nwam_value_create_string(char *, nwam_value_t *);
189nwam_error_t nwam_value_create_string_array(char **, uint_t, nwam_value_t *);
191Values are returned from the _get_prop_value() functions, and the data
192contained in them can be retrieved via the following functions:
194nwam_error_t nwam_value_get_boolean(nwam_value_t, boolean_t *);
195nwam_error_t nwam_value_get_boolean_array(nwam_value_t, boolean_t **, uint_t *);
196nwam_error_t nwam_value_get_uint64(nwam_value_t, uint64_t *);
197nwam_error_t nwam_value_get_uint64_array(nwam_value_t, uint64_t **, uint_t *);
198nwam_error_t nwam_value_get_int64(nwam_value_t, int64_t *);
199nwam_error_t nwam_value_get_int64_array(nwam_value_t, int64_t **, uint_t *);
200nwam_error_t nwam_value_get_string(nwam_value_t, char **);
201nwam_error_t nwam_value_get_string_array(nwam_value_t, char ***, uint_t *);
203Type and number of value can be retrieved via:
205nwam_error_t nwam_value_get_type(nwam_value_t, nwam_value_type_t *);
206nwam_error_t nwam_value_get_numvalues(nwam_value_t, uint_t *);
208and a value is freed using:
210void nwam_value_free(nwam_value_t);
212For property setting,  a typical set of events is to create the value,
213call the appropriate set_prop_value() function, then free the value (values
214can be safely freed prior to commit).  For retrieval, the type and
215number of values usually need to be tested before calling the appropriate
216retrieval function.  In this case, the value should not be freed until
217the associated data is no longer needed.
219NCUs,  locations and ENMs can all specify conditional activation conditions.
220Interfaces are provided to convert a conditional activation predicate into
221a string,  or from a string to a parsed set of variables that comprise the
222condition.  Additionally a function is provided to rate the specificity of
223the activation condition, used to compare location conditions to choose
224the most specific condition to activate in the case where the activation
225conditions of multiple locations are specified.
227nwam_error_t nwam_condition_to_condition_string(nwam_condition_object_type_t,
228    nwam_condition_t, const char *, char **);
229nwam_error_t nwam_condition_string_to_condition(const char *,
230    nwam_condition_object_type_t *, nwam_condition_t *, char **);
231nwam_error_t nwam_condition_rate(nwam_condition_object_type_t,
232    nwam_condition_t, uint64_t *);
234For NCP entities:
236nwam_error_t nwam_ncp_create(const char *name, uint64_t flags,
237    nwam_ncp_handle_t *ncp);
238nwam_error_t nwam_ncp_read(const char *name, uint64_t flags,
239    nwam_ncp_handle_t *ncp);
240nwam_error_t nwam_ncp_copy(nwam_ncp_handle_t ncp, const char *newname,
241    nwam_ncp_handle_t *newncp);
242nwam_error_t nwam_ncp_walk_ncus(nwam_ncp_handle_t ncp,
243    int(*cb)(nwam_ncu_handle_t, void *), void *data, uint64_t flags, int *ret);
244nwam_error_t nwam_ncp_get_name(nwam_ncp_handle_t ncp, char **name);
245nwam_error_t nwam_ncp_activate(nwam_ncp_handle_t ncp);
246nwam_error_t nwam_ncp_deactivate(nwam_ncp_handle_t ncp);
247nwam_error_t nwam_ncp_destroy(nwam_ncp_handle_t ncp, uint64_t flags);
248void nwam_ncp_free(nwam_ncp_handle_t ncp);
250Since the NCP simply consists of the NCUs that comprise it, there is
251no NCP-specific commit() function - we simply read the NCP, walk the
252constituent NCUs, reading, changing or committing them in turn.  The
253walk can be modified via the flags option to only select specific NCU types
254and classes.
256Each NCP has a set of NCUs associated with it, each of which is created/modifed
257using the functions below.
259For NCU entities:
261nwam_error_t nwam_ncu_create(nwam_ncp_handle_t ncp, const char *name,
262    nwam_ncu_type_t type, nwam_ncu_class_t class, nwam_ncu_handle_t *ncu);
263nwam_error_t nwam_ncu_read(nwam_ncp_handle_t ncp, const char *name,
264    nwam_ncu_type_t type, uint64_t flags, nwam_ncu_handle_t *ncu);
265nwam_error_t nwam_ncu_copy(nwam_ncu_handle_t ncu, const char *newname,
266    nwam_ncu_handle_t *newncu);
267nwam_error_t nwam_ncu_commit(nwam_ncu_handle_t ncu, uint64_t flags);
268nwam_error_t nwam_ncu_destroy(nwam_ncu_handle_t ncu, uint64_t flags);
269nwam_error_t nwam_ncu_free(nwam_ncu_handle_t ncu);
270nwam_error_t nwam_ncu_validate(nwam_ncu_handle_t ncu, const char **errprop);
271nwam_error_t nwam_ncu_get_prop_value(nwam_ncu_handle_t ncu, const char *prop,
272    nwam_value_t *value);
273nwam_error_t nwam_ncu_get_prop_description(const char *prop,
274    const char **description);
275nwam_error_t nwam_ncu_delete_prop(nwam_ncu_handle_t ncu, const char *prop);
276nwam_error_t nwam_ncu_set_prop_value(nwam_ncu_handle_t ncu, const char *prop,
277    nwam_value_t value);
278nwam_error_t nwam_ncu_get_name(nwam_ncu_handle_t ncu, char **name);
279nwam_error_t nwam_ncu_set_name(nwam_ncu_handle_t ncu, const char *name);
280nwam_error_t nwam_ncu_get_read_only(nwam_ncu_handle_t ncu, boolean_t *readp);
281nwam_error_t nwam_ncu_validate_prop(nwam_ncu_handle_t ncu, const char *prop,
282    nwam_value_t value);
283nwam_error_t nwam_ncu_walk_props(nwam_ncu_handle_t ncu,
284    int (*func)(void *, const char *, nwam_value_t), void *data,
285    uint64_t flags, int *ret);
286nwam_error_t nwam_ncu_prop_get_type(const char *prop,
287    nwam_value_type_t *value_type);
288nwam_error_t nwam_ncu_get_ncp(nwam_ncu_handle_t ncu, nwam_ncp_handle_t *ncp);
290NCUs are manipulated via an nwam_ncu_handle_t.
292Each NCU has a set of properties associated with it. Each property can
293have mutiple values associated with it, which are set or retrieved via an
294nwam_value_t.  The approach is similar to that used for Locations,   with
295the difference that read/commit/destroy must specify an NCP.  Only two
296NCPs are supported at present, the automatic and user NCPs. Modification
297of the former is restricted to nwamd itself,  and attempts to modify
298the automatic NCP's consituent NCUs will result in an NWAM_ENTITY_READ_ONLY
301For Location entities:
303nwam_error_t nwam_loc_create(const char *name, nwam_loc_handle_t *loc);
304nwam_error_t nwam_loc_read(const char *name, uint64_t flags,
305    nwam_loc_handle_t *loc);
306nwam_error_t nwam_loc_copy(nwam_loc_handle_t loc, const char *newname,
307    nwam_loc_handle_t *newloc);
308nwam_error_t nwam_walk_locs(int (*cb)(nwam_loc_handle_t loc, void *arg),
309    void *arg, uint64_t flags, int *cbretp);
310nwam_error_t nwam_loc_commit(nwam_loc_handle_t loc, uint64_t flags);
311nwam_error_t nwam_loc_destroy(nwam_loc_handle_t loc, uint64_t flags);
312void nwam_loc_free(nwam_loc_handle_t loc);
313nwam_error_t nwam_loc_validate(nwam_loc_handle_t loc, const char *errprop);
314nwam_error_t nwam_loc_walk_props(nwam_loc_handle_t loc,
315    int (*cb)(const char *, nwam_value_t **, void *),
316    void *arg, uint64_t flags, int *cbret);
317nwam_error_t nwam_loc_validate_prop(nwam_loc_handle_t loc,
318    const char *prop, nwam_value_t value);
319nwam_error_t nwam_loc_prop_get_type(const char *prop,
320    nwam_value_type_t *value_type);
321nwam_error_t nwam_loc_get_prop_value(nwam_loc_handle_t loc, const char *prop,
322    nwam_value_t *value);
323nwam_error_t nwam_loc_get_prop_description(const char *prop,
324    const char **description);
325nwam_error_t nwam_loc_delete_prop(nwam_loc_handle_t loc, const char *prop);
326nwam_error_t nwam_loc_set_prop_value(nwam_loc_handle_t loc, const char *prop,
327    nwam_value_t value);
328nwam_error_t nwam_loc_get_name(nwam_loc_handle_t loc, char **name);
329nwam_error_t nwam_loc_set_name(nwam_loc_handle_t loc, const char *name);
330nwam_error_t nwam_loc_activate(nwam_loc_handle_t loc);
331nwam_error_t nwam_loc_deactivate(nwam_loc_handle_t loc);
333Locations are manipulated via an nwam_loc_handle_t.
335A loc handle maps to an in-memory representation of a location; operations via
336this interface manipulate the in-memory data.  In-memory data is read from
337persistant storage via the nwam_loc_read() or nwam_walk_locs() functions, and
338written out to persistent storage via the nwam_loc_commit() function.  A loc
339may be permanently removed from persistent storage with the nwam_loc_destroy()
340function.  Interactions with persistent storage will be nonblocking by default;
341this behavior can be changed by passing the NWAM_FLAG_BLOCKING in the flags
344A typical sequence would be to allocate a loc handle, either by creating a
345new loc (nwam_loc_create()) or by reading one from persistent storage (nwam_
346loc_read() or nwam_walk_locs()).  The various set/get/walk/validate/(de)activate
347functions may then be used to manipulate the loc; any changes made may then be
348committed to persistent storage via nwam_loc_commit().  A call to nwam_loc_
349free() is required to release in-memory resources associated with the handle.
351The flags parameter in the walk functions allows filtering of the locs that
352will be examined, depending on the state of each loc.  Passing in
353NWAM_FLAG_STATE_ALL will examine all locs; specific state flags are defined
354in <libnwam.h>.
356Like NCUs, each loc has a set of properties associated with it. Loc properties
357are stored in nwam_value_t structures; see the Values section for how to store/
358retrieve using these.
360For ENM entities:
362nwam_error_t nwam_enm_create(const char *name, const char *fmri,
363    nwam_enm_handle_t *enm);
364nwam_error_t nwam_enm_read(const char *name, uint64_t flags,
365    nwam_enm_handle_t *enm);
366nwam_error_t nwam_enm_copy(nwam_enm_handle_t enm, const char *newname,
367    nwam_enm_handle_t *newenm);
368nwam_error_t nwam_walk_enms(int (*cb)(nwam_enm_handle_t enm, void *arg),
369    void *arg, uint64_t flags, int *cbretp);
370nwam_error_t nwam_enm_commit(nwam_enm_handle_t enm, uint64_t flags);
371nwam_error_t nwam_enm_destroy(nwam_enm_handle_t enm, uint64_t flags);
372void nwam_enm_free(nwam_enm_handle_t enm);
373nwam_error_t nwam_enm_validate(nwam_enm_handle_t enm, const char *errprop);
374nwam_error_t nwam_enm_walk_props(nwam_enm_handle_t enm,
375    int (*cb)(const char *, nwam_value_t **, void *),
376    void *arg, uint64_t flags, int *cbret);
377nwam_error_t nwam_enm_validate_prop(nwam_enm_handle_t enm,
378    const char *prop, nwam_value_t value);
379nwam_error_t nwam_enm_prop_get_type(const char *prop,
380    nwam_value_type_t *value_type);
381nwam_error_t nwam_enm_get_prop_value(nwam_enm_handle_t enm, const char *prop,
382    nwam_value_t *value);
383nwam_error_t nwam_enm_get_prop_description(const char *prop,
384    const char **description);
385nwam_error_t nwam_enm_delete_prop(nwam_enm_handle_t enm, const char *prop);
386nwam_error_t nwam_enm_set_prop_value(nwam_enm_handle_t enm, const char *prop,
387    nwam_value_t value);
388nwam_error_t nwam_enm_get_name(nwam_enm_handle_t enm, char **name);
389nwam_error_t nwam_enm_set_name(nwam_enm_handle_t enm, const char *name);
390nwam_error_t nwam_enm_activate(nwam_enm_handle_t enm);
391nwam_error_t nwam_enm_deactivate(nwam_enm_handle_t enm);
393ENMs are manipulated via an nwam_enm_handle_t, in a similar manner to
394NCUs and locations.
396The flags parameter in the walk functions allows filtering of the ENMs that
397will be examined, depending on the state of each ENM.  Passing in
398NWAM_FLAG_STATE_ALL will examine all ENMs; specific state flags are defined
399in <libnwam.h>.
401Like NCUs, each ENM has a set of properties associated with it. ENM properties
402are all single valued, though the interface is aligned with the NCU interface,
403which allows for multi-valued properties.  ENM properties are stored in
404nwam_value_t structures; see the Values section for how to store/retrieve
405using these.
407For known WLAN entities:
409nwam_error_t nwam_known_wlan_create(const char *name,
410    nwam_known_wlan_handle_t *kwhp);
411nwam_error_t nwam_known_wlan_read(const char *name, uint64_t flags,
412    nwam_known_wlan_handle_t *kwhp);
413nwam_error_t nwam_known_wlan_copy(nwam_known_wlan_handle_t kwh,
414    const char *newname, nwam_known_wlan_handle_t *newkwh);
415nwam_error_t nwam_walk_known_wlans(int (*cb)(nwam_known_wlan_handle_t, void *),
416    void *arg, uint64_t flags, int *cbretp);
417nwam_error_t nwam_known_wlan_commit(nwam_known_wlan_handle_t kwh,
418    uint64_t flags);
419nwam_error_t nwam_known_wlan_destroy(nwam_known_wlan_handle_t kwh,
420    uint64_t flags);
421void nwam_known_wlan_free(nwam_known_wlan_handle_t kwh);
422nwam_error_t nwam_known_wlan_validate(nwam_known_wlan_handle_t kwh,
423    const char *errprop);
424nwam_error_t nwam_known_wlan_walk_props(nwam_known_wlan_handle_t kwh,
425    int (*cb)(const char *, nwam_value_t **, void *),
426    void *arg, uint64_t flags, int *cbret);
427nwam_error_t nwam_known_wlan_validate_prop(nwam_known_wlan_handle_t kwh,
428    const char *prop, nwam_value_t value);
429nwam_error_t nwam_known_wlan_prop_get_type(const char *prop,
430    nwam_value_type_t *value_type);
431nwam_error_t nwam_known_wlan_get_prop_value(nwam_known_wlan_handle_t kwh,
432    const char *prop, nwam_value_t *value);
433nwam_error_t nwam_known_wlan_get_prop_description(const char *prop,
434    const char **description);
435nwam_error_t nwam_known_wlan_delete_prop(nwam_known_wlan_handle_t kwh,
436    const char *prop);
437nwam_error_t nwam_known_wlan_set_prop_value(nwam_known_wlan_handle_t kwh,
438    const char *prop, nwam_value_t value);
439nwam_error_t nwam_known_wlan_get_name(nwam_known_wlan_handle_t kwh,
440    char **name);
441nwam_error_t nwam_known_wlan_set_name(nwam_known_wlan_handle_t kwh,
442    const char *name);
443nwam_error_t nwam_known_wlan_add_to_known_wlan(const char *essid,
444    const char *bssid);
445nwam_error_t nwam_known_wlan_remove_from_known_wlan(const char *essid,
446    const char *bssid);
448Known WLANs are manipulated via an nwam_known_wlan_handle_t, in a similar
449manner to NCUs, locations and ENMs.
451Like ENMs, each known WLAN has a set of properties associated with it.
452Known WLAN properties are stored in nwam_value_t structures; see the Values
453section for how to store/retrieve using these.
455For WLANs, we define a set of functions to ask nwamd to initiate a scan,
456select a WLAN (and possibly add it to the known WLAN list) or set a WLAN
460extern nwam_error_t nwam_wlan_scan(const char *linkname);
461extern nwam_error_t nwam_wlan_get_scan_results(const char *linkname,
462    uint_t *num_resultsp, nwam_wlan_t **wlansp);
463extern nwam_error_t nwam_wlan_select(const char *linkname,
464    const char *essid, const char *bssid, boolean_t add_to_known_wlans);
465extern nwam_error_t nwam_wlan_set_key(const char *linkname, const char *essid,
466    const char *bssid, uint32_t security_mode, uint_t keyslot, const char *key);
468For Events:
470typedef struct nwam_event {
471	uint32_t type;
473	union {
474		struct {
475			nwam_object_type_t object_type;
476			char name[NWAM_MAX_NAME_LEN];
477			nwam_action_t action;
478		} object_action;
481		... and so on for each message ...
483	} data;
485} *nwam_event_t;
487type comes from the set of constants NWAM_EVENT_TYPE_*.
489Registration and cancellation of registration are done via
490_init and _fini functions:
492extern nwam_error_t nwam_events_init(void);
493extern void nwam_events_fini(void);
495Events can then be recieved by calling nwam_event_wait():
497extern nwam_error_t nwam_event_wait(nwam_event_t *);
499The event can then be processed, and free via nwam_event_free();
503All functions return an nwam_error_t if they return an error. Possible
504errors are:
506	NWAM_SUCCESS			No error occured
507	NWAM_LIST_END			End of list
508	NWAM_INVALID_HANDLE		Entity handle is invalid
509	NWAM_HANDLE_UNBOUND		Handle not bound to entity
510	NWAM_INVALID_ARG		Argument is invalid
511	NWAM_PERMISSION_DENIED		Insufficient privileges for action
512	NWAM_NO_MEMORY			Out of memory
513	NWAM_ENTITY_EXISTS		Entity already exists
514	NWAM_ENTITY_IN_USE		Another user is interacting with entity
515	NWAM_ENTITY_COMMITTED		Entity already committed
516	NWAM_ENTITY_NOT_FOUND		Entity not found
517	NWAM_ENTITY_TYPE_MISMATCH	Entity value-type mismatch
518	NWAM_ENTITY_INVALID		Validation of entity failed
519	NWAM_ENTITY_INVALID_MEMBER	Entity member invalid
520	NWAM_ENTITY_INVALID_VALUE	Validation of entity value failed
521	NWAM_ENTITY_NO_VALUE		No value associated with entity
522	NWAM_ENTITY_MULTIPLE_VALUES,	Multiple values for entity
523	NWAM_ENTITY_READ_ONLY,		Entity is marked read only
524	NWAM_WALK_HALTED,		Callback function returned nonzero
525	NWAM_ERROR_BIND,		Could not bind to backend
526	NWAM_ERROR_BACKEND_INIT,	Could not initialize backend
527	NWAM_ERROR_INTERNAL		Internal error
530	/lib/	shared object
536	nwamd(8), nwamcfg(8), nwamadm(8)