PageRenderTime 56ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/servers/jain-slee/resources/jcc/jcc-camel-provider/java/src/main/java/org/mobicents/jcc/inap/TCHandler.java

http://mobicents.googlecode.com/
Java | 399 lines | 300 code | 42 blank | 57 comment | 49 complexity | 292b72ff0536890d2cbd2116777e0f86 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0, LGPL-2.1, GPL-2.0, CC-BY-SA-3.0, CC0-1.0, Apache-2.0, BSD-3-Clause
  1. /*
  2. * JBoss, Home of Professional Open Source
  3. * Copyright 2011, Red Hat, Inc. and individual contributors
  4. * by the @authors tag. See the copyright.txt in the distribution for a
  5. * full listing of individual contributors.
  6. *
  7. * This is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This software 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 GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this software; if not, write to the Free
  19. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21. */
  22. /*
  23. * The Java Call Control API for CAMEL 2
  24. *
  25. * The source code contained in this file is in in the public domain.
  26. * It can be used in any project or product without prior permission,
  27. * license or royalty payments. There is NO WARRANTY OF ANY KIND,
  28. * EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION,
  29. * THE IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
  30. * AND DATA ACCURACY. We do not warrant or make any representations
  31. * regarding the use of the software or the results thereof, including
  32. * but not limited to the correctness, accuracy, reliability or
  33. * usefulness of the software.
  34. */
  35. package org.mobicents.jcc.inap;
  36. import java.io.IOException;
  37. import java.util.Enumeration;
  38. import javax.csapi.cc.jcc.JccAddress;
  39. import javax.csapi.cc.jcc.JccConnection;
  40. import javax.csapi.cc.jcc.JccConnectionEvent;
  41. import javax.csapi.cc.jcc.JccEvent;
  42. import org.mobicents.jcc.inap.address.JccCalledPartyBCDNumber;
  43. import org.mobicents.jcc.inap.protocol.CallInformationReport;
  44. import org.mobicents.jcc.inap.protocol.EventReportBCSM;
  45. import org.mobicents.jcc.inap.protocol.InitialDP;
  46. import org.mobicents.jcc.inap.protocol.Operation;
  47. import org.mobicents.jcc.inap.protocol.UnknownOperation;
  48. //import org.mobicents.jcc.inap.protocol.OperationCode;
  49. import org.mobicents.jcc.inap.protocol.parms.BCSMEvent;
  50. import org.mobicents.jcc.inap.protocol.parms.CalledPartyBcdNumber;
  51. import org.mobicents.jcc.inap.protocol.parms.CalledPartyNumber;
  52. import org.mobicents.jcc.inap.protocol.parms.CallingPartyNumber;
  53. import org.apache.log4j.Logger;
  54. import org.mobicents.protocols.ss7.sccp.parameter.SccpAddress;
  55. import org.mobicents.protocols.ss7.tcap.api.TCAPProvider;
  56. import org.mobicents.protocols.ss7.tcap.api.tc.dialog.Dialog;
  57. import org.mobicents.protocols.ss7.tcap.api.tc.dialog.events.DialogIndication;
  58. import org.mobicents.protocols.ss7.tcap.api.tc.dialog.events.TCBeginIndication;
  59. import org.mobicents.protocols.ss7.tcap.api.tc.dialog.events.TCContinueIndication;
  60. import org.mobicents.protocols.ss7.tcap.asn.comp.Component;
  61. import org.mobicents.protocols.ss7.tcap.asn.comp.ComponentType;
  62. import org.mobicents.protocols.ss7.tcap.asn.comp.Invoke;
  63. import org.mobicents.protocols.ss7.tcap.asn.comp.OperationCode;
  64. /**
  65. *
  66. * @author Oleg Kulikov
  67. */
  68. public class TCHandler implements Runnable {
  69. private JccInapProviderImpl provider = null;
  70. private SccpAddress calledPartyAddress;
  71. private SccpAddress callingPartyAddress;
  72. private byte[] data;
  73. private DialogIndication message;
  74. private TCAPProvider tcapProvider;
  75. private static Logger logger = Logger.getLogger(TCHandler.class);
  76. /** Creates a new instance of Handler */
  77. public TCHandler(JccInapProviderImpl provider, TCAPProvider tcapProvider, DialogIndication message) {
  78. this.provider = provider;
  79. this.tcapProvider = tcapProvider;
  80. this.calledPartyAddress = message.getDialog().getLocalAddress();
  81. this.callingPartyAddress = message.getDialog().getRemoteAddress();
  82. this.message = message;
  83. }
  84. private boolean isOutgoingCall(InitialDP initialDP) {
  85. return initialDP.getCalledPartyBcdNumber() != null;
  86. }
  87. private boolean isOutAllowed(InitialDP initialDP) {
  88. if (initialDP.getCallingPartyNumber().getAddress().endsWith("9023629581")
  89. || initialDP.getCallingPartyNumber().getAddress().endsWith("9023802866")) {
  90. return true;
  91. } else {
  92. return false;
  93. }
  94. }
  95. private boolean isIncAllowed(InitialDP initialDP) {
  96. if ((initialDP.getCalledPartyNumber() != null && initialDP.getCalledPartyNumber().getAddress().endsWith("9023629581"))
  97. || (initialDP.getCalledPartyNumber() != null && initialDP.getCalledPartyNumber().getAddress().endsWith("9023629581"))) {
  98. return true;
  99. } else {
  100. return false;
  101. }
  102. }
  103. public void run() {
  104. try {
  105. process();
  106. } catch (Exception e) {
  107. e.printStackTrace();
  108. }
  109. }
  110. private boolean existOriginatingConnection(JccCallImpl call, JccAddress callingNumber) {
  111. JccConnection[] connections = call.getConnections();
  112. for (int i = 0; i < connections.length; i++) {
  113. if (connections[i] instanceof OriginatingConnection) {
  114. String address = connections[i].getAddress().getName();
  115. return address.equals(callingNumber.getName());
  116. }
  117. }
  118. return false;
  119. }
  120. private boolean existTerminatingConnection(JccCallImpl call, JccAddress callingNumber) {
  121. JccConnection[] connections = call.getConnections();
  122. for (int i = 0; i < connections.length; i++) {
  123. if (connections[i] instanceof TerminatingConnection) {
  124. String address = connections[i].getOriginatingAddress().getName();
  125. return address.equals(callingNumber.getName());
  126. }
  127. }
  128. return false;
  129. }
  130. public void process() {
  131. Dialog dialog = message.getDialog();
  132. long txID = dialog.getDialogId();
  133. if(logger.isInfoEnabled())
  134. {
  135. logger.info("Processing messsage: "+message.getType()+", for dialog: "+dialog);
  136. }
  137. switch (message.getType()) {
  138. case Begin:
  139. TCBeginIndication begin = (TCBeginIndication) message;
  140. Component[] components = begin.getComponents();
  141. if(components == null || components.length == 0)
  142. {
  143. logger.error("NO COMPONENTS TO PROCESS: TCBegin");
  144. return;
  145. }
  146. for(Component c:components)
  147. {
  148. if(c.getType() != ComponentType.Invoke)
  149. {
  150. logger.error("Received non invoke component: "+c.getType()+", skipping!");
  151. continue;
  152. }
  153. Invoke invoke = (Invoke) c;
  154. //decode operation and parameter, its not TCAP part !
  155. org.mobicents.protocols.ss7.tcap.asn.comp.OperationCode oc = invoke.getOperationCode();
  156. if(invoke.getParameter() == null)
  157. {
  158. logger.error("Received invoke component without parameter, op code: "+oc.getLocalOperationCode()+", skipping!");
  159. continue;
  160. }
  161. //get data, regardles of type, we get buffer of passed param.
  162. byte[] buff = invoke.getParameter().getData();
  163. Operation inapOp = null;
  164. //its ok, long is general representation
  165. switch (oc.getLocalOperationCode().intValue()) {
  166. case Operation.INITIAL_DP:
  167. try {
  168. inapOp = new InitialDP(buff);
  169. } catch (IOException e) {
  170. // TODO Auto-generated catch block
  171. e.printStackTrace();
  172. }
  173. break;
  174. case Operation.CALL_INFORMATION_REPORT:
  175. try {
  176. inapOp = new CallInformationReport(buff);
  177. } catch (IOException e) {
  178. // TODO Auto-generated catch block
  179. e.printStackTrace();
  180. }
  181. break;
  182. case Operation.EVENT_REPORT_BCSM:
  183. try {
  184. inapOp = new EventReportBCSM(buff);
  185. } catch (IOException e) {
  186. // TODO Auto-generated catch block
  187. e.printStackTrace();
  188. }
  189. break;
  190. default:
  191. try {
  192. inapOp = new UnknownOperation(oc.getLocalOperationCode().intValue(), buff);
  193. } catch (IOException e) {
  194. // TODO Auto-generated catch block
  195. e.printStackTrace();
  196. }
  197. }
  198. if( !(inapOp instanceof InitialDP))
  199. {
  200. logger.error("Operation is not InitialDP!: "+inapOp);
  201. continue;
  202. }
  203. InitialDP initialDP = (InitialDP) inapOp;
  204. if (initialDP.getCallingPartyNumber() == null) {
  205. logger.warn("txID = " + txID + ", [InitialDP] CallingPartyNumber missing");
  206. return;
  207. }
  208. // if (!(isIncAllowed(initialDP) || isOutAllowed(initialDP))) {
  209. // return;
  210. // }
  211. //creating calling party address
  212. CallingPartyNumber callingPartyNumber = initialDP.getCallingPartyNumber();
  213. JccAddress callingNumber = provider.createAddress(callingPartyNumber);
  214. //lookup or creating new call
  215. JccCallImpl call = provider.calls.containsKey(callingNumber.getName())
  216. ? provider.getCall(callingNumber)
  217. : provider.createCall(callingNumber);
  218. ConnectionID connectionID = new ConnectionID(txID, calledPartyAddress, callingPartyAddress);
  219. JccAddress calledNumber = null;
  220. if (initialDP.getCalledPartyBcdNumber() != null) {
  221. if (existOriginatingConnection(call, callingNumber)) {
  222. logger.info("Forcing expired call release: " + call);
  223. call.forceRelease();
  224. call = provider.createCall(callingNumber);
  225. }
  226. OriginatingConnection connection = new OriginatingConnection(
  227. connectionID, call, callingNumber,this.tcapProvider,dialog);
  228. //handle o_connection created event
  229. JccEvent evt = new JccConnectionEventImpl(
  230. JccConnectionEvent.CONNECTION_CREATED,
  231. connection,
  232. JccEvent.CAUSE_NEW_CALL);
  233. connection.queueEvent(evt);
  234. CalledPartyBcdNumber bcdNumber = initialDP.getCalledPartyBcdNumber();
  235. calledNumber = provider.createAddress(bcdNumber);
  236. evt = new JccConnectionEventImpl(
  237. JccConnectionEvent.CONNECTION_ADDRESS_ANALYZE,
  238. connection,
  239. JccEvent.CAUSE_NEW_CALL);
  240. ((JccConnectionEventImpl) evt).destAddress = (JccCalledPartyBCDNumber) calledNumber;
  241. connection.queueEvent(evt);
  242. } else if (initialDP.getCalledPartyNumber() != null) {
  243. if (existTerminatingConnection(call, callingNumber)) {
  244. logger.info("Forcing expired call release: " + call);
  245. call.forceRelease();
  246. call = provider.createCall(callingNumber);
  247. }
  248. CalledPartyNumber calledPartyNumber = initialDP.getCalledPartyNumber();
  249. calledNumber = provider.createAddress(calledPartyNumber);
  250. TerminatingConnection connection = new TerminatingConnection(
  251. connectionID, call, calledNumber, callingNumber,this.tcapProvider,dialog);
  252. //handle connection created event
  253. JccEvent evt = new JccConnectionEventImpl(
  254. JccConnectionEvent.CONNECTION_CREATED,
  255. connection,
  256. JccEvent.CAUSE_NEW_CALL);
  257. connection.queueEvent(evt);
  258. //handle authorize_call_attempt event
  259. evt = new JccConnectionEventImpl(
  260. JccConnectionEvent.CONNECTION_AUTHORIZE_CALL_ATTEMPT,
  261. connection,
  262. JccEvent.CAUSE_NEW_CALL);
  263. connection.queueEvent(evt);
  264. } else {
  265. logger.warn("txID = " + txID + ", [InitialDP] either "
  266. + "CalledPartyNumber or CalledPartyBCDNumber missing");
  267. }
  268. }
  269. break;
  270. case Continue:
  271. AbstractConnection connection = provider.getConnection(txID);
  272. if (connection == null) {
  273. logger.warn("Unknown connection " + txID);
  274. return;
  275. //TODO send abort
  276. }
  277. TCContinueIndication continueInd = (TCContinueIndication) message;
  278. components = continueInd.getComponents();
  279. if (components == null) {
  280. logger.warn("One or more components are missing");
  281. return;
  282. }
  283. for(Component c: components){
  284. if(c.getType()!=ComponentType.Invoke)
  285. {
  286. logger.error("Skipping non invoke component: "+c.getType());
  287. continue;
  288. }
  289. Invoke invoke = (Invoke) c;
  290. org.mobicents.protocols.ss7.tcap.asn.comp.OperationCode operation = (OperationCode) invoke.getOperationCode();
  291. switch (operation.getLocalOperationCode().intValue()) {
  292. case Operation.EVENT_REPORT_BCSM:
  293. EventReportBCSM bcsmEvent;
  294. try {
  295. bcsmEvent = new EventReportBCSM(invoke.getParameter().getData());
  296. switch (bcsmEvent.getEventType()) {
  297. case BCSMEvent.O_ANSWER:
  298. case BCSMEvent.T_ANSWER:
  299. JccConnectionEvent evt = new JccConnectionEventImpl(
  300. JccConnectionEvent.CONNECTION_CONNECTED,
  301. connection,
  302. JccConnectionEvent.CAUSE_NORMAL);
  303. connection.queueEvent(evt);
  304. break;
  305. case BCSMEvent.O_DISCONNECT:
  306. case BCSMEvent.T_DISCONNECT:
  307. evt = new JccConnectionEventImpl(
  308. JccConnectionEvent.CONNECTION_DISCONNECTED,
  309. connection,
  310. JccConnectionEvent.CAUSE_NORMAL);
  311. connection.queueEvent(evt);
  312. break;
  313. case BCSMEvent.O_CALLED_PARTY_BUSY:
  314. case BCSMEvent.T_BUSY:
  315. evt = new JccConnectionEventImpl(
  316. JccConnectionEvent.CONNECTION_DISCONNECTED,
  317. connection,
  318. JccConnectionEvent.CAUSE_BUSY);
  319. connection.queueEvent(evt);
  320. break;
  321. case BCSMEvent.O_NO_ANSWER:
  322. case BCSMEvent.T_NO_ANSWER:
  323. evt = new JccConnectionEventImpl(
  324. JccConnectionEvent.CONNECTION_DISCONNECTED,
  325. connection,
  326. JccConnectionEvent.CAUSE_NO_ANSWER);
  327. connection.queueEvent(evt);
  328. break;
  329. }
  330. } catch (IOException e) {
  331. // TODO Auto-generated catch block
  332. e.printStackTrace();
  333. }
  334. break;
  335. default:
  336. if (logger.isDebugEnabled()) {
  337. logger.debug("Ignoring operation: "+operation.getLocalOperationCode());
  338. }
  339. break;
  340. }
  341. }
  342. break;
  343. case UAbort:
  344. case PAbort:
  345. connection = provider.getConnection(txID);
  346. if (connection == null) {
  347. logger.warn("Unknown connection " + txID);
  348. return;
  349. }
  350. JccConnectionEvent evt = new JccConnectionEventImpl(
  351. JccConnectionEvent.CONNECTION_FAILED,
  352. connection,
  353. JccEvent.CAUSE_CALL_CANCELLED);
  354. connection.queueEvent(evt);
  355. }
  356. }
  357. }