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