freeswitch/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp

3215 lines
120 KiB
C++

#include "gsmopen.h"
#ifdef WIN32
#include "win_iconv.c"
#endif // WIN32
#define WANT_GSMLIB
#ifdef WANT_GSMLIB
#include <gsmlib/gsm_sms.h>
//#ifdef WIN32
//#include <gsmlib/gsm_win32_serial.h>
//#else
//#include <gsmlib/gsm_unix_serial.h>
//#endif
//#include <gsmlib/gsm_me_ta.h>
//#include <iostream>
using namespace std;
using namespace gsmlib;
#endif // WANT_GSMLIB
extern int running; //FIXME
int gsmopen_dir_entry_extension = 1; //FIXME
int option_debug = 100; //FIXME
#define gsmopen_sleep switch_sleep
#define gsmopen_strncpy switch_copy_string
extern switch_memory_pool_t *gsmopen_module_pool;
extern switch_endpoint_interface_t *gsmopen_endpoint_interface;
#ifdef WIN32
/***************/
// from http://www.openasthra.com/c-tidbits/gettimeofday-function-for-windows/
#include <time.h>
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#else /* */
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
#endif /* */
struct sk_timezone {
int tz_minuteswest; /* minutes W of Greenwich */
int tz_dsttime; /* type of dst correction */
};
int gettimeofday(struct timeval *tv, struct sk_timezone *tz)
{
FILETIME ft;
unsigned __int64 tmpres = 0;
static int tzflag;
if (NULL != tv) {
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch */
tmpres /= 10; /*convert into microseconds */
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tv->tv_sec = (long) (tmpres / 1000000UL);
tv->tv_usec = (long) (tmpres % 1000000UL);
}
if (NULL != tz) {
if (!tzflag) {
_tzset();
tzflag++;
}
tz->tz_minuteswest = _timezone / 60;
tz->tz_dsttime = _daylight;
}
return 0;
}
/***************/
#endif /* WIN32 */
int gsmopen_serial_init(private_t *tech_pvt, int controldevice_speed)
{
tech_pvt->serialPort_serial_control = new ctb::SerialPort();
if (tech_pvt->serialPort_serial_control->Open(tech_pvt->controldevice_name, 115200, "8N1", ctb::SerialPort::NoFlowControl) >= 0) {
DEBUGA_GSMOPEN("port %s, SUCCESS open\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name);
} else {
ERRORA("port %s, NOT open\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name);
return -1;
}
return 0;
}
int gsmopen_serial_read(private_t *tech_pvt)
{
if (tech_pvt->controldevprotocol == PROTOCOL_AT)
return gsmopen_serial_read_AT(tech_pvt, 0, 100000, 0, NULL, 1); // a 10th of a second timeout
#ifdef GSMOPEN_FBUS2
if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2)
return gsmopen_serial_read_FBUS2(tech_pvt);
#endif /* GSMOPEN_FBUS2 */
#ifdef GSMOPEN_CVM
if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL)
return gsmopen_serial_read_CVM_BUSMAIL(tech_pvt);
#endif /* GSMOPEN_CVM */
return -1;
}
int gsmopen_serial_sync(private_t *tech_pvt)
{
if (tech_pvt->controldevprotocol == PROTOCOL_AT)
return gsmopen_serial_sync_AT(tech_pvt);
#ifdef GSMOPEN_FBUS2
if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2)
return gsmopen_serial_sync_FBUS2(tech_pvt);
#endif /* GSMOPEN_FBUS2 */
#ifdef GSMOPEN_CVM
if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL)
return gsmopen_serial_sync_CVM_BUSMAIL(tech_pvt);
#endif /* GSMOPEN_CVM */
return -1;
}
int gsmopen_serial_config(private_t *tech_pvt)
{
if (tech_pvt->controldevprotocol == PROTOCOL_AT)
return gsmopen_serial_config_AT(tech_pvt);
#ifdef GSMOPEN_FBUS2
if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2)
return gsmopen_serial_config_FBUS2(tech_pvt);
#endif /* GSMOPEN_FBUS2 */
#ifdef GSMOPEN_CVM
if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL)
return gsmopen_serial_config_CVM_BUSMAIL(tech_pvt);
#endif /* GSMOPEN_CVM */
return -1;
}
int gsmopen_serial_config_AT(private_t *tech_pvt)
{
int res;
char at_command[5];
int i;
/* initial_pause? */
if (tech_pvt->at_initial_pause) {
DEBUGA_GSMOPEN("sleeping for %d usec\n", GSMOPEN_P_LOG, tech_pvt->at_initial_pause);
gsmopen_sleep(tech_pvt->at_initial_pause);
}
/* go until first empty preinit string, or last preinit string */
while (1) {
char trash[4096];
res = tech_pvt->serialPort_serial_control->Read(trash, 4096);
if (res) {
DEBUGA_GSMOPEN("READ %d on serialport init\n", GSMOPEN_P_LOG, res);
}
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CFUN=1");
if (res) {
DEBUGA_GSMOPEN("no response to AT+CFUN=1. Continuing\n", GSMOPEN_P_LOG);
}
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT^CURC=0");
if (res) {
DEBUGA_GSMOPEN("no response to AT^CURC=0. Continuing\n", GSMOPEN_P_LOG);
}
if (strlen(tech_pvt->at_preinit_1)) {
res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_preinit_1, tech_pvt->at_preinit_1_expect);
if (res) {
DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_preinit_1, tech_pvt->at_preinit_1_expect);
}
} else {
break;
}
if (strlen(tech_pvt->at_preinit_2)) {
res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_preinit_2, tech_pvt->at_preinit_2_expect);
if (res) {
DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_preinit_2, tech_pvt->at_preinit_2_expect);
}
} else {
break;
}
if (strlen(tech_pvt->at_preinit_3)) {
res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_preinit_3, tech_pvt->at_preinit_3_expect);
if (res) {
DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_preinit_3, tech_pvt->at_preinit_3_expect);
}
} else {
break;
}
if (strlen(tech_pvt->at_preinit_4)) {
res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_preinit_4, tech_pvt->at_preinit_4_expect);
if (res) {
DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_preinit_4, tech_pvt->at_preinit_4_expect);
}
} else {
break;
}
if (strlen(tech_pvt->at_preinit_5)) {
res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_preinit_5, tech_pvt->at_preinit_5_expect);
if (res) {
DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_preinit_5, tech_pvt->at_preinit_5_expect);
}
} else {
break;
}
break;
}
/* after_preinit_pause? */
if (tech_pvt->at_after_preinit_pause) {
DEBUGA_GSMOPEN("sleeping for %d usec\n", GSMOPEN_P_LOG, tech_pvt->at_after_preinit_pause);
gsmopen_sleep(tech_pvt->at_after_preinit_pause);
}
/* phone, brother, art you alive? */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT");
if (res) {
ERRORA("no response to AT\n", GSMOPEN_P_LOG);
return -1;
}
/* for motorola, bring it back to "normal" mode if it happens to be in another mode */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+mode=0");
if (res) {
DEBUGA_GSMOPEN("AT+mode=0 does not get OK from the phone. If it is NOT Motorola," " no problem.\n", GSMOPEN_P_LOG);
}
gsmopen_sleep(50000);
/* for motorola end */
/* reset AT configuration to phone default */
res = gsmopen_serial_write_AT_ack(tech_pvt, "ATZ");
if (res) {
DEBUGA_GSMOPEN("ATZ failed\n", GSMOPEN_P_LOG);
}
/* disable AT command echo */
res = gsmopen_serial_write_AT_ack(tech_pvt, "ATE0");
if (res) {
DEBUGA_GSMOPEN("ATE0 failed\n", GSMOPEN_P_LOG);
}
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CFUN=1");
if (res) {
DEBUGA_GSMOPEN("no response to AT+CFUN=1. Continuing\n", GSMOPEN_P_LOG);
}
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT^CURC=0");
if (res) {
DEBUGA_GSMOPEN("no response to AT^CURC=0. Continuing\n", GSMOPEN_P_LOG);
}
/* disable extended error reporting */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMEE=0");
if (res) {
DEBUGA_GSMOPEN("AT+CMEE failed\n", GSMOPEN_P_LOG);
}
/* various phone manufacturer identifier */
for (i = 0; i < 10; i++) {
memset(at_command, 0, sizeof(at_command));
sprintf(at_command, "ATI%d", i);
res = gsmopen_serial_write_AT_ack(tech_pvt, at_command);
if (res) {
DEBUGA_GSMOPEN("ATI%d command failed, continue\n", GSMOPEN_P_LOG, i);
}
}
/* phone manufacturer */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CGMI");
if (res) {
DEBUGA_GSMOPEN("AT+CGMI failed\n", GSMOPEN_P_LOG);
}
/* phone model */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CGMM");
if (res) {
DEBUGA_GSMOPEN("AT+CGMM failed\n", GSMOPEN_P_LOG);
}
/* signal network registration with a +CREG unsolicited msg */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CREG=1");
if (res) {
DEBUGA_GSMOPEN("AT+CREG=1 failed\n", GSMOPEN_P_LOG);
tech_pvt->network_creg_not_supported = 1;
}
if (!tech_pvt->network_creg_not_supported) {
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CREG?");
if (res) {
DEBUGA_GSMOPEN("AT+CREG? failed\n", GSMOPEN_P_LOG);
}
}
/* query signal strength */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSQ");
if (res) {
DEBUGA_GSMOPEN("AT+CSQ failed\n", GSMOPEN_P_LOG);
}
/* IMEI */
tech_pvt->requesting_imei = 1;
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+GSN");
tech_pvt->requesting_imei = 0;
if (res) {
DEBUGA_GSMOPEN("AT+GSN failed\n", GSMOPEN_P_LOG);
tech_pvt->requesting_imei = 1;
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CGSN");
tech_pvt->requesting_imei = 0;
if (res) {
DEBUGA_GSMOPEN("AT+CGSN failed\n", GSMOPEN_P_LOG);
}
}
/* IMSI */
tech_pvt->requesting_imsi = 1;
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CIMI");
tech_pvt->requesting_imsi = 0;
if (res) {
DEBUGA_GSMOPEN("AT+CIMI failed\n", GSMOPEN_P_LOG);
}
/* signal incoming SMS with a +CMTI unsolicited msg */
//res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CNMI=1,1,0,0,0");
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CNMI=2,1,0,0,0");
if (res) {
DEBUGA_GSMOPEN("AT+CNMI=2,1,0,0,0 failed, continue\n", GSMOPEN_P_LOG);
tech_pvt->sms_cnmi_not_supported = 1;
tech_pvt->gsmopen_serial_sync_period = 30; //FIXME in config
}
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CPMS=\"ME\",\"ME\",\"ME\"");
if (res) {
DEBUGA_GSMOPEN("no response to AT+CPMS=\"ME\",\"ME\",\"ME\". Continuing\n", GSMOPEN_P_LOG);
}
/* signal incoming SMS with a +CMTI unsolicited msg */
//res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CNMI=1,1,0,0,0");
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CNMI=2,1,0,0,0");
if (res) {
DEBUGA_GSMOPEN("AT+CNMI=2,1,0,0,0 failed, continue\n", GSMOPEN_P_LOG);
tech_pvt->sms_cnmi_not_supported = 1;
tech_pvt->gsmopen_serial_sync_period = 30; //FIXME in config
}
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CPMS=\"ME\",\"ME\",\"ME\"");
if (res) {
DEBUGA_GSMOPEN("no response to AT+CPMS=\"ME\",\"ME\",\"ME\". Continuing\n", GSMOPEN_P_LOG);
}
/* signal incoming SMS with a +CMTI unsolicited msg */
//res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CNMI=1,1,0,0,0");
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CNMI=2,1,0,0,0");
if (res) {
DEBUGA_GSMOPEN("AT+CNMI=2,1,0,0,0 failed, continue\n", GSMOPEN_P_LOG);
tech_pvt->sms_cnmi_not_supported = 1;
tech_pvt->gsmopen_serial_sync_period = 30; //FIXME in config
}
/* what is the Message Center address (number) to which the SMS has to be sent? */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCA?");
if (res) {
DEBUGA_GSMOPEN("AT+CSCA? failed, continue\n", GSMOPEN_P_LOG);
}
/* what is the Message Format of SMSs? */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF?");
if (res) {
DEBUGA_GSMOPEN("AT+CMGF? failed, continue\n", GSMOPEN_P_LOG);
}
#ifndef WANT_GSMLIB
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF=1");
if (res) {
ERRORA("Error setting SMS sending mode to TEXT on the cellphone, let's hope is TEXT by default. Continuing\n", GSMOPEN_P_LOG);
}
tech_pvt->sms_pdu_not_supported = 1;
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSMP=17,167,0,8"); //unicode, 16 bit message
if (res) {
WARNINGA("AT+CSMP do not got OK from the phone, continuing\n", GSMOPEN_P_LOG);
}
/* what is the Charset of SMSs? */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS?");
if (res) {
DEBUGA_GSMOPEN("AT+CSCS? failed, continue\n", GSMOPEN_P_LOG);
}
tech_pvt->no_ucs2 = 0;
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS=\"UCS2\"");
if (res) {
WARNINGA("AT+CSCS=\"UCS2\" (set TE messages to ucs2) do not got OK from the phone, let's try with 'GSM'\n", GSMOPEN_P_LOG);
tech_pvt->no_ucs2 = 1;
}
if (tech_pvt->no_ucs2) {
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS=\"GSM\"");
if (res) {
WARNINGA("AT+CSCS=\"GSM\" (set TE messages to GSM) do not got OK from the phone\n", GSMOPEN_P_LOG);
}
//res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSMP=17,167,0,16"); //"flash", class 0 sms 7 bit
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSMP=17,167,0,0"); //normal, 7 bit message
if (res) {
WARNINGA("AT+CSMP do not got OK from the phone, continuing\n", GSMOPEN_P_LOG);
}
}
#else // WANT_GSMLIB
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF=0");
if (res) {
ERRORA("Error setting SMS sending mode to TEXT on the cellphone, let's hope is TEXT by default. Continuing\n", GSMOPEN_P_LOG);
}
tech_pvt->sms_pdu_not_supported = 0;
tech_pvt->no_ucs2 = 1;
if (tech_pvt->no_ucs2) {
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS=\"GSM\"");
if (res) {
WARNINGA("AT+CSCS=\"GSM\" (set TE messages to GSM) do not got OK from the phone\n", GSMOPEN_P_LOG);
}
//res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSMP=17,167,0,16"); //"flash", class 0 sms 7 bit
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSMP=17,167,0,0"); //normal, 7 bit message
if (res) {
WARNINGA("AT+CSMP do not got OK from the phone, continuing\n", GSMOPEN_P_LOG);
}
}
#endif // WANT_GSMLIB
#ifdef NOTDEF //GSMLIB? XXX
else {
//res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSMP=17,167,0,20"); //"flash", class 0 sms 16 bit unicode
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSMP=17,167,0,8"); //unicode, 16 bit message
if (res) {
WARNINGA("AT+CSMP do not got OK from the phone, continuing\n", GSMOPEN_P_LOG);
}
}
#endif // NOTDEF
/* is the unsolicited reporting of mobile equipment event supported? */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMER=?");
if (res) {
DEBUGA_GSMOPEN("AT+CMER=? failed, continue\n", GSMOPEN_P_LOG);
}
/* request unsolicited reporting of mobile equipment indicators' events, to be screened by categories reported by +CIND=? */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMER=3,0,0,1");
if (res) {
DEBUGA_GSMOPEN("AT+CMER=? failed, continue\n", GSMOPEN_P_LOG);
}
/* is the solicited reporting of mobile equipment indications supported? */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CIND=?");
if (res) {
DEBUGA_GSMOPEN("AT+CIND=? failed, continue\n", GSMOPEN_P_LOG);
}
/* is the unsolicited reporting of call monitoring supported? sony-ericsson specific */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT*ECAM=?");
if (res) {
DEBUGA_GSMOPEN("AT*ECAM=? failed, continue\n", GSMOPEN_P_LOG);
}
/* enable the unsolicited reporting of call monitoring. sony-ericsson specific */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT*ECAM=1");
if (res) {
DEBUGA_GSMOPEN("AT*ECAM=1 failed, continue\n", GSMOPEN_P_LOG);
tech_pvt->at_has_ecam = 0;
} else {
tech_pvt->at_has_ecam = 1;
}
/* disable unsolicited signaling of call list */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CLCC=0");
if (res) {
DEBUGA_GSMOPEN("AT+CLCC=0 failed, continue\n", GSMOPEN_P_LOG);
tech_pvt->at_has_clcc = 0;
} else {
tech_pvt->at_has_clcc = 1;
}
/* give unsolicited caller id when incoming call */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CLIP=1");
if (res) {
DEBUGA_GSMOPEN("AT+CLIP failed, continue\n", GSMOPEN_P_LOG);
}
/* for motorola */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+MCST=1"); /* motorola call control codes
(to know when call is disconnected (they
don't give you "no carrier") */
if (res) {
DEBUGA_GSMOPEN("AT+MCST=1 does not get OK from the phone. If it is NOT Motorola," " no problem.\n", GSMOPEN_P_LOG);
}
/* for motorola end */
/* go until first empty postinit string, or last postinit string */
while (1) {
if (strlen(tech_pvt->at_postinit_1)) {
res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_postinit_1, tech_pvt->at_postinit_1_expect);
if (res) {
DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_postinit_1, tech_pvt->at_postinit_1_expect);
}
} else {
break;
}
if (strlen(tech_pvt->at_postinit_2)) {
res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_postinit_2, tech_pvt->at_postinit_2_expect);
if (res) {
DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_postinit_2, tech_pvt->at_postinit_2_expect);
}
} else {
break;
}
if (strlen(tech_pvt->at_postinit_3)) {
res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_postinit_3, tech_pvt->at_postinit_3_expect);
if (res) {
DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_postinit_3, tech_pvt->at_postinit_3_expect);
}
} else {
break;
}
if (strlen(tech_pvt->at_postinit_4)) {
res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_postinit_4, tech_pvt->at_postinit_4_expect);
if (res) {
DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_postinit_4, tech_pvt->at_postinit_4_expect);
}
} else {
break;
}
if (strlen(tech_pvt->at_postinit_5)) {
res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_postinit_5, tech_pvt->at_postinit_5_expect);
if (res) {
DEBUGA_GSMOPEN("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, tech_pvt->at_postinit_5, tech_pvt->at_postinit_5_expect);
}
} else {
break;
}
break;
}
return 0;
}
int gsmopen_serial_sync_AT(private_t *tech_pvt)
{
gsmopen_sleep(10000); /* 10msec */
time(&tech_pvt->gsmopen_serial_synced_timestamp);
return 0;
}
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 select_err = 1;
int res;
struct timeval timeout;
char tmp_answer[AT_BUFSIZ];
char tmp_answer2[AT_BUFSIZ];
char tmp_answer3[AT_BUFSIZ];
char *tmp_answer_ptr;
char *last_line_ptr;
int i = 0;
int read_count = 0;
int la_counter = 0;
int at_ack = -1;
int la_read = 0;
int timeout_in_msec;
int msecs_passed = 0;
timeout_in_msec = (timeout_sec * 1000) + (timeout_usec ? (timeout_usec / 1000) : 0);
if (timeout_in_msec != 100)
DEBUGA_GSMOPEN("TIMEOUT=%d\n", GSMOPEN_P_LOG, timeout_in_msec);
if (!running || !tech_pvt->running) {
return -1;
}
tmp_answer_ptr = tmp_answer;
memset(tmp_answer, 0, sizeof(char) * AT_BUFSIZ);
memset(tmp_answer2, 0, sizeof(char) * AT_BUFSIZ);
memset(tmp_answer3, 0, sizeof(char) * AT_BUFSIZ);
timeout.tv_sec = timeout_sec;
timeout.tv_usec = timeout_usec;
PUSHA_UNLOCKA(tech_pvt->controldev_lock);
LOKKA(tech_pvt->controldev_lock);
while ((!tech_pvt->controldev_dead) && msecs_passed <= timeout_in_msec) {
char *token_ptr;
timeout.tv_sec = timeout_sec; //reset the timeout, linux modify it
timeout.tv_usec = timeout_usec; //reset the timeout, linux modify it
read:
switch_sleep(20000);
msecs_passed += 20;
if (timeout_in_msec != 100) {
//ERRORA("TIMEOUT=%d, PASSED=%d\n", GSMOPEN_P_LOG, timeout_in_msec, msecs_passed);
}
//read_count = tech_pvt->serialPort_serial_control->Readv(tmp_answer_ptr, AT_BUFSIZ - (tmp_answer_ptr - tmp_answer), (timeout_sec * 1000) + (timeout_usec ? (timeout_usec / 1000) : 0));
read_count = tech_pvt->serialPort_serial_control->Read(tmp_answer_ptr, AT_BUFSIZ - (tmp_answer_ptr - tmp_answer));
memset(tmp_answer3, 0, sizeof(char) * AT_BUFSIZ);
strcpy(tmp_answer3, tmp_answer_ptr);
//cicopet read_count = read(tech_pvt->controldevfd, tmp_answer_ptr, AT_BUFSIZ - (tmp_answer_ptr - tmp_answer));
if (read_count == 0) {
if (msecs_passed <= timeout_in_msec) {
goto read;
}
}
if (read_count == -1) {
ERRORA
("read -1 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, power down or battery exhausted\n",
GSMOPEN_P_LOG, tech_pvt->controldevice_name);
tech_pvt->controldev_dead = 1;
//cicopet close(tech_pvt->controldevfd);
ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name);
tech_pvt->running = 0;
alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead");
tech_pvt->active = 0;
tech_pvt->name[0] = '\0';
UNLOCKA(tech_pvt->controldev_lock);
if (tech_pvt->owner) {
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
}
switch_sleep(1000000);
return -1;
}
tmp_answer_ptr = tmp_answer_ptr + read_count;
la_counter = 0;
memset(tmp_answer2, 0, sizeof(char) * AT_BUFSIZ);
strcpy(tmp_answer2, tmp_answer);
if ((token_ptr = strtok(tmp_answer2, "\n\r"))) {
last_line_ptr = token_ptr;
strncpy(tech_pvt->line_array.result[la_counter], token_ptr, AT_MESG_MAX_LENGTH);
if (strlen(token_ptr) > AT_MESG_MAX_LENGTH) {
WARNINGA
("AT mesg longer than buffer, original message was: |%s|, in buffer only: |%s|\n",
GSMOPEN_P_LOG, token_ptr, tech_pvt->line_array.result[la_counter]);
}
la_counter++;
while ((token_ptr = strtok(NULL, "\n\r"))) {
last_line_ptr = token_ptr;
strncpy(tech_pvt->line_array.result[la_counter], token_ptr, AT_MESG_MAX_LENGTH);
if (strlen(token_ptr) > AT_MESG_MAX_LENGTH) {
WARNINGA
("AT mesg longer than buffer, original message was: |%s|, in buffer only: |%s|\n",
GSMOPEN_P_LOG, token_ptr, tech_pvt->line_array.result[la_counter]);
}
la_counter++;
if (la_counter == AT_MESG_MAX_LINES) {
ERRORA("Too many lines in result (>%d). la_counter=%d. tech_pvt->reading_sms_msg=%d. Stop accumulating lines.\n", GSMOPEN_P_LOG,
AT_MESG_MAX_LINES, la_counter, tech_pvt->reading_sms_msg);
WARNINGA("read was %d bytes, tmp_answer3= --|%s|--\n", GSMOPEN_P_LOG, read_count, tmp_answer3);
at_ack = AT_ERROR;
break;
}
}
} else {
last_line_ptr = tmp_answer;
}
if (expected_string && !expect_crlf) {
DEBUGA_GSMOPEN
("last_line_ptr=|%s|, expected_string=|%s|, expect_crlf=%d, memcmp(last_line_ptr, expected_string, strlen(expected_string)) = %d\n",
GSMOPEN_P_LOG, last_line_ptr, expected_string, expect_crlf, memcmp(last_line_ptr, expected_string, strlen(expected_string)));
}
if (expected_string && !expect_crlf && !memcmp(last_line_ptr, expected_string, strlen(expected_string))
) {
strncpy(tech_pvt->line_array.result[la_counter], last_line_ptr, AT_MESG_MAX_LENGTH);
// match expected string -> accept it withtout CRLF
la_counter++;
if (la_counter == AT_MESG_MAX_LINES) {
ERRORA("Too many lines in result (>%d). la_counter=%d. tech_pvt->reading_sms_msg=%d. Stop accumulating lines.\n", GSMOPEN_P_LOG,
AT_MESG_MAX_LINES, la_counter, tech_pvt->reading_sms_msg);
WARNINGA("read was %d bytes, tmp_answer3= --|%s|--\n", GSMOPEN_P_LOG, read_count, tmp_answer3);
at_ack = AT_ERROR;
break;
}
}
/* if the last line read was not a complete line, we'll read the rest in the future */
else if (tmp_answer[strlen(tmp_answer) - 1] != '\r' && tmp_answer[strlen(tmp_answer) - 1] != '\n')
la_counter--;
/* let's list the complete lines read so far, without re-listing the lines that has yet been listed */
for (i = la_read; i < la_counter; i++) {
DEBUGA_GSMOPEN("Read line %d: |%s| la_counter=%d\n", GSMOPEN_P_LOG, i, tech_pvt->line_array.result[i], la_counter);
}
if (la_counter == AT_MESG_MAX_LINES) {
ERRORA("Too many lines in result (>%d). la_counter=%d. tech_pvt->reading_sms_msg=%d. Stop accumulating lines.\n", GSMOPEN_P_LOG,
AT_MESG_MAX_LINES, la_counter, tech_pvt->reading_sms_msg);
WARNINGA("read was %d bytes, tmp_answer3= --|%s|--\n", GSMOPEN_P_LOG, read_count, tmp_answer3);
at_ack = AT_ERROR;
break;
}
/* let's interpret the complete lines read so far (WITHOUT looking for OK, ERROR, and EXPECTED_STRING), without re-interpreting the lines that has been yet interpreted, so we're sure we don't miss anything */
for (i = la_read; i < la_counter; i++) {
if ((strcmp(tech_pvt->line_array.result[i], "RING") == 0)) {
/* with first RING we wait for callid */
gettimeofday(&(tech_pvt->ringtime), NULL);
/* give CALLID (+CLIP) a chance, wait for the next RING before answering */
if (tech_pvt->phone_callflow == CALLFLOW_INCOMING_RING) {
/* we're at the second ring, set the interface state, will be answered by gsmopen_do_monitor */
DEBUGA_GSMOPEN("|%s| got second RING\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
tech_pvt->interface_state = GSMOPEN_STATE_RING;
} else {
/* we're at the first ring, so there is no CALLID yet thus clean the previous one
just in case we don't receive the caller identification in this new call */
memset(tech_pvt->callid_name, 0, sizeof(tech_pvt->callid_name));
memset(tech_pvt->callid_number, 0, sizeof(tech_pvt->callid_number));
/* only send AT+CLCC? if the device previously reported its support */
if (tech_pvt->at_has_clcc != 0) {
/* we're at the first ring, try to get CALLID (with +CLCC) */
DEBUGA_GSMOPEN("|%s| got first RING, sending AT+CLCC?\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
res = gsmopen_serial_write_AT_noack(tech_pvt, "AT+CLCC?");
if (res) {
ERRORA("AT+CLCC? (call list) was not correctly sent to the phone\n", GSMOPEN_P_LOG);
}
} else {
DEBUGA_GSMOPEN("|%s| got first RING, but not sending AT+CLCC? as this device "
"seems not to support\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
}
tech_pvt->phone_callflow = CALLFLOW_INCOMING_RING;
}
if ((strncmp(tech_pvt->line_array.result[i], "+CLCC", 5) == 0)) {
int commacount = 0;
int a = 0;
int b = 0;
int c = 0;
/* with clcc we wait for clip */
memset(tech_pvt->callid_name, 0, sizeof(tech_pvt->callid_name));
memset(tech_pvt->callid_number, 0, sizeof(tech_pvt->callid_number));
for (a = 0; a < strlen(tech_pvt->line_array.result[i]); a++) {
if (tech_pvt->line_array.result[i][a] == ',') {
commacount++;
}
if (commacount == 5) {
if (tech_pvt->line_array.result[i][a] != ',' && tech_pvt->line_array.result[i][a] != '"') {
tech_pvt->callid_number[b] = tech_pvt->line_array.result[i][a];
b++;
}
}
if (commacount == 7) {
if (tech_pvt->line_array.result[i][a] != ',' && tech_pvt->line_array.result[i][a] != '"') {
tech_pvt->callid_name[c] = tech_pvt->line_array.result[i][a];
c++;
}
}
}
tech_pvt->phone_callflow = CALLFLOW_INCOMING_RING;
DEBUGA_GSMOPEN("|%s| CLCC CALLID: name is %s, number is %s\n", GSMOPEN_P_LOG,
tech_pvt->line_array.result[i],
tech_pvt->callid_name[0] ? tech_pvt->callid_name : "not available",
tech_pvt->callid_number[0] ? tech_pvt->callid_number : "not available");
}
if ((strncmp(tech_pvt->line_array.result[i], "+CLIP", 5) == 0)) {
int commacount = 0;
int a = 0;
int b = 0;
int c = 0;
/* with CLIP, we want to answer right away */
memset(tech_pvt->callid_name, 0, sizeof(tech_pvt->callid_name));
memset(tech_pvt->callid_number, 0, sizeof(tech_pvt->callid_number));
for (a = 7; a < strlen(tech_pvt->line_array.result[i]); a++) {
if (tech_pvt->line_array.result[i][a] == ',') {
commacount++;
}
if (commacount == 0) {
if (tech_pvt->line_array.result[i][a] != ',' && tech_pvt->line_array.result[i][a] != '"') {
tech_pvt->callid_number[b] = tech_pvt->line_array.result[i][a];
b++;
}
}
if (commacount == 4) {
if (tech_pvt->line_array.result[i][a] != ',' && tech_pvt->line_array.result[i][a] != '"') {
tech_pvt->callid_name[c] = tech_pvt->line_array.result[i][a];
c++;
}
}
}
if (tech_pvt->interface_state != GSMOPEN_STATE_RING) {
gettimeofday(&(tech_pvt->call_incoming_time), NULL);
DEBUGA_GSMOPEN("GSMOPEN_STATE_RING call_incoming_time.tv_sec=%ld\n", GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec);
}
tech_pvt->interface_state = GSMOPEN_STATE_RING;
tech_pvt->phone_callflow = CALLFLOW_INCOMING_RING;
DEBUGA_GSMOPEN("|%s| CLIP INCOMING CALLID: name is %s, number is %s\n", GSMOPEN_P_LOG,
tech_pvt->line_array.result[i],
(strlen(tech_pvt->callid_name) && tech_pvt->callid_name[0] != 1) ? tech_pvt->callid_name : "not available",
strlen(tech_pvt->callid_number) ? tech_pvt->callid_number : "not available");
if (!strlen(tech_pvt->callid_number)) {
strcpy(tech_pvt->callid_number, "not available");
}
if (!strlen(tech_pvt->callid_name) && tech_pvt->callid_name[0] != 1) {
strncpy(tech_pvt->callid_name, tech_pvt->callid_number, sizeof(tech_pvt->callid_name));
//strncpy(tech_pvt->callid_name, tech_pvt->callid_number, sizeof(tech_pvt->callid_name)) ;
snprintf(tech_pvt->callid_name, sizeof(tech_pvt->callid_name), "GSMopen: %s", tech_pvt->callid_number);
}
DEBUGA_GSMOPEN("|%s| CLIP INCOMING CALLID: NOW name is %s, number is %s\n", GSMOPEN_P_LOG,
tech_pvt->line_array.result[i], tech_pvt->callid_name, tech_pvt->callid_number);
}
if ((strcmp(tech_pvt->line_array.result[i], "+CMS ERROR: 500") == 0)) {
ERRORA("Received: \"%s\", generic error, maybe this account ran OUT OF CREDIT?\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
} else if ((strncmp(tech_pvt->line_array.result[i], "+CMS ERROR:", 11) == 0)) {
ERRORA("Received: \"%s\", what was this error about?\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
if ((strcmp(tech_pvt->line_array.result[i], "BUSY") == 0)) {
tech_pvt->phone_callflow = CALLFLOW_CALL_LINEBUSY;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_LINEBUSY\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
//if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner && tech_pvt->phone_callflow != CALLFLOW_CALL_DOWN)
if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->phone_callflow != CALLFLOW_CALL_DOWN) {
//ast_setstate(tech_pvt->owner, GSMOPEN_STATE_BUSY);
//gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_BUSY);
//cicopet
switch_core_session_t *session = NULL;
switch_channel_t *channel = NULL;
tech_pvt->interface_state = GSMOPEN_STATE_DOWN;
session = switch_core_session_locate(tech_pvt->session_uuid_str);
if (session) {
channel = switch_core_session_get_channel(session);
//gsmopen_hangup(tech_pvt);
switch_core_session_rwunlock(session);
switch_channel_hangup(channel, SWITCH_CAUSE_NONE);
}
//
//tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
//gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
} else {
ERRORA("Why BUSY now?\n", GSMOPEN_P_LOG);
}
}
if ((strcmp(tech_pvt->line_array.result[i], "NO ANSWER") == 0)) {
tech_pvt->phone_callflow = CALLFLOW_CALL_NOANSWER;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_NOANSWER\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) {
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_NO_ANSWER;
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
} else {
ERRORA("Why NO ANSWER now?\n", GSMOPEN_P_LOG);
}
}
if ((strcmp(tech_pvt->line_array.result[i], "NO CARRIER") == 0)) {
tech_pvt->phone_callflow = CALLFLOW_CALL_NOCARRIER;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_NOCARRIER\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) {
//cicopet
switch_core_session_t *session = NULL;
switch_channel_t *channel = NULL;
tech_pvt->interface_state = GSMOPEN_STATE_DOWN;
session = switch_core_session_locate(tech_pvt->session_uuid_str);
if (session) {
channel = switch_core_session_get_channel(session);
//gsmopen_hangup(tech_pvt);
switch_core_session_rwunlock(session);
switch_channel_hangup(channel, SWITCH_CAUSE_NONE);
}
//
//tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
//gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
} else {
ERRORA("Why NO CARRIER now?\n", GSMOPEN_P_LOG);
}
}
if ((strncmp(tech_pvt->line_array.result[i], "+CBC:", 5) == 0)) {
int power_supply, battery_strenght, err;
power_supply = battery_strenght = 0;
err = sscanf(&tech_pvt->line_array.result[i][6], "%d,%d", &power_supply, &battery_strenght);
if (err < 2) {
DEBUGA_GSMOPEN("|%s| is not formatted as: |+CBC: xx,yy| now trying |+CBC:xx,yy|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
err = sscanf(&tech_pvt->line_array.result[i][5], "%d,%d", &power_supply, &battery_strenght);
DEBUGA_GSMOPEN("|%s| +CBC: Powered by %s, battery strenght=%d\n", GSMOPEN_P_LOG,
tech_pvt->line_array.result[i], power_supply ? "power supply" : "battery", battery_strenght);
}
if (err < 2) {
DEBUGA_GSMOPEN("|%s| is not formatted as: |+CBC:xx,yy| giving up\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
else {
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| +CBC: Powered by %s, battery strenght=%d\n", GSMOPEN_P_LOG,
tech_pvt->line_array.result[i], power_supply ? "power supply" : "battery", battery_strenght);
if (!power_supply) {
if (battery_strenght < 10) {
ERRORA("|%s| BATTERY ALMOST EXHAUSTED\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
} else if (battery_strenght < 20) {
WARNINGA("|%s| BATTERY LOW\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
}
}
}
if ((strncmp(tech_pvt->line_array.result[i], "+CSQ:", 5) == 0)) {
int signal_quality, ber, err;
signal_quality = ber = 0;
err = sscanf(&tech_pvt->line_array.result[i][6], "%d,%d", &signal_quality, &ber);
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| +CSQ: Signal Quality: %d, Error Rate=%d\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i], signal_quality, ber);
if (err < 2) {
ERRORA("|%s| is not formatted as: |+CSQ: xx,yy|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
} else {
if (signal_quality < 9 || signal_quality == 99) {
ERRORA
("|%s| CELLPHONE GETS ALMOST NO SIGNAL, consider to move it or additional antenna\n",
GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
tech_pvt->got_signal = 0;
alarm_event(tech_pvt, ALARM_NETWORK_NO_SIGNAL, "CELLPHONE GETS ALMOST NO SIGNAL, consider to move it or additional antenna");
} else if (signal_quality < 11) {
WARNINGA("|%s| CELLPHONE GETS SIGNAL LOW\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
tech_pvt->got_signal = 1;
alarm_event(tech_pvt, ALARM_NETWORK_LOW_SIGNAL, "CELLPHONE GETS SIGNAL LOW");
} else {
tech_pvt->got_signal = 2;
}
}
}
if ((strncmp(tech_pvt->line_array.result[i], "+CREG:", 6) == 0)) {
int n, stat, err;
n = stat = 0;
err = sscanf(&tech_pvt->line_array.result[i][6], "%d,%d", &n, &stat);
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| +CREG: Display: %d, Registration=%d\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i], n, stat);
if (err < 2) {
DEBUGA_GSMOPEN("|%s| is not formatted as: |+CREG: xx,yy|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
} else {
if (stat == 0) {
ERRORA
("|%s| CELLPHONE is not registered to network, consider to move it or additional antenna\n",
GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
tech_pvt->not_registered = 1;
tech_pvt->home_network_registered = 0;
tech_pvt->roaming_registered = 0;
alarm_event(tech_pvt, ALARM_NO_NETWORK_REGISTRATION,
"CELLPHONE is not registered to network, consider to move it or additional antenna");
} else if (stat == 1) {
DEBUGA_GSMOPEN("|%s| CELLPHONE is registered to the HOME network\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
tech_pvt->not_registered = 0;
tech_pvt->home_network_registered = 1;
tech_pvt->roaming_registered = 0;
} else {
ERRORA("|%s| CELLPHONE is registered to a ROAMING network\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
tech_pvt->not_registered = 0;
tech_pvt->home_network_registered = 0;
tech_pvt->roaming_registered = 1;
alarm_event(tech_pvt, ALARM_ROAMING_NETWORK_REGISTRATION, "CELLPHONE is registered to a ROAMING network");
}
}
}
if ((strncmp(tech_pvt->line_array.result[i], "+CMGW:", 6) == 0)) {
int err;
err = sscanf(&tech_pvt->line_array.result[i][7], "%s", tech_pvt->at_cmgw);
DEBUGA_GSMOPEN("|%s| +CMGW: %s\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i], tech_pvt->at_cmgw);
if (err < 1) {
ERRORA("|%s| is not formatted as: |+CMGW: xxxx|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
}
if ((strncmp(tech_pvt->line_array.result[i], "^CEND:1", 7) == 0)) {
tech_pvt->phone_callflow = CALLFLOW_CALL_NOCARRIER;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_NOCARRIER\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) {
//cicopet
switch_core_session_t *session = NULL;
switch_channel_t *channel = NULL;
tech_pvt->interface_state = GSMOPEN_STATE_DOWN;
session = switch_core_session_locate(tech_pvt->session_uuid_str);
if (session) {
channel = switch_core_session_get_channel(session);
//gsmopen_hangup(tech_pvt);
switch_core_session_rwunlock(session);
switch_channel_hangup(channel, SWITCH_CAUSE_NONE);
}
tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_IDLE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) {
DEBUGA_GSMOPEN("just received a remote HANGUP\n", GSMOPEN_P_LOG);
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_NORMAL;
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
DEBUGA_GSMOPEN("just sent GSMOPEN_CONTROL_HANGUP\n", GSMOPEN_P_LOG);
}
//
//tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
//gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
} else {
ERRORA("Why NO CARRIER now?\n", GSMOPEN_P_LOG);
}
}
/* at_call_* are unsolicited messages sent by the modem to signal us about call processing activity and events */
if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_call_idle) == 0)) {
tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_IDLE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) {
DEBUGA_GSMOPEN("just received a remote HANGUP\n", GSMOPEN_P_LOG);
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_NORMAL;
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
DEBUGA_GSMOPEN("just sent GSMOPEN_CONTROL_HANGUP\n", GSMOPEN_P_LOG);
}
tech_pvt->phone_callflow = CALLFLOW_CALL_NOCARRIER;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_NOCARRIER\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) {
//cicopet
switch_core_session_t *session = NULL;
switch_channel_t *channel = NULL;
tech_pvt->interface_state = GSMOPEN_STATE_DOWN;
session = switch_core_session_locate(tech_pvt->session_uuid_str);
if (session) {
channel = switch_core_session_get_channel(session);
//gsmopen_hangup(tech_pvt);
switch_core_session_rwunlock(session);
switch_channel_hangup(channel, SWITCH_CAUSE_NONE);
}
//
//tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
//gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
} else {
ERRORA("Why NO CARRIER now?\n", GSMOPEN_P_LOG);
}
}
if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_call_incoming) == 0)) {
//char list_command[64];
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_INCOMING\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
if (tech_pvt->phone_callflow != CALLFLOW_CALL_INCOMING && tech_pvt->phone_callflow != CALLFLOW_INCOMING_RING) {
//mark the time of CALLFLOW_CALL_INCOMING
gettimeofday(&(tech_pvt->call_incoming_time), NULL);
tech_pvt->phone_callflow = CALLFLOW_CALL_INCOMING;
DEBUGA_GSMOPEN("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld\n", GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec);
}
}
if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_call_active) == 0)) {
tech_pvt->phone_callflow = CALLFLOW_CALL_ACTIVE;
DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_ACTIVE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
if (tech_pvt->interface_state == CALLFLOW_CALL_DIALING || tech_pvt->interface_state == CALLFLOW_STATUS_EARLYMEDIA) {
DEBUGA_PBX("just received a remote ANSWER\n", GSMOPEN_P_LOG);
if (tech_pvt->phone_callflow == GSMOPEN_STATE_UP) {
//gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_RINGING);
DEBUGA_PBX("just sent GSMOPEN_CONTROL_RINGING\n", GSMOPEN_P_LOG);
DEBUGA_PBX("going to send GSMOPEN_CONTROL_ANSWER\n", GSMOPEN_P_LOG);
//gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_ANSWER);
tech_pvt->interface_state = CALLFLOW_CALL_REMOTEANSWER;
DEBUGA_PBX("just sent GSMOPEN_CONTROL_ANSWER\n", GSMOPEN_P_LOG);
}
} else {
tech_pvt->interface_state = GSMOPEN_STATE_UP;
DEBUGA_PBX("just interface_state UP\n", GSMOPEN_P_LOG);
}
}
if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_call_calling) == 0)) {
tech_pvt->phone_callflow = CALLFLOW_CALL_DIALING;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_DIALING\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_call_failed) == 0)) {
tech_pvt->phone_callflow = CALLFLOW_CALL_FAILED;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_FAILED\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) {
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
}
}
if ((strncmp(tech_pvt->line_array.result[i], "+CSCA:", 6) == 0)) { //TODO SMS FIXME in config!
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| +CSCA: Message Center Address!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
if ((strncmp(tech_pvt->line_array.result[i], "+CMGF:", 6) == 0)) { //TODO SMS FIXME in config!
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| +CMGF: Message Format!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
if ((strncmp(tech_pvt->line_array.result[i], "+CMTI:", 6) == 0)) { //TODO SMS FIXME in config!
int err;
int pos;
//FIXME all the following commands in config!
if (option_debug)
DEBUGA_GSMOPEN("|%s| +CMTI: Incoming SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
err = sscanf(&tech_pvt->line_array.result[i][12], "%d", &pos);
if (err < 1) {
ERRORA("|%s| is not formatted as: |+CMTI: \"MT\",xx|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
} else {
DEBUGA_GSMOPEN("|%s| +CMTI: Incoming SMS in position: %d!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i], pos);
tech_pvt->unread_sms_msg_id = pos;
gsmopen_sleep(1000);
if (tech_pvt->unread_sms_msg_id) {
char at_command[256];
if (tech_pvt->no_ucs2 == 0) {
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS=\"UCS2\"");
if (res) {
ERRORA("AT+CSCS=\"UCS2\" (set TE messages to ucs2) do not got OK from the phone, continuing\n", GSMOPEN_P_LOG);
//memset(tech_pvt->sms_message, 0, sizeof(tech_pvt->sms_message));
}
}
memset(at_command, 0, sizeof(at_command));
sprintf(at_command, "AT+CMGR=%d", tech_pvt->unread_sms_msg_id);
memset(tech_pvt->sms_message, 0, sizeof(tech_pvt->sms_message));
tech_pvt->reading_sms_msg = 1;
res = gsmopen_serial_write_AT_ack(tech_pvt, at_command);
tech_pvt->reading_sms_msg = 0;
if (res) {
ERRORA("AT+CMGR (read SMS) do not got OK from the phone, message sent was:|||%s|||\n", GSMOPEN_P_LOG, at_command);
}
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS=\"GSM\"");
if (res) {
ERRORA("AT+CSCS=\"GSM\" (set TE messages to GSM) do not got OK from the phone\n", GSMOPEN_P_LOG);
}
memset(at_command, 0, sizeof(at_command));
sprintf(at_command, "AT+CMGD=%d", tech_pvt->unread_sms_msg_id); /* delete the message */
tech_pvt->unread_sms_msg_id = 0;
res = gsmopen_serial_write_AT_ack(tech_pvt, at_command);
if (res) {
ERRORA("AT+CMGD (Delete SMS) do not got OK from the phone, message sent was:|||%s|||\n", GSMOPEN_P_LOG, at_command);
}
res = sms_incoming(tech_pvt);
if (tech_pvt->phone_callflow == CALLFLOW_CALL_IDLE && tech_pvt->interface_state == GSMOPEN_STATE_DOWN && tech_pvt->owner == NULL) {
/* we're not in a call, neither calling */
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CKPD=\"EEE\"");
if (res) {
ERRORA("AT+CKPD=\"EEE\" (cellphone screen back to user) do not got OK from the phone\n", GSMOPEN_P_LOG);
}
}
} //unread_msg_id
} //CMTI well formatted
} //CMTI
if ((strncmp(tech_pvt->line_array.result[i], "+MMGL:", 6) == 0)) { //TODO MOTOROLA SMS FIXME in config!
int err = 0;
//int unread_msg_id=0;
if (option_debug)
DEBUGA_GSMOPEN("|%s| +MMGL: Listing Motorola SMSs!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
err = sscanf(&tech_pvt->line_array.result[i][7], "%d", &tech_pvt->unread_sms_msg_id);
if (err < 1) {
ERRORA("|%s| is not formatted as: |+MMGL: xx|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
}
if ((strncmp(tech_pvt->line_array.result[i], "+CMGL:", 6) == 0)) { //TODO SMS FIXME in config!
if (option_debug)
DEBUGA_GSMOPEN("|%s| +CMGL: Listing SMSs!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
if ((strncmp(tech_pvt->line_array.result[i], "+MMGR:", 6) == 0)) { //TODO MOTOROLA SMS FIXME in config!
if (option_debug)
DEBUGA_GSMOPEN("|%s| +MMGR: Reading Motorola SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
if (tech_pvt->reading_sms_msg)
tech_pvt->reading_sms_msg++;
}
if ((strncmp(tech_pvt->line_array.result[i], "+CMGR: \"STO U", 13) == 0)) { //TODO SMS FIXME in config!
if (option_debug)
DEBUGA_GSMOPEN("|%s| +CMGR: Reading stored UNSENT SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
} else if ((strncmp(tech_pvt->line_array.result[i], "+CMGR: \"STO S", 13) == 0)) { //TODO SMS FIXME in config!
if (option_debug)
DEBUGA_GSMOPEN("|%s| +CMGR: Reading stored SENT SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
} else if ((strncmp(tech_pvt->line_array.result[i], "+CMGR: \"REC R", 13) == 0)) { //TODO SMS FIXME in config!
if (option_debug)
DEBUGA_GSMOPEN("|%s| +CMGR: Reading received READ SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
} else if ((strncmp(tech_pvt->line_array.result[i], "+CMGR: \"REC U", 13) == 0)) { //TODO SMS FIXME in config!
if (option_debug)
DEBUGA_GSMOPEN("|%s| +CMGR: Reading received UNREAD SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
if (tech_pvt->reading_sms_msg)
tech_pvt->reading_sms_msg++;
} else if ((strncmp(tech_pvt->line_array.result[i], "+CMGR: ", 6) == 0)) { //TODO SMS FIXME in config!
if (option_debug)
DEBUGA_GSMOPEN("|%s| +CMGR: Reading SMS!\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
if (tech_pvt->reading_sms_msg)
tech_pvt->reading_sms_msg++;
}
if ((strcmp(tech_pvt->line_array.result[i], "+MCST: 17") == 0)) { /* motorola call processing unsolicited messages */
tech_pvt->phone_callflow = CALLFLOW_CALL_INFLUX;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_INFLUX\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
if ((strcmp(tech_pvt->line_array.result[i], "+MCST: 68") == 0)) { /* motorola call processing unsolicited messages */
tech_pvt->phone_callflow = CALLFLOW_CALL_NOSERVICE;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_NOSERVICE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) {
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
}
}
if ((strcmp(tech_pvt->line_array.result[i], "+MCST: 70") == 0)) { /* motorola call processing unsolicited messages */
tech_pvt->phone_callflow = CALLFLOW_CALL_OUTGOINGRESTRICTED;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_OUTGOINGRESTRICTED\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) {
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
}
}
if ((strcmp(tech_pvt->line_array.result[i], "+MCST: 72") == 0)) { /* motorola call processing unsolicited messages */
tech_pvt->phone_callflow = CALLFLOW_CALL_SECURITYFAIL;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| CALLFLOW_CALL_SECURITYFAIL\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN && tech_pvt->owner) {
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
}
}
if ((strncmp(tech_pvt->line_array.result[i], "+CPBR", 5) == 0)) { /* phonebook stuff begins */
if (tech_pvt->phonebook_querying) { /* probably phonebook struct begins */
int err, first_entry, last_entry, number_lenght, text_lenght;
if (option_debug)
DEBUGA_GSMOPEN("phonebook struct: |%s|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
err = sscanf(&tech_pvt->line_array.result[i][8], "%d-%d),%d,%d", &first_entry, &last_entry, &number_lenght, &text_lenght);
if (err < 4) {
err = sscanf(&tech_pvt->line_array.result[i][7], "%d-%d,%d,%d", &first_entry, &last_entry, &number_lenght, &text_lenght);
}
if (err < 4) {
ERRORA
("phonebook struct: |%s| is nor formatted as: |+CPBR: (1-750),40,14| neither as: |+CPBR: 1-750,40,14|\n",
GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
} else {
if (option_debug)
DEBUGA_GSMOPEN
("First entry: %d, last entry: %d, phone number max lenght: %d, text max lenght: %d\n",
GSMOPEN_P_LOG, first_entry, last_entry, number_lenght, text_lenght);
tech_pvt->phonebook_first_entry = first_entry;
tech_pvt->phonebook_last_entry = last_entry;
tech_pvt->phonebook_number_lenght = number_lenght;
tech_pvt->phonebook_text_lenght = text_lenght;
}
} else { /* probably phonebook entry begins */
if (tech_pvt->phonebook_listing) {
int err, entry_id, entry_type;
char entry_number[256];
char entry_text[256];
if (option_debug)
DEBUGA_GSMOPEN("phonebook entry: |%s|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
err =
sscanf(&tech_pvt->line_array.result[i][7], "%d,\"%255[0-9+]\",%d,\"%255[^\"]\"", &entry_id, entry_number, &entry_type,
entry_text);
if (err < 4) {
ERRORA
("err=%d, phonebook entry: |%s| is not formatted as: |+CPBR: 504,\"+39025458068\",145,\"ciao a tutti\"|\n",
GSMOPEN_P_LOG, err, tech_pvt->line_array.result[i]);
} else {
//TODO: sanitize entry_text
if (option_debug)
DEBUGA_GSMOPEN("Number: %s, Text: %s, Type: %d\n", GSMOPEN_P_LOG, entry_number, entry_text, entry_type);
/* write entry in phonebook file */
if (tech_pvt->phonebook_writing_fp) {
gsmopen_dir_entry_extension++;
fprintf(tech_pvt->phonebook_writing_fp,
"%s => ,%sSKO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromcell=%s|phonebook_entry_owner=%s\n",
entry_number, entry_text, "no",
tech_pvt->gsmopen_dir_entry_extension_prefix, "2", gsmopen_dir_entry_extension, "yes", "not_specified");
fprintf(tech_pvt->phonebook_writing_fp,
"%s => ,%sDO,,,hidefromdir=%s|phonebook_direct_calling_ext=%d%s%.4d|phonebook_entry_fromcell=%s|phonebook_entry_owner=%s\n",
entry_number, entry_text, "no",
tech_pvt->gsmopen_dir_entry_extension_prefix, "3", gsmopen_dir_entry_extension, "yes", "not_specified");
}
}
}
if (tech_pvt->phonebook_listing_received_calls) {
int err, entry_id, entry_type;
char entry_number[256] = "";
char entry_text[256] = "";
if (option_debug)
DEBUGA_GSMOPEN("phonebook entry: |%s|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
err =
sscanf(&tech_pvt->line_array.result[i][7], "%d,\"%255[0-9+]\",%d,\"%255[^\"]\"", &entry_id, entry_number, &entry_type,
entry_text);
if (err < 1) { //we match only on the progressive id, maybe the remote party has not sent its number, and/or there is no corresponding text entry in the phone directory
ERRORA
("err=%d, phonebook entry: |%s| is not formatted as: |+CPBR: 504,\"+39025458068\",145,\"ciao a tutti\"|\n",
GSMOPEN_P_LOG, err, tech_pvt->line_array.result[i]);
} else {
//TODO: sanitize entry_text
if (option_debug)
DEBUGA_GSMOPEN("Number: %s, Text: %s, Type: %d\n", GSMOPEN_P_LOG, entry_number, entry_text, entry_type);
memset(tech_pvt->callid_name, 0, sizeof(tech_pvt->callid_name));
memset(tech_pvt->callid_number, 0, sizeof(tech_pvt->callid_number));
strncpy(tech_pvt->callid_name, entry_text, sizeof(tech_pvt->callid_name));
strncpy(tech_pvt->callid_number, entry_number, sizeof(tech_pvt->callid_number));
if (option_debug)
DEBUGA_GSMOPEN("incoming callid: Text: %s, Number: %s\n", GSMOPEN_P_LOG, tech_pvt->callid_name, tech_pvt->callid_number);
DEBUGA_GSMOPEN("|%s| CPBR INCOMING CALLID: name is %s, number is %s\n",
GSMOPEN_P_LOG, tech_pvt->line_array.result[i],
tech_pvt->callid_name[0] != 1 ? tech_pvt->callid_name : "not available",
tech_pvt->callid_number[0] ? tech_pvt->callid_number : "not available");
/* mark the time of RING */
gettimeofday(&(tech_pvt->ringtime), NULL);
tech_pvt->interface_state = GSMOPEN_STATE_RING;
tech_pvt->phone_callflow = CALLFLOW_INCOMING_RING;
}
}
else {
DEBUGA_GSMOPEN("phonebook entry: |%s|\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
}
}
if ((strncmp(tech_pvt->line_array.result[i], "*ECAV", 5) == 0) || (strncmp(tech_pvt->line_array.result[i], "*ECAM", 5) == 0)) { /* sony-ericsson call processing unsolicited messages */
int res, ccid, ccstatus, calltype, processid, exitcause, number, type;
res = ccid = ccstatus = calltype = processid = exitcause = number = type = 0;
res =
sscanf(&tech_pvt->line_array.result[i][6], "%d,%d,%d,%d,%d,%d,%d", &ccid, &ccstatus, &calltype, &processid, &exitcause, &number,
&type);
/* only changes the phone_callflow if enought parameters were parsed */
if (res >= 3) {
switch (ccstatus) {
case 0:
if (tech_pvt->owner) {
ast_setstate(tech_pvt->owner, GSMOPEN_STATE_DOWN);
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_NORMAL;
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
}
tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE;
tech_pvt->interface_state = GSMOPEN_STATE_DOWN;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: IDLE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
break;
case 1:
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: CALLING\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
break;
case 2:
if (tech_pvt->owner) {
ast_setstate(tech_pvt->owner, GSMOPEN_STATE_DIALING);
}
tech_pvt->interface_state = CALLFLOW_CALL_DIALING;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: CONNECTING\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
break;
case 3:
if (tech_pvt->owner) {
ast_setstate(tech_pvt->owner, GSMOPEN_STATE_UP);
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_ANSWER);
}
tech_pvt->phone_callflow = CALLFLOW_CALL_ACTIVE;
tech_pvt->interface_state = GSMOPEN_STATE_UP;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: ACTIVE\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
break;
case 4:
if (option_debug > 1)
DEBUGA_GSMOPEN
("|%s| Sony-Ericsson *ECAM/*ECAV: don't know how to handle HOLD event\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
break;
case 5:
if (option_debug > 1)
DEBUGA_GSMOPEN
("|%s| Sony-Ericsson *ECAM/*ECAV: don't know how to handle WAITING event\n", GSMOPEN_P_LOG,
tech_pvt->line_array.result[i]);
break;
case 6:
if (option_debug > 1)
DEBUGA_GSMOPEN
("|%s| Sony-Ericsson *ECAM/*ECAV: don't know how to handle ALERTING event\n", GSMOPEN_P_LOG,
tech_pvt->line_array.result[i]);
break;
case 7:
if (tech_pvt->owner) {
ast_setstate(tech_pvt->owner, GSMOPEN_STATE_BUSY);
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_BUSY);
}
tech_pvt->phone_callflow = CALLFLOW_CALL_LINEBUSY;
tech_pvt->interface_state = GSMOPEN_STATE_BUSY;
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: BUSY\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
break;
}
} else {
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| Sony-Ericsson *ECAM/*ECAV: could not parse parameters\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
}
/* at_indicator_* are unsolicited messages sent by the phone to signal us that some of its visual indicators on its screen has changed, based on CIND CMER ETSI docs */
if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_noservice_string) == 0)) {
ERRORA("|%s| at_indicator_noservice_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
alarm_event(tech_pvt, ALARM_NETWORK_NO_SERVICE, "at_indicator_noservice_string");
}
if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_nosignal_string) == 0)) {
ERRORA("|%s| at_indicator_nosignal_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
alarm_event(tech_pvt, ALARM_NETWORK_NO_SIGNAL, "at_indicator_nosignal_string");
}
if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_lowsignal_string) == 0)) {
WARNINGA("|%s| at_indicator_lowsignal_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
alarm_event(tech_pvt, ALARM_NETWORK_LOW_SIGNAL, "at_indicator_lowsignal_string");
}
if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_lowbattchg_string) == 0)) {
WARNINGA("|%s| at_indicator_lowbattchg_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_nobattchg_string) == 0)) {
ERRORA("|%s| at_indicator_nobattchg_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_callactive_string) == 0)) {
DEBUGA_GSMOPEN("|%s| at_indicator_callactive_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_nocallactive_string) == 0)) {
DEBUGA_GSMOPEN("|%s| at_indicator_nocallactive_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_nocallsetup_string) == 0)) {
DEBUGA_GSMOPEN("|%s| at_indicator_nocallsetup_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_callsetupincoming_string) == 0)) {
DEBUGA_GSMOPEN("|%s| at_indicator_callsetupincoming_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_callsetupoutgoing_string) == 0)) {
DEBUGA_GSMOPEN("|%s| at_indicator_callsetupoutgoing_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
if ((strcmp(tech_pvt->line_array.result[i], tech_pvt->at_indicator_callsetupremoteringing_string)
== 0)) {
DEBUGA_GSMOPEN("|%s| at_indicator_callsetupremoteringing_string\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
}
}
/* let's look for OK, ERROR and EXPECTED_STRING in the complete lines read so far, without re-looking at the lines that has been yet looked at */
for (i = la_read; i < la_counter; i++) {
if (expected_string) {
if ((strncmp(tech_pvt->line_array.result[i], expected_string, strlen(expected_string))
== 0)) {
if (option_debug > 1)
DEBUGA_GSMOPEN("|%s| got what EXPECTED\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
at_ack = AT_OK;
}
} else {
if ((strcmp(tech_pvt->line_array.result[i], "OK") == 0)) {
if (option_debug > 1)
DEBUGA_GSMOPEN("got OK\n", GSMOPEN_P_LOG);
at_ack = AT_OK;
}
}
if ((strcmp(tech_pvt->line_array.result[i], "ERROR") == 0)) {
if (option_debug > 1)
DEBUGA_GSMOPEN("got ERROR\n", GSMOPEN_P_LOG);
at_ack = AT_ERROR;
}
/* if we are requesting IMEI, put the line into the imei buffer if the line is not "OK" or "ERROR" */
if (tech_pvt->requesting_imei && at_ack == -1) {
if (strlen(tech_pvt->line_array.result[i])) { /* we are reading the IMEI */
strncpy(tech_pvt->imei, tech_pvt->line_array.result[i], sizeof(tech_pvt->imei));
}
}
/* if we are requesting IMSI, put the line into the imei buffer if the line is not "OK" or "ERROR" */
if (tech_pvt->requesting_imsi && at_ack == -1) {
if (strlen(tech_pvt->line_array.result[i])) { /* we are reading the IMSI */
strncpy(tech_pvt->imsi, tech_pvt->line_array.result[i], sizeof(tech_pvt->imsi));
}
}
/* if we are reading an sms message from memory, put the line into the sms buffer if the line is not "OK" or "ERROR" */
if (tech_pvt->reading_sms_msg > 1 && at_ack == -1) {
int c;
char sms_body[16000];
int err = 0;
memset(sms_body, '\0', sizeof(sms_body));
if (strncmp(tech_pvt->line_array.result[i], "+CMGR", 5) == 0) { /* we are reading the "header" of an SMS */
char content[512];
char content2[512];
int inside_comma = 0;
int inside_quote = 0;
int which_field = 0;
int d = 0;
DEBUGA_GSMOPEN("HERE\n", GSMOPEN_P_LOG);
memset(content, '\0', sizeof(content));
for (c = 0; c < strlen(tech_pvt->line_array.result[i]); c++) {
if (tech_pvt->line_array.result[i][c] == ',' && tech_pvt->line_array.result[i][c - 1] != '\\' && inside_quote == 0) {
if (inside_comma) {
inside_comma = 0;
DEBUGA_GSMOPEN("inside_comma=%d, inside_quote=%d, we're at=%s\n", GSMOPEN_P_LOG, inside_comma, inside_quote,
&tech_pvt->line_array.result[i][c]);
} else {
inside_comma = 1;
DEBUGA_GSMOPEN("inside_comma=%d, inside_quote=%d, we're at=%s\n", GSMOPEN_P_LOG, inside_comma, inside_quote,
&tech_pvt->line_array.result[i][c]);
}
}
if (tech_pvt->line_array.result[i][c] == '"' && tech_pvt->line_array.result[i][c - 1] != '\\') {
if (inside_quote) {
inside_quote = 0;
DEBUGA_GSMOPEN("END_CONTENT inside_comma=%d, inside_quote=%d, we're at=%s\n", GSMOPEN_P_LOG, inside_comma, inside_quote,
&tech_pvt->line_array.result[i][c]);
DEBUGA_GSMOPEN("%d content=%s\n", GSMOPEN_P_LOG, which_field, content);
memset(content2, '\0', sizeof(content2));
if (which_field == 1) {
//FIXME why this? err = ucs2_to_utf8(tech_pvt, content, content2, sizeof(content2));
err = ucs2_to_utf8(tech_pvt, content, content2, sizeof(content2));
} else {
err = 0;
strncpy(content2, content, sizeof(content2));
}
DEBUGA_GSMOPEN("%d content2=%s\n", GSMOPEN_P_LOG, which_field, content2);
DEBUGA_GSMOPEN("%d content=%s\n", GSMOPEN_P_LOG, which_field, content2);
memset(content, '\0', sizeof(content));
d = 0;
if (which_field == 1) {
strncpy(tech_pvt->sms_sender, content2, sizeof(tech_pvt->sms_sender));
DEBUGA_GSMOPEN("%d content=%s\n", GSMOPEN_P_LOG, which_field, content2);
} else if (which_field == 2) {
strncpy(tech_pvt->sms_date, content2, sizeof(tech_pvt->sms_date));
DEBUGA_GSMOPEN("%d content=%s\n", GSMOPEN_P_LOG, which_field, content2);
} else if (which_field > 2) {
WARNINGA("WHY which_field is > 2 ? (which_field is %d)\n", GSMOPEN_P_LOG, which_field);
}
which_field++;
} else {
inside_quote = 1;
DEBUGA_GSMOPEN("START_CONTENT inside_comma=%d, inside_quote=%d, we're at=%s\n", GSMOPEN_P_LOG, inside_comma, inside_quote,
&tech_pvt->line_array.result[i][c]);
}
}
if (inside_quote && tech_pvt->line_array.result[i][c] != '"') {
content[d] = tech_pvt->line_array.result[i][c];
d++;
}
}
} //it was the +CMGR answer from the cellphone
else {
DEBUGA_GSMOPEN("body=%s\n", GSMOPEN_P_LOG, sms_body);
DEBUGA_GSMOPEN("tech_pvt->line_array.result[i]=%s\n", GSMOPEN_P_LOG, tech_pvt->line_array.result[i]);
if (tech_pvt->sms_pdu_not_supported) {
char content3[1000];
strncpy(tech_pvt->sms_message, tech_pvt->line_array.result[i], sizeof(tech_pvt->sms_message));
memset(content3, '\0', sizeof(content3));
DEBUGA_GSMOPEN("sms_message=%s\n", GSMOPEN_P_LOG, tech_pvt->sms_message);
ucs2_to_utf8(tech_pvt, tech_pvt->sms_message, content3, sizeof(content3));
DEBUGA_GSMOPEN("content3=%s\n", GSMOPEN_P_LOG, content3);
strncpy(tech_pvt->sms_body, content3, sizeof(tech_pvt->sms_body));
if (tech_pvt->sms_cnmi_not_supported) {
sms_incoming(tech_pvt);
DEBUGA_GSMOPEN("2 content3=%s\n", GSMOPEN_P_LOG, content3);
}
} else {
#ifdef WANT_GSMLIB
try {
char content2[1000];
SMSMessageRef sms;
//MessageType messagetype;
//Address servicecentreaddress;
//Timestamp servicecentretimestamp;
//Address sender_recipient_address;
sms = SMSMessage::decode(tech_pvt->line_array.result[i]); // dataCodingScheme = 8 , text=ciao 123 belè новости לק ראת ﺎﻠﺠﻤﻋﺓ 人大
DEBUGA_GSMOPEN("SMS=\n%s\n", GSMOPEN_P_LOG, sms->toString().c_str());
memset(content2, '\0', sizeof(content2));
if (sms->dataCodingScheme().getAlphabet() == DCS_DEFAULT_ALPHABET) {
iso_8859_1_to_utf8(tech_pvt, (char *) sms->userData().c_str(), content2, sizeof(content2));
} else if (sms->dataCodingScheme().getAlphabet() == DCS_SIXTEEN_BIT_ALPHABET) {
ucs2_to_utf8(tech_pvt, (char *) bufToHex((unsigned char *) sms->userData().data(), sms->userData().length()).c_str(),
content2, sizeof(content2));
} else {
ERRORA("dataCodingScheme not supported=%d\n", GSMOPEN_P_LOG, sms->dataCodingScheme().getAlphabet());
}
DEBUGA_GSMOPEN("dataCodingScheme=%d\n", GSMOPEN_P_LOG, sms->dataCodingScheme().getAlphabet());
DEBUGA_GSMOPEN("dataCodingScheme=%s\n", GSMOPEN_P_LOG, sms->dataCodingScheme().toString().c_str());
DEBUGA_GSMOPEN("address=%s\n", GSMOPEN_P_LOG, sms->address().toString().c_str());
DEBUGA_GSMOPEN("serviceCentreAddress=%s\n", GSMOPEN_P_LOG, sms->serviceCentreAddress().toString().c_str());
DEBUGA_GSMOPEN("serviceCentreTimestamp=%s\n", GSMOPEN_P_LOG, sms->serviceCentreTimestamp().toString().c_str());
DEBUGA_GSMOPEN("messageType=%d\n", GSMOPEN_P_LOG, sms->messageType());
DEBUGA_GSMOPEN("userData= |||%s|||\n", GSMOPEN_P_LOG, content2);
memset(sms_body, '\0', sizeof(sms_body));
strncpy(sms_body, content2, sizeof(sms_body));
DEBUGA_GSMOPEN("body=%s\n", GSMOPEN_P_LOG, sms_body);
strncpy(tech_pvt->sms_body, sms_body, sizeof(tech_pvt->sms_body));
strncpy(tech_pvt->sms_sender, sms->address().toString().c_str(), sizeof(tech_pvt->sms_sender));
strncpy(tech_pvt->sms_date, sms->serviceCentreTimestamp().toString().c_str(), sizeof(tech_pvt->sms_date));
strncpy(tech_pvt->sms_datacodingscheme, sms->dataCodingScheme().toString().c_str(), sizeof(tech_pvt->sms_datacodingscheme));
strncpy(tech_pvt->sms_servicecentreaddress, sms->serviceCentreAddress().toString().c_str(),
sizeof(tech_pvt->sms_servicecentreaddress));
tech_pvt->sms_messagetype = sms->messageType();
//messagetype = sms->messageType();
//servicecentreaddress = sms->serviceCentreAddress();
//servicecentretimestamp = sms->serviceCentreTimestamp();
//sender_recipient_address = sms->address();
}
catch(GsmException & ge) {
ERRORA("GsmException= |||%s|||\n", GSMOPEN_P_LOG, ge.what());
}
#endif // WANT_GSMLIB
}
} //it was the UCS2 from cellphone
} //we were reading the SMS
}
la_read = la_counter;
if (look_for_ack && at_ack > -1)
break;
if (la_counter == AT_MESG_MAX_LINES) {
ERRORA("Too many lines in result (>%d). la_counter=%d. tech_pvt->reading_sms_msg=%d. Stop accumulating lines.\n", GSMOPEN_P_LOG,
AT_MESG_MAX_LINES, la_counter, tech_pvt->reading_sms_msg);
WARNINGA("read was %d bytes, tmp_answer3= --|%s|--\n", GSMOPEN_P_LOG, read_count, tmp_answer3);
at_ack = AT_ERROR;
break;
}
}
UNLOCKA(tech_pvt->controldev_lock);
POPPA_UNLOCKA(tech_pvt->controldev_lock);
if (select_err == -1) {
ERRORA("select returned -1 on %s, setting controldev_dead, error was: %s\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name, strerror(errno));
tech_pvt->controldev_dead = 1;
tech_pvt->running = 0;
alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "select returned -1 on interface, setting controldev_dead");
tech_pvt->active = 0;
tech_pvt->name[0] = '\0';
if (tech_pvt->owner)
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
switch_sleep(1000000);
return -1;
}
if (tech_pvt->phone_callflow == CALLFLOW_CALL_INCOMING && tech_pvt->call_incoming_time.tv_sec) { //after three sec of CALLFLOW_CALL_INCOMING, we assume the phone is incapable of notifying RING (eg: motorola c350), so we try to answer
char list_command[64];
struct timeval call_incoming_timeout;
gettimeofday(&call_incoming_timeout, NULL);
call_incoming_timeout.tv_sec -= 3;
DEBUGA_GSMOPEN
("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n",
GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec);
if (call_incoming_timeout.tv_sec > tech_pvt->call_incoming_time.tv_sec) {
tech_pvt->call_incoming_time.tv_sec = 0;
tech_pvt->call_incoming_time.tv_usec = 0;
DEBUGA_GSMOPEN
("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n",
GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec);
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CPBS=RC");
if (res) {
ERRORA("AT+CPBS=RC (select memory of received calls) was not answered by the phone\n", GSMOPEN_P_LOG);
}
tech_pvt->phonebook_querying = 1;
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CPBR=?");
if (res) {
ERRORA("AT+CPBS=RC (select memory of received calls) was not answered by the phone\n", GSMOPEN_P_LOG);
}
tech_pvt->phonebook_querying = 0;
sprintf(list_command, "AT+CPBR=%d,%d", tech_pvt->phonebook_first_entry, tech_pvt->phonebook_last_entry);
tech_pvt->phonebook_listing_received_calls = 1;
res = gsmopen_serial_write_AT_expect_longtime(tech_pvt, list_command, "OK");
if (res) {
WARNINGA("AT+CPBR=%d,%d failed, continue\n", GSMOPEN_P_LOG, tech_pvt->phonebook_first_entry, tech_pvt->phonebook_last_entry);
}
tech_pvt->phonebook_listing_received_calls = 0;
}
}
if (tech_pvt->phone_callflow == CALLFLOW_INCOMING_RING) {
struct timeval call_incoming_timeout;
gettimeofday(&call_incoming_timeout, NULL);
call_incoming_timeout.tv_sec -= 10;
// DEBUGA_GSMOPEN ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n", GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec);
if (call_incoming_timeout.tv_sec > tech_pvt->ringtime.tv_sec) {
ERRORA("Ringing stopped and I have not answered. Why?\n", GSMOPEN_P_LOG);
DEBUGA_GSMOPEN
("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n",
GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec);
if (tech_pvt->owner) {
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
}
}
}
tech_pvt->line_array.elemcount = la_counter;
//NOTICA (" OUTSIDE this gsmopen_serial_device %s \n", GSMOPEN_P_LOG, tech_pvt->controldevice_name);
if (look_for_ack)
return at_ack;
else
return 0;
}
//cicopet int gsmopen_serial_write_AT(private_t * tech_pvt, const char *data)
int gsmopen_serial_write_AT(private_t *tech_pvt, const char *data)
{
int howmany;
int i;
int res;
int count;
char *Data = (char *) data;
howmany = strlen(Data);
for (i = 0; i < howmany; i++) {
//cicopetres = write(tech_pvt->controldevfd, &data[i], 1);
res = tech_pvt->serialPort_serial_control->Write(&Data[i], 1);
if (res != 1) {
DEBUGA_GSMOPEN("Error sending (%.1s): %d (%s)\n", GSMOPEN_P_LOG, &Data[i], res, strerror(errno));
gsmopen_sleep(100000);
for (count = 0; count < 10; count++) {
//cicopet res = write(tech_pvt->controldevfd, &data[i], 1);
res = tech_pvt->serialPort_serial_control->Write(&Data[i], 1);
if (res == 1) {
DEBUGA_GSMOPEN("Successfully RE-sent (%.1s): %d %d (%s)\n", GSMOPEN_P_LOG, &Data[i], count, res, strerror(errno));
break;
} else
DEBUGA_GSMOPEN("Error RE-sending (%.1s): %d %d (%s)\n", GSMOPEN_P_LOG, &Data[i], count, res, strerror(errno));
gsmopen_sleep(100000);
}
if (res != 1) {
ERRORA("Error RE-sending (%.1s): %d %d (%s)\n", GSMOPEN_P_LOG, &Data[i], count, res, strerror(errno));
ERRORA
("wrote -1 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, power down or battery exhausted\n",
GSMOPEN_P_LOG, tech_pvt->controldevice_name);
tech_pvt->controldev_dead = 1;
//cicopet close(tech_pvt->controldevfd);
ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name);
tech_pvt->running = 0;
alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead");
tech_pvt->active = 0;
tech_pvt->name[0] = '\0';
UNLOCKA(tech_pvt->controldev_lock);
if (tech_pvt->owner) {
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
}
switch_sleep(1000000);
return -1;
}
}
if (option_debug > 1)
DEBUGA_GSMOPEN("sent data... (%.1s)\n", GSMOPEN_P_LOG, &Data[i]);
gsmopen_sleep(1000); /* release the cpu */
}
//cicopet res = write(tech_pvt->controldevfd, "\r", 1);
res = tech_pvt->serialPort_serial_control->Write((char *) "\r", 1);
if (res != 1) {
DEBUGA_GSMOPEN("Error sending (carriage return): %d (%s)\n", GSMOPEN_P_LOG, res, strerror(errno));
gsmopen_sleep(100000);
for (count = 0; count < 10; count++) {
//cicopet res = write(tech_pvt->controldevfd, "\r", 1);
res = tech_pvt->serialPort_serial_control->Write((char *) "\r", 1);
if (res == 1) {
DEBUGA_GSMOPEN("Successfully RE-sent carriage return: %d %d (%s)\n", GSMOPEN_P_LOG, count, res, strerror(errno));
break;
} else
DEBUGA_GSMOPEN("Error RE-sending (carriage return): %d %d (%s)\n", GSMOPEN_P_LOG, count, res, strerror(errno));
gsmopen_sleep(100000);
}
if (res != 1) {
ERRORA("Error RE-sending (carriage return): %d %d (%s)\n", GSMOPEN_P_LOG, count, res, strerror(errno));
ERRORA
("wrote -1 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, power down or battery exhausted\n",
GSMOPEN_P_LOG, tech_pvt->controldevice_name);
tech_pvt->controldev_dead = 1;
//cicopet close(tech_pvt->controldevfd);
ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name);
tech_pvt->running = 0;
alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead");
tech_pvt->active = 0;
tech_pvt->name[0] = '\0';
UNLOCKA(tech_pvt->controldev_lock);
if (tech_pvt->owner) {
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
}
switch_sleep(1000000);
return -1;
}
}
if (option_debug > 1)
DEBUGA_GSMOPEN("sent (carriage return)\n", GSMOPEN_P_LOG);
gsmopen_sleep(1000); /* release the cpu */
return howmany;
}
int gsmopen_serial_write_AT_nocr(private_t *tech_pvt, const char *data)
{
int howmany;
int i;
int res;
int count;
char *Data = (char *) data;
howmany = strlen(Data);
for (i = 0; i < howmany; i++) {
//cicopet res = write(tech_pvt->controldevfd, &data[i], 1);
res = tech_pvt->serialPort_serial_control->Write(&Data[i], 1);
if (res != 1) {
DEBUGA_GSMOPEN("Error sending (%.1s): %d (%s)\n", GSMOPEN_P_LOG, &Data[i], res, strerror(errno));
gsmopen_sleep(100000);
for (count = 0; count < 10; count++) {
//cicopet res = write(tech_pvt->controldevfd, &data[i], 1);
res = tech_pvt->serialPort_serial_control->Write(&Data[i], 1);
if (res == 1)
break;
else
DEBUGA_GSMOPEN("Error RE-sending (%.1s): %d %d (%s)\n", GSMOPEN_P_LOG, &Data[i], count, res, strerror(errno));
gsmopen_sleep(100000);
}
if (res != 1) {
ERRORA("Error RE-sending (%.1s): %d %d (%s)\n", GSMOPEN_P_LOG, &Data[i], count, res, strerror(errno));
ERRORA
("wrote -1 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, power down or battery exhausted\n",
GSMOPEN_P_LOG, tech_pvt->controldevice_name);
tech_pvt->controldev_dead = 1;
//cicopet close(tech_pvt->controldevfd);
ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name);
tech_pvt->running = 0;
alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead");
tech_pvt->active = 0;
tech_pvt->name[0] = '\0';
UNLOCKA(tech_pvt->controldev_lock);
if (tech_pvt->owner) {
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
}
switch_sleep(1000000);
return -1;
}
}
if (option_debug > 1)
DEBUGA_GSMOPEN("sent data... (%.1s)\n", GSMOPEN_P_LOG, &Data[i]);
gsmopen_sleep(1000); /* release the cpu */
}
gsmopen_sleep(1000); /* release the cpu */
return howmany;
}
int gsmopen_serial_write_AT_noack(private_t *tech_pvt, const char *data)
{
if (option_debug > 1)
DEBUGA_GSMOPEN("gsmopen_serial_write_AT_noack: %s\n", GSMOPEN_P_LOG, data);
PUSHA_UNLOCKA(tech_pvt->controldev_lock);
LOKKA(tech_pvt->controldev_lock);
if (gsmopen_serial_write_AT(tech_pvt, data) != strlen(data)) {
ERRORA("Error sending data... (%s)\n", GSMOPEN_P_LOG, strerror(errno));
UNLOCKA(tech_pvt->controldev_lock);
ERRORA
("wrote -1 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, power down or battery exhausted\n",
GSMOPEN_P_LOG, tech_pvt->controldevice_name);
tech_pvt->controldev_dead = 1;
//cicopet close(tech_pvt->controldevfd);
ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name);
tech_pvt->running = 0;
alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead");
tech_pvt->active = 0;
tech_pvt->name[0] = '\0';
UNLOCKA(tech_pvt->controldev_lock);
if (tech_pvt->owner) {
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
}
switch_sleep(1000000);
return -1;
}
UNLOCKA(tech_pvt->controldev_lock);
POPPA_UNLOCKA(tech_pvt->controldev_lock);
return 0;
}
int gsmopen_serial_write_AT_ack(private_t *tech_pvt, const char *data)
{
int at_result = AT_ERROR;
PUSHA_UNLOCKA(tech_pvt->controldev_lock);
LOKKA(tech_pvt->controldev_lock);
if (option_debug > 1)
DEBUGA_GSMOPEN("sending: %s\n", GSMOPEN_P_LOG, data);
if (gsmopen_serial_write_AT(tech_pvt, data) != strlen(data)) {
ERRORA("Error sending data... (%s) \n", GSMOPEN_P_LOG, strerror(errno));
UNLOCKA(tech_pvt->controldev_lock);
ERRORA
("wrote -1 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, power down or battery exhausted\n",
GSMOPEN_P_LOG, tech_pvt->controldevice_name);
tech_pvt->controldev_dead = 1;
//cicopet close(tech_pvt->controldevfd);
ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name);
tech_pvt->running = 0;
alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead");
tech_pvt->active = 0;
tech_pvt->name[0] = '\0';
UNLOCKA(tech_pvt->controldev_lock);
if (tech_pvt->owner) {
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
}
switch_sleep(1000000);
return -1;
}
//cicopet at_result = gsmopen_serial_read_AT(tech_pvt, 1, 500000, 2, NULL, 1); // 2.5 sec timeout
at_result = gsmopen_serial_read_AT(tech_pvt, 1, 100000, 0, NULL, 1); // 1/10th sec timeout
UNLOCKA(tech_pvt->controldev_lock);
POPPA_UNLOCKA(tech_pvt->controldev_lock);
return at_result;
}
int gsmopen_serial_write_AT_ack_nocr_longtime(private_t *tech_pvt, const char *data)
{
int at_result = AT_ERROR;
PUSHA_UNLOCKA(tech_pvt->controldev_lock);
LOKKA(tech_pvt->controldev_lock);
if (option_debug > 1)
DEBUGA_GSMOPEN("sending: %s\n", GSMOPEN_P_LOG, data);
if (gsmopen_serial_write_AT_nocr(tech_pvt, data) != strlen(data)) {
ERRORA("Error sending data... (%s) \n", GSMOPEN_P_LOG, strerror(errno));
UNLOCKA(tech_pvt->controldev_lock);
ERRORA
("wrote -1 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, power down or battery exhausted\n",
GSMOPEN_P_LOG, tech_pvt->controldevice_name);
tech_pvt->controldev_dead = 1;
//cicopet close(tech_pvt->controldevfd);
ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name);
tech_pvt->running = 0;
alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead");
tech_pvt->active = 0;
tech_pvt->name[0] = '\0';
UNLOCKA(tech_pvt->controldev_lock);
if (tech_pvt->owner) {
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
}
switch_sleep(1000000);
return -1;
}
at_result = gsmopen_serial_read_AT(tech_pvt, 1, 500000, 20, NULL, 1); // 20.5 sec timeout
UNLOCKA(tech_pvt->controldev_lock);
POPPA_UNLOCKA(tech_pvt->controldev_lock);
return at_result;
}
int gsmopen_serial_write_AT_expect1(private_t *tech_pvt, const char *data, const char *expected_string, int expect_crlf, int seconds)
{
int at_result = AT_ERROR;
PUSHA_UNLOCKA(tech_pvt->controldev_lock);
LOKKA(tech_pvt->controldev_lock);
if (option_debug > 1)
DEBUGA_GSMOPEN("sending: %s, expecting: %s\n", GSMOPEN_P_LOG, data, expected_string);
if (gsmopen_serial_write_AT(tech_pvt, data) != strlen(data)) {
ERRORA("Error sending data... (%s) \n", GSMOPEN_P_LOG, strerror(errno));
UNLOCKA(tech_pvt->controldev_lock);
ERRORA
("wrote -1 bytes!!! Nenormalno! Marking this gsmopen_serial_device %s as dead, andif it is owned by a channel, hanging up. Maybe the phone is stuck, switched off, power down or battery exhausted\n",
GSMOPEN_P_LOG, tech_pvt->controldevice_name);
tech_pvt->controldev_dead = 1;
//cicopet close(tech_pvt->controldevfd);
ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name);
tech_pvt->running = 0;
alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead");
tech_pvt->active = 0;
tech_pvt->name[0] = '\0';
UNLOCKA(tech_pvt->controldev_lock);
if (tech_pvt->owner) {
tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE;
gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP);
}
switch_sleep(1000000);
return -1;
}
at_result = gsmopen_serial_read_AT(tech_pvt, 1, 100000, seconds, expected_string, expect_crlf); // minimum 1/10th sec timeout
UNLOCKA(tech_pvt->controldev_lock);
POPPA_UNLOCKA(tech_pvt->controldev_lock);
return at_result;
}
int gsmopen_serial_AT_expect(private_t *tech_pvt, const char *expected_string, int expect_crlf, int seconds)
{
int at_result = AT_ERROR;
PUSHA_UNLOCKA(tech_pvt->controldev_lock);
LOKKA(tech_pvt->controldev_lock);
if (option_debug > 1)
DEBUGA_GSMOPEN("expecting: %s\n", GSMOPEN_P_LOG, expected_string);
//cicopet at_result = gsmopen_serial_read_AT(tech_pvt, 1, 500000, seconds, expected_string, expect_crlf); // 20.5 sec timeout, used for querying the SIM and sending SMSs
at_result = gsmopen_serial_read_AT(tech_pvt, 1, 100000, seconds, expected_string, expect_crlf); // minimum 1/10th sec timeout
UNLOCKA(tech_pvt->controldev_lock);
POPPA_UNLOCKA(tech_pvt->controldev_lock);
return at_result;
}
int gsmopen_serial_answer(private_t *tech_pvt)
{
if (tech_pvt->controldevprotocol == PROTOCOL_AT)
return gsmopen_serial_answer_AT(tech_pvt);
#ifdef GSMOPEN_FBUS2
if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2)
return gsmopen_serial_answer_FBUS2(tech_pvt);
#endif /* GSMOPEN_FBUS2 */
#ifdef GSMOPEN_CVM
if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL)
return gsmopen_serial_answer_CVM_BUSMAIL(tech_pvt);
#endif /* GSMOPEN_CVM */
return -1;
}
int gsmopen_serial_answer_AT(private_t *tech_pvt)
{
int res;
res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_answer, tech_pvt->at_answer_expect);
if (res) {
DEBUGA_GSMOPEN
("at_answer command failed, command used: %s, expecting: %s, trying with AT+CKPD=\"S\"\n",
GSMOPEN_P_LOG, tech_pvt->at_answer, tech_pvt->at_answer_expect);
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CKPD=\"S\"");
if (res) {
ERRORA("at_answer command failed, command used: 'AT+CKPD=\"S\"', giving up\n", GSMOPEN_P_LOG);
return -1;
}
}
res = gsmopen_serial_write_AT_expect(tech_pvt, "AT^DDSETEX=2", tech_pvt->at_dial_expect);
//tech_pvt->interface_state = GSMOPEN_STATE_UP;
//tech_pvt->phone_callflow = CALLFLOW_CALL_ACTIVE;
DEBUGA_GSMOPEN("AT: call answered\n", GSMOPEN_P_LOG);
return 0;
}
int gsmopen_serial_hangup(private_t *tech_pvt)
{
if (tech_pvt->controldevprotocol == PROTOCOL_AT)
return gsmopen_serial_hangup_AT(tech_pvt);
#ifdef GSMOPEN_FBUS2
if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2)
return gsmopen_serial_hangup_FBUS2(tech_pvt);
#endif /* GSMOPEN_FBUS2 */
#ifdef GSMOPEN_CVM
if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL)
return gsmopen_serial_hangup_CVM_BUSMAIL(tech_pvt);
#endif /* GSMOPEN_CVM */
return -1;
}
int gsmopen_serial_hangup_AT(private_t *tech_pvt)
{
int res;
if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) {
res = gsmopen_serial_write_AT_expect(tech_pvt, tech_pvt->at_hangup, tech_pvt->at_hangup_expect);
if (res) {
DEBUGA_GSMOPEN("at_hangup command failed, command used: %s, trying to use AT+CKPD=\"EEE\"\n", GSMOPEN_P_LOG, tech_pvt->at_hangup);
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CKPD=\"EEE\"");
if (res) {
ERRORA("at_hangup command failed, command used: 'AT+CKPD=\"EEE\"'\n", GSMOPEN_P_LOG);
return -1;
}
}
res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CHUP");
if (res) {
DEBUGA_GSMOPEN("at_hangup command timeout, command used: 'AT+CHUP'\n", GSMOPEN_P_LOG);
//return -1;
}
}
tech_pvt->interface_state = GSMOPEN_STATE_DOWN;
tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE;
return 0;
}
int gsmopen_serial_call(private_t *tech_pvt, char *dstr)
{
if (tech_pvt->controldevprotocol == PROTOCOL_AT)
return gsmopen_serial_call_AT(tech_pvt, dstr);
#ifdef GSMOPEN_FBUS2
if (tech_pvt->controldevprotocol == PROTOCOL_FBUS2)
return gsmopen_serial_call_FBUS2(tech_pvt, dstr);
#endif /* GSMOPEN_FBUS2 */
if (tech_pvt->controldevprotocol == PROTOCOL_NO_SERIAL)
return 0;
#ifdef GSMOPEN_CVM
if (tech_pvt->controldevprotocol == PROTOCOL_CVM_BUSMAIL)
return gsmopen_serial_call_CVM_BUSMAIL(tech_pvt, dstr);
#endif /* GSMOPEN_CVM */
return -1;
}
int gsmopen_serial_call_AT(private_t *tech_pvt, char *dstr)
{
int res;
char at_command[256];
if (option_debug)
DEBUGA_PBX("Dialing %s\n", GSMOPEN_P_LOG, dstr);
memset(at_command, 0, sizeof(at_command));
tech_pvt->phone_callflow = CALLFLOW_CALL_DIALING;
tech_pvt->interface_state = GSMOPEN_STATE_DIALING;
//ast_uri_decode(dstr);
/*
size_t fixdstr = strspn(dstr, AST_DIGIT_ANYDIG);
if (fixdstr == 0) {
ERRORA("dial command failed because of invalid dial number. dial string was: %s\n",
GSMOPEN_P_LOG, dstr);
return -1;
}
*/
//dstr[fixdstr] = '\0';
sprintf(at_command, "%s%s%s", tech_pvt->at_dial_pre_number, dstr, tech_pvt->at_dial_post_number);
DEBUGA_PBX("Dialstring %s\n", GSMOPEN_P_LOG, at_command);
res = gsmopen_serial_write_AT_expect(tech_pvt, at_command, tech_pvt->at_dial_expect);
if (res) {
ERRORA("dial command failed, dial string was: %s\n", GSMOPEN_P_LOG, at_command);
return -1;
}
res = gsmopen_serial_write_AT_expect(tech_pvt, "AT^DDSETEX=2", tech_pvt->at_dial_expect);
// jet - early audio
//if (tech_pvt->at_early_audio) {
//ast_queue_control(tech_pvt->owner, AST_CONTROL_ANSWER);
//}
return 0;
}
int ucs2_to_utf8(private_t *tech_pvt, char *ucs2_in, char *utf8_out, size_t outbytesleft)
{
char converted[16000];
//#ifndef WIN32
iconv_t iconv_format;
int iconv_res;
char *outbuf;
char *inbuf;
size_t inbytesleft;
int c;
char stringa[5];
double hexnum;
int i = 0;
memset(converted, '\0', sizeof(converted));
DEBUGA_GSMOPEN("ucs2_in=|%s|, utf8_out=|%s|\n", GSMOPEN_P_LOG, ucs2_in, utf8_out);
/* cicopet */
for (c = 0; c < strlen(ucs2_in); c++) {
sprintf(stringa, "0x%c%c", ucs2_in[c], ucs2_in[c + 1]);
c++;
hexnum = strtod(stringa, NULL);
converted[i] = (char) hexnum;
i++;
}
outbuf = utf8_out;
inbuf = converted;
iconv_format = iconv_open("UTF8", "UCS-2BE");
//iconv_format = iconv_open("UTF8", "UCS2");
if (iconv_format == (iconv_t) -1) {
ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno));
return -1;
}
inbytesleft = i;
DEBUGA_GSMOPEN("1 ciao in=%s, inleft=%d, out=%s, outleft=%d, converted=%s, utf8_out=%s\n",
GSMOPEN_P_LOG, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, converted, utf8_out);
#ifdef WIN32
iconv_res = iconv(iconv_format, (const char **) &inbuf, &inbytesleft, &outbuf, &outbytesleft);
#else // WIN32
iconv_res = iconv(iconv_format, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
#endif // WIN32
if (iconv_res == (size_t) -1) {
DEBUGA_GSMOPEN("2 ciao in=%s, inleft=%d, out=%s, outleft=%d, converted=%s, utf8_out=%s\n",
GSMOPEN_P_LOG, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, converted, utf8_out);
DEBUGA_GSMOPEN("3 error: %s %d\n", GSMOPEN_P_LOG, strerror(errno), errno);
iconv_close(iconv_format);
return -1;
}
DEBUGA_GSMOPEN
("iconv_res=%d, in=%s, inleft=%d, out=%s, outleft=%d, converted=%s, utf8_out=%s\n",
GSMOPEN_P_LOG, iconv_res, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, converted, utf8_out);
iconv_close(iconv_format);
//#endif //WIN32
return 0;
}
int utf8_to_iso_8859_1(private_t *tech_pvt, char *utf8_in, size_t inbytesleft, char *iso_8859_1_out, size_t outbytesleft)
{
/* cicopet */
//#ifndef WIN32
iconv_t iconv_format;
int iconv_res;
char *outbuf;
char *inbuf;
outbuf = iso_8859_1_out;
inbuf = utf8_in;
iconv_format = iconv_open("ISO_8859-1", "UTF8");
if (iconv_format == (iconv_t) -1) {
ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno));
return -1;
}
outbytesleft = strlen(utf8_in) * 2;
DEBUGA_GSMOPEN("in=%s, inleft=%d, out=%s, outleft=%d, utf8_in=%s, iso_8859_1_out=%s\n",
GSMOPEN_P_LOG, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, utf8_in, iso_8859_1_out);
#ifdef WIN32
iconv_res = iconv(iconv_format, (const char **) &inbuf, &inbytesleft, &outbuf, &outbytesleft);
#else // WIN32
iconv_res = iconv(iconv_format, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
#endif // WIN32
if (iconv_res == (size_t) -1) {
ERRORA("error: %s %d\n", GSMOPEN_P_LOG, strerror(errno), errno);
return -1;
}
DEBUGA_GSMOPEN
("iconv_res=%d, in=%s, inleft=%d, out=%s, outleft=%d, utf8_in=%s, iso_8859_1_out=%s\n",
GSMOPEN_P_LOG, iconv_res, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, utf8_in, iso_8859_1_out);
iconv_close(iconv_format);
#if 0
for (i = 0; i < 16000 - outbytesleft; i++) {
memset(stringa, '\0', sizeof(stringa));
memset(stringa2, '\0', sizeof(stringa2));
sprintf(stringa, "%02X", converted[i]);
DEBUGA_GSMOPEN("character is |%02X|\n", GSMOPEN_P_LOG, converted[i]);
stringa2[0] = stringa[strlen(stringa) - 2];
stringa2[1] = stringa[strlen(stringa) - 1];
strncat(iso_8859_1_out, stringa2, ((outbytesleft - strlen(iso_8859_1_out)) - 1)); //add the received line to the buffer
DEBUGA_GSMOPEN("stringa=%s, stringa2=%s, iso_8859_1_out=%s\n", GSMOPEN_P_LOG, stringa, stringa2, iso_8859_1_out);
}
#endif //0
//#endif //WIN32
return 0;
}
int iso_8859_1_to_utf8(private_t *tech_pvt, char *iso_8859_1_in, char *utf8_out, size_t outbytesleft)
{
//#ifndef WIN32
iconv_t iconv_format;
int iconv_res;
char *outbuf;
char *inbuf;
size_t inbytesleft;
//int c;
//char stringa[5];
//double hexnum;
//int i = 0;
DEBUGA_GSMOPEN("iso_8859_1_in=%s\n", GSMOPEN_P_LOG, iso_8859_1_in);
outbuf = utf8_out;
inbuf = iso_8859_1_in;
iconv_format = iconv_open("UTF8", "ISO_8859-1");
if (iconv_format == (iconv_t) -1) {
ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno));
return -1;
}
inbytesleft = strlen(iso_8859_1_in) * 2;
#ifdef WIN32
iconv_res = iconv(iconv_format, (const char **) &inbuf, &inbytesleft, &outbuf, &outbytesleft);
#else // WIN32
iconv_res = iconv(iconv_format, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
#endif // WIN32
if (iconv_res == (size_t) -1) {
DEBUGA_GSMOPEN("ciao in=%s, inleft=%d, out=%s, outleft=%d, utf8_out=%s\n",
GSMOPEN_P_LOG, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, utf8_out);
DEBUGA_GSMOPEN("error: %s %d\n", GSMOPEN_P_LOG, strerror(errno), errno);
return -1;
}
DEBUGA_GSMOPEN
(" strlen(iso_8859_1_in)=%d, iconv_res=%d, inbuf=%s, inleft=%d, out=%s, outleft=%d, utf8_out=%s\n",
GSMOPEN_P_LOG, (int) strlen(iso_8859_1_in), iconv_res, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, utf8_out);
iconv_close(iconv_format);
//#endif //WIN32
return 0;
}
int utf8_to_ucs2(private_t *tech_pvt, char *utf8_in, size_t inbytesleft, char *ucs2_out, size_t outbytesleft)
{
/* cicopet */
//#ifndef WIN32
iconv_t iconv_format;
int iconv_res;
char *outbuf;
char *inbuf;
char converted[16000];
int i;
char stringa[16];
char stringa2[16];
memset(converted, '\0', sizeof(converted));
outbuf = converted;
inbuf = utf8_in;
iconv_format = iconv_open("UCS-2BE", "UTF8");
if (iconv_format == (iconv_t) -1) {
ERRORA("error: %s\n", GSMOPEN_P_LOG, strerror(errno));
return -1;
}
outbytesleft = 16000;
DEBUGA_GSMOPEN("in=%s, inleft=%d, out=%s, outleft=%d, utf8_in=%s, converted=%s\n",
GSMOPEN_P_LOG, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, utf8_in, converted);
#ifdef WIN32
iconv_res = iconv(iconv_format, (const char **) &inbuf, &inbytesleft, &outbuf, &outbytesleft);
#else // WIN32
iconv_res = iconv(iconv_format, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
#endif // WIN32
if (iconv_res == (size_t) -1) {
ERRORA("error: %s %d\n", GSMOPEN_P_LOG, strerror(errno), errno);
return -1;
}
DEBUGA_GSMOPEN
("iconv_res=%d, in=%s, inleft=%d, out=%s, outleft=%d, utf8_in=%s, converted=%s\n",
GSMOPEN_P_LOG, iconv_res, inbuf, (int) inbytesleft, outbuf, (int) outbytesleft, utf8_in, converted);
iconv_close(iconv_format);
for (i = 0; i < 16000 - outbytesleft; i++) {
memset(stringa, '\0', sizeof(stringa));
memset(stringa2, '\0', sizeof(stringa2));
sprintf(stringa, "%02X", converted[i]);
DEBUGA_GSMOPEN("character is |%02X|\n", GSMOPEN_P_LOG, converted[i]);
stringa2[0] = stringa[strlen(stringa) - 2];
stringa2[1] = stringa[strlen(stringa) - 1];
strncat(ucs2_out, stringa2, ((outbytesleft - strlen(ucs2_out)) - 1)); //add the received line to the buffer
DEBUGA_GSMOPEN("stringa=%s, stringa2=%s, ucs2_out=%s\n", GSMOPEN_P_LOG, stringa, stringa2, ucs2_out);
}
//#endif //WIN32
return 0;
}
/*! \brief Answer incoming call,
* Part of PBX interface */
int gsmopen_answer(private_t *tech_pvt)
{
int res;
if (option_debug) {
DEBUGA_PBX("ENTERING FUNC\n", GSMOPEN_P_LOG);
}
/* do something to actually answer the call, if needed (eg. pick up the phone) */
if (tech_pvt->controldevprotocol != PROTOCOL_NO_SERIAL) {
if (gsmopen_serial_answer(tech_pvt)) {
ERRORA("gsmopen_answer FAILED\n", GSMOPEN_P_LOG);
if (option_debug) {
DEBUGA_PBX("EXITING FUNC\n", GSMOPEN_P_LOG);
}
return -1;
}
}
tech_pvt->interface_state = GSMOPEN_STATE_UP;
tech_pvt->phone_callflow = CALLFLOW_CALL_ACTIVE;
while (tech_pvt->interface_state == GSMOPEN_STATE_RING) {
gsmopen_sleep(10000); //10msec
}
if (tech_pvt->interface_state != GSMOPEN_STATE_UP) {
ERRORA("call answering failed\n", GSMOPEN_P_LOG);
res = -1;
} else {
if (option_debug)
DEBUGA_PBX("call answered\n", GSMOPEN_P_LOG);
res = 0;
if (tech_pvt->owner) {
DEBUGA_PBX("going to send GSMOPEN_STATE_UP\n", GSMOPEN_P_LOG);
ast_setstate(tech_pvt->owner, GSMOPEN_STATE_UP);
//ast_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_ANSWER);
//gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_ANSWER);
DEBUGA_PBX("just sent GSMOPEN_STATE_UP\n", GSMOPEN_P_LOG);
}
}
if (option_debug) {
DEBUGA_PBX("EXITING FUNC\n", GSMOPEN_P_LOG);
}
return res;
}
int gsmopen_ring(private_t *tech_pvt)
{
int res = 0;
switch_core_session_t *session = NULL;
switch_channel_t *channel = NULL;
session = switch_core_session_locate(tech_pvt->session_uuid_str);
if (session) {
switch_core_session_rwunlock(session);
//DEBUGA_PBX("got session, let's exit\n", GSMOPEN_P_LOG);
return 0;
}
new_inbound_channel(tech_pvt);
gsmopen_sleep(10000);
session = switch_core_session_locate(tech_pvt->session_uuid_str);
if (session) {
channel = switch_core_session_get_channel(session);
switch_core_session_queue_indication(session, SWITCH_MESSAGE_INDICATE_RINGING);
if (channel) {
switch_channel_mark_ring_ready(channel);
DEBUGA_GSMOPEN("switch_channel_mark_ring_ready(channel);\n", GSMOPEN_P_LOG);
} else {
ERRORA("no channel\n", GSMOPEN_P_LOG);
}
switch_core_session_rwunlock(session);
} else {
ERRORA("no session\n", GSMOPEN_P_LOG);
}
return res;
}
/*! \brief Hangup gsmopen call
* Part of PBX interface, called from ast_hangup */
int gsmopen_hangup(private_t *tech_pvt)
{
/* if there is not gsmopen pvt why we are here ? */
if (!tech_pvt) {
ERRORA("Asked to hangup channel not connected\n", GSMOPEN_P_LOG);
return 0;
}
DEBUGA_GSMOPEN("ENTERING FUNC\n", GSMOPEN_P_LOG);
if (tech_pvt->controldevprotocol != PROTOCOL_NO_SERIAL) {
if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) {
/* actually hangup through the serial port */
if (tech_pvt->controldevprotocol != PROTOCOL_NO_SERIAL) {
int res;
res = gsmopen_serial_hangup(tech_pvt);
if (res) {
ERRORA("gsmopen_serial_hangup error: %d\n", GSMOPEN_P_LOG, res);
if (option_debug) {
DEBUGA_PBX("EXITING FUNC\n", GSMOPEN_P_LOG);
}
return -1;
}
}
while (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) {
gsmopen_sleep(10000); //10msec
}
if (tech_pvt->interface_state != GSMOPEN_STATE_DOWN) {
ERRORA("call hangup failed\n", GSMOPEN_P_LOG);
return -1;
} else {
DEBUGA_GSMOPEN("call hungup\n", GSMOPEN_P_LOG);
}
}
} else {
tech_pvt->interface_state = GSMOPEN_STATE_DOWN;
tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE;
}
switch_set_flag(tech_pvt, TFLAG_HANGUP);
if (option_debug) {
DEBUGA_PBX("EXITING FUNC\n", GSMOPEN_P_LOG);
}
return 0;
}
int gsmopen_call(private_t *tech_pvt, char *rdest, int timeout)
{
//gsmopen_sleep(5000);
DEBUGA_GSMOPEN("Calling GSM, rdest is: %s\n", GSMOPEN_P_LOG, rdest);
//gsmopen_signaling_write(tech_pvt, "SET AGC OFF");
//gsmopen_sleep(10000);
//gsmopen_signaling_write(tech_pvt, "SET AEC OFF");
//gsmopen_sleep(10000);
gsmopen_serial_call(tech_pvt, rdest);
//ERRORA("failed to communicate with GSM client, now exit\n", GSMOPEN_P_LOG);
//return -1;
//}
return 0;
}
int gsmopen_senddigit(private_t *tech_pvt, char digit)
{
DEBUGA_GSMOPEN("DIGIT received: %c\n", GSMOPEN_P_LOG, digit);
if (tech_pvt->controldevprotocol == PROTOCOL_AT && tech_pvt->at_send_dtmf[0]) {
int res = 0;
char at_command[256];
memset(at_command, '\0', 256);
sprintf(at_command, "%s=1,%c", tech_pvt->at_send_dtmf, digit);
res = gsmopen_serial_write_AT_ack(tech_pvt, at_command);
if (res) {
DEBUGA_GSMOPEN("XXX answer (OK) takes long to come, goes into timeout. command used: '%s=1,%c'\n", GSMOPEN_P_LOG, tech_pvt->at_send_dtmf,
digit);
}
}
return 0;
}
int gsmopen_sendsms(private_t *tech_pvt, char *dest, char *text)
{
//char *idest = data;
//char rdest[256];
//private_t *p = NULL;
//char *device;
//char *dest;
//char *text;
//char *stringp = NULL;
//int found = 0;
int failed = 0;
int err = 0;
char mesg_test[1024];
//strncpy(rdest, idest, sizeof(rdest) - 1);
DEBUGA_GSMOPEN("GSMopenSendsms: dest=%s text=%s\n", GSMOPEN_P_LOG, dest, text);
DEBUGA_GSMOPEN("START\n", GSMOPEN_P_LOG);
/* we can use gsmopen_request to get the channel, but gsmopen_request would look for onowned channels, and probably we can send SMSs while a call is ongoing
*
*/
if (tech_pvt->controldevprotocol != PROTOCOL_AT) {
ERRORA(", GSMOPEN_P_LOGGSMopenSendsms supports only AT command cellphones at the moment :-( !\n", GSMOPEN_P_LOG);
return RESULT_FAILURE;
}
if (tech_pvt->controldevprotocol == PROTOCOL_AT) {
char smscommand[16000];
memset(smscommand, '\0', sizeof(smscommand));
char pdu2[16000];
memset(pdu2, '\0', sizeof(pdu2));
int pdulenght = 0;
PUSHA_UNLOCKA(&tech_pvt->controldev_lock);
LOKKA(tech_pvt->controldev_lock);
#ifndef WANT_GSMLIB
err = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF=1");
if (err) {
ERRORA("AT+CMGF=1 (set message sending to TEXT (as opposed to PDU) do not got OK from the phone\n", GSMOPEN_P_LOG);
}
#else // WANT_GSMLIB
err = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF=0");
if (err) {
ERRORA("AT+CMGF=0 (set message sending to TEXT (as opposed to PDU) do not got OK from the phone\n", GSMOPEN_P_LOG);
}
#endif // WANT_GSMLIB
if (tech_pvt->no_ucs2 || tech_pvt->sms_pdu_not_supported == 0) {
#ifdef WANT_GSMLIB
try {
SMSMessageRef smsMessage;
memset(mesg_test, '\0', sizeof(mesg_test));
sprintf(mesg_test, ":) ciao belè новости לק ראת ﺎﻠﺠﻤﻋﺓ 人大aèéàòçù"); //let's test the beauty of utf8
//sprintf(mesg_test,":) ciao belè èéàòìù");
//text=mesg_test;
utf8_to_iso_8859_1(tech_pvt, text, strlen(text), smscommand, sizeof(smscommand));
smsMessage = new SMSSubmitMessage(smscommand, dest);
string pdu = smsMessage->encode();
strncpy(pdu2, pdu.c_str(), sizeof(pdu2) - 1);
memset(smscommand, '\0', sizeof(smscommand));
pdulenght = pdu.length() / 2 - 1;
sprintf(smscommand, "AT+CMGS=%d", pdulenght);
#ifdef NOTDEF
***9. How to support unicode ? You need 6 steps : 1. set datacodingschema to DCS_SIXTEEN_BIT_ALPHABET 2. set your locale correctly, for example
, my locale, china.setlocale(LC_ALL, "chs");
3. translate MBCS(multiple byte character set) string to unicode string.wchar_t wstr[1000];
memset(wstr, 0, 2000);
mbstowcs(wstr, data.c_str(), data.length());
4. get unicode string length.int wcs_len = wcslen(wstr);
5. change unicode string to net order.for (int i = 0; i < wcs_len; i++)
wstr[i] = htons(wstr[i]);
6. put unicode string into pdu.char content2[1000];
SMSMessageRef sms;
//MessageType messagetype;
//Address servicecentreaddress;
//Timestamp servicecentretimestamp;
//Address sender_recipient_address;
sms = SMSMessage::decode(tech_pvt->line_array.result[i]); // dataCodingScheme = 8 , text=ciao 123 belè новости לק ראת ﺎﻠﺠﻤﻋﺓ 人大
DEBUGA_GSMOPEN("SMS=\n%s\n", GSMOPEN_P_LOG, sms->toString().c_str());
memset(content2, '\0', sizeof(content2));
if (sms->dataCodingScheme().getAlphabet() == DCS_DEFAULT_ALPHABET) {
iso_8859_1_to_utf8(tech_pvt, (char *) sms->userData().c_str(), content2, sizeof(content2));
} else if (sms->dataCodingScheme().getAlphabet() == DCS_SIXTEEN_BIT_ALPHABET) {
ucs2_to_utf8(tech_pvt, (char *) bufToHex((unsigned char *) sms->userData().data(), sms->userData().length()).c_str(), content2,
sizeof(content2));
} else {
ERRORA("dataCodingScheme not supported=%d\n", GSMOPEN_P_LOG, sms->dataCodingScheme().getAlphabet());
}
DEBUGA_GSMOPEN("dataCodingScheme=%d\n", GSMOPEN_P_LOG, sms->dataCodingScheme().getAlphabet());
DEBUGA_GSMOPEN("dataCodingScheme=%s\n", GSMOPEN_P_LOG, sms->dataCodingScheme().toString().c_str());
DEBUGA_GSMOPEN("address=%s\n", GSMOPEN_P_LOG, sms->address().toString().c_str());
DEBUGA_GSMOPEN("serviceCentreAddress=%s\n", GSMOPEN_P_LOG, sms->serviceCentreAddress().toString().c_str());
DEBUGA_GSMOPEN("serviceCentreTimestamp=%s\n", GSMOPEN_P_LOG, sms->serviceCentreTimestamp().toString().c_str());
DEBUGA_GSMOPEN("messageType=%d\n", GSMOPEN_P_LOG, sms->messageType());
DEBUGA_GSMOPEN("userData= |||%s|||\n", GSMOPEN_P_LOG, content2);
memset(sms_body, '\0', sizeof(sms_body));
strncpy(sms_body, content2, sizeof(sms_body));
DEBUGA_GSMOPEN("body=%s\n", GSMOPEN_P_LOG, sms_body);
strncpy(tech_pvt->sms_body, sms_body, sizeof(tech_pvt->sms_body));
strncpy(tech_pvt->sms_sender, sms->address().toString().c_str(), sizeof(tech_pvt->sms_sender));
strncpy(tech_pvt->sms_date, sms->serviceCentreTimestamp().toString().c_str(), sizeof(tech_pvt->sms_date));
strncpy(tech_pvt->sms_datacodingscheme, sms->dataCodingScheme().toString().c_str(), sizeof(tech_pvt->sms_datacodingscheme));
strncpy(tech_pvt->sms_servicecentreaddress, sms->serviceCentreAddress().toString().c_str(), sizeof(tech_pvt->sms_servicecentreaddress));
tech_pvt->sms_messagetype = sms->messageType();
//messagetype = sms->messageType();
//servicecentreaddress = sms->serviceCentreAddress();
//servicecentretimestamp = sms->serviceCentreTimestamp();
//sender_recipient_address = sms->address();
#endif // NOTDEF
}
catch(GsmException & ge) {
ERRORA("GsmException= |||%s|||\n", GSMOPEN_P_LOG, ge.what());
}
#else // WANT_GSMLIB
ERRORA("tech_pvt->no_ucs2 || tech_pvt->sms_pdu_not_supported == 0 && no WANT_GSMLIB\n", GSMOPEN_P_LOG);
return RESULT_FAILURE;
#endif // WANT_GSMLIB
} else {
char dest2[1048];
err = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CSCS=\"UCS2\"");
if (err) {
ERRORA("AT+CSCS=\"UCS2\" (set TE messages to ucs2) do not got OK from the phone\n", GSMOPEN_P_LOG);
}
memset(dest2, '\0', sizeof(dest2));
utf8_to_ucs2(tech_pvt, dest, strlen(dest), dest2, sizeof(dest2));
sprintf(smscommand, "AT+CMGS=\"%s\"", dest2);
}
err = gsmopen_serial_write_AT_noack(tech_pvt, smscommand);
if (err) {
ERRORA("Error sending SMS\n", GSMOPEN_P_LOG);
failed = 1;
goto uscita;
}
err = gsmopen_serial_AT_expect(tech_pvt, "> ", 0, 1); // wait 1.1s for the prompt, no crlf
#if 1
if (err) {
DEBUGA_GSMOPEN
("Error or timeout getting prompt '> ' for sending sms directly to the remote party. BTW, seems that we cannot do that with Motorola c350, so we'll write to cellphone memory, then send from memory\n",
GSMOPEN_P_LOG);
err = gsmopen_serial_write_AT_ack(tech_pvt, "ATE1"); //motorola (at least c350) do not echo the '>' prompt when in ATE0... go figure!!!!
if (err) {
ERRORA("Error activating echo from modem\n", GSMOPEN_P_LOG);
}
tech_pvt->at_cmgw[0] = '\0';
sprintf(smscommand, "AT+CMGW=\"%s\"", dest); //TODO: support phones that only accept pdu mode
err = gsmopen_serial_write_AT_noack(tech_pvt, smscommand);
if (err) {
ERRORA("Error writing SMS destination to the cellphone memory\n", GSMOPEN_P_LOG);
failed = 1;
goto uscita;
}
err = gsmopen_serial_AT_expect(tech_pvt, "> ", 0, 1); // wait 1.5s for the prompt, no crlf
if (err) {
ERRORA("Error or timeout getting prompt '> ' for writing sms text in cellphone memory\n", GSMOPEN_P_LOG);
failed = 1;
goto uscita;
}
}
#endif
#ifndef WANT_GSMLIB
memset(mesg_test, '\0', sizeof(mesg_test));
sprintf(mesg_test, ":) ciao belè новости לק ראת ﺎﻠﺠﻤﻋﺓ 人大aèéàòçù"); //let's test the beauty of utf8
//text=mesg_test;
memset(smscommand, '\0', sizeof(smscommand));
if (tech_pvt->no_ucs2) {
sprintf(smscommand, "%s", text);
} else {
utf8_to_ucs2(tech_pvt, text, strlen(text), smscommand, sizeof(smscommand));
}
#else // WANT_GSMLIB
memset(smscommand, '\0', sizeof(smscommand));
sprintf(smscommand, "%s", pdu2);
#endif // WANT_GSMLIB
smscommand[strlen(smscommand)] = 0x1A;
DEBUGA_GSMOPEN("smscommand len is: %d, text is:|||%s|||\n", GSMOPEN_P_LOG, (int) strlen(smscommand), smscommand);
err = gsmopen_serial_write_AT_ack_nocr_longtime(tech_pvt, smscommand);
//TODO would be better to unlock controldev here
if (err) {
ERRORA("Error writing SMS text to the cellphone memory\n", GSMOPEN_P_LOG);
//return RESULT_FAILURE;
failed = 1;
goto uscita;
}
if (tech_pvt->at_cmgw[0]) {
sprintf(smscommand, "AT+CMSS=%s", tech_pvt->at_cmgw);
err = gsmopen_serial_write_AT_expect_longtime(tech_pvt, smscommand, "OK");
if (err) {
ERRORA("Error sending SMS from the cellphone memory\n", GSMOPEN_P_LOG);
//return RESULT_FAILURE;
failed = 1;
goto uscita;
}
err = gsmopen_serial_write_AT_ack(tech_pvt, "ATE0"); //motorola (at least c350) do not echo the '>' prompt when in ATE0... go figure!!!!
if (err) {
ERRORA("Error de-activating echo from modem\n", GSMOPEN_P_LOG);
}
}
uscita:
gsmopen_sleep(1000);
if (tech_pvt->at_cmgw[0]) {
/* let's see what we've sent, just for check TODO: Motorola it's not reliable! Motorola c350 tells that all was sent, but is not true! It just sends how much it fits into one SMS FIXME: need an algorithm to calculate how many ucs2 chars fits into an SMS. It make difference based, probably, on the GSM alphabet translation, or so */
sprintf(smscommand, "AT+CMGR=%s", tech_pvt->at_cmgw);
err = gsmopen_serial_write_AT_ack(tech_pvt, smscommand);
if (err) {
ERRORA("Error reading SMS back from the cellphone memory\n", GSMOPEN_P_LOG);
}
/* let's delete from cellphone memory what we've sent */
sprintf(smscommand, "AT+CMGD=%s", tech_pvt->at_cmgw);
err = gsmopen_serial_write_AT_ack(tech_pvt, smscommand);
if (err) {
ERRORA("Error deleting SMS from the cellphone memory\n", GSMOPEN_P_LOG);
}
tech_pvt->at_cmgw[0] = '\0';
}
//gsmopen_sleep(500000); //.5 secs
UNLOCKA(tech_pvt->controldev_lock);
POPPA_UNLOCKA(&tech_pvt->controldev_lock);
}
#ifdef NOTDEF
err = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CMGF=0");
if (err) {
DEBUGA_GSMOPEN("AT+CMGF=0 (set message sending to PDU (as opposed to TEXT) do not got OK from the phone, continuing\n", GSMOPEN_P_LOG);
}
#endif // NOTDEF
DEBUGA_GSMOPEN("FINISH\n", GSMOPEN_P_LOG);
if (failed)
return -1;
else
return RESULT_SUCCESS;
}
/************************************************/
/* LUIGI RIZZO's magic */
/* boost support. BOOST_SCALE * 10 ^(BOOST_MAX/20) must
* be representable in 16 bits to avoid overflows.
*/
#define BOOST_SCALE (1<<9)
#define BOOST_MAX 40 /* slightly less than 7 bits */
/*
* store the boost factor
*/
void gsmopen_store_boost(char *s, double *boost)
{
private_t *tech_pvt = NULL;
if (sscanf(s, "%lf", boost) != 1) {
ERRORA("invalid boost <%s>\n", GSMOPEN_P_LOG, s);
return;
}
if (*boost < -BOOST_MAX) {
WARNINGA("boost %s too small, using %d\n", GSMOPEN_P_LOG, s, -BOOST_MAX);
*boost = -BOOST_MAX;
} else if (*boost > BOOST_MAX) {
WARNINGA("boost %s too large, using %d\n", GSMOPEN_P_LOG, s, BOOST_MAX);
*boost = BOOST_MAX;
}
#ifdef WIN32
*boost = exp(log((double) 10) * *boost / 20) * BOOST_SCALE;
#else
*boost = exp(log(10) * *boost / 20) * BOOST_SCALE;
#endif //WIN32
if (option_debug > 1)
DEBUGA_GSMOPEN("setting boost %s to %f\n", GSMOPEN_P_LOG, s, *boost);
}
int gsmopen_sound_boost(void *data, int samples_num, double boost)
{
/* LUIGI RIZZO's magic */
if (boost != 0 && (boost < 511 || boost > 513)) { /* scale and clip values */
int i, x;
int16_t *ptr = (int16_t *) data;
for (i = 0; i < samples_num; i++) {
x = (int) (ptr[i] * boost) / BOOST_SCALE;
if (x > 32767) {
x = 32767;
} else if (x < -32768) {
x = -32768;
}
ptr[i] = x;
}
} else {
//printf("BOOST=%f\n", boost);
}
return 0;
}
int gsmopen_serial_getstatus_AT(private_t *tech_pvt)
{
int res;
private_t *p = tech_pvt;
#if 0
if (p->owner) {
if (p->owner->_state != AST_STATE_UP && p->owner->_state != AST_STATE_DOWN) {
DEBUGA_AT("No getstatus, we're neither UP nor DOWN\n", GSMOPEN_P_LOG);
return 0;
}
}
#endif
PUSHA_UNLOCKA(p->controldev_lock);
LOKKA(p->controldev_lock);
res = gsmopen_serial_write_AT_ack(p, "AT");
if (res) {
ERRORA("AT was not acknowledged, continuing but maybe there is a problem\n", GSMOPEN_P_LOG);
}
gsmopen_sleep(1000);
if (strlen(p->at_query_battchg)) {
res = gsmopen_serial_write_AT_expect(p, p->at_query_battchg, p->at_query_battchg_expect);
if (res) {
WARNINGA("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, p->at_query_battchg, p->at_query_battchg_expect);
}
gsmopen_sleep(1000);
}
if (strlen(p->at_query_signal)) {
res = gsmopen_serial_write_AT_expect(p, p->at_query_signal, p->at_query_signal_expect);
if (res) {
WARNINGA("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, p->at_query_signal, p->at_query_signal_expect);
}
gsmopen_sleep(1000);
}
if (!p->network_creg_not_supported) {
res = gsmopen_serial_write_AT_ack(p, "AT+CREG?");
if (res) {
WARNINGA("%s does not get %s from the phone. Continuing.\n", GSMOPEN_P_LOG, "AT+CREG?", "OK");
}
gsmopen_sleep(1000);
}
//FIXME all the following commands in config!
if (p->sms_cnmi_not_supported) {
res = gsmopen_serial_write_AT_ack(p, "AT+MMGL=\"HEADER ONLY\"");
if (res) {
WARNINGA
("%s does not get %s from the phone. If your phone is not Motorola, please contact the gsmopen developers. Else, if your phone IS a Motorola, probably a long msg was incoming and ther first part was read and then deleted. The second part is now orphan. If you got this warning repeatedly, and you cannot correctly receive SMSs from this interface, please manually clean all messages (and the residual parts of them) from the cellphone/SIM. Continuing.\n",
GSMOPEN_P_LOG, "AT+MMGL=\"HEADER ONLY\"", "OK");
} else {
gsmopen_sleep(1000);
if (p->unread_sms_msg_id) {
char at_command[256];
res = gsmopen_serial_write_AT_ack(p, "AT+CSCS=\"UCS2\"");
if (res) {
ERRORA("AT+CSCS=\"UCS2\" (set TE messages to ucs2) do not got OK from the phone\n", GSMOPEN_P_LOG);
memset(p->sms_message, 0, sizeof(p->sms_message));
}
memset(at_command, 0, sizeof(at_command));
sprintf(at_command, "AT+CMGR=%d", p->unread_sms_msg_id);
memset(p->sms_message, 0, sizeof(p->sms_message));
p->reading_sms_msg = 1;
res = gsmopen_serial_write_AT_ack(p, at_command);
p->reading_sms_msg = 0;
if (res) {
ERRORA("AT+CMGR (read SMS) do not got OK from the phone, message sent was:|||%s|||\n", GSMOPEN_P_LOG, at_command);
}
res = gsmopen_serial_write_AT_ack(p, "AT+CSCS=\"GSM\"");
if (res) {
ERRORA("AT+CSCS=\"GSM\" (set TE messages to GSM) do not got OK from the phone\n", GSMOPEN_P_LOG);
}
memset(at_command, 0, sizeof(at_command));
sprintf(at_command, "AT+CMGD=%d", p->unread_sms_msg_id); /* delete the message */
p->unread_sms_msg_id = 0;
res = gsmopen_serial_write_AT_ack(p, at_command);
if (res) {
ERRORA("AT+CMGD (Delete SMS) do not got OK from the phone, message sent was:|||%s|||\n", GSMOPEN_P_LOG, at_command);
}
if (strlen(p->sms_message)) {
#if 0
manager_event(EVENT_FLAG_SYSTEM, "GSMOPENincomingsms", "Interface: %s\r\nSMS_Message: %s\r\n", p->name, p->sms_message);
if (strlen(p->sms_receiving_program)) {
int fd1[2];
pid_t pid1;
char *arg1[] = { p->sms_receiving_program, (char *) NULL };
int i;
DEBUGA_AT("incoming SMS message:---%s---\n", GSMOPEN_P_LOG, p->sms_message);
pipe(fd1);
pid1 = fork();
if (pid1 == 0) { //child
int err;
dup2(fd1[0], 0); // Connect stdin to pipe output
close(fd1[1]); // close input pipe side
setsid(); //session id
err = execvp(arg1[0], arg1); //exec our program, with stdin connected to pipe output
if (err) {
ERRORA
("'sms_receiving_program' is set in config file to '%s', and it gave us back this error: %d, (%s). SMS received was:---%s---\n",
GSMOPEN_P_LOG, p->sms_receiving_program, err, strerror(errno), p->sms_message);
}
close(fd1[0]); // close output pipe side
} //starting here continue the parent
close(fd1[0]); // close output pipe side
// write the msg on the pipe input
for (i = 0; i < strlen(p->sms_message); i++) {
write(fd1[1], &p->sms_message[i], 1);
}
close(fd1[1]); // close pipe input, let our program know we've finished
} else {
ERRORA
("got SMS incoming message, but 'sms_receiving_program' is not set in config file. SMS received was:---%s---\n",
GSMOPEN_P_LOG, p->sms_message);
}
#endif //0
DEBUGA_GSMOPEN("got SMS incoming message. SMS received was:---%s---\n", GSMOPEN_P_LOG, p->sms_message);
}
#if 0 //is this one needed? maybe it can interrupt an incoming call that is just to announce itself
if (p->phone_callflow == CALLFLOW_CALL_IDLE && p->interface_state == AST_STATE_DOWN && p->owner == NULL) {
/* we're not in a call, neither calling */
res = gsmopen_serial_write_AT_ack(p, "AT+CKPD=\"EEE\"");
if (res) {
ERRORA("AT+CKPD=\"EEE\" (cellphone screen back to user) do not got OK from the phone\n", GSMOPEN_P_LOG);
}
}
#endif
}
}
}
UNLOCKA(p->controldev_lock);
POPPA_UNLOCKA(p->controldev_lock);
return 0;
}
int gsmopen_serial_init_audio_port(private_t *tech_pvt, int controldevice_audio_speed)
{
tech_pvt->serialPort_serial_audio = new ctb::SerialPort();
//if( tech_pvt->serialPort_serial_audio->Open( "COM8", 115200, "8N1", ctb::SerialPort::NoFlowControl ) >= 0 ) {
if (tech_pvt->serialPort_serial_audio->Open(tech_pvt->controldevice_audio_name, 115200, "8N1", ctb::SerialPort::NoFlowControl) >= 0) {
DEBUGA_GSMOPEN("port %s, SUCCESS open\n", GSMOPEN_P_LOG, tech_pvt->controldevice_audio_name);
} else {
ERRORA("port %s, NOT open\n", GSMOPEN_P_LOG, tech_pvt->controldevice_audio_name);
return -1;
}
return 0;
}
int serial_audio_init(private_t *tech_pvt)
{
int res;
int err;
res = gsmopen_serial_init_audio_port(tech_pvt, tech_pvt->controldevice_audio_speed);
DEBUGA_GSMOPEN("serial_audio_init res=%d\n", GSMOPEN_P_LOG, res);
if (res == 0)
err = 0;
else
err = 1;
return err;
}
int serial_audio_shutdown(private_t *tech_pvt)
{
int res;
int err;
res = tech_pvt->serialPort_serial_audio->Close();
DEBUGA_GSMOPEN("serial_audio_shutdown res=%d (controldev_audio_fd is %d)\n", GSMOPEN_P_LOG, res, tech_pvt->controldev_audio_fd);
err = res;
return err;
}