📄 smsc_cimd.c
字号:
/* The Nokia SMSC MAY be configured to send delivery information, which we then will HAVE to acknowledge. Naturally the CIMD 1.3 protocol does not include any kind of negotiation mechanism. */ ret = expect_acknowledge(smsc, &cmd, &err); if (ret >= 1) { if (cmd == 4) { send_acknowledge(smsc); goto okay; } else if (cmd == 3) { goto okay; } } else if (ret == 0) { if (cmd == 4) { send_acknowledge(smsc); goto okay; /* FIXME XXX THIS IS BOGUS, FIX SMSGATEWAY.C */ goto error; } else if (cmd == 3) { goto okay; /* FIXME XXX THIS IS BOGUS, FIX SMSGATEWAY.C */ goto error; } else { error(0, "Unexpected behaviour from the CIMD server"); debug("bb.sms.cimd", 0, "cimd_submit_smsmessage: acknowledge was <%i>", ret); debug("bb.sms.cimd", 0, "cimd_submit_smsmessage: buffer==<%s>", smsc->buffer); goto error; } }okay: gw_free(tmpbuff); gw_free(tmptext); return 0;error: debug("bb.sms.cimd", 0, "cimd_submit_smsmessage: returning error"); gw_free(tmpbuff); gw_free(tmptext); return -1;}int cimd_receive_msg(SMSCenter *smsc, Msg **msg){ char *tmpbuff = NULL, *sender = NULL; char *receiver = NULL, *text = NULL, *scts = NULL; char *tmpchar = NULL; debug("bb.sms.cimd", 0, "cimd_receive_smsmessage: starting"); /* the PENDING function has previously requested for the message and checked that it safely found its way into the memory buffer (smsc->buffer) */ /* we want to temporarily store some data */ tmpbuff = gw_malloc(10 * 1024); sender = gw_malloc(10 * 1024); receiver = gw_malloc(10 * 1024); text = gw_malloc(10 * 1024); scts = gw_malloc(10 * 1024); memset(tmpbuff, 0, 10 * 1024); memset(sender, 0, 10 * 1024); memset(receiver, 0, 10 * 1024); memset(text, 0, 10 * 1024); memset(scts, 0, 10 * 1024); /* cut the raw message out from the message buffer */ tmpchar = memchr(smsc->buffer, 0x0A, smsc->buflen); if (tmpchar == NULL) { tmpchar = memchr(smsc->buffer, 0x03, smsc->buflen); if (tmpchar == NULL) goto error; } strncpy(tmpbuff, smsc->buffer, tmpchar - smsc->buffer); smscenter_remove_from_buffer(smsc, tmpchar - smsc->buffer + 1); /* Parse the raw message */ sscanf(tmpbuff, "\x02\x06\tC:05\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t11\x03\x0A", receiver, sender, text, scts); sscanf(tmpbuff, "\x02\x06\tC:05\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t11\x03", receiver, sender, text, scts); /* Translate from the CIMD character set to iso8859-1 */ parse_cimd_to_iso88591(text, tmpbuff, 10*1024); strncpy(text, tmpbuff, 480); /* create a smsmessage structure out of the components */ *msg = msg_create(sms); if (*msg == NULL) return -1; (*msg)->sms.sender = octstr_create(sender); (*msg)->sms.receiver = octstr_create(receiver); (*msg)->sms.msgdata = octstr_create(text); /* Send acknowledge */ send_acknowledge(smsc); /* We got a message so we can instantly check for a new one. */ smsc->cimd_last_spoke -= 5; /* Free and Finish */ gw_free(tmpbuff); gw_free(sender); gw_free(receiver); gw_free(text); gw_free(scts); debug("bb.sms.cimd", 0, "cimd_receive_smsmessage: return ok"); return 1;error: debug("bb.sms.cimd", 0, "cimd_receive_smsmessage: failed"); gw_free(tmpbuff); gw_free(sender); gw_free(receiver); gw_free(text); gw_free(scts); debug("bb.sms.cimd", 0, "cimd_receive_smsmessage: return failed"); return -1;}/******************************************************************************* In(f)ternal Functions*/static int connect_tcpip(SMSCenter *smsc){ char *tmpbuff = NULL; int ret = 0; int cmd = 0, err = 0; debug("bb.sms.cimd", 0, "reconnecting to <%s>", smsc->name); /* allocate some spare space */ tmpbuff = gw_malloc(10 * 1024); memset(tmpbuff, 0, 10*1024); /* Close connection */ close(smsc->socket); smsc->socket = -1; /* Be sure to open a socket. */ for (;;) { smsc->socket = tcpip_connect_to_server( smsc->cimd_hostname, smsc->cimd_port, NULL); /* XXX add interface_name if required */ if (smsc->socket != -1) break; usleep(1000); } /* Empty the buffer, there might be an evil ghost inside... */ memset(smsc->buffer, 0, smsc->bufsize); smsc->buflen = 0; /* Expect the protocol string "CIMD rel 1.37\n" */ for (;;) { ret = smscenter_read_into_buffer(smsc); if (ret < 0) goto logout; if (strstr(smsc->buffer, "CIMD rel 1.37\n") != NULL) break; usleep(1000); } smscenter_remove_from_buffer(smsc, smsc->buflen); /* send login string */ sprintf(tmpbuff, "%c%s%c%s%c%s%c%s%c%c", 0x02, "01", 0x09, smsc->cimd_username, 0x09, smsc->cimd_password, 0x09, "11", 0x03, 0x0A); ret = write_to_socket(smsc->socket, tmpbuff); if (ret < 0) goto logout; /* get an acknowledge message */ smsc->cimd_last_spoke = 0; if (expect_acknowledge(smsc, &cmd, &err) < 1) goto logout; debug("bb.sms.cimd", 0, "cimd_connect_tcpip: logged in"); gw_free(tmpbuff); return 1;logout: close(smsc->socket); gw_free(tmpbuff); return 0;}/******************************************************************************* Yeah, we got the message!*/static int send_acknowledge(SMSCenter *smsc){ char tmpbuff[100]; int tmpint; if (tmpbuff == NULL) { error(0, "cimd_send_acknowledge: memory allocation failure"); goto error; } memset(tmpbuff, 0, sizeof(tmpbuff)); sprintf(tmpbuff, "\2\6\t11\3\n"); tmpint = write_to_socket(smsc->socket, tmpbuff); if (tmpint == -1) { error(0, "cimd_send_acknowledge: connection failure"); goto error; } return 0;error: debug("bb.sms.cimd", 0, "cimd_send_acknowledge: failed"); return -1;}/******************************************************************************* Wait for the Nokia piece of *!%&%*^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H SMSC* to catch up with our swift operation, block until... (~1sec?)*/static int expect_acknowledge(SMSCenter *smsc, int *cmd, int *err){ char *end_of_dataset = NULL; char *ack = NULL, *nck = NULL; char *cmdspecifier = NULL, *errorspecifier = NULL; int ret = 0;#if 0 time_t thetime; time(&thetime);#endif if (smsc == NULL) goto error; /* Loop until we get an acknowledgement message. */ for (;;) { /* If the server is configured in to end a dataset with a \n */ end_of_dataset = memchr(smsc->buffer, '\n', smsc->buflen); if (end_of_dataset != NULL) break; /* If the server is configured in to end a dataset with a \3 */ end_of_dataset = memchr(smsc->buffer, 0x03, smsc->buflen); if (end_of_dataset != NULL) break; ret = smscenter_read_into_buffer(smsc); if (ret <= 0) { if (errno == EAGAIN) continue; if (errno == EINTR) continue; return -1; } usleep(500);#if 0 /* Abort if no results in 30 seconds */ if (time(NULL) > (thetime + 30)) { error(0, "timeout occurred, maybe the connection was broken?"); if (errno == EPIPE) { error(0, "broken pipe"); } /* if errno */ goto error; } /* if time */#endif } /* Check if our request was answered or denied */ ack = memchr(smsc->buffer, 0x06, end_of_dataset - smsc->buffer); nck = memchr(smsc->buffer, 0x15, end_of_dataset - smsc->buffer); /* Get the command code from the acknowledge message */ cmdspecifier = strstr(smsc->buffer, "\tC:"); if (cmdspecifier != NULL) *cmd = strtol(cmdspecifier + 3, NULL, 10); else *cmd = 0; errorspecifier = strstr(smsc->buffer, "\tE:"); if (errorspecifier != NULL) *err = strtol(errorspecifier + 3, NULL, 10); else *err = 0; debug("bb.sms.cimd", 0, "cimd_pending_smsmessage: smsc->buffer == <%s>", smsc->buffer); /* Remove the acknowledge message from the incoming buffer. */ smscenter_remove_from_buffer(smsc, end_of_dataset - smsc->buffer + 1); /* if we got an acknowledge */ if (ack != NULL) { info(0, "cimd_pending_smsmessage: got ACK"); return 1; } /* if we got an NOT acknowledge */ if (nck != NULL) { info(0, "cimd_pending_smsmessage: got NCK"); return 0; } /* if we got an ERROR */error: error(0, "cimd_expect_acknowledge failed"); return -1;}/******************************************************************************* Convert a string from ISO-8859-1 to the CIMD character set*/static int parse_iso88591_to_cimd(char* from, char* to, int length, int alt_charset){ char *temp = to; if (from == NULL || to == NULL || length == 0) return -1; *to = '\0'; while ((*from != '\0') && ((int) strlen(temp) < (length - 2))) { switch (*from) { case '@': strcat(to, "_Oa"); to += 3; break; case '
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -