1112 lines
39 KiB
C
1112 lines
39 KiB
C
/* -----------------------------------------------------------------------------
|
|
FILE NAME
|
|
jni_msg_funcs.c
|
|
|
|
FILE DESCRIPTION
|
|
This file contains the JNI C code to allow AWIPS II to interface with MHS.
|
|
|
|
The main function is Java_com_raytheon_messaging_mhs_MhsMessage_submitMessage,
|
|
which gets its name from the Java class that calls it. If the class name
|
|
changes at all or is repackaged, then this function must be renamed to match
|
|
the new class name.
|
|
|
|
HISTORY
|
|
06/01/09 Brian Rapp
|
|
Creation
|
|
|
|
----------------------------------------------------------------------------- */
|
|
|
|
static const char Sccsid_msg_object_c[] = "+[-]msg_object.c(CO.DDM) @(#)msg_object.c 7.25 12/15/2004 09:47:04";
|
|
|
|
#include <ctype.h>
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <time.h>
|
|
|
|
#include <mcMON.h>
|
|
|
|
#include <co/ddm_symbols.h>
|
|
#include <co/msg_object.h>
|
|
#include <co/addr_list.h>
|
|
#include <co/addr_object.h>
|
|
#include <co/retrans_request.h>
|
|
#include <co/enclosure.h>
|
|
#include <co/enclosure_list.h>
|
|
|
|
#include <co/ddm/mqrv/API.h>
|
|
#include <coDDM.h>
|
|
#include <jni.h>
|
|
|
|
#ifndef SUCCESS
|
|
#undef SUCCESS
|
|
#endif
|
|
|
|
/*
|
|
#define SUCCESS 0
|
|
#define FAIL_TYPE 1
|
|
#define FAIL_CREATE 2
|
|
#define FAIL_ADDR 3
|
|
#define FAIL_ENCLOSE 4
|
|
#define FAIL_SUBJECT 5
|
|
#define FAIL_PRIORITY 6
|
|
#define FAIL_BODY 7
|
|
#define FAIL_SUBMIT 8
|
|
#define FAIL_MSGID 9
|
|
#define FAIL_VALID_TIME 10
|
|
#define FAIL_CODE 11
|
|
#define FAIL_PRODID 12
|
|
#define FAIL_RETRY_COUNT 13
|
|
#define FAIL_TIMEOUT_TIME 14
|
|
#define FAIL_USER_ID 15
|
|
#define FAIL_JNI 16
|
|
*/
|
|
|
|
#define SUCCESS "Success"
|
|
#define FAIL_TYPE "FailType"
|
|
#define FAIL_CREATE "FailCreate"
|
|
#define FAIL_ADDR "FailAddress"
|
|
#define FAIL_ENCLOSE "FailEnclosure"
|
|
#define FAIL_SUBJECT "FailSubject"
|
|
#define FAIL_PRIORITY "FailPriority"
|
|
#define FAIL_BODY "FailBody"
|
|
#define FAIL_SUBMIT "FailSubmit"
|
|
#define FAIL_MSGID "FailMessageId"
|
|
#define FAIL_VALID_TIME "FailValidTime"
|
|
#define FAIL_CODE "FailHandlerCode"
|
|
#define FAIL_PRODID "FailProductId"
|
|
#define FAIL_RETRY_COUNT "FailRetryCount"
|
|
#define FAIL_TIMEOUT_TIME "FailTimeoutTime"
|
|
#define FAIL_USER_ID "FailUserId"
|
|
#define FAIL_JNI "FailJNI"
|
|
|
|
#define PACKAGE_CLASS "com/raytheon/messaging/mhs"
|
|
#define JNI_FUNC_NAME(package, funcname) Java_ ## package ## funcname
|
|
#define SUBMIT_MESSAGE JNI_FUNC_NAME(com_raytheon_messaging_mhs_MhsMessage, _submitMessage)
|
|
#define STRINGIFY(s) #s
|
|
|
|
/*
|
|
* Class: com_raytheon_messaging_mhs_MhsMessage
|
|
* Method: submitMessage
|
|
* Signature: (Lcom/raytheon/messaging/mhs/MhsMessage;)I
|
|
*/
|
|
JNIEXPORT jstring JNICALL SUBMIT_MESSAGE (JNIEnv *, jobject);
|
|
/* Java_com_raytheon_messaging_mhs_MhsMessage_submitMessage (JNIEnv *, jobject); */
|
|
|
|
void dwbNETsetEnv(int argc, char *argv[]);
|
|
static int buffer_file(char *path, char **p_buf, size_t *p_bufsiz);
|
|
static long hhmmToUtime(char *hhmm);
|
|
int coDDM_setUserID(MsgObject msg, char *user_id);
|
|
static int get_message_type(JNIEnv *env, jobject obj, jclass msg_class, int *type);
|
|
static int set_msg_addressees(MsgObject the_msg, JNIEnv *env, jobject obj, jclass msg_class);
|
|
static int get_priority(JNIEnv *env, jobject obj, jclass msg_class, int *priority);
|
|
static int set_enclosures(MsgObject the_msg, JNIEnv *env, jobject obj, jclass msg_class);
|
|
static int get_boolean_field(JNIEnv *env, jobject obj, jclass msg_class, char *field_name, int *bool_ptr);
|
|
static int get_int_field(JNIEnv *env, jobject obj, jclass msg_class, char *field_name, int *int_ptr);
|
|
static int get_string_field(JNIEnv *env, jobject obj, jclass msg_class, char *field_name, char **str_ptr);
|
|
void throw_submit_exception(JNIEnv *env, char *result_code, char *result_text);
|
|
|
|
static int show_trace;
|
|
static char statbuf[1024];
|
|
static jclass newExcCls;
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
|
|
FUNCTION NAME
|
|
Java_com_raytheon_messaging_mhs_MhsMessage_submitMessage
|
|
|
|
FUNCTION DESCRIPTION
|
|
JNI function for building and submitting an MHS message from Java. The
|
|
MhsMessage elements (Java) are used to create a MsgObject, which is then
|
|
passed to coDDM_createMsg, which in turn executes a DWB transaction to
|
|
submit the message to the message request daemon.
|
|
|
|
submitMessage is called from an instance of the MhsMessage class once all
|
|
needed message parameters have been specified and validated. If the call
|
|
is successful, 0 is returned. A positive return value indicates a messaging
|
|
error. The exact error can be determined from java by looking at the value
|
|
of the "result" member. More detailed error text is available by calling
|
|
result.getResultText(). A negative return value indicates a problem with
|
|
a JNI call that will most likely result in an exception being thrown upon
|
|
return to the JVM.
|
|
|
|
MESSAGE PARAMETERS
|
|
showTrace - Boolean value used to print detailed debugging information to
|
|
stdout and stderr. Defaults to false.
|
|
|
|
type - An integer value from 0 to 20 representing the type of message being
|
|
sent. See com.raytheon.messaging.mhs.MhsMessageType.java for details.
|
|
Defaults to 0.
|
|
|
|
productId - An optional product ID string of up to 32 characters. If provided
|
|
with multiple enclosures, it is only attached to the first enclosure.
|
|
|
|
verifyAddressess - Boolean value. If true, the addressees are run through a
|
|
validation check, but the message is not submitted. Default is false.
|
|
|
|
addressees - A list of destination addresses. The list can contain any
|
|
combination of sites (WFO/RFC) mnemonics, an NCF facility, or special
|
|
addresses (e.g. - INET, NWWS, RETRANS, DEFAULTNCF). Every message must
|
|
have at least one addressee.
|
|
|
|
actionCode - Integer code between 0 and 255 inclusive that determines what
|
|
action is to be taken by the recipients. The action is determined by
|
|
lookup from the text configuration file /awips/ops/data/mhs/rcv_handler.tbl.
|
|
This is a required parameter.
|
|
|
|
subject - Optional text string that is the subject of the message. Can be
|
|
up to 129 bytes.
|
|
|
|
priority - Integer message priority from 0 to 2 with 2 being highest. The
|
|
default value is 0.
|
|
|
|
bodyFile - Fully qualified file name for an optional message body. The
|
|
file can be up to 17K in length.
|
|
|
|
enclosures - An optional list of enclosure files. There is no predefined
|
|
limit to the size of an enclosure.
|
|
|
|
validTime - An optional date string (mm/dd/YYYY[:HHMM]) containing the
|
|
absolute time at which the product expires.
|
|
|
|
timeoutTime - An optional date string containing the absolute time at which
|
|
the message will time out if it has not been delivered. The maximum
|
|
value is 1200 seconds from the time of submission.
|
|
|
|
retryCount - An optional integer value containing the number of retries that
|
|
will be attempted if the message cannot be successfully delivered.
|
|
|
|
userId - The optional mailbox name of the recipient. The default is awipsmhs,
|
|
which should never be changed since MHS does not look for any other mail
|
|
boxes.
|
|
|
|
LOCAL DATA FILES
|
|
None
|
|
|
|
RETURNS
|
|
An integer status code. The Java result code is populated.
|
|
|
|
ERRORS REPORTED
|
|
< Description of errors reported to Monitor and Control >
|
|
|
|
----------------------------------------------------------------------------- */
|
|
|
|
JNIEXPORT jstring JNICALL SUBMIT_MESSAGE (JNIEnv *env, jobject obj) {
|
|
|
|
const char FUNCNAME[] = "submitMessage";
|
|
MsgObject the_msg;
|
|
char *tmpstr;
|
|
char *msg_id;
|
|
int check_flag;
|
|
int actionCode;
|
|
int retry_count;
|
|
char *user_id;
|
|
char *subject;
|
|
char *valid_time;
|
|
long valid_time_long;
|
|
char *timeout_time;
|
|
long timeout_time_long;
|
|
int priority;
|
|
int type;
|
|
char *product;
|
|
char *body_file;
|
|
char *bodybuf = NULL;
|
|
size_t bodybufsiz;
|
|
jclass msg_class;
|
|
jstring jmsg_id;
|
|
char buf[200];
|
|
|
|
/* Start code ----------------------------------------------------------------------------------- */
|
|
dwbNETsetEnv(0, (char **) NULL);
|
|
|
|
msg_class = (*env)->GetObjectClass(env, obj);
|
|
sprintf(buf, "%s/MhsSubmitException", PACKAGE_CLASS);
|
|
if ((newExcCls = (*env)->FindClass(env, buf)) == NULL) {
|
|
sprintf(statbuf, "Could not find Exception Class \"%s/MhsSubmitException\"\n", PACKAGE_CLASS);
|
|
printf(statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
/* Note: To get the various signatures, use this command: javap -s -p com.raytheon.messaging.mhs.MhsMessage */
|
|
|
|
/* Get the showTrace flag ----------------------------------------------------------------------- */
|
|
if (!get_boolean_field(env, obj, msg_class, "showTrace", &show_trace)) {
|
|
strcpy(statbuf, "Could not get boolean field \"showTrace\"");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
/* Get the message type ------------------------------------------------------------------------- */
|
|
if (!get_message_type(env, obj, msg_class, &type)) {
|
|
strcpy(statbuf, "Could not get message type field");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
/* Create the message object -------------------------------------------------------------------- */
|
|
if (!(the_msg = coDDM_createMsg(type))) {
|
|
sprintf (statbuf, "Failed createMsg type=%d\n", type);
|
|
throw_submit_exception(env, FAIL_CREATE, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
/* Get the productID ---------------------------------------------------------------------------- */
|
|
if (!get_string_field(env, obj, msg_class, "productId", &product)) {
|
|
strcpy(statbuf, "Could not get product ID");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
if (strlen(product) > 0) {
|
|
if (show_trace) printf ("Product ID: %s\n", product);
|
|
if (coDDM_setProdID(the_msg, product) < 0) {
|
|
sprintf (statbuf, "Failed setProdID '%s'\n", product);
|
|
free(product);
|
|
throw_submit_exception(env, FAIL_PRODID, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
}
|
|
free(product);
|
|
|
|
/* Get the verifyAddressees flag ---------------------------------------------------------------- */
|
|
if (!get_boolean_field(env, obj, msg_class, "verifyAddressees", &check_flag)) {
|
|
strcpy(statbuf, "Could not get verifyAddressees field");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
if (show_trace) printf ("Verify addressees flag: %d\n", check_flag);
|
|
|
|
/* Get the Addressees --------------------------------------------------------------------------- */
|
|
if (!set_msg_addressees(the_msg, env, obj, msg_class)) {
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
if (show_trace) {
|
|
AddrObject addr;
|
|
for (addr = addrListGetFirstItem(the_msg->addr_list); addr; addr = addrListGetNextItem(the_msg->addr_list)) {
|
|
printf ("Addressee from msg object: %s %s\n", addr->addressee_name, addr->ack_required ? "(A)" : "");
|
|
}
|
|
}
|
|
|
|
/* If check flag is set, don't send the message -- only verify the addressees ------------------- */
|
|
if (check_flag) {
|
|
int bufsiz = 0;
|
|
char *addrbuf;
|
|
char *p_addrlist_out;
|
|
|
|
for (tmpstr = coDDM_getFirstAddrName(the_msg); tmpstr; tmpstr = coDDM_getNextAddrName(the_msg)) {
|
|
bufsiz += strlen(tmpstr)+1;
|
|
}
|
|
|
|
if (!(addrbuf = malloc(bufsiz+1))) {
|
|
sprintf (statbuf, "Could not allocate %d bytes in %s\n", bufsiz+1, FUNCNAME);
|
|
coDDM_destroyMsg(&the_msg);
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
addrbuf[0] = '\0';
|
|
for (tmpstr = coDDM_getFirstAddrName(the_msg); tmpstr; tmpstr = coDDM_getNextAddrName(the_msg)) {
|
|
if (strlen(addrbuf)) {
|
|
strcat (addrbuf, ",");
|
|
}
|
|
strcat(addrbuf, tmpstr);
|
|
}
|
|
|
|
if (show_trace) printf ("check string: %s\n", addrbuf);
|
|
p_addrlist_out = NULL;
|
|
if (mqc_check_addr(the_msg->prodid, addrbuf, &p_addrlist_out) < 0) {
|
|
sprintf (statbuf, "Failed check addr list '%s'\n", addrbuf);
|
|
free (addrbuf);
|
|
coDDM_destroyMsg(&the_msg);
|
|
throw_submit_exception(env, FAIL_ADDR, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
if (p_addrlist_out) {
|
|
printf("Addr list: %s\n", p_addrlist_out);
|
|
} else {
|
|
printf("\n");
|
|
}
|
|
free (addrbuf);
|
|
coDDM_destroyMsg(&the_msg);
|
|
return((*env)->NewStringUTF(env, strlen(p_addrlist_out) ? p_addrlist_out : "\n"));
|
|
}
|
|
|
|
/* Get the message action code ------------------------------------------------------------------ */
|
|
if (!get_int_field(env, obj, msg_class, "actionCode", &actionCode)) {
|
|
coDDM_destroyMsg(&the_msg);
|
|
strcpy(statbuf, "Could not get actionCode");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
if (show_trace) printf ("Action Code: %d\n", actionCode);
|
|
|
|
if (coDDM_setMsgCode(the_msg, actionCode) < 0) {
|
|
sprintf (statbuf, "Failed setMsgCode '%d'\n", actionCode);
|
|
coDDM_destroyMsg(&the_msg);
|
|
throw_submit_exception(env, FAIL_CODE, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
/* Get the subject string ----------------------------------------------------------------------- */
|
|
if (!get_string_field(env, obj, msg_class, "subject", &subject)) {
|
|
coDDM_destroyMsg(&the_msg);
|
|
strcpy(statbuf, "Could not get subject");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
if (strlen(subject) > 0) {
|
|
if (show_trace) printf ("Message subject: %s\n", subject);
|
|
if (coDDM_setSubject(the_msg, subject) < 0) {
|
|
sprintf (statbuf, "Failed setSubject '%s'\n", subject);
|
|
coDDM_destroyMsg(&the_msg);
|
|
free(subject);
|
|
throw_submit_exception(env, FAIL_SUBJECT, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
}
|
|
free(subject);
|
|
|
|
/* Get the message priority code ---------------------------------------------------------------- */
|
|
if (!get_priority(env, obj, msg_class, &priority)) {
|
|
coDDM_destroyMsg(&the_msg);
|
|
strcpy(statbuf, "Could not get priority");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
if (show_trace) printf ("Priority: %d\n", priority);
|
|
|
|
if (coDDM_setPriority(the_msg, priority) < 0) {
|
|
sprintf (statbuf, "Failed setPriority '%d'\n", priority);
|
|
coDDM_destroyMsg(&the_msg);
|
|
throw_submit_exception(env, FAIL_PRIORITY, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
/* Get the body file name ----------------------------------------------------------------------- */
|
|
if (!get_string_field(env, obj, msg_class, "bodyFile", &body_file)) {
|
|
coDDM_destroyMsg(&the_msg);
|
|
strcpy(statbuf, "Could not get bodyFile");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
if (strlen(body_file) > 0) {
|
|
if (show_trace) printf ("Message body file name: %s\n", body_file);
|
|
if (buffer_file((char *) body_file, &bodybuf, &bodybufsiz) < 0) {
|
|
free(bodybuf);
|
|
free(body_file);
|
|
coDDM_destroyMsg(&the_msg);
|
|
throw_submit_exception(env, FAIL_BODY, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
if (show_trace) printf ("Message body: %s", bodybuf);
|
|
|
|
if (coDDM_setMsgBody(the_msg, bodybuf, bodybufsiz) < 0) {
|
|
sprintf (statbuf, "Failed setMsgBody '%s'\n", body_file);
|
|
free(bodybuf);
|
|
free(body_file);
|
|
coDDM_destroyMsg(&the_msg);
|
|
throw_submit_exception(env, FAIL_BODY, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
free(bodybuf);
|
|
}
|
|
|
|
free(body_file);
|
|
|
|
/* Set the Enclosure list ----------------------------------------------------------------------- */
|
|
if (!set_enclosures(the_msg, env, obj, msg_class)) {
|
|
coDDM_destroyMsg(&the_msg);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
if (show_trace) {
|
|
Enclosure encl;
|
|
for (encl = encListGetFirstItem(the_msg->enc_list); encl; encl = encListGetNextItem(the_msg->enc_list)) {
|
|
printf ("Enclosure file from msg object: %s\n", encl->filename);
|
|
}
|
|
}
|
|
|
|
/* Get the valid time string -------------------------------------------------------------------- */
|
|
if (!get_string_field(env, obj, msg_class, "validTimeString", &valid_time)) {
|
|
coDDM_destroyMsg(&the_msg);
|
|
strcpy(statbuf, "Could not get validTimeString");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
if (strlen(valid_time) > 0) {
|
|
if (show_trace) printf ("Valid Time String: %s\n", valid_time);
|
|
valid_time_long = hhmmToUtime((char *) valid_time);
|
|
if (coDDM_setValidTime(the_msg, valid_time_long) < 0) {
|
|
sprintf (statbuf, "Failed setValidTime: %s", ctime((const time_t *)&valid_time_long));
|
|
coDDM_destroyMsg(&the_msg);
|
|
free(valid_time);
|
|
throw_submit_exception(env, FAIL_VALID_TIME, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
}
|
|
|
|
free(valid_time);
|
|
|
|
/* Get the timeout time string ------------------------------------------------------------------ */
|
|
if (!get_string_field(env, obj, msg_class, "timeoutTimeString", &timeout_time)) {
|
|
coDDM_destroyMsg(&the_msg);
|
|
strcpy(statbuf, "Could not get timeoutTimeString");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
if (strlen(timeout_time) > 0) {
|
|
if (show_trace) printf ("Time Out String: %s\n", timeout_time);
|
|
timeout_time_long = hhmmToUtime((char *) timeout_time);
|
|
if (coDDM_setTimeoutTime(the_msg, timeout_time_long) < 0) {
|
|
sprintf (statbuf, "Failed setTimeoutTime: %s", ctime((const time_t *)&timeout_time_long));
|
|
coDDM_destroyMsg(&the_msg);
|
|
free(timeout_time);
|
|
throw_submit_exception(env, FAIL_TIMEOUT_TIME, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
}
|
|
|
|
free(timeout_time);
|
|
|
|
/* Get the retry count -------------------------------------------------------------------------- */
|
|
if (!get_int_field(env, obj, msg_class, "retryCount", &retry_count)) {
|
|
coDDM_destroyMsg(&the_msg);
|
|
strcpy(statbuf, "Could not get retryCount");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
if (retry_count > 0) {
|
|
if (show_trace) printf ("Retry count = %d\n", retry_count);
|
|
if (coDDM_setRetryCount(the_msg, retry_count) < 0) {
|
|
sprintf (statbuf, "Failed setRetryCount '%d'\n", retry_count);
|
|
coDDM_destroyMsg(&the_msg);
|
|
throw_submit_exception(env, FAIL_RETRY_COUNT, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
}
|
|
|
|
/* Get user ID string --------------------------------------------------------------------------- */
|
|
if (!get_string_field(env, obj, msg_class, "userId", &user_id)) {
|
|
coDDM_destroyMsg(&the_msg);
|
|
strcpy(statbuf, "Could not get userId");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
if (strlen(user_id) > 0) {
|
|
if (show_trace) printf ("User ID: %s\n", user_id);
|
|
if (coDDM_setUserID(the_msg, (char *) user_id) < 0) {
|
|
sprintf (statbuf, "Failed setUserID '%s'\n", user_id);
|
|
coDDM_destroyMsg(&the_msg);
|
|
free(user_id);
|
|
throw_submit_exception(env, FAIL_USER_ID, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
}
|
|
|
|
free(user_id);
|
|
|
|
/* Submit the message -------------------------------------------------------------------------- */
|
|
if (coDDM_submitMsg(the_msg) < 0) {
|
|
sprintf (statbuf, "Failed submitMsg\n");
|
|
coDDM_destroyMsg(&the_msg);
|
|
throw_submit_exception(env, FAIL_SUBMIT, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
|
|
if ((msg_id = coDDM_getMsgID(the_msg))) {
|
|
if (show_trace) printf ("Message successfully submitted. Message ID: %s\n", msg_id);
|
|
jmsg_id = (*env)->NewStringUTF(env, msg_id);
|
|
coDDM_destroyMsg(&the_msg);
|
|
return(jmsg_id);
|
|
} else {
|
|
sprintf (statbuf, "Failed getMsgID\n");
|
|
coDDM_destroyMsg(&the_msg);
|
|
throw_submit_exception(env, FAIL_MSGID, statbuf);
|
|
return((*env)->NewStringUTF(env, statbuf));
|
|
}
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------------------------------
|
|
|
|
FUNCTION NAME
|
|
buffer_file
|
|
|
|
FUNCTION DESCRIPTION
|
|
Read the fully-qualified file into a buffer. The buffer is allocated from the heap and
|
|
must be disposed when no longer needed. The buffer and the size are passed by reference.
|
|
|
|
PARAMETERS
|
|
Type Name I/O Description
|
|
char* path I Fully qualified file name to be read.
|
|
char** p_buf O Buffer that will contain the contents of
|
|
the file 'path'.
|
|
size_t* p_bufsiz O Size of the file buffer in bytes.
|
|
|
|
LOCAL DATA FILES
|
|
|
|
RETURNS
|
|
0 on success
|
|
-1 on failure
|
|
|
|
ERRORS REPORTED
|
|
|
|
|
|
---------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
static int buffer_file(char *path, char **p_buf, size_t *p_bufsiz)
|
|
{
|
|
const char FUNCNAME[] = "buffer_file";
|
|
int fd;
|
|
struct stat stbuf;
|
|
|
|
ENTER4;
|
|
|
|
if ((fd = open(path, O_RDONLY)) < 0) {
|
|
sprintf (statbuf, "Failed open file %s, %s", path, strerror(errno));
|
|
RETURN4(-1);
|
|
}
|
|
|
|
if (fstat(fd, &stbuf)) {
|
|
sprintf (statbuf, "Failed stat file %s, %s", path, strerror(errno));
|
|
RETURN4(-1);
|
|
}
|
|
|
|
*p_bufsiz = stbuf.st_size;
|
|
|
|
if (!(*p_buf = malloc(*p_bufsiz + 1))) {
|
|
sprintf (statbuf, "Failed malloc %d bytes", (int) stbuf.st_size);
|
|
RETURN4(-1);
|
|
}
|
|
|
|
if (read(fd, *p_buf, *p_bufsiz) < 0) {
|
|
sprintf(statbuf, "Failed to read %d bytes from %s, %s", (int) stbuf.st_size, path, strerror(errno));
|
|
close(fd);
|
|
free(*p_buf);
|
|
*p_buf = NULL;
|
|
RETURN4(-1);
|
|
}
|
|
|
|
*(*p_buf + *p_bufsiz) = '\0';
|
|
|
|
close(fd);
|
|
RETURN4(0);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------------------------------
|
|
|
|
FUNCTION NAME
|
|
hhmmToUtime
|
|
|
|
FUNCTION DESCRIPTION
|
|
Reads a date/time string formatted as "mm/dd[/yyyy]:HHMM and returns it as a Unix time value.
|
|
|
|
PARAMETERS
|
|
Type Name I/O Description
|
|
char* intime I Formatted date/time string.
|
|
|
|
LOCAL DATA FILES
|
|
|
|
RETURNS
|
|
Unix date value on success.
|
|
-1 on failure
|
|
|
|
ERRORS REPORTED
|
|
|
|
|
|
---------------------------------------------------------------------------------------------- */
|
|
|
|
static long hhmmToUtime(char *intime)
|
|
{
|
|
struct tm *p_tm;
|
|
time_t now;
|
|
char *mmddyyyy;
|
|
char *hhmm;
|
|
|
|
time(&now);
|
|
p_tm = localtime(&now);
|
|
|
|
if (!(mmddyyyy = strtok(intime, ":"))) {
|
|
return -1;
|
|
}
|
|
|
|
if ((hhmm = strtok(NULL, ":"))) {
|
|
/* looks like mm/dd[/yyyy]:HHMM */
|
|
if (sscanf(mmddyyyy, "%d/%d/%d", &p_tm->tm_mon, &p_tm->tm_mday, &p_tm->tm_year) < 2) {
|
|
return -1;
|
|
}
|
|
p_tm->tm_mon -= 1; /* tm month starts at zero */
|
|
if (p_tm->tm_year >= 1900) {
|
|
p_tm->tm_year -= 1900;
|
|
}
|
|
}
|
|
else {
|
|
/* looks like HHMM */
|
|
hhmm = mmddyyyy;
|
|
}
|
|
if (sscanf(hhmm, "%2d%2d",
|
|
&p_tm->tm_hour, &p_tm->tm_min) != 2) {
|
|
return -1;
|
|
}
|
|
|
|
return(mktime(p_tm));
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------------------------------
|
|
|
|
FUNCTION NAME
|
|
get_message_type
|
|
|
|
FUNCTION DESCRIPTION
|
|
Gets the message type value from the Java message object.
|
|
Finds the "type" field ID and object, then gets the value as an int.
|
|
|
|
PARAMETERS
|
|
Type Name I/O Description
|
|
JNIEnv* env I Pointer to the JVM environment.
|
|
jobject obj I The MhsMessage object containing the message.
|
|
jclass msg_class I The MhsMessage object's class.
|
|
int* type O Pointer to the type integer used for output to the caller.
|
|
|
|
LOCAL DATA FILES
|
|
|
|
RETURNS
|
|
0 on success
|
|
-1 on Failure. Also throws a MhsSubmitMessage exception back to the JVM.
|
|
|
|
ERRORS REPORTED
|
|
|
|
---------------------------------------------------------------------------------------------- */
|
|
|
|
int get_message_type(JNIEnv *env, jobject obj, jclass msg_class, int *type) {
|
|
|
|
jfieldID type_fid;
|
|
jmethodID type_value_mid;
|
|
jobject type_obj;
|
|
jclass type_class;
|
|
jmethodID type_text_mid;
|
|
jstring jtype_text;
|
|
char *type_text;
|
|
char buf[200];
|
|
|
|
sprintf(buf, "L%s/MhsMessageType;", PACKAGE_CLASS);
|
|
if ((type_fid = (*env)->GetFieldID(env, msg_class, "type", buf)) == NULL) {
|
|
return(0);
|
|
}
|
|
|
|
if ((type_obj = (*env)->GetObjectField(env, obj, type_fid)) == NULL) {
|
|
sprintf (statbuf, "Error in call to (*env)->GetObjectField(env, obj, type_fid)\n");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return(0);
|
|
}
|
|
|
|
type_class = (*env)->GetObjectClass(env, type_obj);
|
|
type_value_mid = (*env)->GetMethodID(env, type_class, "value", "()I");
|
|
*type = (*env)->CallIntMethod(env, type_obj, type_value_mid);
|
|
type_text_mid = (*env)->GetMethodID(env, type_class, "text", "()Ljava/lang/String;");
|
|
jtype_text = (*env)->CallObjectMethod(env, type_obj, type_text_mid);
|
|
type_text = (char *) (*env)->GetStringUTFChars(env, jtype_text, NULL);
|
|
if (show_trace) printf ("Type: (%d) %s\n", *type, type_text);
|
|
(*env)->ReleaseStringUTFChars(env, jtype_text, type_text);
|
|
return(1);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------------------------------
|
|
|
|
FUNCTION NAME
|
|
set_msg_addressees
|
|
|
|
FUNCTION DESCRIPTION
|
|
Gets the message addressees from the Java message object and adds them to the C message
|
|
object.
|
|
|
|
PARAMETERS
|
|
Type Name I/O Description
|
|
MsgObject the_msg O Pointer to the message object.
|
|
JNIEnv* env I Pointer to the JVM environment.
|
|
jobject obj I The MhsMessage object containing the message.
|
|
jclass msg_class I The MhsMessage object's class.
|
|
|
|
LOCAL DATA FILES
|
|
|
|
RETURNS
|
|
0 on success
|
|
-1 on Failure. Also throws a MhsSubmitMessage exception back to the JVM.
|
|
|
|
ERRORS REPORTED
|
|
|
|
---------------------------------------------------------------------------------------------- */
|
|
|
|
int set_msg_addressees(MsgObject the_msg, JNIEnv *env, jobject obj, jclass msg_class) {
|
|
|
|
jfieldID addresslist_fid;
|
|
jobject addresslist_obj;
|
|
jclass addresslist_class;
|
|
jmethodID addresslist_getCount_mid;
|
|
jmethodID addresslist_get_mid;
|
|
jobject addressee_obj;
|
|
jclass addressee_class;
|
|
jmethodID address_getAddress_mid = NULL;
|
|
jmethodID address_isAckRequired_mid = NULL;
|
|
jstring jaddressee;
|
|
char *addressee;
|
|
int ack_needed;
|
|
int addressee_count;
|
|
int i;
|
|
int first_time = TRUE;
|
|
char buf[200];
|
|
|
|
sprintf(buf, "L%s/AddresseeList;", PACKAGE_CLASS);
|
|
if ((addresslist_fid = (*env)->GetFieldID(env, msg_class, "addressees", buf)) == NULL) {
|
|
strcpy(statbuf, "Could not get fieldID for addressees");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return(0);
|
|
}
|
|
|
|
if ((addresslist_obj = (*env)->GetObjectField(env, obj, addresslist_fid)) == NULL) {
|
|
strcpy(statbuf, "Could not get objectID for addressees");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return(0);
|
|
}
|
|
|
|
addresslist_class = (*env)->GetObjectClass(env, addresslist_obj);
|
|
addresslist_getCount_mid = (*env)->GetMethodID(env, addresslist_class, "getCount", "()I");
|
|
addressee_count = (*env)->CallIntMethod(env, addresslist_obj, addresslist_getCount_mid);
|
|
if (show_trace) printf ("Addresses: %d\n", addressee_count);
|
|
|
|
sprintf(buf, "(I)L%s/Addressee;", PACKAGE_CLASS);
|
|
addresslist_get_mid = (*env)->GetMethodID(env, addresslist_class, "get", buf);
|
|
for (i = 0; i < addressee_count; i++) {
|
|
addressee_obj = (*env)->CallObjectMethod(env, addresslist_obj, addresslist_get_mid, i);
|
|
if (first_time) {
|
|
addressee_class = (*env)->GetObjectClass(env, addressee_obj);
|
|
address_getAddress_mid = (*env)->GetMethodID(env, addressee_class, "getAddress", "()Ljava/lang/String;");
|
|
address_isAckRequired_mid = (*env)->GetMethodID(env, addressee_class, "isAckRequired", "()Z");
|
|
first_time = FALSE;
|
|
}
|
|
jaddressee = (*env)->CallObjectMethod(env, addressee_obj, address_getAddress_mid);
|
|
addressee = (char *) (*env)->GetStringUTFChars(env, jaddressee, NULL);
|
|
ack_needed = (*env)->CallBooleanMethod(env, addressee_obj, address_isAckRequired_mid);
|
|
if (show_trace) printf ("Addressee: %s %s\n", addressee, ack_needed ? "(A)" : "");
|
|
|
|
if (coDDM_addAddressee(the_msg, addressee, ack_needed) < 0) {
|
|
coDDM_destroyMsg(&the_msg);
|
|
sprintf (statbuf, "Failed addAddressee '%s'\n", addressee);
|
|
throw_submit_exception(env, FAIL_ADDR, statbuf);
|
|
return(0);
|
|
}
|
|
(*env)->ReleaseStringUTFChars(env, jaddressee, addressee);
|
|
}
|
|
|
|
return(1);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------------------------------
|
|
|
|
FUNCTION NAME
|
|
get_priority
|
|
|
|
FUNCTION DESCRIPTION
|
|
Gets the message priority value from the Java message object.
|
|
Finds the "priority" field ID and object, then gets the value as an int.
|
|
|
|
PARAMETERS
|
|
Type Name I/O Description
|
|
JNIEnv* env I Pointer to the JVM environment.
|
|
jobject obj I The MhsMessage object containing the message.
|
|
jclass msg_class I The MhsMessage object's class.
|
|
int* type O Pointer to the priority integer used for output to the caller.
|
|
|
|
LOCAL DATA FILES
|
|
|
|
RETURNS
|
|
0 on success
|
|
-1 on Failure. Also throws a MhsSubmitMessage exception back to the JVM.
|
|
|
|
ERRORS REPORTED
|
|
|
|
---------------------------------------------------------------------------------------------- */
|
|
|
|
int get_priority(JNIEnv *env, jobject obj, jclass msg_class, int *priority) {
|
|
|
|
jfieldID priority_fid;
|
|
jmethodID priority_value_methodID;
|
|
jobject priority_obj;
|
|
jclass priority_class;
|
|
char buf[200];
|
|
|
|
sprintf(buf, "L%s/MhsMessagePriority;", PACKAGE_CLASS);
|
|
if ((priority_fid = (*env)->GetFieldID(env, msg_class, "priority", buf)) == NULL) {
|
|
return(0);
|
|
}
|
|
|
|
if ((priority_obj = (*env)->GetObjectField(env, obj, priority_fid)) == NULL) {
|
|
fprintf (stderr, "Error in call to (*env)->GetObjectField(env, msg_class, priority_fid)\n");
|
|
return(0);
|
|
}
|
|
|
|
priority_class = (*env)->GetObjectClass(env, priority_obj);
|
|
priority_value_methodID = (*env)->GetMethodID(env, priority_class, "value", "()I");
|
|
*priority = (*env)->CallIntMethod(env, priority_obj, priority_value_methodID);
|
|
|
|
return(1);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------------------------------
|
|
|
|
FUNCTION NAME
|
|
set_enclosures
|
|
|
|
FUNCTION DESCRIPTION
|
|
Gets the message enclosures from the Java message object and adds them to the C message
|
|
object.
|
|
|
|
PARAMETERS
|
|
Type Name I/O Description
|
|
MsgObject the_msg O Pointer to the message object.
|
|
JNIEnv* env I Pointer to the JVM environment.
|
|
jobject obj I The MhsMessage object containing the message.
|
|
jclass msg_class I The MhsMessage object's class.
|
|
|
|
LOCAL DATA FILES
|
|
|
|
RETURNS
|
|
0 on success
|
|
-1 on Failure. Also throws a MhsSubmitMessage exception back to the JVM.
|
|
|
|
ERRORS REPORTED
|
|
|
|
---------------------------------------------------------------------------------------------- */
|
|
|
|
int set_enclosures(MsgObject the_msg, JNIEnv *env, jobject obj, jclass msg_class) {
|
|
jfieldID enclist_fid;
|
|
jobject enclist_obj;
|
|
jclass enclist_class;
|
|
jmethodID enclist_getCount_mid;
|
|
jmethodID enclist_get_mid;
|
|
jobject enc_obj;
|
|
jclass enc_class;
|
|
jmethodID enc_getName_mid = NULL;
|
|
jstring jenc;
|
|
char *enc;
|
|
int enc_count;
|
|
char *prodid;
|
|
int i;
|
|
char first_time = TRUE;
|
|
char buf[200];
|
|
|
|
sprintf(buf, "L%s/EnclosureList;", PACKAGE_CLASS);
|
|
if ((enclist_fid = (*env)->GetFieldID(env, msg_class, "enclosures", buf)) == NULL) {
|
|
strcpy(statbuf, "Could not get fieldID for enclosures");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return(0);
|
|
}
|
|
|
|
if ((enclist_obj = (*env)->GetObjectField(env, obj, enclist_fid)) == NULL) {
|
|
strcpy(statbuf, "Could not get objectID for enclosures");
|
|
throw_submit_exception(env, FAIL_JNI, statbuf);
|
|
return(0);
|
|
}
|
|
|
|
enclist_class = (*env)->GetObjectClass(env, enclist_obj);
|
|
enclist_getCount_mid = (*env)->GetMethodID(env, enclist_class, "getCount", "()I");
|
|
enc_count = (*env)->CallIntMethod(env, enclist_obj, enclist_getCount_mid);
|
|
if (show_trace) printf ("Enclosure count: %d\n", enc_count);
|
|
|
|
/* Get the Enclosures --------------------------------------------------------------------------- */
|
|
sprintf(buf, "(I)L%s/Enclosure;", PACKAGE_CLASS);
|
|
enclist_get_mid = (*env)->GetMethodID(env, enclist_class, "get", buf);
|
|
prodid = the_msg->prodid;
|
|
for (i = 0; i < enc_count; i++) {
|
|
enc_obj = (*env)->CallObjectMethod(env, enclist_obj, enclist_get_mid, i);
|
|
if (first_time) {
|
|
enc_class = (*env)->GetObjectClass(env, enc_obj);
|
|
enc_getName_mid = (*env)->GetMethodID(env, enc_class, "getEnclosureName", "()Ljava/lang/String;");
|
|
first_time = FALSE;
|
|
}
|
|
jenc = (*env)->CallObjectMethod(env, enc_obj, enc_getName_mid);
|
|
enc = (char *) (*env)->GetStringUTFChars(env, jenc, NULL);
|
|
if (show_trace) printf ("Enclosure: %s\n", enc);
|
|
|
|
if (coDDM_addEnclosureProd(the_msg, enc, prodid) < 0) {
|
|
sprintf (statbuf, "Failed addEnclosure '%s'\n", enc);
|
|
coDDM_destroyMsg(&the_msg);
|
|
throw_submit_exception(env, FAIL_ENCLOSE, statbuf);
|
|
return(0);
|
|
}
|
|
prodid = NULL; /* only put the prodid on the first enclosure */
|
|
(*env)->ReleaseStringUTFChars(env, jenc, enc);
|
|
}
|
|
|
|
return(1);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------------------------------
|
|
|
|
FUNCTION NAME
|
|
get_boolean_field
|
|
|
|
FUNCTION DESCRIPTION
|
|
Generic function to get the value of a specified boolean field from a Java object
|
|
|
|
PARAMETERS
|
|
Type Name I/O Description
|
|
JNIEnv* env I Pointer to the JVM environment.
|
|
jobject obj I The parent object containing the named field.
|
|
jclass msg_class I The parent class containing the named field.
|
|
char* field_name I Name of the Java field name as a string.
|
|
int* bool_ptr O Pointer to the variable that is to contain the boolean value.
|
|
|
|
LOCAL DATA FILES
|
|
|
|
RETURNS
|
|
0 on success
|
|
-1 on Failure.
|
|
|
|
ERRORS REPORTED
|
|
|
|
---------------------------------------------------------------------------------------------- */
|
|
|
|
int get_boolean_field(JNIEnv *env, jobject obj, jclass msg_class, char *field_name, int *bool_ptr) {
|
|
jfieldID fid;
|
|
|
|
if ((fid = (*env)->GetFieldID(env, msg_class, field_name, "Z")) == NULL) {
|
|
return(0);
|
|
}
|
|
|
|
*bool_ptr = (*env)->GetBooleanField(env, obj, fid);
|
|
return(1);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------------------------------
|
|
|
|
FUNCTION NAME
|
|
get_int_field
|
|
|
|
FUNCTION DESCRIPTION
|
|
Generic function to get the value of a specified int field from a Java object
|
|
|
|
PARAMETERS
|
|
Type Name I/O Description
|
|
JNIEnv* env I Pointer to the JVM environment.
|
|
jobject obj I The parent object containing the named field.
|
|
jclass msg_class I The parent class containing the named field.
|
|
char* field_name I Name of the Java field name as a string.
|
|
int* int_ptr O Pointer to the variable that is to contain the integer value.
|
|
|
|
LOCAL DATA FILES
|
|
|
|
RETURNS
|
|
0 on success
|
|
-1 on Failure.
|
|
|
|
ERRORS REPORTED
|
|
|
|
---------------------------------------------------------------------------------------------- */
|
|
|
|
int get_int_field(JNIEnv *env, jobject obj, jclass msg_class, char *field_name, int *int_ptr) {
|
|
jfieldID fid;
|
|
|
|
if ((fid = (*env)->GetFieldID(env, msg_class, field_name, "I")) == NULL) {
|
|
return(0);
|
|
}
|
|
|
|
*int_ptr = (*env)->GetIntField(env, obj, fid);
|
|
return(1);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------------------------------
|
|
|
|
FUNCTION NAME
|
|
get_string_field
|
|
|
|
FUNCTION DESCRIPTION
|
|
Generic function to get the value of a specified String field from a Java object. The
|
|
resultant C string is malloc'd so it must eventually be free'd by the caller.
|
|
|
|
PARAMETERS
|
|
Type Name I/O Description
|
|
JNIEnv* env I Pointer to the JVM environment.
|
|
jobject obj I The parent object containing the named field.
|
|
jclass msg_class I The parent class containing the named field.
|
|
char* field_name I Name of the Java field name as a string.
|
|
char** str_ptr O Pointer to the char* variable for the specified String.
|
|
|
|
LOCAL DATA FILES
|
|
|
|
RETURNS
|
|
0 on success
|
|
-1 on Failure.
|
|
|
|
ERRORS REPORTED
|
|
|
|
---------------------------------------------------------------------------------------------- */
|
|
|
|
int get_string_field(JNIEnv *env, jobject obj, jclass msg_class, char *field_name, char **str_ptr) {
|
|
jfieldID fid;
|
|
jstring jstr;
|
|
const char *str;
|
|
|
|
if ((fid = (*env)->GetFieldID(env, msg_class, field_name, "Ljava/lang/String;")) == NULL) {
|
|
return(0);
|
|
}
|
|
|
|
jstr = (*env)->GetObjectField(env, obj, fid);
|
|
str = (*env)->GetStringUTFChars(env, jstr, NULL);
|
|
if (str == NULL) {
|
|
return(0);
|
|
}
|
|
|
|
if (!(*str_ptr = malloc(strlen(str)+1))) {
|
|
(*env)->ReleaseStringUTFChars(env, jstr, str);
|
|
return(0);
|
|
}
|
|
|
|
strcpy(*str_ptr, str);
|
|
(*env)->ReleaseStringUTFChars(env, jstr, str);
|
|
return(1);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------------------------------
|
|
|
|
FUNCTION NAME
|
|
throw_submit_exception
|
|
|
|
FUNCTION DESCRIPTION
|
|
Raises an MhsSubmitException in the JVM. The exception will not actually get thrown until
|
|
the JNI code returns control to the JVM.
|
|
|
|
PARAMETERS
|
|
Type Name I/O Description
|
|
JNIEnv* env I Pointer to the JVM environment.
|
|
char* result_code I String containing MHS result code (Not currently used.)
|
|
char* result_text I String containing detailed submission result.
|
|
|
|
LOCAL DATA FILES
|
|
|
|
RETURNS
|
|
0 on success
|
|
-1 on Failure.
|
|
|
|
ERRORS REPORTED
|
|
|
|
---------------------------------------------------------------------------------------------- */
|
|
|
|
void throw_submit_exception(JNIEnv *env, char *result_code, char *result_text) {
|
|
(*env)->ThrowNew(env, newExcCls, result_text);
|
|
}
|