[Java] Zugriff auf GSM

Bei meinem aktuellen Projekt beamer-tool benötige ich aus Java heraus möglichst plattformunabhängigen Zugriff auf GSM-Hardware.

Da Ubinetics insolvent ist gibt es deren GSM PCMCIA-Karten GDC-201 für rund 7€ und das zugehörige GSM AT Command Set gibts kostenlost dazu. (Um zu vermeiden, dass es das Dokument irgendwann mal nicht mehr gibt habe ich es lokal heruntergeladen und verlinkt: Ubinetics GSM AT Command Set).

Zuerst war mein Ansatz den Zugriff selber zu schreiben, da bei der Suche im Internet nur kostenpflichtige GSM Bibliotheken für Java auftauchten.

Eher zufällig bin ich über SMSlib gestoßen. Es ist eine wunderbar kleine und handlich API um SMS und Telefongespräche zu empfangen und auszuwerten.
Es ist pures Java, also keine Altlasten von irgendwelchen C-Interfaces oder solche Späße.

Um nur einkommende SMS zu lesen reichen diese paar Zeilen Code:

package example;

import java.util.LinkedList;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.smslib.ICallNotification;
import org.smslib.IInboundMessageNotification;
import org.smslib.InboundMessage;
import org.smslib.Library;
import org.smslib.Service;
import org.smslib.Message.MessageTypes;
import org.smslib.gateway.ModemGateway;
import org.smslib.gateway.SerialModemGateway;

public class Ubinetics {
private static final Logger logger = Logger.getLogger(Ubinetics.class);
private static final Logger smslibLogger = Logger.getLogger("smslibLogger");
Service smsService = null;
private Thread startUpThread = null;

public void init() {
//Use a thread to avoid blocking the application
smsService = new Service(smslibLogger);
// Init and searching for networks takes a long time. so spawn a thread
Thread t = new Thread(new Runnable() {
@Override
public void run() {
logger.info("SMSlib - Version: " + Library.LIB_VERSION + "." + Library.LIB_RELEASE + "." + Library.LIB_SUBRELEASE);

smsService = new Service(smslibLogger);

ModemGateway ubineticsGateway = new SerialModemGateway("ubinetics.com6", "COM6", 9600, "Ubinetics", "GDC201", smsService.getLogger());

ubineticsGateway.setInbound(true);
ubineticsGateway.setOutbound(false);
ubineticsGateway.setSimPin("XXXX");
ubineticsGateway.setInboundNotification( new IInboundMessageNotification() {
private LinkedList<InboundMessage> msgList = new LinkedList<InboundMessage>();
@Override
public void process(String gatewayId, MessageTypes msgType, String memLoc, int memIndex)
{
msgList.clear();

switch (msgType)
{
case INBOUND:
try
{
// Read...
smsService.readMessages(msgList, InboundMessage.MessageClasses.UNREAD, gatewayId);
//Do something with the message list
for(InboundMessage msg : msgList) {
smsService.deleteMessage(msg);
}
}
}
catch (Exception e)
{
System.out.println("Oops, some bad happened...");
e.printStackTrace();
}
break;
case STATUSREPORT:
logger.info(">>> New Status Report message detected from Gateway: " + gatewayId + " : " + memLoc + " @ " + memIndex);
break;
}
}
});
ubineticsGateway.setCallNotification( new ICallNotification() {
@Override
public void process(String gatewayId, String callerId) {
logger.info(">>> New call detected from Gateway: " + gatewayId + " : " + callerId);
}

});
smsService.addGateway(ubineticsGateway);

try {
smsService.startService();

logger.info("Modem Information:");
logger.info("  Manufacturer: " + ubineticsGateway.getManufacturer());
logger.info("  Model: " + ubineticsGateway.getModel());
logger.info("  Serial No: " + ubineticsGateway.getSerialNo());
logger.info("  SIM IMSI: " + ubineticsGateway.getImsi());
logger.info("  Signal Level: " + ubineticsGateway.getSignalLevel() + "%");
logger.info("  Battery Level: " + ubineticsGateway.getBatteryLevel() + "%");
} catch(Exception ex) {
logger.fatal("Can't start SMS service: " + ex.getLocalizedMessage());
ex.printStackTrace();
}
}
});
t.setName("UbineticsInitalizer");
t.start();
}

public void uninit() {
assert (smsService != null);

try {
smsService.stopService();
} catch(Exception e) {
logger.fatal(e.getLocalizedMessage());
}
}
} 

Problematisch ist einzig der Zugriff auf die serielle Schnittstelle. Die orginale Implementierung von Sun funktioniert unter diversen Betriebsystemen nicht oder nicht richtig und wird auch (anscheind) nicht mehr supported.

RXTX.org bietet dies aber für eine ganze Reihe von Betriebsystem die eigentlich jeden zufriedenstellen sollte.

Ein Aufruf mit dem o.g. Code sähe das dann so aus (wenn man noch eine main-Methode baut):
java -cp .;/pfad/zu/smslib-3.0.3.jar;/pfad/zu/log4j-1.2.14.jar;/pfad/zu/RXTXcomm.jar -Djava.library.path=/pfad/zu/rxtx/windows/dll -Dsmslib.debug=1 example.Ubinetics

Ein direkt ähnliches Beispiel existiert auch in den Sourcen von SMSlib im Ordner examples.modem

Schreibe einen Kommentar