Commit c57a59b1 authored by Laurent Monribot's avatar Laurent Monribot
Browse files

Adding TestModules

parent 1ced5526
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>LoraServer</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.5
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>lacl.fr</groupId>
<artifactId>LoraServer</artifactId>
<version>0.0.1</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<log4j-version>1.2.17</log4j-version>
<jdk-version>1.8</jdk-version>
</properties>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j-version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.16.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.fge/json-schema-validator -->
<dependency>
<groupId>com.github.fge</groupId>
<artifactId>json-schema-validator</artifactId>
<version>2.2.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.json/javax.json-api -->
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>com.udojava</groupId>
<artifactId>JMXWrapper</artifactId>
<version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.8.1</version>
</dependency>
<dependency>
<groupId>org.jsonschema2pojo</groupId>
<artifactId>jsonschema2pojo-core</artifactId>
<version>0.4.35</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>${jdk-version}</source>
<target>${jdk-version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.5.0</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<!--classpathPrefix>lib/</classpathPrefix -->
<mainClass>loraserver.LoraServer</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>loraserver.LoraServer</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>simple-command</id>
<phase>package</phase>
<goals>
<goal>attached</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build></project>
\ No newline at end of file
package loraserver;
/**
* This is the object containing constants values for LoraWan messages headers.
* These constants are used for distinguish types of messages exchanged between a gateway and a server.
* Described in the <b>Semtech</b> documentation : <b>ANNWS.01.2.1.W.SYS</b> "Gateway to server interface".
* @author Laurent Monribot
* @version 0.0.0
*/
public class Constants {
public final static byte MES_ID_PUSH_DATA = 0x00; //PUSH_DATA
public final static byte MES_ID_PUSH_ACK = 0x01; // PUSH_ACK
public final static byte MES_ID_PULL_DATA = 0x02; // PULL_DATA
public final static byte MES_ID_PULL_RESP = 0x03; // PULL_RESP
public final static byte MES_ID_PULL_ACK = 0x04; // PULL_ACK
public final static byte MES_ID_TX_ACK = 0x05; // TX_ACK
}
package loraserver;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import org.apache.log4j.Logger;
public class LoraServer {
private static final int BUFFER_RECEPTION_SIZE = 2048;
private final static Logger logger = Logger.getLogger(LoraServer.class);
private DatagramSocket socket;
public LoraServer() {
try {
socket = new DatagramSocket();
socket.setSoTimeout(10);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void sendudp(byte[] datagram, InetAddress adr, int port) {
try {
DatagramPacket packet;
packet = new DatagramPacket(datagram, datagram.length, adr, port);
socket.send(packet);
} catch (SocketException e) { // for the new Datagram...()
logger.error(e.getMessage());
} catch (IOException e) { // for the send()
logger.error(e.getMessage() + " Address : " + adr.getHostAddress() + " Port : " + port);
}
}
private DatagramPacket listen() {
boolean somethingReceived = false;
byte[] buffer = new byte[BUFFER_RECEPTION_SIZE];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
try {
socket.receive(packet);
if(packet.getLength()>0) somethingReceived = true;
} catch (SocketTimeoutException e) {
//logger.warn(e.getMessage());
} catch (IOException e) {
logger.warn(e.getMessage());
}
if (!somethingReceived)
return null;
return packet;
}
private void treatMessage(DatagramPacket packet) {
byte[] content, destination = null;
String document1 = "{" + "\"imme\":10," + "\"freq\":869.3," + "\"rfch\":0," + "\"powe\":12,"
+ "\"modu\":\"LORA\"," + "\"datr\":\"SF11BW125\"," /*+ "\"fdev\":3000,"*/ + "\"size\":32,"
+ "\"data\":\"H3P3N2i9qc4yt7rK7ldqoeCVJGBybzPY5h1Dd7P7p8v\"" + "}";
String document2 = "[{\"txpk\":{" + "\"imme\":10," + "\"freq\":861.3," + "\"rfch\":0," + "\"powe\":12,"
+ "\"modu\":\"LORA\"," + "\"datr\":50000," + "\"ipol\":true," + "\"size\":32,"
+ "\"data\":\"H3P3N2i9qc4yt7rK7ldqoeCVJGBybzPY5h1Dd7P7p8v\"" + "}}]";
byte[] receivedData = packet.getData();
if (receivedData[0] == 0x01 || receivedData[0] == 0x02) {
if(receivedData[3] == Constants.MES_ID_PULL_DATA){
byte[] header = new byte[12];
// PULL_RESP has tow way interpreting token value (set to 0 in
// V1 and set to token PULL in V2)
header[3] = Constants.MES_ID_PULL_ACK;
header[0] = 0x01;
header[1] = receivedData[1];
header[2] = receivedData[2];
header[4] = receivedData[4];
header[5] = receivedData[5];
header[6] = receivedData[6];
header[7] = receivedData[7];
header[8] = receivedData[8];
header[9] = receivedData[9];
header[10] = receivedData[10];
header[11] = receivedData[11];
sendudp(header, packet.getAddress(), packet.getPort());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] header2 = new byte[4];
header2[3] = Constants.MES_ID_PULL_RESP;
header2[0] = 0x01;
header2[1] = 0;
header2[2] = 0;
// V2 :
//header2[0] = 0x02;
//header2[1] = receivedData[1];
//header2[2] = receivedData[2];
content = document1.getBytes();
logger.debug("JSON PART : " + new String(content));
// Create a destination array that is the size of the two arrays
destination = new byte[header2.length + content.length];
System.arraycopy(header2, 0, destination, 0, header2.length);
System.arraycopy(content, 0, destination, header2.length, content.length);
sendudp(destination, packet.getAddress(), packet.getPort());
for(int i = 0; i<10; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sendudp(destination, packet.getAddress(), packet.getPort());
}
}
if(receivedData[3] == Constants.MES_ID_PUSH_DATA){
byte[] header = new byte[4];
header[3] = Constants.MES_ID_PUSH_ACK;
header[0] = 0x01;
// V2 :
//header[0] = 0x02;
header[1] = receivedData[1];
header[2] = receivedData[2];
sendudp(header, packet.getAddress(), packet.getPort());
logger.debug("MES_ID_PUSH_ACK sent");
int jsonOffset = 12; // why the offset is 12 bytes ? This is unknown...
byte[] jsonPart = new byte[packet.getLength()-jsonOffset];
for(int i=0; i<packet.getLength()-jsonOffset; i++){
jsonPart[i] = receivedData[i+jsonOffset];
}
logger.debug(new String(jsonPart));
}
}
}
public void loop() {
DatagramPacket packet = null;
int port = 1700;
try {
socket = new DatagramSocket(port);
socket.setSoTimeout(100);
logger.debug(" En ecoute sur le port : " + port);
while (true) {
packet = listen();
if (packet != null && packet.getData().length != 0) {
logger.info("Message recu de la gateway " + packet.getAddress() + " : " + packet.getPort());
treatMessage(packet);
}
}
} catch (SocketException e) { // for the new DatagramSocket()
logger.error(e.getMessage());
}
socket.close();
socket = null;
}
public static void main(String[] argv) {
LoraServer loraServer = new LoraServer();
loraServer.loop();
}
}
\ No newline at end of file
# Root logger option
log4j.rootLogger=DEBUG, stdout, file
# Redirect log messages to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
# Redirect log messages to a log file, support file rolling.
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=log4j-application.log
log4j.appender.file.MaxFileSize=5MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
\ No newline at end of file
Modules for testing the LWGW
============================
lora_chisterapi_java
--------------------
This is the tiny Iot mockup
This application works on a Raspberry Pi 2 the ChisteraPi card from Snootlab.
You have to install :
* the wiringPi library to connect the Chistera Pi card
The makefile is to make the library working with RADIOHEAD
Just go in src/ to make the program with javac.
And start the Iot mockup with send.sh
LoraServer
----------
This is the tiny server mockup
Build it with eclipse and execute it from your PC.
It listens PULL mesages coming from the LWGW gateway on port 1700.
It acknowledges PULL messages and then sends command to the LWGW gateway.
newLibBasedOnSCPF
-----------------
Just launch the Makefile to make the lib and place it in the target directory of the LWGW project. This library can listen much more types of Iot than the Radiohead based lib (it certainly depends from preambule symbols of radio frames). This lib cannot execute broadcast radio messages that can be found in servers' commands.
Go on and enjoy !
\ No newline at end of file
TARGET=libchisterapi.so
CC=gcc
CXX=g++
RM=rm -f
INCLUDES_PATH=-I lib/radiohead/ -I /usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt/include -I /usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt/include/linux
CPPFLAGS=-g -Wall -DRH_PLATFORM=RH_PLATFORM_RPI -D__RASPBERRY_PI_ $(INCLUDES_PATH)
CFLAGS=-g -Wall -DRH_PLATFORM=RH_PLATFORM_RPI -D__RASPBERRY_PI_ $(INCLUDES_PATH)
LDFLAGS=-lwiringPi
RH95_SRCS=lib/radiohead/RH_RF95.cpp \
lib/radiohead/RHGenericSPI.cpp \
lib/radiohead/RHLinuxSPI.cpp \
lib/radiohead/RHGenericDriver.cpp
RH95_OBJS=$(subst .cpp,.o,$(RH95_SRCS))
all: $(TARGET)
$(TARGET): src/chisterapi-util.o src/Chisterapi.o $(RH95_OBJS)
$(CXX) $(LDFLAGS) -shared -o $@ $^
%.o: %.cpp
$(CXX) $(CPPFLAGS) -fpic -o $@ -c $<
%.o: %.c
$(CC) $(CFLAGS) -fpic -o $@ -c $<
clean:
$(RM) -f $(TARGET) $(RH95_OBJS) src/*.o
LoRa ChisteraPi
=============
LoRa ChisteraPi is the source code for LoRa transmissions with ChisteraPi.
Products
-------
ChisteraPi light LoRa : https://snootlab.com/shields-snootlab/1151-.html
ChisteraPi + accessories LoRa : https://snootlab.com/shields-snootlab/1152-.html
Forums
-------
Visit our specific forum at :
http://forum.snootlab.com/viewforum.php?f=59
Topic
-------
To get more informations visit our topic at :
http://forum.snootlab.com/viewtopic.php?f=59&t=1512
Links
-------
The original Radiohead library is under GPLv2 license.
http://www.airspayce.com/mikem/arduino/RadioHead/
Modifications and examples come from Snootlab with GPLv2 license.
https://snootlab.com/72-03-iot-et-sans-fil
Howto start
------------------
Plug the ChisteraPi on your RaspberryPi.
Power on and connect into your RaspberryPi with SSH.
Activation of the SPI :
```bash
sudo raspi-config
```
Then select "9 - Advanced Options" then "A5 - SPI" and <Yes>.
The lora_chisterapi library need the external library : wiringpi.
If you don't have the library do :
```bash
sudo apt-get update
sudo apt-get install wiringpi
```
Clone the repository :
```bash
git clone https://github.com/Snootlab/lora_chisterapi
```
Get into the repository and select the example :
```bash
cd lora_chisterapi
cp examples/sender.cpp src/main.cpp
OR
cp examples/receiver.cpp src/main.cpp
```
Compile and execute the example :
```bash
make
sudo ./chisterapi
```
/*
* Snootlab
*-----------------------------------------------------------------------------------------
* Example of a communication between two Chistera-Pi or between a Chistera-Pi and a sensor
* with a RFM95 like Snootlab's TeensyWiNo.
* This is the receiver code, the Chistera-Pi receives a message with an address and a
* counter and it prints the informations on the prompt.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <RH_RF95.h>
RH_RF95 rf95;
int run = 1;
/* Signal the end of the software */
void sigint_handler(int signal)
{
run = 0;
}
void setup()
{
wiringPiSetupGpio();
if (!rf95.init())
{
fprintf(stderr, "Init failed\n");
exit(1);
}
/* Tx Power is from +5 to +23 dbm */
rf95.setTxPower(23);
/* There are different configurations
* you can find in lib/radiohead/RH_RF95.h
* at line 437
*/
rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128);
rf95.setFrequency(868.0); /* MHz */
}
void loop()
{
/* If we receive one message we show on the prompt
* the address of the sender and the Rx power.