# KeplerNetworkManagerTM - A KeplerScript Library
**KeplerNetworkManagerTM** is a library to provide APIs for managing network interfaces.

Using APIs in **KeplerNetworkManagerTM**, a KeplerScript application can:
- Enable or disable network interfaces
- Query network status
- Monitor network connections and events
- Manage Wi-Fi access point information and connections
- Monitor Wi-Fi events

**KeplerNetworkManagerTM** includes support for [React Native Network Info](https://github.com/react-native-netinfo/react-native-netinfo), allowing KeplerScript applications to use the same APIs available in React Native Network Info."

## Getting Started
A KeplerScript application can consume **KeplerNetworkManagerTM** for network support.

### Setup
To use the **KeplerNetworkManagerTM**, follow the instructions below:

1. Update `Config`
 Go to the `Config` file in your package and add *KeplerNetworkManagerTM* with 1.0 version.

```json
    dependencies = {
        1.0 = {
            ...
            KeplerNetworkManagerTM = 1.0;
        };
    };
```

2. Update `package.json`
 Open `package.json` file and add "@amazon-devices/keplerscript-netmgr-lib" with the version of "~2.0.0".

```json
     "dependencies": {
       ...
       "@amazon-devices/keplerscript-netmgr-lib": "~2.0.0"
     },
```

3. Add `com.amazon.network.service` to `[wants.service]` in your KeplerScript application's `manifest.toml`:

```json
	[[wants.service]]
	id = "com.amazon.network.service"
```

4. Add API privileges to `[wants.privilege]` in your KeplerScript application's `manifest.toml`:

Each API requires different privileges. Add the required privileges to `[wants.privilege]`.
Invoke the `requestPrivilege()` for run-time privileges. This prompts the operating system to launch its Privilege Request Handler that handles user consent. 
Some APIs requires your applications to be signed.

```json
    [[wants.privilege]]
    id="com.amazon.wifi.privilege.wifi-scan"
    [[wants.privilege]]
    id="com.amazon.network.privilege.net-info"
```

## API
### NetworkManager
`NetworkManager` provides primary APIs for managing network interfaces in the system.
Specifically, it provides APIs for:
 - Enabling or disabling network interfaces
 - Monitoring network status, captive portal status, and IP configurations
 - Notifying applications of network connection changes"

In `NetworkManager`, most of APIs require a network interface id. The network inteface id is defined in `NetworkInterface`. `NetworkInterface` can be obtained from calling `getNetworkInterfaces()` or `getActiveNetworkInterface()`. `getNetworkInterfaces()` returns the list of `NetworkInterface` on the given network interface type and `getActiveNetworkInterface()` returns `NetworkInterface` for the current active network interface.

Use of some APIs in `NetworkManager` requires declaring network information or network administrator permission in your manifest file. Calling the API without proper permission results in getting `Status.PERMISSION_DENIED` as the return of the API.

| API | Description | Permission |
| -----------| ----------- | ----------- |
|`getNetworkInterfaces()`|return the array of `NetworkInterface` provided in the system| -|
|`getActiveNetworkInterface()`|return the default active `NetworkInterface`| -|
|`enableNetworkInterface()`|enable or disable  `NetworkInterface`|com.amazon.network.privilege.net-admin|
|`isNetworkInterfaceEnabled()`|return whether `NetworkInterface` is enabled|-|
|`getIpConfig()`|return IP configuration on the `NetworkInterface`|-|
|`setIpConfig()`|set IP configuration| com.amazon.network.privilege.net-admin|
|`getNetworkState()`|return the current network state|-|
|`getMacAddress()`|return the MAC address of the `NetworkInterface`|com.amazon.network.privilege.restricted-net-info*|
|`evaluateCaptivePortal()`|evaluate captive portal|com.amazon.network.privilege.net-admin|
|`getCaptivePortalState()`|return the captive portal state |-|
|`getNetworkCapabilities()`|return the network capabilities |-|
|`getLinkSpeed()`|return the link speed |-|
|`setNetworkProxy()`|set network proxy|com.amazon.network.privilege.net-admin|
|`getNetworkProxy()`|return network proxy|-|
|`registerNetworkEventCallback()`|register callback to receive network events|-|
|`unregisterNetworkEventCallback()`|unregister callback to receive network events|-|

*. com.amazon.network.privilege.restricted-net-info is only allowed to signed applications.

### WifiInterface
`WifiInterface` is a class that offers APIs for managing Wi-Fi connectivity.
Using APIs in `WifiInterface`, you scan Wi-Fi access points, connect the Wi-Fi access point, disconnect the currently connected access point.

Use of some APIs in `WifiInterface` requires declaring network information, network administrator, or Wi-Fi scan permission in your manifest file. Calling the API without proper permission  results in getting `Status.PERMISSION_DENIED` as the return of the API.

| API | Description | Permission |
| -----------| ----------- | ----------- |
|`startScan()`|start a scan to discovery Wi-Fi access points|com.amazon.wifi.privilege.wifi-scan|
|`getScanResults()`|return discovered Wi-Fi access points from the result of the latest scan|com.amazon.wifi.privilege.wifi-scan|
|`getProfiles()`|return the array of Wi-Fi profiles|com.amazon.network.privilege.net-info|
|`addProfile()`|add a new Wi-Fi profile|com.amazon.network.privilege.net-admin|
|`removeProfile()`|remove a Wi-Fi profile| com.amazon.network.privilege.net-admin|
|`saveProfiles()`|save the current Wi-Fi profiles in the system| com.amazon.network.privilege.net-admin|
|`enableAllProfiles()`|return the current network state|com.amazon.network.privilege.net-admin|
|`connect()`|connect to the access point stored in Wi-Fi profiles|com.amazon.network.privilege.net-admin|
|`disconnect()`|disconnect the connected access point|com.amazon.network.privilege.net-admin|
|`getConnectionInfo()`|return the connection information|com.amazon.network.privilege.net-info|
|`calculateSignalLevel()`|return the level of the signal strength |-|
|`getLinkSpeed()`|return the link speed |-|
|`getStandard()`|return the supported Wi-Fi standard|-|
|`getStatisticsInfo()`|return the statistics information from the current connection|-|
|`registerEventCallback()`|register callback to receive Wi-Fi events|-|
|`unregisterEventCallback()`|unregister callback to receive Wi-Fi events|-|

## Usage
### Query Network Status
The following code snippet shows how to query network status.

```javascript
import {NetworkManager, NetworkState, IpType} from "@amazon-devices/keplerscript-netmgr-lib";
const networkManager = new NetworkManager();
// Get Wi-Fi network interface information including network interface id
networkManager.getNetworkInterfaces(NetworkInterfaceType.WIFI, nis);
// Get network state with the network id from getNetworkInterfaces() or getActiveNetworkInterface()
const [status, state] = networkManager.getNetworkState(networkInterfaceId, IpType.IPV4);

```

### Monitor Network Events
In order to receive network events from network interfaces, you must implement `NetworkEventCallback` and register the `NetworkEventCallback` using `registerNetworkEventCallback`.
For example, this code snippet shows how to implement and register `NetworkEventCallback`.

```javascript
const callback: NetworkEventCallback = {
      onNetworkStateChanged: (networkInterfaceId, type, oldState, newState) => {
      },
      onCaptivePortalEvaluated: (networkInterfaceId, result) => {
      },
    };
networkManager.registerNetworkEventCallback(callback);
```

### Wi-Fi Scan
In order to scan Wi-Fi access points, you can call `startScan()` and wait `onScanDone()` for the completion.

```javascript
const wifiEventCallback: WifiEventCallback = {
    onScanDone: () => {
    }
...
}
wifiInterface.registerEventCallback(wifiEventCallback);
wifiInterface.startScan();
```
Once your `onScanDone()` is called back, you can get the result by calling `getScanResults()`.
```javascript
let results: ScanResultItem[] = [];
res = wifiInterface.getScanResults(results);
```

### Connect an Wi-Fi access point

A `Profile` represents an Wi-Fi access point to connect. For different security modes, different parameter sets in the Wi-Fi Profile are required. `ssid` and `authMode` are required for every Wi-Fi Profiles. WPA1/WPA2 and WPA3 networks require `psk` and `saePassword` respectively.

```javascript
// If you need Open access point
const profile:Profile = {
    ssid: "My AP's SSID",
    authMode: AuthMode.OPEN
};
// If you need WPA2 access point
const profile:Profile = {
    ssid: "My AP's SSID",
    psk: "MY AP's Pre-Shared Key",
    authMode: AuthMode.WPA2
};
// If you need WPA3 access point
 const profile:Profile = {
    ssid: "My AP's SSID",
    saePassword: "MY AP's SAE password",
    authMode: AuthMode.WPA3
};
// Add the profile and connect
wifiInterface.addProfile(profile);
wifiInterface.connect( "My AP's SSID", AuthMode.WPA2);
```
