javaextensions/datagram/datagram/src/nativedatagramconnection.cpp
changeset 21 2a9601315dfc
child 48 e0d6e9bd3ca7
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     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 #include <stdio.h>
       
    20 #include <errno.h>
       
    21 #include <sys/stat.h>
       
    22 #include <sys/types.h>
       
    23 #include <sys/socket.h>
       
    24 #include <netinet/in.h>
       
    25 #include <netdb.h>
       
    26 #include <fcntl.h>
       
    27 #include <unistd.h>
       
    28 #include <string.h>
       
    29 #include <time.h>
       
    30 #include <stdlib.h>
       
    31 #include <arpa/inet.h>
       
    32 
       
    33 #include "logger.h"
       
    34 #include "nativedatagramconnection.h"
       
    35 #include "javacommonutils.h"
       
    36 #include "apnsettings.h"
       
    37 #include "pushexception.h"
       
    38 #include "pusherrorcodes.h"
       
    39 
       
    40 
       
    41 using namespace java;
       
    42 using namespace java::util;
       
    43 
       
    44 NativeDatagramConnection::NativeDatagramConnection(const char *aName,
       
    45         int aMode, const char* aHost, int aPort)
       
    46 {
       
    47     ILOG1(ESOCKET,
       
    48           "NativeDatagramConnection::NativeDatagramConnection() , host = %s",
       
    49           aHost);
       
    50     mName = NULL;
       
    51     mHost = NULL;
       
    52     mDatagramServerFactory = NULL;
       
    53     mDatagramServerPtr = NULL;
       
    54     mName = new char[strlen(aName) + 1];
       
    55     strcpy(mName, aName);
       
    56     LOG1(ESOCKET, EInfo," name = %s",aName);
       
    57     mMode = aMode;
       
    58     LOG1(ESOCKET, EInfo, "before   , aHost + %s", aHost);
       
    59     mHost = new char[strlen(aHost) + 1];
       
    60     strcpy(mHost, aHost);
       
    61     LOG2(ESOCKET, EInfo, "after  mHost = %s , aHost + %s", mHost, aHost);
       
    62     mPort = aPort;
       
    63 }
       
    64 
       
    65 int NativeDatagramConnection::openConnection(int aType, int aApn, int * err)
       
    66 {
       
    67     JELOG2(ESOCKET);
       
    68     int ret  =0;
       
    69     if (strcmp(mHost, "") == 0)
       
    70     {
       
    71         LOG(ESOCKET, EInfo, "Datagram server connection");
       
    72         mDatagramServerFactory =
       
    73             &DatagramServerConnectionFactory::getFactory();
       
    74 
       
    75         mUrl = JavaCommonUtils::utf8ToWstring((const char *) mName);
       
    76         try
       
    77         {
       
    78             mDatagramServerPtr = reinterpret_cast<DatagramServerConnection*>(mDatagramServerFactory->create(
       
    79                                      mUrl));
       
    80         }
       
    81         catch (PushException& ex)
       
    82         {
       
    83             LOG(ESOCKET, EInfo, "ERROR!!! CreateConnection() PushException was caught");
       
    84             return -1;
       
    85         }
       
    86         if (mDatagramServerPtr != NULL)
       
    87         {
       
    88             mSockDesc = mDatagramServerPtr->open();
       
    89         }
       
    90         else
       
    91         {
       
    92             LOG(ESOCKET, EInfo, "mDatagramServerPtr is null ");
       
    93             return -1;
       
    94         }
       
    95     }
       
    96     else
       
    97     {
       
    98 
       
    99         LOG(ESOCKET, EInfo, "Datagram client connection");
       
   100         mSockDesc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
       
   101 
       
   102         if (aApn != -1)
       
   103         {
       
   104             // remove comments if open c patch available
       
   105             ret = ApnSettings::setDefaultApn(aType,aApn);
       
   106         }
       
   107     }
       
   108     LOG1(ESOCKET, EInfo, " NativeDatagramConnection::openConnection :: mSockDesc = ",mSockDesc);
       
   109     *err = ret;
       
   110     return mSockDesc;
       
   111 }
       
   112 
       
   113 int NativeDatagramConnection::sendDatagram(JNIEnv &aJni,
       
   114         jbyteArray aJavaBuffer, int aOffset, int aLength,
       
   115         const char *aDestAddr, int aDestPort)
       
   116 {
       
   117     JELOG2(ESOCKET);
       
   118     char * writeBuffer = NULL;
       
   119     int retVal;
       
   120     struct sockaddr_in addr;
       
   121     addr.sin_family = AF_INET;
       
   122     addr.sin_port = htons(aDestPort);
       
   123 
       
   124     int requiredNativeBufferLength = aLength - aOffset;
       
   125     // Allocate native buffer
       
   126     if (writeBuffer == NULL)
       
   127     {
       
   128         writeBuffer = new char[requiredNativeBufferLength + 1];
       
   129     }
       
   130     /* Copy the data to be written from java buffer to the native buffer.  */
       
   131     JNIArrayUtils::CopyToNative(aJni, aJavaBuffer, aOffset,
       
   132                                 requiredNativeBufferLength, writeBuffer);
       
   133 
       
   134     if (!inet_aton(aDestAddr, &addr.sin_addr))
       
   135     {
       
   136         struct hostent* hp = gethostbyname(aDestAddr);
       
   137         addr.sin_addr.s_addr = ((struct in_addr*)(hp->h_addr))->s_addr;
       
   138     }
       
   139     LOG1(ESOCKET, EInfo, "send buffer is %s", writeBuffer);
       
   140     retVal = sendto(mSockDesc, writeBuffer, requiredNativeBufferLength, 0,
       
   141                     (struct sockaddr*) &addr, sizeof(addr));
       
   142     LOG1(ESOCKET, EInfo, "number of bytes sent is %d ", retVal);
       
   143     if (writeBuffer != NULL)
       
   144     {
       
   145         delete[] writeBuffer;
       
   146     }
       
   147 
       
   148     if (retVal < 0)
       
   149     {
       
   150         return -errno;
       
   151     }
       
   152     else
       
   153     {
       
   154         return retVal;
       
   155     }
       
   156 
       
   157 }
       
   158 
       
   159 
       
   160 int NativeDatagramConnection::receiveDatagram(JNIEnv &aJni,
       
   161         jbyteArray aJavaBuffer, int aOffset, int aLength, char* aSenderAddr,
       
   162         int * aSenderPort)
       
   163 {
       
   164     JELOG2(ESOCKET);
       
   165     char * readBuffer = NULL;
       
   166     struct sockaddr_in sender_addr;
       
   167     sender_addr.sin_family = AF_INET;
       
   168     unsigned int size = sizeof(sender_addr);
       
   169     int retVal;
       
   170     int requiredNativeBufferLength = aLength - aOffset;
       
   171     if (readBuffer == NULL)
       
   172     {
       
   173         readBuffer = new char[requiredNativeBufferLength + 2];
       
   174     }
       
   175     int bytesReceived = recvfrom(mSockDesc, readBuffer,
       
   176                                  requiredNativeBufferLength, 0, (struct sockaddr*) &sender_addr,
       
   177                                  &size);
       
   178 
       
   179     if (bytesReceived < 0)
       
   180     {
       
   181         retVal = -errno;
       
   182     }
       
   183     else
       
   184     {
       
   185         retVal = bytesReceived;
       
   186         strcpy(aSenderAddr, inet_ntoa(sender_addr.sin_addr));
       
   187         *aSenderPort = ntohs(sender_addr.sin_port);
       
   188 
       
   189         ILOG2(ESOCKET,
       
   190               "NativeDatagramConnection::receiveDatagram() senderaddress =  %s, port= %d",
       
   191               aSenderAddr, aSenderPort);
       
   192 
       
   193         JNIArrayUtils::CopyToJava(aJni, readBuffer, bytesReceived, aJavaBuffer,
       
   194                                   aOffset, bytesReceived);
       
   195     }
       
   196     delete[] readBuffer;
       
   197     return retVal;
       
   198 
       
   199 }
       
   200 
       
   201 int NativeDatagramConnection::getLocalAddress(char * aAddress)
       
   202 {
       
   203     JELOG2(ESOCKET);
       
   204     struct sockaddr_in addr;
       
   205     socklen_t len = sizeof(addr);
       
   206     int retval;
       
   207     LOG1(ESOCKET, EInfo,
       
   208          "NativeDatagramConnection::getLocalAddress() : mSockDesc =  : %d",
       
   209          mSockDesc);
       
   210     if (getsockname(mSockDesc, (struct sockaddr*) &addr, &len) < 0)
       
   211     {
       
   212         LOG1(
       
   213             ESOCKET,
       
   214             EInfo,
       
   215             "NativeDatagramConnection::getLocalAddress() : getlocaladdress failed : %d",
       
   216             errno);
       
   217         strcpy(aAddress, "error");
       
   218         retval = -errno;
       
   219     }
       
   220     else
       
   221     {
       
   222         strcpy(aAddress, inet_ntoa(addr.sin_addr));
       
   223         retval = 0;
       
   224     }
       
   225     return retval;
       
   226 }
       
   227 
       
   228 int NativeDatagramConnection::getLocalPort()
       
   229 {
       
   230     JELOG2(ESOCKET);
       
   231     struct sockaddr_in addr;
       
   232     socklen_t len = sizeof(addr);
       
   233     int retval;
       
   234 
       
   235     if ((getsockname(mSockDesc, (struct sockaddr*) &addr, &len)) < 0)
       
   236     {
       
   237         LOG1(
       
   238             ESOCKET,
       
   239             EInfo,
       
   240             "NativeDatagramConnection::getLocalPort() : getlocalport failed : %d",
       
   241             errno);
       
   242         retval = -errno;
       
   243     }
       
   244     else
       
   245     {
       
   246         retval = ntohs(addr.sin_port);
       
   247     }
       
   248     return retval;
       
   249 }
       
   250 
       
   251 // called only via midlet, when UDPDatagrmaConnection.close() is called
       
   252 int NativeDatagramConnection::datagramClose()
       
   253 {
       
   254     JELOG2(ESOCKET);
       
   255     int retValue;
       
   256     if (strcmp(mHost, "") == 0) // server connection
       
   257     {
       
   258         //retValue = close(mSockDesc);
       
   259         if (mUrl.length() != 12)
       
   260         {
       
   261             if (mDatagramServerFactory != NULL)
       
   262             {
       
   263                 mDatagramServerFactory->releaseConnection(mUrl);
       
   264                 mDatagramServerFactory = NULL;
       
   265                 mDatagramServerPtr = NULL;
       
   266             }
       
   267         }
       
   268         else          // is it is normal server connection, then just close the socket
       
   269         {
       
   270             if (mDatagramServerPtr->isNormalServerConnection() == true)
       
   271             {
       
   272                 retValue = ::close(mSockDesc);
       
   273                 if (retValue == -1)
       
   274                 {
       
   275                     LOG1(ESOCKET, EInfo,
       
   276                          "NativeDatagramConnection::datagramClose() : socket close failed : %d",
       
   277                          errno);
       
   278                     return -errno;
       
   279                 }
       
   280                 else
       
   281                 {
       
   282                     LOG1(ESOCKET, EInfo,
       
   283                          "NativeDatagramConnection::setsocketoption  setsockopt errno %d",
       
   284                          -errno);
       
   285                     return retValue;
       
   286                 }
       
   287             }
       
   288             else   // it is added to push db so call releaseconnection
       
   289             {
       
   290                 mDatagramServerFactory->releaseConnection(mUrl);
       
   291                 mDatagramServerFactory = NULL;
       
   292                 mDatagramServerPtr = NULL;
       
   293             }
       
   294         }
       
   295         return 0;
       
   296     }
       
   297     else
       
   298     {
       
   299         retValue = close(mSockDesc);
       
   300         if (retValue == -1)
       
   301         {
       
   302             LOG1(ESOCKET,
       
   303                  EInfo,
       
   304                  "NativeDatagramConnection::socketClose() : socket close failed : %d",
       
   305                  errno);
       
   306             return -errno;
       
   307         }
       
   308         else
       
   309         {
       
   310             LOG1(ESOCKET, EInfo,
       
   311                  "NativeDatagramConnection::setsocketoption  setsockopt errno %d",
       
   312                  -errno);
       
   313             return retValue;
       
   314         }
       
   315     }
       
   316 }
       
   317 
       
   318 NativeDatagramConnection::~NativeDatagramConnection()
       
   319 {
       
   320     JELOG2(ESOCKET);
       
   321     if (mName != NULL)
       
   322     {
       
   323         delete[] mName;
       
   324     }
       
   325     if (mHost != NULL)
       
   326     {
       
   327         delete[] mHost;
       
   328     }
       
   329 }
       
   330