I was wondering can anyone point me to a good tutorial on how to construct a SDP message.
I have read the basics and can construct and understand the parameters but I just can't seem to get it to work.
I either get a not acceptable here reply or no reply at all, this is after I get 100 Trying and 180 ringing back.
So my SIP works but it doesn't like the SDP Data.
Its currently constructed like this:
String sdpData = "v=0\r\n"
+ "o=- 019078020 0"
+ " IN IP4 sip.ciceronetworks.com\r\n" + "s=MySession\r\n"
+ "c=IN IP4 sip.ciceronetworks.com\r\n"
+ "t=0 0\r\n" + "m=audio 6002 RTP/AVP 0\r\n"
+ "a=sendrecv\r\n" + "a=rtpmap:0 PCMU/8000\r\n" + "a=ptime:20\r\n"+ "a=fmtp:97 mode=20\r\n";
byte[] contents = sdpData.getBytes();
request.setContent(contents, contentTypeHeader);
And while like that I get 100 trying then 180 ringing but when I accept the call on the other end I get nothing back at all, it seems to just crash, I also get "Audio device Error" on the pc client that I try ringing.
Anyone any ideas?
The issue could be really simple: you seem to forgot the newline after "a=sendrecv". :-)
Anyway, here's an advice:
For testing purposes you are probably better off using a tool rather than jumping right in and writing parts of the protocol. You can use sipp for this purpose, it makes a great tool for testing SIP networks. Other than that you could of course just sniff the network traffic between two working SIP devices and see how it differs from your traffic.
EDIT:
I missed this one before:
You should omit a=fmtp:97 mode=20, as the session description is invalid this way: You may only use the format parameter attribute for codecs that are mentioned in the media line. Codecs are identified via the payload type number (0=PCMU, 8=PCMA, 18=G723, ...). Some codecs don't have officially assigned numbers, for these the dynamic range 96-127 should be used: user agents are free to assign a number in this range via an rtpmap attribute. So, unless you specify which codec you mean by 97, there is no way for the other user agent to know which codec the format parameters should be applied to.
Paprika is right: the a=fmtp:97 mode=20 is simply wrong (and looks like it's part of an iLBC codec offer). You didn't offer codec 97, you offered codec 0 (PCMU).
Note that the a=fmtp:97 shouldn't hurt you, it's just spurious.
The most likely problem is that you are not sip.ciceronetworks.com - i.e. your c= line (and m= line) said "send my media to port 6002 at sip.ciceronetworks.com". I suspect your PC's IP address is not the same as sip.ciceronetworks.com, and/or there's a firewall/NAT between you and the other end.
It probably isn't your problem, but the o= line is wrong per the spec
From RFC 4566:
o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>
Getting VoIP to work is not as simple as the RFCs or cookbook explanations would imply....
I found a good article which deals with SDP (Session Description Protocol). It is also in relationship with an SDK which is called Ozeki VoIP SIP SDK. If you combine these things you will be able to create a softphone for instance.
There is also a brief overall about SDP.
Working with SDP in VoIP SIP calls is an interesting topic for those who wish to develop their own softphone or webphone application or what you desire.
SDP describes multimedia communication session for the purposes of session announcement, session invitation, and parameter negotiation.
The usage of an SDK can take a lot of burden from one's shoulder bucasue flexibility and high compatibility is assured.
For more information regarding SDP in connection with an SDK to build own applications you can have a look at the mentioned article if you Google for: "Working with SDP in VoIP SIP calls"
Related
I´m developing a personal application, using EMV reader and Javax SmartCardIO, I´m trying to get all the plain data from a SmartCard, I've been reading the specification and some tutorials, even reading some questions here but I came up with a problem:
I'm trying to get the size of a record in the SFI in order to iterate all the records with that information.
I've read in some tutorials that I need to send a request with length 0 and the chip is going to answer with an error code and the correct length of the record("6C XX"), however in my cards (Visa and AMEX) is returning another response which translates to the type of card ("VISA ELECTRON and AMERICAN EXPRESS") and I'm not getting the "6c xx" error.
My code so far looks like this:
byte[] commandArr = {(byte)0x00, (byte)0xB2, (byte)0x01, (byte)0x0C, (byte)0x00};
CommandAPDU commandTest = new CommandAPDU(commandArr);
ResponseAPDU test = this.channel.transmit(commandTest);
System.out.println(hexToAscii(bytesToHex(test.getBytes())));
Both cards have the SFI for the first PSE record in 01 (got that with the select PSE command after the 88 tag).
I'm new using this technology and I'm kind of lost right now, any help is welcome.
Thanks!
In addition to Alexander Vaganov's answer -- javax.smartcardio package handles the 61XX and 6CXX cases automatically, unless told not to do so (by sun.security.smartcardio.t0GetResponse and sun.security.smartcardio.t1GetResponse system properties).
Setting this properties to false should result in the expected behavior (i.e. getting the 6CXX status word).
I am not aware of any documentation for this, so have a look into the source code.
To disable the abovementioned automatic handling of 61XX and 6CXX cases add the following arguments to the java command line:
-Dsun.security.smartcardio.t0GetResponse=false -Dsun.security.smartcardio.t1GetResponse=false
Good luck!
When you establish connection with the card in contact mode, you choose one of two transmission protocol T0 or T1. The main function of them is equal - communicate with card, but realisation and interface are different. Cart may support one of these protocols or both. The one of differenes is how to get responce from card. In T0 responce may constit of two parts (commands). When you got SW=61XX where xx length of response you need perform command GetResponce 00C00000XX to "read" response data. In T1 you get all data with SW at once.
In your case it seems using T1, so card return all data without SW=61XX.
Some parts of documentation:
public abstract Card connect(String protocol) throws CardException
The protocol to use ("T=0", "T=1", or "T=CL"), or "*" to connect using any available protocol.
public abstract ResponseAPDU transmit(CommandAPDU command) throws CardException
Implementations should transparently handle artifacts of the transmission protocol. For example, when using the T=0 protocol, the following processing should occur as described in ISO/IEC 7816-4:
if the response APDU has an SW1 of 61, the implementation should issue a GET RESPONSE command using SW2 as the Lefield. This process is repeated as long as an SW1 of 61 is received. The response body of these exchanges is concatenated to form the final response body.
if the response APDU is 6C XX, the implementation should reissue the command using XX as the Le field.
Currently I am working with the Schneider Power Logic electrical device. I want to read the data from the device and show the value in my system. So far, I discover J2mod, Jamod and Modbus4Java library. I used all modbus4java to connect and get the device's data.
Actually I still confuse whether I suppose to create Master side or Slave side. Based on my understanding, the device will be Slave and my system will be Master (1st question).
Below is the setting AT MY DEVICE. It indicate that the device in slave mode and its protocol is Modbus RTU. So, I need to create a master apps to communicate with it right which is using the ModbusRTU protocol right ? (2nd question)
Mode: Slave
Protocol: Modbus RTU
Address: 1
Baud Rate: 38400
Parity: None
Below is the code of my apps act as the Master and using the ModbusRTU protocol
public static void main(String[] args) throws ModbusTransportException, ErrorResponseException {
ModbusFactory factory = new ModbusFactory();
SerialParameters params = new SerialParameters();
params.setCommPortId("COM6");
params.setBaudRate(9600);
params.setDataBits(8);
params.setStopBits(1);
params.setParity(0);
ModbusMaster master = factory.createRtuMaster(params);
master.setTimeout(1000);
master.setRetries(0);
long start = System.currentTimeMillis();
try {
master.init();
} catch (Exception e) {
System.out.println( "Modbus Master Init Error: " + e.getMessage());
return;
}
try {
System.out.println("Reg. 1001 Value:" + master.getValue(1, RegisterRange.HOLDING_REGISTER, 3110, DataType.FOUR_BYTE_FLOAT_SWAPPED));
}
finally {
master.destroy();
}
System.out.println("Time elapsed: " + (System.currentTimeMillis() - start) + "ms");
}
This is the code that I get from the sample code provide by the Modbus4Java page. The other thing that concern me is the value of params.setCommPortId("COM6"); What other value than "COM6" that I can put there. Because basically it receive a String value. So am I able to put any String value to it ? And what is the function of this particular setCommPortID. (3rd question)
Looking at the sample code provide by the Modbus4Java page, it does not put the IP address of the device. But in my case, my device got an IP address. And the IP address only use in the Slave apps only. How should my system recognize the IP address of the device ? (4th question).
And after I run this code snippet, I got an error:
Stable Library
Native lib Version = RXTX-2.1-7
Java lib Version = RXTX-2.1-7
Modbus Master Init Error: com.serotonin.io.serial.SerialPortException: gnu.io.NoSuchPortException
Please, please and please help me. I been stuck with this almost a month. Really hope someone out there will be able to help me. Thank you in advance for any kind of help and suggestion.
I'm the maintainer for j2mod, so my answer is going to suggest you look at the test programs which are included with j2mod. You can find j2mod on SourceForge at this URL --
https://sourceforge.net/projects/j2mod/
I'm pretty good about answering questions there, but I also follow stackoverflow, so I can explain more here as well. There are a LOT of questions in here, so I apologize in advance if I've missed anything.
The Schneider device is the slave, or "server" and your application is the master or "client". Modbus is a master/slave protocol, with the master initiating all requests. Your application will be the master and responsible for making all requests of your device.
The exact communications will be provided by the device documentation. In this instance, you indicate that the device uses 38400 baud, and so forth. Those are the parameters you will use to update SerialParameters with the RXTX library (which just so happens to also be used by j2mod).
The value passed to setCommPortId() is the Windows COM port identifier - you should be able to pass any value which is associated with an actual COM port -- "COM1", "COM2", etc. Note that some USB converters change their COM port each time they are used, so you may be chasing port names.
You mentioned that your device also has an IP address. You cannot use the RTU classes and methods to access a Modbus/TCP device. The same is true for jamod and j2mod - most Modbus libraries have different classes for RTU and TCP transports (as well as ASCII and UDP, for libraries which support those other transports).
Context:
I am working on a piece of Java code where I am reading mails from an array (which works fine). I was wondering if someone can help me with the callback in order to show a fancy message like Your email was sent.
Questions:
How do I implement this?
Is there any way to get any Boolean type return value from javax.mail to check if the message was sent or not?
Maybe I should create a pool? If yes, how do I do that? Is there any signal to kill the pool?
Code:
// addressTo is the array.
Transport t = sesion.getTransport(this.beanMail.getProtocolo());
t.connect(this.beanMail.getUsuario(), this.beanMail.getPassword());
t.sendMessage(mensaje, addressTo);
t.close();
Quoting from the JavaMail API FAQ (in the context of tracking bounced messages):
While there is an Internet standard for reporting such errors (the multipart/report MIME type, see RFC1892), it is not widely implemented yet. RFC1211 discusses this problem in depth, including numerous examples.In Internet email, the existence of a particular mailbox or user name can only be determined by the ultimate server that would deliver the message. The message may pass through several relay servers (that are not able to detect the error) before reaching the end server. Typically, when the end server detects such an error, it will return a message indicating the reason for the failure to the sender of the original message. There are many Internet standards covering such Delivery Status Notifications but a large number of servers don't support these new standards, instead using ad hoc techniques for returning such failure messages. This makes it very difficult to correlate a "bounced" message with the original message that caused the problem. (Note that this problem is completely independent of JavaMail.)
Source
Greetings,
I am creating a Java based server to create push notifications for Apple's iOS APNs service. I have found Javapns on google code which seems to provide a simple basic framework to communicate with APNs, and which seems to be fairly wide used.
http://code.google.com/p/javapns/
However, reading Apple's docs, there is an "enhanced format" for notifications which supports "expiry" i.e. setting a time (well, in seconds) for a notification to expire if it hasn't yet been delivered. I do not see any way to set this using Javapns, and I am unsure how the APNs service handles expiry of notifications if you do not explicitly set it. So,
Does anyone know how to support the enhanced notification format of APNs specifically how to set the expiry?
Does anyone know how Apple handles notification expiry if it isn't explicitly set?
Does anyone have any suggestions that don't require me to start from scratch, as the server is currently functional as is?
Thanks in advance.
Andrew
I have recently made substantial contributions to the JavaPNS project, which lead to the release of JavaPNS 2.0 a few days ago. That version provides full support for the enhanced notification format, including the ability to set your own expiry.
Sylvain
Nice that you found the java library... to bad you didn't read the docs there.
I'll post some of the highlights below:
The existing code uses the 'Simple notification format' which does not return an error EVER.
See docs at:
http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html
I've tried updating to the 'Enhanced notification format' which is supposed to return an error, but I'm unable to get any errors back from the APNS. (also in the link above)
With the Enhanced format, the connection isn't being dropped immediately after sending data, but I'm not getting anything back from my socket.getInputSocket.read() call.
This issue will have to be tabled until I have more time to troubleshoot.
(Someone else commented)
Thanks a lot for looking into it.
I got the same result as yours. Maybe it has something to do with Apple Gateway.
So... you could:
1) Build your own
2) Help improve the existing library
3) Try another library like: https://github.com/notnoop/java-apns
4) Do nothing
Enhanced ios push here.
To send a notification, you can do it in three steps:
Setup the connection
ApnsService service =
APNS.newService()
.withCert("/path/to/certificate.p12", "MyCertPassword")
.withSandboxDestination()
.build();
Create and send the message
String payload = APNS.newPayload().alertBody("Can't be simpler than this!").build();
String token = "fedfbcfb....";
service.push(token, payload);
To query the feedback service for inactive devices:
Map<String, Date> inactiveDevices = service.getInactiveDevices();
for (String deviceToken : inactiveDevices.keySet()) {
Date inactiveAsOf = inactiveDevices.get(deviceToken);
...
}
Is there a relatively simple way in Java to check if a domain is available or not?
I need a reliable method, so only checking if the connection can be made is not enough.
Domain availability depends on having a whois client. Here is a link to an implementation of a whois client in Java:
Java Whois Client
You'll need to parse the results - and depending on what whois server you use, you may (will) have varying formats that are returned. The best thing to do is to pay for a commercial whois/registration service such as OpenSRS. They have an extensive API which you can use as a registered reseller. Here are the API docs:
http://opensrs.com/resources/documentation/opensrs_xmlapi.pdf
HTH,
-aj
There's a good Whois Java client here:
https://github.com/ethauvin/Whois
You can run it from the command line or interface with it directly:
// don't include the www
Whois.main(new String[] {"skytouch.com"});
Another solution is to use Apache Commons lib. Simplified example:
import org.apache.commons.net.whois.WhoisClient;
public String getWhois(String domainName){
WhoisClient whois = new WhoisClient();
whois.setConnectTimeout(10000);
whois.setDefaultTimeout(10000);
whois.connect("whois.verisign-grs.com", 43);
String domainWhois = whois.query(domainName);
whois.disconnect();
return domainWhois;
}
Check if response equals "no match". Whois servers, timeout length and no availability response differ according to extension so you should have prepared additional collections for them.
Whois servers list can be found:
http://www.mit.edu/afs/athena/contrib/potluck/Net-Services/whois-servers.list
https://raw.githubusercontent.com/whois-server-list/whois-server-list/master/whois-server-list.xml
http://www.nirsoft.net/whois_servers_list.html
If you try to make your queries concurrent, you will definitely get whois response "You have reached configured rate limit." or explicit exception in a code so you should repeat queries after some sleep.
Performing a DNS lookup on the domain is the easiest solution. All available domains will have no DNS record, and most registrars assign a default DNS entry upon registration.
WHOIS lookups will be your most reliable solution, particularly behind an ISP that spoofs their own server (with a "domain not found" page filled with ads) for any missing domain name.