Tag: connection

Set the connection timeout for TCP connections through the BlackBerry MDS Connection Service

 

This is how to set the connection timeout for TCP connections through the BlackBerry MDS Connection Service.[1]

When making a Transmission Control Protocol (TCP) connection from a BlackBerry smartphone, the default connection timeout is 2 minutes. This value takes into consideration the possible time it can take a BlackBerry smartphone to be granted access to send data on the wireless network, and for the connection to travel over the wireless network over the Internet to the destination server and back again. In some circumstances, this value is too long. When making a socket or Hypertext Transfer Protocol (HTTP) connection through the BlackBerry® Mobile Data System (BlackBerry MDS) Connection Service, it is possible to set the timeout value to a lower value than the value that is configured in the BlackBerry MDS Connection Service. By default, the value is 2 minutes. It is not possible to extend beyond the limit configured on the server. Use theConnectionTimeout parameter to specify the timeout value. This parameter accepts a numerical value in milliseconds. The following is an example of an HTTP connection with a timeout value of 1 minute:

StreamConnection s = (StreamConnection)Connector.open("http://myserver.com/mypage.html;ConnectionTimeout=60000;deviceside=false");
HttpConnection httpConn = (HttpConnection)s;

 

Note: The ConnectionTimeout parameter is not supported by direct TCP connections or connections through a Wireless Application Protocol (WAP) gateway. Only TCP connections, made through the BlackBerry MDS Connection Service, support this parameter.

[1] http://www.blackberry.com/knowledgecenterpublic/livelink.exe/fetch/2000/348583/800451/800563/How_To_-_Control_the_connection_timeout_for_TCP_connections_through_BlackBerry_Mobile_Data_System_Connection_Service.html?nodeid=1235131&vernum=0


Configure The BlackBerry MDS Simulator Connection via Proxy

sometime you need to redirect the MDS simulator access not directly to the Internet,

the redirection is via HTTP Proxy (for example Squid).

here’s how to configure..

  • Open the rimpublic.property file. The rimpublic.property file can be found in the following locations:For BlackBerry MDS-CS Simulators installed with BlackBerry Java Plug-in for Eclipse

    \Eclipse\plugins\net.rim.ejde.componentpack#.#.#_#.#.#.##\components\MDS\config

    For BlackBerry MDS-CS Simulators installed with BlackBerry JDE

    \Program Files\Research In Motion\BlackBerry JDE #.#.#\MDS\config

    For standalone BlackBerry MDS-CS Simulators

    \Program Files\Research In Motion\BlackBerry Email and MDS Services Simulators #.#.#\MDS\config

  • Under the [HTTP HANDLER] section, update the following:application.handler.http.proxyEnabled = true

    application.handler.http.proxyHost=hostname

    application.handler.http.proxyPort=hostport

  • To include proxy authentication, update the following under the [HTTP HANDLER] section:application.handler.http.proxyUser=username

    application.handler.http.proxyPass=password

  • To include proxy auto configuration parameters, update the following values:application.handler.http.proxyAutoConfig = true

    application.handler.http.proxyAutoConfigURL=http://URL_to_Your_Config_File

    application.handler.http.proxyAutoConfig.ScriptCacheTime=0

    For the last listed parameter, change 0 to the amount of time you want the BlacKBerry MDS-CS Simulator to cache your config file.

  • [1] http://supportforums.blackberry.com/t5/Testing-and-Deployment/Configure-the-BlackBerry-MDS-Simulator-to-work-behind-a-proxy/ta-p/446115


    Streaming Multimedia on BlackBerry

    Summary

     

    This article applies to the following:

    • BlackBerry® Device Software 4.2.1 and later

     

    Details

     

    This article describes how to create a solid streaming media application and how to use the StreamingPlayer class, which is an open-source application programming interface (API) containing classes and methods that support streaming media.

    Basic Streaming Media

    There are two methods that can be used to stream media.

     

    Streaming media over RTSP

    Real Time Streaming Protocol (RTSP) was first implemented in BlackBerry Device Software 4.3 for BlackBerry smartphones that operate on Code Division Multiple Access (CDMA) networks. RTSP is now supported by all BlackBerry smartphones running BlackBerry Device Software 4.5 and later. There are two ways to stream media content over RTSP.

     

    • Using the browser (starts the Media application on the BlackBerry smartphone)String url = "rtsp://mystreamingserver.com/001.aac";Browser.getDefaultSession().displayPage(url);
    • Using the Mobile Media API that is specified in JSR 135 (plays within an application)String url = "rtsp://mystreamingserver.com/001.aac";Player player = Manager.createPlayer(url);player.start();

    Streaming media over HTTP

    Hypertext Transfer Protocol (HTTP) is a protocol that can stream media content and provide real-time playback. Like RTSP, there are two ways to stream media content over HTTP.

     

    • Using the browser (starts the Media application on the BlackBerry smartphone)
      • String url = "http://mystreamingserver.com/001.mp3";
      • Browser.getDefaultSession().displayPage(url);
    • Using the Mobile Media API that is specified in JSR 135 (plays within an application)
      • String url = "http://mystreamingserver.com/001.mp3";
      • Player player = Manager.createPlayer(url);player.start();

    Advantages of streaming media over HTTP

    • API calls are simple to use.
    • This method hides many complex details.

    Limitations of streaming media over HTTP

    • Raw data in the buffer cannot be accessed.
    • The data flow from the buffer to the media player cannot be controlled.
    • There is no seek() support prior to BlackBerry Device Software 5.0.
    • There is no access to the raw data stream.

    Advanced streaming media

    The Mobile Media API (JSR 135) defines advanced APIs that you can use to control media streaming and allow flexibility in development. These APIs can be found in the javax.microedition.media package.

    Components of advanced streaming media

    The following diagram illustrates the different components and classes that are involved in streaming media and the data flow between a remote media source and the media player.

     

    1828i24A9F271819BF829

    Source Media

    The media file that is located on a content server.

     

    Download Thread

    A thread that connects to the source media and downloads the media file to the media buffer.

    Media Buffer

    A circular byte buffer for storing downloaded data until it is sent to media player for playback.

    SourceStream

    An instance of the javax.microedition.media.protocol.SourceStream class. The SourceStream acts as an input stream for the media player by providing methods such as read() and seek().

    DataSource

    An instance of the javax.microedition.media.protocol.DataSource. DataSource class, and performs the following procedure:

    1. Open a connection to the remote source media.
    2. Start the download thread.
    3. Initialize and return SourceStream objects to play.
    4. Close the connection.

    Player

    An instance of javax.microedition.media.Player. The Player object plays media content as the content is downloaded. You can initialize a Playerobject by invoking

    javax.microedition.media.Manager.createPlayer(DataSource source).

     

    Implementation

    The code sample that is included this article shows a complete implementation of all the components and classes that are mentioned. The code sample also includes a StreamingPlayer class and a StreamingPlayerListener interface that you can use as an API or extend to meet special use cases.

    Implementing the DataSource

    DataSource is an abstract class and has six methods. Each of the following methods is invoked by the Player object:

     

    public void connect()

    • Opens connections and input/output (I/O) streams

    public void disconnect()

    • Closes connections, I/O streams, and so on

    public String getContentType()

    • Returns the content type of the source media

    public SourceStream[] getStreams()

    • Returns SourceStream objects

    public void start()

    • Starts the download thread and begins downloading data

    public void stop()

    • Stops downloading data

    Implementing the SourceStream

    public ContentDescriptor getContentDescriptor()

    • Returns a ContentDescriptor object based on the content type of the media

    public long getContentLength()

    • Returns the content length.

    public int getSeekType()

    • Returns RANDOM_ACCESSIBLE
      • Allows the Player to seek to nearby locations from the current position. SourceStream RANDOM_ACCESSIBLE must be set because video files can have audio and video at different offsets for each frame and the BlackBerry Device Software requires both for smooth playback. If -1 is returned by getContentLength(), the seek calls will only be to a previous position in the media file.

    public int read(byte[] b, int off, int len)

    • Sends data to the Player.
    • Blocks or resumes the feed,depending on the status of the buffer

    public long seek(long where)

    • Called by the Player to seek to a point between 0 and the content length
    • Implementation varies based the following connection types:
    • HTTP streaming
      • Uses this method only if seek() is feasible.
      • seek() point is within the buffered data. Otherwise, return the current position.
    • FileConnection streaming
      • Uses this method with mark()reset() and skip()

    public long tell()

    • Returns the current position in the stream

    How to handle user-initiated seek()

    There are two types of user-initiated seek calls. In both cases, Player.setMediaTime(long microseconds) must be invoked, which in turn invokesSourceStream.seek(long position).

    • Seek calls within available data
      • Invoke seek() within the buffer using mark()reset() or skip()
        1829iDBC451CCF5CA4D3D
    • Seek calls beyond the data that is available
      • Block the feed to the Player.
      • Stop downloading data.
      • Close the HTTP connection.
      • Reopen the connection using the HTTP range header to get data from the seek position.
      • Start downloading using the new connection.
      • Resume the feed to the Player when buffer contains enough information.
      1830i3391D28D515A6667

    Stream control

    Because media is streaming over a wireless network, there must be a mechanism to stop data feed to the Player when the buffer runs out of space due to of network delay. There must also be a way to determine how much of the buffer should be filled before restarting or resuming playback. Downloaded data in the buffer must be held as long as possible to allow for backward seek calls made by the Player, but when buffer is full the data must be discarded to download more data. You can use the following variables to control the feed to the Player:

    1. initialBufferDetermines how much data to buffer before playback starts for the first time. This variable can be determined dynamically by the following criteria:
      • Connection type
      • Bit rate
      • Bandwidth and latency
    2. restartThresholdDetermines when to resume the data feed to the Player based on the data that is available in the buffer. This variable can be determined dynamically by the following criteria:
      • Connection type
      • Bit rate
      • Bandwidth and latency
    3. bufferCapacityDetermines the size of the buffer where data is stored. This variable can be determined dynamically by the following criteria:
      • Connection type
      • Bit rate
      • Bandwidth and latency
      • If a buffer is too small, it can frequently run out of space.
      • If a buffer too big, it can waste system resources.
    4. bufferLeakSizeVideo playback requires the Player to seek back from the current position because audio and video data for the same frame are at different offsets. To accommodate this situation, downloaded data is stored until the Player is at the end of the buffer and the buffer is full. This method requires that more data must be downloaded for the playback to continue. In this situation, the oldest data is discarded first to create space for downloading more data.bufferLeakSize determines how much data is discarded each time this occurs.

    Creating a Player from a DataSource

    To create a Player from a DataSource, use the following code:

    Player player = Manager.createPlayer(new MyDataSource());player.start();

     

    Using the right transport method

    Wi-Fi® technology is the preferred transport because it is fast and free. If a Wi-Fi connection becomes available during a streaming session, it is recommended that the Player dynamically switch to the Wi-Fi connection after prompting the BlackBerry smartphone user to do so. If a Wi-Fi connection is not available, transport methods that are used by wireless service providers, such as Wireless Application Protocol (WAP/WAP2) or Transmission Control Protocol (TCP), are recommended. Using the BlackBerry® Mobile Data System (BlackBerry MDS) or the BlackBerry® Internet Service is not recommended because media streaming results in large data usage through these transport methods. Both the BlackBerry MDS and BlackBerry Internet Service also result in added latency because the data travels through the BlackBerry® Infrastructure.

    Downloads

    A complete implementation of a streaming media application is available to download. This example application uses the StreamingPlayer class andStreamingPlayerListener class as libraries, and can be used in your application to stream media over HTTP. This application will only play the media files that are supported by the target BlackBerry smartphone. Make sure that you type the web page and content type of your media file on the Options screen of the application before pressing play.

     

    Note: The API needs an implementation of a thread safe Circular Byte Buffer. You can copy the implementation as CircularByteBuffer.java to rimx.media.streaming package and then complile the project. For an example, click here.

     

    1831i1650ADCE11412CDA
     

    Refer to attachment section below to download the example application, including the libraries.

     

     

    [1] http://supportforums.blackberry.com/t5/Java-Development/Streaming-media-Start-to-finish/ta-p/488255

    streamingplayersampleapp__download_pdf_renameto_zip


    Check The Network Coverage on BlackBerry

    Here’s the code from the BlackBerry PUSH API about the how to check the Network Coverage on the BlackBerry:

    public static boolean hasCoverage() {
           boolean bisCoverage = CoverageInfo.isCoverageSufficient( CoverageInfo.COVERAGE_BIS_B );
           boolean carrierCoverage = false;
           carrierCoverage = CoverageInfo.isCoverageSufficient( CoverageInfo.COVERAGE_DIRECT );
           return bisCoverage || carrierCoverage;
    }

    [1] http://us.blackberry.com/developers/platform/pushapi.jsp


    Download large files using the BlackBerry Mobile Data System

    Background

    The size of files that can be downloaded to the BlackBerry smartphone using the BlackBerry® Mobile Data System (BlackBerry MDS) is limited due to storage availability on the BlackBerry smartphone and the cost of transferring data wirelessly. The BlackBerry MDS uses the Multipurpose Internet Mail Extensions (MIME) type reported by the web server to determine which file limit should be applied. This file limit may also include any additional overhead from the web server, and will apply both before and after transcoding is done by the BlackBerry MDS. BlackBerry MDS provides a response code of 413 if the file size is too big. For standard Hypertext Transfer Protocol (HTTP) file downloading, as is done in the following example, there is no additional overhead or transcoding. For more information on BlackBerry MDS file settings and response code 413, see DB-00623.

    HTTP Range request header

    If it is supported by the server, the Range header can be used to make individual requests for parts of a file. By keeping these file range requests below the limit of an individual file, larger files can be downloaded in parts and recombined on the BlackBerry smartphone. The file does not have to be separated into chunks on the server using this approach. The following example uses the Range header to request a file in several parts.

    Note: The use of response code 206 for partial content and downloading the file correctly is based entirely on calculating the correct byte range to request. The same approach could be used to resume downloading interrupted transfers.

    private class DownloadCombiner extends Thread {
        private String remoteName;
        private String localName;
        private int connection;
        private int chunksize;
        public DownloadCombiner(String remoteName,
            String localName, int connection, int chunksize) {
            this.remoteName = remoteName;
            this.localName = localName;
            this.connection = connection;
            this.chunksize = chunksize;
        }
        public void run() {
            try {
                int chunkIndex = 0;
                int totalSize = 0;
    
                /*
                 * File connection
                 */
                FileConnection file =(FileConnection)Connector.open(localName);
                if (!file.exists()) {
                    file.create();
                file.setWritable(true);
                OutputStream out = file.openOutputStream();
    
                /*
                 * HTTP Connections
                 */
                String currentFile = remoteName + connectionType();
                log("Full URL: " + currentFile);
                HttpConnection conn;
                InputStream in;
                int rangeStart = 0;
                int rangeEnd = 0;
                while (true) {
                    log("Opening Chunk: " + chunkIndex);
                    conn = (HttpConnection) Connector.open(currentFile,
                            Connector.READ_WRITE, true);
                    rangeStart = chunkIndex * chunksize;
                    rangeEnd = rangeStart + chunksize - 1;
                    log("Requesting Range: " + rangeStart +
                         "-" + rangeEnd);
                    conn.setRequestProperty("Range", "bytes=" +
                         rangeStart + "-" + rangeEnd);
                    int responseCode = conn.getResponseCode();
                    if (responseCode != 200 && responseCode != 206)
                    {
                        log("Response Code = " + conn.getResponseCode());
                        break;
                    }
                    log("Retreived Range: " + conn.getHeaderField("Content-Range"));
                    in = conn.openInputStream();
                    int length = -1;
                    byte[] readBlock = new byte[256];
                    int fileSize = 0;
                    while ((length = in.read(readBlock)) != -1) {
                        out.write(readBlock, 0, length);
                        fileSize += length;
                        Thread.yield(); // Try not to get cut off
                    }
                    totalSize += fileSize;
                    log("Chunk Downloaded: " + fileSize + " Bytes");
                    chunkIndex++; // index (range) increase
                    in.close();
                    conn.close();
                    in = null;
                    conn = null;
                    /*
                     * Pause to allow connections to close and other Threads
                     * to run.
                     */
                     Thread.sleep(1000);
                }
                log("Full file downloaded: " + totalSize + " Bytes");
                out.close();
                file.close();
                log("Wrote file to local storage");
                } catch (Exception e) {
                     log(e.toString());
                }
            }
        private String connectionType() {
            switch (connection) {
                case 1:
                    return ";deviceside=false";
                case 2:
                    return ";deviceside=true;interface=wifi";
                default:
                    return ";deviceside=true";
            }
        }
    }

    File splitting

    A large file can be downloaded to the BlackBerry smartphone by splitting the file into multiple parts and then downloading each part to the microSD card, where the parts can be recombined into the original file.

    The following code segment describes a scheme for splitting a file into defined part sizes. The file parts are labeled with the original filename and a part ID.

    public void splitFile() throws Exception {
        BufferedInputStream input = new BufferedInputStream(new FileInputStream(_file));
        byte[] readBlock = new byte[_chunksize];
        int chunkFileId = 0;
        int length = -1;
        while ((length = input.read(readBlock)) != -1) {
            String chunkFileName = _file.getName() + "." + chunkFileId++;
            BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(chunkFileName));
            output.write(readBlock, 0, length);
            output.flush();
            output.close();
            System.out.println("Wrote Chunk file " + chunkFileName + " of " + length + " Bytes");
        }
        System.out.println("Completed Splitting " + _file.getName());
    }

    File downloading

    Once the file has been split into a series of parts, each part can be downloaded in order and written out to one file on the microSD card.

    Note: The response code is used to determine whether the part exists. If the part does not exist, the downloading process is completed.

    private class DownloadCombiner extends Thread {
    
        private String remoteName;
        private String localName;
        private int connection;
    
        public DownloadCombiner(String remoteName, String localName) {
            this.remoteName = remoteName;
            this.localName = localName;
        }
    
        public void run() {
            try {
                int chunkIndex = 0;
                int totalSize = 0;
                FileConnection file = (FileConnection) Connector.open(localName);
                if (!file.exists()) {
                     file.create();
                }
                file.setWritable(true);
                OutputStream out = file.openOutputStream();
                HttpConnection conn;
                InputStream in;
                while (true) {
                     System.out.println("Opening Chunk: " + chunkIndex);
                     String currentFile = remoteName + "." + chunkIndex++;
                     conn = (HttpConnection) Connector.open(currentFile);
                     if (conn.getResponseCode() != 200) {
                         System.out.println("Response Code = " +
                                             conn.getResponseCode());
                         break;
                     }
                     in = conn.openInputStream();
                     int length = -1;
                     byte[] readBlock = new byte[256];
                     int fileSize = 0;
                     while ((length = in.read(readBlock)) != -1) {
                         out.write(readBlock, 0, length);
                         fileSize += length;
                     }
                     totalSize += fileSize;
                     System.out.println("Chunk Downloaded: " + fileSize + " Bytes");
                     in.close();
                     conn.close();
                     in = null;
                     conn = null;
                     Thread.yield(); // allow other threads time
                }
                System.out.println("Full file downloaded: " + totalSize + " Bytes");
                out.close();
                file.close();
                System.out.println("Wrote file to local storage");
            } catch (Exception e) {
                System.err.println(e.toString());
              }
        }
    }
    

    [1] http://www.blackberry.com/knowledgecenterpublic/livelink.exe/fetch/2000/348583/800332/800431/How_To_-_Download_large_files_using_the_BlackBerry_Mobile_Data_System.html?nodeid=1371855&vernum=0


    Process incoming data (queue overflow)

    When you develop applications for the BlackBerry smartphone, any network communication or lengthy data processing should be performed in its own thread. This is easy to realize for network input/output (I/O) because network connections must be initiated in their own thread, otherwise a deadlock situation may occur.[1]

    When an application performs lengthy processing on the main event thread, the BlackBerry smartphone user can perceive the application to be slow because it is unable to process input commands. In an extreme situation, the application can close if it blocks or ties up the main event thread. If an application ties up the main event thread, the system is unable to dispatch messages to it (for example, BlackBerry smartphone user input, UI updates or network I/O). If the application message queue exceeds its limit, the application is terminated with the one of the following errors[2]:

    Process [application name] killed due to message queue overflow

    or

    Uncaught Exception: [ApplicationName] is not responding; process terminated

    Cause
    An application is blocking the main event thread.

    The main event thread processes system messages. Blocking this thread prevents system messages from being processed and can lead to a message queue overflow.

    Because there is a finite amount of storage space for messages, the issue is caused when these messages are not being processed. If an application stops processing messages for a long period of time, the system assumes that the application has stopped responding and is no longer functioning as expected. This is the reason why the process was terminated.

    Resolution
    Move long processes or processes that block to a separate background thread.

    Application stops responding when opening a connection[3]

    Flow of what is occurring

    • Application opens connection
    • UI pushing dialog box to the foreground
    • BlackBerry is now locked

    Flow of what should occur

    • Application places a connection into a thread
    • Application runs the connection in a thread off of the main event thread
    • UI pushes dialog box to the foreground and thread execution is currently paused
    • User is notified of connection and accepts
    • System returns execution to the connection thread

    [1] http://www.blackberry.com/knowledgecenterpublic/livelink.exe/fetch/2000/348583/800451/800563/How_To_-_Process_incoming_data.html?nodeid=1162112&vernum=0
    [2] http://www.blackberry.com/knowledgecenterpublic/livelink.exe/fetch/2000/348583/800451/800783/Support_-_Process_[ApplicationName]_killed_due_to_message_queue_overflow.html?nodeid=826932&vernum=0
    [3] http://www.blackberry.com/knowledgecenterpublic/livelink.exe/fetch/2000/348583/796557/800451/800563/Support_-_My_Application_Hangs_When_Opening_a_Connection.html?nodeid=800455


    Open a push listener connection

    The BlackBerry Mobile Data Service is capable of pushing data to a third-party application so that data is always available to the user. There are two common scenarios in which a push connection would be opened[1]:

    • when an application runs
    • when the device starts and runs in the background
    //run method from with a thread
    public void run() {
         //For Background Listener threads it is import to add the delay
         //If the application starts and displays the “Allow Connection” dialogue
         //Before the home screen is available it’s possible to cause a UI lock
         while(RadioInfo.getSignalLevel()==RadioInfor.LEVEL_NO_COVERAGE)(
              try {
                   Thread sleep(1000);
              } catch( Exception e ) {}
         }
         //Just add an extra wait to ensure the device is fully up and running
         //the user is looking at the home screen
         try {
              Thread sleep(3000);
         } catch( Exception e ) {}
    
         StreamConnection stream = null;
         InputStream input = null;
    
         try {
              for(;;){
                   try {
                        Thread.sleep(1000);
                        System.out.printIn(‘eclBackgroundThread--ThreadRunning (just to be sure)”);
                   } catch( Exception e ) {}
              synchronized(this) {
                   //synchronize here so that we don’t end up creating a connection that is never closed
                   //The URL will be http://: where  is the value that the push server also                needs
                   //to use to post data
                   _notify = (StreamConnectionNotifier)Connector open(URL);
                   _connectionOpened = true;
              }
    
              //NOTE: the following will block until data is received
              stream = _notify acceptAndOpen();
              input = stream.openInputStream();
    
              //Read the received data in from the stream and process it accordingly
         } catch (IOException ioex) {}
    }
    
    
    
    

    [1] http://www.blackberry.com/knowledgecenterpublic/livelink.exe/fetch/2000/348583/796557/800451/800662/How_To_-_Open_a_push_listener_connection.html?nodeid=1033505&vernum=0


  • Copyright © 1996-2010 vaks.in. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress