hope everyone is fine with this pandemic.
I receive a sms from a SMSC, and i would like to send him a deliver_sm_resp.
I try to implement it like that :
#Override
public PduResponse firePduRequestReceived(PduRequest pduRequest) {
logger.warn("***** BIND RECEIVER *****");
DeliverSm sms = null;
if ((pduRequest != null) && pduRequest.getName().equals("deliver_sm")) {
sms = (DeliverSm) pduRequest;
}
if ((pduRequest != null) && pduRequest.getName().equals("enquire_link")) {
return pduRequest.createResponse();
}
if ( sms !=null && (int)sms.getDataCoding() == 0 ) {
//message content is English
logger.warn("***** New Message Received *****");
logger.warn("From: " + sms.getSourceAddress().getAddress());
logger.warn("To: " + sms.getDestAddress().getAddress());
logger.warn("Content: " + new String(sms.getShortMessage()));
DeliverSm deliver = new DeliverSm();
deliver.setSourceAddress(sms.getSourceAddress());
deliver.setDestAddress(sms.getDestAddress());
deliver.setDataCoding(sms.getDataCoding());
try {
deliver.setShortMessage(sms.getShortMessage());
} catch (SmppInvalidArgumentException e) {
e.printStackTrace();
}
deliver.setSequenceNumber(sms.getSequenceNumber());
//deliver.setCommandLength(sms.getCommandLength());
deliver.setCommandStatus(sms.getCommandStatus());
runDeliverSmRespSmppSessionHandler(session, deliver);
}
return super.firePduRequestReceived(pduRequest);
}
i call runDeliverSmRespSmppSessionHandler asynchrously, like that :
public class RunDeliverSmRespSmppSessionHandler extends DefaultSmppSessionHandler implements Runnable {
.
.
.
public void run() {
logger.info("welcome to deliver TestSmppSessionHandler RUN");
sendRequestPdu(session, deliver);
}
private void sendRequestPdu(SmppSession session, DeliverSm deliver) {
logger.info("welcome to deliver TestSmppSessionHandler sendRequestPdu");
try {
WindowFuture<Integer,PduRequest,PduResponse> future = session.sendRequestPdu(deliver, 10000, false);
if (!future.await()) {
logger.error("Failed to receive deliver_sm_resp within specified time");
} else if (future.isSuccess()) {
DeliverSmResp deliverSmResp = (DeliverSmResp)future.getResponse();
logger.info("deliver_sm_resp: commandStatus [" + deliverSmResp.getCommandStatus() + "=" + deliverSmResp.getResultMessage() + "]");
} else {
logger.error("Failed to properly receive deliver_sm_resp: " + future.getCause());
}
} catch (Exception e) {
logger.error("message catched in smDeliver : "+e.getMessage()+" get stackTrace : "+e.getStackTrace());
}
}
Unfortunally, i had this error in sendRequestPdu():
04-04-2020 23:15:41 ERROR TestSmppSessionHandler:61 - Failed to receive deliver_sm_resp within specified time
04-04-2020 23:16:06 WARN EnquireLinkTask:37 - Enquire link failed, executing reconnect:
com.cloudhopper.smpp.type.SmppTimeoutException: Unable to accept offer within [10000 ms] (window full)
at com.cloudhopper.smpp.impl.DefaultSmppSession.sendRequestPdu(DefaultSmppSession.java:508)
at com.cloudhopper.smpp.impl.DefaultSmppSession.sendRequestAndGetResponse(DefaultSmppSession.java:464)
Thank you for your helping
to send a response to inform the SMSC than you received your SMS, you have to use
private void sendResponsePdu(SmppSession session, DeliverSmResp deliver) {
logger.info("welcome to deliver TestSmppSessionHandlerV2 sendRequestPdu");
try {
session.sendResponsePdu(deliver);
logger.info("message deliver response sent successfully !!!");
} catch (Exception e) {
logger.error("message catched in smDeliver : "+e.getMessage()+" get stackTrace : "+e.getStackTrace());
}
About DeliverSmResp deliver, you can initialize like that :
DeliverSmResp deliver_sm_resp = new DeliverSmResp();
deliver_sm_resp.setCommandLength(17);
deliver_sm_resp.setCommandStatus(sms.getCommandStatus());
deliver_sm_resp.setSequenceNumber(sms.getSequenceNumber());
deliver_sm_resp.setMessageId("");
I have started to develop chat application. I needed to check user has registered or not in xmpp server.So when user trying to register,I want check user has already registered or not in xmpp server. After xmpp server connected successfully,Tried to search as number using Usersearchmanager.But Getting error as
java.lang.IllegalArgumentException: Must have a local(user) JID set.Either you didn 't configure one or you where not connected at least once
at org.jivesoftware.smack.filter.IQReplyFilter. < init > (IQReplyFilter.java: 94)
at org.jivesoftware.smack.AbstractXMPPConnection.createPacketCollectorAndSend(AbstractXMPPConnection.java: 699)
at org.jivesoftware.smackx.search.UserSearch.getSearchForm(UserSearch.java: 73)
at org.jivesoftware.smackx.search.UserSearchManager.getSearchForm(UserSearchManager.java: 71)
at com.techno.samplechat.Myxmpp.searchUsers(Myxmpp.java: 335)
at com.techno.samplechat.Myxmpp$XMPPConnectionListener.connected(Myxmpp.java: 284)
at org.jivesoftware.smack.AbstractXMPPConnection.callConnectionConnectedListener(AbstractXMPPConnection.java: 1162)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectInternal(XMPPTCPConnection.java: 850)
at org.jivesoftware.smack.AbstractXMPPConnection.connect(AbstractXMPPConnection.java: 365)
at com.techno.samplechat.Myxmpp$1.run(Myxmpp.java: 117)
at java.lang.Thread.run(Thread.java: 818)
Code:
private void CreateAccount() {
org.jivesoftware.smackx.iqregister.AccountManager am = org.jivesoftware.smackx.iqregister.AccountManager
.getInstance(connection);
am.sensitiveOperationOverInsecureConnection(true);
Map < String, String > attributes = new HashMap < String, String > ();
attributes.put("username", loginUser);
attributes.put("email", "Manikandan.s#technoduce.com");
attributes.put("password", passwordUser);
attributes.put("name", UserName);
try {
if (am.supportsAccountCreation()) {
am.createAccount(
loginUser,
passwordUser,
attributes);
login();
}
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
}
private void login() {
try {
connection.login(loginUser, passwordUser);
Log.i("LOGIN", "Yey! We're connected to the Xmpp server!");
} catch (XMPPException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
ChatManager.getInstanceFor(connection).addChatListener(this);
}
#
Override
public void chatCreated(Chat chat, boolean createdLocally) {
Log.i("service", "chatCreated()");
System.out.println("+chatList++" + chat.getParticipant());
chat.addMessageListener(this);
}
#
Override
public void entriesAdded(Collection < String > addresses) {
}
#
Override
public void entriesUpdated(Collection < String > addresses) {
}
#
Override
public void entriesDeleted(Collection < String > addresses) {
}
#
Override
public void presenceChanged(Presence presence) {
}
#
Override
public void processMessage(Chat chat, Message message) {
if (message.getType() == Message.Type.chat || message.getType() == Message.Type.normal) {
if (message.getBody() != null) {
// Toast.makeText(this,message.getFrom() + " : " + message.getBody(),Toast.LENGTH_LONG).show();
System.out.println("++From++" + message.getFrom() + "++Body++" + message.getBody());
}
}
}
#
Override
public void pingFailed() {
}
private class XMPPConnectionListener implements ConnectionListener {
#
Override
public void connected(XMPPConnection connection) {
Log.e("success", "Connected");
try {
searchUsers(loginUser);
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
}
// CreateAccount();
}
#
Override
public void authenticated(XMPPConnection connection, boolean resumed) {
}
#
Override
public void connectionClosed() {
}
#
Override
public void connectionClosedOnError(Exception e) {
System.out.println("+_" + e.toString());
}
#
Override
public void reconnectionSuccessful() {
}
#
Override
public void reconnectingIn(int seconds) {
}
#
Override
public void reconnectionFailed(Exception e) {
}
}
public void searchUsers(String userName) throws SmackException.NotConnectedException, XMPPException.XMPPErrorException, SmackException.NoResponseException {
UserSearchManager search = new UserSearchManager(connection);
Form searchForm = search
.getSearchForm("search." + connection.getServiceName());
Form answerForm = searchForm.createAnswerForm();
answerForm.setAnswer("Username", true);
answerForm.setAnswer("search", userName);
ReportedData data = search
.getSearchResults(answerForm, "search." + connection.getServiceName());
if (data.getRows() != null) {
for (ReportedData.Row row: data.getRows()) {
for (String value: row.getValues("jid")) {
Log.i("Iteartor values......", " " + value);
}
}
} else {
CreateAccount();
}
}
String you are looking for must to be a JID, not an username:
you need something like:
user1#myserver
and not just
user1
Then, it's quite useless in your usecase to check for JID.
I have register user using below code on smack 4.1:-
//Login User
public XMPPTCPConnection loginUser(Context objContext, XMPPTCPConnection objXmpptcpConnection, String strUsername, String strPassword) {
try {
AccountManager objAccountManager = AccountManager.getInstance(objXmpptcpConnection);
objAccountManager.createAccount(strUsername, strPassword);
objXmpptcpConnection = loginToServer(objXmpptcpConnection, strUsername, strPassword);
} catch (SmackException | XMPPException e) {
System.out.println("Msg=" + e.getMessage() + "\nCause =" + e.getCause() + "\n Local msg=" + e.getLocalizedMessage() + "\n stack=" + e.getStackTrace() + "\n class " + e.getClass());
System.out.println("Code=" + e.getStackTrace()[0].getLineNumber());
if (e.getMessage().contains("conflict")) {
objXmpptcpConnection = loginToServer(objXmpptcpConnection, strUsername, strPassword);
}
}
return objXmpptcpConnection;
}
private XMPPTCPConnection loginToServer(XMPPTCPConnection objXmpptcpConnection, String strUsername, String strPassword) {
try {
objXmpptcpConnection.login(strUsername + "#" + AppConstants.HOST, strPassword, "example");
// objXmpptcpConnection.sendPacket(new Presence(Presence.Type.unavailable));
//objXmpptcpConnection.sendPacket(new Presence(Presence.Type.available));
} catch (XMPPException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Log.i("XMPPChatDemoActivity", "Logged in as "
+ objXmpptcpConnection.getUser());
Toast.makeText(
objContext,
"log in as "
+ objXmpptcpConnection.getUser(),
Toast.LENGTH_SHORT).show();
return objXmpptcpConnection;
}
Using above two methods register user to ejabberd successfully.
And Connect Method is:-
public XMPPTCPConnection connect(String strUsername, String strPassword) throws IOException, XMPPException, SmackException {
objXmpptcpConnection = null;
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
// Create a connection
XMPPTCPConnectionConfiguration.Builder config = XMPPTCPConnectionConfiguration.builder();
config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
config.setServiceName(Constants.HOST);
config.setPort(Constants.PORT);
config.setHost(Constants.HOST);
config.setDebuggerEnabled(true);
config.setSendPresence(true);
config.setUsernameAndPassword(strUsername + "#" + Constants.HOST, strPassword);
SASLAuthentication.blacklistSASLMechanism("SCRAM-SHA-1");
SASLAuthentication.blacklistSASLMechanism("DIGEST-MD5");
SASLAuthentication.unBlacklistSASLMechanism("PLAIN");
objXmpptcpConnection = new XMPPTCPConnection(config.build());
objXmpptcpConnection.setUseStreamManagement(true);
objXmpptcpConnection.setUseStreamManagementResumption(true);
try {
ProviderManager objProviderManager = new ProviderManager();
ProviderManager.addExtensionProvider(DeliveryReceipt.ELEMENT, DeliveryReceipt.NAMESPACE, new DeliveryReceipt.Provider());
ProviderManager.addExtensionProvider(DeliveryReceiptRequest.ELEMENT, new DeliveryReceiptRequest().getNamespace(), new DeliveryReceiptRequest.Provider());
ProviderManager.addIQProvider("query", "http://jabber.org/protocol/bytestreams", new BytestreamsProvider());
ProviderManager.addIQProvider("query", "http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());
ProviderManager.addIQProvider("query", "http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());
// Offline Message Requests
objProviderManager.addIQProvider("offline", "http://jabber.org/protocol/offline", new OfflineMessageRequest.Provider());
// Offline Message Indicator
objProviderManager.addExtensionProvider("offline", "http://jabber.org/protocol/offline", new OfflineMessageInfo.Provider());
objXmpptcpConnection.connect();
System.out.println("Connected to===>" + objXmpptcpConnection.getHost());
objXmpptcpConnection.login();
objDeliveryReceiptManager = DeliveryReceiptManager.getInstanceFor(objXmpptcpConnection);
objDeliveryReceiptManager.autoAddDeliveryReceiptRequests();
objDeliveryReceiptManager.setAutoReceiptMode(DeliveryReceiptManager.AutoReceiptMode.disabled);
objDeliveryReceiptManager.addReceiptReceivedListener(this);
} catch (XMPPException e) {
e.printStackTrace();
return objXmpptcpConnection;
} catch (SmackException e) {
e.printStackTrace();
return objXmpptcpConnection;
} catch (IOException e) {
e.printStackTrace();
return objXmpptcpConnection;
}
return objXmpptcpConnection;
}
Also you want to check ejabberd side configuration also.
Its working for me tried using the answer :- Smack API User search.
Hope its useful to you.
I wonder how to confirm a request of adding friends.
Smack Version 4.1.1
As I know now ,
roster = Roster.getInstanceFor(con);
roster.setSubscriptionMode(Roster.SubscriptionMode.manual);
roster.createEntry(targetUser, nickname, new String[] {"friends"});
will create a roster in the database, and send a stanza request to the targetUser.
And my stanza listener is as follows:
StanzaListener callback = new StanzaListener() {
#Override
public void processPacket(Stanza stanza) throws NotConnectedException {
// TODO Auto-generated method stub
String head = con.getUser() + " : ";
System.out.println(head + "Got the presence stanza");
if(((Presence)stanza).getType().equals(Presence.Type.subscribe)) {
Presence subscribed = new Presence(Presence.Type.subscribed);
subscribed.setTo(stanza.getFrom());
System.out.println(head + subscribed.getFrom());
subscribed.setFrom(stanza.getTo());
con.sendStanza(subscribed);
if( ! roster.contains(stanza.getFrom())) {
System.out.println(head + "Friend added.");
addFriend(stanza.getFrom(),"computer");
}
} else {
System.out.println(head + "Subscribed received from " + stanza.getFrom());
if(roster.contains(stanza.getFrom())) {
System.out.println(head + "OK");
}
}
}
};
It does not work, I wonder when the targetUser receives the stanza request , how to send a callback presence(or something else) to confirm or approve or agree?
How to add a friend?
Try this:
public void addFriend(User usuario) {
if (APDApplication.connection != null && APDApplication.connection.isConnected()) {
try {
Roster.setDefaultSubscriptionMode(Roster.SubscriptionMode.manual);
Roster roster = Roster.getInstanceFor(APDApplication.connection);
if (!roster.contains(usuario.getChatId())) {
roster.createEntry(usuario.getChatId() + "#jabber/Smack", usuario.getName(), null);
} else {
logManager.error("Contacto ya existente en la libreta de direcciones");
}
} catch (SmackException.NotLoggedInException e) {
e.printStackTrace();
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Hope this helps you!!
When a user clicks on a link, I want to change the page and then load the relevant info.
However, the HTMLElement is always null.
The following is the code:
WebViewPanel.java
//to be used in JFX Thread
public void loadURLFX(final String url) {
if (Misc.stringHasContent(url)) {
String tmp = toURL(url);
if (tmp == null) {
tmp = toURL("http://" + url);
}
boolean invalidURL = false;
InputStream stream = null;
try {
URL urlObj = new URL(tmp);
stream = urlObj.openStream();
} catch (Exception e) {
invalidURL = true;
} finally {
try {
stream.close();
} catch (Exception ex) {
}
stream = null;
}
if (!invalidURL) {
engine.load(tmp);
} else {
//https://www.google.com.sg/search?q=searchTerm
engine.load("https://www.google.com.sg/search?q=" + url);
}
}
}
App.java
public void load(){
if(Platform.isFxApplicationThread()){
webViewPanel.loadURLFX(App.class.getResource("/hello.html").toExternalForm());
HTMLElement element = (HTMLElement) WebMisc.getHTMLElement(webViewPanel.getWebEngine(), "menu");
}
}
element is always null. What should I do to fix it?
I have been using the Google Drive SDK in both Java and Objective-c for months now and suddenly today (Jul 10, 2013) inserting new files using the java api (google-api-client-1.15.0-rc.jar & version 1.14) is failing to execute on FileInsert.execute(). Here is the static helper method I've been using (basically a copy from the DrEdit tutorials):
public static File insertFile(Drive driveService, String title, String description,
String parentId, String mimeType, java.io.File content) {
System.out.println("<GDrive insertFile> start");
File body = new File();
body.setTitle(title);
body.setDescription(description);
body.setMimeType(mimeType);
if (parentId != null && parentId.length() > 0) {
body.setParents( Arrays.asList(new ParentReference().setId(parentId)) );
}
Insert fileInsert = null;
System.out.println("<GDrive insertFile> before content attache");
if (content != null && content.length() > 0) {
FileContent mediaContent = new FileContent(mimeType, content);
try { fileInsert = driveService.files().insert(body, mediaContent); }
catch (IOException e) { e.printStackTrace(); }
} else {
try { fileInsert = driveService.files().insert(body); }
catch (IOException e) { e.printStackTrace(); }
}
try {
if (fileInsert != null) {
System.out.println("<GDrive insertFile> before execute");
File file = fileInsert.execute();
System.out.println("<GDrive insertFile> file posted " + file.getId());
return file;
} else return null;
} catch (IOException e) {
System.out.println("An error occured: " + e);
return null;
}
}
Obviously System.out was used to locate the issue, it hangs up on "before execute". I haven't been able to find any posts about Google server issues or changes in how the api is to be used. Here is the error message that is logged when the app fails any time after 20 - 180 seconds:
An error occured: java.net.SocketTimeoutException: Read timed out
Exception in thread "main" java.lang.NullPointerException
Thanks.