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 + -
显示快捷键?