Skip to content

Sending requests

Tap communication is based on a Lightweight M2M protocol, where the Tap device plays a role of a server and the mobile app an LwM2M client. Available commands are organized into services. See the list of services and functions.

There are two ways to send requests to your Tap:

Service API

The Service API is a wrapper on the IoTize Client API that lists availables services and handles sending requests building and binary parsing of responses.

If you want to send raw requests, you can use the client directly (see Client API)

Accessing service object

import { Tap } from "@iotize/device-client.js/device";
import { BundleService, TargetService, FirmwareService } from "@iotize/device-client.js/device/service";

let tap: Tap;

let bundleService: BundleService = tap.service.bundle
let targetService: TargetService = tap.service.target
let firmwareService: FirmwareService = tap.service.firmware
// ...

import com.iotize.android.device.device.impl.IoTizeDevice;
import com.iotize.android.device.device.api.service.definition.BundleService;
import com.iotize.android.device.device.api.service.definition.FirmwareService;
import com.iotize.android.device.device.api.service.definition.TargetService;

IoTizeDevice tap = // ... ;

// Access different services:
BundleService bundleService = tap.service.bundle;
TargetService targetService = tap.service.target;
FirmwareService firmwareService = tap.service.firmware;
// ...
let tap: TapDevice = // ... ;

// Access different services:
let bundleService: BundleService = tap.service.bundle;
let targetService: TargetService = tap.service.target;
let firmwareService: FirmwareService = tap.service.firmware;

Performing calls

You can make synchronous or asynchronous calls to the tap device.

Synchronously

// Only available if you are in an ASYNC function
let response: Response<string> = await tap.service.device.getSerialNumber();
Call<String> call = tap.service.device.getSerialNumber();
Response<String> response = call.execute();
let response: ApiResponse<String> = try tap.service.device.getSerialNumber();

Asynchronously, with callbacks

import { Response } from "@iotize/device-client.js/client/api/response";
import { Tap } from "@iotize/device-client.js/device";

let tap: Tap // Init you tap instance...

let responsePromise: Promise<Response<string>> = tap.service.device.getSerialNumber();

responsePromise
    .then((response: Response<string>) => {
        console.log('Device response:', response);
    })
    .catch((error) => {
        console.error('An error occured:', error);
    })

Call<String> call = tap.service.device.getSerialNumber();
commandCall.enqueue(new ICallback<String>() {
    @Override
    public void onResponse(Call<String> call, Response<String> response) {
        // Do what you need here
    }

    @Override
    public void onFailure(Call<String> call, Throwable throwable) {
        Log.e("yourlogtag", "Error occured: " + throwable.getMessage(), throwable);
    }
});
// Not available yet

Client API

Command format

LwM2M frames are composed by:

  • header: command type (GET, PUT or POST) and command path string with <Object ID>/<Object Instance ID>/<Resource ID>.
  • payload: in bytes.

Building a command

Commands are built by a Command Object. You can use helper methods to instantiate it according to the request type you want to use.

import { ApiRequest } from '@iotize/device-client.js/client/impl/request';
// Get request
let getRequest = ApiRequest.GET("/1/2/3")
// Put request with body 0x01020304
let putRequest = ApiRequest.PUT("/1/2/3", Uint8Array.from([1,2,3,4]))
// Post request with body 0x01020304
let postRequest = ApiRequest.POST("/1/2/3", Uint8Array.from([1,2,3,4]))

import com.iotize.android.device.api.client.request.Command;

// Get command 
Command command = Command.GET("/1/2/3")
// Put command
Command command = Command.PUT("/1/2/3")
// Post command
Command command = Command.POST("/1/2/3")

import TapDeviceClient
// Get command
let request = ApiRequest.GET<Bytes>(path: "/1/2/3")
// Put command
let request = ApiRequest.PUT<Bytes>(path: "/1/2/3")
// Post command
let request = ApiRequest.POST<Bytes>(path: "/1/2/3")

Handling Response

A response is composed of

  • result code: See the list of result code returns by a Tap.
  • payload (optionally): encoded data (bytes)

A Response can be configured with a Converter class to decode bytes into the corresponding type. If you are using the Service API, Response is preconfigured with the proper Converter instance. We suppose in the following examples that we have a response for the getSerialNumber command which returns an ASCII string.

import { Response } from "@iotize/device-client.js/client/impl/response"

let response: Response<string> = //...;

if (response.isSuccess()){
    // If you are using Service API
    let serialNumber = response.body();

    // Or if you build request with the client, you can give the converter type
    let serialNumber = resonse.body(StringConverter.instance());
}
else {
    // Handle invalid response
    console.error(`Response error: ${response.codeRet()}`);
}
import com.iotize.android.device.api.client.response.Response;

Response<String> response = // ...;

// Check if command was successful
if (response.isSuccessful()){
    String serialNumber = response.body();
    Log.i("yourlogtag", "Serial number is : " + serialNumber);
}
else{
    // If command is not successful we can check error code to know why
    Log.w("yourtag", "Iotize error code: " + response.codeRet());
}
let response: ApiResponse<String> = // ...;
if (response.isSuccessful()){
    let serialNumber: String = response.body();
    print("Serial number is : \(serialNumber)");
}
else{
    // If command is not successful we can check error code to know why
    print("Iotize error code: \(response.codeRet()");
}

You can also access raw body (without any decoding)

let body: Uint8Array = response.rawBody();
byte[] body = response.rawBody();
let bytes: Bytes = response.rawBody()