socketprotocol.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 968 行 · 第 1/3 页

C
968
字号
/* *   * * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */#include <stdio.h>#include <kni.h>#include <sni.h>#include <commonKNIMacros.h>#include <ROMStructs.h>#include <anc_indicators.h>#include <midpError.h>#include <push_server_export.h>#include <push_server_resource_mgmt.h>#include <midp_properties_port.h>#include <midp_logging.h>#include <midpResourceLimit.h>#include <string.h>#include <pcsl_network.h>#include <midp_thread.h>#include <midp_libc_ext.h>#include <kni_globals.h>#include <midpUtilKni.h>#include <midp_net_events.h>/** * @file *  * The default implementation of the native functions that are needed * for supporting the "socket:" Generic Connection protocols. *//* Macro to retrieve C structure representation of an Object */typedef struct Java_com_sun_midp_io_j2me_socket_Protocol _socketProtocol;#define getMidpSocketProtocolPtr(handle) (unhand(_socketProtocol,(handle)))/** * Opens a TCP connection to a server. * <p> * Java declaration: * <pre> *     open([BI)V * </pre> * * @param ipBytes Byte array that represents a raw IP address * @param port TCP port at host * * @return a native handle to the network connection. */KNIEXPORT KNI_RETURNTYPE_VOIDJava_com_sun_midp_io_j2me_socket_Protocol_open0(void) {    int   port;    void *pcslHandle = INVALID_HANDLE;    int status;    void* context = NULL;    MidpReentryData* info;    port = (int)KNI_GetParameterAsInt(2);    KNI_StartHandles(2);    KNI_DeclareHandle(thisObject);    KNI_DeclareHandle(bufferObject);    KNI_GetThisPointer(thisObject);    KNI_GetParameterAsObject(1, bufferObject);    info = (MidpReentryData*)SNI_GetReentryData(NULL);    if (info == NULL) {   /* First invocation */       getMidpSocketProtocolPtr(thisObject)->handle = (jint)INVALID_HANDLE;       /**         * Verify that the resource is available well within limit as per          * the policy in ResourceLimiter         */        if (midpCheckResourceLimit(RSC_TYPE_TCP_CLI, 1) == 0) {            REPORT_INFO(LC_PROTOCOL,                "Resource limit exceeded for TCP client sockets");             KNI_ThrowNew(midpIOException,                "Resource limit exceeded for TCP client sockets");        } else {            SNI_BEGIN_RAW_POINTERS;            status = pcsl_socket_open_start(                     (unsigned char*)JavaByteArray(bufferObject),                     port, &pcslHandle, &context);            SNI_END_RAW_POINTERS;            if (status == PCSL_NET_SUCCESS) {                getMidpSocketProtocolPtr(thisObject)->handle = (jint)pcslHandle;                if (midpIncResourceCount(RSC_TYPE_TCP_CLI, 1) == 0) {                    REPORT_INFO(LC_PROTOCOL, "Resource limit update error");                 }            } else if (status == PCSL_NET_IOERROR) {                midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE,                        "IOError in socket::open = %d\n",                        (int)pcsl_network_error(pcslHandle));                REPORT_INFO1(LC_PROTOCOL, "%s\n", gKNIBuffer);                KNI_ThrowNew(midpIOException, gKNIBuffer);            } else if (status == PCSL_NET_CONNECTION_NOTFOUND) {                midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE,                         "ConnectionNotFound error in socket::open :"                         " error = %d\n", (int)pcsl_network_error(pcslHandle));                REPORT_INFO1(LC_PROTOCOL, "%s\n", gKNIBuffer);                 KNI_ThrowNew(midpConnectionNotFoundException, gKNIBuffer);            } else if (status == PCSL_NET_WOULDBLOCK) {                ANC_INC_NETWORK_INDICATOR;                getMidpSocketProtocolPtr(thisObject)->handle = (jint)pcslHandle;                if (midpIncResourceCount(RSC_TYPE_TCP_CLI, 1) == 0) {                    REPORT_INFO(LC_PROTOCOL, "Resource limit update error");                 }                REPORT_INFO1(LC_PROTOCOL, " handle = %d\n", pcslHandle);                midp_thread_wait(NETWORK_WRITE_SIGNAL, (int)pcslHandle,                    context);            } else {                REPORT_INFO(LC_PROTOCOL, "Unknown error during socket::open");                 KNI_ThrowNew(midpIOException, NULL);            }        }    } else {  /* Reinvocation after unblocking the thread */        pcslHandle = (void *) info->descriptor;        context = (void *)info->status;        if (getMidpSocketProtocolPtr(thisObject)->handle != (jint)pcslHandle) {            REPORT_CRIT2(LC_PROTOCOL,                          "socket::open Handles mismatched 0x%x != 0x%x\n",                          pcslHandle,                         getMidpSocketProtocolPtr(thisObject)->handle);        }        status = pcsl_socket_open_finish(pcslHandle, context);        if (status == PCSL_NET_SUCCESS) {            ANC_DEC_NETWORK_INDICATOR;        } else if (status == PCSL_NET_WOULDBLOCK) {            midp_thread_wait(NETWORK_WRITE_SIGNAL, (int)pcslHandle, context);        } else  {            ANC_DEC_NETWORK_INDICATOR;            getMidpSocketProtocolPtr(thisObject)->handle = (jint)INVALID_HANDLE;            if (midpDecResourceCount(RSC_TYPE_TCP_CLI, 1) == 0) {                REPORT_INFO(LC_PROTOCOL, "Resource limit update error");             }            midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE,                    "error %d in socket::open",                    (int)pcsl_network_error(pcslHandle));            REPORT_INFO1(LC_PROTOCOL, "%s\n", gKNIBuffer);             KNI_ThrowNew(midpConnectionNotFoundException, gKNIBuffer);        }    }    KNI_EndHandles();    KNI_ReturnVoid();}/** * Reads from the open socket connection. * <p> * Java declaration: * <pre> *     read0([BII)I * </pre> * * @param b the buffer into which the data is read. * @param off the start offset in array <code>b</code> *            at which the data is written. * @param len the maximum number of bytes to read. * * @return the total number of bytes read into the buffer, or *         <tt>-1</tt> if there is no more data because the end of *         the stream has been reached. */KNIEXPORT KNI_RETURNTYPE_INTJava_com_sun_midp_io_j2me_socket_Protocol_read0(void) {    int length;    int offset;    int iStreams;    void *pcslHandle;    int bytesRead = -1;    int status = PCSL_NET_INVALID;    void* context = NULL;    MidpReentryData* info;        length = (int)KNI_GetParameterAsInt(3);    offset = (int)KNI_GetParameterAsInt(2);    KNI_StartHandles(2);        KNI_DeclareHandle(bufferObject);    KNI_DeclareHandle(thisObject);    KNI_GetThisPointer(thisObject);    KNI_GetParameterAsObject(1, bufferObject);        pcslHandle = (void *)(getMidpSocketProtocolPtr(thisObject)->handle);    iStreams = (int)(getMidpSocketProtocolPtr(thisObject)->iStreams);     REPORT_INFO3(LC_PROTOCOL, "socket::read0 o=%d l=%d fd=%d\n",                 offset, length, (int)pcslHandle);    if (pcslHandle != INVALID_HANDLE) {        int ipAddress;        int port;        /* Check the push cache for a waiting packet. */        SNI_BEGIN_RAW_POINTERS;        bytesRead = pushgetcachedpacket((int)pcslHandle, &ipAddress, &port,            (char*)&(JavaByteArray(bufferObject)[offset]), length);        SNI_END_RAW_POINTERS;    }    if (bytesRead <= 0) {        info = (MidpReentryData*)SNI_GetReentryData(NULL);        ANC_START_NETWORK_INDICATOR;        if (info == NULL) {   /* First invocation */            if (INVALID_HANDLE == pcslHandle) {                KNI_ThrowNew(midpIOException, "invalid handle during socket::read");            } else {                ANC_INC_NETWORK_INDICATOR;                SNI_BEGIN_RAW_POINTERS;                status = pcsl_socket_read_start(pcslHandle,                               (unsigned char*)&(JavaByteArray(bufferObject)[offset]),                               length, &bytesRead, &context);                SNI_END_RAW_POINTERS;            }        } else {  /* Reinvocation after unblocking the thread */            if (INVALID_HANDLE == pcslHandle || iStreams == 0) {                /* connection or its input streams are closed by another thread */                KNI_ThrowNew(midpInterruptedIOException,                             "Interrupted IO error during socket::read");                ANC_DEC_NETWORK_INDICATOR;            } else {                if ((void *)info->descriptor != pcslHandle) {                    REPORT_CRIT2(LC_PROTOCOL,                                 "socket::read Handles mismatched 0x%x != 0x%x\n",                                 pcslHandle,                                 info->descriptor);                }                context = info->pResult;                SNI_BEGIN_RAW_POINTERS;                status = pcsl_socket_read_finish(pcslHandle,                           (unsigned char*)&(JavaByteArray(bufferObject)[offset]),                           length, &bytesRead, context);                SNI_END_RAW_POINTERS;            }        }        REPORT_INFO1(LC_PROTOCOL, "socket::read0 bytesRead=%d\n", bytesRead);        if (INVALID_HANDLE != pcslHandle) {            if (status == PCSL_NET_SUCCESS) {                if (bytesRead == 0) {                    /* end of stream */                    bytesRead = -1;                }                ANC_DEC_NETWORK_INDICATOR;            } else {                REPORT_INFO1(LC_PROTOCOL, "socket::read error=%d\n",                             pcsl_network_error(pcslHandle));                if (status == PCSL_NET_WOULDBLOCK) {                    midp_thread_wait(NETWORK_READ_SIGNAL, (int)pcslHandle, context);                } else if (status == PCSL_NET_INTERRUPTED) {                    midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE,                            "Interrupted IO error %d during socket::read ",                            pcsl_network_error(pcslHandle));                    KNI_ThrowNew(midpInterruptedIOException, gKNIBuffer);                    ANC_DEC_NETWORK_INDICATOR;                } else {                    midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE,                            "Unknown error %d during socket::read ",                            pcsl_network_error(pcslHandle));                    KNI_ThrowNew(midpIOException, gKNIBuffer);                    ANC_DEC_NETWORK_INDICATOR;                }            }        }        ANC_STOP_NETWORK_INDICATOR;    }    KNI_EndHandles();    KNI_ReturnInt((jint)bytesRead);}/** * Writes to the open socket connection. * <p> * Java declaration: * <pre> *     write0([BII)I * </pre> * * @param b the buffer of the data to write * @param off the start offset in array <tt>b</tt> *            at which the data is written. * @param len the number of bytes to write. * * @return the total number of bytes written */KNIEXPORT KNI_RETURNTYPE_INTJava_com_sun_midp_io_j2me_socket_Protocol_write0(void) {     int length;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?