00001 00008 /*************************************************************************** 00009 * * 00010 * This program is free software; you can redistribute it and/or modify * 00011 * it under the terms of the GNU General Public License as published by * 00012 * the Free Software Foundation; either version 2 of the License, or * 00013 * (at your option) any later version. * 00014 * * 00015 ***************************************************************************/ 00016 00017 #ifndef CONNECTION_H 00018 #define CONNECTION_H 00019 00020 #include <capi20.h> 00021 #include <vector> 00022 #include <string> 00023 #include <fstream> 00024 #include "capiexception.h" 00025 00026 class CallInterface; 00027 class Capi; 00028 00029 using namespace std; 00030 00049 class Connection 00050 { 00051 friend class Capi; 00052 00053 public: 00064 enum service_t { 00065 VOICE, 00066 FAXG3, 00067 OTHER 00068 }; 00069 00088 Connection (Capi* capi, _cdword controller, string call_from, bool clir, string call_to, service_t service, string faxStationID, string faxHeadline) throw (CapiExternalError, CapiMsgError); 00089 00100 ~Connection(); 00101 00106 void registerCallInterface(CallInterface *call_if); 00107 00126 void changeProtocol (service_t desired_service, string faxStationID, string faxHeadline) throw (CapiMsgError, CapiExternalError, CapiWrongState); 00127 00140 void start_file_transmission(string filename) throw (CapiWrongState, CapiExternalError, CapiMsgError); 00141 00146 void stop_file_transmission(); 00147 00159 void start_file_reception(string filename) throw (CapiWrongState, CapiExternalError); 00160 00165 void stop_file_reception(); 00166 00169 enum disconnect_mode_t { 00170 ALL, 00171 PHYSICAL_ONLY, 00172 LOGICAL_ONLY 00173 }; 00174 00193 void disconnectCall(disconnect_mode_t disconnect_mode=ALL) throw (CapiMsgError); 00194 00206 void connectWaiting(service_t desired_service, string faxStationID="", string faxHeadline="") throw (CapiWrongState, CapiExternalError, CapiMsgError); 00207 00217 void rejectWaiting(_cword reject) throw (CapiWrongState, CapiMsgError, CapiExternalError); 00218 00228 void acceptWaiting() throw (CapiMsgError, CapiWrongState); 00229 00239 void enableDTMF() throw (CapiWrongState, CapiMsgError); 00240 00246 void disableDTMF() throw (CapiWrongState, CapiMsgError); 00247 00254 string getDTMF(); 00255 00258 void clearDTMF(); 00259 00264 string getCalledPartyNumber(); 00265 00270 string getCallingPartyNumber(); 00271 00276 service_t getService(); 00277 00285 _cword getCause(); 00286 00294 _cword getCauseB3(); 00295 00296 00299 enum connection_state_t { 00300 DOWN, 00301 WAITING, 00302 UP, 00303 OTHER_STATE 00304 }; 00305 00310 connection_state_t getState(); 00311 00317 struct fax_info_t { 00318 int rate; 00319 bool hiRes; 00320 unsigned short format; 00321 int pages; 00322 std::string stationID; 00323 }; 00324 00329 fax_info_t* getFaxInfo(); 00330 00338 void errorMessage(string message); 00339 00340 00349 void debugMessage(string message, unsigned short level); 00350 00351 protected: 00352 00367 Connection (_cmsg& message, Capi *capi, unsigned short DDILength=0, unsigned short DDIBaseLength=0, std::vector<std::string> DDIStopNumbers=std::vector<std::string>()); 00368 00369 /********************************************************************************/ 00370 /* methods handling CAPI messages - called by the Capi class */ 00371 /********************************************************************************/ 00372 00373 /*************************** INDICATIONS ****************************************/ 00374 00384 void connect_active_ind(_cmsg& message) throw (CapiWrongState, CapiMsgError); 00385 00394 void connect_b3_ind(_cmsg& message) throw (CapiWrongState, CapiMsgError); 00395 00404 void connect_b3_active_ind(_cmsg& message) throw (CapiWrongState, CapiExternalError); 00405 00414 void data_b3_ind(_cmsg& message) throw (CapiWrongState,CapiMsgError); 00415 00424 void facility_ind_DTMF(_cmsg& message) throw (CapiWrongState); 00425 00433 void info_ind_alerting(_cmsg& message) throw (CapiWrongState); 00434 00445 bool info_ind_called_party_nr(_cmsg& message) throw (CapiWrongState); 00446 00455 void disconnect_b3_ind(_cmsg& message) throw (CapiWrongState); 00456 00465 void disconnect_ind(_cmsg& message) throw (CapiWrongState, CapiMsgError); 00466 00467 /*************************** CONFIRMATIONS **************************************/ 00468 00475 void connect_conf(_cmsg& message) throw (CapiWrongState, CapiMsgError); 00476 00483 void connect_b3_conf(_cmsg& message) throw (CapiWrongState, CapiMsgError); 00484 00491 void select_b_protocol_conf(_cmsg& message) throw (CapiWrongState, CapiMsgError); 00492 00499 void alert_conf(_cmsg& message) throw (CapiWrongState, CapiMsgError); 00500 00510 void data_b3_conf(_cmsg& message) throw (CapiWrongState, CapiMsgError, CapiExternalError); 00511 00518 void facility_conf_DTMF(_cmsg& message) throw (CapiWrongState, CapiMsgError); 00519 00526 void disconnect_b3_conf(_cmsg& message) throw (CapiWrongState, CapiMsgError); 00527 00534 void disconnect_conf(_cmsg& message) throw (CapiWrongState, CapiMsgError); 00535 00536 /********************************************************************************/ 00537 /* internal methods */ 00538 /********************************************************************************/ 00539 00544 string prefix(); 00545 00552 string getNumber (_cstruct capi_input, bool isCallingNr); 00553 00566 void send_block() throw (CapiWrongState, CapiExternalError, CapiMsgError); 00567 00588 void buildBconfiguration(_cdword controller, service_t service, string faxStationID, string faxHeadline, _cword& B1proto, _cword& B2proto, _cword& B3proto, _cstruct& B1config, _cstruct& B2config, _cstruct& B3config) throw (CapiExternalError); 00589 00599 void convertToCP437(string &text); 00600 00601 /********************************************************************************/ 00602 /* attributes */ 00603 /********************************************************************************/ 00604 00610 enum plci_state_t { 00611 P0, 00612 P01, 00613 P1, 00614 P2, 00615 P3, 00616 P4, 00617 P5, 00618 P6, 00619 PACT 00620 } plci_state; 00621 00626 enum ncci_state_t { 00627 N0, 00628 N01, 00629 N1, 00630 N2, 00631 N3, 00632 N4, 00633 N5, 00634 NACT 00635 } ncci_state; 00636 00637 _cdword plci; 00638 _cdword ncci; 00639 00640 service_t service; 00641 00642 _cword connect_ind_msg_nr; 00643 00644 _cword disconnect_cause, 00645 disconnect_cause_b3; 00646 00647 string call_from; 00648 string call_to; 00649 00650 string received_dtmf; 00651 00652 bool keepPhysicalConnection, 00653 our_call; 00654 00655 CallInterface *call_if; 00656 Capi *capi; 00657 00658 pthread_mutex_t send_mutex, 00659 receive_mutex; 00660 00661 ofstream *file_for_reception; 00662 ifstream *file_to_send; 00663 00664 ostream &debug, 00665 &error; 00666 unsigned short debug_level; 00667 00676 char send_buffer[7][2048]; 00677 00678 unsigned short buffer_start, 00679 buffers_used; 00680 00681 fax_info_t* fax_info; 00682 00683 unsigned short DDILength; 00684 unsigned short DDIBaseLength; 00685 vector<string> DDIStopNumbers; 00686 }; 00687 00688 #endif 00689 00690 /* History 00691 00692 $Log: connection.h,v $ 00693 Revision 1.6.2.4 2003/11/11 21:05:41 gernot 00694 - fix typo in comment 00695 00696 Revision 1.6.2.3 2003/11/02 14:58:16 gernot 00697 - use DDI_base_length instead of DDI_base 00698 - added DDI_stop_numbers option 00699 - use DDI_* options in the Connection class 00700 - call the Python script if number is complete 00701 00702 Revision 1.6.2.2 2003/11/01 22:59:33 gernot 00703 - read CalledPartyNr InfoElements 00704 00705 Revision 1.6.2.1 2003/10/26 16:51:55 gernot 00706 - begin implementation of DDI, get DDI Info Elements 00707 00708 Revision 1.6 2003/06/28 12:49:47 gernot 00709 - convert fax headline to CP437, so that german umlauts and other special 00710 characters will work now 00711 00712 Revision 1.5 2003/05/25 13:38:30 gernot 00713 - support reception of color fax documents 00714 00715 Revision 1.4 2003/05/24 13:48:54 gernot 00716 - get fax details (calling station ID, transfer format, ...), handle PLCI 00717 00718 Revision 1.3 2003/04/17 10:39:42 gernot 00719 - support ALERTING notification (to know when it's ringing on the other side) 00720 - cosmetical fixes in capi.cpp 00721 00722 Revision 1.2 2003/04/04 09:17:59 gernot 00723 - buildBconfiguration() now checks the abilities of the given controller 00724 and throws an error if it doesn't support the service 00725 - it also sets the fax protocol setting now the highest available ability 00726 (fax G3 or fax G3 extended) of the controller, thus preparing fax polling 00727 and *working around a severe bug in the AVM drivers producing a kernel 00728 oops* with some analog fax devices. AVM knows about this and analyzes it. 00729 00730 Revision 1.1.1.1 2003/02/19 08:19:53 gernot 00731 initial checkin of 0.4 00732 00733 Revision 1.30 2003/02/10 14:20:52 ghillie 00734 merged from NATIVE_PTHREADS to HEAD 00735 00736 Revision 1.29.2.1 2003/02/10 14:07:54 ghillie 00737 - use pthread_mutex_* instead of CommonC++ Semaphore 00738 00739 Revision 1.29 2003/01/04 16:08:22 ghillie 00740 - log improvements: log_level, timestamp 00741 - added methods debugMessage(), errorMessage(), removed get*Stream() 00742 - added some additional debug output for connection setup / finish 00743 00744 Revision 1.28 2002/12/16 13:13:47 ghillie 00745 - added getCauseB3 to return B3 cause 00746 00747 Revision 1.27 2002/12/13 11:46:59 ghillie 00748 - added attribute our_call to differ outgoing and incoming calls 00749 00750 Revision 1.26 2002/12/11 13:39:05 ghillie 00751 - added support for PHYSICAL_ONLY disconnect in disconnectCall() 00752 00753 Revision 1.25 2002/12/10 15:06:15 ghillie 00754 - new methods get*Stream() for use in capisuitemodule 00755 00756 Revision 1.24 2002/12/09 15:42:24 ghillie 00757 - save debug and error stream in own attributes 00758 00759 Revision 1.23 2002/12/06 15:25:47 ghillie 00760 - new return value for getState(): WAITING 00761 00762 Revision 1.22 2002/12/06 13:07:36 ghillie 00763 - update docs because application is now responsible to delete 00764 Connection object 00765 - new methods getCause() and getState() 00766 00767 Revision 1.21 2002/12/05 15:05:12 ghillie 00768 - moved constructor for incoming calls to "private:" 00769 00770 Revision 1.20 2002/12/02 12:31:36 ghillie 00771 renamed Connection::SPEECH to Connection::VOICE 00772 00773 Revision 1.19 2002/11/29 10:25:01 ghillie 00774 - updated comments, use doxygen format now 00775 00776 Revision 1.18 2002/11/27 16:03:20 ghillie 00777 updated comments for doxygen 00778 00779 Revision 1.17 2002/11/25 11:51:54 ghillie 00780 - removed the unhandy CIP parameters from the interface to the application layer, use service type instead 00781 - rejectWaiting() tests against cause!=0 now 00782 - removed isUp() method 00783 00784 Revision 1.16 2002/11/22 15:13:44 ghillie 00785 - new attribute keepPhysicalConnection which prevents disconnect_b3_ind() from sending disconnect_req() 00786 - moved the ugly B*configuration, B*protocol settings from some methods to private method buildBconfiguration 00787 - new methods changeProtocol(), select_b_protocol_conf(), clearDTMF() 00788 - disconnect_b3_ind sets ncci_state to N0 before calling the callbacks 00789 - added parameter disconnect_mode to disconnectCall() 00790 - getDTMF() does non-destructive read now 00791 00792 Revision 1.15 2002/11/21 15:30:28 ghillie 00793 - added new method Connection::acceptWaiting() - sends ALERT_REQ 00794 - updated description of Connection::connectWaiting() 00795 00796 Revision 1.14 2002/11/19 15:57:19 ghillie 00797 - Added missing throw() declarations 00798 - phew. Added error handling. All exceptions are caught now. 00799 00800 Revision 1.13 2002/11/18 14:24:09 ghillie 00801 - moved global severity_t to CapiError::severity_t 00802 - added throw() declarations 00803 00804 Revision 1.12 2002/11/18 12:24:33 ghillie 00805 - changed disconnectCall() so that it doesn't throw exceptions any more, 00806 so that we can call it in any state 00807 00808 Revision 1.11 2002/11/17 14:40:55 ghillie 00809 added isUp() 00810 00811 Revision 1.10 2002/11/15 15:25:53 ghillie 00812 added ALERT_REQ so we don't loose a call when we wait before connection establishment 00813 00814 Revision 1.9 2002/11/15 13:49:10 ghillie 00815 fix: callmodule wasn't aborted when call was only connected/disconnected physically 00816 00817 Revision 1.8 2002/11/14 17:05:19 ghillie 00818 major structural changes - much is easier, nicer and better prepared for the future now: 00819 - added DisconnectLogical handler to CallInterface 00820 - DTMF handling moved from CallControl to Connection 00821 - new call module ConnectModule for establishing connection 00822 - python script reduced from 2 functions to one (callWaiting, callConnected 00823 merged to callIncoming) 00824 - call modules implement the CallInterface now, not CallControl any more 00825 => this freed CallControl from nearly all communication stuff 00826 00827 Revision 1.7 2002/11/13 08:34:54 ghillie 00828 moved history to the bottom 00829 00830 Revision 1.6 2002/11/10 17:05:18 ghillie 00831 changed to support multiple buffers -> deadlock in stop_file_transmission!! 00832 00833 Revision 1.5 2002/11/08 07:57:07 ghillie 00834 added functions to initiate a call 00835 corrected FACILITY calls to use PLCI instead of NCCI in DTMF processing as told by Mr. Ortmann on comp.dcom.isdn.capi 00836 00837 Revision 1.4 2002/10/31 12:40:06 ghillie 00838 added DTMF support 00839 small fixes like making some unnecessary global variables local, removed some unnecessary else cases 00840 00841 Revision 1.3 2002/10/30 14:29:25 ghillie 00842 added getCIPvalue 00843 00844 Revision 1.2 2002/10/29 14:27:42 ghillie 00845 added stop_file_*, added semaphores 00846 00847 Revision 1.1 2002/10/25 13:29:38 ghillie 00848 grouped files into subdirectories 00849 00850 Revision 1.10 2002/10/10 12:45:40 gernot 00851 added AudioReceive module, some small details changed 00852 00853 Revision 1.9 2002/10/09 11:18:59 gernot 00854 cosmetic changes (again...) and changed info function of CAPI class 00855 00856 Revision 1.8 2002/10/04 15:48:03 gernot 00857 structure changes completed & compiles now! 00858 00859 Revision 1.7 2002/10/04 13:27:15 gernot 00860 some restructuring to get it to a working state ;-) 00861 00862 does not do anything useful yet nor does it even compile... 00863 00864 Revision 1.6 2002/10/01 09:02:04 gernot 00865 changes for compilation with gcc3.2 00866 00867 Revision 1.5 2002/09/22 14:22:53 gernot 00868 some cosmetic comment improvements ;-) 00869 00870 Revision 1.4 2002/09/19 12:08:19 gernot 00871 added magic CVS strings 00872 00873 * Sun Sep 15 2002 - gernot@hillier.de 00874 - put under CVS, cvs changelog follows above 00875 00876 * Sun May 20 2002 - gernot@hillier.de 00877 - first version 00878 00879 */