vm.Script. The sandbox exposes a small set of purpose-built globals and enforces a deterministic, replay-safe execution model.
Execution model
The sandbox uses a replay-based approach to bridge the gap between a synchronous scripting API and the asynchronous, multi-round-trip nature of CWMP.Script runs and declares its data needs
The script executes and calls
declare() to describe which parameters it
wants to read or write. These are recorded as declarations, not immediately
resolved.commit() triggers a fetch cycle
When
commit() is called — either explicitly or implicitly when a declared
parameter’s attribute is first accessed — the script throws an internal
sentinel symbol and exits immediately.The session engine fulfills the declarations
GenieACS processes the collected declarations and issues the necessary CWMP
RPCs (GetParameterValues, SetParameterValues, AddObject, etc.) to the device.
The script is re-run from the beginning
Once the RPCs complete, the script starts over from line 1. Earlier
declare() calls that were already satisfied return their cached results
immediately. The script progresses further than before.Determinism across replays
Two measures ensure that replaying a script with the same inputs always produces the same outputs:Math.random()is replaced with a seeded pseudo-random number generator. The seed is derived from the device ID, so results are consistent for a given device across replays in the same session.Date.now()is controlled by the session context. All calls within a session return a stable timestamp, accessible via thenowglobal.
Script timeout
Each individual run of the script is limited to 50 milliseconds of CPU time. Long-running synchronous computations will cause the script to fault. Useext() for any operation that requires I/O or significant processing time.
Global variables
args
An array of arguments passed to the provision when it was assigned to a preset. For virtual parameter scripts, args holds metadata about the current declare/get state instead.
now
The current session timestamp in milliseconds (Unix epoch). This value is stable for the duration of a session.
Built-in functions
declare(path, timestamps, values)
Declares a parameter to be read, written, or both. This is the primary way a script interacts with device data.
| Argument | Type | Description |
|---|---|---|
path | string | The TR-069 parameter path. May include wildcards (*) and alias filters ([k:v]). |
timestamps | object | Minimum freshness requirements per attribute, as Unix timestamps. Pass null to skip. |
values | object | Attribute values to set. Pass null to skip. |
timestamps and values are:
value
value
A
[value, type] pair where type is an XSD type string (e.g.
"xsd:string", "xsd:unsignedInt"). If you supply a plain value instead of
an array, the type is inferred from the parameter’s existing type.Not available for objects or object instances.writable
writable
Boolean. For regular parameters, whether the value can be written. For
objects, whether instances can be added. For object instances, whether the
instance can be deleted.
object
object
Boolean.
true if this path refers to an object or object instance,
false for leaf parameters.path
path
Special attribute. In
timestamps, a recent timestamp causes GenieACS to
re-discover all child instances matching the path (useful after a factory
reset, or to detect new instances). In values, an integer specifies the
desired number of instances — used to create or delete object instances. See
path expressions for details.ParameterWrapper instance.
clear(path, timestamp, attributes)
Invalidates the locally-cached copy of parameters matching path whose last-refresh timestamp is older than timestamp. Child parameters are also invalidated.
The most common use case is clearing the entire cached data model after a factory reset, so GenieACS re-discovers everything from scratch:
commit()
Explicitly flushes the pending declarations and triggers a CWMP fetch/write cycle. In most scripts you do not need to call this directly — it is invoked implicitly when you access any attribute on a value returned by declare(), and at the end of the script.
Call commit() explicitly only when you need strict ordering: for example, when you must read a parameter before deciding what to write to a different parameter.
ext(file, function, ...args)
Calls a function in an extension module and returns the result. Extension calls are cached per session revision, so replays do not issue duplicate calls.
log(message)
Writes a string to the genieacs-cwmp access log. Intended for debugging.
Because scripts can run multiple times per session, you may see multiple log
entries for a single session. This is expected behavior.
ParameterWrapper
declare() returns a ParameterWrapper object that provides lazy access to parameter attributes. Accessing any attribute on it implicitly calls commit() if there are pending declarations.
Attribute accessors
The available accessors mirror the attribute names passed todeclare():
| Accessor | Type | Description |
|---|---|---|
.value | [value, type] | The parameter value and its XSD type string. |
.writable | boolean | Whether the parameter is writable. |
.object | boolean | Whether this path refers to an object. |
.path | string | The resolved concrete path of the first match. |
.size | number | undefined | The number of parameters matching the path. |
Iterating multiple results
When the path contains wildcards or alias filters, the wrapper implements the iterator protocol. Usefor...of to visit each matching parameter:
.size property gives the number of matching parameters without iterating:
Virtual parameter scripts
Virtual parameter scripts share the same sandbox API but have two differences from provision scripts:-
Return value is required. The script must return an object describing the parameter:
-
argsis not user-supplied. Instead,argsholds the declare/current state passed in by the session engine.
For full details on virtual parameters, see Virtual Parameters.