July 1, 2019 Trigonometry and encryption in the Bridge
Firmware 1.30 offers trigonometric functions and constants, and allows distribution of protected programs and "locked" devices.
Let's start from the simple things. New math functions and constants (see the picture above) allows creation of programs to manage autopilots and calculation of wind, drift, VMG, distance between waypoints, etc. The trigonometric functions accept arguments in radians.
Below is an example of a program (download the code) that calculates TWA, TWS and TWD (theoretical wind angle, speed and direction) using AWA/AWS (apparent wind angle and speed) and COG/SOG data. It receives and sends data from/to a CAN1 interface, so the CAN2 interface can be left unconnected.
The program looks big, but it actually takes up about 4% of the available memory. You can create programs 25 times bigger!
# Calculate TWS, TWD and TWA (teoretical wind) by COG/SOG and AWS/AWA
# (c) 2019, Yacht Devices Ltd. Version 1.1, 29/06/2019
# Byte code size is 660 bytes (4% of user program space)
FW_CAN1_TO_CAN2=OFF
FW_CAN2_TO_CAN1=OFF
init()
{
# T = 0 # No COG/SOG data, but all variables are 0 at start
M = 0 - 1.0 # Float -1.0
}
# COG & SOG, Rapid Update
match(CAN1,0x1F80200,0x1FFFF00)
{
R = get(DATA+1,UINT8) & 0x3 # True Reference = 0
A = get(DATA+2,UINT16) # Course Over Ground, 0.0001 rad/bit
B = get(DATA+4,UINT16) # Speed Over Ground, 0.01 m/s
if (R == 0) {
if (A < 0xFFFD) {
if (B < 0xFFFD) {
T = timer() # Timestamp of COG/SOG data
C = cast(A,FLOAT) / 10000 # COG, to radians
S = cast(B,FLOAT) / 100 # SOG, m/s
}
}
}
}
# Wind Data
match(CAN1,0x1FD0200,0x1FFFF00)
{
R = get(DATA+5,UINT8) & 0x7 # Apparent Wind = 2
W = get(DATA+1,UINT16) # Wind speed, 0.01 m/s
A = get(DATA+3,UINT16) # Wind direction, 0.0001 rad/bit
# Have valid apparent wind data?
if (R == 2) {
if (A < 0xFFFD) {
if (W < 0xFFFD) {
# Have actual COG/SOG data (2000 ms)
if (T > 0) {
if (timediff(T) < 2000) {
# TWD calculation when no speed or TWS is about zero
A = cast(A,FLOAT) / 10000 # Wind angle
Y = C + A # TWD=COG+AWA
if (S == 0) {
X = W # TWS is equal to AWS when no speed
}
else {
W = cast(W,FLOAT) / 100 # Wind speed, float
# Calculate TWS
U = sqrt(W*W + S*S - 2*W*S*cos(A))
X = cast(U*100,UINT16) # 0.01 m/s per bit
# Calculate TWD
if (X != 0) {
F = (S*S + U*U - W*W) / (2 * U * S)
# Possible possible rounding issue
if (F < M) {
F = M
}
F = M_PI - acos( F ) # M_PI is 3.14... constant
if (A > M_PI) {
Y = C - F
}
else {
Y = C + F
}
}
}
# Check is TWD in 360 degrees
if (Y > M_2PI) {
Y = Y - M_2PI # M_2PI is 2*PI constant, M_PI2 is PI/2
}
if (Y < 0) {
Y = Y + M_2PI
}
# Calculate TWA and check the range of value
Z = Y - C
if (Z < 0) {
Z = Z + M_2PI
}
# Transform to NMEA 2000 resolution, 0.0001 rad/bit
Y = cast(Y*10000,UINT16)
Z = cast(Z*10000,UINT16)
# Theoretical Wind (ground referenced, referenced to True North;
# calculated using COG/SOG) - TWD/TWS
set(DATA+5, UINT8, 0xF8) # Data type
set(DATA+1, UINT16, X) # TWS
set(DATA+3, UINT16, Y) # TWD
# Send message to the same interface, using the address
# of the wind sensor
send(CAN1)
# Theoretical (Calculated to Centerline of the vessel, refernced
# to ground; calculated using COG/SOG) - TWA/TWS
set(DATA+5, UINT8, 0xFB) # Data type
set(DATA+3, UINT16, Z) # TWA
send(CAN1)
}
}
}
}
}
}
# End of program
To test the program, you can use the CAN Log Viewer and our NMEA 2000 Wi-Fi Router YDNR-02. We'll send COG/SOG and AWA/AWS data from the CAN Log Viewer and check the results in Web Gauges.
In the routing rules of YDNR-02, turn on the routing from the server with CAN Log Viewer to Server #1, which is used for Web Gauges. This will allow you to see source data (sent from CAN Log Viewer) along with output data (sent by the Bridge).On the "NMEA Settings" page of YDNR, you also need to set wind calculations to "Any" (factory setting) or "COG/SOG". The YDNR will not actually calculate the theoretical wind if it is available on the NMEA 2000 network; it will use the data from the network. However, if you will set calculations to "Disabled", it will use theoretical wind data calculated using the STW/Heading to convert theoretical wind from NMEA 2000 to NMEA 0183.
Figure 1. Sending messages form CAN Log Viewer
Copy and paste messages from the table below to the CAN Log Viewer (see Figure 1) and send to the network.
Table 1. Test data for the program
Test | Source messages | Source data | Bridge's output |
1 | 09F802A3 FF FC 39 14 E8 03 FF FF |
COG 30°, SOG 10 m/s AWS 10 m/s, AWA 30° |
TWS 5.1 m/s TWA 104.8° TWD 134.5° |
2 | 09F802A3 FF FC 39 14 E8 03 FF FF |
COG 30°, SOG 10 m/s AWS 10 m/s, AWA 330° |
TWS 5.2 m/s TWA 255° TWD 284.7° |
3 | 09F802A3 FF FC 39 14 E8 03 FF FF |
COG 30°, SOG 10 m/s AWS 0 m/s, AWA 330° |
TWS 10 m/s TWA 180° TWD 209.7° |
4 | 09F802A3 FF FC 00 00 E8 03 FF FF |
COG 0°, SOG 10 m/s AWS 10 m/s, AWA 330° |
TWS 5.2 m/s TWA 255° TWD 255° |
5 | 09F802A3 FF FC E0 FA E8 03 FF FF |
COG 330°, SOG 10 m/s AWS 10 m/s, AWA 330° |
TWS 5.2 m/s TWA 255° TWD 330° |
6 | 09F802A3 FF FC 00 00 E8 03 FF FF |
COG 0°, SOG 10 m/s AWS 10 m/s, AWA 45° |
TWS 7.7 m/s TWA 112.5° TWD 112.5° |
The best way check the results is to configure Web Gauges in the way shown in Figure 2, you will see input and output data on the same page.
Figure 2. Web Gauges with wind data (Test 1)
And, of course, you can use the log() function for deep debug of the program.
This year we have served several customers who have created very complicated programs for the Bridge, use proprietary protocols and have non-disclosure obligations. To meet their requirements, we added encryption to the Bridge.
Please, read the following carefully, or you can lock your Bridge forever!
Table 2. The PASSWORD_LEVEL key
Bit # | ||
1 | Password protection is enabled | Password protection is disabled, all other bits are ignored (will be reset to 0) |
2 | Device's serial is used for encryption | Serial number is not used for encryption |
3 | The program cannot be downloaded from the Bridge | Encrypted program can be downloaded from the Bridge |
4 | The Bridge can be reset using the password only | The Bridge can be reset by user, the program will be erased |
The protection is managed by the PASSWORD (from 1 to 64 symbols) and PASSWORD_LEVEL (values from 0 to 15) settings. If the PASSWORD is empty in the user program, the PASSWORD_LEVEL will be reset to 0 and these settings will not be saved in the YDNBSAVE.CFG file.
To enable password protection, add the following lines to your program:
PASSWORD=abc123
PASSWORD_LEVEL=1
The YDNBSAVE.CFG with the encrypted program will be saved (see the example). After that, the Bridge will only accept programs encrypted with the password "abc123". To reset the Bridge, load the configuration file with a special comment:
# YD:RESET
Then, turn on the "maximum protection":
PASSWORD=abc123
PASSWORD_LEVEL=15
The YDNBSAVE.CFG will contain a message that the program is locked and cannot be downloaded. Because you set bit 4 (15 is 8+4+2+1, all bits are set), you can reset the Bridge with the original password only. You will need to load the configuration file:
# YD:RESET abc123
We do not publicize the encryption algorithm, but you can be certain that a software attack will be more expensive than hardware attack. If the Bridge is protected, there is no way to restore the password or save unencrypted program.
How you can use this feature:
- you can re-sell Bridges with the user program protected from unauthorized access or modification, and you can distribute encrypted updates to your users;
- if the bit 4 is set, the Bridge cannot be reset by the user and can be used only with your own programs;
- if the bit 2 is set, you will need to generate individual updates for your users, but you will have the opportunity to sell individual updates and prevent unauthorized distribution of updates;
- bit 3 increases protection, the user can check with the LED signals whether the received update has successfully uploaded to the Bridge or not.
To generate programs for end-users, we added one more key, PASSWORD_SERIAL, it must contain the serial number (eight digits) of the target device. This key is not stored in the YDNBSAVE.CFG file and used for its generation only. If bit 2 is not set in the PASSWORD_LEVEL, you can use any valid number (for example, 00000000), because the serial number will not be used in the encryption. If the key is set, PASSWORD and PASSWORD_LEVEL will be reset after YDNBSAVE.CFG file generation, and you will not need to reset your Bridge after generation of each encrypted program.
When bit 2 is set, and PASSWORD_SERIAL key is not present, the Bridge will use the serial number of your own Bridge to encrypt the YDNBSAVE.CFG file.
Knowledge of the password allows to reset the Bridge, but does not allow decryption of the program. Therefore, you can ask the end-user to send you the serial number and any password he or she likes. Then, you need to send back the usual YDNB.CFG with PASSWORD and PASSWORD_LEVEL settings (1 or higher), to switch the Bridge to protected mode. Another YDNB.CFG with the protected program is generated with PASSWORD_LEVEL set to 3 or higher value. You can be sure that the program you send will be used with the customer's Bridge only.
The PASSWORD_LEVEL setting allows setting of protection bits (increases the protection), but not to reset bits. The only way to reset bits (decrease the protection) is to reset the Bridge along with erasing the user program.
The update for 1.30 is available in the Downloads section. To learn more about the NMEA 2000 Bridge, visit the product's home page. The User Manual will be updated soon.
Next articles:
- Pressure sensor, updates for Engine Gateways / May 24, 2019
- All the best in one product / April 17, 2019
- Meet the NMEA 0183 Multiplexer / April 16, 2019
Previous articles:
- July bug fixes, AIS in Navionics / July 8, 2019
- New device: Alarm Button YDAB-01 / July 12, 2019
- Anchor alarm with Bridge and Button / July 17, 2019
See also: recent news, all news...