Skeleton script

The script can be divided into following two parts:
  • Main codec functions, encode() and decode().
  • Utility functions used by the codec.

A skeleton codec script:

var utils = Java.type('com.nokia.transformation.script.model.TransformUtil');
 
function LoraPulseCodec() {
 
    ///////////////////////////////
    // Encoder function
    this.encode = function (impactRequest) {
 
        // 1. get the request details from input
        var request = getImpactRequestAsJson(impactRequest);
 
        // 2. handle the request
        var resBuffer;      // typeof resBuffer is Int8Array
        var unack = true;   // true means this request has no response/ack from the device
        switch (request.type) {
            case "READ":
                unack = false; // device will response for READ, hence setting unack = false
 
                // handle read request and set resBuffer
                break;
            case "WRITE":
                // handle write request and set resBuffer
                break;
            case "EXECUTE":
                // handle execute request and set resBuffer
                break;
            case "OBSERVE":
            case "DELETE":
            default:
                // throw error if a request type is not supported
                throw new Error(`request type ${request.type} not supported by the lora pulse device`);
        }
 
        return  utils.createBinaryResponse(resBuffer, _map, unack);
    }
     
    ///////////////////////////////
    // Decoder Function
    this.decode = function (decodeCtx) {
 
        var bytes = decodeCtx.getUplinkMessage();
            
        var resources = [];
        // decode the input and extract all resource information available
 
        // return as json
        return formImpactResponseFromJson(decodeCtx, resources, (result == success));
    }
 
}
 
var codec = new LoraPulseCodec();
 
(codec);
The util functions for the codec can be defined as below:
var utils = Java.type('com.nokia.transformation.script.model.TransformUtil');
 
// utility functions
//
 
function getImpactRequestAsJson(impactRequest) {
 
    var request = {};
    request.type = utils.getRequestType(impactRequest);
    request.url = impactRequest.getResource();
 
    if (!request.type || !request.url) {
        throw new Error(`request type and resource URL are required in the input`);
    }
 
    var resourceItems = request.url.split("/");
    request.resource = resourceItems[resourceItems.length - 1];
 
    if (impactRequest.getValue) {
        request.resourceValue = impactRequest.getValue();
    }
 
    console.log("input to encoder", request);
 
    return request;
}
 
function formImpactResponseFromJson(decodeCtx, resources, success=true) {
 
    if(decodeCtx.getRequest() != null) {
        var corrId = decodeCtx.getRequest().getCorrelatorId();
 
        var resp = {responseCode: success? 0: 1, requestStatus: 0, response: [], correlatorId: corrId};
        var resourceObj = {"device/0/endPointClientName":client.getEndpoint()};
        resources.forEach(resource => {
            resourceObj[resource.name] = resource.value;
        });
        resp.response.push(resourceObj);
 
        console.log('sending response ' + JSON.stringify(resp));
        return utils.createJsonResponse(JSON.stringify(resp));
 
    } else {
 
        var resp = {details: {"device/0/endPointClientName": client.getEndpoint()}};
        resources.forEach(resource => {
            resp.details[resource.name] = resource.value;
        });
 
        console.log('sending notification ' + JSON.stringify(resp));
        return utils.createJsonResponse(JSON.stringify(resp));
    }
 
}
 
function buf2hex(buffer) { // buffer is an ArrayBuffer
    return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}
 
function bytes2String(bytes, offset=0) {
    if (offset < 0) { offset=0; }
 
    var result = "";
    for (var i = offset; i < bytes.length; i++) {
        result += String.fromCharCode(bytes[i]);
    }
    return result;
}
 
function string2Bytes(str, offset=0) {
    if (offset < 0) { offset=0; }
 
    var bytes;
    const strLen = str? str.length : 0;
    bytes = new Array(strLen + offset);
 
    for (var i = 0; i < strLen; i++) {
        bytes[offset+i] = str.charCodeAt(i);
    }
 
    return bytes;
}
 
function isBitSet(byte, bitNum) {
    return ((byte >> bitNum) & 0xFF) == 0x01;
}