javaextensions/datagram/datagram/javasrc/com/nokia/mj/impl/datagram/UDPDatagramConnectionImpl.java
branchRCL_3
changeset 14 04becd199f91
child 23 e5618cc85d74
equal deleted inserted replaced
13:f5050f1da672 14:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 package com.nokia.mj.impl.datagram;
       
    20 
       
    21 import java.io.*;
       
    22 import javax.microedition.io.*;
       
    23 import com.nokia.mj.impl.gcf.utils.UrlParser;
       
    24 import com.nokia.mj.impl.utils.Logger;
       
    25 import com.nokia.mj.impl.rt.support.Finalizer;
       
    26 import com.nokia.mj.impl.rt.support.ApplicationUtils;
       
    27 import com.nokia.mj.impl.rt.support.ShutdownListener;
       
    28 import com.nokia.mj.impl.gcf.protocol.datagram.DatagramPermissionImpl;
       
    29 import com.nokia.mj.impl.connectionmanager.ConnectionManager;
       
    30 import com.nokia.mj.impl.connectionmanager.AccessPoint;
       
    31 import com.nokia.mj.impl.rt.support.ApplicationInfo;
       
    32 import com.nokia.mj.impl.utils.Uid;
       
    33 
       
    34 /**
       
    35  * UDP DatagramConnection Implementation class.
       
    36  *
       
    37  */
       
    38 
       
    39 public class UDPDatagramConnectionImpl implements UDPDatagramConnection
       
    40 {
       
    41     private int iNativePeerHandle;
       
    42     private UrlParser iUri;
       
    43     private boolean iConnectionOpen = true;
       
    44     private Finalizer iFinalizer;
       
    45     private static final String DATAGRAM_PROTOCOL = "datagram";
       
    46     private static final int MAX_DATAGRAM_SIZE = 65535;
       
    47     private static final int NOMINAL_DATAGRAM_SIZE = 256;
       
    48     private ConnectionManager iCmInstance = null;
       
    49     private AccessPoint iApn = null;
       
    50     private String iFullUrl = null;
       
    51 
       
    52     /**
       
    53      * Constructs the UDPDatagramConnectionImpl.
       
    54      *
       
    55      * @param aUri the uri to which udp connection is opened
       
    56      * @param aMode the with which udp datagram connection is opened
       
    57      * @param aTimeout the with period for the connection
       
    58      * @throws IOException in case of any IO errors
       
    59      */
       
    60 
       
    61     public UDPDatagramConnectionImpl(String aUri, int aMode, boolean aTimeout)
       
    62     throws IOException
       
    63     {
       
    64 
       
    65         Logger.LOG(Logger.ESOCKET,Logger.EInfo," +UDPDatagramConnectionImpl(): aUri = " + aUri);
       
    66         int retVal = 0;
       
    67 
       
    68         int retval[] = new int[1];
       
    69 
       
    70         String apnstring = null;
       
    71         String urls = null;
       
    72         int apnid = -1;
       
    73         int index = -1;
       
    74         iFullUrl = "datagram:"+aUri;
       
    75 
       
    76         index = aUri.indexOf(";nokia_netid=");
       
    77         if (index != -1)
       
    78         {
       
    79             apnstring = aUri.substring(index);
       
    80             int equalindex = apnstring.indexOf('=');
       
    81             if (equalindex != -1)
       
    82             {
       
    83                 String temp = apnstring.substring(equalindex+1);
       
    84                 try
       
    85                 {
       
    86                     apnid = Integer.parseInt(temp);
       
    87                 }
       
    88                 catch (NumberFormatException e)
       
    89                 {
       
    90                     throw new IllegalArgumentException("Invalid URL: "+iFullUrl);
       
    91                 }
       
    92             }
       
    93             else
       
    94             {
       
    95                 throw new IllegalArgumentException("Invalid URL: "+iFullUrl);
       
    96             }
       
    97             urls = aUri.substring(0, index);
       
    98         }
       
    99         else
       
   100         {
       
   101             index = aUri.indexOf(";nokia_apnid=");
       
   102             if (index != -1)
       
   103             {
       
   104                 apnstring = aUri.substring(index);
       
   105                 int equalindex = apnstring.indexOf('=');
       
   106                 if (equalindex != -1)
       
   107                 {
       
   108                     String temp = apnstring.substring(equalindex+1);
       
   109                     try
       
   110                     {
       
   111                         apnid = Integer.parseInt(temp);
       
   112                     }
       
   113                     catch (NumberFormatException e)
       
   114                     {
       
   115                         throw new IllegalArgumentException("Invalid URL: "+iFullUrl);
       
   116                     }
       
   117                 }
       
   118                 else
       
   119                 {
       
   120                     throw new IllegalArgumentException("Invalid URL: "+iFullUrl);
       
   121                 }
       
   122                 urls = aUri.substring(0, index);
       
   123             }
       
   124             else
       
   125             {
       
   126                 urls = aUri;
       
   127             }
       
   128         }
       
   129         Logger.LOG(Logger.ESOCKET, Logger.EInfo,"UDPDatagramConnectionImpl -after removing nokia_apnid : "+urls);
       
   130 
       
   131         if (urls.equals("//:"))
       
   132         {
       
   133             String temp = "datagram:"+urls;
       
   134 
       
   135             /* security related stuff */
       
   136             ApplicationUtils appUtils = ApplicationUtils.getInstance();
       
   137             DatagramPermissionImpl per = new DatagramPermissionImpl("datagram://");
       
   138             Logger.LOG(Logger.ESOCKET, Logger.EInfo,
       
   139                        "calling check permissions from UDPDatagramConnectionImpl");
       
   140             appUtils.checkPermission(per);
       
   141             /* security related stuff */
       
   142 
       
   143             iNativePeerHandle =  _createNativePeer(temp,aMode,"",0);
       
   144         }
       
   145         else
       
   146         {
       
   147             iUri = new UrlParser(DATAGRAM_PROTOCOL, urls);
       
   148 
       
   149             if (iUri.port == -1)
       
   150             {
       
   151                 /* client connecction should have a port number */
       
   152                 throw new IllegalArgumentException("Invalid URL: "+iFullUrl);
       
   153             }
       
   154             /* check for restricted ports */
       
   155             Logger.LOG(Logger.ESOCKET, Logger.EInfo,
       
   156                        "port = "+iUri.port);
       
   157 
       
   158             if (iUri.getPort() == 9200 || iUri.getPort() == 9201 || iUri.getPort() == 9202 || iUri.getPort() == 9203)
       
   159             {
       
   160                 if (ApplicationInfo.getInstance().getRuntimeType().equals(ApplicationInfo.RUNTIME_MIDP) == true)
       
   161                 {
       
   162                     if ((ApplicationInfo.getInstance().getProtectionDomain().equals(ApplicationInfo.UNIDENTIFIED_THIRD_PARTY_DOMAIN)) == true)
       
   163                     {
       
   164                         Logger.LOG(Logger.ESOCKET, Logger.EInfo,"Throwing security exception for restricted port");
       
   165                         throw new SecurityException("Unable to open datagram connection: port " +iUri.getPort()+ " is restricted");
       
   166                     }
       
   167                 }
       
   168             }
       
   169 
       
   170             if (iUri.host == null)
       
   171             {
       
   172                 /* security related stuff, server mode datagram connection */
       
   173                 ApplicationUtils appUtils = ApplicationUtils.getInstance();
       
   174                 DatagramPermissionImpl per = new DatagramPermissionImpl("datagram://");
       
   175                 Logger.LOG(Logger.ESOCKET, Logger.EInfo,
       
   176                            "calling check permissions from UDPDatagramConnectionImpl");
       
   177                 appUtils.checkPermission(per);
       
   178                 /* security related stuff */
       
   179 
       
   180                 iNativePeerHandle =  _createNativePeer(iUri.toString(),aMode,"",iUri.port);
       
   181             }
       
   182             else
       
   183             {
       
   184                 /* security related stuff, client mode datagram connection */
       
   185                 ApplicationUtils appUtils = ApplicationUtils.getInstance();
       
   186                 DatagramPermissionImpl per = new DatagramPermissionImpl("datagram://*");
       
   187                 Logger.LOG(Logger.ESOCKET, Logger.EInfo,
       
   188                            "calling check permissions from UDPDatagramConnectionImpl");
       
   189                 appUtils.checkPermission(per);
       
   190                 /* security related stuff */
       
   191 
       
   192                 iNativePeerHandle =  _createNativePeer(iUri.toString(),aMode,iUri.host,iUri.port);
       
   193             }
       
   194         }
       
   195         if (iNativePeerHandle == 0)
       
   196         {
       
   197             throw new IOException("Unable to open datagram connection.Creating native peer failed");
       
   198         }
       
   199 
       
   200         // remove comments if open c patch available
       
   201         iCmInstance = ConnectionManager.getInstance();
       
   202         Logger.LOG(Logger.ESOCKET, Logger.EInfo,"after getting ConnectionManager instance");
       
   203         // get application suite uid
       
   204         try
       
   205         {
       
   206             Uid appSuite = ApplicationInfo.getInstance().getSuiteUid();
       
   207             try
       
   208             {
       
   209                 // remove comments if open c patch available
       
   210                 iApn = iCmInstance.getNetworkAccessPoint(appSuite, aUri);
       
   211                 Logger.LOG(Logger.ESOCKET, Logger.EInfo,"iApn.getType = "+iApn.getType()+ " iApn.getNapId= "+iApn.getNapId());
       
   212             }
       
   213             catch (Exception e)
       
   214             {
       
   215                 Logger.LOG(Logger.ESOCKET, Logger.EInfo,"getNetworkAccessPoint threw Exception");
       
   216             }
       
   217 
       
   218         }
       
   219         catch (Exception e)
       
   220         {
       
   221             Logger.LOG(Logger.ESOCKET, Logger.EInfo,"getSuiteUid exception ");
       
   222         }
       
   223 
       
   224         if (iApn != null)
       
   225         {
       
   226             retVal = _openConnection(iNativePeerHandle,iApn.getType(),iApn.getNapId(), retval);
       
   227         }
       
   228         else
       
   229         {
       
   230             retVal = _openConnection(iNativePeerHandle, -1, -1, retval);
       
   231         }
       
   232         Logger.LOG(Logger.ESOCKET, Logger.EInfo,
       
   233                    "UDPDatagramConnectionImpl::UDPDatagramConnectionImpl(): _openConnection return value "
       
   234                    + retVal);
       
   235         if (iCmInstance != null)
       
   236         {
       
   237             if (retval[0] < 0)
       
   238             {
       
   239                 //reset connection manager
       
   240                 iCmInstance.reset();
       
   241             }
       
   242         }
       
   243 
       
   244         if (retVal < 0)
       
   245         {
       
   246             throw new IOException("Unable to open datagram connection. POSIX error code: "+retVal);
       
   247         }
       
   248 
       
   249         iFinalizer = registerforFinalization();
       
   250 
       
   251         setShutdownListener();
       
   252         Logger.LOG(Logger.ESOCKET,Logger.EInfo," --UDPDatagramConnectionImpl()");
       
   253     }
       
   254 
       
   255     /**
       
   256      * Registers for shutdown listener
       
   257      */
       
   258     private void setShutdownListener()
       
   259     {
       
   260         // Get the instance of ApplicationUtils.
       
   261         ApplicationUtils appUtils = ApplicationUtils.getInstance();
       
   262 
       
   263         // Get the name of the application.
       
   264         appUtils.addShutdownListener(new ShutdownListener()
       
   265         {
       
   266             public void shuttingDown()
       
   267             {
       
   268                 try
       
   269                 {
       
   270                     close();// Do cleaning...
       
   271                 }
       
   272                 catch (IOException ex)
       
   273                 {
       
   274                     // catch the exception and call dispose
       
   275                 }
       
   276                 if (iNativePeerHandle != 0)
       
   277                 {
       
   278                     _dispose(iNativePeerHandle);
       
   279                     iNativePeerHandle = 0;
       
   280                 }
       
   281             }
       
   282 
       
   283         });
       
   284     }
       
   285     /**
       
   286      * Get the local socket address of this UDPDatagram connection.
       
   287      *
       
   288      * @return the local address
       
   289      * @throws IOException in case of any IO errors
       
   290      */
       
   291 
       
   292     public String getLocalAddress() throws IOException
       
   293     {
       
   294         String[] address = new String[1];
       
   295         int retVal;
       
   296         if (!iConnectionOpen)
       
   297         {
       
   298             throw new IOException("getLocalAddress failed: connection is already closed");
       
   299         }
       
   300         retVal = _getLocalAddress(iNativePeerHandle, address);
       
   301         if (retVal < 0)
       
   302         {
       
   303             throw new IOException("getLocalAddress method failed.Posix error code: " + retVal);
       
   304         }
       
   305         else
       
   306         {
       
   307             return address[0];
       
   308         }
       
   309     }
       
   310 
       
   311     /**
       
   312      * Get the local port of this UDPDatagram connection.
       
   313      *
       
   314      * @return the local port
       
   315      * @throws IOException in case of any IO errors
       
   316      */
       
   317 
       
   318     public int getLocalPort() throws IOException
       
   319     {
       
   320         int retVal;
       
   321         if (!iConnectionOpen)
       
   322         {
       
   323             throw new IOException("getLocalPort failed: connection is already closed");
       
   324         }
       
   325         retVal = _getLocalPort(iNativePeerHandle);
       
   326         if (retVal < 0)
       
   327         {
       
   328             throw new IOException("getLocalPort method failed.Posix error code: " + retVal);
       
   329         }
       
   330         else
       
   331         {
       
   332             return retVal;
       
   333         }
       
   334     }
       
   335 
       
   336     /**
       
   337      * Close the secure connection.
       
   338      *
       
   339      * @throws IOException in case of any IO errors
       
   340      */
       
   341 
       
   342     public synchronized void close() throws IOException
       
   343     {
       
   344         Logger.LOG(Logger.ESOCKET, Logger.EInfo,
       
   345                    "+UDPDatagramConnectionImpl::Close()");
       
   346         if (iConnectionOpen == true)
       
   347         {
       
   348             iConnectionOpen = false;
       
   349             int ret = _close(iNativePeerHandle);
       
   350             if (ret != 0)
       
   351             {
       
   352                 if (ret == -4)
       
   353                 {
       
   354                     // if recieve is blocked when close is called
       
   355                     throw new InterruptedIOException();
       
   356                 }
       
   357                 else
       
   358                 {
       
   359                     throw new IOException("close method failed.Posix error code: " + ret);
       
   360                 }
       
   361             }
       
   362         }
       
   363         Logger.LOG(Logger.ESOCKET, Logger.EInfo,
       
   364                    "-UDPDatagramConnectionImpl::Close()");
       
   365     }
       
   366 
       
   367     /**
       
   368      * Please refer JSR 118.
       
   369      */
       
   370 
       
   371     public int getMaximumLength() throws IOException
       
   372     {
       
   373         if (!iConnectionOpen)
       
   374         {
       
   375             throw new IOException("getMaximumLength failed: connection is already closed");
       
   376         }
       
   377         return MAX_DATAGRAM_SIZE;
       
   378     }
       
   379 
       
   380     /**
       
   381      * Please refer JSR 118.
       
   382      */
       
   383 
       
   384     public int getNominalLength() throws IOException
       
   385     {
       
   386         if (!iConnectionOpen)
       
   387         {
       
   388             throw new IOException("getNominalLength failed: connection is already closed");
       
   389         }
       
   390         return NOMINAL_DATAGRAM_SIZE;
       
   391     }
       
   392 
       
   393     /**
       
   394      * Please refer JSR 118.
       
   395      */
       
   396 
       
   397     public void send(Datagram aDgram) throws IOException
       
   398     {
       
   399 
       
   400         int retVal;
       
   401         if (!iConnectionOpen)
       
   402         {
       
   403             throw new IOException("send failed: connection is already closed");
       
   404         }
       
   405         String addr = aDgram.getAddress();
       
   406         UrlParser url1;
       
   407         if (addr == null)
       
   408         {
       
   409             url1 = iUri; // address from the connector.open uri
       
   410         }
       
   411         else
       
   412         {
       
   413             url1 = new UrlParser(addr);
       
   414 
       
   415             if (url1.getPort() == 9200 || url1.getPort() == 9201 || url1.getPort() == 9202 || url1.getPort() == 9203)
       
   416             {
       
   417                 if ((ApplicationInfo.getInstance().getProtectionDomain().equals(ApplicationInfo.UNIDENTIFIED_THIRD_PARTY_DOMAIN)) == true)
       
   418                 {
       
   419                     Logger.LOG(Logger.ESOCKET, Logger.EInfo,"Throwing secuirty exception for restricted port");
       
   420                     throw new SecurityException("Unable to open datagram connection: port " +url1.getPort()+ " is restricted");
       
   421                 }
       
   422             }
       
   423         }
       
   424 
       
   425         retVal = _send(iNativePeerHandle, aDgram.getData(), aDgram
       
   426                        .getOffset(), aDgram.getLength(), url1.host, url1.port);
       
   427 
       
   428         if (retVal < 0)
       
   429         {
       
   430             throw new IOException("send method failed.Posix error code: " + retVal);
       
   431         }
       
   432 
       
   433     }
       
   434 
       
   435     /**
       
   436      * Please refer JSR 118.
       
   437      */
       
   438 
       
   439     public void receive(Datagram aDgram) throws IOException
       
   440     {
       
   441         String addr = new String("  ");
       
   442         String[] senderAddr = new String[1];
       
   443         int[] senderPort = new int[1];
       
   444         int port = 0;
       
   445         int retVal;
       
   446 
       
   447         if (!iConnectionOpen)
       
   448         {
       
   449             throw new IOException("receive failed: connection is already closed");
       
   450         }
       
   451 
       
   452 
       
   453         retVal = _receive(iNativePeerHandle, aDgram.getData(), aDgram
       
   454                           .getOffset(), aDgram.getLength(), senderAddr, senderPort);
       
   455 
       
   456         Logger.LOG(Logger.ESOCKET, Logger.EInfo,
       
   457                    "UDPDatagramConnectionImpl.java recieve returned : "+retVal);
       
   458         if (retVal < 0)
       
   459         {
       
   460             throw new IOException("receive method failed.Posix error code: " + retVal);
       
   461         }
       
   462         Logger.LOG(Logger.ESOCKET, Logger.EInfo, "addr = "
       
   463                    + senderAddr[0] + "port = " + senderPort[0]
       
   464                    + "recieve retval = " + retVal);
       
   465         StringBuffer recvurl = new StringBuffer();
       
   466         recvurl.append(DATAGRAM_PROTOCOL + "://");
       
   467         recvurl.append(senderAddr[0]);
       
   468         recvurl.append(":");
       
   469 
       
   470         recvurl.append(senderPort[0]);
       
   471         Logger.LOG(Logger.ESOCKET, Logger.EInfo, "recvurl = " + recvurl);
       
   472         aDgram.setAddress(recvurl.toString());
       
   473         aDgram.setLength(retVal);
       
   474 
       
   475     }
       
   476 
       
   477     /**
       
   478      * Please refer JSR 118.
       
   479      */
       
   480 
       
   481     public Datagram newDatagram(int aSize) throws IOException
       
   482     {
       
   483         return newDatagram(aSize, null);
       
   484     }
       
   485 
       
   486     /**
       
   487      * Please refer JSR 118.
       
   488      */
       
   489     public Datagram newDatagram(int aSize, String aAddr) throws IOException
       
   490     {
       
   491         if (aSize < 0)
       
   492         {
       
   493             throw new IllegalArgumentException("Invalid argument in newDatagram method");
       
   494         }
       
   495         byte[] buf = new byte[aSize];
       
   496         return newDatagram(buf, aSize, aAddr);
       
   497     }
       
   498 
       
   499     /**
       
   500      * Please refer JSR 118.
       
   501      */
       
   502 
       
   503     public Datagram newDatagram(byte[] aBuf, int aSize) throws IOException
       
   504     {
       
   505         return newDatagram(aBuf, aSize, null);
       
   506     }
       
   507 
       
   508     /**
       
   509      * Please refer JSR 118.
       
   510      */
       
   511 
       
   512     public Datagram newDatagram(byte[] aBuf, int aSize, String aAddr)
       
   513     throws IOException
       
   514     {
       
   515 
       
   516         if (!iConnectionOpen)
       
   517         {
       
   518             throw new IOException("newDatagram failed: connection is already closed");
       
   519         }
       
   520         if (aBuf == null)
       
   521         {
       
   522             throw new IllegalArgumentException("Invalid argument in newDatagram method");
       
   523         }
       
   524         if (aAddr != null)
       
   525         {
       
   526             UrlParser urlvalidation = new UrlParser(aAddr);
       
   527         }
       
   528         DatagramImpl t = new DatagramImpl(aBuf, aSize, aAddr);
       
   529         return t;
       
   530     }
       
   531 
       
   532     Finalizer registerforFinalization()
       
   533     {
       
   534         Logger.LOG(Logger.ESOCKET, Logger.EInfo,
       
   535                    "creating a datagram finalizer object ");
       
   536         return new Finalizer()
       
   537         {
       
   538             public void finalizeImpl()
       
   539             {
       
   540                 doFinalize();
       
   541             }
       
   542         };
       
   543     }
       
   544 
       
   545     public void doFinalize()
       
   546     {
       
   547         Logger.LOG(Logger.ESOCKET, Logger.EInfo,
       
   548                    "datagram doFinalize() called :");
       
   549         if (iConnectionOpen == true)
       
   550         {
       
   551             try
       
   552             {
       
   553                 close();
       
   554             }
       
   555             catch (IOException e)
       
   556             {
       
   557                 // catch the exception and call dispose
       
   558             }
       
   559         }
       
   560         if (iNativePeerHandle != 0)
       
   561         {
       
   562             _dispose(iNativePeerHandle);
       
   563             iNativePeerHandle = 0;
       
   564         }
       
   565     }
       
   566     // Native calls
       
   567     private native int _createNativePeer(String aUri, int aMode, String host,
       
   568                                          int port);
       
   569     private native int _openConnection(int iNativePeerHandle, int aType, int aApn, int[] retval);
       
   570     private native int _send(int iNativePeerHandle, byte[] buf, int offset,
       
   571                              int length, String host, int port);
       
   572     private native int _receive(int iNativePeerHandle, byte[] buf, int offset,
       
   573                                 int length, String[] senderAddr, int[] senderPort);
       
   574     private native int _getLocalAddress(int iNativePeerHandle, String[] address);
       
   575     private native int _getLocalPort(int iNativePeerHandle);
       
   576     private native int _close(int iNativePeerHandle);
       
   577     private native void _dispose(int iNativePeerHandle);
       
   578 
       
   579 }