Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Thursday, December 20, 2012

CSipSimple - Getting started to hack it (tailor to my needs)


Just one or two things I need to remember about CSipSimple:

Infrastructure
  • SipStack runs in background (communication via Parcable interface). It interacts with PJSIP.
    Important there is a watchdog timer (about 5s)!
  • pjsua.java, pjsuaConstants is the SWIG generated interface to PJSIP
  • Native functions never return boolean, check for pjSuaConstants.PJ_SUCCESS
  • Be aware of string exchange with the native stack: PjSipService.pjStrToString(...)
  • UAStateReceiver.java does the call creation and everything related to SipStack
  • PjSipService.java is deeply integrated with UAStateReceiver.java (for example does recording...)

UI
  • CustomDistribution.java defines some things for fast modifying the behavior
  • Main screen is created in SipHome.java (incl. the slidable tabs)
    To remove tabs, just disable tab.add (except for the warning tab and the message tab [message disable in CustomDistribution.java]: may be triggered from outside)
  • Notifications are handled in SipNotifications.java (but from Sip-Thread)
  • DialerFragment.java is the dialer incl. call button and account switcher...
    Here the re-dial functionality is missing... (press the call button twice without number should redial previous number)
  • InCallActivity.java :)
    Important call setup is done BEFORE launching the InCallActivity via SipManager.ACTION_SIP_CALL_UI from UAStateReceiver.launchCallHandler(...).
    There is even a activity start delay of 2000ms (UAStateReceiver.LAUNCH_TRIGGER_DELAY).
    I think it's not nice!!!! Because a user may hear sound of before the UI is ready, but there is might be a problem with race conditions...
  • InCallControls.java is the ui element on the bottom of InCallActivity to control Bluetooth and loudspeaker etc. (Deeply integrated with InCallActivity: sadly NO MVC...)
  • InCall.java is also related to Dialer

Saturday, March 20, 2010

Java Servlet (3.0): How can I access multipart encoded content provided by a http post request?

At the last friday i stood right before a tricky problem: How can I save a image provided via HTTP post into a database?
I had three problems:
1. How to upload a file via HTML?
2. How to access the data at the server side?
3. How to put in the database using JPA?

The first one was easy, just create a html form add a input field (type='file') and a submit button.

The second one cost me one day. And it was really simple: Just place the @MultipartConfig annotation at the class definition of the servlet and use HTTPRequest.getPart[s]() methods to access the data as an inputstream.

The last part was straight forward: use a InputStreamReader to copy the data into a byte[] and add @Lob byte[] field to the entity class.

Because I use MySQL it was necessary to change the columnt type from TEXT to MEDIUMBLOB.

Sunday, February 7, 2010

Java: CDI & ConversationScope

Yesterday I recreated my web app project with maven. Now CDI is available and @ConversationScoped is really nice and makes the development a lot easier.
I used Glassfish v3.

... Post my pom.xml tomorrow again.

Monday, May 26, 2008

JTree on an JScrollPane and resizing

Early on the morning I read my early morning bug reports ;).

It was about an JTree on a JScrollPane. The model of the will be modified during runtime and fires events if something is changes. So far everything looks pretty straight forward and it works.

The problem occured if the tree gots larger than the parent scrollpane, so I believed the scrollpane starts to activate the scrollbars and everything stays cool... But the tree never changed it's size. It simple stayed in the old size and the scrollpane didn't start scrolling. And so some items of the tree were invisible.

TreeModel model = new DefaultTreeModel();
JTree tree = new JTree(model);
tree.setPreferredSize(new Dimension(100, 100));
JScrollPane pane = new JScrollPane(tree);
The model fires an TreeModelEvent (DefaultTreeModel.nodeStructureChanged) and the tree get's an JTree.treeDidChange() so it can recompute it's size.

This doesn't work out. It was necessary to set the preferred size of the tree to null before excecuting treeDidChange...

Why? I honestly don't know...

Wednesday, November 21, 2007

JOptionPane and the Focus

I started to write a login screen (NEED: two input field [username, password]and two buttons [ok, cancel]). Since a login is a blocking panel I created a JPanel and put that on a JOptionPane.showDialog(...). Everything looked quite fine, but the default focus was set on the OK-Button. So I tried to requestDefaultFocus, but nothing worked. Mark provides a running solution. And it works!

Monday, August 20, 2007

Java Base64 encoding (sun.misc.Base64Encoder)

Today I would like to say some words about BASE64 encoding and JAVA. Let me introduce a cool class to encode a string: sun.misc.Base64Encoder
This class seams to work quite all right for some weeks. So, today we transfered our JEE server from a linux to windows (not my idea). Till now I have assumed that the mythos of the JAVA plattform independence is not only a myth. During the check of the application (the deployed JEE project) it showed up error messages that the base64 coded strings doesn't match.
On the first look everything seemed to be fine. The second showed up that the strings on the windows machine were one (!) character longer. Two hours later we found the problem: Does RFC 3548 say something about line feeds and carriage return?
So why does the base64 coded strings contain some?
The anwser is: Because the encode method of the Base64Enconder split the string after some characters (I suppose at char 76 / 77, but I'm not quite sure). So if you switch the operation system and the new system uses another encoding for the line break, your old base64 encoded data is worthless.
To solve this problem I used the java mail api (cause JEE server needs to implement these):
StringOutputStream output = new StringOutputStream();
OutputStream encoding = MimeUtility.encode(output, "base64");
encoding.write("Hello World");
result = output.toString();
import java.io.IOException; import java.io.OutputStream;
/** * * @author Dennis Guse * */
public class StringOutputStream extends OutputStream {
  private StringBuffer data = new StringBuffer();
  public StringOutputStream() {}
  public String toString() {
    return data.toString();
  }
  public void write(int b) throws IOException { data.append((char)b); } }
So a half day of work for nothing....
PS: Feel free to use this stuff.