81 #include <sys/types.h> 82 #include <sys/socket.h> 83 #include <netinet/in.h> 85 #include <sys/ioctl.h> 101 static unsigned char nibble2hex(
unsigned char b);
167 warning(0,
"AT2[%s]: trying to open device with not closed device!!! Please report!!!",
173 O_RDWR | O_NONBLOCK | O_NOCTTY);
240 tios.c_iflag |= IGNBRK;
241 tios.c_iflag &= ~INPCK;
242 tios.c_cflag |= HUPCL;
243 tios.c_cflag |= CREAD;
244 tios.c_cflag |= CLOCAL;
245 tios.c_cflag &= ~CSIZE;
247 tios.c_oflag &= ~ONLCR;
248 tios.c_iflag |= IGNPAR;
249 tios.c_iflag &= ~INPCK;
252 if(
privdata->modem->hardware_flow_control) {
263 tios.c_cc[VSUSP] = 0;
270 ret = tcsetattr(
privdata->fd, TCSANOW, &tios);
272 error(errno,
"AT2[%s]: at_data_link: fail to set termios attribute",
312 error(errno,
"AT2[%s]: at2_read_buffer: fd = -1. Can not read",
319 if (count > SSIZE_MAX)
327 int usecs = timeout * 1000000;
328 tv.tv_sec = usecs / 1000000;
329 tv.tv_usec = usecs % 1000000;
334 ret = select(
privdata->fd + 1, &read_fd, NULL, NULL, &tv);
336 if (!(errno == EINTR || errno == EAGAIN))
346 error(errno,
"AT2[%s]: at2_read_buffer: Error during read",
370 while (time(&cur_time) <=
end_time) {
425 if ((gtloc != -1) && ((eol == -1) || (eol > gtloc)))
444 if (
octstr_len(line) == 0 && (gt_flag == 0)) {
447 if ((gt_flag) && (gtloc != -1)) {
474 int write_count = 0, data_written = 0;
482 while (count > data_written) {
485 count - data_written);
486 if (s < 0 && errno == EAGAIN && write_count <
RETRY_WRITE) {
497 error(errno,
"AT2[%s]: Couldnot write to device.",
504 100 :
privdata->modem->sendline_sleep) / 1000);
512 char *ctrlz =
"\032" ;
519 if (s < 0 && errno == EAGAIN && write_count <
RETRY_WRITE) {
526 error(errno,
"AT2[%s]: Couldnot write to device.",
533 100 :
privdata->modem->sendline_sleep) / 1000);
540 int count, data_written = 0, write_count = 0;
545 count = strlen(line);
546 while(count > data_written) {
547 s = write(
privdata->fd, line + data_written, count - data_written);
548 if (s < 0 && errno == EAGAIN && write_count <
RETRY_WRITE) {
559 error(errno,
"AT2[%s]: Couldnot write to device.",
566 100 :
privdata->modem->sendline_sleep) / 1000);
592 error(0,
"AT2[%s]: Wrong or no answer to ATZ, ignoring",
599 error(0,
"AT2[%s]: Wrong or no answer to AT. Trying again",
602 error(0,
"AT2[%s]: Second attempt to send AT failed",
611 error(0,
"AT2[%s]: No answer to AT&F. Trying again",
622 error(0,
"AT2[%s]: Wrong or no answer to ATE0. Trying again",
625 error(0,
"AT2[%s]: Second attempt to send ATE0 failed",
638 info(0,
"AT2[%s]: cannot enable hardware handshake",
658 }
else if (ret == -1)
694 info(0,
"AT2[%s]: Cannot set SMS message center, continuing",
745 if (
privdata->sms_memory_poll_interval &&
privdata->modem->message_storage) {
769 Octstr *smsc_number = NULL;
837 debug(
"bb.smsc.at2", 0,
"AT2[%s]: +CMTI incoming SMS indication: %s",
849 error(0,
"AT2[%s]: got +CMT but waiting for next line timed out",
857 error(0,
"AT2[%s]: got +CMT but pdu_extract failed",
871 error(0,
"AT2[%s]: could not decode PDU to a message.",
893 error(0,
"AT2[%s]: Got +CMGS but failed to read message id",
938 int message_count = 0;
940 sprintf(cmd,
"AT+CMGR=%d", message_number);
944 debug(
"bb.smsc.at2", 0,
"AT2[%s]: failed to get message %d.",
950 if (!message_count) {
951 debug(
"bb.smsc.at2", 0,
"AT2[%s]: not deleted.",
956 sprintf(cmd,
"AT+CMGD=%d", message_number);
967 error(2,
"AT2[%s]: failed to delete message %d.",
983 Octstr *current_storage = NULL;
985 if (
privdata->modem->message_storage) {
991 Octstr *cmti_storage = NULL, *line = NULL;
998 if (next_quote == -1) {
1004 cmti_storage =
octstr_copy(line, pos, next_quote - pos);
1011 if (!
privdata->modem->message_storage && cmti_storage) {
1012 info(2,
"AT2[%s]: CMTI received, but no message-storage is set in confiuration." 1021 error(2,
"AT2[%s]: failed to find memory location in CMTI notification",
1030 error(2,
"AT2[%s]: error parsing memory location in CMTI notification",
1038 if (!current_storage || (
octstr_compare(current_storage, cmti_storage) != 0)) {
1045 error(1,
"AT2[%s]: CMTI notification received, but no message found in memory!",
1054 if (current_storage &&
privdata->modem->message_storage
1097 int message_count = 0;
1100 debug(
"bb.smsc.at2", 0,
"AT2[%s]: %d messages waiting in memory",
1130 Octstr *search_cpms = NULL;
1134 debug(
"bb.smsc.at2.memory_check", 0,
"failed to send mem select command to modem %d", ret);
1160 debug(
"bb.smsc.at2", 0,
"AT2[%s]: couldn't parse all memory locations : %d:'%s'.",
1167 privdata->sms_memory_usage = values[0];
1168 privdata->sms_memory_capacity = values[1];
1181 debug(
"bb.smsc.at2", 0,
"AT2[%s]: no correct header for CPMS response.",
1195 struct termios tios;
1269 cfsetospeed(&tios, speed);
1270 cfsetispeed(&tios, speed);
1271 ret = tcsetattr(
privdata->fd, TCSANOW, &tios);
1273 error(errno,
"AT2[%s]: at_data_link: fail to set termios attribute",
1286 int reconnecting = 0, error_count = 0;
1287 long idle_timeout, memory_poll_timeout = 0;
1303 error(0,
"AT2[%s]: Couldn't connect (retrying in %ld seconds).",
1312 info(0,
"AT2[%s]: trying to use speed <%ld> from modem definition",
1316 info(0,
"AT2[%s]: speed is %ld",
1319 info(0,
"AT2[%s]: speed in modem definition don't work, will autodetect",
1335 error(errno,
"AT2[%s]: at2_device_thread: open_at2_device failed.",
1342 error(errno,
"AT2[%s]: at2_device_thread: at2_login_device failed.",
1348 if (
privdata->max_error_count > 0 && error_count >
privdata->max_error_count
1364 error_count,
privdata->max_error_count);
1405 idle_timeout = time(NULL);
1408 if (
privdata->sms_memory_poll_interval &&
1409 memory_poll_timeout +
privdata->sms_memory_poll_interval < time(NULL)) {
1415 memory_poll_timeout = time(NULL);
1420 idle_timeout = time(NULL);
1444 gw_free(conn->
data);
1458 debug(
"bb.sms", 0,
"AT2[%s]: Shutting down SMSCConn, %s",
1460 finish_sending ?
"slow" :
"instant");
1472 if (finish_sending == 0) {
1522 Octstr *modem_type_string;
1534 error(0,
"AT2[-]: 'device' missing in at2 configuration.");
1540 if (
privdata->rawtcp_host == NULL) {
1541 error(0,
"AT2[-]: 'host' missing in at2 rawtcp configuration.");
1545 error(0,
"AT2[-]: 'port' missing in at2 rawtcp configuration.");
1553 if (
privdata->rawtcp_host == NULL) {
1554 error(0,
"AT2[-]: 'host' missing in at2 telnet configuration.");
1558 error(0,
"AT2[-]: 'port' missing in at2 telnet configuration.");
1581 if (
privdata->sms_memory_poll_interval) {
1598 if (modem_type_string != NULL) {
1605 info(0,
"AT2[%s]: configuration doesn't show modemtype. will autodetect",
1608 info(0,
"AT2[%s]: configuration shows modemtype <%s>",
1612 modem_type_string, 0);
1614 info(0,
"AT2[%s]: modemtype not found, revert to autodetect",
1617 info(0,
"AT2[%s]: read modem definition for <%s>",
1657 error(0,
"AT2[%s]: Failed to create at2 smsc connection",
1698 if (!
privdata->modem->broken && tmp == -1)
1706 if (pos == -1 || len == 0)
1755 return 'A'+ b - 0x0A;
1774 ton = (ton >> 4) & 0x07;
1796 b = ((c & 0xF0) >> 4);
1798 if((b == 0x0F) && (len < 2))
1813 hexc = toupper(hexc) - 48;
1814 return (hexc > 9) ? hexc - 7 : hexc;
1844 int len, pos, i, ntype;
1845 int udhi, dcs, udhlen, pid;
1850 Msg *message = NULL;
1873 if ((ntype & 0xD0) == 0xD0) {
1879 debug(
"bb.smsc.at2", 0,
"AT2[%s]: Alphanumeric sender <%s>",
1881 pos += (len + 1) / 2;
1884 if ((ntype & 0x90) == 0x90) {
1888 for (i = 0; i < len; i += 2, pos++) {
1893 debug(
"bb.smsc.at2", 0,
"AT2[%s]: Numeric sender %s <%s>",
1912 mtime.
year += (mtime.
year < 70 ? 2000 : 1900);
1932 timezone = ((timezone >> 7) ? -1 : 1) * (timezone & 127);
1944 mtime.
hour -= timezone / 4;
1945 mtime.
minute -= 15 * (timezone % 4);
1955 debug(
"bb.smsc.at2", 0,
"AT2[%s]: User data length read as (%d)",
1960 if (udhi && len > 0) {
1963 if (udhlen + 1 > len)
1968 }
else if (len <= 0)
1971 debug(
"bb.smsc.at2", 0,
"AT2[%s]: Udh decoding done len=%d udhi=%d udhlen=%d udh='%s'",
1985 message->sms.pid = pid;
1989 if (message->sms.coding ==
DC_8BIT || message->sms.coding ==
DC_UCS2) {
1994 if (udhi && message->sms.coding ==
DC_7BIT) {
1996 nbits = (udhlen + 1) * 8;
1998 offset = (((nbits / 7) + 1) * 7 - nbits) % 7;
2005 len = len + udhlen + 1 - (8 * (udhlen + 1) + 6) / 7;
2010 message->sms.sender = origin;
2018 message->sms.udhdata = udh;
2020 message->sms.msgdata =
text;
2021 message->sms.time = stime;
2043 int type, tp_mr, len, ntype, pos;
2055 debug(
"bb.smsc.at2", 0,
"AT2[%s]: got STATUS-REPORT for message <%d>:",
2063 if ((ntype & 0xD0) == 0xD0) {
2069 debug(
"bb.smsc.at2", 0,
"AT2[%s]: Alphanumeric receiver <%s>",
2071 pos += (len + 1) / 2;
2075 if ((ntype & 0x90) == 0x90) {
2079 for (i = 0; i < len; i += 2, pos++) {
2084 debug(
"bb.smsc.at2", 0,
"AT2[%s]: Numeric receiver %s <%s>",
2092 error(1,
"AT2[%s]: STATUS-REPORT pdu too short to have TP-Status field !",
2133 debug(
"bb.smsc.at2", 1,
"AT2[%s]: Received delivery notification but can't find that ID in the DLR storage",
2156 for (i = 0; i < len; i += 2) {
2165 static int at2_lmask[8] = { 0, 128, 192, 224, 240, 248, 252, 254 };
2169 unsigned char septet, octet, prevoctet;
2180 *ip = *ip >> offset;
2182 *ip = (*ip >> offset) | (*(ip + 1) << (8 - offset));
2188 for (i = 0; i < len; i++) {
2189 septet = ((octet &
at2_rmask[c]) << (r - 1)) + prevoctet;
2192 prevoctet = (octet &
at2_lmask[r]) >> c;
2195 if ((r == 7) && (i < len - 1)) {
2201 r = (r > 6) ? 1 : r + 1;
2202 c = (c < 2) ? 7 : c - 1;
2219 debug(
"bb.sms.at2", 0,
"AT2[%s]: throughput limit exceeded (load: %.02f, throughput: %.02f)",
2264 sprintf(command,
"AT+CMGS=%ld",
octstr_len(pdu) / 2);
2267 debug(
"bb.smsc.at2", 0,
"AT2[%s]: send command status: %d",
2293 if (strlen(command) > 18) {
2295 int len = strlen(command);
2300 if (pos + ret > len)
2302 memcpy(chop, command + pos, ret);
2315 debug(
"bb.smsc.at2", 0,
"AT2[%s]: send command status: %d",
2325 error(0,
"AT2[%s]: delivery notification requested, but I have no message ID!",
2340 error(0,
"AT2[%s]: Error received, notifying failure, " 2341 "sender: %s receiver: %s msgdata: %s udhdata: %s",
2360 int len, setvalidity = 0;
2368 ((
msg->sms.rpi > 0 ? 1 : 0) << 7)
2394 long val = (
msg->sms.validity - time(NULL)) / 60;
2397 if (val >= 50400 && val <= 635040)
2398 setvalidity = (val - 1) / 7 / 24 / 60 + 192 + 1;
2399 if (val > 43200 && val < 50400)
2401 if (val >= 2880 && val <= 43200)
2402 setvalidity = (val - 1) / 24 / 60 + 166 + 1;
2403 if (val > 1440 && val < 2880)
2405 if (val >= 750 && val <= 1440)
2406 setvalidity = (val - 720 - 1) / 30 + 143 + 1;
2407 if (val > 720 && val < 750)
2409 if (val >= 5 && val <= 720)
2410 setvalidity = (val - 1) / 5 - 1 + 1;
2417 if (setvalidity >= 0 && setvalidity <= 143)
2418 debug(
"bb.smsc.at2", 0,
"AT2[%s]: TP-Validity-Period: %d minutes",
2420 else if (setvalidity >= 144 && setvalidity <= 167)
2421 debug(
"bb.smsc.at2", 0,
"AT2[%s]: TP-Validity-Period: %3.1f hours",
2423 else if (setvalidity >= 168 && setvalidity <= 196)
2424 debug(
"bb.smsc.at2", 0,
"AT2[%s]: TP-Validity-Period: %d days",
2427 debug(
"bb.smsc.at2", 0,
"AT2[%s]: TP-Validity-Period: %d weeks",
2449 len += (temp_len = (((8 *
octstr_len(
msg->sms.udhdata)) + 6) / 7));
2475 offset = (((nbits / 7) + 1) * 7 - nbits) % 7;
2503 int LSBmask[8] = { 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F };
2504 int MSBmask[8] = { 0x00, 0x40, 0x60, 0x70, 0x78, 0x7C, 0x7E, 0x7F };
2505 int destRemain = (int)ceil((
octstr_len(source) * 7.0 + offset) / 8.0);
2506 int i = (offset?8-offset:7), iStore = offset;
2509 int target_chr = 0, source_chr;
2512 for (posS = 0; (source_chr =
octstr_get_char(source, posS++)) != -1;) {
2515 target_chr |= (source_chr & LSBmask[i]) << iStore;
2524 target_chr |= (source_chr & MSBmask[7 - i]) >> (8 - iStore) % 8;
2526 iStore = (--iStore < 0 ? 7 : iStore);
2529 i = (++i > 7 ? 1 : i);
2547 for (i = 0; i < len; i++) {
2558 return (num > 9) ? (num + 55) : (num + 48);
2565 int autospeeds[] = {
2572 38400, 19200, 9600 };
2574 debug(
"bb.smsc.at2", 0,
"AT2[%s]: detecting modem speed. ",
2577 for (i = 0; i < (
sizeof(autospeeds) /
sizeof(
int)) && !
privdata->
shutdown; i++) {
2689 debug(
"bb.smsc.at2", 0,
"AT2[%s]: found string <%s>, using modem definition <%s>",
2696 debug(
"bb.smsc.at2", 0,
"AT2[%s]: found string <%s> plus <%s>, using modem " 2712 debug(
"bb.smsc.at2", 0,
"AT2[%s]: Cannot detect modem, using generic",
2715 panic(0,
"AT2[%s]: Cannot detect modem and generic not found",
2774 debug(
"bb.smsc.at2", 0,
"AT2[%s]: Reading modem definitions from <%s>",
2779 panic(0,
"Cannot read modem definition file");
2783 debug(
"bb.smsc.at2", 0,
"AT2[%s]: Found <%ld> modems in config",
2786 if (grplist == NULL)
2787 panic(0,
"Where are the modem definitions ?!?!");
2793 info(0,
"Modems group without id, bad");
2810 if (grplist != NULL)
2814 modem = gw_malloc(
sizeof(
ModemDef));
2819 if (modem->
name == NULL)
2831 modem->
speed = 9600;
2878 if (modem != NULL) {
2895 return ( ( byte & 15 ) * 10 ) + ( byte >> 4 );
2929 while (out != NULL &&
octstr_len(temp) > 0) {
2936 if(digit1 >= 0 && digit1 < 16 && digit2 < 16) {
2963 return !ret ? 0 : -1;
2988 return "Modem returned ERROR but no error code - possibly unsupported or invalid command?";
2995 return "Unassigned (unallocated) number (+CMS) or No connection to phone (+CME)";
2997 return "Phone-adaptor link reserved";
3003 return "Operation not allowed at this time (connection may be required)";
3009 return "Operation / Parameter(s) not supported";
3011 return "PH-SIM PIN required";
3018 return "Operator determined barring";
3024 return "Call barred (+CMS) or SIM not inserted or Card inserted is not a SIM (+CME)";
3026 return "SIM PIN required";
3028 return "SIM PUK required";
3030 return "SIM failure";
3036 return "Incorrect password";
3042 return "Network failure (+CMS) or SIM PIN2 required (+CME)";
3044 return "SIM PUK2 required";
3046 return "Memory full";
3054 return "Short message transfer rejected (+CMS) or Invalid Index (+CME)";
3062 return "Congestion (+CMS) or Memory capacity exceeded (+CME)";
3064 return "Memory failure";
3066 return "Text string too long";
3068 return "Invalid characters in text string";
3070 return "Dial string too long";
3081 return "Destination out of service";
3087 return "Unidentified subscriber";
3093 return "Facility rejected";
3100 return "Unknown subscriber (+CMS) or No network service (+CME)";
3102 return "Network timeout";
3104 return "Network not allowed - emergency calls only";
3112 return "Network out of order";
3114 return "Network personal PIN required (Network lock)";
3122 return "Temporary failure (+CMS) or Network personalization PUK required (+CME)";
3128 return "Congestion (+CMS) or Network subset personalization PIN required (+CME)";
3130 return "Network subset personalization PUK required";
3132 return "Service provider personalization PIN required";
3134 return "Service provider personalization PUK required";
3136 return "Corporate personalization PIN required";
3142 return "Resources unavailable, unspecified (+CMS) or Corporate personalization PUK required (+CME)";
3149 return "Requested facility not subscribed";
3155 return "Requested facility not implemented";
3162 return "Invalid short message transfer reference value";
3168 return "Invalid message, unspecified";
3175 return "Invalid mandatory information";
3183 return "Message type non-existent or not implemented";
3191 return "Message not compatible with short message protocol state";
3201 return "Information element non-existent or not implemented";
3205 return "Illegal MS (#3)";
3207 return "Illegal ME (#6)";
3209 return "GPRS services not allowed (#7)";
3216 return "Protocol error, unspecified (+CMS) or PLMN not allowed (#11) (+CME)";
3218 return "Location area not allowed (#12)";
3220 return "Roaming not allowed in this area (#13)";
3227 return "Interworking, unspecified";
3229 return "Telematic interworking not supported";
3231 return "Short message Type 0 not supported";
3233 return "Cannot replace short message";
3235 return "Service option not supported (#32)";
3237 return "Requested service option not subscribed (#33)";
3239 return "Service option temporarily out of order (#34)";
3241 return "Unspecified TP-PID error";
3243 return "Data coding scheme (alphabet) not supported";
3245 return "Message class not supported";
3247 return "Unspecified GPRS error";
3249 return "PDP authentication failure";
3251 return "Invalid mobile class";
3253 return "Unspecified TP-DCS error";
3255 return "Command cannot be actioned";
3257 return "Unsupported command";
3259 return "Unspecified TP-Command error";
3261 return "TPDU not supported";
3265 return "No SC subscription";
3267 return "SC system failure";
3269 return "Invalid SME address";
3271 return "Destination SME barred";
3273 return "SM Rejected-Duplicate SM";
3275 return "TP-VPF not supported";
3277 return "TP-VP not supported";
3279 return "DO SIM SMS storage full";
3281 return "No SMS storage capability in SIM";
3283 return "Error in MS";
3285 return "SIM Memory Capacity Exceeded";
3287 return "SIM Application Toolkit Busy";
3289 return "SIM data download error";
3291 return "Unspecified error cause";
3298 return "Mobile equipment (ME) failure";
3303 return "SMS service of mobile equipment (ME) is reserved";
3305 return "The operation to be done by the AT command is not allowed";
3307 return "The operation to be done by the AT command is not supported";
3309 return "One or more parameter values assigned to the AT command are invalid";
3311 return "One or more parameter values assigned to the AT command are invalid";
3313 return "There is no SIM card";
3319 return "The SIM card requires a PIN to operate";
3325 return "The SIM card requires a PH-SIM PIN to operate";
3327 return "SIM card failure";
3329 return "The SIM card is busy";
3331 return "The SIM card is wrong";
3337 return "The SIM card requires a PUK to operate";
3339 return "The SIM card requires a PIN2 to operate";
3341 return "The SIM card requires a PUK2 to operate";
3343 return "Memory/message storage failure";
3345 return "The memory/message storage index assigned to the AT command is invalid";
3347 return "The memory/message storage is out of space";
3349 return "The SMS center (SMSC) address is unknown";
3351 return "No network service is available";
3353 return "Network timeout occurred";
3355 return "There is no need to send message ack by the AT command +CNMA";
3357 return "An unknown error occurred";
3362 return "User abort or MM establishment failure (SMS)";
3367 return "Lower layer falure (SMS)";
3372 return "CP error (SMS)";
3374 return "Please wait, service not available, init or command in progress";
3379 return "SIM ToolKit facility not supported";
3384 return "SIM ToolKit indication not received";
3389 return "Reset the product to activate or change a new echo cancellation algorithm";
3394 return "Automatic abort about get plmn list for an incoming call";
3399 return "PIN deactivation forbidden with this SIM card";
3404 return "Please wait, RR or MM is busy. Retry your selection later";
3409 return "Location update failure. Emergency calls only";
3414 return "PLMN selection failure. Emergency calls only";
3419 return "SMS not sent: the <da> is not in FDN phonebook, and FDN lock is enabled";
3424 return "The embedded application is activated so the objects flash are not erased";
3429 return "Missing or unknown APN";
3431 return "Error number unknown. Ask google and add it";
void error(int err, const char *fmt,...)
static void at2_device_thread(void *arg)
static int at2_test_speed(PrivAT2data *privdata, long speed)
void info(int err, const char *fmt,...)
Msg * msg_duplicate(Msg *msg)
void bb_smscconn_connected(SMSCConn *conn)
static int at2_wait_modem_command(PrivAT2data *privdata, time_t timeout, int gt_flag, int *output)
static Octstr * at2_convertpdu(Octstr *pdutext)
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
void octstr_append_data(Octstr *ostr, const char *data, long len)
static const char * at2_error_string(int errcode)
static long at2_queued_cb(SMSCConn *conn)
gw_assert(wtls_machine->packet_to_send !=NULL)
static int at2_login_device(PrivAT2data *privdata)
void gwlist_append(List *list, void *item)
int tcpip_connect_to_server(char *hostname, int port, const char *source_addr)
void bb_smscconn_killed(void)
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
#define AT2_DEFAULT_SMS_POLL_INTERVAL
long gwlist_len(List *list)
static int reconnect(SMSCConn *conn)
Octstr * cfg_get_configfile(CfgGroup *grp)
static Msg * at2_pdu_decode(Octstr *data, PrivAT2data *privdata)
void octstr_append_char(Octstr *ostr, int ch)
int sms_msgdata_len(Msg *msg)
void charset_utf8_to_gsm(Octstr *ostr)
int load_add_interval(Load *load, int interval)
static Msg * at2_pdu_decode_deliver_sm(Octstr *data, PrivAT2data *privdata)
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
#define cfg_get(grp, varname)
static int at2_check_sms_memory(PrivAT2data *privdata)
Load * load_create_real(int heuristic)
#define gw_prioqueue_produce(queue, item)
void octstr_append_cstr(Octstr *ostr, const char *cstr)
void octstr_strip_blanks(Octstr *text)
double load_get(Load *load, int pos)
Msg * dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int typ, int use_dst)
void dlr_add(const Octstr *smsc, const Octstr *ts, Msg *msg, int use_dst)
#define octstr_get_cstr(ostr)
#define octstr_copy(ostr, from, len)
void octstr_binary_to_hex(Octstr *ostr, int uppercase)
void(* start_conn)(SMSCConn *conn)
long octstr_search_char(const Octstr *ostr, int ch, long pos)
static int at2_init_device(PrivAT2data *privdata)
void log_thread_to(int idx)
int hardware_flow_control
static int at2_set_message_storage(PrivAT2data *privdata, Octstr *memory_name)
int smsc_at2_create(SMSCConn *conn, CfgGroup *cfg)
Cfg * cfg_create(Octstr *filename)
static Msg * at2_pdu_decode_report_sm(Octstr *data, PrivAT2data *privdata)
smscconn_killed_t why_killed
static void at2_read_pending_incoming_messages(PrivAT2data *privdata)
static int at2_read_delete_message(PrivAT2data *privdata, int message_number)
Octstr * octstr_imm(const char *cstr)
int sms_priority_compare(const void *a, const void *b)
void cfg_destroy(Cfg *cfg)
void * gwlist_extract_first(List *list)
static int at2_hexchar(int hexc)
static Octstr * gsm2number(Octstr *pdu)
static int at2_shutdown_cb(SMSCConn *conn, int finish_sending)
static ModemDef * at2_read_modems(PrivAT2data *privdata, Octstr *file, Octstr *id, int idnumber)
void octstr_delete(Octstr *ostr1, long pos, long len)
static int at2_read_sms_memory(PrivAT2data *privdata)
long bb_smscconn_receive(SMSCConn *conn, Msg *sms)
static void at2_flush_buffer(PrivAT2data *privdata)
static int at2_add_msg_cb(SMSCConn *conn, Msg *sms)
static int at2_send_modem_command(PrivAT2data *privdata, char *cmd, time_t timeout, int gt_flag)
static int at2_detect_speed(PrivAT2data *privdata)
#define octstr_duplicate(ostr)
List * cfg_get_multi_group(Cfg *cfg, Octstr *name)
static Octstr * at2_pdu_encode(Msg *msg, PrivAT2data *privdata)
int octstr_item_match(void *item, void *pattern)
static void at2_scan_for_telnet_escapes(PrivAT2data *privdata)
static unsigned char nibble2hex(unsigned char b)
static int swap_nibbles(unsigned char byte)
void warning(int err, const char *fmt,...)
void * gw_prioqueue_remove(gw_prioqueue_t *queue)
static void at2_close_device(PrivAT2data *privdata)
Octstr * octstr_format(const char *fmt,...)
long gw_prioqueue_len(gw_prioqueue_t *queue)
static int at2_open_device1(PrivAT2data *privdata)
void octstr_destroy(Octstr *ostr)
static void at2_send_one_message(PrivAT2data *privdata, Msg *msg)
#define gwthread_create(func, arg)
#define octstr_create(cstr)
static void at2_set_speed(PrivAT2data *privdata, int bps)
void octstr_destroy_item(void *os)
int fields_to_dcs(Msg *msg, int mode)
gw_prioqueue_t * gw_prioqueue_create(int(*cmp)(const void *, const void *))
void gwthread_sleep(double seconds)
#define SMS_PARAM_UNDEFINED
static void at2_send_messages(PrivAT2data *privdata)
#define AT_STATUS_REPORT_SM
static Octstr * at2_encode7bituncompressed(Octstr *source, int offset)
static void at2_read_buffer(PrivAT2data *privdata, double timeout)
static void at2_decode7bituncompressed(Octstr *input, int len, Octstr *decoded, int offset)
#define load_increase(load)
long octstr_len(const Octstr *ostr)
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
void gw_prioqueue_destroy(gw_prioqueue_t *queue, void(*item_destroy)(void *))
void bb_smscconn_sent(SMSCConn *conn, Msg *sms, Octstr *reply)
int(* shutdown)(SMSCConn *conn, int finish_sending)
void debug(const char *place, int err, const char *fmt,...)
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
static void at2_destroy_modem(ModemDef *modem)
void gwthread_wakeup(long thread)
#define MSG_PARAM_UNDEFINED
int octstr_hex_to_binary(Octstr *ostr)
int octstr_str_compare(const Octstr *ostr, const char *str)
void load_destroy(Load *load)
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
static int at2_numtext(int num)
static int at2_open_device(PrivAT2data *privdata)
static int at2_write(PrivAT2data *privdata, char *line)
long(* queued)(SMSCConn *conn)
static int at2_write_ctrlz(PrivAT2data *privdata)
void octstr_truncate(Octstr *ostr, int new_len)
static int at2_pdu_extract(PrivAT2data *privdata, Octstr **pdu, Octstr *line, Octstr *smsc_number)
int(* send_msg)(SMSCConn *conn, Msg *msg)
void kannel_cfmakeraw(struct termios *tio)
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
static Octstr * at2_wait_line(PrivAT2data *privdata, time_t timeout, int gt_flag)
int dcs_to_fields(Msg **msg, int dcs)
static void at2_start_cb(SMSCConn *conn)
long date_convert_universal(struct universaltime *t)
static Octstr * at2_format_address_field(Octstr *msisdn)
int octstr_get_char(const Octstr *ostr, long pos)
static int at2_write_line(PrivAT2data *privdata, char *line)
void octstr_set_char(Octstr *ostr, long pos, int ch)
#define DLR_IS_ENABLED_DEVICE(dlr)
#define octstr_create_from_data(data, len)
static Octstr * at2_encode8bituncompressed(Octstr *input)
List * octstr_split(const Octstr *os, const Octstr *sep)
static XMLRPCDocument * msg
static Octstr * at2_extract_line(PrivAT2data *privdata, int gt_flag)
static Octstr * at2_read_line(PrivAT2data *privdata, int gt_flag, double timeout)
static int at2_detect_modem_type(PrivAT2data *privdata)
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
void charset_gsm_to_utf8(Octstr *ostr)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)