1 /*
2  * Copyright (C) 2013 Konstantin Mosesov
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * This file is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version
10  *
11  *
12  * This file is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  */
22 #include "../../core/str.h"
23 #include "../../core/sr_module.h"
24 #include "../../core/ip_addr.h"
25 #include "../../core/flags.h"
26 
27 #include <jni.h>
28 
29 #include "global.h"
30 #include "utils.h"
31 #include "app_java_mod.h"
32 #include "java_iface.h"
33 #include "java_support.h"
34 #include "java_msgobj.h"
35 #include "java_native_methods.h"
36 #include "java_sig_parser.h"
37 
38 
39 //// native methods ////
40 
41 /*
42     java: native void LM_XXXXXX(Params XXXX);
43     c: JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1XXXXXX(JNIEnv *jenv, jobject this, Params XXXX)
44 
45     Why (for example) Java_Kamailio_LM_1ERR but not Java_Kamailio_LM_ERR?
46     See explaination here: http://qscribble.blogspot.ca/2012/04/underscores-in-jni-method-names.html
47 
48     Also, from here: http://192.9.162.55/docs/books/jni/html/design.html
49     The JNI adopts a simple name-encoding scheme to ensure that all Unicode characters
50     translate into valid C function names. The underscore ("_") character separates the
51     components of fully qualified class names. Because a name or type descriptor never
52     begins with a number, we can use _0, ..., _9 for escape sequences, as illustrated below:
53     +-------------------+------------------------------------+
54     |  Escape Sequence  |            Denotes                 |
55     +-------------------+------------------------------------+
56     |	_0XXXX          |  a Unicode character XXXX          |
57     |	_1              |  the character "_"                 |
58     |	_2              |  the character ";" in descriptors  |
59     |	_3              |  the character "[" in descriptors  |
60     +-------------------+------------------------------------+
61 
62 */
63 
64 /*
65     *** Java API ***
66     Package: org.siprouter
67     Class: NativeMethods
68     Method: LM_ERR(Ljava/lang/String;)V
69     Prototype: public static native void LM_ERR(String s);
70 */
Java_org_siprouter_NativeMethods_LM_1ERR(JNIEnv * jenv,jobject this,jstring js)71 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1ERR(
72 		JNIEnv *jenv, jobject this, jstring js)
73 {
74 	const char *s;
75 	jboolean iscopy;
76 
77 	s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
78 	if((*jenv)->ExceptionCheck(jenv)) {
79 		handle_exception();
80 		return;
81 	}
82 
83 	LM_ERR("%s", s == NULL ? "null\n" : s);
84 
85 	(*jenv)->ReleaseStringUTFChars(jenv, js, s);
86 }
87 
88 /*
89     *** Java API ***
90     Package: org.siprouter
91     Class: NativeMethods
92     Method: LM_WARN(Ljava/lang/String;)V
93     Prototype: public static native void LM_WARN(String s);
94 */
Java_org_siprouter_NativeMethods_LM_1WARN(JNIEnv * jenv,jobject this,jstring js)95 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1WARN(
96 		JNIEnv *jenv, jobject this, jstring js)
97 {
98 	const char *s;
99 	jboolean iscopy;
100 
101 	s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
102 	if((*jenv)->ExceptionCheck(jenv)) {
103 		handle_exception();
104 		return;
105 	}
106 
107 	LM_WARN("%s", s == NULL ? "null\n" : s);
108 
109 	(*jenv)->ReleaseStringUTFChars(jenv, js, s);
110 }
111 
112 /*
113     *** Java API ***
114     Package: org.siprouter
115     Class: NativeMethods
116     Method: LM_NOTICE(Ljava/lang/String;)V
117     Prototype: public static native void LM_NOTICE(String s);
118 */
Java_org_siprouter_NativeMethods_LM_1NOTICE(JNIEnv * jenv,jobject this,jstring js)119 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1NOTICE(
120 		JNIEnv *jenv, jobject this, jstring js)
121 {
122 	const char *s;
123 	jboolean iscopy;
124 
125 	s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
126 	if((*jenv)->ExceptionCheck(jenv)) {
127 		handle_exception();
128 		return;
129 	}
130 
131 	LM_NOTICE("%s", s == NULL ? "null\n" : s);
132 
133 	(*jenv)->ReleaseStringUTFChars(jenv, js, s);
134 }
135 
136 /*
137     *** Java API ***
138     Package: org.siprouter
139     Class: NativeMethods
140     Method: LM_INFO(Ljava/lang/String;)V
141     Prototype: public static native void LM_INFO(String s);
142 */
Java_org_siprouter_NativeMethods_LM_1INFO(JNIEnv * jenv,jobject this,jstring js)143 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1INFO(
144 		JNIEnv *jenv, jobject this, jstring js)
145 {
146 	const char *s;
147 	jboolean iscopy;
148 
149 	s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
150 	if((*jenv)->ExceptionCheck(jenv)) {
151 		handle_exception();
152 		return;
153 	}
154 
155 	LM_INFO("%s", s == NULL ? "null\n" : s);
156 
157 	(*jenv)->ReleaseStringUTFChars(jenv, js, s);
158 }
159 
160 /*
161     *** Java API ***
162     Package: org.siprouter
163     Class: NativeMethods
164     Method: LM_DBG(Ljava/lang/String;)V
165     Prototype: public static native void LM_DBG(String s);
166 */
Java_org_siprouter_NativeMethods_LM_1DBG(JNIEnv * jenv,jobject this,jstring js)167 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1DBG(
168 		JNIEnv *jenv, jobject this, jstring js)
169 {
170 	const char *s;
171 	jboolean iscopy;
172 
173 	s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
174 	if((*jenv)->ExceptionCheck(jenv)) {
175 		handle_exception();
176 		return;
177 	}
178 
179 	LM_DBG("%s", s == NULL ? "null\n" : s);
180 
181 	(*jenv)->ReleaseStringUTFChars(jenv, js, s);
182 }
183 
184 /*
185     *** Java API ***
186     Package: org.siprouter
187     Class: NativeMethods
188     Method: LM_CRIT(Ljava/lang/String;)V
189     Prototype: public static native void LM_CRIT(String s);
190 */
Java_org_siprouter_NativeMethods_LM_1CRIT(JNIEnv * jenv,jobject this,jstring js)191 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1CRIT(
192 		JNIEnv *jenv, jobject this, jstring js)
193 {
194 	const char *s;
195 	jboolean iscopy;
196 
197 	s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
198 	if((*jenv)->ExceptionCheck(jenv)) {
199 		handle_exception();
200 		return;
201 	}
202 
203 	LM_CRIT("%s", s == NULL ? "null\n" : s);
204 
205 	(*jenv)->ReleaseStringUTFChars(jenv, js, s);
206 }
207 
208 
209 #ifdef LM_ALERT
210 /*
211     *** Java API ***
212     Package: org.siprouter
213     Class: NativeMethods
214     Method: LM_ALERT(Ljava/lang/String;)V
215     Prototype: public static native void LM_ALERT(String s);
216 */
Java_org_siprouter_NativeMethods_LM_1ALERT(JNIEnv * jenv,jobject this,jstring js)217 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1ALERT(
218 		JNIEnv *jenv, jobject this, jstring js)
219 {
220 	const char *s;
221 	jboolean iscopy;
222 
223 	s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
224 	if((*jenv)->ExceptionCheck(jenv)) {
225 		handle_exception();
226 		return;
227 	}
228 
229 	LM_ALERT("%s", s == NULL ? "null\n" : s);
230 
231 	(*jenv)->ReleaseStringUTFChars(jenv, js, s);
232 }
233 #endif
234 
235 
236 /*
237     *** Java API ***
238     Package: org.siprouter
239     Class: NativeMethods
240     Method: LM_GEN2(ILjava/lang/String;)V
241     Prototype: public static native void LM_GEN1(int logLevel, String s);
242 */
Java_org_siprouter_NativeMethods_LM_1GEN1(JNIEnv * jenv,jobject this,jint ll,jstring js)243 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1GEN1(
244 		JNIEnv *jenv, jobject this, jint ll, jstring js)
245 {
246 	const char *s;
247 	jboolean iscopy;
248 
249 	s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
250 	if((*jenv)->ExceptionCheck(jenv)) {
251 		handle_exception();
252 		return;
253 	}
254 
255 	LM_GEN1((int)ll, "%s", s == NULL ? "null\n" : s);
256 
257 	(*jenv)->ReleaseStringUTFChars(jenv, js, s);
258 }
259 
260 /*
261     *** Java API ***
262     Package: org.siprouter
263     Class: NativeMethods
264     Method: LM_GEN2(IILjava/lang/String;)V
265     Prototype: public static native void LM_GEN2(int logLevel, int logFacility, String s);
266 */
Java_org_siprouter_NativeMethods_LM_1GEN2(JNIEnv * jenv,jobject this,jint ll,jint lf,jstring js)267 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1GEN2(
268 		JNIEnv *jenv, jobject this, jint ll, jint lf, jstring js)
269 {
270 	const char *s;
271 	jboolean iscopy;
272 
273 	s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
274 	if((*jenv)->ExceptionCheck(jenv)) {
275 		handle_exception();
276 		return;
277 	}
278 
279 	LM_GEN2((int)ll, (int)lf, "%s", s == NULL ? "null\n" : s);
280 
281 	(*jenv)->ReleaseStringUTFChars(jenv, js, s);
282 }
283 
284 /*
285     *** Java API ***
286     Package: org.siprouter
287     Class: NativeMethods
288     Method: KamExec(Ljava/lang/String;[Ljava/lang/String;)I
289     Prototype: public static native int KamExec(String fname, String... params);
290 */
Java_org_siprouter_NativeMethods_KamExec(JNIEnv * jenv,jobject this,jstring jfname,jobjectArray strArrParams)291 JNIEXPORT jint JNICALL Java_org_siprouter_NativeMethods_KamExec(
292 		JNIEnv *jenv, jobject this, jstring jfname, jobjectArray strArrParams)
293 {
294 	int retval;
295 	char *fname;
296 	int argc;
297 	jsize pc;
298 	int i;
299 	char *argv[MAX_ACTIONS];
300 	jboolean is_copy;
301 	jstring strp;
302 	char *strc;
303 
304 	if(jfname == NULL) {
305 		LM_ERR("%s: KamExec() required at least 1 argument (function name)\n",
306 				APP_NAME);
307 		return -1;
308 	}
309 
310 	fname = (char *)(*jenv)->GetStringUTFChars(jenv, jfname, &is_copy);
311 	if((*jenv)->ExceptionCheck(jenv)) {
312 		handle_exception();
313 		return -1;
314 	}
315 
316 	memset(argv, 0, MAX_ACTIONS * sizeof(char *));
317 	argc = 0;
318 
319 	pc = (*jenv)->GetArrayLength(jenv, strArrParams);
320 	if(pc >= 6) {
321 		pc = 6;
322 	}
323 
324 	for(i = 0; i < pc; i++) {
325 		strp = (jstring)(*jenv)->GetObjectArrayElement(jenv, strArrParams, i);
326 		if((*jenv)->ExceptionCheck(jenv)) {
327 			handle_exception();
328 			return -1;
329 		}
330 
331 		strc = (char *)(*jenv)->GetStringUTFChars(jenv, strp, &is_copy);
332 		if((*jenv)->ExceptionCheck(jenv)) {
333 			handle_exception();
334 			return -1;
335 		}
336 
337 		if(strc) {
338 			argv[argc++] = strc;
339 		}
340 	}
341 
342 	retval = KamExec(jenv, fname, argc, argv);
343 
344 	(*jenv)->ReleaseStringUTFChars(jenv, jfname, fname);
345 
346 	return (jint)retval;
347 }
348 
KamExec(JNIEnv * jenv,char * fname,int argc,char ** argv)349 int KamExec(JNIEnv *jenv, char *fname, int argc, char **argv)
350 {
351 	ksr_cmd_export_t *fexport;
352 	int rval;
353 	int mod_type;
354 	struct action *act;
355 	struct run_act_ctx ra_ctx;
356 	int i;
357 
358 	if(!_aj_msg)
359 		return -1;
360 
361 	fexport = find_export_record(fname, argc, 0);
362 	if(!fexport) {
363 		LM_ERR("%s: KamExec(): '%s' - no such function\n", APP_NAME, fname);
364 		return -1;
365 	}
366 
367 	/* check fixups */
368 	if(force_cmd_exec == 0 && fexport->fixup != NULL
369 			&& fexport->free_fixup == NULL) {
370 		LM_ERR("%s: KamExec(): function '%s' has fixup - cannot be used\n",
371 				APP_NAME, fname);
372 		return -1;
373 	}
374 
375 	switch(fexport->param_no) {
376 		case 0:
377 			mod_type = MODULE0_T;
378 			break;
379 		case 1:
380 			mod_type = MODULE1_T;
381 			break;
382 		case 2:
383 			mod_type = MODULE2_T;
384 			break;
385 		case 3:
386 			mod_type = MODULE3_T;
387 			break;
388 		case 4:
389 			mod_type = MODULE4_T;
390 			break;
391 		case 5:
392 			mod_type = MODULE5_T;
393 			break;
394 		case 6:
395 			mod_type = MODULE6_T;
396 			break;
397 		case VAR_PARAM_NO:
398 			mod_type = MODULEX_T;
399 			break;
400 		default:
401 			LM_ERR("%s: KamExec(): unknown/bad definition for function '%s' "
402 				   "(%d params)\n",
403 					APP_NAME, fname, fexport->param_no);
404 			return -1;
405 	}
406 
407 
408 	act = mk_action(mod_type, (argc + 2), /* number of (type, value) pairs */
409 			MODEXP_ST, fexport,			  /* function */
410 			NUMBER_ST, argc,			  /* parameter number */
411 			STRING_ST, argv[0],			  /* param. 1 */
412 			STRING_ST, argv[1],			  /* param. 2 */
413 			STRING_ST, argv[2],			  /* param. 3 */
414 			STRING_ST, argv[3],			  /* param. 4 */
415 			STRING_ST, argv[4],			  /* param. 5 */
416 			STRING_ST, argv[5]			  /* param. 6 */
417 			);
418 
419 	if(!act) {
420 		LM_ERR("%s: KamExec(): action structure couldn't be created\n",
421 				APP_NAME);
422 		return -1;
423 	}
424 
425 
426 	/* handle fixups */
427 	if(fexport->fixup) {
428 		if(argc == 0) {
429 			rval = fexport->fixup(0, 0);
430 			if(rval < 0) {
431 				LM_ERR("%s: KamExec(): (no params) Error in fixup (0) for "
432 					   "'%s'\n",
433 						APP_NAME, fname);
434 				return -1;
435 			}
436 		} else {
437 			for(i = 0; i <= argc; i++) {
438 				if(act->val[i + 2].u.data != 0x0) {
439 					rval = fexport->fixup(&(act->val[i + 2].u.data), i + 1);
440 					if(rval < 0) {
441 						LM_ERR("%s: KamExec(): (params: %d) Error in fixup "
442 							   "(%d) for '%s'\n",
443 								APP_NAME, argc, i + 1, fname);
444 						return -1;
445 					}
446 					act->val[i + 2].type = MODFIXUP_ST;
447 				}
448 			}
449 		}
450 	}
451 
452 	init_run_actions_ctx(&ra_ctx);
453 	rval = do_action(&ra_ctx, act, _aj_msg);
454 
455 	/* free fixups */
456 	if(fexport->free_fixup) {
457 		for(i = 0; i <= argc; i++) {
458 			if((act->val[i + 2].type == MODFIXUP_ST)
459 					&& (act->val[i + 2].u.data)) {
460 				fexport->free_fixup(&(act->val[i + 2].u.data), i + 1);
461 			}
462 		}
463 	}
464 
465 	pkg_free(act);
466 
467 	return rval;
468 }
469 
470 
471 /*
472     *** Java API ***
473     Package: org.siprouter
474     Class: SipMsg
475     Method: ParseSipMsg()Lorg/siprouter/SipMsg;
476     Prototype: public static native org.siprouter.SipMsg ParseSipMsg();
477 */
Java_org_siprouter_SipMsg_ParseSipMsg(JNIEnv * jenv,jobject this)478 JNIEXPORT jobject JNICALL Java_org_siprouter_SipMsg_ParseSipMsg(
479 		JNIEnv *jenv, jobject this)
480 {
481 	if(!_aj_msg)
482 		return NULL;
483 
484 	return fill_sipmsg_object(jenv, _aj_msg);
485 }
486 
487 
488 /*
489     *** Java API ***
490     Package: org.siprouter
491     Class: SipMsg
492     Method: getMsgType()Ljava/org/String;
493     Prototype: public static native String getMsgType();
494 */
Java_org_siprouter_SipMsg_getMsgType(JNIEnv * jenv,jobject this)495 JNIEXPORT jstring JNICALL Java_org_siprouter_SipMsg_getMsgType(
496 		JNIEnv *jenv, jobject this)
497 {
498 	char *cs;
499 	jstring js;
500 
501 	if(!_aj_msg)
502 		return NULL;
503 
504 	switch((_aj_msg->first_line).type) {
505 		case SIP_REQUEST:
506 			cs = "SIP_REQUEST";
507 			break;
508 
509 		case SIP_REPLY:
510 			cs = "SIP_REPLY";
511 			break;
512 
513 		default:
514 			cs = "SIP_INVALID";
515 			break;
516 	}
517 
518 	js = (*jenv)->NewStringUTF(jenv, cs);
519 	if((*jenv)->ExceptionCheck(jenv)) {
520 		handle_exception();
521 		return NULL;
522 	}
523 
524 	return js;
525 }
526 
527 /*
528     *** Java API ***
529     Package: org.siprouter
530     Class: SipMsg
531     Method: getStatus()Ljava/org/String;
532     Prototype: public static native String getStatus();
533 */
Java_org_siprouter_SipMsg_getStatus(JNIEnv * jenv,jobject this)534 JNIEXPORT jstring JNICALL Java_org_siprouter_SipMsg_getStatus(
535 		JNIEnv *jenv, jobject this)
536 {
537 	str *cs;
538 	jstring js;
539 
540 	if(!_aj_msg)
541 		return NULL;
542 
543 	if((_aj_msg->first_line).type != SIP_REQUEST) {
544 		LM_ERR("%s: getStatus(): Unable to fetch status. Error: Not a request "
545 			   "message - no method available.\n",
546 				APP_NAME);
547 		return NULL;
548 	}
549 
550 	cs = &((_aj_msg->first_line).u.request.method);
551 
552 	js = (*jenv)->NewStringUTF(jenv, (cs && cs->s && cs->len > 0) ? cs->s : "");
553 	if((*jenv)->ExceptionCheck(jenv)) {
554 		handle_exception();
555 		return NULL;
556 	}
557 
558 	return js;
559 }
560 
561 /*
562     *** Java API ***
563     Package: org.siprouter
564     Class: SipMsg
565     Method: getRURI()Ljava/org/String;
566     Prototype: public static native String getRURI();
567 */
Java_org_siprouter_SipMsg_getRURI(JNIEnv * jenv,jobject this)568 JNIEXPORT jstring JNICALL Java_org_siprouter_SipMsg_getRURI(
569 		JNIEnv *jenv, jobject this)
570 {
571 	str *cs;
572 	jstring js;
573 
574 	if(!_aj_msg)
575 		return NULL;
576 
577 	if((_aj_msg->first_line).type != SIP_REQUEST) {
578 		LM_ERR("%s: getRURI(): Unable to fetch ruri. Error: Not a request "
579 			   "message - no method available.\n",
580 				APP_NAME);
581 		return NULL;
582 	}
583 
584 	cs = &((_aj_msg->first_line).u.request.uri);
585 
586 	js = (*jenv)->NewStringUTF(jenv, (cs && cs->s && cs->len > 0) ? cs->s : "");
587 	if((*jenv)->ExceptionCheck(jenv)) {
588 		handle_exception();
589 		return NULL;
590 	}
591 
592 	return js;
593 }
594 
595 /*
596     *** Java API ***
597     Package: org.siprouter
598     Class: SipMsg
599     Method: getSrcAddress()Lorg/siprouter/IPPair;
600     Prototype: public static native org.siprouter.IPPair getSrcAddress();
601 */
Java_org_siprouter_SipMsg_getSrcAddress(JNIEnv * jenv,jobject this)602 JNIEXPORT jobject JNICALL Java_org_siprouter_SipMsg_getSrcAddress(
603 		JNIEnv *jenv, jobject this)
604 {
605 	jclass ippair_cls;
606 	jmethodID ippair_cls_id;
607 	jobject ippair_cls_instance;
608 
609 	char *ip;
610 	jstring jip;
611 	int port;
612 
613 	if(!_aj_msg)
614 		return NULL;
615 
616 	ippair_cls = (*jenv)->FindClass(jenv, "org/siprouter/IPPair");
617 	if((*jenv)->ExceptionCheck(jenv)) {
618 		handle_exception();
619 		return NULL;
620 	}
621 
622 	ippair_cls_id = (*jenv)->GetMethodID(
623 			jenv, ippair_cls, "<init>", "(Ljava/lang/String;I)V");
624 	if(!ippair_cls_id || (*jenv)->ExceptionCheck(jenv)) {
625 		handle_exception();
626 		return NULL;
627 	}
628 
629 	ip = ip_addr2a(&_aj_msg->rcv.src_ip);
630 	if(!ip) {
631 		LM_ERR("%s: getSrcAddress(): Unable to fetch src ip address.\n",
632 				APP_NAME);
633 		return NULL;
634 	}
635 	jip = (*jenv)->NewStringUTF(jenv, ip);
636 	if((*jenv)->ExceptionCheck(jenv)) {
637 		handle_exception();
638 		return NULL;
639 	}
640 
641 	port = _aj_msg->rcv.src_port;
642 	if(port == 0x0) {
643 		LM_ERR("%s: getSrcAddress(): Unable to fetch src port.\n", APP_NAME);
644 		return NULL;
645 	}
646 
647 	// calling constructor
648 	ippair_cls_instance = (*jenv)->NewObject(
649 			jenv, ippair_cls, ippair_cls_id, (jstring)jip, (jint)port);
650 	if(!ippair_cls_instance || (*jenv)->ExceptionCheck(jenv)) {
651 		handle_exception();
652 		return NULL;
653 	}
654 
655 	return ippair_cls_instance;
656 }
657 
658 /*
659     *** Java API ***
660     Package: org.siprouter
661     Class: SipMsg
662     Method: getDstAddress()Lorg/siprouter/IPPair;
663     Prototype: public static native org.siprouter.IPPair getDstAddress();
664 */
Java_org_siprouter_SipMsg_getDstAddress(JNIEnv * jenv,jobject this)665 JNIEXPORT jobject JNICALL Java_org_siprouter_SipMsg_getDstAddress(
666 		JNIEnv *jenv, jobject this)
667 {
668 	jclass ippair_cls;
669 	jmethodID ippair_cls_id;
670 	jobject ippair_cls_instance;
671 
672 	char *ip;
673 	jstring jip;
674 	int port;
675 
676 	if(!_aj_msg)
677 		return NULL;
678 
679 	ippair_cls = (*jenv)->FindClass(jenv, "org/siprouter/IPPair");
680 	if((*jenv)->ExceptionCheck(jenv)) {
681 		handle_exception();
682 		return NULL;
683 	}
684 
685 	ippair_cls_id = (*jenv)->GetMethodID(
686 			jenv, ippair_cls, "<init>", "(Ljava/lang/String;I)V");
687 	if(!ippair_cls_id || (*jenv)->ExceptionCheck(jenv)) {
688 		handle_exception();
689 		return NULL;
690 	}
691 
692 	ip = ip_addr2a(&_aj_msg->rcv.dst_ip);
693 	if(!ip) {
694 		LM_ERR("%s: getDstAddress(): Unable to fetch src ip address.\n",
695 				APP_NAME);
696 		return NULL;
697 	}
698 	jip = (*jenv)->NewStringUTF(jenv, ip);
699 	if((*jenv)->ExceptionCheck(jenv)) {
700 		handle_exception();
701 		return NULL;
702 	}
703 
704 	port = _aj_msg->rcv.dst_port;
705 	if(port == 0x0) {
706 		LM_ERR("%s: getDstAddress(): Unable to fetch src port.\n", APP_NAME);
707 		return NULL;
708 	}
709 
710 	// calling constructor
711 	ippair_cls_instance = (*jenv)->NewObject(
712 			jenv, ippair_cls, ippair_cls_id, (jstring)jip, (jint)port);
713 	if(!ippair_cls_instance || (*jenv)->ExceptionCheck(jenv)) {
714 		handle_exception();
715 		return NULL;
716 	}
717 
718 	return ippair_cls_instance;
719 }
720 
721 /*
722     *** Java API ***
723     Package: org.siprouter
724     Class: SipMsg
725     Method: getBuffer()Ljava/org/String;
726     Prototype: public static native String getBuffer();
727 */
Java_org_siprouter_SipMsg_getBuffer(JNIEnv * jenv,jobject this)728 JNIEXPORT jstring JNICALL Java_org_siprouter_SipMsg_getBuffer(
729 		JNIEnv *jenv, jobject this)
730 {
731 	jstring js;
732 
733 	if(!_aj_msg)
734 		return NULL;
735 
736 	if((_aj_msg->first_line).type != SIP_REQUEST) {
737 		LM_ERR("%s: getRURI(): Unable to fetch ruri. Error: Not a request "
738 			   "message - no method available.\n",
739 				APP_NAME);
740 		return NULL;
741 	}
742 
743 	js = (*jenv)->NewStringUTF(jenv, _aj_msg->buf ? _aj_msg->buf : "");
744 	if((*jenv)->ExceptionCheck(jenv)) {
745 		handle_exception();
746 		return NULL;
747 	}
748 
749 	return js;
750 }
751 
752 
753 ///// Core Functions /////
754 
755 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
756 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
757 
758 /*
759     *** Java API ***
760     Package: org.siprouter
761     Class: CoreMethods
762     Method: seturi(Ljava/org/String;)I
763     Prototype: public static native int seturi(String uri);
764 */
Java_org_siprouter_CoreMethods_seturi(JNIEnv * jenv,jobject this,jstring juri)765 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_seturi(
766 		JNIEnv *jenv, jobject this, jstring juri)
767 {
768 	return cf_seturi(jenv, this, juri, "seturi");
769 }
770 
771 /*
772     *** Java API ***
773     Package: org.siprouter
774     Class: CoreMethods
775     Method: rewriteuri(Ljava/org/String;)I
776     Prototype: public static native int rewriteuri(String uri);
777 */
Java_org_siprouter_CoreMethods_rewriteuri(JNIEnv * jenv,jobject this,jstring juri)778 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_rewriteuri(
779 		JNIEnv *jenv, jobject this, jstring juri)
780 {
781 	return cf_seturi(jenv, this, juri, "rewriteuri");
782 }
783 
784 /* wrapped function */
cf_seturi(JNIEnv * jenv,jobject this,jstring juri,char * fname)785 jint cf_seturi(JNIEnv *jenv, jobject this, jstring juri, char *fname)
786 {
787 	struct action act;
788 	struct run_act_ctx ra_ctx;
789 	int retval;
790 	jboolean is_copy;
791 	char *curi;
792 
793 	if(!_aj_msg) {
794 		LM_ERR("%s: %s: Can't process, _aj_msg=NULL\n", APP_NAME, fname);
795 		return -1;
796 	}
797 
798 	curi = (char *)(*jenv)->GetStringUTFChars(jenv, juri, &is_copy);
799 	if((*jenv)->ExceptionCheck(jenv)) {
800 		handle_exception();
801 		return -1;
802 	}
803 
804 	memset(&act, 0, sizeof(act));
805 	act.type = SET_URI_T;
806 	act.val[0].type = STRING_ST;
807 	act.val[0].u.str.s = curi;
808 	act.val[0].u.str.len = strlen(curi);
809 	init_run_actions_ctx(&ra_ctx);
810 	retval = do_action(&ra_ctx, &act, _aj_msg);
811 	(*jenv)->ReleaseStringUTFChars(jenv, juri, curi);
812 	return (jint)retval;
813 }
814 
815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
816 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
817 
818 
819 /*
820     *** Java API ***
821     Package: org.siprouter
822     Class: CoreMethods
823     Method: add_local_rport()I
824     Prototype: public static native int add_local_rport();
825 */
Java_org_siprouter_CoreMethods_add_1local_1rport(JNIEnv * jenv,jobject this)826 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_add_1local_1rport(
827 		JNIEnv *jenv, jobject this)
828 {
829 	struct action act;
830 	struct run_act_ctx ra_ctx;
831 	int retval;
832 
833 	if(!_aj_msg) {
834 		LM_ERR("%s: add_local_rport: Can't process, _aj_msg=NULL\n", APP_NAME);
835 		return -1;
836 	}
837 
838 	memset(&act, 0, sizeof(act));
839 	act.type = ADD_LOCAL_RPORT_T;
840 	init_run_actions_ctx(&ra_ctx);
841 	retval = do_action(&ra_ctx, &act, _aj_msg);
842 	return (jint)retval;
843 }
844 
845 /*
846     *** Java API ***
847     Package: org.siprouter
848     Class: CoreMethods
849     Method: append_branch()I
850     Method(o): append_branch(Ljava/lang/String)I
851     Prototype: public static native int append_branch();
852     Prototype(o): public static native int append_branch(String branch);
853 */
Java_org_siprouter_CoreMethods_append_1branch(JNIEnv * jenv,jobject this,jstring jbranch)854 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_append_1branch(
855 		JNIEnv *jenv, jobject this, jstring jbranch)
856 {
857 	struct action act;
858 	struct run_act_ctx ra_ctx;
859 	int retval;
860 	jboolean is_copy;
861 	char *cbranch;
862 
863 	if(!_aj_msg) {
864 		LM_ERR("%s: append_branch: Can't process, _aj_msg=NULL\n", APP_NAME);
865 		return -1;
866 	}
867 
868 	memset(&act, 0, sizeof(act));
869 	act.type = APPEND_BRANCH_T;
870 
871 	cbranch = NULL;
872 
873 	if(jbranch) {
874 		cbranch = (char *)(*jenv)->GetStringUTFChars(jenv, jbranch, &is_copy);
875 		if((*jenv)->ExceptionCheck(jenv)) {
876 			handle_exception();
877 			return -1;
878 		}
879 
880 		act.val[0].type = STR_ST;
881 		act.val[0].u.str.s = cbranch;
882 		act.val[0].u.str.len = strlen(cbranch);
883 	}
884 
885 	init_run_actions_ctx(&ra_ctx);
886 	retval = do_action(&ra_ctx, &act, _aj_msg);
887 
888 	if(cbranch) {
889 		(*jenv)->ReleaseStringUTFChars(jenv, jbranch, cbranch);
890 	}
891 
892 	return (jint)retval;
893 }
894 
895 /*
896     *** Java API ***
897     Package: org.siprouter
898     Class: CoreMethods
899     Method: drop()I
900     Prototype: public static native int drop();
901     Returns:
902 	0 if action -> end of list(e.g DROP)
903         > 0 to continue processing next actions
904 	< 0 on error
905 */
Java_org_siprouter_CoreMethods_drop(JNIEnv * jenv,jobject this)906 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_drop(
907 		JNIEnv *jenv, jobject this)
908 {
909 	struct action act;
910 	struct run_act_ctx ra_ctx;
911 	int retval;
912 
913 	if(!_aj_msg) {
914 		LM_ERR("%s: drop: Can't process, _aj_msg=NULL\n", APP_NAME);
915 		return -1;
916 	}
917 
918 	memset(&act, 0, sizeof(act));
919 	act.type = DROP_T;
920 	act.val[0].type = NUMBER_ST;
921 	act.val[0].u.number = 0;
922 	init_run_actions_ctx(&ra_ctx);
923 	retval = do_action(&ra_ctx, &act, _aj_msg);
924 	return (jint)retval;
925 }
926 
927 /*
928     *** Java API ***
929     Package: org.siprouter
930     Class: CoreMethods
931     Method: force_rport()I
932     Prototype: public static native int force_rport();
933 */
Java_org_siprouter_CoreMethods_force_1rport(JNIEnv * jenv,jobject this)934 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_force_1rport(
935 		JNIEnv *jenv, jobject this)
936 {
937 	return cf_force_rport(jenv, this, "force_rport");
938 }
939 
940 /*
941     *** Java API ***
942     Package: org.siprouter
943     Class: CoreMethods
944     Method: add_rport()I
945     Prototype: public static native int add_rport();
946 */
Java_org_siprouter_CoreMethods_add_1rport(JNIEnv * jenv,jobject this)947 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_add_1rport(
948 		JNIEnv *jenv, jobject this)
949 {
950 	return cf_force_rport(jenv, this, "add_rport");
951 }
952 
953 /* wrapped function */
cf_force_rport(JNIEnv * jenv,jobject this,char * fname)954 jint cf_force_rport(JNIEnv *jenv, jobject this, char *fname)
955 {
956 	struct action act;
957 	struct run_act_ctx ra_ctx;
958 	int retval;
959 
960 	if(!_aj_msg) {
961 		LM_ERR("%s: %s: Can't process, _aj_msg=NULL\n", APP_NAME, fname);
962 		return -1;
963 	}
964 
965 	memset(&act, 0, sizeof(act));
966 	act.type = FORCE_RPORT_T;
967 	init_run_actions_ctx(&ra_ctx);
968 	retval = do_action(&ra_ctx, &act, _aj_msg);
969 	return (jint)retval;
970 }
971 
972 
973 /*
974     *** Java API ***
975     Package: org.siprouter
976     Class: CoreMethods
977     Method: force_send_socket(Ljava/lang/String;I)I
978     Prototype: public static native int force_send_socket(String srchost, int srcport);
979 */
Java_org_siprouter_CoreMethods_force_1send_1socket(JNIEnv * jenv,jobject this,jstring jsrchost,jint jsrcport)980 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_force_1send_1socket(
981 		JNIEnv *jenv, jobject this, jstring jsrchost, jint jsrcport)
982 {
983 	struct action act;
984 	struct run_act_ctx ra_ctx;
985 	int retval;
986 	jboolean is_copy;
987 	struct socket_id *si;
988 	struct name_lst *nl;
989 
990 	if(!_aj_msg) {
991 		LM_ERR("%s: force_send_socket: Can't process, _aj_msg=NULL\n",
992 				APP_NAME);
993 		return -1;
994 	}
995 
996 	nl = (struct name_lst *)pkg_malloc(sizeof(struct name_lst));
997 	if(!nl) {
998 		PKG_MEM_ERROR;
999 		return -1;
1000 	}
1001 
1002 	si = (struct socket_id *)pkg_malloc(sizeof(struct socket_id));
1003 	if(!si) {
1004 		PKG_MEM_ERROR;
1005 		return -1;
1006 	}
1007 
1008 
1009 	memset(&act, 0, sizeof(act));
1010 	act.type = FORCE_SEND_SOCKET_T;
1011 
1012 	nl->name = (char *)(*jenv)->GetStringUTFChars(jenv, jsrchost, &is_copy);
1013 	if((*jenv)->ExceptionCheck(jenv)) {
1014 		handle_exception();
1015 		return -1;
1016 	}
1017 	nl->next = NULL;
1018 	nl->flags = 0;
1019 
1020 	si->addr_lst = nl;
1021 	si->flags = 0;
1022 	si->proto = PROTO_NONE;
1023 	si->port = (int)jsrcport;
1024 
1025 	act.val[0].type = SOCKETINFO_ST;
1026 	act.val[0].u.data = si;
1027 
1028 	init_run_actions_ctx(&ra_ctx);
1029 	retval = do_action(&ra_ctx, &act, _aj_msg);
1030 
1031 	(*jenv)->ReleaseStringUTFChars(jenv, jsrchost, nl->name);
1032 	pkg_free(nl);
1033 	pkg_free(si);
1034 	return (jint)retval;
1035 }
1036 
1037 
1038 /*
1039     *** Java API ***
1040     Package: org.siprouter
1041     Class: CoreMethods
1042     Method: forward()I
1043     Method(o): forward(Ljava/lang/String;I)I
1044     Prototype: public static native int forward();
1045     Prototype(o): public static native int forward(String ruri, int i);
1046 */
Java_org_siprouter_CoreMethods_forward(JNIEnv * jenv,jobject this,jstring jrurihost,jint juriport)1047 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_forward(
1048 		JNIEnv *jenv, jobject this, jstring jrurihost, jint juriport)
1049 {
1050 	struct action act;
1051 	struct run_act_ctx ra_ctx;
1052 	int retval;
1053 	jboolean is_copy;
1054 	char *crurihost;
1055 
1056 	if(!_aj_msg) {
1057 		LM_ERR("%s: forward: Can't process, _aj_msg=NULL\n", APP_NAME);
1058 		return -1;
1059 	}
1060 
1061 	memset(&act, 0, sizeof(act));
1062 	act.type = FORWARD_T;
1063 
1064 	crurihost = NULL;
1065 
1066 	if(jrurihost) {
1067 		crurihost =
1068 				(char *)(*jenv)->GetStringUTFChars(jenv, jrurihost, &is_copy);
1069 		if((*jenv)->ExceptionCheck(jenv)) {
1070 			handle_exception();
1071 			return -1;
1072 		}
1073 
1074 		act.val[0].type = URIHOST_ST;
1075 		act.val[0].u.str.s = crurihost;
1076 		act.val[0].u.str.len = strlen(crurihost);
1077 
1078 		act.val[1].type = NUMBER_ST;
1079 		act.val[1].u.number = (int)juriport;
1080 	}
1081 
1082 	init_run_actions_ctx(&ra_ctx);
1083 	retval = do_action(&ra_ctx, &act, _aj_msg);
1084 
1085 	if(crurihost) {
1086 		(*jenv)->ReleaseStringUTFChars(jenv, jrurihost, crurihost);
1087 	}
1088 
1089 	return (jint)retval;
1090 }
1091 
1092 /*
1093     *** Java API ***
1094     Package: org.siprouter
1095     Class: CoreMethods
1096     Method: isflagset(I)Z
1097     Prototype: public static native boolean isflagset(int flag);
1098 */
Java_org_siprouter_CoreMethods_isflagset(JNIEnv * jenv,jobject this,jint jflag)1099 JNIEXPORT jboolean JNICALL Java_org_siprouter_CoreMethods_isflagset(
1100 		JNIEnv *jenv, jobject this, jint jflag)
1101 {
1102 	if(!_aj_msg) {
1103 		LM_ERR("%s: isflagset: Can't process, _aj_msg=NULL\n", APP_NAME);
1104 		return -1;
1105 	}
1106 
1107 	return isflagset(_aj_msg, (int)jflag) == 1 ? JNI_TRUE : JNI_FALSE;
1108 }
1109 
1110 /*
1111     *** Java API ***
1112     Package: org.siprouter
1113     Class: CoreMethods
1114     Method: setflag(I)V
1115     Prototype: public static native void setflag(int flag);
1116 */
Java_org_siprouter_CoreMethods_setflag(JNIEnv * jenv,jobject this,jint jflag)1117 JNIEXPORT void JNICALL Java_org_siprouter_CoreMethods_setflag(
1118 		JNIEnv *jenv, jobject this, jint jflag)
1119 {
1120 	if(!_aj_msg) {
1121 		LM_ERR("%s: setflag: Can't process, _aj_msg=NULL\n", APP_NAME);
1122 		return;
1123 	}
1124 
1125 	setflag(_aj_msg, (int)jflag);
1126 }
1127 
1128 /*
1129     *** Java API ***
1130     Package: org.siprouter
1131     Class: CoreMethods
1132     Method: resetflag(I)V
1133     Prototype: public static native void resetflag(int flag);
1134 */
Java_org_siprouter_CoreMethods_resetflag(JNIEnv * jenv,jobject this,jint jflag)1135 JNIEXPORT void JNICALL Java_org_siprouter_CoreMethods_resetflag(
1136 		JNIEnv *jenv, jobject this, jint jflag)
1137 {
1138 	if(!_aj_msg) {
1139 		LM_ERR("%s: resetflag: Can't process, _aj_msg=NULL\n", APP_NAME);
1140 		return;
1141 	}
1142 
1143 	resetflag(_aj_msg, (int)jflag);
1144 }
1145 
1146 
1147 /*
1148     *** Java API ***
1149     Package: org.siprouter
1150     Class: CoreMethods
1151     Method: revert_uri()I
1152     Prototype: public static native int revert_uri();
1153 */
Java_org_siprouter_CoreMethods_revert_1uri(JNIEnv * jenv,jobject this)1154 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_revert_1uri(
1155 		JNIEnv *jenv, jobject this)
1156 {
1157 	struct action act;
1158 	struct run_act_ctx ra_ctx;
1159 	int retval;
1160 
1161 	if(!_aj_msg) {
1162 		LM_ERR("%s: revert_uri: Can't process, _aj_msg=NULL\n", APP_NAME);
1163 		return -1;
1164 	}
1165 
1166 	memset(&act, 0, sizeof(act));
1167 	act.type = REVERT_URI_T;
1168 	init_run_actions_ctx(&ra_ctx);
1169 	retval = do_action(&ra_ctx, &act, _aj_msg);
1170 	return (jint)retval;
1171 }
1172 
1173 /*
1174     *** Java API ***
1175     Package: org.siprouter
1176     Class: CoreMethods
1177     Method: route(Ljava/lang/String)I
1178     Prototype: public static native int route(String target);
1179 */
Java_org_siprouter_CoreMethods_route(JNIEnv * jenv,jobject this,jstring jtarget)1180 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_route(
1181 		JNIEnv *jenv, jobject this, jstring jtarget)
1182 {
1183 	struct action act;
1184 	struct run_act_ctx ra_ctx;
1185 	int retval;
1186 	jboolean is_copy;
1187 	char *ctarget;
1188 
1189 	ctarget = (char *)(*jenv)->GetStringUTFChars(jenv, jtarget, &is_copy);
1190 	if((*jenv)->ExceptionCheck(jenv)) {
1191 		handle_exception();
1192 		return -1;
1193 	}
1194 
1195 	retval = route_lookup(&main_rt, ctarget);
1196 
1197 	if(retval == -1) // route index lookup failed.
1198 	{
1199 		LM_ERR("%s: route: failed to find route name '%s'\n", APP_NAME,
1200 				ctarget);
1201 		(*jenv)->ReleaseStringUTFChars(jenv, jtarget, ctarget);
1202 		return -1;
1203 	}
1204 
1205 	act.type = ROUTE_T;
1206 	act.val[0].type = NUMBER_ST;
1207 	act.val[0].u.number = retval;
1208 
1209 	init_run_actions_ctx(&ra_ctx);
1210 	retval = do_action(&ra_ctx, &act, _aj_msg);
1211 
1212 	(*jenv)->ReleaseStringUTFChars(jenv, jtarget, ctarget);
1213 
1214 	return retval;
1215 }
1216