| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223 | /** * $Id$ * * Copyright (C) 2013 Konstantin Mosesov * * This file is part of Kamailio, a free SIP server. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * * * This file 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 for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * */#include "../../str.h"#include "../../sr_module.h"#include "../../ip_addr.h"#include "../../flags.h"#include <jni.h>#include "global.h"#include "utils.h"#include "java_mod.h"#include "java_iface.h"#include "java_support.h"#include "java_msgobj.h"#include "java_native_methods.h"#include "java_sig_parser.h"//// native methods /////*    java: native void LM_XXXXXX(Params XXXX);    c: JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1XXXXXX(JNIEnv *jenv, jobject this, Params XXXX)    Why (for example) Java_Kamailio_LM_1ERR but not Java_Kamailio_LM_ERR?     See explaination here: http://qscribble.blogspot.ca/2012/04/underscores-in-jni-method-names.html    Also, from here: http://192.9.162.55/docs/books/jni/html/design.html    The JNI adopts a simple name-encoding scheme to ensure that all Unicode characters     translate into valid C function names. The underscore ("_") character separates the     components of fully qualified class names. Because a name or type descriptor never     begins with a number, we can use _0, ..., _9 for escape sequences, as illustrated below:    +-------------------+------------------------------------+    |  Escape Sequence  |            Denotes                 |    +-------------------+------------------------------------+    |	_0XXXX          |  a Unicode character XXXX          |    |	_1              |  the character "_"                 |    |	_2              |  the character ";" in descriptors  |    |	_3              |  the character "[" in descriptors  |    +-------------------+------------------------------------+*//*    *** Java API ***    Package: org.siprouter    Class: NativeMethods    Method: LM_ERR(Ljava/lang/String;)V    Prototype: public static native void LM_ERR(String s);*/JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1ERR(JNIEnv *jenv, jobject this, jstring js){    const char *s;    jboolean iscopy;    s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);    if ((*jenv)->ExceptionCheck(jenv))    {	handle_exception();	return;    }    LM_ERR("%s", s == NULL ? "null\n" : s);    (*jenv)->ReleaseStringUTFChars(jenv, js, s);}/*    *** Java API ***    Package: org.siprouter    Class: NativeMethods    Method: LM_WARN(Ljava/lang/String;)V    Prototype: public static native void LM_WARN(String s);*/JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1WARN(JNIEnv *jenv, jobject this, jstring js){    const char *s;    jboolean iscopy;    s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);    if ((*jenv)->ExceptionCheck(jenv))    {	handle_exception();	return;    }    LM_WARN("%s", s == NULL ? "null\n" : s);    (*jenv)->ReleaseStringUTFChars(jenv, js, s);}/*    *** Java API ***    Package: org.siprouter    Class: NativeMethods    Method: LM_NOTICE(Ljava/lang/String;)V    Prototype: public static native void LM_NOTICE(String s);*/JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1NOTICE(JNIEnv *jenv, jobject this, jstring js){    const char *s;    jboolean iscopy;    s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);    if ((*jenv)->ExceptionCheck(jenv))    {	handle_exception();	return;    }    LM_NOTICE("%s", s == NULL ? "null\n" : s);    (*jenv)->ReleaseStringUTFChars(jenv, js, s);}/*    *** Java API ***    Package: org.siprouter    Class: NativeMethods    Method: LM_INFO(Ljava/lang/String;)V    Prototype: public static native void LM_INFO(String s);*/JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1INFO(JNIEnv *jenv, jobject this, jstring js){    const char *s;    jboolean iscopy;    s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);    if ((*jenv)->ExceptionCheck(jenv))    {	handle_exception();	return;    }    LM_INFO("%s", s == NULL ? "null\n" : s);    (*jenv)->ReleaseStringUTFChars(jenv, js, s);}/*    *** Java API ***    Package: org.siprouter    Class: NativeMethods    Method: LM_DBG(Ljava/lang/String;)V    Prototype: public static native void LM_DBG(String s);*/JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1DBG(JNIEnv *jenv, jobject this, jstring js){    const char *s;    jboolean iscopy;    s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);    if ((*jenv)->ExceptionCheck(jenv))    {	handle_exception();	return;    }    LM_DBG("%s", s == NULL ? "null\n" : s);    (*jenv)->ReleaseStringUTFChars(jenv, js, s);}/*    *** Java API ***    Package: org.siprouter    Class: NativeMethods    Method: LM_CRIT(Ljava/lang/String;)V    Prototype: public static native void LM_CRIT(String s);*/JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1CRIT(JNIEnv *jenv, jobject this, jstring js){    const char *s;    jboolean iscopy;    s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);    if ((*jenv)->ExceptionCheck(jenv))    {	handle_exception();	return;    }    LM_CRIT("%s", s == NULL ? "null\n" : s);    (*jenv)->ReleaseStringUTFChars(jenv, js, s);}#ifdef LM_ALERT/*    *** Java API ***    Package: org.siprouter    Class: NativeMethods    Method: LM_ALERT(Ljava/lang/String;)V    Prototype: public static native void LM_ALERT(String s);*/JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1ALERT(JNIEnv *jenv, jobject this, jstring js){    const char *s;    jboolean iscopy;    s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);    if ((*jenv)->ExceptionCheck(jenv))    {	handle_exception();	return;    }    LM_ALERT("%s", s == NULL ? "null\n" : s);    (*jenv)->ReleaseStringUTFChars(jenv, js, s);}#endif/*    *** Java API ***    Package: org.siprouter    Class: NativeMethods    Method: LM_GEN2(ILjava/lang/String;)V    Prototype: public static native void LM_GEN1(int logLevel, String s);*/JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1GEN1(JNIEnv *jenv, jobject this, jint ll, jstring js){    const char *s;    jboolean iscopy;    s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);    if ((*jenv)->ExceptionCheck(jenv))    {	handle_exception();	return;    }    LM_GEN1((int)ll, "%s", s == NULL ? "null\n" : s);    (*jenv)->ReleaseStringUTFChars(jenv, js, s);}/*    *** Java API ***    Package: org.siprouter    Class: NativeMethods    Method: LM_GEN2(IILjava/lang/String;)V    Prototype: public static native void LM_GEN2(int logLevel, int logFacility, String s);*/JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1GEN2(JNIEnv *jenv, jobject this, jint ll, jint lf, jstring js){    const char *s;    jboolean iscopy;    s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);    if ((*jenv)->ExceptionCheck(jenv))    {	handle_exception();	return;    }    LM_GEN2((int)ll, (int)lf, "%s", s == NULL ? "null\n" : s);    (*jenv)->ReleaseStringUTFChars(jenv, js, s);}/*    *** Java API ***    Package: org.siprouter    Class: NativeMethods    Method: KamExec(Ljava/lang/String;[Ljava/lang/String;)I    Prototype: public static native int KamExec(String fname, String... params);*/JNIEXPORT jint JNICALL Java_org_siprouter_NativeMethods_KamExec(JNIEnv *jenv, jobject this, jstring jfname, jobjectArray strArrParams){    int retval;    char *fname;    int argc;    jsize pc;    int i;    char *argv[MAX_ACTIONS];    jboolean is_copy;    jstring strp;    char *strc;    if (jfname == NULL)    {	LM_ERR("app_java: KamExec() required at least 1 argument (function name)\n");	return -1;    }    fname = (char *)(*jenv)->GetStringUTFChars(jenv, jfname, &is_copy);    if ((*jenv)->ExceptionCheck(jenv))    {        handle_exception();        return -1;    }    memset(argv, 0, MAX_ACTIONS * sizeof(char *));    argc = 0;    pc = (*jenv)->GetArrayLength(jenv, strArrParams);    if (pc >= 6)    {	pc = 6;    }    for (i=0; i<pc; i++)    {	strp = (jstring)(*jenv)->GetObjectArrayElement(jenv, strArrParams, i);	if ((*jenv)->ExceptionCheck(jenv))	{    	    handle_exception();    	    return -1;	}	strc = (char *)(*jenv)->GetStringUTFChars(jenv, strp, &is_copy);	if ((*jenv)->ExceptionCheck(jenv))	{    	    handle_exception();    	    return -1;	}	if (strc)	{	    argv[argc++] = strc;	}    }        retval = KamExec(jenv, fname, argc, argv);    (*jenv)->ReleaseStringUTFChars(jenv, jfname, fname);    return (jint)retval;}int KamExec(JNIEnv *jenv, char *fname, int argc, char **argv){    sr31_cmd_export_t *fexport;    unsigned mod_ver;    int rval;    int mod_type;    struct action *act;    struct run_act_ctx ra_ctx;    int i;    if (!msg)	return -1;    fexport = find_export_record(fname, argc, 0, &mod_ver);    if (!fexport)    {	LM_ERR("app_java: KamExec(): '%s' - no such function\n", fname);        return -1;    }    /* check fixups */    if (force_cmd_exec == 0 && fexport->fixup != NULL && fexport->free_fixup == NULL)    {        LM_ERR("app_java: KamExec(): function '%s' has fixup - cannot be used\n", fname);	return -1;    }    switch(fexport->param_no)    {    	case 0:			mod_type = MODULE0_T;	break;	case 1:			mod_type = MODULE1_T;	break;	case 2:			mod_type = MODULE2_T;	break;	case 3:			mod_type = MODULE3_T;	break;	case 4:			mod_type = MODULE4_T;	break;	case 5:			mod_type = MODULE5_T;	break;	case 6:			mod_type = MODULE6_T;	break;	case VAR_PARAM_NO:	mod_type = MODULEX_T;	break;	default:		LM_ERR("app_java: KamExec(): unknown/bad definition for function '%s' (%d params)\n", fname, fexport->param_no);		return -1;    }    act = mk_action(mod_type, (argc+2),			/* number of (type, value) pairs */                	MODEXP_ST, fexport,		/* function */                	NUMBER_ST, argc,		/* parameter number */			STRING_ST, argv[0],		/* param. 1 */			STRING_ST, argv[1],		/* param. 2 */			STRING_ST, argv[2],		/* param. 3 */			STRING_ST, argv[3],		/* param. 4 */			STRING_ST, argv[4],		/* param. 5 */			STRING_ST, argv[5]		/* param. 6 */                   );    if (!act)    {	LM_ERR("app_java: KamExec(): action structure couldn't be created\n");	return -1;    }    /* handle fixups */    if (fexport->fixup)    {        if (argc == 0)	{            rval = fexport->fixup(0, 0);            if (rval < 0)	    {		LM_ERR("app_java: KamExec(): (no params) Error in fixup (0) for '%s'\n", fname);                return -1;            }        }	else	{	    for (i=0; i<=argc; i++)	    {		if (act->val[i+2].u.data != 0x0)		{        	    rval = fexport->fixup(&(act->val[i+2].u.data), i+1);        	    if (rval < 0)		    {			LM_ERR("app_java: KamExec(): (params: %d) Error in fixup (%d) for '%s'\n", argc, i+1, fname);            		return -1;        	    }        	    act->val[i+2].type = MODFIXUP_ST;		}	    }        }    }    init_run_actions_ctx(&ra_ctx);    rval = do_action(&ra_ctx, act, msg);    /* free fixups */    if (fexport->free_fixup)    {	for (i=0; i<=argc; i++)	{	    if ((act->val[i+2].type == MODFIXUP_ST) && (act->val[i+2].u.data))	    {		fexport->free_fixup(&(act->val[i+2].u.data), i+1);	    }	}    }    pkg_free(act);    return rval;}/*    *** Java API ***    Package: org.siprouter    Class: SipMsg    Method: ParseSipMsg()Lorg/siprouter/SipMsg;    Prototype: public static native org.siprouter.SipMsg ParseSipMsg();*/JNIEXPORT jobject JNICALL Java_org_siprouter_SipMsg_ParseSipMsg(JNIEnv *jenv, jobject this){    if (!msg)	return NULL;    return fill_sipmsg_object(jenv, msg);}/*    *** Java API ***    Package: org.siprouter    Class: SipMsg    Method: getMsgType()Ljava/org/String;    Prototype: public static native String getMsgType();*/JNIEXPORT jstring JNICALL Java_org_siprouter_SipMsg_getMsgType(JNIEnv *jenv, jobject this){    char *cs;    jstring js;    if (!msg)	return NULL;    switch ((msg->first_line).type)    {        case SIP_REQUEST:            cs = "SIP_REQUEST";            break;        case SIP_REPLY:            cs = "SIP_REPLY";            break;        default:	    cs = "SIP_INVALID";	    break;    }    js = (*jenv)->NewStringUTF(jenv, cs);    if ((*jenv)->ExceptionCheck(jenv))    {        handle_exception();        return NULL;    }    return js;}/*    *** Java API ***    Package: org.siprouter    Class: SipMsg    Method: getStatus()Ljava/org/String;    Prototype: public static native String getStatus();*/JNIEXPORT jstring JNICALL Java_org_siprouter_SipMsg_getStatus(JNIEnv *jenv, jobject this){    str *cs;    jstring js;    if (!msg)	return NULL;    if ((msg->first_line).type != SIP_REQUEST)    {	LM_ERR("app_java: getStatus(): Unable to fetch status. Error: Not a request message - no method available.\n");        return NULL;    }    cs = &((msg->first_line).u.request.method);    js = (*jenv)->NewStringUTF(jenv, (cs && cs->s && cs->len > 0) ? cs->s : "");    if ((*jenv)->ExceptionCheck(jenv))    {        handle_exception();        return NULL;    }    return js;}/*    *** Java API ***    Package: org.siprouter    Class: SipMsg    Method: getRURI()Ljava/org/String;    Prototype: public static native String getRURI();*/JNIEXPORT jstring JNICALL Java_org_siprouter_SipMsg_getRURI(JNIEnv *jenv, jobject this){    str *cs;    jstring js;    if (!msg)	return NULL;    if ((msg->first_line).type != SIP_REQUEST)    {	LM_ERR("app_java: getRURI(): Unable to fetch ruri. Error: Not a request message - no method available.\n");        return NULL;    }    cs = &((msg->first_line).u.request.uri);    js = (*jenv)->NewStringUTF(jenv, (cs && cs->s && cs->len > 0) ? cs->s : "");    if ((*jenv)->ExceptionCheck(jenv))    {        handle_exception();        return NULL;    }    return js;}/*    *** Java API ***    Package: org.siprouter    Class: SipMsg    Method: getSrcAddress()Lorg/siprouter/IPPair;    Prototype: public static native org.siprouter.IPPair getSrcAddress();*/JNIEXPORT jobject JNICALL Java_org_siprouter_SipMsg_getSrcAddress(JNIEnv *jenv, jobject this){    jclass ippair_cls;    jmethodID ippair_cls_id;    jobject ippair_cls_instance;    char *ip;    jstring jip;    int port;    if (!msg)	return NULL;    ippair_cls = (*jenv)->FindClass(jenv, "org/siprouter/IPPair");    if ((*jenv)->ExceptionCheck(jenv))    {        handle_exception();        return NULL;    }    ippair_cls_id = (*jenv)->GetMethodID(jenv, ippair_cls, "<init>", "(Ljava/lang/String;I)V");    if (!ippair_cls_id || (*jenv)->ExceptionCheck(jenv))    {        handle_exception();        return NULL;    }    ip = ip_addr2a(&msg->rcv.src_ip);    if (!ip)    {	LM_ERR("app_java: getSrcAddress(): Unable to fetch src ip address.\n");	return NULL;    }    jip = (*jenv)->NewStringUTF(jenv, ip);    if ((*jenv)->ExceptionCheck(jenv))    {        handle_exception();        return NULL;    }    port = msg->rcv.src_port;    if (port == 0x0)    {	LM_ERR("app_java: getSrcAddress(): Unable to fetch src port.\n");	return NULL;    }    // calling constructor    ippair_cls_instance = (*jenv)->NewObject(jenv, ippair_cls, ippair_cls_id, (jstring)jip, (jint)port);    if (!ippair_cls_instance || (*jenv)->ExceptionCheck(jenv))    {        handle_exception();        return NULL;    }    return ippair_cls_instance;}/*    *** Java API ***    Package: org.siprouter    Class: SipMsg    Method: getDstAddress()Lorg/siprouter/IPPair;    Prototype: public static native org.siprouter.IPPair getDstAddress();*/JNIEXPORT jobject JNICALL Java_org_siprouter_SipMsg_getDstAddress(JNIEnv *jenv, jobject this){    jclass ippair_cls;    jmethodID ippair_cls_id;    jobject ippair_cls_instance;    char *ip;    jstring jip;    int port;    if (!msg)	return NULL;    ippair_cls = (*jenv)->FindClass(jenv, "org/siprouter/IPPair");    if ((*jenv)->ExceptionCheck(jenv))    {        handle_exception();        return NULL;    }    ippair_cls_id = (*jenv)->GetMethodID(jenv, ippair_cls, "<init>", "(Ljava/lang/String;I)V");    if (!ippair_cls_id || (*jenv)->ExceptionCheck(jenv))    {        handle_exception();        return NULL;    }    ip = ip_addr2a(&msg->rcv.dst_ip);    if (!ip)    {	LM_ERR("app_java: getDstAddress(): Unable to fetch src ip address.\n");	return NULL;    }    jip = (*jenv)->NewStringUTF(jenv, ip);    if ((*jenv)->ExceptionCheck(jenv))    {        handle_exception();        return NULL;    }    port = msg->rcv.dst_port;    if (port == 0x0)    {	LM_ERR("app_java: getDstAddress(): Unable to fetch src port.\n");	return NULL;    }    // calling constructor    ippair_cls_instance = (*jenv)->NewObject(jenv, ippair_cls, ippair_cls_id, (jstring)jip, (jint)port);    if (!ippair_cls_instance || (*jenv)->ExceptionCheck(jenv))    {        handle_exception();        return NULL;    }    return ippair_cls_instance;}/*    *** Java API ***    Package: org.siprouter    Class: SipMsg    Method: getBuffer()Ljava/org/String;    Prototype: public static native String getBuffer();*/JNIEXPORT jstring JNICALL Java_org_siprouter_SipMsg_getBuffer(JNIEnv *jenv, jobject this){    jstring js;    if (!msg)	return NULL;    if ((msg->first_line).type != SIP_REQUEST)    {	LM_ERR("app_java: getRURI(): Unable to fetch ruri. Error: Not a request message - no method available.\n");        return NULL;    }    js = (*jenv)->NewStringUTF(jenv, msg->buf ? msg->buf : "");    if ((*jenv)->ExceptionCheck(jenv))    {        handle_exception();        return NULL;    }    return js;}///// Core Functions //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*    *** Java API ***    Package: org.siprouter    Class: CoreMethods    Method: seturi(Ljava/org/String;)I    Prototype: public static native int seturi(String uri);*/JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_seturi(JNIEnv *jenv, jobject this, jstring juri){    return cf_seturi(jenv, this, juri, "seturi");}/*    *** Java API ***    Package: org.siprouter    Class: CoreMethods    Method: rewriteuri(Ljava/org/String;)I    Prototype: public static native int rewriteuri(String uri);*/JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_rewriteuri(JNIEnv *jenv, jobject this, jstring juri){    return cf_seturi(jenv, this, juri, "rewriteuri");}/* wrapped function */jint cf_seturi(JNIEnv *jenv, jobject this, jstring juri, char *fname){    struct action act;    struct run_act_ctx ra_ctx;    int retval;    jboolean is_copy;    char *curi;    if (!msg)    {	LM_ERR("app_java: %s: Can't process, msg=NULL\n", fname);	return -1;    }    curi = (char *)(*jenv)->GetStringUTFChars(jenv, juri, &is_copy);    if ((*jenv)->ExceptionCheck(jenv))    {	handle_exception();    	return -1;    }    memset(&act, 0, sizeof(act));    act.type = SET_URI_T;    act.val[0].type = STRING_ST;    act.val[0].u.str.s = curi;    act.val[0].u.str.len = strlen(curi);    init_run_actions_ctx(&ra_ctx);    retval = do_action(&ra_ctx, &act, msg);    (*jenv)->ReleaseStringUTFChars(jenv, juri, curi);    return (jint)retval;}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*    *** Java API ***    Package: org.siprouter    Class: CoreMethods    Method: add_local_rport()I    Prototype: public static native int add_local_rport();*/JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_add_1local_1rport(JNIEnv *jenv, jobject this){    struct action act;    struct run_act_ctx ra_ctx;    int retval;    if (!msg)    {	LM_ERR("app_java: add_local_rport: Can't process, msg=NULL\n");	return -1;    }    memset(&act, 0, sizeof(act));    act.type = ADD_LOCAL_RPORT_T;    init_run_actions_ctx(&ra_ctx);    retval = do_action(&ra_ctx, &act, msg);    return (jint)retval;}/*    *** Java API ***    Package: org.siprouter    Class: CoreMethods    Method: append_branch()I    Method(o): append_branch(Ljava/lang/String)I    Prototype: public static native int append_branch();    Prototype(o): public static native int append_branch(String branch);*/JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_append_1branch(JNIEnv *jenv, jobject this, jstring jbranch){    struct action act;    struct run_act_ctx ra_ctx;    int retval;    jboolean is_copy;    char *cbranch;    if (!msg)    {	LM_ERR("app_java: append_branch: Can't process, msg=NULL\n");	return -1;    }    memset(&act, 0, sizeof(act));    act.type = APPEND_BRANCH_T;    cbranch = NULL;    if (jbranch)    {	cbranch = (char *)(*jenv)->GetStringUTFChars(jenv, jbranch, &is_copy);	if ((*jenv)->ExceptionCheck(jenv))	{	    handle_exception();	    return -1;	}	act.val[0].type = STR_ST;	act.val[0].u.str.s = cbranch;	act.val[0].u.str.len = strlen(cbranch);    }    init_run_actions_ctx(&ra_ctx);    retval = do_action(&ra_ctx, &act, msg);    if (cbranch)    {	(*jenv)->ReleaseStringUTFChars(jenv, jbranch, cbranch);    }    return (jint)retval;}/*    *** Java API ***    Package: org.siprouter    Class: CoreMethods    Method: drop()I    Prototype: public static native int drop();    Returns:	0 if action -> end of list(e.g DROP)        > 0 to continue processing next actions	< 0 on error*/JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_drop(JNIEnv *jenv, jobject this){    struct action act;    struct run_act_ctx ra_ctx;    int retval;    if (!msg)    {	LM_ERR("app_java: drop: Can't process, msg=NULL\n");	return -1;    }    memset(&act, 0, sizeof(act));    act.type = DROP_T;    act.val[0].type = NUMBER_ST;    act.val[0].u.number = 0;    init_run_actions_ctx(&ra_ctx);    retval = do_action(&ra_ctx, &act, msg);    return (jint)retval;}/*    *** Java API ***    Package: org.siprouter    Class: CoreMethods    Method: force_rport()I    Prototype: public static native int force_rport();*/JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_force_1rport(JNIEnv *jenv, jobject this){    return cf_force_rport(jenv, this, "force_rport");}/*    *** Java API ***    Package: org.siprouter    Class: CoreMethods    Method: add_rport()I    Prototype: public static native int add_rport();*/JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_add_1rport(JNIEnv *jenv, jobject this){    return cf_force_rport(jenv, this, "add_rport");}/* wrapped function */jint cf_force_rport(JNIEnv *jenv, jobject this, char *fname){    struct action act;    struct run_act_ctx ra_ctx;    int retval;    if (!msg)    {	LM_ERR("app_java: %s: Can't process, msg=NULL\n", fname);	return -1;    }    memset(&act, 0, sizeof(act));    act.type = FORCE_RPORT_T;    init_run_actions_ctx(&ra_ctx);    retval = do_action(&ra_ctx, &act, msg);    return (jint)retval;}/*    *** Java API ***    Package: org.siprouter    Class: CoreMethods    Method: force_send_socket(Ljava/lang/String;I)I    Prototype: public static native int force_send_socket(String srchost, int srcport);*/JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_force_1send_1socket(JNIEnv *jenv, jobject this, jstring jsrchost, jint jsrcport){    struct action act;    struct run_act_ctx ra_ctx;    int retval;    jboolean is_copy;    struct socket_id *si;    struct name_lst *nl;    if (!msg)    {	LM_ERR("app_java: force_send_socket: Can't process, msg=NULL\n");	return -1;    }    nl = (struct name_lst *)pkg_malloc(sizeof(struct name_lst));    if (!nl)    {	LM_ERR("app_java: force_send_socket: pkg_malloc() has failed. Not enough memory!\n");	return -1;    }        si = (struct socket_id *)pkg_malloc(sizeof(struct socket_id));    if (!si)    {	LM_ERR("app_java: force_send_socket: pkg_malloc() has failed. Not enough memory!\n");	return -1;    }        memset(&act, 0, sizeof(act));    act.type = FORCE_SEND_SOCKET_T;    nl->name = (char *)(*jenv)->GetStringUTFChars(jenv, jsrchost, &is_copy);    if ((*jenv)->ExceptionCheck(jenv))    {        handle_exception();        return -1;    }    nl->next = NULL;    nl->flags = 0;    si->addr_lst = nl;    si->flags = 0;    si->proto = PROTO_NONE;    si->port = (int)jsrcport;        act.val[0].type = SOCKETINFO_ST;    act.val[0].u.data = si;    init_run_actions_ctx(&ra_ctx);    retval = do_action(&ra_ctx, &act, msg);    (*jenv)->ReleaseStringUTFChars(jenv, jsrchost, nl->name);    pkg_free(nl);    pkg_free(si);    return (jint)retval;}/*    *** Java API ***    Package: org.siprouter    Class: CoreMethods    Method: forward()I    Method(o): forward(Ljava/lang/String;I)I    Prototype: public static native int forward();    Prototype(o): public static native int forward(String ruri, int i);*/JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_forward(JNIEnv *jenv, jobject this, jstring jrurihost, jint juriport){    struct action act;    struct run_act_ctx ra_ctx;    int retval;    jboolean is_copy;    char *crurihost;    if (!msg)    {	LM_ERR("app_java: forward: Can't process, msg=NULL\n");	return -1;    }    memset(&act, 0, sizeof(act));    act.type = FORWARD_T;    crurihost = NULL;    if (jrurihost)    {	crurihost = (char *)(*jenv)->GetStringUTFChars(jenv, jrurihost, &is_copy);	if ((*jenv)->ExceptionCheck(jenv))	{    	    handle_exception();    	    return -1;	}	act.val[0].type = URIHOST_ST;	act.val[0].u.str.s = crurihost;	act.val[0].u.str.len = strlen(crurihost);	act.val[1].type = NUMBER_ST;	act.val[1].u.number = (int)juriport;    }    init_run_actions_ctx(&ra_ctx);    retval = do_action(&ra_ctx, &act, msg);    if (crurihost)    {	(*jenv)->ReleaseStringUTFChars(jenv, jrurihost, crurihost);    }    return (jint)retval;}/*    *** Java API ***    Package: org.siprouter    Class: CoreMethods    Method: isflagset(I)Z    Prototype: public static native boolean isflagset(int flag);*/JNIEXPORT jboolean JNICALL Java_org_siprouter_CoreMethods_isflagset(JNIEnv *jenv, jobject this, jint jflag){    if (!msg)    {	LM_ERR("app_java: isflagset: Can't process, msg=NULL\n");	return -1;    }    return isflagset(msg, (int)jflag) == 1 ? JNI_TRUE : JNI_FALSE;}/*    *** Java API ***    Package: org.siprouter    Class: CoreMethods    Method: setflag(I)V    Prototype: public static native void setflag(int flag);*/JNIEXPORT void JNICALL Java_org_siprouter_CoreMethods_setflag(JNIEnv *jenv, jobject this, jint jflag){    if (!msg)    {	LM_ERR("app_java: setflag: Can't process, msg=NULL\n");	return;    }    setflag(msg, (int)jflag);}/*    *** Java API ***    Package: org.siprouter    Class: CoreMethods    Method: resetflag(I)V    Prototype: public static native void resetflag(int flag);*/JNIEXPORT void JNICALL Java_org_siprouter_CoreMethods_resetflag(JNIEnv *jenv, jobject this, jint jflag){    if (!msg)    {	LM_ERR("app_java: resetflag: Can't process, msg=NULL\n");	return;    }    resetflag(msg, (int)jflag);}/*    *** Java API ***    Package: org.siprouter    Class: CoreMethods    Method: revert_uri()I    Prototype: public static native int revert_uri();*/JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_revert_1uri(JNIEnv *jenv, jobject this){    struct action act;    struct run_act_ctx ra_ctx;    int retval;    if (!msg)    {	LM_ERR("app_java: revert_uri: Can't process, msg=NULL\n");	return -1;    }    memset(&act, 0, sizeof(act));    act.type = REVERT_URI_T;    init_run_actions_ctx(&ra_ctx);    retval = do_action(&ra_ctx, &act, msg);    return (jint)retval;}/*    *** Java API ***    Package: org.siprouter    Class: CoreMethods    Method: route(Ljava/lang/String)I    Prototype: public static native int route(String target);*/JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_route(JNIEnv *jenv, jobject this, jstring jtarget){    struct action act;    struct run_act_ctx ra_ctx;    int retval;    jboolean is_copy;    char *ctarget;    ctarget = (char *)(*jenv)->GetStringUTFChars(jenv, jtarget, &is_copy);    if ((*jenv)->ExceptionCheck(jenv))    {	handle_exception();	return -1;    }    retval = route_lookup(&main_rt, ctarget);    if (retval == -1)	// route index lookup failed.    {	LM_ERR("app_java: route: failed to find route name '%s'\n", ctarget);	(*jenv)->ReleaseStringUTFChars(jenv, jtarget, ctarget);	return -1;    }    act.type = ROUTE_T;    act.val[0].type = NUMBER_ST;    act.val[0].u.number = retval;    init_run_actions_ctx(&ra_ctx);    retval = do_action(&ra_ctx, &act, msg);    (*jenv)->ReleaseStringUTFChars(jenv, jtarget, ctarget);    return retval;}
 |