SMPP Forum's documentation page contains valuable protocol and application related FAQs.
There is also a discussion board on forum's pages with invaluable answers to many protocol related questions.

Q What for is this "SMPP"?
A SMPP, or Short Message Peer to Peer, is messaging protocol for integration of applications with wireless mobile network messaging systems. With SMPP you can as an application developer send data to mobile devices or to the other applications over SMSC (Short Messasge Service Centre).
 
Q Can I use your SMPP library in my programs and sell my programs without paying you anything?
A Yes, as long as you agree with the licence agreement.
 
Q Should I enclose your source code with my programs?
A No, it is not necessary. If you want, you can provide your customer with the compiled library only.
 
Q How do I send ring tone, operator logo and picture?
A Sending of this type of data is mobile phone vendor specific. What's described here is sending of ringing tones to Nokia phones. The details about sending of pictures and operator logos can be found in Nokia's Smart Messaging Specification v 3.0.0 (see forum.nokia.com) for Nokia phones or in other vendor specific documentation, however the general procedure is similar.

If you want to send ring tone (or picture or operator logo), you have to prepend the actual data with binary User Data Header (these are specified in GSM 03.40, see www.etsi.org). The UDH you have to use basically contains source port and destination port where the phone expects certain type of data. For different data types there can be additional information as well. For example fo Nokia phones the destination port for ring tones is 0x1581. See the example below. (IE is information element)

Note that UDHs aren't supported directly in the toolkit at the moment. It means that there is nothing like class UDH which would simplify creation of the UDHs and automatic concatenation with the message content. So you have to create the binary content representing the UDH "manually".

  // let's assume that the session is already created
  // and the application is already bound to the smsc

  // we'll send the data as submit_sm PDU
  SubmitSM request = new SubmitSM(); 

  // set the source and destination phone numbers
  request.setSourceAddr("353871234567"); 
  request.setDestAddr("353867654321"); 

  // create a buffer for the message payload
  ByteBuffer message = new ByteBuffer(); 

  // UDH is needed to tell the mobile phone details 
  // how to deliver the data in the message payload
  // first goes UDH length -- this UDH will have 6 bytes 
  message.appendByte((byte)6); 

  // then goes IE -- information element
  // IE Identifier -- 5 means that the following will
  // be destination and originator port numbers
  message.appendByte((byte)5); 

  // IE Data Length -- the length of the IE
  // two ports per two bytes = 4 
  message.appendByte((byte)4); 

  // the destination port -- port where ringing tone is received 
  // on Nokia phones 
  message.appendShort((short)0x1581); 

  // originator port (unused in fact)
  message.appendShort((short)0x0000); 

  // load the ringtone data into a buffer.
  // note that we expect that the ringtone data are already
  // in the Nokia's format specified in the Smart Messaging Specs.
  // Nokia PC Composer can save tones in this format.
  // my ringtone file is called test.ott
  ByteBuffer toneData = loadByteBuffer("test.ott"); 

  // simply append the ring tone data to the message payload
  message.appendBuffer(toneData); 

  // we send all the data as a message payload
  request.setMessagePayload(message); 

  // you must set the esme class to indicate that the message
  // contains UDH
  request.setEsmClass((byte)(Data.SM_UDH_GSM)); 

  // the coding is GSM specific
  request.setDataCoding((byte)0x0f5);

  // finally submit the mesasge
  response = session.submit(request); 

  // for your convenience here is the code for loading
  // of the data from a file
  public ByteBuffer loadByteBuffer(String fileName) 
  throws FileNotFoundException,IOException 
  { 
      FileInputStream is = new FileInputStream(fileName); 
      byte[] data = new byte[is.available()]; 
      is.read(data); 
      is.close(); 
      return new ByteBuffer(data); 
  } 
  

Well, and that's it.
 

Q How can i send UCS2/16 Bit messages? Everytime I set the Data Coding to 0x08, the message appears as boxes on my phone.
A This feature is only supported since version 1.3 of the library. If you have older version, you must download 1.3 version to use this feature.
You have to 'tell' the SubmitSM object what type of encoding is used in the message text when you call setShortMessage. See the example:
  SubmitSM request = new SubmitSM();

  // this is my chinese message
  String myMessage = "\u4e2d\u6587\u5b57\u5b57";

  // set addresses etc...
  // (...)

  // set the message data with the encoding indication
  // Data.ENC_UTF16_BE is for 2 byte unicode Big Endian encoding
  // without byte order mark
  request.setShortMessage(myMessage, Data.ENC_UTF16_BE); 

  // set the indication of data coding
  request.setDataCoding(0x08);

  // and that's it, now you can submit the request
  session.submit(request);
Or if you use message payload field for sending the message data, you need to define a buffer to prepare the message payload:
  String myMessage = "\u4e2d\u6587\u5b57\u5b57";
  SubmitSM request = new SubmitSM();
  ByteBuffer payload = new ByteBuffer(); 
  payload.appendString(myMessage, Data.ENC_UTF16_BE);
  request.setMessagePayload(payload);

  // etc.
Note that Data class contains encoding definition for encodings supported by the rt.jar Java library, which should be suported on all systems. There is more encodings specified which are distributed in i18n.jar library.