Menu

Knox Webhook Notification for Knox Asset Intelligence

The following tutorials will help you get started on using the Knox Webhook Notification API for Knox Asset Intelligence.

Currently, the Knox Webhook Notification API supports the following Knox Asset Intelligence events:

Prerequisites

Registration

To successfully make calls to the Knox Asset Intelligence API, ensure that you've configured Knox Asset Intelligence in the Knox Admin Portal and enrolled your managed devices in Knox Asset Intelligence. See Get started with Knox Asset Intelligence for details.

Authentication

To get started with using the Knox Asset Intelligence API, you need an authentication token. For more information, see Knox Cloud API Authentication tutorial for customers.

Certificate

Download your Samsung Knox validation certificate. You'll need this to validate the response you'll receive from Knox Webhook Notification.

DOWNLOAD CERTIFICATE

Use the Knox Webhook Notification API

App no response and force close

Step 1: Subscribe an event

  1. Subscribe a particular event to Knox Webhook Notification through the Create Subscription operation — POST /kwn/v1/subscriptions:
  2. Provide a subscription URL — known as a "callback" — that you'll register to receive asynchronous API operation results.
  3. Register the KAI_APP_ANR_FC event to asynchronously receive ANR and FC event details. Knox Asset Intelligence checks for ANR and FC events every hour and only posts event details if there have been any new issues since the previous check.

Step 2: Handle response message

If there's been an ANR/FC event, you'll receive the following message in the body of the subscribed URL call as the response payload:

{ 
    "subscriptionId" : "123456789123",
    "event" : "KAI_APP_ANR_FC",
    "payload": {
    "imei": "123456789",
    "imei1": "123456789",
    "imei2": "465789132",
    "serialNumber" : "EX4MP13",
    "appName": "Android System WebView",
    "appVersion": "98.0.4606.89",
    "packageName": "com.google.android.webview",
    "class": "com.samsung.android.knox.rtls.ui.view.landing.TabVenueFragment",
    "callStack": "java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference at com.samsung.android.knox.rtls.ui.view.landing.TabVenueFragment.onViewCreated(TabVenueFragment.java:72)",
    "osVersion": "Android 11",
    "firmwareVersion": "4.14.190-23230211-abG973WVLS6HVA1",
    "model": "Example Device",
    "issueType": "ANR",
    "groupName": "Example Group",
    "updatedTime": 1692994420,
    "timeZone": "EST"
    }
}
            

Wi-Fi disconnections

Step 1: Subscribe an event

  1. Subscribe a particular event to Knox Webhook Notification through the Create Subscription operation — POST /kwn/v1/subscriptions:
  2. Provide a subscription URL — known as a "callback" — that you'll register to receive asynchronous API operation results.
  3. Register the KAI_WIFI_DISCONNECTIONS event to asynchronously receive abnormal Wi-Fi disconnection event details as they occur.

Step 2: Handle response message

In the event of an abnormal Wi-Fi disconnection, you'll receive the following message in the body of the subscribed URL call as the response payload:

{ 
    "subscriptionId" : "123456789123",
    "event" : "KAI_WIFI_DISCONNECTIONS",
    "payload": {
    "imei": "123456789",
    "serialNumber" : "EX4MP13",
    "groupName": "Example Group",
    "localGenerated": "GENERATED_BY_DEVICE",
    "disconnectionCategory": "3rd Party App",
    "disconnectionEvent": "Caused by 3rd Party App",
    "disconnectionReasonCode": "36",
    "disconnectionReason": "Requesting STA is leaving the BSS (or resetting) (36)",
    "bssid": "00:30:00:00:00:00",
    "ssid": "DAI_DEV_2.5G",
    "vendorName": "Example Vendor",
    "oui": "e8:07:bf",
    "accessPointType": "APTYPE_PASSPOINT",
    "frequency": "5000",
    "screenState": "SCREEN_OFF",
    "powerSavingMode": "POWER_OFF",
    "updatedTime": 1692989890863,
    "timeZone": "EST"
    }
}
            

Battery status

Step 1: Subscribe an event

  1. Subscribe a particular event to Knox Webhook Notification through the Create Subscription operation — POST /kwn/v1/subscriptions:
  2. Provide a subscription URL — known as a "callback" — that you'll register to receive asynchronous API operation results.
  3. Register the KAI_BATTERY_STATUS event to asynchronously receive battery status details. Knox Asset Intelligence provides battery status information every three hours periodically.

Step 2: Handle response message

Every three hours, you'll receive the following message in the body of the subscribed URL call as the response payload:

{ 
    "subscriptionId" : "123456789123",
    "event" : "KAI_BATTERY_STATUS",
    "payload": {
    "imei": "123456789",
    "imei1": "123456789",
    "imei2": "465789132",
    "serialNumber" : "EX4MP13",
    "groupName": "Example Group",
    "model": "Example Device",
    "updatedTime": 1692989890863,
    "timeZone": "EST",
    "batteryChargingType": "",
    "batteryChargingPlug": "N/A",
    "batteryLevel": 74,
    "batteryRemainingTime": 1118,
    "batterySoh": "Good",
    "batterySohValue": 99,
    "batteryStatus": "Discharging",
    "batteryChargingCycle": 29,
    "fullChargeBatteryTime": 1511
    }
}
            

Device diagnostics logs

Step 1: Subscribe an event

  1. Subscribe a particular event to Knox Webhook Notification through the Create Subscription operation — POST /kwn/v1/subscriptions:
  2. Provide a subscription URL — known as a "callback" — that you'll register to receive asynchronous API operation results.
  3. Register the KAI_DEVICE_DIAGNOSTICSLOGS event to asynchronously receive the device diagnostics log once it's complete. Knox Asset Intelligence can take up to five minutes to generate the log file.

Step 2: Generate device diagnostics logs

The generating operation makes an API call to the Knox Asset Intelligence generate device debug logs operation.

Step 3: Handle response message

After Knox Asset Intelligence finishes generating the device diagnostics log, you'll receive the following message in the body of the subscribed URL call as the response payload:

{ 
    "subscriptionId" : "123456789123",
    "event" : "KAI_DEVICE_DIAGNOSTICSLOGS",
    "payload": {
    "imei": "123456789",
    "imei1": "123456789",
    "imei2": "465789132",
    "serialNumber" : "EX4MP13",
    "logId": "64e851ddc136352a60a5e1a0",
    "status": "Completed",
    "downloadLink": "https://example-download-link.com/log.zip",
    "groupName": "Example Group",
    "updatedTime": 1692989890863
    }
}
            

Verify the response

To verify the Knox Webhook Notification callback response:

  1. Get the String value of HttpRequestPayload
  2. byte[] inputStreamBytes = StreamUtils.copyToByteArray(request.getInputStream());
    Map jsonBody = objectMapper.readValue(inputStreamBytes, HashMap.class);
    String requestBody = objectMapper.writeValueAsString(jsonBody);            
                  
  3. Parse the encoded JoseHeader and signature from X-WSM-SIGNATURE
  4. String[] jwsParts = jwsSignature.split("\\.");
    if (jwsParts.length != 3) {
      // Invalid JWS signature,              
      return new ResponseEntity<>("Invalid JWS signature: X-WSM-SIGNATURE=" + jwsSignature, HttpStatus.BAD_REQUEST);
    }
    
    String encodedHeaders = jwsParts[0];
    String encodedRequestBody =  Base64.getUrlEncoder().encodeToString(requestBody.getBytes(StandardCharsets.UTF_8));
    String signature = jwsParts[2];            
                  
  5. Prepare the data to verify: DataToVerify = encodedJoseHeader.Base64UrlEncode(HttpRequestPayload)
  6. String dataToVerify = encodedHeaders + "." + encodedRequestBody;
                  
  7. Decode the signature with Base64Url decoder and verify the data above by using SHA256withRSA
    • verify(DataToVerify, Base64UrlDecode(Signature))
    byte[] signatureByte = Base64.getUrlDecoder().decode(signature);
    
    Signature rsaSignature = Signature.getInstance("SHA256withRSA");
    
    // Pre-download Samsung certificate and store it locally with your application. Load public key from locallyed stored cert file.
    
    rsaSignature.initVerify(publicKey);  
    rsaSignature.update(dataToVerify.getBytes(StandardCharsets.UTF_8));
    boolean verified = rsaSignature.verify(signatureByte);
    if (verified) {
      // Process the result
      // DO YOUR BUSINESS LOGIC, returns OK
    
      return new ResponseEntity<> ("Result is processed successfully", HttpStatus.OK);
    } else {
      return new ResponseEntity<>("Signature validation failed: X-WSM-SIGNATURE=" + jwsSignature, HttpStatus.INTERNAL_SERVER_ERROR);
    }
                  

Complete code

public ResponseEntity<String> receiveResult(HttpServletRequest request,
  @Valid @NotBlank @RequestHeader(value="X-WSM-SIGNATURE") String jwsSignature,
  @Valid @NotBlank @RequestHeader(value="X-WSM-TRACEID") String transId) {
      try {
        // 1. Get the request body
        byte[] inputStreamBytes = StreamUtils.copyToByteArray(request.getInputStream());
        Map jsonBody = objectMapper.readValue(inputStreamBytes, HashMap.class);
        String requestBody = objectMapper.writeValueAsString(jsonBody);

        // 2. Verify the data and signature
        String[] jwsParts = jwsSignature.split("\\.");
        if (jwsParts.length != 3) {
          // Invalid JWS signature,              
          return new ResponseEntity<>("Invalid JWS signature: X-WSM-SIGNATURE=" + jwsSignature, HttpStatus.BAD_REQUEST);
      }

      String encodedHeaders = jwsParts[0];
      String encodedRequestBody =  Base64.getUrlEncoder().encodeToString(requestBody.getBytes(StandardCharsets.UTF_8));
      String signature = jwsParts[2];

      String dataToVerify = encodedHeaders + "." + encodedRequestBody;
      byte[] signatureByte = Base64.getUrlDecoder().decode(signature);

      Signature rsaSignature = Signature.getInstance("SHA256withRSA");

      // Pre-download Samsung certificate and store it locally with your application. Load public key from locallyed stored cert file.

      rsaSignature.initVerify(publicKey);  
      rsaSignature.update(dataToVerify.getBytes(StandardCharsets.UTF_8));
      boolean verified = rsaSignature.verify(signatureByte);
      if (verified) {
        // 3. Process the result
        // DO YOUR BUSINESS LOGIC and returns OK

        return new ResponseEntity<> ("Result is processed successfully", HttpStatus.OK);
      } else {
        return new ResponseEntity<>("Signature validation failed: X-WSM-SIGNATURE=" + jwsSignature, HttpStatus.INTERNAL_SERVER_ERROR);
      }

    } catch (Exception e) {
      log.error("receiveResult: failed to verify or parse request body", e);
      return new ResponseEntity<>("Internal error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }
            

One URL for multiple subscriptions

As a customer, you can configure one URL to subscribe to multiple events, as follows:

  1. Use customerA to create the subscription using the Knox Webhook Notification Subscription API.
  2. Configure example.com/kwn_result/customerA as the callback URL.
  3. Make a call to one or more supported events using the same callback URL.

Once you successfully complete these steps, the configured URL example.com/kwn_result/customerA will receive the operation result.