KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_cldc_io_j2me_socket_Protocol_writeBuf() { int result; int fd = KNI_GetParameterAsInt(1); int offset = KNI_GetParameterAsInt(3); int length = KNI_GetParameterAsInt(4); KNI_StartHandles(1); KNI_DeclareHandle(buffer_object); KNI_GetParameterAsObject(2, buffer_object); char *buffer = (char *) SNI_GetRawArrayPointer(buffer_object) + offset; result = jvm_send(fd, buffer, length, 0); // We rely on open0() for setting the socket to non-blocking KNI_EndHandles(); if (result < 0) { int err_code = GET_LAST_ERROR(); if (err_code == EWOULDBLOCK) { if (SNI_GetReentryData(NULL) == NULL) { BlockingSocket *socket = (BlockingSocket *) SNI_AllocateReentryData(sizeof(*socket)); socket->fd = fd; socket->check_flags = CHECK_WRITE; } SNI_BlockThread(); } } KNI_ReturnInt(result); }
KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_cldc_io_j2me_socket_Protocol_open0() { static int inited = 0; if (!inited) { pcsl_network_init(); inited = 1; } int fd = -1; // (1) Get the hostname, and convert it to IP address KNI_StartHandles(1); { KNI_DeclareHandle(hostname_object); KNI_GetParameterAsObject(1, hostname_object); // hostname is always NUL terminated. See socket/Protocol.java for detail. char *hostname = (char*) SNI_GetRawArrayPointer(hostname_object); int port = KNI_GetParameterAsInt(2); unsigned char addr[4]; int len; int status; void *context; void *handle; status = pcsl_network_gethostbyname_start( hostname, addr, sizeof(addr), &len, &handle, &context); if (status == PCSL_NET_WOULDBLOCK) { do { status = pcsl_network_gethostbyname_finish(addr, sizeof(addr), &len, &handle, &context); } while (status == PCSL_NET_WOULDBLOCK); } if (status != PCSL_NET_SUCCESS) { goto done; } // (2) Make the connection status = pcsl_socket_open_start( addr, port, &handle, &context); if (status == PCSL_NET_WOULDBLOCK) { do { status = pcsl_socket_open_finish(handle, context); } while (status == PCSL_NET_WOULDBLOCK); } if (status != PCSL_NET_SUCCESS) { goto done; } fd = (int)handle; } done: KNI_EndHandles(); KNI_ReturnInt(fd); }
KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_cldc_io_j2me_socket_Protocol_open0() { SocketOpenParameter *p; struct hostent *phostent; char *hostname; int port; int result; init_sockets(); if (!ANI_Start()) { ANI_Wait(); KNI_ReturnInt(-1); } p = (SocketOpenParameter *)(ANI_GetParameterBlock(NULL)); if (p == NULL) { p = (SocketOpenParameter *) (ANI_AllocateParameterBlock(sizeof(SocketOpenParameter))); p->fd = -1; KNI_StartHandles(1); KNI_DeclareHandle(hostname_object); KNI_GetParameterAsObject(1, hostname_object); // hostname is always NUL terminated. See socket/Protocol.java for detail. hostname = (char *)(SNI_GetRawArrayPointer(hostname_object)); // 'gethostbyname()' is NON-REENTRANT and its result is in global memory! // => its call must not be moved to 'asynchronous_connect_socket()'! phostent = gethostbyname(hostname); KNI_EndHandles(); if (phostent != NULL) { p->destination_sin.sin_family = AF_INET; port = KNI_GetParameterAsInt(2); p->destination_sin.sin_port = htons((short)port); memcpy((char *) &p->destination_sin.sin_addr, phostent->h_addr, phostent->h_length); p->fd = socket(AF_INET, SOCK_STREAM, 0); if (p->fd >= 0 && set_blocking_flags(&p->fd, /*is_blocking*/ KNI_TRUE) && !ANI_UseFunction(asynchronous_connect_socket, /*try_non_blocking*/ KNI_FALSE)) { ANI_BlockThread(); } } } result = p->fd; ANI_End(); KNI_ReturnInt(result); }
KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_cldc_io_j2me_socket_Protocol_writeBuf() { void *handle = (void*)KNI_GetParameterAsInt(1); int offset = KNI_GetParameterAsInt(3); int length = KNI_GetParameterAsInt(4); int result; KNI_StartHandles(1); { KNI_DeclareHandle(buffer_object); KNI_GetParameterAsObject(2, buffer_object); char *buffer = (char *) SNI_GetRawArrayPointer(buffer_object) + offset; result = do_pcsl_write(handle, buffer, length); } KNI_EndHandles(); KNI_ReturnInt(result); }
/** * Performs reset of the device. * <p>Java declaration: * <pre> * private native int reset0(byte[] atr); * </pre> * @param atr ATR bytes * @return Length of ATR in case of success, else -1 */ KNIEXPORT KNI_RETURNTYPE_INT KNIDECL(com_sun_cardreader_PlatformCardDevice_reset0) { jint retcode; javacall_int32 atr_length; char *atr_buffer; MidpReentryData* info; void *context = NULL; javacall_result status_code; KNI_StartHandles(1); KNI_DeclareHandle(atr_handle); info = (MidpReentryData*)SNI_GetReentryData(NULL); KNI_GetParameterAsObject(1, atr_handle); if (KNI_IsNullHandle(atr_handle)) { atr_buffer = NULL; atr_length = 0; } else { atr_length = KNI_GetArrayLength(atr_handle); atr_buffer = SNI_GetRawArrayPointer(atr_handle); } if (info == NULL) { status_code = javacall_carddevice_reset_start(atr_buffer, &atr_length, &context); } else { context = info->pResult; status_code = javacall_carddevice_reset_finish(atr_buffer, &atr_length, context); } if (status_code == JAVACALL_WOULD_BLOCK) { midp_thread_wait(CARD_READER_DATA_SIGNAL, SIGNAL_RESET, context); goto end; } if (status_code != JAVACALL_OK) { retcode = -1; } else { retcode = atr_length; } end: KNI_EndHandles(); KNI_ReturnInt(retcode); }
KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_cldc_io_j2me_socket_Protocol_readBuf() { int result; int fd = KNI_GetParameterAsInt(1); int offset = KNI_GetParameterAsInt(3); int length = KNI_GetParameterAsInt(4); KNI_StartHandles(1); KNI_DeclareHandle(buffer_object); KNI_GetParameterAsObject(2, buffer_object); char *buffer = (char *) SNI_GetRawArrayPointer(buffer_object) + offset; result = jvm_recv(fd, buffer, length, 0); // We rely on open0() for setting the socket to non-blocking KNI_EndHandles(); if (result == 0) { // If remote side has shut down the connection gracefully, and all // data has been received, recv() will complete immediately with // zero bytes received. // // This is true for Win32/CE and Linux result = -1; } else if (result < 0) { int err_code = GET_LAST_ERROR(); if (err_code == EWOULDBLOCK) { if (SNI_GetReentryData(NULL) == NULL) { BlockingSocket *socket = (BlockingSocket *)SNI_AllocateReentryData(sizeof(*socket)); socket->fd = fd; socket->check_flags = CHECK_READ; } SNI_BlockThread(); } } KNI_ReturnInt(result); }
KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_cldc_io_j2me_socket_Protocol_open0() { init_sockets(); SocketOpenParameter *p = (SocketOpenParameter*) SNI_GetReentryData(NULL); if (p == NULL) { p = (SocketOpenParameter*) SNI_AllocateReentryData(sizeof(*p)); p->fd = -1; struct hostent *phostent; KNI_StartHandles(1); KNI_DeclareHandle(hostname_object); KNI_GetParameterAsObject(1, hostname_object); // hostname is always NUL terminated. See socket/Protocol.java for detail. char *hostname = (char*) SNI_GetRawArrayPointer(hostname_object); phostent = (struct hostent*)jvm_gethostbyname(hostname); KNI_EndHandles(); if (phostent == NULL) { KNI_ReturnInt(-1); } struct sockaddr_in destination_sin; destination_sin.sin_family = AF_INET; int port = KNI_GetParameterAsInt(2); destination_sin.sin_port = jvm_htons(port); jvm_memcpy((char *) &destination_sin.sin_addr, phostent->h_addr, phostent->h_length); p->fd = jvm_socket(AF_INET, SOCK_STREAM, 0); if (p->fd < 0) { KNI_ReturnInt(-1); } if (!set_blocking_flags(&p->fd, /*is_blocking*/ KNI_FALSE)) { KNI_ReturnInt(-1); } if (jvm_connect(p->fd, (struct sockaddr *) &destination_sin, sizeof(destination_sin)) < 0) { int err_code = GET_LAST_ERROR(); if (err_code == EINPROGRESS) { // When the socket is ready for connect, it becomes *writable* // (according to BSD socket spec of select()) p->check_flags = CHECK_WRITE | CHECK_EXCEPTION; SNI_BlockThread(); } else { jvm_shutdown(p->fd, 2); closesocket(p->fd); p->fd = -1; } } KNI_ReturnInt(p->fd); } else { // When we come to here, a CheckEvent() call has reported one of the // following: // [1] connect() has succeeded. In this case we return the socket fd. // [2] connect() has failed. In this case CheckEvent has already closed // the socket and set p->fd to -1. So we'd be returning -1. KNI_ReturnInt(p->fd); } }
/** * Copies the contents of fromMsg to the contents of toMsg. Both must be * instances of LinkMessage. The toLink object must be an instance of Link. * It's filled in if the contents of fromMsg are a Link. Returns KNI_TRUE if * successful, otherwise KNI_FALSE. */ static jboolean copy(jobject fromMsg, jobject toMsg, jobject toLink) { jboolean retval; KNI_StartHandles(6); KNI_DeclareHandle(byteArrayClass); KNI_DeclareHandle(stringClass); KNI_DeclareHandle(linkClass); KNI_DeclareHandle(fromContents); KNI_DeclareHandle(newString); KNI_DeclareHandle(newByteArray); KNI_FindClass("[B", byteArrayClass); KNI_FindClass("java/lang/String", stringClass); KNI_FindClass("com/sun/midp/links/Link", linkClass); getContents(fromMsg, fromContents); if (KNI_IsInstanceOf(fromContents, byteArrayClass)) { /* do a byte array copy */ jint fromOffset; jint fromLength; getRange(fromMsg, &fromOffset, &fromLength); SNI_NewArray(SNI_BYTE_ARRAY, fromLength, newByteArray); if (KNI_IsNullHandle(newByteArray)) { retval = KNI_FALSE; } else { KNI_GetRawArrayRegion(fromContents, fromOffset, fromLength, SNI_GetRawArrayPointer(newByteArray)); setContents(toMsg, newByteArray); setRange(toMsg, 0, fromLength); retval = KNI_TRUE; } } else if (KNI_IsInstanceOf(fromContents, stringClass)) { /* do a string copy */ jchar *buf; jsize slen = KNI_GetStringLength(fromContents); SNI_NewArray(SNI_BYTE_ARRAY, slen*sizeof(jchar), newByteArray); if (KNI_IsNullHandle(newByteArray)) { retval = KNI_FALSE; } else { buf = SNI_GetRawArrayPointer(newByteArray); KNI_GetStringRegion(fromContents, 0, slen, buf); KNI_NewString(buf, slen, newString); setContents(toMsg, newString); retval = KNI_TRUE; } } else if (KNI_IsInstanceOf(fromContents, linkClass)) { /* copy the link */ rendezvous *rp = getNativePointer(fromContents); setNativePointer(toLink, rp); rp_incref(rp); setContents(toMsg, toLink); retval = KNI_TRUE; } else { retval = KNI_FALSE; } KNI_EndHandles(); return retval; }
/** * Performs data transfer to the device. * <p>Java declaration: * <pre> * private native int cmdXfer0(byte[] request, byte[] response); * </pre> * @param request Buffer with request data * @param response Buffer for response data * @return Length of response in case of success, else -1 */ KNIEXPORT KNI_RETURNTYPE_INT KNIDECL(com_sun_cardreader_PlatformCardDevice_cmdXfer0) { jint retcode; javacall_int32 tx_length, rx_length; char *tx_buffer, *rx_buffer; MidpReentryData* info; void *context = NULL; javacall_result status_code; KNI_StartHandles(2); KNI_DeclareHandle(request_handle); KNI_DeclareHandle(response_handle); info = (MidpReentryData*)SNI_GetReentryData(NULL); KNI_GetParameterAsObject(1, request_handle); if (KNI_IsNullHandle(request_handle)) { tx_buffer = NULL; tx_length = 0; retcode = -1; goto end; } else { tx_length = KNI_GetArrayLength(request_handle); tx_buffer = SNI_GetRawArrayPointer(request_handle); } KNI_GetParameterAsObject(2, response_handle); if (KNI_IsNullHandle(response_handle)) { rx_buffer = NULL; rx_length = 0; retcode = -1; goto end; } else { rx_length = KNI_GetArrayLength(response_handle); rx_buffer = SNI_GetRawArrayPointer(response_handle); } if (tx_length > 5) { jsize apdu_len = 5 + (tx_buffer[4]&0xFF) + 1; if (tx_length > apdu_len) { tx_length = apdu_len; } } if (info == NULL) { status_code = javacall_carddevice_xfer_data_start(tx_buffer, tx_length, rx_buffer, &rx_length, &context); } else { context = info->pResult; status_code = javacall_carddevice_xfer_data_finish(tx_buffer, tx_length, rx_buffer, &rx_length, context); } if (status_code == JAVACALL_WOULD_BLOCK) { midp_thread_wait(CARD_READER_DATA_SIGNAL, SIGNAL_XFER, context); goto end; } if (status_code != JAVACALL_OK) { retcode = -1; } else { retcode = rx_length; } end: KNI_EndHandles(); KNI_ReturnInt(retcode); }
/** * Performs data transfer to the device. This method must be called within * <tt>synchronize</tt> block with the Slot object. * <p>Java declaration: * <pre> * public native static int exchangeAPDU0(Handle h, Slot slot, byte[] request, byte[] response) throws IOException; * </pre> * @param h Connection handle. Can be null for internal purposes * @param slot Slot object. Unused when <tt>h</tt> is not null. * Must be provided if <tt>h</tt> is null. * @param request Buffer with request data * @param response Buffer for response data * @return Length of response data * @exception NullPointerException if any parameter is null * @exception IllegalArgumentException if request does not contain proper APDU * @exception InterruptedIOException if the connection handle is suddenly closed * in the middle of exchange or the card was removed and inserted again * @exception IOException if any I/O troubles occured */ KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_midp_io_j2me_apdu_APDUManager_exchangeAPDU0() { jint retcode = -1; MidpReentryData* info; void *context = NULL; JSR177_STATUSCODE status_code; JSR177_CARD_MOVEMENT movements; jsize tx_length, rx_length, rx_length_max; jbyte *tx_buffer, *rx_buffer; jbyte *cur; jbyte case_2[5]; int Lc, Le; int cla, channel; ConnectionHandle *h; CardSlot *card_slot; char *err_msg; jbyte getResponseAPDU[5]; KNI_StartHandles(4); KNI_DeclareHandle(connection_handle); KNI_DeclareHandle(slot_handle); KNI_DeclareHandle(request_handle); KNI_DeclareHandle(response_handle); info = (MidpReentryData*)SNI_GetReentryData(NULL); // If the Handle object is provided we get a Slot object from it KNI_GetParameterAsObject(1, connection_handle); if (!KNI_IsNullHandle(connection_handle)) { h = unhand(ConnectionHandle,(connection_handle)); card_slot = h->cardSlot; if (card_slot == NULL) { KNI_ThrowNew(midpNullPointerException, "Slot object is null"); goto end; } } else { h = NULL; KNI_GetParameterAsObject(2, slot_handle); if (KNI_IsNullHandle(slot_handle)) { KNI_ThrowNew(midpNullPointerException, "Handle and slot are null"); goto end; } card_slot = unhand(CardSlot,(slot_handle)); } KNI_GetParameterAsObject(3, request_handle); if (KNI_IsNullHandle(request_handle)) { KNI_ThrowNew(midpNullPointerException, "Request APDU is null"); goto end; } tx_length = KNI_GetArrayLength(request_handle); tx_buffer = SNI_GetRawArrayPointer(request_handle); KNI_GetParameterAsObject(4, response_handle); if (KNI_IsNullHandle(response_handle)) { KNI_ThrowNew(midpNullPointerException, "Response buffer is null"); goto end; } rx_length_max = KNI_GetArrayLength(response_handle); rx_buffer = SNI_GetRawArrayPointer(response_handle); if (h != NULL && (!h->opened || h->cardSessionId != card_slot->cardSessionId)) { char *msg = "Connection closed"; if (!card_slot->locked) { KNI_ThrowNew(midpIOException, msg); goto end; } else { KNI_ThrowNew(midpInterruptedIOException, msg); goto unlock_end; } } if (!card_slot->powered) { char *msg = "Card not powered up"; if (!card_slot->locked) { KNI_ThrowNew(midpIOException, msg); goto end; } else { KNI_ThrowNew(midpInterruptedIOException, msg); goto unlock_end; } } if (tx_length < 4) { // invalid APDU: too short invalid_apdu: KNI_ThrowNew(midpIllegalArgumentException, "Invalid APDU"); goto end; } // trying to guess the case if (tx_length == 4) { // case 1 Lc = Le = 0; } else { Lc = (tx_buffer[4]&0xFF); if (tx_length == 5) { // case 2 Le = Lc; Lc = 0; if (Le == 0) { Le = 256; } } else if (tx_length == 5 + Lc) { // case 3 Le = 0; } else { // case 4 if (5 + Lc >= tx_length) { // invalid APDU: bad Lc field goto invalid_apdu; } Le = tx_buffer[5 + Lc] & 0xFF; if (Le == 0) { Le = 256; } } } // if APDU of case 4 has Lc=0 then we transform it to case 2 if (tx_length > 5 && Lc == 0) { memcpy(case_2, tx_buffer, 4); case_2[4] = tx_buffer[5]; tx_buffer = case_2; tx_length = 5; } // trimming APDU if (tx_length > 5 + Lc + 1) { tx_length = 5 + Lc + 1; } cla = tx_buffer[0] & 0xf8; // mask channel and secure bit channel = cla != 0 && (cla < 0x80 || cla > 0xA0) ? 0 : tx_buffer[0] & 3; // locked slot means that we are in the middle of an exchange, // otherwise we should start a data transfer if (!card_slot->locked) { card_slot->received = 0; cur = rx_buffer; } else { cur = rx_buffer + card_slot->received; } do { // infinite loop int sw1, sw2; rx_length = rx_length_max - (jint)(cur - rx_buffer); if (rx_length < Le + 2) { err_msg = "Too long response"; goto err_mess; } if (info == NULL || info->status == SIGNAL_LOCK) { if (!card_slot->locked) { status_code = jsr177_lock(); if (status_code == JSR177_STATUSCODE_WOULD_BLOCK) { midp_thread_wait(CARD_READER_DATA_SIGNAL, SIGNAL_LOCK, NULL); goto end; } if (status_code != JSR177_STATUSCODE_OK) { goto err; } card_slot->locked = KNI_TRUE; // Since this line slot is locked status_code = jsr177_select_slot(card_slot->slot); if (status_code != JSR177_STATUSCODE_OK) { goto err; } } status_code = jsr177_xfer_data_start(tx_buffer, tx_length, cur, &rx_length, &context); } else { context = info->pResult; status_code = jsr177_xfer_data_finish(tx_buffer, tx_length, cur, &rx_length, context); } if (jsr177_card_movement_events(&movements) == JSR177_STATUSCODE_OK) { if ((movements & JSR177_CARD_MOVEMENT_MASK) != 0) { err_msg = "Card changed"; jsr177_set_error(err_msg); if (jsr177_get_error((jbyte*)gKNIBuffer, KNI_BUFFER_SIZE)) { err_msg = gKNIBuffer; } card_slot->powered = KNI_FALSE; goto interrupted; } } if (status_code == JSR177_STATUSCODE_WOULD_BLOCK) { midp_thread_wait(CARD_READER_DATA_SIGNAL, SIGNAL_XFER, context); card_slot->received = (jint)(cur - rx_buffer); goto end; } if (status_code != JSR177_STATUSCODE_OK) { err: if (jsr177_get_error((jbyte*)gKNIBuffer, KNI_BUFFER_SIZE)) { err_msg = gKNIBuffer; } else { err_msg = "exchangeAPDU0()"; } err_mess: KNI_ThrowNew(midpIOException, err_msg); if (card_slot->locked) { status_code = jsr177_unlock(); // ignore status_code card_slot->locked = KNI_FALSE; midp_thread_signal(CARD_READER_DATA_SIGNAL, SIGNAL_LOCK, SIGNAL_LOCK); } goto end; } if (rx_length < 2) { err_msg = "Response error"; goto err_mess; } if (h != NULL && (!h->opened || h->cardSessionId != card_slot->cardSessionId)) { err_msg = "Handle invalid or closed"; interrupted: KNI_ThrowNew(midpInterruptedIOException, err_msg); goto unlock_end; } sw1 = cur[rx_length - 2] & 0xFF; sw2 = cur[rx_length - 1] & 0xFF; if (sw1 == 0x6C && sw2 != 0x00 && Le != 0) { tx_buffer[tx_length - 1] = sw2; Le = sw2; info = NULL; continue; } cur += rx_length; if (Le == 0 || (sw1 != 0x61 && (channel != 0 || !card_slot->SIMPresent || (sw1 != 0x62 && sw1 != 0x63 && sw1 != 0x9E && sw1 != 0x9F)))) { break; } cur -= 2; // delete last SW1/SW2 from buffer Le = sw1 == 0x62 || sw1 == 0x63 ? 0 : sw2; memset(getResponseAPDU, 0, sizeof getResponseAPDU); tx_buffer = getResponseAPDU; tx_buffer[0] = channel; tx_buffer[1] = 0xC0; tx_buffer[4] = Le; if (Le == 0) { Le = 256; } tx_length = 5; info = NULL; } while(1); retcode = (jint)(cur - rx_buffer); unlock_end: card_slot->locked = KNI_FALSE; midp_thread_signal(CARD_READER_DATA_SIGNAL, SIGNAL_LOCK, SIGNAL_LOCK); status_code = jsr177_unlock(); if (status_code != JSR177_STATUSCODE_OK) { goto err; } end: KNI_EndHandles(); KNI_ReturnInt(retcode); }