java_native_methods.c 29 KB

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