├── .gitignore
├── openNTRIP.iml
├── src
├── test
│ ├── resources
│ │ ├── 2233
│ │ ├── RTCM_30
│ │ ├── RTCM_31
│ │ ├── RTCM_32
│ │ ├── RTCM_33
│ │ ├── 1004.rtcm3
│ │ ├── 1019.rtcm3
│ │ ├── 1021.rtcm3
│ │ ├── 1023.rtcm3
│ │ ├── 1025.rtcm3
│ │ ├── RTCM3EPH(3.3)
│ │ ├── geoids
│ │ │ ├── spb.GGF
│ │ │ ├── bering.GGF
│ │ │ ├── england.GGF
│ │ │ ├── florida.GGF
│ │ │ └── australia.GGF
│ │ └── testRtcm.rtcm3
│ └── java
│ │ ├── org
│ │ └── dav95s
│ │ │ └── openNTRIP
│ │ │ ├── crs
│ │ │ └── gridShift
│ │ │ │ └── GridShiftTest.java
│ │ │ ├── utils
│ │ │ ├── BasicAuthParserTest.java
│ │ │ ├── binaryParse
│ │ │ │ └── BitUtilsTest.java
│ │ │ └── Geoids
│ │ │ │ └── GGFTest.java
│ │ │ ├── protocols
│ │ │ └── rtcm
│ │ │ │ ├── MSG1026Test.java
│ │ │ │ ├── MSG1027Test.java
│ │ │ │ ├── MSG1023Test.java
│ │ │ │ ├── MSG1006Test.java
│ │ │ │ ├── MSG1025Test.java
│ │ │ │ └── MSG1021Test.java
│ │ │ └── users
│ │ │ └── passwords
│ │ │ └── BCryptTest.java
│ │ └── SandBox.java
└── main
│ ├── java
│ └── org
│ │ └── dav95s
│ │ └── openNTRIP
│ │ ├── protocols
│ │ ├── ntrip
│ │ │ ├── NetworkType.java
│ │ │ ├── NtripResponse.java
│ │ │ └── SourceLoginMessage.java
│ │ ├── rtcm
│ │ │ ├── assets
│ │ │ │ ├── CRS2.java
│ │ │ │ ├── CRS3.java
│ │ │ │ ├── CRS1.java
│ │ │ │ ├── ProjectionType.java
│ │ │ │ ├── TransformationType.java
│ │ │ │ └── Plates.java
│ │ │ ├── messages
│ │ │ │ ├── MSG1014.java
│ │ │ │ ├── MSG1007.java
│ │ │ │ ├── MSG1008.java
│ │ │ │ ├── MSG1013.java
│ │ │ │ ├── MSG1017.java
│ │ │ │ ├── MSG1001.java
│ │ │ │ ├── MSG1025.java
│ │ │ │ ├── MSG1002.java
│ │ │ │ ├── MSG1022.java
│ │ │ │ ├── MSG1026.java
│ │ │ │ ├── MSG1003.java
│ │ │ │ ├── MSG1020.java
│ │ │ │ └── MSG1027.java
│ │ │ └── Rtcm3Separator.java
│ │ └── nmea
│ │ │ └── NMEA.java
│ │ ├── crs
│ │ ├── geoids
│ │ │ ├── IGeoid.java
│ │ │ └── GGF.java
│ │ └── gridShift
│ │ │ ├── GridNode.java
│ │ │ ├── GeodeticPoint.java
│ │ │ └── ResidualsGrid.java
│ │ ├── database
│ │ ├── models
│ │ │ ├── assets
│ │ │ │ └── Authenticator.java
│ │ │ ├── ServerModel.java
│ │ │ ├── GridModel.java
│ │ │ ├── UserGroupModel.java
│ │ │ ├── SourceTableModel.java
│ │ │ ├── CrsModel.java
│ │ │ ├── UserModel.java
│ │ │ └── MountPointModel.java
│ │ ├── modelsV2
│ │ │ ├── UserModel.java
│ │ │ ├── ReferenceStationModel.java
│ │ │ ├── NetworkModel.java
│ │ │ └── MountpointModel.java
│ │ ├── DataSource.java
│ │ └── repository
│ │ │ ├── UserRepository.java
│ │ │ ├── MountpointRepository.java
│ │ │ ├── NetworkRepository.java
│ │ │ └── ReferenceStationRepository.java
│ │ ├── users
│ │ ├── User.java
│ │ └── passwords
│ │ │ └── BCrypt.java
│ │ ├── exception
│ │ ├── MountpointNotFound.java
│ │ ├── ReferenceStationNotFoundException.java
│ │ ├── UserAuthorizationException.java
│ │ └── ReferenceStationAuthorizationException.java
│ │ ├── commons
│ │ ├── GlobalStats.java
│ │ ├── Message.java
│ │ └── Registry.java
│ │ ├── utils
│ │ ├── geometry
│ │ │ ├── Point.java
│ │ │ ├── AngleTools.java
│ │ │ └── Polygon.java
│ │ ├── binaryParse
│ │ │ ├── Normalize.java
│ │ │ ├── Crc24q.java
│ │ │ └── BitUtils.java
│ │ ├── Config.java
│ │ ├── ParseUtil.java
│ │ ├── BasicAuthParser.java
│ │ └── ServerProperties.java
│ │ ├── core
│ │ ├── stationsServer
│ │ │ ├── ReferenceStationChannelMatcher.java
│ │ │ ├── ReferenceStationServer.java
│ │ │ └── handlers
│ │ │ │ ├── Rtcm3InboundHandler.java
│ │ │ │ └── ReferenceStationAuthHandler.java
│ │ ├── ChannelState.java
│ │ ├── userServer
│ │ │ ├── handlers
│ │ │ │ ├── NmeaPositionHander.java
│ │ │ │ ├── authentication
│ │ │ │ │ ├── NtripNoneAuthHandler.java
│ │ │ │ │ └── NtripBasicAuthHandler.java
│ │ │ │ └── UserAuthHandler.java
│ │ │ └── NtripServer.java
│ │ └── BaseServer.java
│ │ ├── TransportTypeHolder.java
│ │ └── ServerLauncher.java
│ └── resources
│ ├── db.properties
│ ├── database.properties
│ ├── logback.xml
│ └── app.properties
├── .idea
├── vcs.xml
├── misc.xml
└── compiler.xml
├── README.md
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 | .idea
--------------------------------------------------------------------------------
/openNTRIP.iml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/test/resources/2233:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/2233
--------------------------------------------------------------------------------
/src/test/resources/RTCM_30:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/RTCM_30
--------------------------------------------------------------------------------
/src/test/resources/RTCM_31:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/RTCM_31
--------------------------------------------------------------------------------
/src/test/resources/RTCM_32:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/RTCM_32
--------------------------------------------------------------------------------
/src/test/resources/RTCM_33:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/RTCM_33
--------------------------------------------------------------------------------
/src/test/resources/1004.rtcm3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/1004.rtcm3
--------------------------------------------------------------------------------
/src/test/resources/1019.rtcm3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/1019.rtcm3
--------------------------------------------------------------------------------
/src/test/resources/1021.rtcm3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/1021.rtcm3
--------------------------------------------------------------------------------
/src/test/resources/1023.rtcm3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/1023.rtcm3
--------------------------------------------------------------------------------
/src/test/resources/1025.rtcm3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/1025.rtcm3
--------------------------------------------------------------------------------
/src/test/resources/RTCM3EPH(3.3):
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/RTCM3EPH(3.3)
--------------------------------------------------------------------------------
/src/test/resources/geoids/spb.GGF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/geoids/spb.GGF
--------------------------------------------------------------------------------
/src/test/resources/testRtcm.rtcm3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/testRtcm.rtcm3
--------------------------------------------------------------------------------
/src/test/resources/geoids/bering.GGF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/geoids/bering.GGF
--------------------------------------------------------------------------------
/src/test/resources/geoids/england.GGF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/geoids/england.GGF
--------------------------------------------------------------------------------
/src/test/resources/geoids/florida.GGF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/geoids/florida.GGF
--------------------------------------------------------------------------------
/src/test/resources/geoids/australia.GGF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DAV95s/openNTRIP/HEAD/src/test/resources/geoids/australia.GGF
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/ntrip/NetworkType.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.ntrip;
2 |
3 | public enum NetworkType {
4 | CAS, NET, STR
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/crs/geoids/IGeoid.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.crs.geoids;
2 |
3 | public interface IGeoid {
4 | double getValueByPoint(double lat, double lon);
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/models/assets/Authenticator.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database.models.assets;
2 |
3 | public enum Authenticator {
4 | None, Basic, Digest;
5 | }
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/users/User.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.users;
2 |
3 | public class User {
4 | int id;
5 | String username;
6 | String password;
7 |
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/exception/MountpointNotFound.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.exception;
2 |
3 | public class MountpointNotFound extends Exception {
4 | public MountpointNotFound(String message) {
5 | super(message);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/commons/GlobalStats.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.commons;
2 |
3 | import org.dav95s.openNTRIP.utils.ServerProperties;
4 |
5 | public class GlobalStats {
6 | public GlobalStats(ServerProperties serverProperties) {
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/resources/db.properties:
--------------------------------------------------------------------------------
1 | jdbcUrl=jdbc:mysql://localhost:3306/ntrip?useSSL=false&serverTimezone=UTC
2 | dataSource.user=root
3 | dataSource.password=123
4 | dataSource.cachePrepStmts=true
5 | dataSource.prepStmtCacheSize=250
6 | dataSource.prepStmtCacheSqlLimit=2048
7 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/assets/CRS2.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm.assets;
2 |
3 | /**
4 | * Upcast residuals grid message
5 | */
6 | public interface CRS2 {
7 | int getMessageNumber();
8 | byte[] getBytes();
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/assets/CRS3.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm.assets;
2 |
3 | /**
4 | * Upcast projection message
5 | */
6 | public interface CRS3 {
7 | int getMessageNumber();
8 | byte[] getBytes();
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/exception/ReferenceStationNotFoundException.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.exception;
2 |
3 | public class ReferenceStationNotFoundException extends Exception{
4 | public ReferenceStationNotFoundException() {
5 | super();
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/exception/UserAuthorizationException.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.exception;
2 |
3 | public class UserAuthorizationException extends Exception {
4 | public UserAuthorizationException(String message) {
5 | super(message);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/assets/CRS1.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm.assets;
2 |
3 | /**
4 | * Upcast transformation parameters message
5 | */
6 | public interface CRS1 {
7 | int getMessageNumber();
8 | byte[] getBytes();
9 | }
10 |
--------------------------------------------------------------------------------
/src/test/java/org/dav95s/openNTRIP/crs/gridShift/GridShiftTest.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.crs.gridShift;
2 |
3 | import org.junit.Test;
4 |
5 | public class GridShiftTest {
6 | @Test
7 | public void GridShift(){
8 |
9 | System.out.println(123);
10 | }
11 | }
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/exception/ReferenceStationAuthorizationException.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.exception;
2 |
3 | public class ReferenceStationAuthorizationException extends Exception{
4 | public ReferenceStationAuthorizationException(String message) {
5 | super(message);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/utils/geometry/Point.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.utils.geometry;
2 |
3 | public final class Point {
4 | public final double x;
5 | public final double y;
6 |
7 | public Point(double x, double y) {
8 | this.x = x;
9 | this.y = y;
10 | }
11 | }
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/ntrip/NtripResponse.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.ntrip;
2 |
3 | public class NtripResponse {
4 | public static final byte[] OK_MESSAGE = "ICY 200 OK\r\n".getBytes();
5 | public static final byte[] BAD_PASSWORD = "ERROR - Bad Password\r\n".getBytes();
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/crs/gridShift/GridNode.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.crs.gridShift;
2 |
3 | public class GridNode {
4 | public long id;
5 | public double north;
6 | public double east;
7 | public double height;
8 |
9 | public double dNorth;
10 | public double dEast;
11 | public double dH;
12 |
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/ntrip/SourceLoginMessage.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.ntrip;
2 |
3 | public class SourceLoginMessage {
4 | public final String login;
5 | public final String password;
6 |
7 | public SourceLoginMessage(String login, String password) {
8 | this.login = login;
9 | this.password = password;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/resources/database.properties:
--------------------------------------------------------------------------------
1 | development.driver=com.mysql.cj.jdbc.Driver
2 | development.username=root
3 | development.password=123
4 | development.url=jdbc:mysql://localhost:3306/ntrip?useSSL=false&serverTimezone=UTC
5 |
6 | test.driver=com.mysql.cj.jdbc.Driver
7 | test.username=user2
8 | test.password=pwd
9 | test.url=jdbc:mysql://localhost/acme_test
10 |
11 | production.jndi=java:comp/env/jdbc/acme
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/utils/binaryParse/Normalize.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.utils.binaryParse;
2 |
3 | public class Normalize {
4 | private static final int[] pow10 = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
5 |
6 | public static double normalize(double nmb, int scale) {
7 | return (double) Math.round(nmb * pow10[scale]) / pow10[scale];
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/assets/ProjectionType.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm.assets;
2 |
3 | public enum ProjectionType {
4 | NONE(0), TM(1), TMS(2), LCC1SP(3), LCC2SP(4),
5 | LCCW(5), CS(6), OM(7), OS(8), MC(9), PS(10), DS(11);
6 |
7 | public int getNmb() {
8 | return nmb;
9 | }
10 |
11 | int nmb;
12 |
13 | ProjectionType(int i) {
14 | nmb = i;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/utils/Config.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.utils;
2 |
3 | import java.nio.charset.Charset;
4 | import java.nio.charset.StandardCharsets;
5 |
6 | public class Config {
7 | public static final Charset DEFAULT_CHARSET = StandardCharsets.ISO_8859_1;
8 |
9 | public static final String SERVER_PROPERTIES_FILENAME = "app.properties";
10 | public static final String MAIL_PROPERTIES_FILENAME = "mail.properties";
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/commons/Message.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.commons;
2 |
3 | public class Message {
4 | public final String name;
5 | public final byte[] bytes;
6 |
7 |
8 | public Message(String name, byte[] bytes) {
9 | this.name = name;
10 | this.bytes = bytes;
11 | }
12 |
13 | public Message(short name, byte[] bytes) {
14 | this.name = String.valueOf(name);
15 | this.bytes = bytes;
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/assets/TransformationType.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm.assets;
2 |
3 | public enum TransformationType {
4 | HelmertLinearExpression(0),
5 | HelmertStrict(1),
6 | MolodenskiAbridged(2),
7 | MolodenskiBadekas(3);
8 |
9 | private int index;
10 |
11 | TransformationType(int i) {
12 | this.index = i;
13 | }
14 |
15 | public int getIndex() {
16 | return index;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/assets/Plates.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm.assets;
2 |
3 | public enum Plates {
4 | NONE(0), AFRC(1), ANTA(2), ARAB(3), AUST(4), CARB(5), COCO(6), EURA(7), INDI(8),
5 | NOAM(9), NAZC(10), PCFC(11), SOAM(12), JUFU(13), PHIL(14), RIVR(15), SCOT(16);
6 |
7 | int plateNmb;
8 |
9 | public int getPlateNmb() {
10 | return plateNmb;
11 | }
12 |
13 | Plates(int i) {
14 | plateNmb = i;
15 | }
16 | }
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/modelsV2/UserModel.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database.modelsV2;
2 |
3 | public class UserModel {
4 | public final int id;
5 | public final String username;
6 | public final String password;
7 | public final String email;
8 |
9 | public UserModel(int id, String username, String password, String email) {
10 | this.id = id;
11 | this.username = username;
12 | this.password = password;
13 | this.email = email;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/crs/gridShift/GeodeticPoint.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.crs.gridShift;
2 |
3 | public class GeodeticPoint {
4 | public long id;
5 | public double north;
6 | public double east;
7 | public double dNorth;
8 | public double dEast;
9 |
10 | public double distance;
11 |
12 | public double distance(double pNorth, double pEast) {
13 | distance = Math.sqrt(Math.pow(north + pNorth, 2) + Math.pow(east + pEast, 2));
14 | return distance;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # openNTRIP
2 | openNTRIP is multi-caster server for streaming RTCM data to internet.
3 |
4 | ## Installation
5 | 1. Install mysql
6 | 2. Insert table "ntrip" in the database (openNTRIP/src/main/resources/ntrip.sql)
7 | 3. Edit config file (openNTRIP/src/main/resources/ntrip.sql/db.properties)
8 | 4. Try to run
9 |
10 | ## Usage
11 | For reference station
12 | SOURCE: AL1 or AL2
13 | PASSWORD: 44444
14 |
15 | For user (if mountpoint authentication set 1)
16 | Account: Administrator
17 | Password: password
18 |
19 | You can use RtkLib for retranslating gnns data to openNTRIP.
20 |
21 | ## Roadmap
22 | 1. Add support RTCM 1021-1027 message.
23 | 2. Add support FKP.
24 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/utils/ParseUtil.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.utils;
2 |
3 | public class ParseUtil {
4 | public static int parseInt(String intProperty) {
5 | try {
6 | return Integer.parseInt(intProperty);
7 | } catch (NumberFormatException nfe) {
8 | throw new RuntimeException(intProperty + " not a number. " + nfe.getMessage());
9 | }
10 | }
11 |
12 | public static long parseLong(String longProperty) {
13 | try {
14 | return Long.parseLong(longProperty);
15 | } catch (NumberFormatException nfe) {
16 | throw new RuntimeException(longProperty + " not a number. " + nfe.getMessage());
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/core/stationsServer/ReferenceStationChannelMatcher.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.core.stationsServer;
2 |
3 | import io.netty.channel.Channel;
4 | import io.netty.channel.group.ChannelMatcher;
5 | import io.netty.util.AttributeKey;
6 | import org.dav95s.openNTRIP.core.ChannelState;
7 |
8 | public class ReferenceStationChannelMatcher implements ChannelMatcher {
9 | final AttributeKey key = ChannelState.REFERENCE_STATION;
10 | final String name;
11 |
12 | public ReferenceStationChannelMatcher(String name) {
13 | this.name = name;
14 | }
15 |
16 | @Override
17 | public boolean matches(Channel channel) {
18 | return channel.attr(key).get().equals(name) || (channel.attr(key).get() == null);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/utils/geometry/AngleTools.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.utils.geometry;
2 |
3 | public class AngleTools {
4 | static public double dmsToDecimal(int degrees, int minutes, float seconds){
5 | if (minutes > 59 || seconds > 59.9999){
6 | throw new IllegalArgumentException("minutes or seconds more than 59");
7 | }
8 |
9 | return Math.signum(degrees) * (Math.abs(degrees) + (minutes / 60.0) + (seconds / 3600.0));
10 | }
11 | static public double dmsToDecimal(int degrees, int minutes){
12 | if (minutes > 59){
13 | throw new IllegalArgumentException("minutes or seconds more than 59");
14 | }
15 |
16 | return Math.signum(degrees) * (Math.abs(degrees) + (minutes / 60.0));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/DataSource.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database;
2 |
3 | import com.zaxxer.hikari.HikariConfig;
4 | import com.zaxxer.hikari.HikariDataSource;
5 |
6 | import java.sql.Connection;
7 | import java.sql.SQLException;
8 |
9 | public class DataSource {
10 |
11 | private static final HikariConfig configHikari = new HikariConfig();
12 | private static final HikariDataSource ds;
13 |
14 | static {
15 | String configFile = "src/main/resources/db.properties";
16 | HikariConfig cfg = new HikariConfig(configFile);
17 |
18 | ds = new HikariDataSource(cfg);
19 | }
20 |
21 | private DataSource() {}
22 |
23 | public static Connection getConnection() throws SQLException {
24 | return ds.getConnection();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/core/ChannelState.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.core;
2 |
3 | import io.netty.util.AttributeKey;
4 | import org.dav95s.openNTRIP.database.modelsV2.MountpointModel;
5 | import org.dav95s.openNTRIP.database.modelsV2.ReferenceStationModel;
6 |
7 | public class ChannelState {
8 | public static final AttributeKey MOUNTPOINT = AttributeKey.valueOf("MOUNT_POINT");
9 | public static final AttributeKey REFERENCE_STATION_MODEL = AttributeKey.valueOf("REFERENCE_STATION_MODEL");
10 | public static final AttributeKey REFERENCE_STATION = AttributeKey.valueOf("REFERENCE_STATION");
11 | public static final AttributeKey NETWORK = AttributeKey.valueOf("NETWORK");
12 | public static final AttributeKey AUTHENTICATION = AttributeKey.valueOf("AUTHENTICATION");
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/modelsV2/ReferenceStationModel.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database.modelsV2;
2 |
3 | public class ReferenceStationModel {
4 | public final int id;
5 | public final String name;
6 | public final String format;
7 | public final double lat;
8 | public final double lon;
9 | public final double alt;
10 | public final String password;
11 | public final int hz;
12 | public final String[] networks;
13 |
14 |
15 | public ReferenceStationModel(int id, String name, String format, double lat, double lon, double alt, String password, int hz, String[] networks) {
16 | this.id = id;
17 | this.name = name;
18 | this.format = format;
19 | this.lat = lat;
20 | this.lon = lon;
21 | this.alt = alt;
22 | this.password = password;
23 | this.hz = hz;
24 | this.networks = networks;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/core/userServer/handlers/NmeaPositionHander.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.core.userServer.handlers;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.SimpleChannelInboundHandler;
5 | import org.dav95s.openNTRIP.commons.Registry;
6 | import org.dav95s.openNTRIP.protocols.nmea.NMEA;
7 |
8 | public class NmeaPositionHander extends SimpleChannelInboundHandler {
9 | Registry registry;
10 |
11 | public NmeaPositionHander(Registry registry) {
12 | this.registry = registry;
13 | }
14 |
15 | @Override
16 | protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
17 | NMEA nmea = new NMEA();
18 | NMEA.GPSPosition gpsPosition = nmea.parse(msg);
19 | if (gpsPosition.isSet()) {
20 | System.out.println("No implement!");
21 |
22 | } else {
23 | System.out.println("No nmea coordinate!");
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/utils/BasicAuthParser.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.utils;
2 |
3 | import java.util.Base64;
4 |
5 | public class BasicAuthParser {
6 | public final String account;
7 | public final String password;
8 |
9 | public BasicAuthParser(String authorization) {
10 | String[] split = authorization.split(" ", 2);
11 | if (split.length != 2 || !split[0].equals("Basic")) {
12 | throw new IllegalArgumentException();
13 | }
14 |
15 | byte[] accPassBytes = Base64.getDecoder().decode(split[1]);
16 | String accPass = new String(accPassBytes);
17 | split = accPass.split(":");
18 |
19 | if (split.length == 1) {
20 | this.account = split[0];
21 | this.password = "";
22 | } else if (split.length == 2) {
23 | this.account = split[0];
24 | this.password = split[1];
25 | } else {
26 | throw new IllegalArgumentException();
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/test/java/org/dav95s/openNTRIP/utils/BasicAuthParserTest.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.utils;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | public class BasicAuthParserTest {
7 | @Test(expected = IllegalArgumentException.class)
8 | public void test1() {
9 | String tested = "Basic";
10 | BasicAuthParser basicAuthParser = new BasicAuthParser(tested);
11 | }
12 |
13 | @Test
14 | public void test2() {
15 | String tested = "Basic QUNDOlBBU1M=";
16 | BasicAuthParser basicAuthParser = new BasicAuthParser(tested);
17 |
18 | Assert.assertEquals("ACC", basicAuthParser.account);
19 | Assert.assertEquals("PASS", basicAuthParser.password);
20 |
21 | }
22 |
23 | @Test
24 | public void test3() {
25 | String tested = "Basic QUNDOg==";
26 | BasicAuthParser basicAuthParser = new BasicAuthParser(tested);
27 |
28 | Assert.assertEquals("ACC", basicAuthParser.account);
29 | Assert.assertEquals("", basicAuthParser.password);
30 |
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/src/test/java/org/dav95s/openNTRIP/utils/binaryParse/BitUtilsTest.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.utils.binaryParse;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | public class BitUtilsTest {
7 | @Test
8 | public void IntUnsignedTest() {
9 | BitUtils bitUtils = new BitUtils();
10 | bitUtils.setInt(2147483647, 31);
11 | bitUtils.setInt(16777215, 24);
12 | bitUtils.setPointer(0);
13 | Assert.assertEquals(2147483647, bitUtils.getUnsignedInt(31));
14 | Assert.assertEquals(16777215, bitUtils.getUnsignedInt(24));
15 | }
16 |
17 | @Test
18 | public void IntSignedTest() {
19 | BitUtils bitUtils = new BitUtils();
20 | bitUtils.setInt(0b10000000, 8);
21 | bitUtils.setInt(0b1111111110000000, 16);
22 | bitUtils.setInt(0b1101111110000000, 16);
23 | bitUtils.setPointer(0);
24 | Assert.assertEquals(-128, bitUtils.getSignedInt(8));
25 | Assert.assertEquals(-128, bitUtils.getSignedInt(16));
26 | Assert.assertEquals(-8320, bitUtils.getSignedInt(16));
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/utils/geometry/Polygon.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.utils.geometry;
2 |
3 | public class Polygon {
4 | private Point[] points; // Points making up the boundary
5 |
6 | public Polygon(Point[] points) {
7 | this.points = points;
8 | }
9 |
10 |
11 | /**
12 | * Return true if the given point is contained inside the boundary.
13 | * See: http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
14 | *
15 | * @param test The point to check
16 | * @return true if the point is inside the boundary, false otherwise
17 | */
18 | public boolean contains(Point test) {
19 | int i;
20 | int j;
21 | boolean result = false;
22 | for (i = 0, j = points.length - 1; i < points.length; j = i++) {
23 | if ((points[i].y > test.y) != (points[j].y > test.y) &&
24 | (test.x < (points[j].x - points[i].x) * (test.y - points[i].y) / (points[j].y - points[i].y) + points[i].x)) {
25 | result = !result;
26 | }
27 | }
28 | return result;
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/users/passwords/BCrypt.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.users.passwords;
2 |
3 | import static at.favre.lib.crypto.bcrypt.BCrypt.verifyer;
4 |
5 | public class BCrypt {
6 |
7 |
8 | public boolean compare(String DBPassword, String UserPassword) {
9 | if (DBPassword == null || UserPassword == null) {
10 | return false;
11 | }
12 | DBPassword = DBPassword.trim();
13 | UserPassword = UserPassword.trim();
14 | // if (DBPassword.isEmpty() && UserPassword.isEmpty()) {
15 | // return true;
16 | // }
17 |
18 | return verifyer().verify(UserPassword.getBytes(), DBPassword.getBytes()).verified;
19 | }
20 |
21 | public String hash(String rawPassword, int BCryptRounds) {
22 | if (rawPassword == null) {
23 | throw new NullPointerException("Input string is null");
24 | }
25 |
26 | byte[] rawResult = at.favre.lib.crypto.bcrypt.BCrypt.withDefaults().hash(BCryptRounds, rawPassword.getBytes());
27 | return new String(rawResult);
28 | }
29 |
30 |
31 | public String hash(String rawPassword) {
32 | return hash(rawPassword, 12);
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/messages/MSG1014.java:
--------------------------------------------------------------------------------
1 | //package org.dav95s.openNTRIP.Tools.RTCM;
2 | //
3 | //public class MSG1014 extends RTCM {
4 | // private int messageNumber;
5 | // private int NetworkID;
6 | // private int SubnetworkID;
7 | // private int NumberAuxiliaryStationsTransmitted;
8 | // private int MasterStation;
9 | // private int AuxiliaryReferenceStationID;
10 | // private int AuxMasterDeltaLatitude;
11 | // private int AuxMasterDeltaLongitude;
12 | // private int AuxMasterDeltaHeight;
13 | //
14 | // public MSG1014(byte[] msg) {
15 | // super.rawMsg = msg;
16 | // super.setToBinaryBuffer(msg);
17 | //
18 | // messageNumber = toUnsignedInt(getBits(16, 12));
19 | // NetworkID = toUnsignedInt(getBits(28, 8));
20 | // SubnetworkID = toUnsignedInt(getBits(36, 4));
21 | // NumberAuxiliaryStationsTransmitted = toUnsignedInt(getBits(40,5));
22 | // MasterStation = toUnsignedInt(getBits(45, 12));
23 | // AuxiliaryReferenceStationID = toUnsignedInt(getBits(57, 12));
24 | // AuxMasterDeltaLatitude = toSignedInt(getBits(69, 20));
25 | // AuxMasterDeltaLongitude = toSignedInt(getBits(89, 21));
26 | // AuxMasterDeltaHeight = toSignedInt(getBits(110, 23));
27 | // }
28 | //}
29 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/core/userServer/handlers/authentication/NtripNoneAuthHandler.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.core.userServer.handlers.authentication;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.SimpleChannelInboundHandler;
5 | import io.netty.handler.codec.http.FullHttpRequest;
6 | import org.dav95s.openNTRIP.commons.Registry;
7 | import org.dav95s.openNTRIP.core.ChannelState;
8 | import org.dav95s.openNTRIP.database.modelsV2.NetworkModel;
9 | import org.dav95s.openNTRIP.protocols.ntrip.NtripResponse;
10 |
11 | public class NtripNoneAuthHandler extends SimpleChannelInboundHandler {
12 |
13 | private final Registry registry;
14 |
15 | public NtripNoneAuthHandler(Registry registry) {
16 | this.registry = registry;
17 | }
18 |
19 | @Override
20 | protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
21 | ctx.writeAndFlush(NtripResponse.OK_MESSAGE);
22 |
23 | String networkName = ctx.channel().attr(ChannelState.NETWORK).get();
24 | NetworkModel networkModel = registry.networks.get(networkName);
25 | networkModel.channelGroup.add(ctx.channel());
26 |
27 | ctx.channel().attr(ChannelState.AUTHENTICATION).set(true);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/modelsV2/NetworkModel.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database.modelsV2;
2 |
3 | import io.netty.channel.group.ChannelGroup;
4 | import io.netty.channel.group.ChannelMatcher;
5 | import io.netty.channel.group.DefaultChannelGroup;
6 | import io.netty.util.concurrent.GlobalEventExecutor;
7 | import org.dav95s.openNTRIP.commons.Message;
8 | import org.dav95s.openNTRIP.protocols.ntrip.NetworkType;
9 |
10 | import java.util.ArrayList;
11 |
12 | public class NetworkModel {
13 | public final ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
14 | public final String identifier;
15 | public final NetworkType type;
16 |
17 | public NetworkModel(String identifier, String type) {
18 | this.identifier = identifier;
19 | this.type = NetworkType.valueOf(type);
20 | }
21 | public NetworkModel(String identifier, NetworkType type) {
22 | this.identifier = identifier;
23 | this.type = type;
24 | }
25 |
26 | //todo need remove cycle and unwrap array in outbound handler
27 | public synchronized void write(ArrayList messages, ChannelMatcher matcher) {
28 | for (Message message : messages) {
29 | channelGroup.write(message, matcher);
30 | }
31 | channelGroup.flush();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/test/java/org/dav95s/openNTRIP/protocols/rtcm/MSG1026Test.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm;
2 |
3 | import org.dav95s.openNTRIP.utils.binaryParse.BitUtils;
4 | import org.dav95s.openNTRIP.protocols.rtcm.messages.MSG1026;
5 | import org.junit.Assert;
6 | import org.junit.Test;
7 |
8 | import java.util.Arrays;
9 |
10 | public class MSG1026Test {
11 | @Test
12 | public void maxValues() {
13 |
14 | MSG1026 msg1026 = new MSG1026();
15 | msg1026.setSystemIdentificationNumber(255);
16 | msg1026.setProjectionType(11);
17 | msg1026.setLaFO(90);
18 | msg1026.setLoFO(180);
19 | msg1026.setLaSP1(90);
20 | msg1026.setLaSP2(90);
21 | msg1026.setEFO(68719476.735);
22 | msg1026.setNFO(17179869.182);
23 | byte[] result1 = msg1026.getBytes();
24 | MSG1026 msg10261 = new MSG1026(result1);
25 | byte[] result2 = msg10261.getBytes();
26 | System.out.println(Arrays.toString(result1));
27 | System.out.println(Arrays.toString(result2));
28 | System.out.println(msg1026.toString());
29 | System.out.println(msg10261.toString());
30 | System.out.println(new BitUtils(result1).toString(' '));
31 | System.out.println(new BitUtils(result2).toString(' '));
32 | Assert.assertArrayEquals(result1, result2);
33 | }
34 |
35 | }
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/commons/Registry.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.commons;
2 |
3 | import org.dav95s.openNTRIP.database.modelsV2.NetworkModel;
4 | import org.dav95s.openNTRIP.database.repository.NetworkRepository;
5 | import org.dav95s.openNTRIP.utils.ServerProperties;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import java.util.ArrayList;
10 | import java.util.Map;
11 | import java.util.concurrent.ConcurrentHashMap;
12 |
13 | public class Registry {
14 | private final static Logger logger = LoggerFactory.getLogger(Registry.class.getName());
15 |
16 | private final NetworkRepository networkRepository;
17 |
18 | public final Map networks = new ConcurrentHashMap<>();
19 |
20 |
21 | public Registry(ServerProperties serverProperties, NetworkRepository networkRepository) {
22 | this.networkRepository = networkRepository;
23 | updateNetworks();
24 | }
25 |
26 | public void updateNetworks() {
27 | ArrayList allReferenceStation = this.networkRepository.getAllReferenceStations();
28 | ArrayList allNetworks = this.networkRepository.getAllNetworks();
29 | allReferenceStation.forEach(network -> networks.putIfAbsent(network.identifier, network));
30 | allNetworks.forEach(network -> networks.putIfAbsent(network.identifier, network));
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/java/org/dav95s/openNTRIP/protocols/rtcm/MSG1027Test.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm;
2 |
3 | import org.dav95s.openNTRIP.utils.binaryParse.BitUtils;
4 | import org.dav95s.openNTRIP.protocols.rtcm.messages.MSG1027;
5 | import org.junit.Assert;
6 | import org.junit.Test;
7 |
8 | import java.util.Arrays;
9 |
10 | public class MSG1027Test {
11 | @Test
12 | public void maxValues() {
13 |
14 | MSG1027 msg1027 = new MSG1027();
15 | msg1027.setSystemIdentificationNumber(255);
16 | msg1027.setProjectionType(11);
17 | msg1027.setLaPC(90);
18 | msg1027.setLoPC(180);
19 | msg1027.setAzIL(360);
20 | msg1027.setRectifiedToSkew(360.369098741);
21 | msg1027.setSILppm(1.003737418);
22 | msg1027.setEPC(68719476.735);
23 | msg1027.setNPC(17179869.183);
24 |
25 | byte[] result1 = msg1027.getBytes();
26 | MSG1027 msg10271 = new MSG1027(result1);
27 | byte[] result2 = msg10271.getBytes();
28 |
29 | System.out.println(Arrays.toString(result1));
30 | System.out.println(Arrays.toString(result2));
31 | System.out.println(msg1027.toString());
32 | System.out.println(msg10271.toString());
33 | System.out.println(new BitUtils(result1).toString(' '));
34 | System.out.println(new BitUtils(result2).toString(' '));
35 | Assert.assertArrayEquals(result1, result2);
36 | }
37 | }
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/modelsV2/MountpointModel.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database.modelsV2;
2 |
3 | import org.dav95s.openNTRIP.database.models.assets.Authenticator;
4 |
5 | public class MountpointModel {
6 | public final int id;
7 | public final String name;
8 | public final String format;
9 | public final String network;
10 | public final boolean nmea;
11 | public final boolean solution;
12 | public final String compression;
13 | public final Authenticator authenticator;
14 | public final boolean fee;
15 |
16 | public MountpointModel(int id, String name, String format, String network, boolean nmea, boolean solution, String compression, String authenticator, boolean fee) {
17 | this.id = id;
18 | this.name = name;
19 | this.format = format;
20 | this.network = network;
21 | this.nmea = nmea;
22 | this.solution = solution;
23 | this.compression = compression;
24 | this.fee = fee;
25 |
26 |
27 | switch (authenticator) {
28 | case "B":
29 | case "Basic":
30 | this.authenticator = Authenticator.Basic;
31 | break;
32 | case "D":
33 | case "Digest":
34 | this.authenticator = Authenticator.Digest;
35 | break;
36 | default:
37 | this.authenticator = Authenticator.None;
38 | break;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/messages/MSG1007.java:
--------------------------------------------------------------------------------
1 | //package org.dav95s.openNTRIP.Tools.RTCM;
2 | //
3 | //public class MSG1007 extends RTCM {
4 | //
5 | // private int antennaID;
6 | // private int messageNumber;
7 | // private int stationID;
8 | // private int descriptorCounter;
9 | // private String antennaDescriptor;
10 | //
11 | // public MSG1007(byte[] msg) {
12 | // super.rawMsg = msg;
13 | //
14 | // super.setToBinaryBuffer(msg);
15 | //
16 | // messageNumber = toUnsignedInt(getBits(16, 12));
17 | // stationID = toUnsignedInt(getBits(28, 12));
18 | // descriptorCounter = toUnsignedInt(getBits(40, 8));
19 | // antennaDescriptor = "";
20 | // for (int i = 0; i < descriptorCounter; i++) {
21 | // antennaDescriptor += (char) toUnsignedInt(getBits(48 + (i * 8), 8));
22 | // }
23 | // int pointer = 48 + (descriptorCounter * 8);
24 | // antennaID = toUnsignedInt(getBits(pointer, 8));
25 | //
26 | // }
27 | //
28 | // public int getAntennaID() {
29 | // return antennaID;
30 | // }
31 | //
32 | // public int getMessageNumber() {
33 | // return messageNumber;
34 | // }
35 | //
36 | // public int getStationID() {
37 | // return stationID;
38 | // }
39 | //
40 | // public int getDescriptorCounter() {
41 | // return descriptorCounter;
42 | // }
43 | //
44 | // public String getAntennaDescriptor() {
45 | // return antennaDescriptor;
46 | // }
47 | //}
48 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/TransportTypeHolder.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP;
2 |
3 | import io.netty.channel.EventLoopGroup;
4 | import io.netty.channel.ServerChannel;
5 | import io.netty.channel.epoll.EpollEventLoopGroup;
6 | import io.netty.channel.epoll.EpollServerSocketChannel;
7 | import io.netty.channel.nio.NioEventLoopGroup;
8 | import io.netty.channel.socket.nio.NioServerSocketChannel;
9 | import org.dav95s.openNTRIP.utils.ServerProperties;
10 |
11 | public class TransportTypeHolder {
12 | public final EventLoopGroup bossGroup;
13 | public final EventLoopGroup workerGroup;
14 | public final Class extends ServerChannel> channelClass;
15 | public final boolean epollEnabled;
16 |
17 | public TransportTypeHolder(ServerProperties serverProperties) {
18 | this(serverProperties.getBoolProperty("enable.native.epoll.transport"),
19 | serverProperties.getIntProperty("server.worker.threads", Runtime.getRuntime().availableProcessors() * 2));
20 | }
21 |
22 | private TransportTypeHolder(boolean enableNativeEpoll, int workerThreads) {
23 | epollEnabled = enableNativeEpoll;
24 | if (enableNativeEpoll) {
25 | bossGroup = new EpollEventLoopGroup(1);
26 | workerGroup = new EpollEventLoopGroup(workerThreads);
27 | channelClass = EpollServerSocketChannel.class;
28 | } else {
29 | bossGroup = new NioEventLoopGroup(1);
30 | workerGroup = new NioEventLoopGroup(workerThreads);
31 | channelClass = NioServerSocketChannel.class;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/test/java/org/dav95s/openNTRIP/protocols/rtcm/MSG1023Test.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm;
2 |
3 | import org.dav95s.openNTRIP.commons.Message;
4 | import org.dav95s.openNTRIP.protocols.rtcm.messages.MSG1023;
5 | import org.junit.Assert;
6 | import org.junit.Test;
7 |
8 | import java.io.FileInputStream;
9 | import java.io.IOException;
10 | import java.util.ArrayList;
11 | import java.util.List;
12 | import java.util.stream.Collectors;
13 |
14 | public class MSG1023Test {
15 | @Test
16 | public void decodeEncode() {
17 |
18 | String file = "src/test/resources/1023.rtcm3";
19 | try (FileInputStream input = new FileInputStream(file)) {
20 | byte[] bytes = input.readAllBytes();
21 | Rtcm3Separator separator = new Rtcm3Separator();
22 | ArrayList separate = separator.separate(bytes);
23 |
24 | List collect1023 = separate.stream().filter(msg -> msg.name.equals("1023")).collect(Collectors.toList());
25 | Assert.assertTrue(collect1023.size() > 0);
26 |
27 | for (Message msg1023 : collect1023){
28 | MSG1023 msg1 = new MSG1023(msg1023.bytes);
29 | byte[] bytes1 = msg1.getBytes();
30 | MSG1023 msg2 = new MSG1023(bytes1);
31 | byte[] bytes2 = msg2.getBytes();
32 | Assert.assertArrayEquals(msg1023.bytes, bytes1);
33 | Assert.assertArrayEquals(msg1023.bytes, bytes2);
34 | }
35 | } catch (IOException e) {
36 | e.printStackTrace();
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/src/test/java/org/dav95s/openNTRIP/protocols/rtcm/MSG1006Test.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm;
2 |
3 | import org.dav95s.openNTRIP.commons.Message;
4 | import org.dav95s.openNTRIP.protocols.rtcm.messages.MSG1006;
5 | import org.junit.Assert;
6 | import org.junit.Test;
7 |
8 | import java.io.File;
9 | import java.io.FileInputStream;
10 | import java.io.IOException;
11 | import java.util.ArrayList;
12 | import java.util.List;
13 | import java.util.stream.Collectors;
14 |
15 | public class MSG1006Test {
16 | String path = "src/test/resources/RTCM_32";
17 |
18 | @Test
19 | public void start() {
20 |
21 | File file = new File(path);
22 |
23 | try (FileInputStream input = new FileInputStream(file)) {
24 | byte[] bytes = input.readAllBytes();
25 | Rtcm3Separator separator = new Rtcm3Separator();
26 | ArrayList separate = separator.separate(bytes);
27 |
28 | List collect1006 = separate.stream().filter(msg -> msg.name.equals("1006")).collect(Collectors.toList());
29 | Assert.assertTrue(collect1006.size() > 0);
30 |
31 | for (Message msg1006 : collect1006){
32 | MSG1006 msg = new MSG1006(bytes);
33 | byte[] bytes2 = msg.getBytes();
34 | MSG1006 msg2 = new MSG1006(bytes2);
35 | byte[] bytes3 = msg2.getBytes();
36 | Assert.assertArrayEquals(bytes2, bytes3);
37 | }
38 |
39 | } catch (IOException e) {
40 | e.printStackTrace();
41 | }
42 |
43 | }
44 |
45 |
46 | }
--------------------------------------------------------------------------------
/src/test/java/org/dav95s/openNTRIP/protocols/rtcm/MSG1025Test.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm;
2 |
3 | import org.dav95s.openNTRIP.commons.Message;
4 | import org.dav95s.openNTRIP.protocols.rtcm.messages.MSG1025;
5 | import org.junit.Assert;
6 | import org.junit.Test;
7 |
8 | import java.io.FileInputStream;
9 | import java.io.IOException;
10 | import java.util.ArrayList;
11 | import java.util.List;
12 | import java.util.stream.Collectors;
13 |
14 | public class MSG1025Test {
15 |
16 | @Test
17 | public void decodeEncode() {
18 | String file = "src/test/resources/1025.rtcm3";
19 | try (FileInputStream input = new FileInputStream(file)) {
20 | byte[] bytes = input.readAllBytes();
21 | Rtcm3Separator separator = new Rtcm3Separator();
22 | ArrayList separate = separator.separate(bytes);
23 |
24 | List collect1025 = separate.stream().filter(msg -> msg.name.equals("1025")).collect(Collectors.toList());
25 | Assert.assertTrue(collect1025.size() > 0);
26 |
27 | for (Message msg1025 : collect1025){
28 | MSG1025 msg1 = new MSG1025(msg1025.bytes);
29 | byte[] bytes1 = msg1.getBytes();
30 | MSG1025 msg2 = new MSG1025(bytes1);
31 | byte[] bytes2 = msg2.getBytes();
32 | Assert.assertArrayEquals(msg1025.bytes, bytes1);
33 | Assert.assertArrayEquals(msg1025.bytes, bytes2);
34 | }
35 | } catch (IOException e) {
36 | e.printStackTrace();
37 | }
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/repository/UserRepository.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database.repository;
2 |
3 | import org.dav95s.openNTRIP.database.DataSource;
4 | import org.dav95s.openNTRIP.database.modelsV2.UserModel;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | import java.sql.Connection;
9 | import java.sql.PreparedStatement;
10 | import java.sql.ResultSet;
11 | import java.sql.SQLException;
12 |
13 | public class UserRepository {
14 | final static private Logger logger = LoggerFactory.getLogger(UserRepository.class.getName());
15 |
16 | public UserModel getUserByUsername(String username) {
17 | String sql = "SELECT `id`,`username`, `password`, `email` FROM users WHERE `username` = ?";
18 |
19 | try (Connection con = DataSource.getConnection();
20 | PreparedStatement statement = con.prepareStatement(sql)) {
21 |
22 | statement.setString(1, username);
23 |
24 | try (ResultSet rs = statement.executeQuery()) {
25 | if (rs.next()) {
26 | return new UserModel(
27 | rs.getInt("id"),
28 | rs.getString("username"),
29 | rs.getString("password"),
30 | rs.getString("email")
31 | );
32 | } else {
33 | return null;
34 | }
35 | }
36 |
37 | } catch (SQLException e) {
38 | logger.error("SQL Error", e);
39 | return null;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/ServerLauncher.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP;
2 |
3 | import org.dav95s.openNTRIP.commons.GlobalStats;
4 | import org.dav95s.openNTRIP.commons.Registry;
5 | import org.dav95s.openNTRIP.core.userServer.NtripServer;
6 | import org.dav95s.openNTRIP.core.stationsServer.ReferenceStationServer;
7 | import org.dav95s.openNTRIP.database.repository.NetworkRepository;
8 | import org.dav95s.openNTRIP.database.repository.ReferenceStationRepository;
9 | import org.dav95s.openNTRIP.utils.ServerProperties;
10 |
11 | public class ServerLauncher {
12 | private final ServerProperties serverProperties;
13 | private final Registry registry;
14 | private final GlobalStats stats;
15 | private final ReferenceStationServer referenceStationServer;
16 | private final NtripServer ntripServer;
17 |
18 | private ServerLauncher(ServerProperties serverProperties) {
19 | this.serverProperties = serverProperties;
20 | this.registry = new Registry(serverProperties, new NetworkRepository());
21 | this.stats = new GlobalStats(serverProperties);
22 |
23 | TransportTypeHolder transportType = new TransportTypeHolder(serverProperties);
24 |
25 | this.referenceStationServer = new ReferenceStationServer(serverProperties, registry, transportType, new ReferenceStationRepository());
26 | this.ntripServer = new NtripServer(serverProperties, registry, transportType);
27 | }
28 |
29 | private void start() {
30 | //start servers
31 | new Thread(referenceStationServer).start();
32 | new Thread(ntripServer).start();
33 | }
34 |
35 | public static void main(String[] args) {
36 | ServerProperties serverProperties = new ServerProperties();
37 | new ServerLauncher(serverProperties).start();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/models/ServerModel.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database.models;
2 |
3 | public class ServerModel {
4 | int id;
5 | int port;
6 |
7 | public void read() {
8 | String sql = "SELECT * FROM `reference_stations` WHERE `id` = ?";
9 |
10 | // try (Connection con = DataSource.getConnection();
11 | // PreparedStatement statement = con.prepareStatement(sql)) {
12 | //
13 | // statement.setInt(1, id);
14 | //
15 | // try (ResultSet rs = statement.executeQuery()) {
16 | // if (rs.next()) {
17 | // this.name = rs.getString("name");
18 | // this.identifier = rs.getString("identifier");
19 | // this.format = rs.getString("format");
20 | // this.format_details = rs.getString("format_details");
21 | // this.carrier = rs.getInt("carrier");
22 | // this.nav_system = rs.getString("nav_system");
23 | // this.country = rs.getString("country");
24 | // this.position.lat = (float) rs.getDouble("lat");
25 | // this.position.lon = (float) rs.getDouble("lon");
26 | // this.position.altitude = (float) rs.getDouble("alt");
27 | // this.bitrate = rs.getInt("bitrate");
28 | // this.misc = rs.getString("misc");
29 | // this.password = rs.getString("password");
30 | // this.hz = rs.getInt("hz");
31 | // return true;
32 | // } else {
33 | // return false;
34 | // }
35 | // }
36 | // } catch (SQLException e) {
37 | // logger.error("SQL Error", e);
38 | // return false;
39 | // }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/test/java/org/dav95s/openNTRIP/users/passwords/BCryptTest.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.users.passwords;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertFalse;
6 | import static org.junit.Assert.assertTrue;
7 |
8 | public class BCryptTest {
9 |
10 | @Test
11 | public void testCompare() {
12 | BCrypt bCrypt = new BCrypt();
13 |
14 | assertTrue(bCrypt.compare("$2y$12$P07ACb3XmtIvHJXrzhTULeOUAF1Q0zh3STfPpjZTu9z8JVD4580Uu", "password"));
15 | assertTrue(bCrypt.compare("$2a$10$eGYNvSMbYMw2ks818r6HdOlqiPRR1ETqTATsdxWzoO8aug7sxx.mC", "ffaqq"));
16 | assertTrue(bCrypt.compare("$2a$04$YFzshOrWKAZ8iu4gW0/NhOo9B.A1Lnn8k6uzXivraiAKv66ByW1q6", "rqrqrqr1144"));
17 | assertTrue(bCrypt.compare("$2b$10$uayG5HrmJSRK7.gDW9QX7.e9RYM0lwlUbzieDbVCcVrKJ14XFHwx6", "ttt4444ccz"));
18 | assertTrue(bCrypt.compare("$2a$04$AQgn0ch7ZWrrfP8Opq/k8.xazPZcqyvbz/8xf52W69utG9onGhi16", "yyytttqqee4444"));
19 | assertTrue(bCrypt.compare("$2y$12$8TkvffyD05BaK7KGKNDTD.AdvYKs0W6dfoWGvQUmbZy.9kNf0jze6", ""));
20 |
21 |
22 | assertFalse(bCrypt.compare("2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", "hallo"));
23 | assertFalse(bCrypt.compare("$2y$12$8TkvffyD05BaK7KGKNDTD.AdvYKs0W6dfoWGvQUmbZy.9kNf0jze6", "!2@@#31"));
24 | assertFalse(bCrypt.compare(null, "11313"));
25 | assertFalse(bCrypt.compare(null, null));
26 | assertFalse(bCrypt.compare("2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", null));
27 |
28 | }
29 |
30 | @Test
31 | public void testHash() {
32 | BCrypt bCrypt = new BCrypt();
33 |
34 | String example = "12asdfasfqwrqwrqwr";
35 | String hash = bCrypt.hash("12asdfasfqwrqwrqwr");
36 | assertTrue(bCrypt.compare(hash, example));
37 | assertFalse(bCrypt.compare(hash, "123123123123"));
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/messages/MSG1008.java:
--------------------------------------------------------------------------------
1 | //package org.dav95s.openNTRIP.Tools.RTCM;
2 | //
3 | //public class MSG1008 extends RTCM {
4 | //
5 | // private int antennaID;
6 | // private int messageNumber;
7 | // private int stationID;
8 | // private String antennaDescriptor;
9 | // private String serialNumber;
10 | //
11 | // public MSG1008(byte[] msg) {
12 | // super.rawMsg = msg;
13 | //
14 | // super.setToBinaryBuffer(msg);
15 | //
16 | // messageNumber = toUnsignedInt(getBits(16, 12));
17 | // stationID = toUnsignedInt(getBits(28, 12));
18 | // int descriptorCounter = toUnsignedInt(getBits(40, 8));
19 | //
20 | // /* antennaDescriptor */
21 | // antennaDescriptor = "";
22 | // for (int i = 0; i < descriptorCounter; i++) {
23 | // antennaDescriptor += (char) toUnsignedInt(getBits(48 + (i * 8), 8));
24 | // }
25 | // /* antennaDescriptor */
26 | //
27 | // int pointer = 48 + (descriptorCounter * 8); //pointer to next
28 | // antennaID = toUnsignedInt(getBits(pointer, 8));
29 | //
30 | // /* serialNumber */
31 | // int serialNumberCounter = toUnsignedInt(getBits(pointer + 8, 8));
32 | // serialNumber = "";
33 | // for (int i = 0; i < serialNumberCounter; i++) {
34 | // serialNumber += (char) toUnsignedInt(getBits((pointer + 16) + (i * 8), 8));
35 | // }
36 | // /* serialNumber */
37 | //
38 | // }
39 | //
40 | // public int getAntennaID() {
41 | // return antennaID;
42 | // }
43 | //
44 | // public int getMessageNumber() {
45 | // return messageNumber;
46 | // }
47 | //
48 | // public int getStationID() {
49 | // return stationID;
50 | // }
51 | //
52 | // public String getAntennaDescriptor() {
53 | // return antennaDescriptor;
54 | // }
55 | //
56 | // public String getSerialNumber() {
57 | // return serialNumber;
58 | // }
59 | //}
60 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/models/GridModel.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database.models;
2 |
3 | import org.dav95s.openNTRIP.crs.gridShift.GeodeticPoint;
4 | import org.dav95s.openNTRIP.database.DataSource;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | import java.sql.Connection;
9 | import java.sql.PreparedStatement;
10 | import java.sql.ResultSet;
11 | import java.sql.SQLException;
12 | import java.util.ArrayList;
13 |
14 | public class GridModel {
15 | static final private Logger logger = LoggerFactory.getLogger(GridModel.class.getName());
16 |
17 | public ArrayList getAddGeodeticPointByCrsId(int crsId) {
18 | String sql = "SELECT id, ROUND(X(geodetic_point_measured), 9) AS north, ROUND(Y(geodetic_point_measured), 9) AS east, ROUND(X(geodetic_point_from_catalog)-X(geodetic_point_measured), 9) AS dnorth, ROUND(Y(geodetic_point_from_catalog)-Y(geodetic_point_measured), 9) AS deast FROM `crs_grids` WHERE `crs_id` = ?;";
19 |
20 | try (Connection con = DataSource.getConnection();
21 | PreparedStatement statement = con.prepareStatement(sql)) {
22 | statement.setInt(1, crsId);
23 |
24 | try (ResultSet rs = statement.executeQuery()) {
25 | ArrayList gridNodes = new ArrayList<>();
26 |
27 | while (rs.next()) {
28 | GeodeticPoint point = new GeodeticPoint();
29 | point.id = rs.getLong("id");
30 | point.north = rs.getDouble("north");
31 | point.east = rs.getDouble("east");
32 | point.dNorth = rs.getDouble("dnorth");
33 | point.dEast = rs.getDouble("deast");
34 | gridNodes.add(point);
35 | }
36 | return gridNodes;
37 | }
38 |
39 | } catch (SQLException e) {
40 | logger.error("SQL Error", e);
41 | return new ArrayList<>();
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/repository/MountpointRepository.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database.repository;
2 |
3 | import org.dav95s.openNTRIP.database.DataSource;
4 | import org.dav95s.openNTRIP.database.modelsV2.MountpointModel;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | import java.sql.Connection;
9 | import java.sql.PreparedStatement;
10 | import java.sql.ResultSet;
11 | import java.sql.SQLException;
12 |
13 | public class MountpointRepository {
14 | final static private Logger logger = LoggerFactory.getLogger(MountpointRepository.class.getName());
15 |
16 | public MountpointModel getMountpoint(String name) {
17 | if (name == null || name.isEmpty()) {
18 | return null;
19 | }
20 |
21 | String sql = "SELECT `id`, `name`, `format`, network, nmea, solution, compression, authenticator, fee FROM mountpoints WHERE `name` = ?;";
22 |
23 | try (Connection con = DataSource.getConnection();
24 | PreparedStatement statement = con.prepareStatement(sql)) {
25 |
26 | statement.setString(1, name);
27 |
28 | try (ResultSet rs = statement.executeQuery()) {
29 | MountpointModel response;
30 | if (rs.next()) {
31 | response = new MountpointModel(
32 | rs.getInt("id"),
33 | rs.getString("name"),
34 | rs.getString("format"),
35 | rs.getString("network"),
36 | rs.getBoolean("nmea"),
37 | rs.getBoolean("solution"),
38 | rs.getString("compression"),
39 | rs.getString("authenticator"),
40 | rs.getBoolean("fee")
41 | );
42 | return response;
43 | } else {
44 | return null;
45 | }
46 | }
47 |
48 | } catch (SQLException e) {
49 | logger.error("SQL Error", e);
50 | return null;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/models/UserGroupModel.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database.models;
2 |
3 | import org.dav95s.openNTRIP.database.DataSource;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | import java.sql.Connection;
8 | import java.sql.PreparedStatement;
9 | import java.sql.ResultSet;
10 | import java.sql.SQLException;
11 | import java.util.HashSet;
12 | import java.util.Set;
13 |
14 | public class UserGroupModel {
15 | final static private Logger logger = LoggerFactory.getLogger(UserGroupModel.class.getName());
16 |
17 | private int group_id;
18 | private String name;
19 | private String description;
20 |
21 | public Set readAllGroups() {
22 | String sql = "SELECT * FROM `groups`";
23 | Set groups = new HashSet<>();
24 |
25 | try (Connection con = DataSource.getConnection();
26 | PreparedStatement statement = con.prepareStatement(sql)) {
27 |
28 | try (ResultSet rs = statement.executeQuery()) {
29 |
30 | while (rs.next()) {
31 | UserGroupModel group = new UserGroupModel();
32 | group.setGroup_id(rs.getInt("id"));
33 | group.setName(rs.getString("name"));
34 | group.setDescription(rs.getString("description"));
35 | groups.add(group);
36 | }
37 | return groups;
38 | }
39 | } catch (SQLException e) {
40 | logger.error("SQL Error", e);
41 | return new HashSet<>();
42 | }
43 | }
44 |
45 | public int getGroup_id() {
46 | return this.group_id;
47 | }
48 |
49 | public String getName() {
50 | return this.name;
51 | }
52 |
53 | public String getDescription() {
54 | return this.description;
55 | }
56 |
57 | public void setGroup_id(int group_id) {
58 | this.group_id = group_id;
59 | }
60 |
61 | public void setName(String name) {
62 | this.name = name;
63 | }
64 |
65 | public void setDescription(String description) {
66 | this.description = description;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/test/java/SandBox.java:
--------------------------------------------------------------------------------
1 | import org.dav95s.openNTRIP.database.modelsV2.ReferenceStationModel;
2 | import org.dav95s.openNTRIP.database.repository.ReferenceStationRepository;
3 | import org.json.JSONArray;
4 | import org.json.JSONObject;
5 | import org.junit.Test;
6 |
7 | public class SandBox {
8 |
9 | @Test
10 | public void start() {
11 | String json = "{\"type\":\"FeatureCollection\",\"totalFeatures\":1,\"features\":[{\"type\":\"Feature\",\"id\":\"ZKP_LAND_06.239216801\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[108820.5,84474.09],[108707.71,84426.3],[108734.23,84359.9],[108763.53,84346.78],[108775.15,84343.76],[108847.13,84381.85],[108843.98,84386.98],[108835.68,84400.32],[108836.44,84401.7],[108856.74,84413.87],[108820.5,84474.09]],[[108803.27,84378.69],[108772.61,84382.61],[108774.15,84394.79],[108805.11,84390.61],[108803.27,84378.69]]]},\"geometry_name\":\"GEOLOC\",\"properties\":{\"KN\":\"78:15:0843201:1008\",\"STATUS\":\"Неизвестно\",\"ADDRESS\":\"г.Санкт-Петербург, проспект Стачек, участок 238, (г.Санкт-Петербург, проспект Стачек, участок 238, (у дома 208))\",\"PERMITTED_USE\":\" Для размещения религиозных объектов\",\"FACT_AREA\":null,\"UPDATED_AREA\":null,\"DECLARED_AREA\":11480,\"RIGHT_KIND\":null,\"P_DATE\":\"22.10.2002\",\"CAD_COST\":12819205.14,\"PREV_KNS\":\"78:8432А:1008\",\"BEFORE_KN\":null,\"HAS_CAD_SURVEY\":\"Да\",\"WAS_RENTED\":\"В аренде\"}}],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"urn:ogc:def:crs:EPSG::99781\"}}}";
12 | JSONObject jsonObject = new JSONObject(json);
13 |
14 | JSONArray jsonArray = jsonObject.getJSONArray("features").getJSONObject(0).getJSONObject("geometry").getJSONArray("coordinates").getJSONArray(0);
15 | for (int i = 0; i < jsonArray.length(); i++) {
16 | JSONArray polygon = jsonArray.getJSONArray(i);
17 | System.out.println(polygon.getDouble(0) + " " + polygon.getDouble(1));
18 | }
19 | }
20 |
21 | @Test
22 | public void start2(){
23 | ReferenceStationRepository referenceStationRepository = new ReferenceStationRepository();
24 | ReferenceStationModel al1 = referenceStationRepository.GetReferenceStationByName("AL2");
25 | System.out.println(123);
26 | }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/repository/NetworkRepository.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database.repository;
2 |
3 | import org.dav95s.openNTRIP.database.DataSource;
4 | import org.dav95s.openNTRIP.database.modelsV2.NetworkModel;
5 | import org.dav95s.openNTRIP.protocols.ntrip.NetworkType;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import java.sql.Connection;
10 | import java.sql.PreparedStatement;
11 | import java.sql.ResultSet;
12 | import java.sql.SQLException;
13 | import java.util.ArrayList;
14 |
15 | public class NetworkRepository {
16 | final static private Logger logger = LoggerFactory.getLogger(ReferenceStationRepository.class.getName());
17 |
18 | public ArrayList getAllNetworks() {
19 |
20 | String sql = "SELECT `type`, `identifier` FROM `networks`";
21 |
22 | ArrayList networks = new ArrayList<>();
23 |
24 | try (Connection con = DataSource.getConnection();
25 | PreparedStatement statement = con.prepareStatement(sql)) {
26 | try (ResultSet rs = statement.executeQuery()) {
27 | while (rs.next()) {
28 | networks.add(new NetworkModel(rs.getString("identifier"), rs.getString("type")));
29 | }
30 | }
31 | } catch (SQLException e) {
32 | logger.error("SQL Error", e);
33 | return null;
34 | }
35 | return networks;
36 | }
37 |
38 | public ArrayList getAllReferenceStations() {
39 | String sql = "SELECT `name` FROM `reference_stations`";
40 |
41 | ArrayList networks = new ArrayList<>();
42 |
43 | try (Connection con = DataSource.getConnection();
44 | PreparedStatement statement = con.prepareStatement(sql)) {
45 | try (ResultSet rs = statement.executeQuery()) {
46 | while (rs.next()) {
47 | networks.add(new NetworkModel(rs.getString("name"), NetworkType.STR));
48 | }
49 | }
50 | return networks;
51 | } catch (SQLException e) {
52 | logger.error("SQL Error", e);
53 | return null;
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/core/BaseServer.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.core;
2 |
3 | import io.netty.bootstrap.ServerBootstrap;
4 | import io.netty.channel.*;
5 | import io.netty.channel.socket.SocketChannel;
6 | import org.dav95s.openNTRIP.TransportTypeHolder;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | public abstract class BaseServer implements Runnable {
11 |
12 | private final static Logger logger = LoggerFactory.getLogger(BaseServer.class.getName());
13 | protected final int port;
14 | private final TransportTypeHolder transportTypeHolder;
15 |
16 | private Channel channel;
17 |
18 | protected BaseServer(int port, TransportTypeHolder transportTypeHolder) {
19 | this.port = port;
20 | this.transportTypeHolder = transportTypeHolder;
21 | }
22 |
23 | @Override
24 | public void run() {
25 | if (transportTypeHolder.epollEnabled) {
26 | logger.warn("Native epoll transport enabled.");
27 | }
28 | buildServerAndRun(
29 | transportTypeHolder.bossGroup,
30 | transportTypeHolder.workerGroup,
31 | transportTypeHolder.channelClass
32 | );
33 | }
34 |
35 | private void buildServerAndRun(EventLoopGroup bossGroup, EventLoopGroup workerGroup,
36 | Class extends ServerChannel> channelClass) {
37 |
38 | ServerBootstrap b = new ServerBootstrap();
39 | try {
40 | b.group(bossGroup, workerGroup)
41 | .channel(channelClass)
42 | .childOption(ChannelOption.SO_KEEPALIVE, true)
43 | .childHandler(getChannelInitializer());
44 |
45 | ChannelFuture channelFuture = b.bind(port).sync();
46 |
47 | this.channel = channelFuture.channel();
48 | this.channel.closeFuture().sync();
49 | } catch (Exception e) {
50 | logger.error("", e);
51 | } finally {
52 | bossGroup.shutdownGracefully();
53 | workerGroup.shutdownGracefully();
54 | }
55 | }
56 |
57 | protected abstract ChannelInitializer getChannelInitializer();
58 |
59 | public void stop() {
60 | if (channel != null) {
61 | channel.close().awaitUninterruptibly();
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/models/SourceTableModel.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database.models;
2 |
3 | import org.dav95s.openNTRIP.database.DataSource;
4 |
5 | import java.nio.charset.StandardCharsets;
6 | import java.sql.Connection;
7 | import java.sql.PreparedStatement;
8 | import java.sql.ResultSet;
9 | import java.sql.SQLException;
10 | import java.util.ArrayList;
11 |
12 | public class SourceTableModel {
13 | //"SELECT CONCAT('STR', ';', name, ';', identifier, ';', format, ';', format_details, ';', carrier, ';', nav_system, ';', network, ';', country, ';', ROUND(latitude,2), ';', ROUND(longitude,2), ';', nmea, ';', solution, ';', generator, ';', compression, ';', authenticator, ';', fee, ';', bitrate, ';', misc) as `sourcetable` FROM mountpoints WHERE caster_id = ? AND available = ?"
14 | private ArrayList getTable() {
15 | String sql = "SELECT CONCAT_WS(';','STR', name, identifier, format, format_details, carrier, nav_system, network, country, ROUND(latitude,2), ROUND(longitude,2), nmea, solution, generator, compression, authenticator, fee, bitrate, misc) as `sourcetable` FROM mountpoints WHERE available = ?";
16 |
17 | ArrayList response = new ArrayList<>();
18 |
19 | try (Connection con = DataSource.getConnection();
20 | PreparedStatement statement = con.prepareStatement(sql)) {
21 |
22 | statement.setInt(1, 1);
23 |
24 | try (ResultSet rs = statement.executeQuery()) {
25 | while (rs.next()) {
26 | response.add(rs.getString("sourcetable"));
27 | }
28 | }
29 | } catch (SQLException e) {
30 | e.printStackTrace();
31 | }
32 | return response;
33 | }
34 |
35 | public String getSourcetable() {
36 | ArrayList table = this.getTable();
37 | String header = "SOURCETABLE 200 OK\r\n" +
38 | "Content-Type: text/html\r\n" +
39 | "Connection: close\r\n";
40 |
41 | StringBuilder body = new StringBuilder();
42 | table.forEach((mp) -> {
43 | body.append(mp);
44 | body.append("\r\n");
45 | });
46 | body.append("ENDSOURCETABLE\r\n");
47 |
48 | String bodyString = body.toString();
49 | header += "Content-Length: " + bodyString.getBytes(StandardCharsets.ISO_8859_1).length + "\r\n\n";
50 |
51 | return header + bodyString;
52 | }
53 |
54 | public byte[] getBytesSourcetable() {
55 | return getSourcetable().getBytes(StandardCharsets.US_ASCII);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/core/userServer/NtripServer.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.core.userServer;
2 |
3 | import io.netty.channel.ChannelInitializer;
4 | import io.netty.channel.ChannelPipeline;
5 | import io.netty.channel.socket.SocketChannel;
6 | import io.netty.handler.codec.bytes.ByteArrayEncoder;
7 | import io.netty.handler.codec.http.HttpObjectAggregator;
8 | import io.netty.handler.codec.http.HttpRequestDecoder;
9 | import org.dav95s.openNTRIP.TransportTypeHolder;
10 | import org.dav95s.openNTRIP.commons.Registry;
11 | import org.dav95s.openNTRIP.core.BaseServer;
12 | import org.dav95s.openNTRIP.core.userServer.handlers.UserAuthHandler;
13 | import org.dav95s.openNTRIP.database.repository.MountpointRepository;
14 | import org.dav95s.openNTRIP.database.repository.UserRepository;
15 | import org.dav95s.openNTRIP.utils.ServerProperties;
16 | import org.slf4j.Logger;
17 | import org.slf4j.LoggerFactory;
18 |
19 | public class NtripServer extends BaseServer {
20 | private final static Logger logger = LoggerFactory.getLogger(NtripServer.class.getName());
21 |
22 | MountpointRepository mountpointRepository = new MountpointRepository();
23 | UserRepository userRepository = new UserRepository();
24 |
25 | private final ChannelInitializer channelInitializer;
26 |
27 | public NtripServer(ServerProperties serverProperties, Registry registry, TransportTypeHolder transportType) {
28 | super(serverProperties.getIntProperty("ntrip.default.port"), transportType);
29 |
30 | int stationTimeoutSecs = serverProperties.getIntProperty("station.socket.idle.timeout", 0);
31 |
32 | channelInitializer = new ChannelInitializer() {
33 | @Override
34 | protected void initChannel(SocketChannel ch) throws Exception {
35 | ChannelPipeline pipeline = ch.pipeline();
36 | pipeline.addLast("ByteArrayEncoder", new ByteArrayEncoder());
37 | pipeline.addLast("HttpInboundHandler", new HttpRequestDecoder());
38 | pipeline.addLast("HttpObjectAggregator ", new HttpObjectAggregator(2048,true));
39 | pipeline.addLast("Authentication", new UserAuthHandler(registry, mountpointRepository, userRepository));
40 | }
41 | };
42 |
43 | logger.debug("hard.socket.idle.timeout = {}", stationTimeoutSecs);
44 |
45 | logger.info("Plain tcp/ip reference station server port {}.", port);
46 | }
47 |
48 | @Override
49 | protected ChannelInitializer getChannelInitializer() {
50 | return channelInitializer;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/models/CrsModel.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database.models;
2 |
3 | import org.dav95s.openNTRIP.database.DataSource;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | import java.sql.Connection;
8 | import java.sql.PreparedStatement;
9 | import java.sql.ResultSet;
10 | import java.sql.SQLException;
11 |
12 | public class CrsModel {
13 | static final private Logger logger = LoggerFactory.getLogger(CrsModel.class.getName());
14 |
15 | int id;
16 | int mountpointId;
17 | String crs;
18 | String geoidPath;
19 |
20 |
21 | String residualGrid;
22 |
23 | public CrsModel(int mountpointId) {
24 | this.mountpointId = mountpointId;
25 | }
26 |
27 | public boolean read() {
28 | String sql = "SELECT * FROM `crs` WHERE `id` = ?";
29 |
30 | try (Connection con = DataSource.getConnection();
31 | PreparedStatement statement = con.prepareStatement(sql)) {
32 |
33 | statement.setInt(1, mountpointId);
34 |
35 | try (ResultSet rs = statement.executeQuery()) {
36 | if (rs.next()) {
37 | id = rs.getInt("id");
38 | crs = rs.getString("crs");
39 | geoidPath = rs.getString("geoid_path");
40 | residualGrid = rs.getString("residual_grid");
41 | return true;
42 | } else {
43 | return false;
44 | }
45 | }
46 |
47 | } catch (SQLException e) {
48 | logger.error("SQL error", e);
49 | return false;
50 | }
51 | }
52 |
53 | public boolean update() {
54 | String sql = "UPDATE `crs` SET `residual_grid`= ? WHERE `id` = ?";
55 |
56 | try (Connection con = DataSource.getConnection();
57 | PreparedStatement statement = con.prepareStatement(sql)) {
58 |
59 | statement.setString(1, residualGrid);
60 | statement.setInt(2, id);
61 |
62 | return statement.executeUpdate() > 0;
63 | } catch (SQLException e) {
64 | logger.error("SQL Error", e);
65 | return false;
66 | }
67 | }
68 |
69 | public int getId() {
70 | return id;
71 | }
72 |
73 | public int getMountpointId() {
74 | return mountpointId;
75 | }
76 |
77 | public String getCrs() {
78 | return crs;
79 | }
80 |
81 | public String getGeoidPath() {
82 | return geoidPath;
83 | }
84 |
85 | public String getResidualGrid() {
86 | return residualGrid;
87 | }
88 |
89 | public void setResidualGrid(String residualGrid) {
90 | this.residualGrid = residualGrid;
91 | }
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/core/stationsServer/ReferenceStationServer.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.core.stationsServer;
2 |
3 | import io.netty.channel.ChannelInitializer;
4 | import io.netty.channel.ChannelPipeline;
5 | import io.netty.channel.socket.SocketChannel;
6 | import io.netty.handler.codec.bytes.ByteArrayDecoder;
7 | import io.netty.handler.codec.bytes.ByteArrayEncoder;
8 | import io.netty.handler.timeout.ReadTimeoutHandler;
9 | import org.dav95s.openNTRIP.TransportTypeHolder;
10 | import org.dav95s.openNTRIP.commons.Registry;
11 | import org.dav95s.openNTRIP.core.BaseServer;
12 | import org.dav95s.openNTRIP.core.stationsServer.handlers.ReferenceStationAuthHandler;
13 | import org.dav95s.openNTRIP.database.repository.ReferenceStationRepository;
14 | import org.dav95s.openNTRIP.utils.ServerProperties;
15 | import org.slf4j.Logger;
16 | import org.slf4j.LoggerFactory;
17 |
18 | public class ReferenceStationServer extends BaseServer {
19 | private final static Logger logger = LoggerFactory.getLogger(ReferenceStationServer.class.getName());
20 |
21 | private final ChannelInitializer channelInitializer;
22 |
23 | public ReferenceStationServer(ServerProperties serverProperties, Registry registry,
24 | TransportTypeHolder transportType, ReferenceStationRepository referenceStationRepository) {
25 |
26 | super(serverProperties.getIntProperty("station.default.port"), transportType);
27 |
28 | int stationTimeoutSecs = serverProperties.getIntProperty("station.socket.idle.timeout", 0);
29 |
30 | channelInitializer = new ChannelInitializer() {
31 | @Override
32 | protected void initChannel(SocketChannel ch) throws Exception {
33 | ChannelPipeline pipeline = ch.pipeline();
34 |
35 | //non-sharable handlers
36 | if (stationTimeoutSecs > 0) {
37 | pipeline.addLast(new ReadTimeoutHandler(stationTimeoutSecs));
38 | }
39 |
40 | pipeline.addLast("ByteArrayEncoder", new ByteArrayEncoder());
41 | pipeline.addLast("ByteArrayDecoder", new ByteArrayDecoder());
42 | pipeline.addLast("StationAuthHandler", new ReferenceStationAuthHandler(registry, referenceStationRepository));
43 | }
44 | };
45 |
46 | logger.debug("hard.socket.idle.timeout = {}", stationTimeoutSecs);
47 |
48 | logger.info("Plain tcp/ip reference station server port {}.", port);
49 | }
50 |
51 | @Override
52 | public ChannelInitializer getChannelInitializer() {
53 | return channelInitializer;
54 | }
55 |
56 | @Override
57 | public void stop() {
58 | logger.info("Shutting down default server...");
59 | super.stop();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/messages/MSG1013.java:
--------------------------------------------------------------------------------
1 | //package org.dav95s.openNTRIP.Tools.RTCM;
2 | //
3 | //public class MSG1013 extends RTCM {
4 | // private int messageNumber;
5 | // private int stationID;
6 | // private int MJD; //Modified Julian Day Number
7 | // private int UTC; //Seconds of Day UTC
8 | // private int LeapSeconds; // Leap Seconds, GPS-UTC
9 | // private Message[] list;
10 | //
11 | //
12 | // public MSG1013(byte[] msg) {
13 | // super.rawMsg = msg;
14 | // super.setToBinaryBuffer(msg);
15 | //
16 | // messageNumber = toUnsignedInt(getBits(16, 12));
17 | // stationID = toUnsignedInt(getBits(28, 12));
18 | // MJD = toUnsignedInt(getBits(40, 16));
19 | // UTC = toUnsignedInt(getBits(56, 17));
20 | // int messageCounter = toUnsignedInt(getBits(73, 5));
21 | // list = new Message[messageCounter];
22 | // LeapSeconds = toUnsignedInt(getBits(78, 8));//86
23 | //
24 | // for (int i = 0; i < messageCounter; i++) {
25 | // int shift = i * 29;
26 | // Message m = new Message();
27 | //
28 | // m.setMessageID(toUnsignedInt(getBits(89 + shift, 12)));
29 | // m.setSyncFlag(toUnsignedInt(getBits(101 + shift, 1)));
30 | // m.setTransmissionInterval(toUnsignedInt(getBits(102 + shift, 16)));
31 | //
32 | // list[i] = m;
33 | // }
34 | //
35 | // }
36 | //
37 | // public int getMessageNumber() {
38 | // return messageNumber;
39 | // }
40 | //
41 | // public int getStationID() {
42 | // return stationID;
43 | // }
44 | //
45 | // public int getMJD() {
46 | // return MJD;
47 | // }
48 | //
49 | // public int getUTC() {
50 | // return UTC;
51 | // }
52 | //
53 | // public int getLeapSeconds() {
54 | // return LeapSeconds;
55 | // }
56 | //
57 | // public Message[] getList() {
58 | // return list;
59 | // }
60 | //
61 | // public class Message {
62 | // private int MessageID;
63 | // private int SyncFlag;
64 | // private int TransmissionInterval;
65 | //
66 | // public int getMessageID() {
67 | // return MessageID;
68 | // }
69 | //
70 | // public void setMessageID(int messageID) {
71 | // MessageID = messageID;
72 | // }
73 | //
74 | // public int getSyncFlag() {
75 | // return SyncFlag;
76 | // }
77 | //
78 | // public void setSyncFlag(int syncFlag) {
79 | // SyncFlag = syncFlag;
80 | // }
81 | //
82 | // public int getTransmissionInterval() {
83 | // return TransmissionInterval;
84 | // }
85 | //
86 | // public void setTransmissionInterval(int transmissionInterval) {
87 | // TransmissionInterval = transmissionInterval;
88 | // }
89 | //
90 | // }
91 | //}
92 | //
93 | //
94 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/core/stationsServer/handlers/Rtcm3InboundHandler.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.core.stationsServer.handlers;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.SimpleChannelInboundHandler;
5 | import org.dav95s.openNTRIP.commons.Message;
6 | import org.dav95s.openNTRIP.commons.Registry;
7 | import org.dav95s.openNTRIP.core.ChannelState;
8 | import org.dav95s.openNTRIP.core.stationsServer.ReferenceStationChannelMatcher;
9 | import org.dav95s.openNTRIP.database.modelsV2.NetworkModel;
10 | import org.dav95s.openNTRIP.database.modelsV2.ReferenceStationModel;
11 | import org.dav95s.openNTRIP.protocols.rtcm.Rtcm3Separator;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 |
15 | import java.util.ArrayList;
16 |
17 | public class Rtcm3InboundHandler extends SimpleChannelInboundHandler {
18 | private final static Logger logger = LoggerFactory.getLogger(Rtcm3InboundHandler.class.getName());
19 |
20 | private final Registry registry;
21 | private final ReferenceStationModel model;
22 | private final ReferenceStationChannelMatcher channelMatcher;
23 | private final Rtcm3Separator separator = new Rtcm3Separator();
24 |
25 | public Rtcm3InboundHandler(Registry registry, ReferenceStationModel model) {
26 | this.model = model;
27 | this.registry = registry;
28 | this.channelMatcher = new ReferenceStationChannelMatcher(model.name);
29 | }
30 |
31 | int totalLengthBytes = 0;
32 | int totalLengthMessages = 0;
33 |
34 | @Override
35 | protected void channelRead0(ChannelHandlerContext ctx, byte[] bytes) throws Exception {
36 | ReferenceStationModel referenceStationModel = ctx.channel().attr(ChannelState.REFERENCE_STATION_MODEL).get();
37 |
38 | ArrayList messages = separator.separate(bytes);
39 |
40 | totalLengthBytes += bytes.length;
41 | for (Message msg : messages) {
42 | totalLengthMessages += msg.bytes.length;
43 | }
44 |
45 | logger.debug("Station: " + model.name + " accept " + bytes.length + " bytes, " + " messages " + messages.size());
46 | logger.debug("Station: " + model.name + " total bytes accepted " + totalLengthBytes + " total parser to " + totalLengthMessages);
47 |
48 | for (String network : referenceStationModel.networks) {
49 | NetworkModel networkModel = registry.networks.get(network);
50 | if (networkModel == null) {
51 | logger.warn("Reference station " + model.name + " has undefined network");
52 | continue;
53 | }
54 | networkModel.write(messages, channelMatcher);
55 | }
56 | registry.networks.get(referenceStationModel.name).write(messages, channelMatcher);
57 | }
58 |
59 | @Override
60 | public void channelInactive(ChannelHandlerContext ctx) throws Exception {
61 | //registry.removeReferenceStation(ctx.channel().attr(ChannelState.REFERENCE_STATION).get());
62 | super.channelInactive(ctx);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/core/userServer/handlers/authentication/NtripBasicAuthHandler.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.core.userServer.handlers.authentication;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.SimpleChannelInboundHandler;
5 | import io.netty.handler.codec.http.FullHttpRequest;
6 | import org.dav95s.openNTRIP.commons.Registry;
7 | import org.dav95s.openNTRIP.core.ChannelState;
8 | import org.dav95s.openNTRIP.database.modelsV2.NetworkModel;
9 | import org.dav95s.openNTRIP.database.modelsV2.UserModel;
10 | import org.dav95s.openNTRIP.database.repository.UserRepository;
11 | import org.dav95s.openNTRIP.exception.UserAuthorizationException;
12 | import org.dav95s.openNTRIP.protocols.ntrip.NtripResponse;
13 | import org.dav95s.openNTRIP.users.passwords.BCrypt;
14 | import org.dav95s.openNTRIP.utils.BasicAuthParser;
15 | import org.slf4j.Logger;
16 | import org.slf4j.LoggerFactory;
17 |
18 | public class NtripBasicAuthHandler extends SimpleChannelInboundHandler {
19 | private final static Logger logger = LoggerFactory.getLogger(NtripBasicAuthHandler.class.getName());
20 |
21 | private final Registry registry;
22 | private final UserRepository userRepository;
23 |
24 | public NtripBasicAuthHandler(Registry registry, UserRepository userRepository) {
25 | this.registry = registry;
26 | this.userRepository = userRepository;
27 | }
28 |
29 | @Override
30 | protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
31 |
32 | String authorizationString = msg.headers().get("Authorization");
33 |
34 | BasicAuthParser parser = new BasicAuthParser(authorizationString);
35 |
36 | UserModel userModel = userRepository.getUserByUsername(parser.account);
37 |
38 | if (userModel == null) {
39 | throw new UserAuthorizationException("Bad password!");
40 | }
41 |
42 | BCrypt bCrypt = new BCrypt();
43 |
44 | if (bCrypt.compare(userModel.password, parser.password)) {
45 | ctx.writeAndFlush(NtripResponse.OK_MESSAGE);
46 |
47 | String networkName = ctx.channel().attr(ChannelState.NETWORK).get();
48 | NetworkModel networkModel = registry.networks.get(networkName);
49 | networkModel.channelGroup.add(ctx.channel());
50 |
51 | ctx.channel().attr(ChannelState.AUTHENTICATION).set(true);
52 | }else {
53 | ctx.channel().attr(ChannelState.AUTHENTICATION).set(false);
54 | }
55 |
56 | }
57 |
58 | @Override
59 | public void channelReadComplete(ChannelHandlerContext ctx) {
60 | ctx.flush();
61 | }
62 |
63 | @Override
64 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
65 | if (cause instanceof UserAuthorizationException) {
66 | logger.info("Channel ID:" + ctx.channel().id() + " " + cause.getMessage(), cause);
67 | ctx.writeAndFlush(NtripResponse.BAD_PASSWORD);
68 | ctx.close();
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/test/java/org/dav95s/openNTRIP/protocols/rtcm/MSG1021Test.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm;
2 |
3 | import org.dav95s.openNTRIP.commons.Message;
4 | import org.dav95s.openNTRIP.protocols.rtcm.messages.MSG1021;
5 | import org.junit.Assert;
6 | import org.junit.Test;
7 |
8 | import java.io.FileInputStream;
9 | import java.io.IOException;
10 | import java.util.ArrayList;
11 | import java.util.List;
12 | import java.util.stream.Collectors;
13 |
14 |
15 | public class MSG1021Test {
16 | @Test
17 | public void msg1021MaxValues() {
18 | MSG1021 msg1021Max = new MSG1021();
19 | msg1021Max.setMessageNumber(1021);
20 | msg1021Max.setSourceName("0123456789012345678901234567891");
21 | msg1021Max.setTargetName("0123456789012345678901234567891");
22 | msg1021Max.setSystemIdentificationNumber(255);
23 | msg1021Max.setUtilizedTransformationMessageIndicator(10);
24 | msg1021Max.setPlateNumber(31);
25 | msg1021Max.setComputationIndicator(15);
26 | msg1021Max.setHeightIndicator(3);
27 | msg1021Max.setLatValid(90);
28 | msg1021Max.setLonValid(180);
29 | msg1021Max.setdLatValid(9.1);
30 | msg1021Max.setdLonValid(9.1);
31 | msg1021Max.setdX(4194.303);
32 | msg1021Max.setdY(4194.303);
33 | msg1021Max.setdZ(4194.303);
34 | msg1021Max.setRx(42949.67291);
35 | msg1021Max.setRy(42949.67291);
36 | msg1021Max.setRz(42949.67291);
37 | msg1021Max.setdS(167.77215);
38 | msg1021Max.setAs(6386777.215);
39 | msg1021Max.setBs(6383554.431);
40 | msg1021Max.setAt(6386777.215);
41 | msg1021Max.setBt(6383554.431);
42 | msg1021Max.setHorizontalQuality(7);
43 | msg1021Max.setVerticalQuality(7);
44 |
45 | byte[] check1 = msg1021Max.getBytes();
46 | MSG1021 msg10212 = new MSG1021(check1);
47 | byte[] check2 = msg10212.getBytes();
48 |
49 | Assert.assertArrayEquals(check1, check2);
50 | }
51 |
52 | @Test
53 | public void decoderEncode() {
54 | String file = "src/test/resources/1021.rtcm3";
55 | try (FileInputStream input = new FileInputStream(file)) {
56 | byte[] bytes = input.readAllBytes();
57 | Rtcm3Separator separator = new Rtcm3Separator();
58 | ArrayList separate = separator.separate(bytes);
59 |
60 | List collect1021 = separate.stream().filter(msg -> msg.name.equals("1021")).collect(Collectors.toList());
61 | Assert.assertTrue(collect1021.size() > 0);
62 |
63 | for (Message msg1021 : collect1021){
64 | MSG1021 msg1 = new MSG1021(msg1021.bytes);
65 | byte[] bytes1 = msg1.getBytes();
66 | MSG1021 msg2 = new MSG1021(bytes1);
67 | byte[] bytes2 = msg2.getBytes();
68 | Assert.assertArrayEquals(msg1021.bytes, bytes1);
69 | Assert.assertArrayEquals(msg1021.bytes, bytes2);
70 | }
71 | } catch (IOException e) {
72 | e.printStackTrace();
73 | }
74 | }
75 |
76 | }
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/Rtcm3Separator.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm;
2 |
3 | import org.dav95s.openNTRIP.commons.Message;
4 | import org.dav95s.openNTRIP.utils.binaryParse.Crc24q;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | import java.util.ArrayList;
9 | import java.util.Arrays;
10 | import java.util.HashSet;
11 |
12 | public class Rtcm3Separator {
13 | static final private Logger logger = LoggerFactory.getLogger(Rtcm3Separator.class.getName());
14 |
15 | private static final HashSet rtcm3messages = null;
16 | private final byte PREAMBLE = -45;
17 |
18 | private byte[] tail = null; //residual of the previous message
19 |
20 | public ArrayList separate(byte[] bytes) {
21 | ArrayList messages = new ArrayList<>();
22 |
23 | if (bytes == null || bytes.length == 0) {
24 | return messages;
25 | }
26 |
27 | if (tail == null) {
28 | if (bytes[0] == PREAMBLE)
29 | return parse(bytes, messages);
30 | } else {
31 | //Concatenation new message with residual of the previous message
32 | byte[] newBytes = new byte[tail.length + bytes.length];
33 | System.arraycopy(tail, 0, newBytes, 0, tail.length);
34 | System.arraycopy(bytes, 0, newBytes, tail.length, bytes.length);
35 | tail = null;
36 | return parse(newBytes, messages);
37 | }
38 |
39 | return messages;
40 | }
41 |
42 | private ArrayList parse(byte[] bytes, ArrayList messages) {
43 | for (int i = 0; i < bytes.length; i++) {
44 | if (bytes[i] != PREAMBLE) {
45 | continue;
46 | }
47 |
48 | try {
49 | short length = (short) (((bytes[i + 1] & 0xFF) << 8) | (bytes[i + 2] & 0xFF));
50 | short msgNumb = (short) (((bytes[i + 3] & 0xFF) << 8) | (bytes[i + 4] & 0xFF));
51 | length = (short) (length & 0x3FF); //cut off reserved bits
52 | msgNumb = (short) (msgNumb >> 4);
53 |
54 |
55 |
56 | if (checkExistsMessageNumber(msgNumb)) {
57 | byte[] msg = new byte[length + 6];
58 | System.arraycopy(bytes, i, msg, 0, length + 6);
59 | messages.add(new Message(msgNumb, msg));
60 | i = i + length + 5; //in the next cycle i will be incremented
61 | }
62 |
63 | } catch (IndexOutOfBoundsException e) {
64 | this.tail = Arrays.copyOfRange(bytes, i, bytes.length);
65 | break;
66 | }
67 | }
68 | return messages;
69 | }
70 |
71 |
72 | protected boolean checkCrs(byte[] bytes) {
73 | byte[] crs = Crc24q.crc24q(bytes, bytes.length - 3, 0);
74 | return Arrays.equals(bytes, bytes.length - 3, bytes.length - 1, crs, 0, 2);
75 | }
76 |
77 | protected boolean checkExistsMessageNumber(int nmb) {
78 | return (1001 <= nmb && nmb <= 1039) || (1057 <= nmb && nmb <= 1068)
79 | || (1070 <= nmb && nmb <= 1230) || (4001 <= nmb && nmb <= 4095);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/utils/ServerProperties.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.utils;
2 |
3 | import java.io.InputStream;
4 | import java.nio.file.Files;
5 | import java.nio.file.Path;
6 | import java.nio.file.Paths;
7 | import java.util.Properties;
8 |
9 | public class ServerProperties extends Properties {
10 | public ServerProperties() {
11 | initProperties(Config.SERVER_PROPERTIES_FILENAME);
12 | }
13 |
14 | public ServerProperties(String propertiesFileName) {
15 | initProperties(propertiesFileName);
16 | }
17 |
18 | public ServerProperties(Path propertiesFileNamePath) {
19 | initProperties(propertiesFileNamePath);
20 | }
21 |
22 | private static Path getFileInCurrentDir(String filename) {
23 | return Paths.get(System.getProperty("user.dir"), filename);
24 | }
25 |
26 | public static Path getCurrentDir() {
27 | return Paths.get(System.getProperty("user.dir"));
28 | }
29 |
30 | /**
31 | * First loads properties file from class path after that from current folder.
32 | * So properties file in current folder is always overrides properties in classpath.
33 | *
34 | * @param filePropertiesName - name of properties file, for example "twitter4j.properties"
35 | */
36 | private void initProperties(String filePropertiesName) {
37 | if (!filePropertiesName.startsWith("/")) {
38 | filePropertiesName = "/" + filePropertiesName;
39 | }
40 |
41 | try (InputStream classPath = ServerProperties.class.getResourceAsStream(filePropertiesName)) {
42 | if (classPath != null) {
43 | load(classPath);
44 | }
45 | } catch (Exception e) {
46 | throw new RuntimeException("Error getting properties file : " + filePropertiesName, e);
47 | }
48 |
49 | Path curDirPath = getFileInCurrentDir(filePropertiesName);
50 | if (Files.exists(curDirPath)) {
51 | try (InputStream curFolder = Files.newInputStream(curDirPath)) {
52 | load(curFolder);
53 | } catch (Exception e) {
54 | throw new RuntimeException("Error getting properties file : " + filePropertiesName, e);
55 | }
56 | }
57 |
58 | }
59 |
60 | private void initProperties(Path path) {
61 | if (Files.exists(path)) {
62 | try (InputStream curFolder = Files.newInputStream(path)) {
63 | load(curFolder);
64 | } catch (Exception e) {
65 | throw new RuntimeException("Error getting properties file : " + path, e);
66 | }
67 | }
68 | }
69 |
70 | public int getIntProperty(String propertyName) {
71 | return ParseUtil.parseInt(getProperty(propertyName));
72 | }
73 |
74 | public int getIntProperty(String propertyName, int defaultValue) {
75 | if (getProperty(propertyName) == null || "".equals(getProperty(propertyName))) {
76 | return defaultValue;
77 | }
78 | return ParseUtil.parseInt(getProperty(propertyName));
79 | }
80 |
81 | public boolean getBoolProperty(String propertyName) {
82 | return Boolean.parseBoolean(getProperty(propertyName));
83 | }
84 |
85 | public long getLongProperty(String propertyName) {
86 | return ParseUtil.parseLong(getProperty(propertyName));
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/repository/ReferenceStationRepository.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database.repository;
2 |
3 | import org.dav95s.openNTRIP.database.DataSource;
4 | import org.dav95s.openNTRIP.database.modelsV2.ReferenceStationModel;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | import java.sql.Connection;
9 | import java.sql.PreparedStatement;
10 | import java.sql.ResultSet;
11 | import java.sql.SQLException;
12 | import java.util.ArrayList;
13 |
14 | public class ReferenceStationRepository {
15 | final static private Logger logger = LoggerFactory.getLogger(ReferenceStationRepository.class.getName());
16 |
17 | public ReferenceStationModel GetReferenceStationByName(String name) {
18 | String sql = "SELECT `id`, `name`, `format`, `country`, `lat`, `lon`, `alt`, `password`, `hz`, " +
19 | "(SELECT GROUP_CONCAT(network_name) FROM network_stations_mapping WHERE station_name = NAME) AS networks " +
20 | "FROM `reference_stations` " +
21 | "WHERE `name` = ?";
22 |
23 | try (Connection con = DataSource.getConnection();
24 | PreparedStatement statement = con.prepareStatement(sql)) {
25 |
26 | statement.setString(1, name);
27 |
28 | try (ResultSet rs = statement.executeQuery()) {
29 | if (rs.next()) {
30 | return new ReferenceStationModel(
31 | rs.getInt("id"),
32 | rs.getString("name"),
33 | rs.getString("format"),
34 | rs.getDouble("lat"),
35 | rs.getDouble("lon"),
36 | rs.getDouble("alt"),
37 | rs.getString("password"),
38 | rs.getInt("hz"),
39 | rs.getString("networks").split(",")
40 | );
41 | } else {
42 | return null;
43 | }
44 | }
45 | } catch (SQLException e) {
46 | logger.error("SQL Error", e);
47 | return null;
48 | }
49 | }
50 |
51 | public ArrayList GetNetworksByReferenceStation(String name) {
52 | String sql = "SELECT `network_name` FROM `network_stations_mapping` WHERE station_name = ?";
53 |
54 | ArrayList networks = new ArrayList<>();
55 |
56 | try (Connection con = DataSource.getConnection();
57 | PreparedStatement statement = con.prepareStatement(sql)) {
58 |
59 | statement.setString(1, name);
60 |
61 | try (ResultSet rs = statement.executeQuery()) {
62 | while (rs.next()) {
63 | networks.add(rs.getString("network_name"));
64 | }
65 | }
66 | } catch (SQLException e) {
67 | logger.error("SQL Error", e);
68 | return null;
69 | }
70 | return networks;
71 | }
72 |
73 | public boolean updateOnlineStatus(String name, boolean status) {
74 | String sql = "UPDATE `reference_stations` SET `is_online` = ? WHERE `name` = ?";
75 |
76 |
77 | try (Connection con = DataSource.getConnection();
78 | PreparedStatement statement = con.prepareStatement(sql)) {
79 |
80 | statement.setBoolean(1, status);
81 | statement.setString(2, name);
82 |
83 | return statement.executeUpdate() > 0;
84 |
85 | } catch (SQLException e) {
86 | logger.error("SQL Error", e);
87 | return false;
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/utils/binaryParse/Crc24q.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.utils.binaryParse;
2 |
3 | public class Crc24q {
4 | private static final int[] crc24 = new int[]{
5 | 0x000000, 0x864CFB, 0x8AD50D, 0x0C99F6, 0x93E6E1, 0x15AA1A, 0x1933EC, 0x9F7F17,
6 | 0xA18139, 0x27CDC2, 0x2B5434, 0xAD18CF, 0x3267D8, 0xB42B23, 0xB8B2D5, 0x3EFE2E,
7 | 0xC54E89, 0x430272, 0x4F9B84, 0xC9D77F, 0x56A868, 0xD0E493, 0xDC7D65, 0x5A319E,
8 | 0x64CFB0, 0xE2834B, 0xEE1ABD, 0x685646, 0xF72951, 0x7165AA, 0x7DFC5C, 0xFBB0A7,
9 | 0x0CD1E9, 0x8A9D12, 0x8604E4, 0x00481F, 0x9F3708, 0x197BF3, 0x15E205, 0x93AEFE,
10 | 0xAD50D0, 0x2B1C2B, 0x2785DD, 0xA1C926, 0x3EB631, 0xB8FACA, 0xB4633C, 0x322FC7,
11 | 0xC99F60, 0x4FD39B, 0x434A6D, 0xC50696, 0x5A7981, 0xDC357A, 0xD0AC8C, 0x56E077,
12 | 0x681E59, 0xEE52A2, 0xE2CB54, 0x6487AF, 0xFBF8B8, 0x7DB443, 0x712DB5, 0xF7614E,
13 | 0x19A3D2, 0x9FEF29, 0x9376DF, 0x153A24, 0x8A4533, 0x0C09C8, 0x00903E, 0x86DCC5,
14 | 0xB822EB, 0x3E6E10, 0x32F7E6, 0xB4BB1D, 0x2BC40A, 0xAD88F1, 0xA11107, 0x275DFC,
15 | 0xDCED5B, 0x5AA1A0, 0x563856, 0xD074AD, 0x4F0BBA, 0xC94741, 0xC5DEB7, 0x43924C,
16 | 0x7D6C62, 0xFB2099, 0xF7B96F, 0x71F594, 0xEE8A83, 0x68C678, 0x645F8E, 0xE21375,
17 | 0x15723B, 0x933EC0, 0x9FA736, 0x19EBCD, 0x8694DA, 0x00D821, 0x0C41D7, 0x8A0D2C,
18 | 0xB4F302, 0x32BFF9, 0x3E260F, 0xB86AF4, 0x2715E3, 0xA15918, 0xADC0EE, 0x2B8C15,
19 | 0xD03CB2, 0x567049, 0x5AE9BF, 0xDCA544, 0x43DA53, 0xC596A8, 0xC90F5E, 0x4F43A5,
20 | 0x71BD8B, 0xF7F170, 0xFB6886, 0x7D247D, 0xE25B6A, 0x641791, 0x688E67, 0xEEC29C,
21 | 0x3347A4, 0xB50B5F, 0xB992A9, 0x3FDE52, 0xA0A145, 0x26EDBE, 0x2A7448, 0xAC38B3,
22 | 0x92C69D, 0x148A66, 0x181390, 0x9E5F6B, 0x01207C, 0x876C87, 0x8BF571, 0x0DB98A,
23 | 0xF6092D, 0x7045D6, 0x7CDC20, 0xFA90DB, 0x65EFCC, 0xE3A337, 0xEF3AC1, 0x69763A,
24 | 0x578814, 0xD1C4EF, 0xDD5D19, 0x5B11E2, 0xC46EF5, 0x42220E, 0x4EBBF8, 0xC8F703,
25 | 0x3F964D, 0xB9DAB6, 0xB54340, 0x330FBB, 0xAC70AC, 0x2A3C57, 0x26A5A1, 0xA0E95A,
26 | 0x9E1774, 0x185B8F, 0x14C279, 0x928E82, 0x0DF195, 0x8BBD6E, 0x872498, 0x016863,
27 | 0xFAD8C4, 0x7C943F, 0x700DC9, 0xF64132, 0x693E25, 0xEF72DE, 0xE3EB28, 0x65A7D3,
28 | 0x5B59FD, 0xDD1506, 0xD18CF0, 0x57C00B, 0xC8BF1C, 0x4EF3E7, 0x426A11, 0xC426EA,
29 | 0x2AE476, 0xACA88D, 0xA0317B, 0x267D80, 0xB90297, 0x3F4E6C, 0x33D79A, 0xB59B61,
30 | 0x8B654F, 0x0D29B4, 0x01B042, 0x87FCB9, 0x1883AE, 0x9ECF55, 0x9256A3, 0x141A58,
31 | 0xEFAAFF, 0x69E604, 0x657FF2, 0xE33309, 0x7C4C1E, 0xFA00E5, 0xF69913, 0x70D5E8,
32 | 0x4E2BC6, 0xC8673D, 0xC4FECB, 0x42B230, 0xDDCD27, 0x5B81DC, 0x57182A, 0xD154D1,
33 | 0x26359F, 0xA07964, 0xACE092, 0x2AAC69, 0xB5D37E, 0x339F85, 0x3F0673, 0xB94A88,
34 | 0x87B4A6, 0x01F85D, 0x0D61AB, 0x8B2D50, 0x145247, 0x921EBC, 0x9E874A, 0x18CBB1,
35 | 0xE37B16, 0x6537ED, 0x69AE1B, 0xEFE2E0, 0x709DF7, 0xF6D10C, 0xFA48FA, 0x7C0401,
36 | 0x42FA2F, 0xC4B6D4, 0xC82F22, 0x4E63D9, 0xD11CCE, 0x575035, 0x5BC9C3, 0xDD8538};
37 |
38 | public static byte[] crc24q(byte[] buf, int len, int crc) {
39 | for (int i = 0; i < len; i++) {
40 | crc = ((crc << 8) & 0xFFFFFF) ^ crc24[(crc >> 16) ^ (buf[i] & 0xFF)];
41 | }
42 | byte[] result = new byte[3];
43 |
44 | result[0] = (byte) (crc >> 16);
45 | result[1] = (byte) (crc >> 8);
46 | result[2] = (byte) (crc);
47 |
48 | return result;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/messages/MSG1017.java:
--------------------------------------------------------------------------------
1 | //package org.dav95s.openNTRIP.Tools.RTCM;
2 | //
3 | //public class MSG1017 extends RTCM {
4 | // private int messageNumber;
5 | // private int NetworkID;
6 | // private int SubnetworkID;
7 | // private int TOW; //GPS Epoch Time (GPS TOW)
8 | // private boolean MultipleMessageIndicator;
9 | // private int MasterStationID;
10 | // private int AuxiliaryStationID;
11 | //
12 | // private GPS[] list;
13 | //
14 | //
15 | // public MSG1017(byte[] msg) {
16 | // super.rawMsg = msg;
17 | // super.setToBinaryBuffer(msg);
18 | //
19 | // messageNumber = toUnsignedInt(getBits(16, 12));
20 | // NetworkID = toUnsignedInt(getBits(28, 8));
21 | // SubnetworkID = toUnsignedInt(getBits(36, 4));
22 | // TOW = toUnsignedInt(getBits(40, 23));
23 | // MultipleMessageIndicator = binaryBuffer.charAt(63) == BIT1;
24 | // MasterStationID = toUnsignedInt(getBits(64, 12));
25 | // AuxiliaryStationID = toUnsignedInt(getBits(76, 12));
26 | // int gpsCounter = toUnsignedInt(getBits(88, 4));
27 | // for (int i = 0; i < gpsCounter; i++) {
28 | // int shift = i * 53;
29 | // GPS g = new GPS();
30 | //
31 | // g.setID(toUnsignedInt(getBits(92, 6)));
32 | // g.setAmbiguityStatusFlag(toUnsignedInt(getBits(98, 2)));
33 | // g.setNonSyncCount(toUnsignedInt(getBits(100, 3)));
34 | // g.setGeometricCarrierPhaseCorrectionDifference(toUnsignedInt(getBits(103, 17)));
35 | // g.setIODE(toUnsignedInt(getBits(120, 8)));
36 | // g.setIonosphericCarrierPhaseCorrectionDifference(toSignedInt(getBits(128, 17)));
37 | //
38 | // }
39 | // }
40 | //
41 | // public class GPS {
42 | // private int ID;
43 | // private int AmbiguityStatusFlag;
44 | // private int NonSyncCount;
45 | // private int GeometricCarrierPhaseCorrectionDifference;
46 | // private int IODE;
47 | // private int IonosphericCarrierPhaseCorrectionDifference;
48 | //
49 | // public int getID() {
50 | // return ID;
51 | // }
52 | //
53 | // public void setID(int ID) {
54 | // this.ID = ID;
55 | // }
56 | //
57 | // public int getAmbiguityStatusFlag() {
58 | // return AmbiguityStatusFlag;
59 | // }
60 | //
61 | // public void setAmbiguityStatusFlag(int ambiguityStatusFlag) {
62 | // AmbiguityStatusFlag = ambiguityStatusFlag;
63 | // }
64 | //
65 | // public int getNonSyncCount() {
66 | // return NonSyncCount;
67 | // }
68 | //
69 | // public void setNonSyncCount(int nonSyncCount) {
70 | // NonSyncCount = nonSyncCount;
71 | // }
72 | //
73 | // public int getGeometricCarrierPhaseCorrectionDifference() {
74 | // return GeometricCarrierPhaseCorrectionDifference;
75 | // }
76 | //
77 | // public void setGeometricCarrierPhaseCorrectionDifference(int geometricCarrierPhaseCorrectionDifference) {
78 | // GeometricCarrierPhaseCorrectionDifference = geometricCarrierPhaseCorrectionDifference;
79 | // }
80 | //
81 | // public int getIODE() {
82 | // return IODE;
83 | // }
84 | //
85 | // public void setIODE(int IODE) {
86 | // this.IODE = IODE;
87 | // }
88 | //
89 | // public int getIonosphericCarrierPhaseCorrectionDifference() {
90 | // return IonosphericCarrierPhaseCorrectionDifference;
91 | // }
92 | //
93 | // public void setIonosphericCarrierPhaseCorrectionDifference(int ionosphericCarrierPhaseCorrectionDifference) {
94 | // IonosphericCarrierPhaseCorrectionDifference = ionosphericCarrierPhaseCorrectionDifference;
95 | // }
96 | // }
97 | //}
98 |
--------------------------------------------------------------------------------
/src/main/resources/app.properties:
--------------------------------------------------------------------------------
1 | #station plain tcp/ip port
2 | station.default.port=8442
3 |
4 | #ntrip plain tcp/ip port
5 | ntrip.default.port=8443
6 |
7 | #by default server uses embedded in jar cert to simplify local server installation.
8 | #WARNNING DO NOT USE THIS CERTIFICATES ON PRODUCTION OR IN WHERE ENVIRNOMENTS REAL SECURITY REQUIRED.
9 | #provide either full path to files either use '.' for specifying current directory. For instance "./myfile.crt"
10 | server.ssl.cert=
11 | server.ssl.key=
12 | server.ssl.key.pass=
13 | client.ssl.cert=
14 | client.ssl.key=
15 |
16 | #by default System.getProperty("java.io.tmpdir")/blynk used
17 | data.folder=
18 |
19 | #folder for logs.
20 | logs.folder=./logs
21 |
22 | #log debug level. trace|debug|info|error. Defines how precise logging will be.
23 | log.level=trace
24 |
25 | #defines maximum allowed number of user dashboards. Needed to limit possible number of tokens.
26 | user.dashboard.max.limit=10
27 |
28 | #user is limited with 100 messages per second.
29 | user.message.quota.limit=100
30 | #in case of consistent quota limit exceed during long term, sending warning response back to exceeding channel
31 | #for performance reason sending only 1 message within interval. In millis
32 | user.message.quota.limit.exceeded.warning.period=60000
33 |
34 | #maximum allowed number of notification queue. Queue responsible for processing email, pushes, twits sending.
35 | #Because of performance issue - those queue is processed in separate thread, this is required due
36 | #to blocking nature of all above operations. Usually limit shouldn't be reached.
37 | notifications.queue.limit=10000
38 |
39 | #todo finish
40 | #this setting defines how often we can send mail/tweet/push or any other notification. Specified in seconds
41 | notifications.frequency.user.quota.limit=60
42 |
43 | #maximum size of user profile in kb's
44 | user.profile.max.size=128
45 |
46 | #in memory storage limit for storing *read* values from hardware
47 | user.in.memory.storage.limit=1000
48 |
49 | #period in millis for saving all user DB to disk.
50 | profile.save.worker.period=60000
51 |
52 | #period in millis for saving stats to disk.
53 | stats.print.worker.period=60000
54 |
55 | #@
56 | #specifies maximum period of time when application socket could be idle. After which
57 | #socket will be closed due to non activity. In seconds. Default value 600 if not provided.
58 | #leave it empty for infinity timeout
59 | app.socket.idle.timeout=600
60 | #specifies maximum period of time when hardware socket could be idle. After which
61 | #socket will be closed due to non activity. In seconds. Default value 15 if not provided.
62 | #leave it empty for infinity timeout
63 | station.socket.idle.timeout=15
64 |
65 | #Enables native socket transport for Linux using JNI. Should be turned on only if you 100% sure.
66 | #may not work on some environments. Used to increase server performance. Performance boost is ~20-40%.
67 | enable.native.epoll.transport=false
68 |
69 | #Enabled native openSSL support for SSL handlers. Should be turned on only if you 100% sure.
70 | #may not work on some environments. Used to increase server performance. Performance boost is ~16%.
71 | #For more details see - http://netty.io/wiki/forked-tomcat-native.html
72 | enable.native.openssl=false
73 |
74 | #mostly required for local servers setup in case user want to log raw data in CSV format
75 | #from his hardware
76 | enable.raw.data.store=true
77 |
78 | #size of async logger ring buffer. should be increased for loads >2-3k req/sec
79 | async.logger.ring.buffer.size=8192
80 |
81 |
82 | #ADMINISTRATION SECTION
83 |
84 | #admin monitoring port.
85 | server.admin.port=8777
86 |
87 | #comma separated list of users allowed to create accounts. leave it empty if no restriction required.
88 | allowed.users.list=
89 | #
90 | passwordHashAlgorithm=BCrypt
91 | # Default email domain for new users
92 |
93 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/core/userServer/handlers/UserAuthHandler.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.core.userServer.handlers;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 | import io.netty.channel.SimpleChannelInboundHandler;
6 | import io.netty.handler.codec.http.FullHttpRequest;
7 | import io.netty.handler.codec.http.HttpMethod;
8 | import org.dav95s.openNTRIP.commons.Registry;
9 | import org.dav95s.openNTRIP.core.ChannelState;
10 | import org.dav95s.openNTRIP.core.userServer.handlers.authentication.NtripBasicAuthHandler;
11 | import org.dav95s.openNTRIP.core.userServer.handlers.authentication.NtripNoneAuthHandler;
12 | import org.dav95s.openNTRIP.database.models.SourceTableModel;
13 | import org.dav95s.openNTRIP.database.modelsV2.MountpointModel;
14 | import org.dav95s.openNTRIP.database.repository.MountpointRepository;
15 | import org.dav95s.openNTRIP.database.repository.UserRepository;
16 | import org.dav95s.openNTRIP.exception.MountpointNotFound;
17 | import org.slf4j.Logger;
18 | import org.slf4j.LoggerFactory;
19 |
20 | import java.nio.charset.StandardCharsets;
21 |
22 | public class UserAuthHandler extends ChannelInboundHandlerAdapter {
23 | private final static Logger logger = LoggerFactory.getLogger(UserAuthHandler.class.getName());
24 |
25 | private final MountpointRepository mountpointRepository;
26 | private final UserRepository userRepository;
27 | private final Registry registry;
28 |
29 | public UserAuthHandler(Registry registry, MountpointRepository mountpointRepository, UserRepository userRepository) {
30 | this.mountpointRepository = mountpointRepository;
31 | this.userRepository = userRepository;
32 | this.registry = registry;
33 | }
34 |
35 | @Override
36 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
37 | assert msg instanceof FullHttpRequest;
38 |
39 | FullHttpRequest message = (FullHttpRequest) msg;
40 |
41 | if (message.method() != HttpMethod.GET) {
42 | throw new IllegalArgumentException("Only GET messages");
43 | }
44 |
45 | String request = message.uri().substring(1);
46 |
47 | MountpointModel mountpoint = mountpointRepository.getMountpoint(request);
48 |
49 | if (mountpoint == null) {
50 | throw new MountpointNotFound(request + " Requested reference station not exists!");
51 | }
52 |
53 | ctx.channel().attr(ChannelState.MOUNTPOINT).set(mountpoint);
54 | ctx.channel().attr(ChannelState.NETWORK).set(mountpoint.network);
55 |
56 | ctx.channel().pipeline().remove(this);
57 |
58 | switch (mountpoint.authenticator) {
59 | case Digest:
60 | logger.warn("Digest authentication not supported!");
61 | ctx.close();
62 | break;
63 |
64 | case Basic:
65 | SimpleChannelInboundHandler authHandler = new NtripBasicAuthHandler(registry, userRepository);
66 | authHandler.channelRead(ctx, msg);
67 | break;
68 |
69 | case None:
70 | ctx.pipeline().addLast(new NtripNoneAuthHandler(registry));
71 | break;
72 | }
73 | }
74 |
75 |
76 | @Override
77 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
78 | if (cause instanceof IllegalArgumentException) {
79 | logger.info("Channel ID:" + ctx.channel().id() + " " + cause.getMessage(), cause);
80 | ctx.close();
81 | } else if (cause instanceof MountpointNotFound) {
82 | logger.info("Channel ID:" + ctx.channel().id() + " " + cause.getMessage(), cause);
83 | sendSourceTable(ctx);
84 | }
85 |
86 | }
87 |
88 | private void sendSourceTable(ChannelHandlerContext ctx) {
89 | SourceTableModel sourceTableModel = new SourceTableModel();
90 | ctx.writeAndFlush(sourceTableModel.getSourcetable().getBytes(StandardCharsets.US_ASCII));
91 | ctx.close();
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.dav95s
8 | openNTRIP
9 | 1.0-SNAPSHOT
10 |
11 | jar
12 |
13 |
14 |
15 |
16 | org.apache.maven.plugins
17 | maven-compiler-plugin
18 | 3.5.1
19 |
20 | 11
21 | 11
22 |
23 |
24 |
25 |
26 |
27 |
28 | UTF-8
29 | 11
30 | 11
31 |
32 |
33 |
34 |
35 |
36 | org.slf4j
37 | slf4j-api
38 | 1.7.30
39 |
40 |
41 |
42 | ch.qos.logback
43 | logback-core
44 | 1.2.3
45 |
46 |
47 |
48 | ch.qos.logback
49 | logback-classic
50 | 1.2.3
51 |
52 |
53 |
54 |
55 | mysql
56 | mysql-connector-java
57 | 8.0.19
58 |
59 |
60 |
61 |
62 | com.zaxxer
63 | HikariCP
64 | 3.4.3
65 |
66 |
67 |
68 |
69 | at.favre.lib
70 | bcrypt
71 | 0.9.0
72 |
73 |
74 |
75 |
76 | com.google.guava
77 | guava
78 | 30.1-jre
79 |
80 |
81 |
82 |
83 | org.json
84 | json
85 | 20210307
86 |
87 |
88 |
89 |
90 | io.netty
91 | netty-all
92 | 4.1.69.Final
93 |
94 |
95 |
96 | junit
97 | junit
98 | 4.13.2
99 | test
100 |
101 |
102 |
103 |
104 | com.harium
105 | kdtree
106 | 1.0.0
107 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/core/stationsServer/handlers/ReferenceStationAuthHandler.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.core.stationsServer.handlers;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.SimpleChannelInboundHandler;
5 | import org.dav95s.openNTRIP.commons.Registry;
6 | import org.dav95s.openNTRIP.core.ChannelState;
7 | import org.dav95s.openNTRIP.database.modelsV2.NetworkModel;
8 | import org.dav95s.openNTRIP.database.modelsV2.ReferenceStationModel;
9 | import org.dav95s.openNTRIP.database.repository.ReferenceStationRepository;
10 | import org.dav95s.openNTRIP.exception.ReferenceStationAuthorizationException;
11 | import org.dav95s.openNTRIP.protocols.ntrip.NtripResponse;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 |
15 | public class ReferenceStationAuthHandler extends SimpleChannelInboundHandler {
16 | private final static Logger logger = LoggerFactory.getLogger(ReferenceStationAuthHandler.class.getName());
17 |
18 | private final Registry registry;
19 | private final ReferenceStationRepository referenceStationRepository;
20 |
21 | public ReferenceStationAuthHandler(Registry registry, ReferenceStationRepository referenceStationRepository) {
22 | this.registry = registry;
23 | this.referenceStationRepository = referenceStationRepository;
24 | }
25 |
26 | @Override
27 | public void channelActive(ChannelHandlerContext ctx) throws Exception {
28 | logger.info("New inbound connect " + ctx.channel().remoteAddress() + " channelID:" + ctx.channel().id());
29 | super.channelActive(ctx);
30 | }
31 |
32 | @Override
33 | protected void channelRead0(ChannelHandlerContext ctx, byte[] msg) throws Exception {
34 | String message = new String(msg);
35 | String[] params = message.split("\r\n");
36 |
37 | if (params.length < 1)
38 | throw new IllegalArgumentException("Not valid request" + ctx.channel().remoteAddress());
39 |
40 | String[] authData = params[0].split(" ", 3);
41 |
42 | if (authData.length != 3 || !authData[0].equals("SOURCE")) {
43 | throw new IllegalArgumentException("Not valid request" + ctx.channel().remoteAddress());
44 | }
45 |
46 | String pass = authData[1];
47 | String name = authData[2];
48 |
49 | ReferenceStationModel model = referenceStationRepository.GetReferenceStationByName(name);
50 |
51 | if (model == null || !model.password.equals(pass)) {
52 | throw new ReferenceStationAuthorizationException("Reference station " + name + " is not exists or bad password " + ctx.channel().remoteAddress());
53 | }
54 |
55 | ctx.channel().attr(ChannelState.REFERENCE_STATION_MODEL).set(model);
56 |
57 | logger.info(model.name + ": Successful authorization " + ctx.channel().remoteAddress());
58 | ctx.writeAndFlush(NtripResponse.OK_MESSAGE);
59 | ctx.pipeline().remove("StationAuthHandler");
60 | ctx.pipeline().addLast("RtcmStreamHandler", new Rtcm3InboundHandler(registry, model));
61 |
62 | for (String network : model.networks) {
63 | NetworkModel networkModel = registry.networks.get(network);
64 | if (networkModel == null){
65 | logger.warn("Reference station " + model.name + " has undefined network");
66 | continue;
67 | }
68 | networkModel.channelGroup.add(ctx.channel());
69 | }
70 |
71 | registry.networks.get(model.name).channelGroup.add(ctx.channel());
72 | }
73 |
74 | @Override
75 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
76 | if (cause instanceof IllegalArgumentException) {
77 | logger.info("Channel ID:" + ctx.channel().id() + " " + cause.getMessage(), cause);
78 | ctx.writeAndFlush(NtripResponse.BAD_PASSWORD);
79 | } else if (cause instanceof ReferenceStationAuthorizationException) {
80 | logger.info("Reference station is not exists or bad password ");
81 | ctx.writeAndFlush(NtripResponse.BAD_PASSWORD);
82 | }
83 |
84 | ctx.close();
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/messages/MSG1001.java:
--------------------------------------------------------------------------------
1 | //package org.dav95s.openNTRIP.Tools.RTCM;
2 | //
3 | //import java.math.BigDecimal;
4 | //import java.math.RoundingMode;
5 | //
6 | //public class MSG1001 extends RTCM {
7 | //
8 | // private int messageNumber;
9 | // private int stationID;
10 | // private double TOW;
11 | // private boolean synchronous;
12 | // private int signalsProcessed; //No. of GPS Satellite Signals Processed
13 | // private boolean smoothingIndicator;
14 | // private int smoothingInterval;
15 | // private final double LightMilliSecond = 299792.458;
16 | // String[] smoothing = new String[]{
17 | // "No smoothing",
18 | // "< 30 s",
19 | // "30-60 s",
20 | // "1-2 min",
21 | // "2-4 min",
22 | // "4-8 min",
23 | // ">8 min",
24 | // "Unlimited smoothing interval"
25 | // };
26 | //
27 | // Sat1001[] listSatellites;
28 | //
29 | // public Sat1001[] getListSatellites() {
30 | // return listSatellites;
31 | // }
32 | //
33 | // public MSG1001(byte[] msg) {
34 | //
35 | // super.rawMsg = msg;
36 | //
37 | // super.setToBinaryBuffer(msg);
38 | //
39 | // messageNumber = Integer.parseUnsignedInt(binaryBuffer.substring(16, 28), 2);//1005 1006
40 | // stationID = Integer.parseUnsignedInt(binaryBuffer.substring(28, 40), 2);
41 | // TOW = toUnsignedInt(binaryBuffer.substring(40, 70)) / 1000.0d;
42 | // synchronous = binaryBuffer.charAt(70) == RTCM.BIT1;
43 | // signalsProcessed = toUnsignedInt(binaryBuffer.substring(71, 76));
44 | // smoothingIndicator = binaryBuffer.charAt(76) == RTCM.BIT1;
45 | // smoothingInterval = toUnsignedInt(binaryBuffer.substring(77, 80));
46 | //
47 | // listSatellites = new Sat1001[signalsProcessed];
48 | //
49 | // for (int i = 0; i < signalsProcessed; i++) {
50 | // int shift = i * 58;
51 | //
52 | // Sat1001 s = new Sat1001();
53 | //
54 | // s.setID(toUnsignedInt(getBits(80 + shift, 6)));
55 | // s.setCodeL1(toUnsignedInt(getBits(86 + shift, 1)));
56 | // s.setL1Psr(toUnsignedInt(getBits(87 + shift, 24)));
57 | // s.setL1Phr_L1Psr(toSignedInt(getBits(111 + shift, 20)));
58 | // s.setLockL1(toUnsignedInt(getBits(131 + shift, 7)));
59 | //
60 | // listSatellites[i] = s;
61 | // }
62 | // }
63 | //
64 | // public class Sat1001 {
65 | // //Psr - PseudoRange
66 | // //Phr - PhaseRange
67 | //
68 | // String[] L1Indicator = new String[]{
69 | // "C/A Code",
70 | // "P(Y) Code Direct"
71 | // };
72 | //
73 | // String[] L2Indicator = new String[]{
74 | // "C/A or L2C code",
75 | // "P(Y) code direct",
76 | // "P(Y) code cross-correlated",
77 | // "Correlated P/Y"
78 | // };
79 | //
80 | // private int ID;
81 | // private int CodeL1;
82 | // private int L1Psr;
83 | // private int L1Phr_L1Psr;
84 | // private int L1Phr;
85 | // private int LockL1;
86 | //
87 | //
88 | // @Override
89 | // public String toString() {
90 | //
91 | // String response = "";
92 | // response += customFormat("##", ID) + "\t|\t";
93 | // response += L1Indicator[CodeL1] + "\t|\t";
94 | // //response += L1Psr + "\t|\t";
95 | // response += new BigDecimal(L1Phr_L1Psr / 2000d).setScale(2, RoundingMode.HALF_EVEN) + "\t|\t";
96 | // response += LockL1 + "\t|\t";
97 | //
98 | // return response;
99 | // }
100 | //
101 | // public int getID() {
102 | // return ID;
103 | // }
104 | //
105 | // public void setID(int ID) {
106 | // this.ID = ID;
107 | // }
108 | //
109 | // public int getCodeL1() {
110 | // return CodeL1;
111 | // }
112 | //
113 | // public void setCodeL1(int codeL1) {
114 | // CodeL1 = codeL1;
115 | // }
116 | //
117 | // public int getL1Psr() {
118 | // return L1Psr;
119 | // }
120 | //
121 | // public void setL1Psr(int l1Psr) {
122 | // L1Psr = l1Psr;
123 | // }
124 | //
125 | // public int getL1Phr_L1Psr() {
126 | // return L1Phr_L1Psr;
127 | // }
128 | //
129 | // public void setL1Phr_L1Psr(int l1Phr_L1Psr) {
130 | // this.L1Phr_L1Psr = l1Phr_L1Psr;
131 | // }
132 | //
133 | // public int getLockL1() {
134 | // return LockL1;
135 | // }
136 | //
137 | // public void setLockL1(int lockL1) {
138 | // LockL1 = lockL1;
139 | // }
140 | // }
141 | //}
142 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/nmea/NMEA.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.nmea;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | /*
6 | from = https://gist.github.com/javisantana/1326141
7 | */
8 |
9 | public class NMEA {
10 |
11 | interface SentenceParser {
12 | public boolean parse(String[] tokens, GPSPosition position);
13 | }
14 |
15 | // utils
16 | static float Latitude2Decimal(String lat, String NS) {
17 | float med = Float.parseFloat(lat.substring(2)) / 60.0f;
18 | med += Float.parseFloat(lat.substring(0, 2));
19 | if (NS.startsWith("S")) {
20 | med = -med;
21 | }
22 | return med;
23 | }
24 |
25 | static float Longitude2Decimal(String lon, String WE) {
26 | float med = Float.parseFloat(lon.substring(3)) / 60.0f;
27 | med += Float.parseFloat(lon.substring(0, 3));
28 | if (WE.startsWith("W")) {
29 | med = -med;
30 | }
31 | return med;
32 | }
33 |
34 | // parsers
35 | class GPGGA implements SentenceParser {
36 | public boolean parse(String[] tokens, GPSPosition position) {
37 | position.time = Float.parseFloat(tokens[1]);
38 | position.lat = Latitude2Decimal(tokens[2], tokens[3]);
39 | position.lon = Longitude2Decimal(tokens[4], tokens[5]);
40 | position.quality = Integer.parseInt(tokens[6]);
41 | position.altitude = Float.parseFloat(tokens[9]);
42 | return true;
43 | }
44 | }
45 |
46 | class GPGGL implements SentenceParser {
47 | public boolean parse(String[] tokens, GPSPosition position) {
48 | position.lat = Latitude2Decimal(tokens[1], tokens[2]);
49 | position.lon = Longitude2Decimal(tokens[3], tokens[4]);
50 | position.time = Float.parseFloat(tokens[5]);
51 | return true;
52 | }
53 | }
54 |
55 | class GPRMC implements SentenceParser {
56 | public boolean parse(String[] tokens, GPSPosition position) {
57 | position.time = Float.parseFloat(tokens[1]);
58 | position.lat = Latitude2Decimal(tokens[3], tokens[4]);
59 | position.lon = Longitude2Decimal(tokens[5], tokens[6]);
60 | position.velocity = Float.parseFloat(tokens[7]);
61 | position.dir = Float.parseFloat(tokens[8]);
62 | return true;
63 | }
64 | }
65 |
66 | class GPVTG implements SentenceParser {
67 | public boolean parse(String[] tokens, GPSPosition position) {
68 | position.dir = Float.parseFloat(tokens[3]);
69 | return true;
70 | }
71 | }
72 |
73 | class GPRMZ implements SentenceParser {
74 | public boolean parse(String[] tokens, GPSPosition position) {
75 | position.altitude = Float.parseFloat(tokens[1]);
76 | return true;
77 | }
78 | }
79 |
80 |
81 | public class GPSPosition {
82 | public float time = 0.0f;
83 | public float lat = 0.0f;
84 | public float lon = 0.0f;
85 | public boolean fixed = false;
86 | public int quality = 0;
87 | public float dir = 0.0f;
88 | public float altitude = 0.0f;
89 | public float velocity = 0.0f;
90 |
91 | public void updatefix() {
92 | fixed = quality > 0;
93 | }
94 |
95 | public String toString() {
96 | return String.format("POSITION: lat: %f, lon: %f, time: %f, Q: %d, dir: %f, alt: %f, vel: %f", lat, lon, time, quality, dir, altitude, velocity);
97 | }
98 |
99 | public boolean isSet() {
100 | System.out.println(position.lat != 0.0f && position.lon != 0.0f);
101 | return position.lat != 0.0f && position.lon != 0.0f;
102 | }
103 | }
104 |
105 | GPSPosition position = new GPSPosition();
106 |
107 | private static final Map sentenceParsers = new HashMap();
108 |
109 | public NMEA() {
110 | //Add new message
111 | sentenceParsers.put("GNGGA", new GPGGA());
112 |
113 | sentenceParsers.put("GPGGA", new GPGGA());
114 | sentenceParsers.put("GPGGL", new GPGGL());
115 | sentenceParsers.put("GPRMC", new GPRMC());
116 | sentenceParsers.put("GPRMZ", new GPRMZ());
117 | //only really good GPS devices have this sentence but ...
118 | sentenceParsers.put("GPVTG", new GPVTG());
119 | }
120 |
121 | public GPSPosition parse(String line) {
122 |
123 | if (line.startsWith("$")) {
124 | String nmea = line.substring(1);
125 | String[] tokens = nmea.split(",");
126 | String type = tokens[0];
127 | //TODO check crc
128 | if (sentenceParsers.containsKey(type)) {
129 | sentenceParsers.get(type).parse(tokens, position);
130 | }
131 | position.updatefix();
132 | }
133 |
134 | return position;
135 | }
136 | }
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/messages/MSG1025.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm.messages;
2 |
3 | import com.google.common.primitives.Bytes;
4 | import org.dav95s.openNTRIP.protocols.rtcm.assets.CRS3;
5 | import org.dav95s.openNTRIP.utils.binaryParse.BitUtils;
6 | import org.dav95s.openNTRIP.utils.binaryParse.Crc24q;
7 | import org.dav95s.openNTRIP.utils.binaryParse.Normalize;
8 |
9 | import static com.google.common.base.Preconditions.checkArgument;
10 |
11 | public class MSG1025 implements CRS3 {
12 |
13 | private int messageNumber;
14 | private int SystemIdentificationNumber;
15 | private int ProjectionType;
16 | private double LaNO;
17 | private double LoNO;
18 | private double S;
19 | private double FalseEasting;
20 | private double FalseNorthing;
21 |
22 | public MSG1025() {
23 | messageNumber = 1025;
24 | }
25 |
26 | public MSG1025(byte[] msg) {
27 | BitUtils bitUtils = new BitUtils(msg);
28 | bitUtils.setPointer(24);
29 | messageNumber = bitUtils.getUnsignedInt(12);
30 | setSystemIdentificationNumber(bitUtils.getUnsignedInt(8));
31 | setProjectionType(bitUtils.getUnsignedInt(6));
32 | setLaNO(bitUtils.getSignedLong(34) * 0.000000011d);
33 | setLoNO(bitUtils.getSignedLong(35) * 0.000000011d);
34 | setS((bitUtils.getUnsignedLong(30) * 0.00001d + 993000) / 1000000);
35 | setFalseEasting(bitUtils.getUnsignedLong(36) * 0.001d);
36 | setFalseNorthing(bitUtils.getSignedLong(35) * 0.001d);
37 | }
38 |
39 | public byte[] getBytes() {
40 | BitUtils bitUtils = new BitUtils();
41 | bitUtils.setBitString("11010011000000"); //preamble + 6 reserved bit
42 | bitUtils.setInt(25, 10);
43 | bitUtils.setInt(messageNumber, 12);
44 | bitUtils.setInt(SystemIdentificationNumber, 8);
45 | bitUtils.setInt(ProjectionType, 6);
46 | bitUtils.setLong(Math.round(LaNO / 0.000000011d), 34);
47 | bitUtils.setLong(Math.round(LoNO / 0.000000011d), 35);
48 | bitUtils.setLong(Math.round((S * 1000000 - 993000) / 0.00001d), 30);
49 | bitUtils.setLong(Math.round(FalseEasting / 0.001d), 36);
50 | bitUtils.setLong(Math.round(FalseNorthing / 0.001d), 35);
51 | byte[] bytes = bitUtils.getByteArray();
52 | return Bytes.concat(bytes, Crc24q.crc24q(bytes, bytes.length, 0));
53 | }
54 |
55 | @Override
56 | public String toString() {
57 | return "MSG1025{" +
58 | "messageNumber=" + messageNumber +
59 | ", SystemIdentificationNumber=" + SystemIdentificationNumber +
60 | ", ProjectionType=" + ProjectionType +
61 | ", LaNO=" + LaNO +
62 | ", LoNO=" + LoNO +
63 | ", S=" + S +
64 | ", FalseEasting=" + FalseEasting +
65 | ", FalseNorthing=" + FalseNorthing +
66 | '}';
67 | }
68 |
69 | public int getMessageNumber() {
70 | return messageNumber;
71 | }
72 |
73 | public int getSystemIdentificationNumber() {
74 | return SystemIdentificationNumber;
75 | }
76 |
77 | public void setSystemIdentificationNumber(int systemIdentificationNumber) {
78 | checkArgument(0 <= systemIdentificationNumber && systemIdentificationNumber <= 255);
79 | SystemIdentificationNumber = systemIdentificationNumber;
80 | }
81 |
82 | public int getProjectionType() {
83 | return ProjectionType;
84 | }
85 |
86 | public void setProjectionType(int projectionType) {
87 | checkArgument(0 <= projectionType && projectionType <= 11);
88 | ProjectionType = projectionType;
89 | }
90 |
91 | public double getLaNO() {
92 | return LaNO;
93 | }
94 |
95 | public void setLaNO(double laNO) {
96 | double normalized = Normalize.normalize(laNO, 8);
97 | checkArgument(-90 <= normalized && normalized <= 90);
98 | LaNO = normalized;
99 | }
100 |
101 | public double getLoNO() {
102 | return LoNO;
103 | }
104 |
105 | public void setLoNO(double loNO) {
106 | double normalized = Normalize.normalize(loNO, 8);
107 | checkArgument(-180 <= normalized && normalized <= 180);
108 | LoNO = normalized;
109 | }
110 |
111 | public double getS() {
112 | return S;
113 | }
114 |
115 | public void setS(double s) {
116 | double normalized = Normalize.normalize(s, 6);
117 | checkArgument(0.993 <= normalized && normalized <= 1.003737418);
118 | this.S = normalized;
119 | }
120 |
121 | public double getFalseEasting() {
122 | return FalseEasting;
123 | }
124 |
125 | public void setFalseEasting(double falseEasting) {
126 | double normalized = Normalize.normalize(falseEasting, 4);
127 | checkArgument(0 <= normalized && normalized <= 68719476.735);
128 | FalseEasting = normalized;
129 | }
130 |
131 | public double getFalseNorthing() {
132 | return FalseNorthing;
133 | }
134 |
135 | public void setFalseNorthing(double falseNorthing) {
136 | double normalized = Normalize.normalize(falseNorthing, 4);
137 | checkArgument(-17179869.183 <= normalized && normalized <= 17179869.183);
138 | FalseNorthing = normalized;
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/messages/MSG1002.java:
--------------------------------------------------------------------------------
1 | //package org.dav95s.openNTRIP.Tools.RTCM;
2 | //
3 | //import java.math.BigDecimal;
4 | //import java.math.RoundingMode;
5 | //
6 | //public class MSG1002 extends RTCM {
7 | //
8 | // private int messageNumber;
9 | // private int stationID;
10 | // private double TOW;
11 | // private boolean synchronous;
12 | // private int signalsProcessed; //No. of GPS Satellite Signals Processed
13 | // private boolean smoothingIndicator;
14 | // private int smoothingInterval;
15 | // private final double LightMilliSecond = 299792.458;
16 | // String[] smoothing = new String[]{
17 | // "No smoothing",
18 | // "< 30 s",
19 | // "30-60 s",
20 | // "1-2 min",
21 | // "2-4 min",
22 | // "4-8 min",
23 | // ">8 min",
24 | // "Unlimited smoothing interval"
25 | // };
26 | //
27 | // Sat1002[] listSatellites;
28 | //
29 | // public Sat1002[] getListSatellites() {
30 | // return listSatellites;
31 | // }
32 | //
33 | // public MSG1002(byte[] msg) {
34 | //
35 | // super.rawMsg = msg;
36 | //
37 | // super.setToBinaryBuffer(msg);
38 | //
39 | // messageNumber = Integer.parseUnsignedInt(binaryBuffer.substring(16, 28), 2);//1005 1006
40 | // stationID = Integer.parseUnsignedInt(binaryBuffer.substring(28, 40), 2);
41 | // TOW = toUnsignedInt(binaryBuffer.substring(40, 70)) / 1000.0d;
42 | // synchronous = binaryBuffer.charAt(70) == RTCM.BIT1;
43 | // signalsProcessed = toUnsignedInt(binaryBuffer.substring(71, 76));
44 | // smoothingIndicator = binaryBuffer.charAt(76) == RTCM.BIT1;
45 | // smoothingInterval = toUnsignedInt(binaryBuffer.substring(77, 80));
46 | //
47 | // listSatellites = new Sat1002[signalsProcessed];
48 | //
49 | // for (int i = 0; i < signalsProcessed; i++) {
50 | // int shift = i * 74;
51 | //
52 | // Sat1002 s = new Sat1002();
53 | //
54 | // s.setID(toUnsignedInt(getBits(80 + shift, 6)));
55 | // s.setCodeL1(toUnsignedInt(getBits(86 + shift, 1)));
56 | // s.setL1Psr(toUnsignedInt(getBits(87 + shift, 24)));
57 | // s.setL1Phr_L1Psr(toSignedInt(getBits(111 + shift, 20)));
58 | // s.setLockL1(toUnsignedInt(getBits(131 + shift, 7)));
59 | // s.setSNRL1(toUnsignedInt(getBits(138 + shift, 8)));
60 | //
61 | // listSatellites[i] = s;
62 | // }
63 | // }
64 | //
65 | // public class Sat1002 {
66 | // //Psr - PseudoRange
67 | // //Phr - PhaseRange
68 | //
69 | // String[] L1Indicator = new String[]{
70 | // "C/A Code",
71 | // "P(Y) Code Direct"
72 | // };
73 | //
74 | // String[] L2Indicator = new String[]{
75 | // "C/A or L2C code",
76 | // "P(Y) code direct",
77 | // "P(Y) code cross-correlated",
78 | // "Correlated P/Y"
79 | // };
80 | //
81 | // private int ID;
82 | // private int CodeL1;
83 | // private int L1Psr;
84 | // private int L1Phr_L1Psr;
85 | // private int LockL1;
86 | // private int AmbL1;
87 | // private int SNRL1;
88 | //
89 | //
90 | // @Override
91 | // public String toString() {
92 | //
93 | // String response = "";
94 | // response += customFormat("##", ID) + "\t|\t";
95 | // response += L1Indicator[CodeL1] + "\t|\t";
96 | // //response += L1Psr + "\t|\t";
97 | // response += new BigDecimal(L1Phr_L1Psr / 2000d).setScale(2, RoundingMode.HALF_EVEN) + "\t|\t";
98 | // response += LockL1 + "\t|\t";
99 | // response += new BigDecimal(AmbL1 * LightMilliSecond).setScale(2, RoundingMode.HALF_EVEN) + "\t|\t";
100 | // response += new BigDecimal(SNRL1 / 4.0d).setScale(2, RoundingMode.HALF_EVEN) + "\t|\t";
101 | //
102 | // return response;
103 | // }
104 | //
105 | // public int getID() {
106 | // return ID;
107 | // }
108 | //
109 | // public void setID(int ID) {
110 | // this.ID = ID;
111 | // }
112 | //
113 | // public int getCodeL1() {
114 | // return CodeL1;
115 | // }
116 | //
117 | // public void setCodeL1(int codeL1) {
118 | // CodeL1 = codeL1;
119 | // }
120 | //
121 | // public int getL1Psr() {
122 | // return L1Psr;
123 | // }
124 | //
125 | // public void setL1Psr(int l1Psr) {
126 | // L1Psr = l1Psr;
127 | // }
128 | //
129 | // public int getL1Phr_L1Psr() {
130 | // return L1Phr_L1Psr;
131 | // }
132 | //
133 | // public void setL1Phr_L1Psr(int l1Phr_L1Psr) {
134 | // this.L1Phr_L1Psr = l1Phr_L1Psr;
135 | // }
136 | //
137 | // public int getLockL1() {
138 | // return LockL1;
139 | // }
140 | //
141 | // public void setLockL1(int lockL1) {
142 | // LockL1 = lockL1;
143 | // }
144 | //
145 | // public int getAmbL1() {
146 | // return AmbL1;
147 | // }
148 | //
149 | // public void setAmbL1(int ambL1) {
150 | // AmbL1 = ambL1;
151 | // }
152 | //
153 | // public int getSNRL1() {
154 | // return SNRL1;
155 | // }
156 | //
157 | // public void setSNRL1(int SNRL1) {
158 | // this.SNRL1 = SNRL1;
159 | // }
160 | //
161 | // }
162 | //}
163 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/crs/geoids/GGF.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.crs.geoids;
2 |
3 | import org.dav95s.openNTRIP.utils.binaryParse.Normalize;
4 |
5 | import java.io.IOException;
6 | import java.io.RandomAccessFile;
7 | import java.nio.ByteBuffer;
8 | import java.nio.ByteOrder;
9 | import java.nio.channels.FileChannel;
10 |
11 | public class GGF implements IGeoid {
12 |
13 | Header header;
14 | float[][] model;
15 |
16 | public GGF(String path) {
17 | try (RandomAccessFile reader = new RandomAccessFile(path, "r")) {
18 | FileChannel channel = reader.getChannel();
19 | ByteBuffer headerBuffer = ByteBuffer.allocate(146);
20 | channel.read(headerBuffer);
21 |
22 | header = new Header(headerBuffer);
23 | model = new float[header.countLat][header.countLon];
24 |
25 | ByteBuffer buffer = ByteBuffer.allocate(header.countLon * 4);
26 | buffer.order(ByteOrder.LITTLE_ENDIAN);
27 |
28 | for (int row = 0; row < model.length; row++) {
29 | channel.read(buffer); // read 1 row
30 | buffer.flip();
31 | for (int col = 0; col < model[0].length; col++) {
32 | model[row][col] = buffer.getFloat();
33 | }
34 | buffer.clear();
35 | }
36 | } catch (IOException e) {
37 | e.printStackTrace();
38 | }
39 | }
40 |
41 |
42 | public double getValueByPoint(double lat, double lon) {
43 | if (lon < 0 || header.lonMax > 360) {
44 | lon += 360;
45 | }
46 |
47 | int latP = (int) Normalize.normalize((lat - header.latMin) / header.resolutionLat, 4);
48 | int lonP = (int) (Normalize.normalize((lon - header.lonMin) / header.resolutionLon, 4));
49 |
50 | double dLon = lon - (lonP * header.resolutionLon + header.lonMin);
51 | double dLat = lat - (latP * header.resolutionLat + header.latMin);
52 |
53 | float[][] v = new float[][]{{model[latP][lonP], model[latP][lonP + 1]}, {model[latP + 1][lonP], model[latP + 1][lonP + 1]}};
54 |
55 | return bilinear(dLat / header.resolutionLat, dLon / header.resolutionLon, v);
56 | }
57 |
58 | public static float bilinear(double x, double y, float[][] v) {
59 | return (float) (v[0][0] * (1 - x) * (1 - y) + v[1][0] * x * (1 - y) + v[0][1] * (1 - x) * y + v[1][1] * x * y);
60 | }
61 |
62 |
63 | @Override
64 | public String toString() {
65 | return header.toString();
66 | }
67 |
68 | class Header {
69 | String description;
70 | double latMin, latMax;
71 | double lonMin, lonMax;
72 | double resolutionLat, resolutionLon;
73 | int countLat, countLon;
74 | double NorthPole, SouthPole, Missing, Scalar;
75 | int window;
76 | byte flag0;
77 | byte flag1;
78 | byte flag2;
79 | byte flag3;
80 | byte flag4;
81 | byte flag5;
82 | byte flag6;
83 | byte flag7;
84 |
85 | public Header(ByteBuffer buffer) {
86 | buffer.order(ByteOrder.LITTLE_ENDIAN);
87 | buffer.flip();
88 | flag1 = buffer.get();
89 | flag2 = buffer.get();
90 | byte[] descriptionRaw = new byte[46];
91 | buffer.get(descriptionRaw, 0, 46);
92 | description = new String(descriptionRaw);
93 | latMin = buffer.getDouble();
94 | latMax = buffer.getDouble();
95 | lonMin = buffer.getDouble();
96 | lonMax = buffer.getDouble();
97 | resolutionLat = buffer.getDouble();
98 | resolutionLon = buffer.getDouble();
99 | countLat = buffer.getInt();
100 | countLon = buffer.getInt();
101 | NorthPole = buffer.getDouble();
102 | SouthPole = buffer.getDouble();
103 | Missing = buffer.getDouble();
104 | Scalar = buffer.getDouble();
105 | window = buffer.getShort();
106 | flag0 = buffer.get();
107 | flag1 = buffer.get();
108 | flag2 = buffer.get();
109 | flag3 = buffer.get();
110 | flag4 = buffer.get();
111 | flag5 = buffer.get();
112 | flag6 = buffer.get();
113 | flag7 = buffer.get();
114 | }
115 |
116 | public void qualityCheck() {
117 |
118 | }
119 |
120 | @Override
121 | public String toString() {
122 | return "Header{" +
123 | "description='" + description + '\'' +
124 | ", latMin=" + latMin +
125 | ", latMax=" + latMax +
126 | ", lonMin=" + lonMin +
127 | ", lonMax=" + lonMax +
128 | ", resolutionLat=" + resolutionLat +
129 | ", resolutionLon=" + resolutionLon +
130 | ", countLat=" + countLat +
131 | ", countLon=" + countLon +
132 | ", NorthPole=" + NorthPole +
133 | ", SouthPole=" + SouthPole +
134 | ", Missing=" + Missing +
135 | ", Scalar=" + Scalar +
136 | ", window=" + window +
137 | ", flag0=" + flag0 +
138 | ", flag1=" + flag1 +
139 | ", flag2=" + flag2 +
140 | ", flag3=" + flag3 +
141 | ", flag4=" + flag4 +
142 | ", flag5=" + flag5 +
143 | ", flag6=" + flag6 +
144 | ", flag7=" + flag7 +
145 | '}';
146 | }
147 | }
148 | }
149 |
150 |
151 |
152 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/models/UserModel.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database.models;
2 |
3 | import org.dav95s.openNTRIP.database.DataSource;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | import java.sql.Connection;
8 | import java.sql.PreparedStatement;
9 | import java.sql.ResultSet;
10 | import java.sql.SQLException;
11 | import java.util.HashSet;
12 | import java.util.Set;
13 |
14 | public class UserModel {
15 | final static private Logger logger = LoggerFactory.getLogger(UserModel.class.getName());
16 | private int id;
17 | private String username;
18 | private String password;
19 | private String email;
20 | private Boolean active;
21 | final private Set listGroups = new HashSet<>();
22 |
23 | public UserModel(String username) {
24 | this.username = username;
25 | }
26 |
27 | public UserModel() {
28 |
29 | }
30 |
31 | public void setPassword(String password) {
32 | this.password = password;
33 | }
34 |
35 | public boolean read() {
36 | String sql;
37 | String searchIndex;
38 |
39 | if (username != null) {
40 | sql = "SELECT * FROM users WHERE `username` = ?";
41 | searchIndex = username;
42 | } else if (email != null) {
43 | sql = "SELECT * FROM users WHERE `email` = ?";
44 | searchIndex = email;
45 | } else {
46 | logger.error("Need username of email, for the select query!");
47 | return false;
48 | }
49 |
50 | try (Connection con = DataSource.getConnection();
51 | PreparedStatement statement = con.prepareStatement(sql)) {
52 |
53 | statement.setString(1, searchIndex);
54 |
55 | try (ResultSet rs = statement.executeQuery()) {
56 | if (rs.next()) {
57 | id = rs.getInt("id");
58 | username = rs.getString("username");
59 | password = rs.getString("password");
60 | email = rs.getString("email");
61 | active = rs.getBoolean("active");
62 | return true;
63 | } else {
64 | return false;
65 | }
66 | }
67 |
68 | } catch (SQLException e) {
69 | logger.error("SQL Error", e);
70 | return false;
71 | }
72 | }
73 |
74 | public boolean readGroups() {
75 | String sql = "SELECT groups.name, groups.description, groups.id FROM users_groups LEFT JOIN groups ON users_groups.group_id = groups.id WHERE users_groups.user_id = ?";
76 |
77 | try (Connection con = DataSource.getConnection();
78 | PreparedStatement statement = con.prepareStatement(sql)) {
79 |
80 | statement.setInt(1, id);
81 |
82 | try (ResultSet rs = statement.executeQuery()) {
83 |
84 | if (!rs.next())
85 | return false;
86 |
87 | do {
88 | UserGroupModel group = new UserGroupModel();
89 | group.setGroup_id(rs.getInt("id"));
90 | group.setName(rs.getString("name"));
91 | group.setDescription(rs.getString("description"));
92 | listGroups.add(group);
93 | } while (rs.next());
94 |
95 | return true;
96 | }
97 | } catch (SQLException e) {
98 | logger.error("SQL Error", e);
99 | return false;
100 | }
101 | }
102 |
103 | public boolean deleteFromGroup(int group_id) {
104 | String sql = "DELETE FROM `users_groups` WHERE `users_groups.user_id` = ? AND `users_groups.group_id` = ?";
105 |
106 | try (Connection con = DataSource.getConnection();
107 | PreparedStatement statement = con.prepareStatement(sql)) {
108 |
109 | statement.setInt(1, id);
110 | statement.setInt(2, group_id);
111 | return statement.executeUpdate() > 0;
112 | } catch (SQLException e) {
113 | logger.error("SQL Error", e);
114 | return false;
115 | }
116 | }
117 |
118 | public boolean addToGroup(int group_id) {
119 | String sql = "INSERT INTO `users_groups`(`user_id`, `group_id`) VALUES (?,?)";
120 |
121 | try (Connection con = DataSource.getConnection();
122 | PreparedStatement statement = con.prepareStatement(sql)) {
123 |
124 | statement.setInt(1, id);
125 | statement.setInt(2, group_id);
126 |
127 | return statement.executeUpdate() > 0;
128 | } catch (SQLException e) {
129 | logger.error("SQL Error", e);
130 | return false;
131 | }
132 | }
133 |
134 | public int getId() {
135 | return this.id;
136 | }
137 |
138 | public String getUsername() {
139 | return this.username;
140 | }
141 |
142 | public String getPassword() {
143 | return this.password;
144 | }
145 |
146 | public String getEmail() {
147 | return this.email;
148 | }
149 |
150 | public Boolean getActive() {
151 | return this.active;
152 | }
153 |
154 | public Set getListGroups() {
155 | return this.listGroups;
156 | }
157 |
158 | public void setId(int id) {
159 | this.id = id;
160 | }
161 |
162 | public void setUsername(String username) {
163 | this.username = username;
164 | }
165 |
166 | public void setEmail(String email) {
167 | this.email = email;
168 | }
169 |
170 | public void setActive(Boolean active) {
171 | this.active = active;
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/messages/MSG1022.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm.messages;
2 |
3 | import com.google.common.base.Preconditions;
4 | import com.google.common.primitives.Bytes;
5 | import org.dav95s.openNTRIP.protocols.rtcm.assets.CRS1;
6 | import org.dav95s.openNTRIP.utils.binaryParse.BitUtils;
7 | import org.dav95s.openNTRIP.utils.binaryParse.Crc24q;
8 | import org.dav95s.openNTRIP.utils.binaryParse.Normalize;
9 |
10 | public class MSG1022 extends MSG1021 implements CRS1 {
11 |
12 | double Xp;
13 | double Yp;
14 | double Zp;
15 |
16 | public MSG1022() {
17 | this.messageNumber = 1022;
18 | }
19 |
20 | public MSG1022(byte[] msg) {
21 | BitUtils bitUtils = new BitUtils(msg);
22 | bitUtils.setPointer(24);
23 |
24 | messageNumber = bitUtils.getUnsignedInt(12);
25 | SourceNameCounter = bitUtils.getUnsignedInt(5);
26 | setSourceName(bitUtils.getString(SourceNameCounter * 8));
27 | TargetNameCounter = bitUtils.getUnsignedInt(5);
28 | setTargetName(bitUtils.getString(TargetNameCounter * 8));
29 | setSystemIdentificationNumber(bitUtils.getUnsignedInt(8));
30 | setUtilizedTransformationMessageIndicator(bitUtils.getUnsignedInt(10));
31 | setPlateNumber(bitUtils.getUnsignedInt(5));
32 | setComputationIndicator(bitUtils.getUnsignedInt(4));
33 | setHeightIndicator(bitUtils.getUnsignedInt(2));
34 | setLatValid(bitUtils.getSignedInt(19) * 2 / 3600d);
35 | setLonValid(bitUtils.getSignedInt(20) * 2 / 3600d);
36 | setdLatValid(bitUtils.getUnsignedInt(14) * 2 / 3600d);
37 | setdLonValid(bitUtils.getUnsignedInt(14) * 2 / 3600d);
38 | setdX(bitUtils.getSignedInt(23) * 0.0001);
39 | setdY(bitUtils.getSignedInt(23) * 0.0001);
40 | setdZ(bitUtils.getSignedInt(23) * 0.0001);
41 | setRx(bitUtils.getSignedInt(32) * 0.00002);
42 | setRy(bitUtils.getSignedInt(32) * 0.00002);
43 | setRz(bitUtils.getSignedInt(32) * 0.00002);
44 | setdS(bitUtils.getSignedInt(25) * 0.00001);
45 | setXp(bitUtils.getSignedLong(35) * 0.001);
46 | setYp(bitUtils.getSignedLong(35) * 0.001);
47 | setZp(bitUtils.getSignedLong(35) * 0.001);
48 | setAs(bitUtils.getUnsignedLong(24) * 0.001 + 6370000);
49 | setBs(bitUtils.getUnsignedLong(25) * 0.001 + 6350000);
50 | setAt(bitUtils.getUnsignedLong(24) * 0.001 + 6370000);
51 | setBt(bitUtils.getUnsignedLong(25) * 0.001 + 6350000);
52 | setHorizontalQuality(bitUtils.getUnsignedInt(3));
53 | setVerticalQuality(bitUtils.getUnsignedInt(3));
54 | }
55 |
56 | public byte[] getBytes() {
57 | BitUtils bitUtils = new BitUtils();
58 | bitUtils.setBitString("11010011000000"); //preamble + 6 reserved bit
59 | bitUtils.setInt(65 + SourceNameCounter + TargetNameCounter, 10);
60 | bitUtils.setInt(messageNumber, 12);
61 | bitUtils.setInt(SourceNameCounter, 5);
62 | bitUtils.setString(SourceName);
63 | bitUtils.setInt(TargetNameCounter, 5);
64 | bitUtils.setString(TargetName);
65 | bitUtils.setInt(SystemIdentificationNumber, 8);
66 | bitUtils.setInt(UtilizedTransformationMessageIndicator, 10);
67 | bitUtils.setInt(PlateNumber, 5);
68 | bitUtils.setInt(ComputationIndicator, 4);
69 | bitUtils.setInt(HeightIndicator, 2);
70 | bitUtils.setInt((int) Math.round(LatValid * 3600 / 2), 19);
71 | bitUtils.setInt((int) Math.round(LonValid * 3600 / 2), 20);
72 | bitUtils.setInt((int) Math.round(dLatValid * 3600 / 2), 14);
73 | bitUtils.setInt((int) Math.round(dLonValid * 3600 / 2), 14);
74 | bitUtils.setInt((int) Math.round(dX * 10000), 23);
75 | bitUtils.setInt((int) Math.round(dY * 10000), 23);
76 | bitUtils.setInt((int) Math.round(dZ * 10000), 23);
77 | bitUtils.setInt((int) Math.round(Rx / 0.00002), 32);
78 | bitUtils.setInt((int) Math.round(Ry / 0.00002), 32);
79 | bitUtils.setInt((int) Math.round(Rz / 0.00002), 32);
80 | bitUtils.setInt((int) Math.round(dS * 100000), 25);
81 | bitUtils.setInt((int) Math.round(Xp * 1000), 35);
82 | bitUtils.setInt((int) Math.round(Yp * 1000), 35);
83 | bitUtils.setInt((int) Math.round(Zp * 1000), 35);
84 | bitUtils.setInt((int) Math.round((As - 6370000) * 1000), 24);
85 | bitUtils.setInt((int) Math.round((Bs - 6350000) * 1000), 25);
86 | bitUtils.setInt((int) Math.round((At - 6370000) * 1000), 24);
87 | bitUtils.setInt((int) Math.round((Bt - 6350000) * 1000), 25);
88 | bitUtils.setInt(HorizontalQuality, 3);
89 | bitUtils.setInt(VerticalQuality, 3);
90 | byte[] bytes = bitUtils.getByteArray();
91 | return Bytes.concat(bytes, Crc24q.crc24q(bytes, bytes.length, 0));
92 | }
93 |
94 | public double getXp() {
95 | return Xp;
96 | }
97 |
98 | public void setXp(double xp) {
99 | double normalized = Normalize.normalize(xp, 4);
100 | Preconditions.checkArgument(-17179869.184 <= normalized && normalized <= 17179869.184);
101 | Xp = normalized;
102 | }
103 |
104 | public double getYp() {
105 | return Yp;
106 | }
107 |
108 | public void setYp(double yp) {
109 | double normalized = Normalize.normalize(yp, 4);
110 | Preconditions.checkArgument(-17179869.184 <= normalized && normalized <= 17179869.184);
111 | Yp = normalized;
112 | }
113 |
114 | public double getZp() {
115 | return Zp;
116 | }
117 |
118 | public void setZp(double zp) {
119 | double normalized = Normalize.normalize(zp, 4);
120 | Preconditions.checkArgument(-17179869.184 <= normalized && normalized <= 17179869.184);
121 | Zp = normalized;
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/messages/MSG1026.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm.messages;
2 |
3 | import com.google.common.primitives.Bytes;
4 | import org.dav95s.openNTRIP.protocols.rtcm.assets.CRS3;
5 | import org.dav95s.openNTRIP.utils.binaryParse.BitUtils;
6 | import org.dav95s.openNTRIP.utils.binaryParse.Crc24q;
7 | import org.dav95s.openNTRIP.utils.binaryParse.Normalize;
8 |
9 | import static com.google.common.base.Preconditions.checkArgument;
10 |
11 | public class MSG1026 implements CRS3 {
12 |
13 | private final int messageNumber;
14 | private int SystemIdentificationNumber;
15 | private int ProjectionType;
16 | double LaFO; // – Latitude of False Origin
17 | double LoFO; // – Longitude of False Origin
18 | double LaSP1; // – Latitude of Standard Parallel No. 1
19 | double LaSP2; // – Latitude of Standard Parallel No. 2
20 | double EFO; // – Easting of False Origin
21 | double NFO; // – Northing of False Origin
22 |
23 | public MSG1026() {
24 | messageNumber = 1026;
25 | }
26 |
27 | public MSG1026(byte[] msg) {
28 | BitUtils bitUtils = new BitUtils(msg);
29 | bitUtils.setPointer(24);
30 | messageNumber = bitUtils.getUnsignedInt(12);
31 | SystemIdentificationNumber = bitUtils.getUnsignedInt(8);
32 | ProjectionType = bitUtils.getUnsignedInt(6);
33 | setLaFO(bitUtils.getSignedLong(34) * 0.000000011);
34 | setLoFO(bitUtils.getSignedLong(35) * 0.000000011);
35 | setLaSP1(bitUtils.getSignedLong(34) * 0.000000011);
36 | setLaSP2(bitUtils.getSignedLong(34) * 0.000000011);
37 | setEFO(bitUtils.getUnsignedLong(36) * 0.001);
38 | setNFO(bitUtils.getSignedLong(35) * 0.001);
39 | }
40 |
41 | public byte[] getBytes() {
42 | BitUtils bitUtils = new BitUtils();
43 | bitUtils.setBitString("11010011000000"); //preamble + 6 reserved bit
44 | bitUtils.setInt(30, 10);//todo length message !!!!!!
45 | bitUtils.setInt(messageNumber, 12);
46 | bitUtils.setInt(SystemIdentificationNumber, 8);
47 | bitUtils.setInt(ProjectionType, 6);
48 | bitUtils.setLong(Math.round(LaFO / 0.000000011), 34);
49 | bitUtils.setLong(Math.round(LoFO / 0.000000011), 35);
50 | bitUtils.setLong(Math.round(LaSP1 / 0.000000011), 34);
51 | bitUtils.setLong(Math.round(LaSP2 / 0.000000011), 34);
52 | bitUtils.setLong(Math.round(EFO / 0.001), 36);
53 | bitUtils.setLong(Math.round(NFO / 0.001), 35);
54 |
55 | byte[] bytes = bitUtils.getByteArray();
56 | return Bytes.concat(bytes, Crc24q.crc24q(bytes, bytes.length, 0));
57 | }
58 |
59 | public int getMessageNumber(){
60 | return messageNumber;
61 | }
62 |
63 | public int getSystemIdentificationNumber() {
64 | return SystemIdentificationNumber;
65 | }
66 |
67 | public void setSystemIdentificationNumber(int systemIdentificationNumber) {
68 | checkArgument(0 <= systemIdentificationNumber && systemIdentificationNumber <= 255);
69 | SystemIdentificationNumber = systemIdentificationNumber;
70 | }
71 |
72 | public int getProjectionType() {
73 | return ProjectionType;
74 | }
75 |
76 | public void setProjectionType(int projectionType) {
77 | checkArgument(0 <= projectionType && projectionType <= 11);
78 | ProjectionType = projectionType;
79 | }
80 |
81 | public double getLaFO() {
82 |
83 | return LaFO;
84 | }
85 |
86 | public void setLaFO(double laFO) {
87 | double normalized = Normalize.normalize(laFO, 8);
88 | checkArgument(-90 <= normalized && normalized <= 90);
89 | LaFO = normalized;
90 | }
91 |
92 | public double getLoFO() {
93 | return LoFO;
94 | }
95 |
96 | public void setLoFO(double loFO) {
97 | double normalized = Normalize.normalize(loFO, 8);
98 | checkArgument(-180 <= normalized && normalized <= 180);
99 | LoFO = normalized;
100 | }
101 |
102 | public double getLaSP1() {
103 | return LaSP1;
104 | }
105 |
106 | public void setLaSP1(double laSP1) {
107 | double normalized = Normalize.normalize(laSP1, 8);
108 | checkArgument(-90 <= normalized && normalized <= 90);
109 | LaSP1 = normalized;
110 |
111 | }
112 |
113 | public double getLaSP2() {
114 | return LaSP2;
115 | }
116 |
117 | public void setLaSP2(double laSP2) {
118 | double normalized = Normalize.normalize(laSP2, 8);
119 | checkArgument(-90 <= normalized && normalized <= 90);
120 | LaSP2 = normalized;
121 |
122 | }
123 |
124 | public double getEFO() {
125 | return EFO;
126 | }
127 |
128 | public void setEFO(double EFO) {
129 | double normalized = Normalize.normalize(EFO, 4);
130 | checkArgument(0 <= normalized && normalized <= 68719476.735);
131 | this.EFO = normalized;
132 | }
133 |
134 | public double getNFO() {
135 | return NFO;
136 | }
137 |
138 | public void setNFO(double NFO) {
139 | double normalized = Normalize.normalize(NFO, 4);
140 | checkArgument(-17179869.183 <= normalized && normalized <= 17179869.183);
141 | this.NFO = normalized;
142 | }
143 |
144 | @Override
145 | public String toString() {
146 | return "MSG1026{" +
147 | "messageNumber=" + messageNumber +
148 | ", SystemIdentificationNumber=" + SystemIdentificationNumber +
149 | ", ProjectionType=" + ProjectionType +
150 | ", LaFO=" + LaFO +
151 | ", LoFO=" + LoFO +
152 | ", LaSP1=" + LaSP1 +
153 | ", LaSP2=" + LaSP2 +
154 | ", EFO=" + EFO +
155 | ", NFO=" + NFO +
156 | '}';
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/messages/MSG1003.java:
--------------------------------------------------------------------------------
1 | //package org.dav95s.openNTRIP.Tools.RTCM;
2 | //
3 | //import java.math.BigDecimal;
4 | //import java.math.RoundingMode;
5 | //
6 | //public class MSG1003 extends RTCM {
7 | //
8 | // private int messageNumber;
9 | // private int stationID;
10 | // private double TOW;
11 | // private boolean synchronous;
12 | // private int signalsProcessed; //No. of GPS Satellite Signals Processed
13 | // private boolean smoothingIndicator;
14 | // private int smoothingInterval;
15 | // private final double LightMilliSecond = 299792.458;
16 | // String[] smoothing = new String[]{
17 | // "No smoothing",
18 | // "< 30 s",
19 | // "30-60 s",
20 | // "1-2 min",
21 | // "2-4 min",
22 | // "4-8 min",
23 | // ">8 min",
24 | // "Unlimited smoothing interval"
25 | // };
26 | //
27 | // Sat1003[] listSatellites;
28 | //
29 | // public Sat1003[] getListSatellites() {
30 | // return listSatellites;
31 | // }
32 | //
33 | // public MSG1003(byte[] msg) {
34 | //
35 | // rawMsg = msg;
36 | //
37 | // for (int i = 1; i < msg.length; i++) {
38 | // binaryBuffer += toBinaryString(msg[i]);
39 | // }
40 | //
41 | //
42 | // messageNumber = Integer.parseUnsignedInt(binaryBuffer.substring(16, 28), 2);//1005 1006
43 | // stationID = Integer.parseUnsignedInt(binaryBuffer.substring(28, 40), 2);
44 | // TOW = toUnsignedInt(binaryBuffer.substring(40, 70)) / 1000.0d;
45 | // synchronous = binaryBuffer.charAt(70) == RTCM.BIT1;
46 | // signalsProcessed = toUnsignedInt(binaryBuffer.substring(71, 76));
47 | // smoothingIndicator = binaryBuffer.charAt(76) == RTCM.BIT1;
48 | // smoothingInterval = toUnsignedInt(binaryBuffer.substring(77, 80));
49 | //
50 | // listSatellites = new Sat1003[signalsProcessed];
51 | //
52 | // for (int i = 0; i < signalsProcessed; i++) {
53 | // int shift = i * 101;
54 | //
55 | // Sat1003 s = new Sat1003();
56 | //
57 | // s.setID(toUnsignedInt(getBits(80 + shift, 6)));
58 | // s.setCodeL1(toUnsignedInt(getBits(86 + shift, 1)));
59 | // s.setL1Psr(toUnsignedInt(getBits(87 + shift, 24)));
60 | // s.setL1Phr_L1Psr(toSignedInt(getBits(111 + shift, 20)));
61 | // s.setLockL1(toUnsignedInt(getBits(131 + shift, 7)));
62 | // s.setCodeL2(toUnsignedInt(getBits(138 + shift, 2)));
63 | // s.setL2Psr_L1Psr(toSignedInt(getBits(140 + shift, 14)));
64 | // s.setL2Phr_L1Psr(toSignedInt(getBits(154 + shift, 20)));
65 | // s.setLockL2(toUnsignedInt(getBits(174 + shift, 7)));
66 | //
67 | //
68 | //
69 | // listSatellites[i] = s;
70 | // }
71 | // }
72 | //
73 | // public class Sat1003 {
74 | // //Psr - PseudoRange
75 | // //Phr - PhaseRange
76 | //
77 | // String[] L1Indicator = new String[]{
78 | // "C/A Code",
79 | // "P(Y) Code Direct"
80 | // };
81 | //
82 | // String[] L2Indicator = new String[]{
83 | // "C/A or L2C code",
84 | // "P(Y) code direct",
85 | // "P(Y) code cross-correlated",
86 | // "Correlated P/Y"
87 | // };
88 | //
89 | // private int ID;
90 | // private int CodeL1;
91 | // private int L1Psr;
92 | // private int L1Phr_L1Psr;
93 | // private int LockL1;
94 | // private int CodeL2;
95 | // private int L2Psr_L1Psr;
96 | // private int L2Phr_L1Psr;
97 | // private int LockL2;
98 | //
99 | //
100 | // @Override
101 | // public String toString() {
102 | //
103 | // String response = "";
104 | // response += customFormat("##", ID) + "\t|\t";
105 | // response += L1Indicator[CodeL1] + "\t|\t";
106 | // //response += L1Psr + "\t|\t";
107 | // response += new BigDecimal(L1Phr_L1Psr / 2000d).setScale(2, RoundingMode.HALF_EVEN) + "\t|\t";
108 | // response += LockL1 + "\t|\t";
109 | // response += L2Indicator[CodeL2] + "\t|\t";
110 | // response += new BigDecimal(L2Psr_L1Psr * 0.02d).setScale(2, RoundingMode.HALF_EVEN) + "\t|\t";
111 | // response += new BigDecimal(L2Phr_L1Psr / 2000.0d).setScale(2, RoundingMode.HALF_EVEN) + "\t|\t";
112 | // response += LockL2 + "\t|\t";
113 | //
114 | // return response;
115 | // }
116 | //
117 | // public int getID() {
118 | // return ID;
119 | // }
120 | //
121 | // public void setID(int ID) {
122 | // this.ID = ID;
123 | // }
124 | //
125 | // public int getCodeL1() {
126 | // return CodeL1;
127 | // }
128 | //
129 | // public void setCodeL1(int codeL1) {
130 | // CodeL1 = codeL1;
131 | // }
132 | //
133 | // public int getL1Psr() {
134 | // return L1Psr;
135 | // }
136 | //
137 | // public void setL1Psr(int l1Psr) {
138 | // L1Psr = l1Psr;
139 | // }
140 | //
141 | // public int getL1Phr_L1Psr() {
142 | // return L1Phr_L1Psr;
143 | // }
144 | //
145 | // public void setL1Phr_L1Psr(int l1Phr_L1Psr) {
146 | // this.L1Phr_L1Psr = l1Phr_L1Psr;
147 | // }
148 | //
149 | // public int getLockL1() {
150 | // return LockL1;
151 | // }
152 | //
153 | // public void setLockL1(int lockL1) {
154 | // LockL1 = lockL1;
155 | // }
156 | //
157 | // public int getCodeL2() {
158 | // return CodeL2;
159 | // }
160 | //
161 | // public void setCodeL2(int codeL2) {
162 | // CodeL2 = codeL2;
163 | // }
164 | //
165 | // public int getL2Psr_L1Psr() {
166 | // return L2Psr_L1Psr;
167 | // }
168 | //
169 | // public void setL2Psr_L1Psr(int l2Psr_L1Psr) {
170 | // this.L2Psr_L1Psr = l2Psr_L1Psr;
171 | // }
172 | //
173 | // public int getL2Phr_L1Psr() {
174 | // return L2Phr_L1Psr;
175 | // }
176 | //
177 | // public void setL2Phr_L1Psr(int l2Phr_L1Psr) {
178 | // this.L2Phr_L1Psr = l2Phr_L1Psr;
179 | // }
180 | //
181 | // public int getLockL2() {
182 | // return LockL2;
183 | // }
184 | //
185 | // public void setLockL2(int lockL2) {
186 | // LockL2 = lockL2;
187 | // }
188 | //
189 | // }
190 | //}
191 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/messages/MSG1020.java:
--------------------------------------------------------------------------------
1 | //package org.dav95s.openNTRIP.Tools.RTCM;
2 | //
3 | //public class MSG1020 extends RTCM {
4 | // private int MessageNumber;
5 | // private int SatelliteID;
6 | // private int SatelliteChannel;
7 | // private int almanacHealth; //almanac health (Cn word)
8 | // private int almanacAvailabilityIndicator;
9 | // private int P1;
10 | // private int tk;
11 | // private int MSB_of_Bn;
12 | // private int P2;
13 | // private int tb;
14 | // private int xn_f; //first derivative
15 | // private int xn;
16 | // private int xn_s; //second derivative
17 | // private int yn_f; //first derivative
18 | // private int yn;
19 | // private int yn_s; //second derivative
20 | // private int zn_f; //first derivative
21 | // private int zn;
22 | // private int zn_s; //second derivative
23 | // private int P3;
24 | // private int Gamma_n;
25 | // private int M_P;
26 | // private int M_ln; // (third string)
27 | // private int Tn;
28 | // private int M_dTn;
29 | // private int En;
30 | // private int M_P4;
31 | // private int M_FT;
32 | // private int M_NT;
33 | // private int M_M;
34 | // private int Availability_Additional_Data;
35 | // private int NA; // N^A
36 | // private int Tc;
37 | // private int M_N4;
38 | // private int M_Tgps;
39 | // private int M_ln_fi; // (fifth string)
40 | // private int reserved;
41 | //
42 | // public MSG1020(byte[] msg) {
43 | // MessageNumber = toUnsignedInt(getBits(16, 12));
44 | // SatelliteID = toUnsignedInt(getBits(28, 6));
45 | // SatelliteChannel = toUnsignedInt(getBits(34, 5));
46 | // almanacHealth = toUnsignedInt(getBits(39, 1));
47 | // almanacAvailabilityIndicator = toUnsignedInt(getBits(40, 1));
48 | // P1 = toUnsignedInt(getBits(41, 2));
49 | // tk = toUnsignedInt(getBits(43, 12));
50 | // MSB_of_Bn = toUnsignedInt(getBits(55, 1));
51 | // P2 = toUnsignedInt(getBits(56, 1));
52 | // tb = toUnsignedInt(getBits(57, 7));
53 | // xn_f = toIntS(getBits(64, 24));
54 | // xn = toIntS(getBits(88, 27));
55 | // xn_s = toIntS(getBits(115, 5));
56 | // yn_f = toIntS(getBits(120, 24));
57 | // yn = toIntS(getBits(144, 27));
58 | // yn_s = toIntS(getBits(171, 5));
59 | // zn_f = toIntS(getBits(176, 24));
60 | // zn = toIntS(getBits(200, 27));
61 | // zn_s = toIntS(getBits(227, 5));
62 | // P3 = toUnsignedInt(getBits(232, 1));
63 | // Gamma_n = toIntS(getBits(233, 11));
64 | // M_P = toUnsignedInt(getBits(244, 2));
65 | // M_ln = toUnsignedInt(getBits(246, 1));
66 | // Tn = toIntS(getBits(247, 22));
67 | // M_dTn = toIntS(getBits(269, 5));
68 | // En = toUnsignedInt(getBits(274, 5));
69 | // M_P4 = toUnsignedInt(getBits(279, 1));
70 | // M_FT = toUnsignedInt(getBits(280, 4));
71 | // M_NT = toUnsignedInt(getBits(284, 11));
72 | // M_M = toUnsignedInt(getBits(295, 2));
73 | // Availability_Additional_Data = toUnsignedInt(getBits(297, 1));
74 | // NA = toUnsignedInt(getBits(298, 11));
75 | // Tc = toIntS(getBits(309, 32));
76 | // M_N4 = toUnsignedInt(getBits(341, 5));
77 | // M_Tgps = toIntS(getBits(346, 22));
78 | // M_ln_fi = toUnsignedInt(getBits(368, 1));
79 | // reserved = toUnsignedInt(getBits(369, 7));
80 | // }
81 | //
82 | // public int getMessageNumber() {
83 | // return MessageNumber;
84 | // }
85 | //
86 | // public int getSatelliteID() {
87 | // return SatelliteID;
88 | // }
89 | //
90 | // public int getSatelliteChannel() {
91 | // return SatelliteChannel;
92 | // }
93 | //
94 | // public int getAlmanacHealth() {
95 | // return almanacHealth;
96 | // }
97 | //
98 | // public int getAlmanacAvailabilityIndicator() {
99 | // return almanacAvailabilityIndicator;
100 | // }
101 | //
102 | // public int getP1() {
103 | // return P1;
104 | // }
105 | //
106 | // public int getTk() {
107 | // return tk;
108 | // }
109 | //
110 | // public int getMSB_of_Bn() {
111 | // return MSB_of_Bn;
112 | // }
113 | //
114 | // public int getP2() {
115 | // return P2;
116 | // }
117 | //
118 | // public int getTb() {
119 | // return tb;
120 | // }
121 | //
122 | // public int getXn_f() {
123 | // return xn_f;
124 | // }
125 | //
126 | // public int getXn() {
127 | // return xn;
128 | // }
129 | //
130 | // public int getXn_s() {
131 | // return xn_s;
132 | // }
133 | //
134 | // public int getYn_f() {
135 | // return yn_f;
136 | // }
137 | //
138 | // public int getYn() {
139 | // return yn;
140 | // }
141 | //
142 | // public int getYn_s() {
143 | // return yn_s;
144 | // }
145 | //
146 | // public int getZn_f() {
147 | // return zn_f;
148 | // }
149 | //
150 | // public int getZn() {
151 | // return zn;
152 | // }
153 | //
154 | // public int getZn_s() {
155 | // return zn_s;
156 | // }
157 | //
158 | // public int getP3() {
159 | // return P3;
160 | // }
161 | //
162 | // public int getGamma_n() {
163 | // return Gamma_n;
164 | // }
165 | //
166 | // public int getM_P() {
167 | // return M_P;
168 | // }
169 | //
170 | // public int getM_ln() {
171 | // return M_ln;
172 | // }
173 | //
174 | // public int getTn() {
175 | // return Tn;
176 | // }
177 | //
178 | // public int getM_dTn() {
179 | // return M_dTn;
180 | // }
181 | //
182 | // public int getEn() {
183 | // return En;
184 | // }
185 | //
186 | // public int getM_P4() {
187 | // return M_P4;
188 | // }
189 | //
190 | // public int getM_FT() {
191 | // return M_FT;
192 | // }
193 | //
194 | // public int getM_NT() {
195 | // return M_NT;
196 | // }
197 | //
198 | // public int getM_M() {
199 | // return M_M;
200 | // }
201 | //
202 | // public int getAvailability_Additional_Data() {
203 | // return Availability_Additional_Data;
204 | // }
205 | //
206 | // public int getNA() {
207 | // return NA;
208 | // }
209 | //
210 | // public int getTc() {
211 | // return Tc;
212 | // }
213 | //
214 | // public int getM_N4() {
215 | // return M_N4;
216 | // }
217 | //
218 | // public int getM_Tgps() {
219 | // return M_Tgps;
220 | // }
221 | //
222 | // public int getM_ln_fi() {
223 | // return M_ln_fi;
224 | // }
225 | //
226 | // public int getReserved() {
227 | // return reserved;
228 | // }
229 | //}
230 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/utils/binaryParse/BitUtils.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.utils.binaryParse;
2 |
3 | import com.google.common.base.Preconditions;
4 | import com.google.common.base.Splitter;
5 | import com.google.common.collect.Iterables;
6 |
7 | import java.nio.charset.StandardCharsets;
8 | import java.util.Iterator;
9 |
10 | public class BitUtils {
11 |
12 | String buffer;
13 |
14 | int pointer = 0;
15 |
16 | public BitUtils(byte[] arr) {
17 | StringBuilder sb = new StringBuilder();
18 | for (byte b : arr) {
19 | sb.append(toBinaryString(b));
20 | }
21 | buffer = sb.toString();
22 | }
23 |
24 | public BitUtils(String bitString) {
25 | buffer = bitString;
26 | }
27 |
28 | public BitUtils() {
29 | buffer = "";
30 | }
31 |
32 | public void setPointer(int i) {
33 | pointer = i;
34 | }
35 |
36 | public void clear() {
37 | buffer = "";
38 | }
39 |
40 | private String toBinaryString(byte n) {
41 | StringBuilder sb = new StringBuilder("00000000");
42 | for (int bit = 0; bit < 8; bit++) {
43 | if (((n >> bit) & 1) > 0) {
44 | sb.setCharAt(7 - bit, '1');
45 | }
46 | }
47 | return sb.toString();
48 | }
49 |
50 | public boolean getBoolean() {
51 | int pointer = this.pointer;
52 | this.pointer += 1;
53 |
54 | return buffer.substring(pointer, this.pointer).equals("1");
55 | }
56 |
57 | public void setBoolean(boolean data) {
58 | buffer += data ? "1" : "0";
59 | }
60 |
61 | public int getSignedInt(int length) {
62 | int pointer = this.pointer;
63 | this.pointer += length;
64 |
65 | return toSignedInt(buffer.substring(pointer, this.pointer));
66 | }
67 |
68 | public long getSignedLong(int length) {
69 | int pointer = this.pointer;
70 | this.pointer += length;
71 |
72 | return toSignedLong(buffer.substring(pointer, this.pointer));
73 | }
74 |
75 | public long getUnsignedLong(int length) {
76 | Preconditions.checkArgument(length < 64);
77 | int pointer = this.pointer;
78 | this.pointer += length;
79 |
80 | return Long.parseLong(buffer.substring(pointer, this.pointer), 2);
81 | }
82 |
83 | public int getUnsignedInt(int length) {
84 | Preconditions.checkArgument(length < 32);
85 | int pointer = this.pointer;
86 | this.pointer += length;
87 |
88 | return Integer.parseInt(buffer.substring(pointer, this.pointer), 2);
89 | }
90 |
91 | public void setInt(int data, int length) {
92 | StringBuilder stringBuilder = new StringBuilder();
93 | for (int i = length - 1; i >= 0; i--) {
94 | int mask = 1 << i;
95 | stringBuilder.append((data & mask) != 0 ? "1" : "0");
96 | }
97 | buffer += stringBuilder.toString();
98 | }
99 |
100 | public void setLong(long data, int length) {
101 | StringBuilder stringBuilder = new StringBuilder();
102 | for (int i = length - 1; i >= 0; i--) {
103 | long mask = 1L << i;
104 | stringBuilder.append((data & mask) != 0 ? "1" : "0");
105 | }
106 | buffer += stringBuilder.toString();
107 | }
108 |
109 | public void setString(String str) {
110 | byte[] bytes = str.getBytes(StandardCharsets.ISO_8859_1);
111 | StringBuilder stringBuilder = new StringBuilder();
112 | for (byte b : bytes) {
113 | stringBuilder.append(toBinaryString(b));
114 | }
115 | buffer += stringBuilder.toString();
116 | }
117 |
118 | public void setBitString(String str) {
119 | buffer += str;
120 | }
121 |
122 | public String getString(int length) {
123 | int pointer = this.pointer;
124 | this.pointer += length;
125 | byte[] bString = getByteByString(buffer.substring(pointer, this.pointer));
126 | return new String(bString, StandardCharsets.ISO_8859_1);
127 | }
128 |
129 | public byte[] getArrayFromBuffer() {
130 | return getByteByString(buffer);
131 | }
132 |
133 | private long toSignedLong(String bits) {
134 | int position = 0;
135 | long answer = 0;
136 |
137 | for (int i = bits.length() - 1; i > 0; i--) {
138 | if (bits.charAt(i) == '1')
139 | answer += (long) Math.pow(2, position);
140 | position++;
141 | }
142 | if (bits.charAt(0) == '1')
143 | answer += (long) Math.pow(2, position) * -1;
144 | return answer;
145 | }
146 |
147 | public int toSignedInt(String bits) {
148 | int position = 0;
149 | int answer = 0;
150 |
151 | for (int i = bits.length() - 1; i > 0; i--) {
152 | if (bits.charAt(i) == '1')
153 | answer += Math.pow(2, position);
154 | position++;
155 | }
156 | if (bits.charAt(0) == '1')
157 | answer += Math.pow(2, position) * -1;
158 | return answer;
159 | }
160 |
161 | private byte[] getByteByString(String binaryString) {
162 | Iterable iterable = Splitter.fixedLength(8).split(binaryString);
163 | byte[] ret = new byte[Iterables.size(iterable)];
164 | Iterator iterator = iterable.iterator();
165 | int i = 0;
166 | while (iterator.hasNext()) {
167 | Integer byteAsInt = Integer.parseInt(iterator.next(), 2);
168 | ret[i] = byteAsInt.byteValue();
169 | i++;
170 | }
171 | return ret;
172 | }
173 |
174 | public byte[] getByteArray() {
175 | Iterable iterable = Splitter.fixedLength(8).split(buffer);
176 | byte[] ret = new byte[Iterables.size(iterable)];
177 | Iterator iterator = iterable.iterator();
178 | int i = 0;
179 | while (iterator.hasNext()) {
180 | Integer byteAsInt = Integer.parseInt(iterator.next().toString(), 2);
181 | ret[i] = byteAsInt.byteValue();
182 | i++;
183 | }
184 | int shift = buffer.length() % 8;
185 | ret[i - 1] = (byte) (ret[i - 1] << (8 - shift));
186 |
187 | return ret;
188 | }
189 |
190 | @Override
191 | public String toString() {
192 | return buffer;
193 | }
194 |
195 | public String toString(char splitter) {
196 | StringBuilder builder = new StringBuilder();
197 | for (int i = 0; i < buffer.length(); i += 8) {
198 | builder.append(buffer, i, i + 8);
199 | builder.append(splitter);
200 | }
201 | return builder.toString();
202 | }
203 |
204 |
205 | }
206 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/protocols/rtcm/messages/MSG1027.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.protocols.rtcm.messages;
2 |
3 | import com.google.common.primitives.Bytes;
4 | import org.dav95s.openNTRIP.protocols.rtcm.assets.CRS3;
5 | import org.dav95s.openNTRIP.utils.binaryParse.BitUtils;
6 | import org.dav95s.openNTRIP.utils.binaryParse.Crc24q;
7 | import org.dav95s.openNTRIP.utils.binaryParse.Normalize;
8 |
9 | import static com.google.common.base.Preconditions.checkArgument;
10 |
11 | public class MSG1027 implements CRS3 {
12 |
13 | private int messageNumber;
14 | private int SystemIdentificationNumber;
15 | private int ProjectionType;
16 | private boolean RectificationFlag = false;
17 | private double LaPC;
18 | private double LoPC;
19 | private double AzIL;
20 | private double RectifiedToSkew;
21 | private double SILppm;
22 | private double EPC;
23 | private double NPC;
24 |
25 | public MSG1027() {
26 | messageNumber = 1027;
27 | }
28 |
29 | public MSG1027(byte[] msg) {
30 | BitUtils bitUtils = new BitUtils(msg);
31 | bitUtils.setPointer(24);
32 | messageNumber = bitUtils.getUnsignedInt(12);
33 | SystemIdentificationNumber = bitUtils.getUnsignedInt(8);
34 | ProjectionType = bitUtils.getUnsignedInt(6);
35 |
36 | RectificationFlag = (bitUtils.getBoolean());
37 | setLaPC(bitUtils.getSignedLong(34) * 0.000000011);
38 | setLoPC(bitUtils.getSignedLong(35) * 0.000000011);
39 | setAzIL(bitUtils.getUnsignedLong(35) * 0.000000011);
40 | if (RectificationFlag) {
41 | setRectifiedToSkew(bitUtils.getSignedInt(26) * 0.000000011 + AzIL);
42 | } else {
43 | setRectifiedToSkew(bitUtils.getSignedInt(26));
44 | }
45 | setSILppm((bitUtils.getUnsignedLong(30) * 0.00001d + 993000) / 1000000);
46 | setEPC(bitUtils.getUnsignedLong(36) * 0.001);
47 | setNPC(bitUtils.getSignedLong(35) * 0.001);
48 | }
49 |
50 | public byte[] getBytes() {
51 | BitUtils bitUtils = new BitUtils();
52 | bitUtils.setBitString("11010011000000"); //preamble + 6 reserved bit
53 | bitUtils.setInt(33, 10);
54 | bitUtils.setInt(messageNumber, 12);
55 | bitUtils.setInt(SystemIdentificationNumber, 8);
56 | bitUtils.setInt(ProjectionType, 6);
57 | bitUtils.setBoolean(RectificationFlag);
58 | bitUtils.setLong(Math.round(LaPC / 0.000000011), 34);
59 | bitUtils.setLong(Math.round(LoPC / 0.000000011), 35);
60 | bitUtils.setLong(Math.round(AzIL / 0.000000011), 35);
61 | if (RectificationFlag) {
62 | bitUtils.setLong(Math.round((RectifiedToSkew - AzIL) / 0.000000011), 26);
63 | } else {
64 | bitUtils.setLong(0, 26);
65 | }
66 | bitUtils.setLong(Math.round((SILppm * 1000000 - 993000) / 0.00001d), 30);
67 | bitUtils.setLong(Math.round(EPC / 0.001), 36);
68 | bitUtils.setLong(Math.round(NPC / 0.001), 35);
69 |
70 | byte[] bytes = bitUtils.getByteArray();
71 | return Bytes.concat(bytes, Crc24q.crc24q(bytes, bytes.length, 0));
72 | }
73 |
74 | public int getMessageNumber() {
75 | return messageNumber;
76 | }
77 |
78 | public int getSystemIdentificationNumber() {
79 | return SystemIdentificationNumber;
80 | }
81 |
82 | public void setSystemIdentificationNumber(int systemIdentificationNumber) {
83 | checkArgument(0 <= systemIdentificationNumber && systemIdentificationNumber <= 255);
84 | SystemIdentificationNumber = systemIdentificationNumber;
85 | }
86 |
87 | public int getProjectionType() {
88 | return ProjectionType;
89 | }
90 |
91 | public void setProjectionType(int projectionType) {
92 | checkArgument(0 <= projectionType && projectionType <= 11);
93 | ProjectionType = projectionType;
94 | }
95 |
96 | public double getLaPC() {
97 | return LaPC;
98 | }
99 |
100 | public void setLaPC(double laPC) {
101 | double normalized = Normalize.normalize(laPC, 8);
102 | checkArgument(-90 <= normalized && normalized <= 90);
103 | LaPC = normalized;
104 | }
105 |
106 | public double getLoPC() {
107 | return LoPC;
108 | }
109 |
110 | public void setLoPC(double loPC) {
111 | double normalized = Normalize.normalize(loPC, 8);
112 | checkArgument(-180 <= normalized && normalized <= 180);
113 | LoPC = normalized;
114 | }
115 |
116 | public double getAzIL() {
117 | return AzIL;
118 | }
119 |
120 | public void setAzIL(double azIL) {
121 | double normalized = Normalize.normalize(azIL, 8);
122 | checkArgument(0 <= normalized && normalized <= 360);
123 | AzIL = normalized;
124 | }
125 |
126 | public double getRectifiedToSkew() {
127 | return RectifiedToSkew;
128 | }
129 |
130 | public void setRectifiedToSkew(double rectifiedToSkew) {
131 | double normalized = Normalize.normalize(rectifiedToSkew, 8);
132 | checkArgument(-0.369098741 <= normalized - AzIL && normalized - AzIL <= 0.369098741);
133 | RectificationFlag = true;
134 | RectifiedToSkew = normalized;
135 | }
136 |
137 | public double getSILppm() {
138 | return SILppm;
139 | }
140 |
141 | public void setSILppm(double SILppm) {
142 | double normalized = Normalize.normalize(SILppm, 9);
143 | checkArgument(0.993 <= normalized && normalized <= 1.003737418);
144 | this.SILppm = normalized;
145 | }
146 |
147 | public double getEPC() {
148 | return EPC;
149 | }
150 |
151 | public void setEPC(double EPC) {
152 | double normalized = Normalize.normalize(EPC, 3);
153 | checkArgument(0 <= normalized && normalized <= 68719476.735);
154 | this.EPC = normalized;
155 | }
156 |
157 | public double getNPC() {
158 | return NPC;
159 | }
160 |
161 | public void setNPC(double NPC) {
162 | double normalized = Normalize.normalize(NPC, 3);
163 | checkArgument(-17179869.183 <= normalized && normalized <= 17179869.183);
164 | this.NPC = normalized;
165 | }
166 |
167 | @Override
168 | public String toString() {
169 | return "MSG1027{" +
170 | "messageNumber=" + messageNumber +
171 | ", SystemIdentificationNumber=" + SystemIdentificationNumber +
172 | ", ProjectionType=" + ProjectionType +
173 | ", RectificationFlag=" + RectificationFlag +
174 | ", LaPC=" + LaPC +
175 | ", LoPC=" + LoPC +
176 | ", AzIL=" + AzIL +
177 | ", RectifiedToSkew=" + RectifiedToSkew +
178 | ", SIL=" + SILppm +
179 | ", EPC=" + EPC +
180 | ", NPC=" + NPC +
181 | '}';
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/src/test/java/org/dav95s/openNTRIP/utils/Geoids/GGFTest.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.utils.Geoids;
2 |
3 | import org.dav95s.openNTRIP.crs.geoids.GGF;
4 | import org.junit.Assert;
5 | import org.junit.Test;
6 |
7 | import static org.dav95s.openNTRIP.utils.geometry.AngleTools.dmsToDecimal;
8 |
9 | public class GGFTest {
10 |
11 | @Test
12 | public void testSpb() {
13 | GGF ggf = new GGF("src/test/resources/geoids/spb.GGF");
14 | Assert.assertEquals(15.86201, ggf.getValueByPoint(60, 30), 0.00001);
15 | Assert.assertEquals(15.84909, ggf.getValueByPoint(dmsToDecimal(60, 1), dmsToDecimal(30, 1)), 0.00001);
16 | Assert.assertEquals(15.83819, ggf.getValueByPoint(dmsToDecimal(60, 2), dmsToDecimal(30, 2)), 0.00001);
17 | Assert.assertEquals(15.79763, ggf.getValueByPoint(dmsToDecimal(60, 2), dmsToDecimal(31, 2)), 0.00001);
18 |
19 | Assert.assertEquals(15.79657, ggf.getValueByPoint(dmsToDecimal(60, 2, 10), dmsToDecimal(31, 2, 10)), 0.00001);
20 | Assert.assertEquals(15.79553, ggf.getValueByPoint(dmsToDecimal(60, 2, 20), dmsToDecimal(31, 2, 20)), 0.00001);
21 | Assert.assertEquals(15.79450, ggf.getValueByPoint(dmsToDecimal(60, 2, 30), dmsToDecimal(31, 2, 30)), 0.00001);
22 | Assert.assertEquals(15.79349, ggf.getValueByPoint(dmsToDecimal(60, 2, 40), dmsToDecimal(31, 2, 40)), 0.00001);
23 | Assert.assertEquals(15.79250, ggf.getValueByPoint(dmsToDecimal(60, 2, 50), dmsToDecimal(31, 2, 50)), 0.00001);
24 | Assert.assertEquals(15.78683, ggf.getValueByPoint(dmsToDecimal(60, 3, 55), dmsToDecimal(31, 3, 55)), 0.00001);
25 | Assert.assertEquals(15.85548, ggf.getValueByPoint(dmsToDecimal(60, 0, 30), dmsToDecimal(30, 0, 30)), 0.00001);
26 | }
27 |
28 | @Test
29 | public void testEngland() {
30 | GGF ggf = new GGF("src/test/resources/geoids/england.GGF");
31 | Assert.assertEquals(45.00320, ggf.getValueByPoint(51, 1), 0.00001);
32 | Assert.assertEquals(46.41333, ggf.getValueByPoint(51, -1), 0.00001);
33 |
34 |
35 | Assert.assertEquals(44.99883, ggf.getValueByPoint(dmsToDecimal(51, 3), dmsToDecimal(1, 3)), 0.00001);
36 | Assert.assertEquals(44.99875, ggf.getValueByPoint(dmsToDecimal(51, 3,10), dmsToDecimal(1, 3,10)), 0.00001);
37 | Assert.assertEquals(44.99867, ggf.getValueByPoint(dmsToDecimal(51, 3,20), dmsToDecimal(1, 3,20)), 0.00001);
38 | Assert.assertEquals(44.99857, ggf.getValueByPoint(dmsToDecimal(51, 3,30), dmsToDecimal(1, 3,30)), 0.00001);
39 | Assert.assertEquals(44.99847, ggf.getValueByPoint(dmsToDecimal(51, 3,40), dmsToDecimal(1, 3,40)), 0.00001);
40 | Assert.assertEquals(44.99836, ggf.getValueByPoint(dmsToDecimal(51, 3,50), dmsToDecimal(1, 3,50)), 0.00001);
41 | Assert.assertEquals(44.99830, ggf.getValueByPoint(dmsToDecimal(51, 3,55), dmsToDecimal(1, 3,55)), 0.00001);
42 |
43 | Assert.assertEquals(46.54407, ggf.getValueByPoint(dmsToDecimal(51, 3), dmsToDecimal(-1, 3)), 0.00001);
44 | Assert.assertEquals(46.55101, ggf.getValueByPoint(dmsToDecimal(51, 3,10), dmsToDecimal(-1, 3,10)), 0.00001);
45 | Assert.assertEquals(46.55794, ggf.getValueByPoint(dmsToDecimal(51, 3,20), dmsToDecimal(-1, 3,20)), 0.00001);
46 | Assert.assertEquals(46.56487, ggf.getValueByPoint(dmsToDecimal(51, 3,30), dmsToDecimal(-1, 3,30)), 0.00001);
47 | Assert.assertEquals(46.57180, ggf.getValueByPoint(dmsToDecimal(51, 3,40), dmsToDecimal(-1, 3,40)), 0.00001);
48 | Assert.assertEquals(46.57872, ggf.getValueByPoint(dmsToDecimal(51, 3,50), dmsToDecimal(-1, 3,50)), 0.00001);
49 | Assert.assertEquals(46.58218, ggf.getValueByPoint(dmsToDecimal(51, 3,55), dmsToDecimal(-1, 3,55)), 0.00001);
50 | }
51 |
52 | @Test
53 | public void testAustralia() {
54 | GGF ggf = new GGF("src/test/resources/geoids/australia.GGF");
55 | Assert.assertEquals(35.06186, ggf.getValueByPoint(-16, 130), 0.00001);
56 | Assert.assertEquals(35.06186, ggf.getValueByPoint(-16, 130), 0.00001);
57 |
58 | Assert.assertEquals(29.24346, ggf.getValueByPoint(dmsToDecimal(-16,55, 2), dmsToDecimal(125,58, 23)), 0.00001);
59 | Assert.assertEquals(29.78914, ggf.getValueByPoint(dmsToDecimal(-16,30, 10), dmsToDecimal(125,30, 10)), 0.00001);
60 | Assert.assertEquals(29.78705, ggf.getValueByPoint(dmsToDecimal(-16,30, 20), dmsToDecimal(125,30, 20)), 0.00001);
61 | Assert.assertEquals(29.78502, ggf.getValueByPoint(dmsToDecimal(-16,30, 30), dmsToDecimal(125,30, 30)), 0.00001);
62 | Assert.assertEquals(29.78306, ggf.getValueByPoint(dmsToDecimal(-16,30, 40), dmsToDecimal(125,30, 40)), 0.00001);
63 | Assert.assertEquals(29.78115, ggf.getValueByPoint(dmsToDecimal(-16,30, 50), dmsToDecimal(125,30, 50)), 0.00001);
64 | Assert.assertEquals(29.78023, ggf.getValueByPoint(dmsToDecimal(-16,30, 55), dmsToDecimal(125,30, 55)), 0.00001);
65 | }
66 |
67 | @Test
68 | public void testFlorida() {
69 | GGF ggf = new GGF("src/test/resources/geoids/florida.GGF");
70 | Assert.assertEquals(-27.37862, ggf.getValueByPoint(28, -82), 0.00001);
71 | Assert.assertEquals(-29.32500, ggf.getValueByPoint(28, -81), 0.00001);
72 | Assert.assertEquals(-29.06320, ggf.getValueByPoint(dmsToDecimal(28,30,10), dmsToDecimal(-81,30,10)), 0.00001);
73 | Assert.assertEquals(-29.05826, ggf.getValueByPoint(dmsToDecimal(28,30,20), dmsToDecimal(-81,30,20)), 0.00001);
74 | Assert.assertEquals(-29.05338, ggf.getValueByPoint(dmsToDecimal(28,30,30), dmsToDecimal(-81,30,30)), 0.00001);
75 | Assert.assertEquals(-29.04858, ggf.getValueByPoint(dmsToDecimal(28,30,40), dmsToDecimal(-81,30,40)), 0.00001);
76 | Assert.assertEquals(-29.04384, ggf.getValueByPoint(dmsToDecimal(28,30,50), dmsToDecimal(-81,30,50)), 0.00001);
77 | Assert.assertEquals(-29.04149, ggf.getValueByPoint(dmsToDecimal(28,30,55), dmsToDecimal(-81,30,55)), 0.00001);
78 | }
79 |
80 | @Test
81 | public void testBering() {
82 | GGF ggf = new GGF("src/test/resources/geoids/bering.GGF");
83 | Assert.assertEquals(4.85217, ggf.getValueByPoint(63, 180), 0.00001);
84 | Assert.assertEquals(5.54611, ggf.getValueByPoint(63, 179), 0.00001);
85 | Assert.assertEquals(5.03305, ggf.getValueByPoint(63, -179), 0.00001);
86 | Assert.assertEquals(4.43816, ggf.getValueByPoint(dmsToDecimal(63,30,10), dmsToDecimal(-178,30,10)), 0.00001);
87 | Assert.assertEquals(4.43570, ggf.getValueByPoint(dmsToDecimal(63,30,20), dmsToDecimal(-178,30,20)), 0.00001);
88 | Assert.assertEquals(4.43325, ggf.getValueByPoint(dmsToDecimal(63,30,30), dmsToDecimal(-178,30,30)), 0.00001);
89 | Assert.assertEquals(4.43083, ggf.getValueByPoint(dmsToDecimal(63,30,40), dmsToDecimal(-178,30,40)), 0.00001);
90 | Assert.assertEquals(4.42842, ggf.getValueByPoint(dmsToDecimal(63,30,50), dmsToDecimal(-178,30,50)), 0.00001);
91 | Assert.assertEquals(4.42722, ggf.getValueByPoint(dmsToDecimal(63,30,55), dmsToDecimal(-178,30,55)), 0.00001);
92 | Assert.assertEquals(4.42710, ggf.getValueByPoint(dmsToDecimal(63,30, 55.5F), dmsToDecimal(-178,30,55.5F)), 0.00001);
93 |
94 | }
95 |
96 | }
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/crs/gridShift/ResidualsGrid.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.crs.gridShift;
2 |
3 | import com.harium.storage.kdtree.KDTree;
4 | import com.harium.storage.kdtree.KeyDuplicateException;
5 | import com.harium.storage.kdtree.KeySizeException;
6 | import org.dav95s.openNTRIP.crs.geoids.GGF;
7 | import org.dav95s.openNTRIP.crs.geoids.IGeoid;
8 | import org.dav95s.openNTRIP.database.models.CrsModel;
9 | import org.dav95s.openNTRIP.database.models.GridModel;
10 | import org.dav95s.openNTRIP.protocols.nmea.NMEA;
11 | import org.dav95s.openNTRIP.utils.binaryParse.Normalize;
12 | import org.json.JSONArray;
13 | import org.json.JSONObject;
14 | import org.slf4j.Logger;
15 | import org.slf4j.LoggerFactory;
16 |
17 | import java.util.ArrayList;
18 | import java.util.Arrays;
19 | import java.util.List;
20 |
21 | public class ResidualsGrid {
22 | private final Logger logger = LoggerFactory.getLogger(ResidualsGrid.class.getName());
23 | //crs boundary box
24 | double area_top;
25 | double area_bottom;
26 | double area_left;
27 | double area_right;
28 | //number of points in the grid
29 | int colCount;
30 | int rowCount;
31 | //resolution of the grid
32 | double dLat0 = 0.004167;
33 | double dLon0 = 0.008333;
34 |
35 | IGeoid geoid;
36 |
37 | // [0],[1],[2],[3],[4],[5],[6],...[N]
38 | // [N+1],[N+2],[N+3],[N+4],[N+5],[N+6],[N+7],...
39 | GridNode[][] grid;
40 |
41 | public ResidualsGrid(int crs_id, JSONObject json, CrsModel model) {
42 | geoid = initGeoid(model.getGeoidPath());
43 | JSONObject validArea = json.getJSONObject("AreaOfValidity");
44 | double latC = validArea.getDouble("LatCenter");
45 | double lonC = validArea.getDouble("LonCenter");
46 | double height = validArea.getDouble("Height");
47 | double width = validArea.getDouble("Width");
48 |
49 | //crs boundary
50 | area_top = latC + height / 2;
51 | area_bottom = latC - height / 2;
52 | area_left = lonC - width / 2;
53 | area_right = lonC + width / 2;
54 |
55 | if (area_left < -180)
56 | area_left += 360;
57 |
58 | if (area_left > 180)
59 | area_left -= 360;
60 |
61 | if (area_right < -180)
62 | area_right += 360;
63 |
64 | if (area_right > 180)
65 | area_right -= 360;
66 |
67 | //resolution of crs grid
68 | colCount = (int) (Math.abs(area_right - area_left) / dLon0);
69 | rowCount = (int) (Math.abs(area_top - area_bottom) / dLat0);
70 |
71 | grid = new GridNode[rowCount][colCount];
72 |
73 | initGrid(crs_id);
74 | backupGrid(model);
75 |
76 | }
77 |
78 | private void initGrid(int crs_id) {
79 | KDTree kdTree = new KDTree<>(2);
80 | GridModel gridModel = new GridModel();
81 |
82 | //get from db all geodetic point
83 | ArrayList points = gridModel.getAddGeodeticPointByCrsId(crs_id);
84 | //create spatial index
85 | for (GeodeticPoint point : points) {
86 | try {
87 | kdTree.insert(new double[]{point.north, point.east}, point);
88 | } catch (KeySizeException | KeyDuplicateException e) {
89 | e.printStackTrace();
90 | }
91 | }
92 |
93 | //delete array from memory
94 | points = null;
95 |
96 | //generate grid
97 | for (int row = 0; row < rowCount; row++) {
98 | for (int col = 0; col < colCount; col++) {
99 | try {
100 | double nodeLat = area_top - row * dLat0;
101 | double nodeLon = area_left + col * dLon0;
102 | //get nearest geodetic point for node of grid
103 | List nearestPoints = kdTree.nearest(new double[]{nodeLat, nodeLon}, 5);
104 | //init node of grid
105 | grid[row][col] = IDW(nearestPoints, nodeLat, nodeLon);
106 | grid[row][col].height = geoid.getValueByPoint(nodeLat, nodeLon);
107 | } catch (KeySizeException e) {
108 | e.printStackTrace();
109 | }
110 | }
111 | }
112 |
113 |
114 | }
115 |
116 | private GridNode IDW(List gridNodes, double nodeLat, double nodeLon) {
117 | double sum = 0;
118 | for (GeodeticPoint gridNode : gridNodes) {
119 | sum += gridNode.distance(nodeLat, nodeLon);
120 | }
121 |
122 | sum = 1 / sum;
123 |
124 | for (GeodeticPoint GeodeticPoint : gridNodes) {
125 | GeodeticPoint.distance = 1 / GeodeticPoint.distance / sum;
126 | }
127 |
128 | GridNode response = new GridNode();
129 | response.north = Normalize.normalize(nodeLat, 9);
130 | response.east = Normalize.normalize(nodeLon, 9);
131 | response.dEast = 0;
132 | response.dNorth = 0;
133 |
134 | for (GeodeticPoint gridNode : gridNodes) {
135 | response.dNorth += gridNode.dNorth * gridNode.distance;
136 | response.dEast += gridNode.dEast * gridNode.distance;
137 | }
138 |
139 | response.dNorth = Normalize.normalize(response.dNorth, 9);
140 | response.dEast = Normalize.normalize(response.dEast, 9);
141 |
142 | return response;
143 | }
144 |
145 | public void backupGrid(CrsModel model) {
146 | JSONObject jsonObject = new JSONObject();
147 | jsonObject.put("top", area_top);
148 | jsonObject.put("bottom", area_bottom);
149 | jsonObject.put("left", area_left);
150 | jsonObject.put("right", area_right);
151 | jsonObject.put("gridWidth", dLon0);
152 | jsonObject.put("gridHeight", dLat0);
153 | jsonObject.put("zone", new JSONArray());
154 |
155 | JSONArray gridJson = new JSONArray();
156 | for (int row = 0; row < rowCount; row++) {
157 | for (int col = 0; col < colCount; col++) {
158 | JSONArray cell = new JSONArray();
159 | cell.put(grid[row][col].dNorth);
160 | cell.put(grid[row][col].dEast);
161 | cell.put(grid[row][col].dH);
162 | gridJson.put(cell);
163 | }
164 | }
165 | jsonObject.put("grid", gridJson);
166 | model.setResidualGrid(jsonObject.toString());
167 | model.update();
168 | }
169 |
170 | public GridNode[] get16PointsAroundUser(NMEA.GPSPosition user) {
171 | ArrayList grid16 = new ArrayList<>(16);
172 | int lon = (int) Normalize.normalize((user.lon - area_left) / dLon0, 4) - 1;
173 | int lat = (int) Normalize.normalize((user.lat - area_top) / dLat0, 4) - 1;
174 | for (int x = 0; x < 4; x++) {
175 | grid16.addAll(Arrays.asList(grid[lat + x]).subList(lon, 4 + lon));
176 | }
177 | return grid16.toArray(new GridNode[16]);
178 | }
179 |
180 | private IGeoid initGeoid(String geoidPath) {
181 | return new GGF(geoidPath);
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/src/main/java/org/dav95s/openNTRIP/database/models/MountPointModel.java:
--------------------------------------------------------------------------------
1 | package org.dav95s.openNTRIP.database.models;
2 |
3 |
4 | import org.dav95s.openNTRIP.database.DataSource;
5 | import org.dav95s.openNTRIP.database.models.assets.Authenticator;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import java.sql.Connection;
10 | import java.sql.PreparedStatement;
11 | import java.sql.ResultSet;
12 | import java.sql.SQLException;
13 | import java.util.ArrayList;
14 |
15 | public class MountPointModel {
16 | final static private Logger logger = LoggerFactory.getLogger(MountPointModel.class.getName());
17 |
18 | protected int id;
19 | protected String name;
20 | protected String identifier;
21 | protected String format;
22 | protected String format_details;
23 | protected int carrier;
24 | protected String nav_system;
25 | protected String network;
26 | protected String country;
27 | protected double lat;
28 | protected double lon;
29 | protected boolean nmea;
30 | protected boolean solution;
31 | protected String generator;
32 | protected String compression;
33 | protected Authenticator authenticator;
34 | protected boolean fee;
35 | protected int bitRate;
36 | protected String misc;
37 | protected int caster_id;
38 | protected boolean available;
39 | protected int plugin_id;
40 | protected ArrayList referenceStationIds = new ArrayList<>();
41 |
42 | public MountPointModel(String name) {
43 | this.name = name;
44 | }
45 |
46 | @Override
47 | public String toString() {
48 | return "STR" + ';' + getName() + ';' + getIdentifier() + ';' + getFormat() + ';' + getFormat_details() + ';' + getCarrier() + ';' + getNav_system() + ';' + getNetwork() + ';' + getCountry()
49 | + ';' + String.format("%.2f", getLat()) + ';' + String.format("%.2f", getLon()) + ';' + (isNmea() ? 1 : 0) + ';' + (isSolution() ? 1 : 0) + ';' + getGenerator() + ';' + getCompression()
50 | + ';' + authenticator + ';' + (isFee() ? 'Y' : 'N') + ';' + getBitRate() + ';' + getMisc() + "\r\n";
51 | }
52 |
53 | public boolean read() {
54 | String sql = "SELECT *, " +
55 | "(SELECT `name` FROM `reference_stations` WHERE `id` = station_id) AS `stations` " +
56 | "FROM mountpoints " +
57 | "LEFT JOIN mountpoints_stations " +
58 | "ON mountpoints.id=mountpoints_stations.mountpoint_id " +
59 | "WHERE `name` = ?;";
60 |
61 | try (Connection con = DataSource.getConnection();
62 | PreparedStatement statement = con.prepareStatement(sql)) {
63 |
64 | statement.setString(1, name);
65 |
66 | try (ResultSet rs = statement.executeQuery()) {
67 | if (rs.next()) {
68 | id = rs.getInt("id");
69 | identifier = rs.getString("identifier");
70 | format = rs.getString("format");
71 | format_details = rs.getString("format_details");
72 | carrier = rs.getInt("carrier");
73 | nav_system = rs.getString("nav_system");
74 | network = rs.getString("network");
75 | country = rs.getString("country");
76 | lat = rs.getDouble("latitude");
77 | lon = rs.getDouble("longitude");
78 | nmea = rs.getBoolean("nmea");
79 | solution = rs.getBoolean("solution");
80 | generator = rs.getString("generator");
81 | compression = rs.getString("compression");
82 | setAuthenticator(rs.getString("authenticator"));
83 | fee = rs.getBoolean("fee");
84 | bitRate = rs.getInt("bitrate");
85 | misc = rs.getString("misc");
86 | caster_id = rs.getInt("caster_id");
87 | available = rs.getBoolean("available");
88 | plugin_id = rs.getInt("plugin_id");
89 | referenceStationIds.add(rs.getString("stations"));
90 | } else {
91 | return false;
92 | }
93 |
94 | while (rs.next()) {
95 | referenceStationIds.add(rs.getString("stations"));
96 | }
97 | return true;
98 | }
99 |
100 | } catch (SQLException e) {
101 | logger.error("SQL Error", e);
102 | return false;
103 | }
104 | }
105 |
106 | public ArrayList getReferenceStationIds() {
107 | return referenceStationIds;
108 | }
109 |
110 | public int getId() {
111 | return this.id;
112 | }
113 |
114 | public String getName() {
115 | return this.name;
116 | }
117 |
118 | public String getIdentifier() {
119 | return this.identifier;
120 | }
121 |
122 | public String getFormat() {
123 | return this.format;
124 | }
125 |
126 | public String getFormat_details() {
127 | return this.format_details;
128 | }
129 |
130 | public int getCarrier() {
131 | return this.carrier;
132 | }
133 |
134 | public String getNav_system() {
135 | return this.nav_system;
136 | }
137 |
138 | public String getNetwork() {
139 | return this.network;
140 | }
141 |
142 | public String getCountry() {
143 | return this.country;
144 | }
145 |
146 | public double getLat() {
147 | return this.lat;
148 | }
149 |
150 | public double getLon() {
151 | return this.lon;
152 | }
153 |
154 | public boolean isNmea() {
155 | return this.nmea;
156 | }
157 |
158 | public boolean isSolution() {
159 | return this.solution;
160 | }
161 |
162 | public String getGenerator() {
163 | return this.generator;
164 | }
165 |
166 | public String getCompression() {
167 | return this.compression;
168 | }
169 |
170 | public Authenticator getAuthenticator() {
171 | return this.authenticator;
172 | }
173 |
174 | private void setAuthenticator(String authenticator) {
175 | switch (authenticator) {
176 | case "B":
177 | case "Basic":
178 | this.authenticator = Authenticator.Basic;
179 | break;
180 | case "D":
181 | case "Digest":
182 | this.authenticator = Authenticator.Digest;
183 | break;
184 | default:
185 | this.authenticator = Authenticator.None;
186 | break;
187 | }
188 | }
189 |
190 | public boolean isFee() {
191 | return this.fee;
192 | }
193 |
194 | public int getBitRate() {
195 | return this.bitRate;
196 | }
197 |
198 | public String getMisc() {
199 | return this.misc;
200 | }
201 |
202 | public int getCaster_id() {
203 | return this.caster_id;
204 | }
205 |
206 | public boolean isAvailable() {
207 | return this.available;
208 | }
209 |
210 | public int getPlugin_id() {
211 | return this.plugin_id;
212 | }
213 | }
214 |
215 |
216 |
--------------------------------------------------------------------------------