/* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * Copyright (C) 2005/2011, Anthony Minessale II * * Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * * The Initial Developer of the Original Code is * Anthony Minessale II * Portions created by the Initial Developer are Copyright (C) * the Initial Developer. All Rights Reserved. * * This module (mod_gsmopen) has been contributed by: * * Giovanni Maruzzelli (gmaruzz@gmail.com) * * * Further Contributors: * * * * mod_gsmopen.c -- GSM compatible Endpoint Module * */ #define __STDC_LIMIT_MACROS #ifdef WIN32 #define HAVE_VSNPRINTF #pragma warning(disable: 4290) #endif //WIN32 #define MY_EVENT_INCOMING_SMS "gsmopen::incoming_sms" #define MY_EVENT_DUMP "gsmopen::dump_event" #define MY_EVENT_ALARM "gsmopen::alarm" #define ALARM_FAILED_INTERFACE 0 #define ALARM_NO_NETWORK_REGISTRATION 1 #define ALARM_ROAMING_NETWORK_REGISTRATION 2 #define ALARM_NETWORK_NO_SERVICE 3 #define ALARM_NETWORK_NO_SIGNAL 4 #define ALARM_NETWORK_LOW_SIGNAL 5 #undef GIOVA48 #ifndef GIOVA48 #define SAMPLES_PER_FRAME 160 #else // GIOVA48 #define SAMPLES_PER_FRAME 960 #endif // GIOVA48 #ifndef GIOVA48 #define GSMOPEN_FRAME_SIZE 160 #else //GIOVA48 #define GSMOPEN_FRAME_SIZE 960 #endif //GIOVA48 #define SAMPLERATE_GSMOPEN 8000 #ifndef NO_ALSA #define GSMOPEN_ALSA #endif // NO_ALSA #include #include #ifndef WIN32 #include #include #include #endif //WIN32 //#include #ifdef GSMOPEN_ALSA #define ALSA_PCM_NEW_HW_PARAMS_API #define ALSA_PCM_NEW_SW_PARAMS_API #include #endif /* GSMOPEN_ALSA */ #ifdef GSMOPEN_PORTAUDIO #include "pablio.h" #undef WANT_SPEEX #ifdef WANT_SPEEX #include "speex/speex_preprocess.h" #include "speex/speex_echo.h" #endif /* WANT_SPEEX */ #endif// GSMOPEN_PORTAUDIO //#include "celliax_spandsp.h" #ifndef WIN32 #include //#include //#include //#include #endif //WIN32 #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES #include #include #ifdef _MSC_VER //Windows macro for FD_SET includes a warning C4127: conditional expression is constant #pragma warning(push) #pragma warning(disable:4127) #endif #define PROTOCOL_ALSA_VOICEMODEM 4 #define PROTOCOL_AT 2 #define PROTOCOL_FBUS2 1 #define PROTOCOL_NO_SERIAL 3 #define AT_BUFSIZ 8192 //FIXME FIXME FIXME #define AT_MESG_MAX_LENGTH 2048 /* much more than 10 SMSs */ #define AT_MESG_MAX_LENGTH 2048 /* much more than 10 SMSs */ //FIXME FIXME FIXME #define AT_MESG_MAX_LINES 256 /* 256 lines, so it can contains the results of AT+CLAC, that gives all the AT commands the phone supports */ #define AT_MESG_MAX_LINES 20 /* 256 lines, so it can contains the results of AT+CLAC, that gives all the AT commands the phone supports */ //#define SAMPLERATE_GSMOPEN 16000 //#define SAMPLES_PER_FRAME SAMPLERATE_GSMOPEN/50 #ifndef GSMOPEN_SVN_VERSION #define GSMOPEN_SVN_VERSION SWITCH_VERSION_REVISION #endif /* GSMOPEN_SVN_VERSION */ typedef enum { TFLAG_IO = (1 << 0), TFLAG_INBOUND = (1 << 1), TFLAG_OUTBOUND = (1 << 2), TFLAG_DTMF = (1 << 3), TFLAG_VOICE = (1 << 4), TFLAG_HANGUP = (1 << 5), TFLAG_LINEAR = (1 << 6), TFLAG_CODEC = (1 << 7), TFLAG_BREAK = (1 << 8) } TFLAGS; typedef enum { GFLAG_MY_CODEC_PREFS = (1 << 0) } GFLAGS; #define DEBUGA_GSMOPEN(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "rev "GSMOPEN_SVN_VERSION "[%p|%-7lx][DEBUG_GSMOPEN %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); #define DEBUGA_CALL(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "rev "GSMOPEN_SVN_VERSION "[%p|%-7lx][DEBUG_CALL %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); #define DEBUGA_PBX(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "rev "GSMOPEN_SVN_VERSION "[%p|%-7lx][DEBUG_PBX %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); #define ERRORA(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "rev "GSMOPEN_SVN_VERSION "[%p|%-7lx][ERRORA %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); #define WARNINGA(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "rev "GSMOPEN_SVN_VERSION "[%p|%-7lx][WARNINGA %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); #define NOTICA(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "rev "GSMOPEN_SVN_VERSION "[%p|%-7lx][NOTICA %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); #define GSMOPEN_P_LOG (void *)NULL, (unsigned long)55, __LINE__, tech_pvt ? tech_pvt->name ? tech_pvt->name : "none" : "none", -1, tech_pvt ? tech_pvt->interface_state : -1, tech_pvt ? tech_pvt->phone_callflow : -1 /*********************************/ #define GSMOPEN_CAUSE_NORMAL 1 #define GSMOPEN_CAUSE_FAILURE 2 #define GSMOPEN_CAUSE_NO_ANSWER 3 /*********************************/ #define GSMOPEN_FRAME_DTMF 1 /*********************************/ #define GSMOPEN_CONTROL_RINGING 1 #define GSMOPEN_CONTROL_ANSWER 2 #define GSMOPEN_CONTROL_HANGUP 3 #define GSMOPEN_CONTROL_BUSY 4 /*********************************/ #define GSMOPEN_STATE_IDLE 0 #define GSMOPEN_STATE_DOWN 1 #define GSMOPEN_STATE_RING 2 #define GSMOPEN_STATE_DIALING 3 #define GSMOPEN_STATE_BUSY 4 #define GSMOPEN_STATE_UP 5 #define GSMOPEN_STATE_RINGING 6 #define GSMOPEN_STATE_PRERING 7 #define GSMOPEN_STATE_ERROR_DOUBLE_CALL 8 #define GSMOPEN_STATE_SELECTED 9 #define GSMOPEN_STATE_HANGUP_REQUESTED 10 #define GSMOPEN_STATE_PREANSWER 11 /*********************************/ /* call flow from the device */ #define CALLFLOW_CALL_IDLE 0 #define CALLFLOW_CALL_DOWN 1 #define CALLFLOW_INCOMING_RING 2 #define CALLFLOW_CALL_DIALING 3 #define CALLFLOW_CALL_LINEBUSY 4 #define CALLFLOW_CALL_ACTIVE 5 #define CALLFLOW_INCOMING_HANGUP 6 #define CALLFLOW_CALL_RELEASED 7 #define CALLFLOW_CALL_NOCARRIER 8 #define CALLFLOW_CALL_INFLUX 9 #define CALLFLOW_CALL_INCOMING 10 #define CALLFLOW_CALL_FAILED 11 #define CALLFLOW_CALL_NOSERVICE 12 #define CALLFLOW_CALL_OUTGOINGRESTRICTED 13 #define CALLFLOW_CALL_SECURITYFAIL 14 #define CALLFLOW_CALL_NOANSWER 15 #define CALLFLOW_STATUS_FINISHED 16 #define CALLFLOW_STATUS_CANCELLED 17 #define CALLFLOW_STATUS_FAILED 18 #define CALLFLOW_STATUS_REFUSED 19 #define CALLFLOW_STATUS_RINGING 20 #define CALLFLOW_STATUS_INPROGRESS 21 #define CALLFLOW_STATUS_UNPLACED 22 #define CALLFLOW_STATUS_ROUTING 23 #define CALLFLOW_STATUS_EARLYMEDIA 24 #define CALLFLOW_INCOMING_CALLID 25 #define CALLFLOW_STATUS_REMOTEHOLD 26 #define CALLFLOW_CALL_REMOTEANSWER 27 #define CALLFLOW_CALL_HANGUP_REQUESTED 28 /*********************************/ #define AT_OK 0 #define AT_ERROR 1 #define GSMOPEN_MAX_INTERFACES 64 #ifndef WIN32 struct GSMopenHandles { //Window gsmopen_win; //Display *disp; //Window win; int currentuserhandle; int api_connected; int fdesc[2]; }; #else //WIN32 struct GSMopenHandles { HWND win32_hInit_MainWindowHandle; HWND win32_hGlobal_GSMAPIWindowHandle; HINSTANCE win32_hInit_ProcessHandle; char win32_acInit_WindowClassName[128]; UINT win32_uiGlobal_MsgID_GSMControlAPIAttach; UINT win32_uiGlobal_MsgID_GSMControlAPIDiscover; int currentuserhandle; int api_connected; switch_file_t *fdesc[2]; }; #endif //WIN32 /*! * \brief structure for storing the results of AT commands, in an array of AT_MESG_MAX_LINES * AT_MESG_MAX_LENGTH chars */ struct s_result { int elemcount; char result[AT_MESG_MAX_LINES][AT_MESG_MAX_LENGTH]; }; struct ciapa_struct { int state; int hangupcause; }; typedef struct ciapa_struct ciapa_t; struct private_object { unsigned int flags; switch_codec_t read_codec; switch_codec_t write_codec; switch_frame_t read_frame; unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; char session_uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; switch_caller_profile_t *caller_profile; switch_mutex_t *mutex; switch_mutex_t *flag_mutex; char id[80]; char name[80]; char dialplan[80]; char context[80]; char dial_regex[256]; char fail_dial_regex[256]; char hold_music[256]; char type[256]; char X11_display[256]; #ifdef WIN32 unsigned short tcp_cli_port; unsigned short tcp_srv_port; #else int tcp_cli_port; int tcp_srv_port; #endif struct GSMopenHandles GSMopenHandles; int interface_state; /*!< \brief 'state' of the interface (channel) */ char language[80]; /*!< \brief default Asterisk dialplan language for this interface */ char exten[80]; /*!< \brief default Asterisk dialplan extension for this interface */ int gsmopen_sound_rate; /*!< \brief rate of the sound device, in Hz, eg: 8000 */ char callid_name[50]; char callid_number[50]; double playback_boost; double capture_boost; int stripmsd; char gsmopen_call_id[512]; int gsmopen_call_ongoing; char gsmopen_friends[4096]; char gsmopen_fullname[512]; char gsmopen_displayname[512]; int phone_callflow; /*!< \brief 'callflow' of the gsmopen interface (as opposed to phone interface) */ int gsmopen; /*!< \brief config flag, bool, GSM support on this interface (0 if false, -1 if true) */ int control_to_send; #ifdef WIN32 switch_file_t *audiopipe[2]; switch_file_t *audiogsmopenpipe[2]; switch_file_t *gsmopen_sound_capt_fd; /*!< \brief file descriptor for sound capture dev */ #else /* WIN32 */ int audiopipe[2]; int audiogsmopenpipe[2]; int gsmopen_sound_capt_fd; /*!< \brief file descriptor for sound capture dev */ #endif /* WIN32 */ switch_thread_t *tcp_srv_thread; switch_thread_t *tcp_cli_thread; switch_thread_t *gsmopen_signaling_thread; switch_thread_t *gsmopen_api_thread; //short audiobuf[SAMPLES_PER_FRAME]; //int audiobuf_is_loaded; //int phonebook_listing; //int phonebook_querying; //int phonebook_listing_received_calls; //int phonebook_first_entry; //int phonebook_last_entry; //int phonebook_number_lenght; //int phonebook_text_lenght; int gsmopen_dir_entry_extension_prefix; char gsmopen_user[256]; char gsmopen_password[256]; char destination[256]; struct timeval answer_time; struct timeval transfer_time; char transfer_callid_number[50]; char gsmopen_transfer_call_id[512]; int running; unsigned long ib_calls; unsigned long ob_calls; unsigned long ib_failed_calls; unsigned long ob_failed_calls; char controldevice_name[50]; /*!< \brief name of the serial device controlling the interface, possibly none */ int controldevprotocol; /*!< \brief which protocol is used for serial control of this interface */ char controldevprotocolname[50]; /*!< \brief name of the serial device controlling protocol, one of "at" "fbus2" "no_serial" "alsa_voicemodem" */ int controldevfd; /*!< \brief serial controlling file descriptor for this interface */ //pthread_t controldev_thread; /*!< \brief serial control thread for this interface, running during the call */ #ifdef WIN32 int controldevice_speed; #else speed_t controldevice_speed; #endif// WIN32 int controldev_dead; char at_dial_pre_number[64]; char at_dial_post_number[64]; char at_dial_expect[64]; unsigned int at_early_audio; char at_hangup[64]; char at_hangup_expect[64]; char at_answer[64]; char at_answer_expect[64]; unsigned int at_initial_pause; char at_preinit_1[64]; char at_preinit_1_expect[64]; char at_preinit_2[64]; char at_preinit_2_expect[64]; char at_preinit_3[64]; char at_preinit_3_expect[64]; char at_preinit_4[64]; char at_preinit_4_expect[64]; char at_preinit_5[64]; char at_preinit_5_expect[64]; unsigned int at_after_preinit_pause; char at_postinit_1[64]; char at_postinit_1_expect[64]; char at_postinit_2[64]; char at_postinit_2_expect[64]; char at_postinit_3[64]; char at_postinit_3_expect[64]; char at_postinit_4[64]; char at_postinit_4_expect[64]; char at_postinit_5[64]; char at_postinit_5_expect[64]; char at_send_dtmf[64]; char at_query_battchg[64]; char at_query_battchg_expect[64]; char at_query_signal[64]; char at_query_signal_expect[64]; char at_call_idle[64]; char at_call_incoming[64]; char at_call_active[64]; char at_call_failed[64]; char at_call_calling[64]; #define CIEV_STRING_SIZE 64 char at_indicator_noservice_string[64]; char at_indicator_nosignal_string[64]; char at_indicator_lowsignal_string[64]; char at_indicator_lowbattchg_string[64]; char at_indicator_nobattchg_string[64]; char at_indicator_callactive_string[64]; char at_indicator_nocallactive_string[64]; char at_indicator_nocallsetup_string[64]; char at_indicator_callsetupincoming_string[64]; char at_indicator_callsetupoutgoing_string[64]; char at_indicator_callsetupremoteringing_string[64]; int at_indicator_callp; int at_indicator_callsetupp; int at_indicator_roamp; int at_indicator_battchgp; int at_indicator_servicep; int at_indicator_signalp; int at_has_clcc; int at_has_ecam; char at_cmgw[16]; int no_ucs2; time_t gsmopen_serial_sync_period; time_t gsmopen_serial_synced_timestamp; struct s_result line_array; int unread_sms_msg_id; int reading_sms_msg; char sms_message[4800]; char sms_sender[256]; char sms_date[256]; char sms_body[4800]; char sms_datacodingscheme[256]; char sms_servicecentreaddress[256]; int sms_messagetype; int sms_cnmi_not_supported; int sms_pdu_not_supported; //char sms_receiving_program[256]; struct timeval call_incoming_time; switch_mutex_t *controldev_lock; int phonebook_listing; int phonebook_querying; int phonebook_listing_received_calls; int phonebook_first_entry; int phonebook_last_entry; int phonebook_number_lenght; int phonebook_text_lenght; FILE *phonebook_writing_fp; struct timeval ringtime; ciapa_t *owner; #ifdef GSMOPEN_ALSA snd_pcm_t *alsac; /*!< \brief handle of the ALSA capture audio device */ snd_pcm_t *alsap; /*!< \brief handle of the ALSA playback audio device */ char alsacname[50]; /*!< \brief name of the ALSA capture audio device */ char alsapname[50]; /*!< \brief name of the ALSA playback audio device */ int alsa_period_size; /*!< \brief ALSA period_size, in byte */ int alsa_periods_in_buffer; /*!< \brief how many periods in ALSA buffer, to calculate buffer_size */ unsigned long int alsa_buffer_size; /*!< \brief ALSA buffer_size, in byte */ int alsawrite_filled; int alsa_capture_is_mono; int alsa_play_is_mono; struct pollfd pfd; #endif // GSMOPEN_ALSA time_t audio_play_reset_timestamp; int audio_play_reset_period; switch_timer_t timer_read; switch_timer_t timer_write; teletone_dtmf_detect_state_t dtmf_detect; switch_time_t old_dtmf_timestamp; int no_sound; #ifdef GSMOPEN_PORTAUDIO int speexecho; int speexpreprocess; int portaudiocindex; /*!< \brief Index of the Portaudio capture audio device */ int portaudiopindex; /*!< \brief Index of the Portaudio playback audio device */ PABLIO_Stream *stream; #ifdef WANT_SPEEX SpeexPreprocessState *preprocess; SpeexEchoState *echo_state; #endif// WANT_SPEEX #endif// GSMOPEN_PORTAUDIO dtmf_rx_state_t dtmf_state; int active; int home_network_registered; int roaming_registered; int not_registered; int got_signal; char imei[128]; int requesting_imei; char imsi[128]; int requesting_imsi; int network_creg_not_supported; char creg[128]; }; typedef struct private_object private_t; void *SWITCH_THREAD_FUNC gsmopen_api_thread_func(switch_thread_t * thread, void *obj); int gsmopen_audio_read(private_t * tech_pvt); int gsmopen_audio_init(private_t * tech_pvt); int gsmopen_signaling_read(private_t * tech_pvt); int gsmopen_call(private_t * tech_pvt, char *idest, int timeout); int gsmopen_senddigit(private_t * tech_pvt, char digit); void *gsmopen_do_tcp_srv_thread_func(void *obj); void *SWITCH_THREAD_FUNC gsmopen_do_tcp_srv_thread(switch_thread_t * thread, void *obj); void *gsmopen_do_tcp_cli_thread_func(void *obj); void *SWITCH_THREAD_FUNC gsmopen_do_tcp_cli_thread(switch_thread_t * thread, void *obj); void *gsmopen_do_gsmopenapi_thread_func(void *obj); void *SWITCH_THREAD_FUNC gsmopen_do_gsmopenapi_thread(switch_thread_t * thread, void *obj); int dtmf_received(private_t * tech_pvt, char *value); int start_audio_threads(private_t * tech_pvt); int new_inbound_channel(private_t * tech_pvt); int outbound_channel_answered(private_t * tech_pvt); //int gsmopen_signaling_write(private_t * tech_pvt, char *msg_to_gsmopen); #if defined(WIN32) && !defined(__CYGWIN__) int gsmopen_pipe_read(switch_file_t * pipe, short *buf, int howmany); int gsmopen_pipe_write(switch_file_t * pipe, short *buf, int howmany); /* Visual C do not have strsep ? */ char *strsep(char **stringp, const char *delim); #else int gsmopen_pipe_read(int pipe, short *buf, int howmany); int gsmopen_pipe_write(int pipe, short *buf, int howmany); #endif /* WIN32 */ int gsmopen_close_socket(unsigned int fd); private_t *find_available_gsmopen_interface_rr(private_t * tech_pvt_calling); int remote_party_is_ringing(private_t * tech_pvt); int remote_party_is_early_media(private_t * tech_pvt); //int gsmopen_answer(private_t * tech_pvt, char *id, char *value); #if 0 int gsmopen_transfer(private_t * tech_pvt, char *id, char *value); #endif //0 int gsmopen_socket_create_and_bind(private_t * tech_pvt, int *which_port); void *gsmopen_do_controldev_thread(void *data); #ifdef WIN32 int gsmopen_serial_init(private_t * tech_pvt, int controldevice_speed); #else int gsmopen_serial_init(private_t * tech_pvt, speed_t controldevice_speed); #endif //WIN32 int gsmopen_serial_monitor(private_t * tech_pvt); int gsmopen_serial_sync(private_t * tech_pvt); int gsmopen_serial_sync_AT(private_t * tech_pvt); int gsmopen_serial_config(private_t * tech_pvt); int gsmopen_serial_config_AT(private_t * tech_pvt); #define gsmopen_serial_write_AT_expect(P, D, S) gsmopen_serial_write_AT_expect1(P, D, S, 1, 2) #define gsmopen_serial_write_AT_expect_noexpcr(P, D, S) gsmopen_serial_write_AT_expect1(P, D, S, 0, 2) #define gsmopen_serial_write_AT_expect_noexpcr_tout(P, D, S, T) gsmopen_serial_write_AT_expect1(P, D, S, 0, T) // 20.5 sec timeout, used for querying the SIM and sending SMSs #define gsmopen_serial_write_AT_expect_longtime(P, D, S) gsmopen_serial_write_AT_expect1(P, D, S, 1, 20) #define gsmopen_serial_write_AT_expect_longtime_noexpcr(P, D, S) gsmopen_serial_write_AT_expect1(P, D, S, 0, 20) int gsmopen_serial_write_AT(private_t * tech_pvt, const char *data); int gsmopen_serial_write_AT_nocr(private_t * tech_pvt, const char *data); int gsmopen_serial_write_AT_ack(private_t * tech_pvt, const char *data); int gsmopen_serial_write_AT_ack_nocr_longtime(private_t * tech_pvt, const char *data); int gsmopen_serial_write_AT_noack(private_t * tech_pvt, const char *data); int gsmopen_serial_write_AT_expect1(private_t * tech_pvt, const char *data, const char *expected_string, int expect_crlf, int seconds); int gsmopen_serial_AT_expect(private_t * tech_pvt, const char *expected_string, int expect_crlf, int seconds); int gsmopen_serial_read_AT(private_t * tech_pvt, int look_for_ack, int timeout_usec, int timeout_sec, const char *expected_string, int expect_crlf); int gsmopen_serial_read(private_t * tech_pvt); #ifdef NOTDEF int gsmopen_serial_getstatus(private_t * tech_pvt); int gsmopen_serial_hangup(private_t * tech_pvt); int gsmopen_serial_answer(private_t * tech_pvt); int gsmopen_serial_answer_AT(private_t * tech_pvt); int gsmopen_serial_hangup_AT(private_t * tech_pvt); int gsmopen_serial_call_AT(private_t * tech_pvt, char *dstr); int gsmopen_serial_getstatus_AT(private_t * tech_pvt); #endif // NOTDEF #define RESULT_FAILURE 0 #define RESULT_SUCCESS 1 int utf_to_ucs2(private_t * tech_pvt, char *utf_in, size_t inbytesleft, char *ucs2_out, size_t outbytesleft); int ucs2_to_utf8(private_t * tech_pvt, char *ucs2_in, char *utf8_out, size_t outbytesleft); //#define PUSHA_UNLOCKA(x) pthread_cleanup_push(gsmopen_unlocka_log, (void *) x); //#define POPPA_UNLOCKA(x) pthread_cleanup_pop(0); #define PUSHA_UNLOCKA(x) if(option_debug > 100) ERRORA("PUSHA_UNLOCKA: %p\n", GSMOPEN_P_LOG, (void *)x); #define POPPA_UNLOCKA(x) if(option_debug > 100) ERRORA("POPPA_UNLOCKA: %p\n", GSMOPEN_P_LOG, (void *)x); //#define LOKKA(x) if(option_debug > 100) ERRORA("LOKKA: %p\n", GSMOPEN_P_LOG, (void *)x); #define LOKKA(x) switch_mutex_lock(x); #define UNLOCKA(x) switch_mutex_unlock(x); //#define UNLOCKA(x) if(option_debug > 100) ERRORA("UNLOCKA: %p\n", GSMOPEN_P_LOG, (void *)x); #define gsmopen_queue_control(x, y) ERRORA("gsmopen_queue_control: %p, %d\n", GSMOPEN_P_LOG, (void *)x, y); #define ast_setstate(x, y) ERRORA("ast_setstate: %p, %d\n", GSMOPEN_P_LOG, (void *)x, y); int gsmopen_serial_read(private_t * tech_pvt); int gsmopen_answer(private_t * tech_pvt); int gsmopen_serial_answer(private_t * tech_pvt); int gsmopen_serial_answer_AT(private_t * tech_pvt); int gsmopen_serial_hangup(private_t * tech_pvt); int gsmopen_serial_hangup_AT(private_t * tech_pvt); int gsmopen_hangup(private_t * tech_pvt); int gsmopen_serial_call(private_t * tech_pvt, char *dstr); int gsmopen_serial_call_AT(private_t * tech_pvt, char *dstr); int gsmopen_sendsms(private_t * tech_pvt, char *dest, char *text); #ifdef GSMOPEN_ALSA int alsa_init(private_t * tech_pvt); int alsa_shutdown(private_t * tech_pvt); snd_pcm_t *alsa_open_dev(private_t * tech_pvt, snd_pcm_stream_t stream); int alsa_write(private_t * tech_pvt, short *data, int datalen); int alsa_read(private_t * tech_pvt, short *data, int datalen); #endif /* GSMOPEN_ALSA */ void gsmopen_store_boost(char *s, double *boost); int gsmopen_sound_boost(void *data, int samples_num, double boost); int sms_incoming(private_t * tech_pvt); int gsmopen_ring(private_t * tech_pvt); int iso_8859_1_to_utf8(private_t * tech_pvt, char *iso_8859_1_in, char *utf8_out, size_t outbytesleft); int gsmopen_serial_getstatus_AT(private_t * tech_pvt); #ifdef GSMOPEN_PORTAUDIO int gsmopen_portaudio_devlist(private_t *tech_pvt); int gsmopen_portaudio_init(private_t *tech_pvt); int gsmopen_portaudio_write(private_t * tech_pvt, short *data, int datalen); int gsmopen_portaudio_read(private_t * tech_pvt, short *data, int datalen); int gsmopen_portaudio_shutdown(private_t *tech_pvt); #endif // GSMOPEN_PORTAUDIO int dump_event(private_t *tech_pvt); int alarm_event(private_t * tech_pvt, int alarm_code, const char *alarm_message); int dump_event_full(private_t * tech_pvt, int is_alarm, int alarm_code, const char *alarm_message);