[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:

  1. package example;
  2.  
  3. import java.util.LinkedList;
  4.  
  5. import org.apache.log4j.Level;
  6. import org.apache.log4j.Logger;
  7. import org.smslib.ICallNotification;
  8. import org.smslib.IInboundMessageNotification;
  9. import org.smslib.InboundMessage;
  10. import org.smslib.Library;
  11. import org.smslib.Service;
  12. import org.smslib.Message.MessageTypes;
  13. import org.smslib.gateway.ModemGateway;
  14. import org.smslib.gateway.SerialModemGateway;
  15.  
  16. public class Ubinetics {
  17. private static final Logger logger = Logger.getLogger(Ubinetics.class);
  18. private static final Logger smslibLogger = Logger.getLogger("smslibLogger");
  19. Service smsService = null;
  20. private Thread startUpThread = null;
  21.  
  22. public void init() {
  23. //Use a thread to avoid blocking the application
  24. smsService = new Service(smslibLogger);
  25. // Init and searching for networks takes a long time. so spawn a thread
  26. Thread t = new Thread(new Runnable() {
  27. @Override
  28. public void run() {
  29. logger.info("SMSlib - Version: " + Library.LIB_VERSION + "." + Library.LIB_RELEASE + "." + Library.LIB_SUBRELEASE);
  30.  
  31. smsService = new Service(smslibLogger);
  32.  
  33. ModemGateway ubineticsGateway = new SerialModemGateway("ubinetics.com6", "COM6", 9600, "Ubinetics", "GDC201", smsService.getLogger());
  34.  
  35. ubineticsGateway.setInbound(true);
  36. ubineticsGateway.setOutbound(false);
  37. ubineticsGateway.setSimPin("XXXX");
  38. ubineticsGateway.setInboundNotification( new IInboundMessageNotification() {
  39. private LinkedList<InboundMessage> msgList = new LinkedList<InboundMessage>();
  40. @Override
  41. public void process(String gatewayId, MessageTypes msgType, String memLoc, int memIndex)
  42. {
  43. msgList.clear();
  44.  
  45. switch (msgType)
  46. {
  47. case INBOUND:
  48. try
  49. {
  50. // Read...
  51. smsService.readMessages(msgList, InboundMessage.MessageClasses.UNREAD, gatewayId);
  52. //Do something with the message list
  53. for(InboundMessage msg : msgList) {
  54. smsService.deleteMessage(msg);
  55. }
  56. }
  57. }
  58. catch (Exception e)
  59. {
  60. System.out.println("Oops, some bad happened...");
  61. e.printStackTrace();
  62. }
  63. break;
  64. case STATUSREPORT:
  65. logger.info(">>> New Status Report message detected from Gateway: " + gatewayId + " : " + memLoc + " @ " + memIndex);
  66. break;
  67. }
  68. }
  69. });
  70. ubineticsGateway.setCallNotification( new ICallNotification() {
  71. @Override
  72. public void process(String gatewayId, String callerId) {
  73. logger.info(">>> New call detected from Gateway: " + gatewayId + " : " + callerId);
  74. }
  75.  
  76. });
  77. smsService.addGateway(ubineticsGateway);
  78.  
  79. try {
  80. smsService.startService();
  81.  
  82. logger.info("Modem Information:");
  83. logger.info("  Manufacturer: " + ubineticsGateway.getManufacturer());
  84. logger.info("  Model: " + ubineticsGateway.getModel());
  85. logger.info("  Serial No: " + ubineticsGateway.getSerialNo());
  86. logger.info("  SIM IMSI: " + ubineticsGateway.getImsi());
  87. logger.info("  Signal Level: " + ubineticsGateway.getSignalLevel() + "%");
  88. logger.info("  Battery Level: " + ubineticsGateway.getBatteryLevel() + "%");
  89. } catch(Exception ex) {
  90. logger.fatal("Can't start SMS service: " + ex.getLocalizedMessage());
  91. ex.printStackTrace();
  92. }
  93. }
  94. });
  95. t.setName("UbineticsInitalizer");
  96. t.start();
  97. }
  98.  
  99. public void uninit() {
  100. assert (smsService != null);
  101.  
  102. try {
  103. smsService.stopService();
  104. } catch(Exception e) {
  105. logger.fatal(e.getLocalizedMessage());
  106. }
  107. }
  108. }

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