# NM Implementation Explained
## Tested environment
- OS: Ubuntu 20.04 LTS
- Language: C++14
## Implement Status
Basic functionalities completed. Partial Network (PN) isn't implemented.
## Project
Github: https://github.com/seanpai96/APNM
2 important branches:
- main
This branch contains our implementation of NM. main files can also serve as a simple demo running in terminal.
This document will focus on this branch, providing some explanation of our structure and codes.
- GPIO
This branch is for demo purpose only.
Note that the changes made in this branch may not comply to related AUTOSAR specifications.
Those changes include exposing internal states, websocket connection with presenting websites and GPIO controls.
In order to run the code in this branch, you'll need to install `libwebsockets` on machines. [Guide](https://machinezone.github.io/IXWebSocket/build/)
Also, you can connect 4 leds to GPIO 16 and 17 on machine 1, GPIO 16 on machine 2 and 3. They will blink when the nodes receive NM message from others.
## Project structure & explanation
In this section, we'll explain the purpose of each part of the project and some important part of the codes.
### Manifest configuration - shiroe
Here are our configuration of NM module.
**Note:** We doesn't implement partial network in our project, so pnc field could be ignored.
### ARA adaptation -- secminhr
This layer connects NM state machine with the rest of the AUTOSAR stack, complying to the AUTOSAR specification.
Note that though we have **checked** our interface with the related AUTOSAR specification, we cannot fully **verify** if we really followed the specification, because we don't have the actual AUTOSAR system or even any related tools.
Files locate in `src/ara`, except `src/ara/nm/nm.hpp`,`src/ara/nm/nm.hpp` and `src/ara/nm/CallbackTimer.cpp`
---
#### Folder structure
There're 3 folders under `src/ara`, they're `com`, `core` and `nm`.
- `src/ara/core`
A minimal implementation of AUTOSAR AP Core that's required by nm specification. Most of them are just an empty implementation.
The declarations/implementations should comply with **Specification of Adaptive Platform Core** (AUTOSAR_SWS_AdaptivePlatformCore)
Here is the R22-11 version: https://www.autosar.org/fileadmin/standards/R22-11/AP/AUTOSAR_SWS_AdaptivePlatformCore.pdf <br>
Functionalities/Declarations are not presented if it's not necessary to nm module.
- `src/ara/com`
Again for files in `src/ara/com`, unnecessary functionalities/declarations are not presented.
- `fakecom.hpp`
This is a minimal implementataion of AUTOSAR Communication Management. Just like `src/ara/core`, most of them are empty implementation.
The implementation here should comply with **Specification of Communication Management** (AUTOSAR_SWS_CommunicationManagement)
Here is the R22-11 version: https://www.autosar.org/fileadmin/standards/R22-11/AP/AUTOSAR_SWS_CommunicationManagement.pdf
- `com_set_handler.hpp/.cpp`
This is the only special part of COM implementation. A variable `handlers` sits in this file, it's a mapping from NetworkRequsetedState to a vector of functions (or SetHandlers).
`handlers` represents the SetHandlers of some `NetworkRequestedState`s, where `NetworkRequestedState` is a field of NM handle.
If you're unfamiliar with COM terms like *SetHandler*, *field*, visit the [COM section](https://hackmd.io/Pf56ai2cTUmC8U9PIPLjDA#Communication-Management-COM) of our reports.<br>
The `handlers` variable isn't part of COM specification. The handling/manipulating of SetHandlers should be provided by a COM module.
Since we don't have such a module, we decided to store SetHandlers inside the `handlers` global variable when a SetHandler is registered, and access the handlers directly in `main` when we run a demo.
Here `handlers[NetworkRequestedState]` indicates the SetHandlers regisetered on that specific `NetworkRequestedState` field.
- `src/ara/nm`
This is where we connect NM state machine with AUTOSAR AP. We wrap NM state machine implementation to make it works with AUTOSAR AP.
---
#### `src/ara/nm`
- `IStateMachine.hpp`
This is the interface representing a state machine.
You may notice that `NMInstance` in `nm.hpp/.cpp` inherits from `IStateMachine`.
`StartInstance` and `StopInstance` will be explained in [NM state machine section](https://hackmd.io/0THy-C2rTYmt9WL40uhJyg?both#NM-state-machine-–-SeanPai)
`setRequested` is used to notify that the handle controlling the state machine is requested. The state machine should change state if necessary. <br>
This class isn't important or even necessary from a functional aspect. However, it separates the development of NM service from the state machine, so 2 parts can progress simultaneously.
- `NetworkState_HandleSkeleton.hpp/.cpp` & `NetworkStateType`
This is the interface of NM module service. This interface of the service is required by COM module.
To see the interface of NM required by COM (and explanation), visit [Service perspective of ara::nm](https://hackmd.io/@NCKU-autosar/Byg4-Qbmi)
- `NetworkState_HandleImpl.hpp/.cpp`
This is the implementation of the skeleton. This Skeleton/Impl style is derived from **Explanation of ara::com API** (AUTOSAR_EXP_ARAComAPI).
To have an example of Skeleton/Impl style of implementation, have a look at the examples in **Explanation of ara::com API** (AUTOSAR_EXP_ARAComAPI)
Here's the R22-11 version: https://www.autosar.org/fileadmin/standards/R22-11/AP/AUTOSAR_EXP_ARAComAPI.pdf
- `struct Machine`
A structure storing some information of a state machine.
`machineStateChangeCallback` will be fed into the state machine's constructor. State machine use it to notify the internal state changes.
- `updateNetworkCurrentState`
Update the field `NetworkCurrentState` of the `NetworkState_Handle` if necessary. When `machineStateChangeCallback` is called by state machine, it'll call `updateNetworkCurrentState` to check if `NetworkCurrentState` has to change.
- `initialize()`
The initializer for a `NetworkState_Handle`, called in every constructor.
It'll wrap and register `networkRequestedStateSetHandler` as the SetHandler of `NetworkRequestedState` field, create a `Machine` for each node (or `EthernetCommunicationConnector`) and start the state machine with `StartInstance()`
- `networkRequestedStateSetHandler`
Called when `NetworkRequestedState` is changed by the user of NM module.
It'll call `setRequested` on the state machines controlled by this `NetworkState_Handle` to notify the state machines.
- `NmConfigReader.hpp/.cpp`
A helper class for `NetworkState_HandleImpl`. It reads the manifest configuration and create 2 mappings:
- from `EthernetCommunicationConnector` to `UdpNmNode`, and
- from `UdpNmNode` to `UdpNmCluster`
This is used in `NetworkState_HandleImpl` to find the corresponding `UdpNmNode` and `UdpNmCluster` from `EthernetCommunicationConnector`.
If you don't know about manifest configuration, visit [An interpretation of Nm configurations](https://hackmd.io/@NCKU-autosar/SyeD8Znhjs)
### NM state machine -- SeanPai
The State Machine locates in `nm.cpp` and `nm.hpp`. The `CallbackTimer.cpp` is also used here.
#### Initialization
When initiallize, it will also initiallize Socket connection.
#### `StartInstance()`
When called, it will reset and start the state Machine.
#### `StopInstance()`
When called, it will stop the state machine and close the socket.
#### `Reset()`
When called, it will reset all the variables.
#### State Machine
The state machine diagram is shown as below:

To be noted that the graph is wrong:
```
[Bus Sleep Mode] <==== [Prepare Bus Sleep Mode].
the arrow is drawn the wrong way.
```
When the machine starts, it will spawn a thread and run `Tick()` periodically. Because the state machine's unit is second, so the thread calls `Tick()` per second.
Last paragraph is implemented by `CallbackTimer.cpp`, it can create a subthread and run specific function periodically using `start(int interval, function())`, while `int interval` is in microsecond. It can be stopped by calling `stop()`.
Every state runs accordingly to the spec, [Here](https://hackmd.io/@NCKU-autosar/ByRW93zfj#Operational-Modes) is a simple version of it.
Each second it will print current state.
### Socket - Smile
#### `setServerAndBind(string multicastAddr)`
Setting server address to multicast address and bind to that address.
#### `setServerLoopBack()`
Open server loob back.
#### `serverSendBuffer(char node)`
Send message to multicast address with node data.
#### `setClientAndBind(string multicastAddr)`
Setting client address to multicast address and bind to that address.
#### `setClientAddGroup(char node)`
Add client to multicast address group.
#### `receiveBroadcast(char node)`
Receive message and check the message's target is this node.
#### `clientLeaveGroup()`
Make client leave group.
#### `closeClientSocket()`
Close client socket.
#### `closeServerSocket()`
Close server socket.
#### `setPort(int port)`
Set port.
## Contact
- 張邑 (secminhr): email: secminhrian@gmail.com
- 白翔云 (SeanPai): email: seanpai96@gmail.com
- 陳宥橋 (Smile) : email: chenforwork1368@gmail.com
- 李承哲 (shiroe) : email:
gq4575@gmail.com