I need to store SMS (when they arrive to the GSM modem) in MySQL.
I have read the docs, but it says to use the smsserver and the conffile.
Then I read that I should use database.java.
Can someone guide me on this?
I am already using the ReadMessages.java and I have achieved storing in a MySQL database, but I have managed to store only the ones that are in the SIM card memory, not the inbound messages.
The inbound messages are just printed by the console, I read that this can do with threads.
This is my code:
public void doIt() throws Exception
{
// Define a list which will hold the read messages.
List<InboundMessage> msgList;
// Create the notification callback method for inbound & status report
// messages.
InboundNotification inboundNotification = new InboundNotification();
// Create the notification callback method for inbound voice calls.
CallNotification callNotification = new CallNotification();
//Create the notification callback method for gateway statuses.
GatewayStatusNotification statusNotification = new GatewayStatusNotification();
OrphanedMessageNotification orphanedMessageNotification = new OrphanedMessageNotification();
try
{
//System.out.println("Example: Read messages from a serial gsm modem.");
//System.out.println(Library.getLibraryDescription());
//System.out.println("Version: " + Library.getLibraryVersion());
// Create the Gateway representing the serial GSM modem.
SerialModemGateway gateway = new SerialModemGateway("modem.com1", "COM4", 115200, "Huawei", "E160");
// Set the modem protocol to PDU (alternative is TEXT). PDU is the default, anyway...
gateway.setProtocol(Protocols.PDU);
// Do we want the Gateway to be used for Inbound messages?
gateway.setInbound(true);
// Do we want the Gateway to be used for Outbound messages?
gateway.setOutbound(true);
// Let SMSLib know which is the SIM PIN.
gateway.setSimPin("0000");
// Set up the notification methods.
Service.getInstance().setInboundMessageNotification(inboundNotification);
Service.getInstance().setCallNotification(callNotification);
Service.getInstance().setGatewayStatusNotification(statusNotification);
Service.getInstance().setOrphanedMessageNotification(orphanedMessageNotification);
// Add the Gateway to the Service object.
Service.getInstance().addGateway(gateway);
// Similarly, you may define as many Gateway objects, representing
// various GSM modems, add them in the Service object and control all of them.
// Start! (i.e. connect to all defined Gateways)
Service.getInstance().startService();
// Printout some general information about the modem.
System.out.println();
System.out.println("Informacion del modem:");
System.out.println(" Fabricante: " + gateway.getManufacturer());
System.out.println(" Modelo: " + gateway.getModel());
System.out.println(" Serial No: " + gateway.getSerialNo());
System.out.println(" SIM IMSI: " + gateway.getImsi());
//System.out.println(" Signal Level: " + gateway.getSignalLevel() + " dBm");
//System.out.println(" Battery Level: " + gateway.getBatteryLevel() + "%");
System.out.println();
// In case you work with encrypted messages, its a good time to declare your keys.
// Create a new AES Key with a known key value.
// Register it in KeyManager in order to keep it active. SMSLib will then automatically
// encrypt / decrypt all messages send to / received from this number.
Service.getInstance().getKeyManager().registerKey("+306948494037", new AESKey(new SecretKeySpec("0011223344556677".getBytes(), "AES")));
// Read Messages. The reading is done via the Service object and
// affects all Gateway objects defined. This can also be more directed to a specific
// Gateway - look the JavaDocs for information on the Service method calls.
ConexionMySQL mysql = new ConexionMySQL();
Connection cnn = mysql.Conectar();
String sms= "";
String originator="";
String sql ="";
int n = 0;
String success="Mensajee satisfactorio";
msgList = new ArrayList<InboundMessage>();
Service.getInstance().readMessages(msgList, MessageClasses.ALL);
for (InboundMessage msg : msgList){
//System.out.println(msg);
sms = msg.getText().toString();
remitente = msg.getOriginator().toString();
//fecha = msg.getDate().getTime();
sql ="INSERT INTO message(message, originator) VALUES (?,?)";
PreparedStatement post = (PreparedStatement) cnn.prepareStatement(sql);
post.setString(1, message);
post.setString(2, originator);
//post.setDate(3, fecha); public void doIt() throws Exception
{
// Define a list which will hold the read messages.
List<InboundMessage> msgList;
// Create the notification callback method for inbound & status report
// messages.
InboundNotification inboundNotification = new InboundNotification();
// Create the notification callback method for inbound voice calls.
CallNotification callNotification = new CallNotification();
//Create the notification callback method for gateway statuses.
GatewayStatusNotification statusNotification = new GatewayStatusNotification();
OrphanedMessageNotification orphanedMessageNotification = new OrphanedMessageNotification();
try
{
//System.out.println("Example: Read messages from a serial gsm modem.");
//System.out.println(Library.getLibraryDescription());
//System.out.println("Version: " + Library.getLibraryVersion());
// Create the Gateway representing the serial GSM modem.
SerialModemGateway gateway = new SerialModemGateway("modem.com1", "COM4", 115200, "Huawei", "E160");
// Set the modem protocol to PDU (alternative is TEXT). PDU is the default, anyway...
gateway.setProtocol(Protocols.PDU);
// Do we want the Gateway to be used for Inbound messages?
gateway.setInbound(true);
// Do we want the Gateway to be used for Outbound messages?
gateway.setOutbound(true);
// Let SMSLib know which is the SIM PIN.
gateway.setSimPin("0000");
// Set up the notification methods.
Service.getInstance().setInboundMessageNotification(inboundNotification);
Service.getInstance().setCallNotification(callNotification);
Service.getInstance().setGatewayStatusNotification(statusNotification);
Service.getInstance().setOrphanedMessageNotification(orphanedMessageNotification);
// Add the Gateway to the Service object.
Service.getInstance().addGateway(gateway);
// Similarly, you may define as many Gateway objects, representing
// various GSM modems, add them in the Service object and control all of them.
// Start! (i.e. connect to all defined Gateways)
Service.getInstance().startService();
// Printout some general information about the modem.
System.out.println();
System.out.println("Informacion del modem:");
System.out.println(" Fabricante: " + gateway.getManufacturer());
System.out.println(" Modelo: " + gateway.getModel());
System.out.println(" Serial No: " + gateway.getSerialNo());
System.out.println(" SIM IMSI: " + gateway.getImsi());
//System.out.println(" Signal Level: " + gateway.getSignalLevel() + " dBm");
//System.out.println(" Battery Level: " + gateway.getBatteryLevel() + "%");
System.out.println();
// In case you work with encrypted messages, its a good time to declare your keys.
// Create a new AES Key with a known key value.
// Register it in KeyManager in order to keep it active. SMSLib will then automatically
// encrypt / decrypt all messages send to / received from this number.
Service.getInstance().getKeyManager().registerKey("+306948494037", new AESKey(new SecretKeySpec("0011223344556677".getBytes(), "AES")));
// Read Messages. The reading is done via the Service object and
// affects all Gateway objects defined. This can also be more directed to a specific
// Gateway - look the JavaDocs for information on the Service method calls.
ConexionMySQL mysql = new ConexionMySQL();
Connection cnn = mysql.Conectar();
String sms= "";
String remitente="";
//Date fecha;
String sql ="";
int n = 0;
String mensaje="Mensajee satisfactorio";
msgList = new ArrayList<InboundMessage>();
Service.getInstance().readMessages(msgList, MessageClasses.ALL);
for (InboundMessage msg : msgList){
//System.out.println(msg);
sms = msg.getText().toString();
remitente = msg.getOriginator().toString();
//fecha = msg.getDate().getTime();
sql ="INSERT INTO mensaje(mensaje, remitente) VALUES (?,?)";
PreparedStatement post = (PreparedStatement) cnn.prepareStatement(sql);
post.setString(1, sms);
post.setString(2, originator);
n = post.executeUpdate();
if(n >0){
JOptionPane.showMessageDialog(null, mensaje);
Service.getInstance().deleteMessage(msg);
}
// Sleep now. Emulate real world situation and give a chance to the notifications
// methods to be called in the event of message or voice call reception.
System.out.println("Now Sleeping - Hit <enter> to stop service.");
System.in.read();
System.in.read();
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
Service.getInstance().stopService();
}
}
n = post.executeUpdate();
if(n >0){
JOptionPane.showMessageDialog(null, mensaje);
Service.getInstance().deleteMessage(msg);
}
// Sleep now. Emulate real world situation and give a chance to the notifications
// methods to be called in the event of message or voice call reception.
System.out.println("Now Sleeping - Hit <enter> to stop service.");
System.in.read();
System.in.read();
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
Service.getInstance().stopService();
}
}
You should check where you've put the InboundNotification class.
The messages you're seeing from the console with inbound sms comes from there
public class InboundNotification implements IInboundMessageNotification
{
public void process(AGateway gateway, MessageTypes msgType, InboundMessage msg)
{
if (msgType == MessageTypes.INBOUND) System.out.println(">>> New Inbound message detected from Gateway: " + gateway.getGatewayId());
else if (msgType == MessageTypes.STATUSREPORT) System.out.println(">>> New Inbound Status Report message detected from Gateway: " + gateway.getGatewayId());
System.out.println(msg);
}
}
Related
getConnectionState() as connected /disconnected depending on the device .if it is sending message i should see connected and if it not sending i should get disconnected .But each time i run the below java Program i am getting status as disconnected irrespective of device is sending messages or not
RegistryManager registryManager = RegistryManager.createFromConnectionString(connectionString);
System.out.println(registryManager.getDevices(new Integer(1000)));
while(true){
ArrayList<Device> deviceslist=registryManager.getDevices(new Integer(1000));
for(Device device:deviceslist)
{
/*System.out.println(device.getDeviceId());
System.out.println(device.getPrimaryKey());
System.out.println(device.getSecondaryKey());*/
System.out.println(device.getDeviceId());
System.out.println(device.getConnectionState());
/*System.out.println(device.getConnectionStateUpdatedTime());
System.out.println(device.getLastActivityTime());
System.out.println(device.getStatusReason());
System.out.println(device.getStatusUpdatedTime());
System.out.println(device.getSymmetricKey());
System.out.println(device.geteTag());
*/ }
}
I definitely am seeing otherwise.
I'm creating an simple C# console application using the code below,
static async void QueryDevices()
{
RegistryManager manager = RegistryManager.CreateFromConnectionString(connectionString);
while (true)
{
var devices = await manager.GetDevicesAsync(100);
{
foreach (var item in devices)
{
Console.WriteLine(DateTime.Now + ": " + item.Id + ", " + item.ConnectionState);
System.Threading.Thread.Sleep(100);
}
}
}
}
The git here is to always query the whole device list, because the ConnectionState property somehow looks like "static" memebers of the single device client instance, which is not apt-to change even when the actual state changes.
And my output is like below, the "connected" state is when I'm using an java client sample to send message to the IoT Hub.
I have a GCM-backend Java server and I'm trying to send to all users a notification msg. Is my approach right? To just split them into 1000 each time before giving the send request? Or is there a better approach?
public void sendMessage(#Named("message") String message) throws IOException {
int count = ofy().load().type(RegistrationRecord.class).count();
if(count<=1000) {
List<RegistrationRecord> records = ofy().load().type(RegistrationRecord.class).limit(count).list();
sendMsg(records,message);
}else
{
int msgsDone=0;
List<RegistrationRecord> records = ofy().load().type(RegistrationRecord.class).list();
do {
List<RegistrationRecord> regIdsParts = regIdTrim(records, msgsDone);
msgsDone+=1000;
sendMsg(regIdsParts,message);
}while(msgsDone<count);
}
}
The regIdTrim method
private List<RegistrationRecord> regIdTrim(List<RegistrationRecord> wholeList, final int start) {
List<RegistrationRecord> parts = wholeList.subList(start,(start+1000)> wholeList.size()? wholeList.size() : start+1000);
return parts;
}
The sendMsg method
private void sendMsg(List<RegistrationRecord> records,#Named("message") String message) throws IOException {
if (message == null || message.trim().length() == 0) {
log.warning("Not sending message because it is empty");
return;
}
Sender sender = new Sender(API_KEY);
Message msg = new Message.Builder().addData("message", message).build();
// crop longer messages
if (message.length() > 1000) {
message = message.substring(0, 1000) + "[...]";
}
for (RegistrationRecord record : records) {
Result result = sender.send(msg, record.getRegId(), 5);
if (result.getMessageId() != null) {
log.info("Message sent to " + record.getRegId());
String canonicalRegId = result.getCanonicalRegistrationId();
if (canonicalRegId != null) {
// if the regId changed, we have to update the datastore
log.info("Registration Id changed for " + record.getRegId() + " updating to " + canonicalRegId);
record.setRegId(canonicalRegId);
ofy().save().entity(record).now();
}
} else {
String error = result.getErrorCodeName();
if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
log.warning("Registration Id " + record.getRegId() + " no longer registered with GCM, removing from datastore");
// if the device is no longer registered with Gcm, remove it from the datastore
ofy().delete().entity(record).now();
} else {
log.warning("Error when sending message : " + error);
}
}
}
}
Quoting from Google Docs:
GCM is support for up to 1,000 recipients for a single message. This capability makes it much easier to send out important messages to your entire user base. For instance, let's say you had a message that needed to be sent to 1,000,000 of your users, and your server could handle sending out about 500 messages per second. If you send each message with only a single recipient, it would take 1,000,000/500 = 2,000 seconds, or around half an hour. However, attaching 1,000 recipients to each message, the total time required to send a message out to 1,000,000 recipients becomes (1,000,000/1,000) / 500 = 2 seconds. This is not only useful, but important for timely data, such as natural disaster alerts or sports scores, where a 30 minute interval might render the information useless.
Taking advantage of this functionality is easy. If you're using the GCM helper library for Java, simply provide a List collection of registration IDs to the send or sendNoRetry method, instead of a single registration ID.
We can not send more than 1000 push notification at time.I searched a lot but not result then i did this with same approach split whole list in sub lists of 1000 items and send push notification.
I am working on a POC for RabbitMQ for an M2M solution. I have a large number of physical devices that will be publishing data (simulating clients using the Java client for now - eventually over MQTT). I want to:
subscribe and journal all raw data to the database
subscribe to sub-sets of the data by data type so I can scale
solutions for those types of data independently
publish new events through the exchange (e.g. take a raw event, make
it more useful and resubmit it through the system)
Each message has a routing key like key:value.key:value.key:value.messageType:1 and data from the devices has an extra key of FROMDEVICE.MESSAGETYPE:1.key:value... etc. The subscriber that saves the raw data from the device builds a queue from the exchange with the routing key #.FROMDEVICE.# (case #1 above). The subscriber that takes a specific message type and value-adds it builds a queue with the routing key #.MESSAGETYPE:1.# (case #2 above) and submits a new message to the same exchange removing FROMDEVICE from the routing key and replacing .MESSAGETYPE:1 with .MESSAGETYPE:101 (case #3 above). There is then an independent subscriber/queue for the new message type.
Everything is fine except my subscriber that should only receive the data from the devices is also getting the value added data (MESSAGETYPE:101) even though the routingKey it should be searching for does not exist in the re-published/value-added message.
FROMDEVICE.MESSAGETYPE:1 ->
should match routing key #.FROMDEVICE.#
should match #.MESSAGETYPE:1.#
MESSAGETYPE:101
should match routing key #.MESSAGETYPE:101.#
should NOT match #.FROMDEVICE.# (but does)
Code to subscribe to data from devices only:
public class HandlerWriteEverythingFromDevice {
private final static String EXCHANGE_NAME = "logsTopicDurable";
private final static String QUEUE_NAME = "fromDevice";
/**
* Writes all data from device to a data store.
*/
public static void main(String[] args) throws java.io.IOException, java.lang.InterruptedException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.56.101");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "topic", true);
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
System.out.println(" [*] listens for messages from devices - durable!");
channel.basicQos(1);
String routingKey = "#.fromDevice.#".toUpperCase();
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, routingKey); //bind to all selected messages
System.out.println(" [*] subscribing to: " + routingKey);
System.out.println(" [*] Waiting for messages. To exit press CTRL_C");
QueueingConsumer consumer = new QueueingConsumer(channel);
boolean autoAck = false; //ack back when done
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
int msgCount = 0;
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Message Count: " + ++msgCount + " ROUTINGKEY: '" + delivery.getEnvelope().getRoutingKey() + "\n MESSAGE: '" + message + "'");
Thread.sleep(250); //simulate some time to insert into the db.
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
}
Code to subscribe only to messageType:1 and re-publish messageType:101
private final static String EXCHANGE_NAME = "logsTopicDurable";
private final static String QUEUE_NAME = "messageType1";
/**
* Handler for messageType:1
*/
public static void main(String[] args) throws java.io.IOException, java.lang.InterruptedException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.56.101");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "topic", true);
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
System.out.println(" [*] listens for messageType:1 and submits messageType:101");
channel.basicQos(1);
String routingKey = "#.messageType:1.#".toUpperCase();
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, routingKey); //bind to all selected messages
System.out.println(" [*] subscribing to: " + routingKey);
System.out.println(" [*] Waiting for messages. To exit press CTRL_C");
QueueingConsumer consumer = new QueueingConsumer(channel);
boolean autoAck = false; //ack back when done
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
int msgCount = 0;
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Message Count: " + ++msgCount + " ROUTINGKEY: '" + delivery.getEnvelope().getRoutingKey() + "\n MESSAGE: '" + message + "'");
channel.basicPublish(EXCHANGE_NAME,
delivery.getEnvelope().
getRoutingKey().
replaceAll("messageType:1", "messageType:101").
replaceAll(".FROMDEVICE", "").
replaceAll("FROMDEVICE.", "").trim(),
true,
MessageProperties.PERSISTENT_BASIC,
message.getBytes());
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
There is publisher code and subscriber code for messageType:101 but I don't think they are needed for this discussion. I've wondered if publishing to a channel that has a queue bound to it might be the cause, but I tried creating two channels (same connection object) and had the same result and a lot uglier code.
I would suggest that you are being a bit to liberal with your binding keys. To make things a little more clear you should use the term binding key and routing key differently. The routing key is what is sent by the producer. The binding key is what you use to bind the queue to the topic exchange.
As I cannot be sure which you are referring to when you say
"should match routing key #.MESSAGETYPE:101.#"
are you sending a message with a routing key #.MESSAGETYPE:101.# because that would be a bad idea. I presume not, but if you are don't!
Lets assume then that this is your binding key. I am not sure as I haven't done any testing of this specifically but the # before and after maybe causing some problems. You should think about a specification for your routing keys. Some format that they must conform to. It may be extendable but not completely free. That way you can have much more specific binding keys using * instead of # which will give a little more control.
I have a system with a db4o server that has two clients. One client is hosted in process, the other is a web server hosting a number of servlets that need to query the database.
In the web server's connection code, I have registered for the commit event, and use it to refresh objects as suggested by the db4o documentation at http://community.versant.com/documentation/reference/db4o-8.0/java/reference/Content/advanced_topics/callbacks/possible_usecases/committed_event_example.htm :
client = Db4oClientServer.openClient (context.getBean ("db4oClientConfiguration", ClientConfiguration.class),
arg0.getServletContext ().getInitParameter ("databasehost"),
Integer.parseInt (arg0.getServletContext ().getInitParameter ("databaseport")),
arg0.getServletContext ().getInitParameter ("databaseuser"),
arg0.getServletContext ().getInitParameter ("databasepassword"));
System.out.println ("DB4O connection established");
EventRegistry events = EventRegistryFactory.forObjectContainer (client);
events.committed ().addListener (new EventListener4<CommitEventArgs> () {
public void onEvent (Event4<CommitEventArgs> commitEvent, CommitEventArgs commitEventArgs)
{
for (Iterator4<?> it = commitEventArgs.updated ().iterator (); it.moveNext ();)
{
LazyObjectReference reference = (LazyObjectReference) it.current ();
System.out.println ("Updated object: " + reference.getClass () + ":" + reference.getInternalID ());
//if (trackedClasses.contains (reference.getClass ()))
{
Object obj = reference.getObject ();
commitEventArgs.objectContainer ().ext ().refresh (obj, 1);
System.out.println (" => updated (" + obj + ")");
}
}
}
});
In the in-process client, the following code is then executed:
try {
PlayerCharacter pc = new PlayerCharacter (player, name);
pc.setBio(bio);
pc.setArchetype(archetype);
player.getCharacters ().add (pc);
database.store (pc);
database.store (player.getCharacters ());
database.store (player);
database.commit ();
con.sendEvent (id, "CHARACTER_CREATED".getBytes (Constants.CHARSET));
}
catch (Exception e)
{
con.sendEvent (id, EventNames.ERROR, e.toString ());
}
The 'CHARACTER_CREATED' event gets sent successfully, so I know that commit isn't throwing an exception, but nothing shows up on the other client. It continues to use the old versions of the objects, and the 'updated object' messages I'm expecting don't show up on the server console.
Any ideas what I'm doing wrong?
Apparently the .committed() event only fires on a client, when the commit is from a other TCP client.
So you would need to turn your internal .openClient() / .openSession() clients to full blown TCP clients to see the events.
The .openClient() / .openSession() object containers are way more light weight and bypass all code which is related to network communication. Apparently also the event distribution across the network.
I am trying to send a sms with smslib but It did not send the message, can somebody guide me on this?
this is my code:
import org.smslib.AGateway;
import org.smslib.IOutboundMessageNotification;
import org.smslib.Library;
import org.smslib.OutboundMessage;
import org.smslib.Service;
import org.smslib.modem.SerialModemGateway;
public class SendMessage
{
public void doIt() throws Exception
{
OutboundNotification outboundNotification = new OutboundNotification();
System.out.println("Example: Send message from a serial gsm modem.");
System.out.println(Library.getLibraryDescription());
System.out.println("Version: " + Library.getLibraryVersion());
SerialModemGateway gateway = new SerialModemGateway("modem.com1", "COM4", 115200, "Huawei", "");
gateway.setInbound(true);
gateway.setOutbound(true);
gateway.setSimPin("0000");
// Explicit SMSC address set is required for some modems.
// Below is for VODAFONE GREECE - be sure to set your own!
gateway.setSmscNumber("+919825068000");
Service.getInstance().setOutboundMessageNotification(outboundNotification);
Service.getInstance().addGateway(gateway);
Service.getInstance().startService();
System.out.println();
System.out.println("Modem Information:");
System.out.println(" Manufacturer: " + gateway.getManufacturer());
System.out.println(" Model: " + gateway.getModel());
System.out.println(" Serial No: " + gateway.getSerialNo());
System.out.println(" SIM IMSI: " + gateway.getImsi());
System.out.println(" Signal Level: " + gateway.getSignalLevel() + " dBm");
System.out.println(" Battery Level: " + gateway.getBatteryLevel() + "%");
System.out.println();
// Send a message synchronously.
OutboundMessage msg = new OutboundMessage("+524747388616", "que onda como andas!");
Service.getInstance().sendMessage(msg);
System.out.println(msg);
// Or, send out a WAP SI message.
//OutboundWapSIMessage wapMsg = new OutboundWapSIMessage("306974000000", new URL("http://www.smslib.org/"), "Visit SMSLib now!");
//Service.getInstance().sendMessage(wapMsg);
//System.out.println(wapMsg);
// You can also queue some asynchronous messages to see how the callbacks
// are called...
//msg = new OutboundMessage("309999999999", "Wrong number!");
//srv.queueMessage(msg, gateway.getGatewayId());
//msg = new OutboundMessage("308888888888", "Wrong number!");
//srv.queueMessage(msg, gateway.getGatewayId());
System.out.println("Now Sleeping - Hit <enter> to terminate.");
System.in.read();
Service.getInstance().stopService();
}
public class OutboundNotification implements IOutboundMessageNotification
{
public void process(AGateway gateway, OutboundMessage msg)
{
System.out.println("Outbound handler called from Gateway: " + gateway.getGatewayId());
System.out.println(msg);
}
}
public static void main(String args[])
{
SendMessage app = new SendMessage();
try
{
app.doIt();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
and my result:
Example: Send message from a serial gsm modem.
SMSLib: A Java API library for sending and receiving SMS via a GSM modem or other supported gateways.
This software is distributed under the terms of the Apache v2.0 License.
Web Site: http://smslib.org
Version: 3.5.1
Modem Information:
Manufacturer: Nokia Corporation
Model: Nokia Internet Stick CS-10
Serial No: 359340022861915
SIM IMSI: ** MASKED **
Signal Level: -53 dBm
Battery Level: 0%
===============================================================================
<< OutboundMessage >>
-------------------------------------------------------------------------------
Gateway Id: *
Message Id: 0
Message UUID: e30f84ad-b083-4956-85ef-16dc89020769
Encoding: 7-bit
Date: Fri Mar 09 13:15:52 CST 2012
SMSC Ref No: null
Recipient: 524747388616
Dispatch Date: null
Message Status: FAILED
Failure Cause: UNKNOWN
Validity Period (Hours): -1
Status Report: false
Source / Destination Ports: -1 / -1
Flash SMS: false
Text: que onda como andas!
PDU data: F17A19F47693C3A0F1BBFD0685DDE4F03C04
Scheduled Delivery: null
===============================================================================
Now Sleeping - Hit <enter> to terminate.
This example has extra line of code about SMSC-number. I have played with this same library and in my code there is not any SMSC - at any line of my code.
It is a suggestion, "if needed", and I certainly believe getting rid of it solves your problem. You most probably don't know what you exactly have to put on it, so better leaving it out. Then modem will not try to do this routing manually to given number but it can make it to the correct, what it knows by SIM settings on the SIM card.
Another thing I would check is that the modem really answers from COM4 port. Although now it seems to do so, because the signal strength is read. But check this always, because every startup of server can map the device to different port. I was at least having this kind of problem on Linux side.
Maybe you have not taken care enough (yet) to the SerialModemGateway constructor arguments, as you left "Huawei" as vendor whereas you use a Nokia device. That parameter is not important but the baud rate is. According to SMSlib documentation, most devices only works properly in a preset/uniq baudrate.
I propose you open other software settings to get or confirm parameters you have used:
baud rate
gateway SMSC number - maybe from Connection history menu according to Nokia user guide
As you get your code from an Huawei example, this example set the gateway SMSC number but this parameter is supposed to be optional for most devices, only Huawei devices may require it. Try a run without gateway.setSmscNumber !
I also invite you to monitor serial port traffic with Portmon for instance and report it here and on SMSlib forum to get support.
Finally, you should ask SMSlib maintainer its option about your device, as it is in the compatibility list (yet)
Following is a sample code I used and tested. You can re-use it.
package com.stackoverflow.smstest;
import java.net.URL;
import org.smslib.AGateway;
import org.smslib.IOutboundMessageNotification;
import org.smslib.Library;
import org.smslib.OutboundMessage;
import org.smslib.OutboundWapSIMessage;
import org.smslib.Service;
import org.smslib.modem.SerialModemGateway;
public class Main {
public void sendMessage() throws Exception {
OutboundNotification outboundNotification = new OutboundNotification();
System.out.println("Sample of Send message from a serial gsm modem.");
System.out.println(Library.getLibraryDescription());
System.out.println("Version: " + Library.getLibraryVersion());
SerialModemGateway gateway = new SerialModemGateway("modem.com4",
"COM4", 57600, "Huawei", "E160");
gateway.setInbound(false);
gateway.setOutbound(true);
// gateway.setSimPin("");
Service.getInstance().setOutboundMessageNotification(
outboundNotification);
Service.getInstance().addGateway(gateway);
Service.getInstance().startService();
System.out.println();
System.out.println("Modem Information:");
System.out.println(" Manufacturer: " + gateway.getManufacturer());
System.out.println(" Model: " + gateway.getModel());
System.out.println(" Serial No: " + gateway.getSerialNo());
System.out.println(" SIM IMSI: " + gateway.getImsi());
System.out.println(" Signal Level: " + gateway.getSignalLevel()
+ " dBm");
System.out.println(" Battery Level: " + gateway.getBatteryLevel()
+ "%");
// Send a message synchronously.
OutboundMessage msg = new OutboundMessage("+94123456789",
"SMS test: sample message from StackOverflow");
Service srvice = Service.getInstance();
// Service.getInstance().sendMessage(msg);
System.out.println(msg);
// Or, send out a WAP SI message.
OutboundWapSIMessage wapMsg = new OutboundWapSIMessage("+94123456789",
new URL("http://stackoverflow.com/"),
"WAP test: sample message from StackOverflow!");
// gateway.setFrom("chandpriyankara");
// wapMsg.setFrom("chandpriyankara");
srvice.queueMessage(wapMsg);
Service.getInstance().stopService();
}
/**
* Outbound Message informations handler
*
* #author chandpriyankara
*
*/
public class OutboundNotification implements IOutboundMessageNotification {
public void process(AGateway gateway, OutboundMessage msg) {
System.out.println("Outbound handler called from Gateway: "
+ gateway.getGatewayId());
System.out.println(msg);
}
}
public static void main(String args[]) {
Main app = new Main();
try {
app.sendMessage();
} catch (Exception e) {
e.printStackTrace();
}
}
}