Cracked code which helps you in understanding how Mobile SMS SERVER GATEWAY/CENTER works???? - An excellent code.
/*****************************************************************************
* smsc_smpp.c - Short Message Peer to Peer Provisioning Protocol 3.3
* Mikael Gueck for WapIT Ltd.
*/
#include "errno.h"
#include "stdarg.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include "sys/time.h"
#include "sys/types.h"
#include "sys/socket.h"
#include "netinet/in.h"
#include "smsc.h"
#include "smsc_smpp.h"
#include "octstr.h"
#include "wapitlib.h"
SMSCenter *smpp_open(char *host, int port, char *system_id, char *password, char* system_type, char *address_range) {
SMSCenter *smsc = NULL;
struct smpp_pdu *pdu = NULL;
struct smpp_pdu_bind_receiver *bind_receiver = NULL;
struct smpp_pdu_bind_transmitter *bind_transmitter = NULL;
smsc = smscenter_construct();
if(smsc==NULL) goto error;
smsc->type = SMSC_TYPE_SMPP_IP;
sprintf(smsc->name, "SMPP:%s:%i:%s:%s", host, port, system_id, system_type);
smsc->latency = 100*1000;
smsc->hostname = strdup(host);
smsc->port = port;
smsc->smpp_system_id = (system_id != NULL) ? strdup(system_id) : NULL;
smsc->smpp_system_type = (system_type != NULL) ? strdup(system_type) : NULL;
smsc->smpp_password = (password != NULL) ? strdup(password) : NULL;
smsc->smpp_address_range = (address_range != NULL) ? strdup(address_range) : NULL;
/* Create FIFO stacks */
smsc->unsent_mt = fifo_new();
if(smsc->unsent_mt == NULL) goto error;
smsc->sent_mt = fifo_new();
if(smsc->sent_mt == NULL) goto error;
smsc->delivered_mt = fifo_new();
if(smsc->delivered_mt == NULL) goto error;
smsc->received_mo = fifo_new();
if(smsc->received_mo == NULL) goto error;
smsc->fifo_t_in = fifo_new();
if(smsc->fifo_t_in == NULL) goto error;
smsc->fifo_t_out = fifo_new();
if(smsc->fifo_t_out == NULL) goto error;
smsc->fifo_r_in = fifo_new();
if(smsc->fifo_r_in == NULL) goto error;
smsc->fifo_r_out = fifo_new();
if(smsc->fifo_r_out == NULL) goto error;
/* Create buffers */
smsc->data_t = data_new();
if(smsc->data_t == NULL) goto error;
smsc->data_r = data_new();
if(smsc->data_r == NULL) goto error;
/* Open the transmitter connection */
smsc->fd_t = tcpip_connect_to_server(smsc->hostname, smsc->port);
if(smsc->fd_t == -1) goto error;
debug(0, "smsc->fd_t == %i", smsc->fd_t);
debug(0, "smsc->hostname == %s", smsc->hostname);
debug(0, "smsc->port == %i", smsc->port);
smsc->smpp_t_state = SMPP_STATE_CONNECTED;
/* Open the receiver connection */
smsc->fd_r = tcpip_connect_to_server(smsc->hostname, smsc->port);
if(smsc->fd_r == -1) goto error;
debug(0, "smsc->fd_r == %i", smsc->fd_t);
debug(0, "smsc->hostname == %s", smsc->hostname);
debug(0, "smsc->port == %i", smsc->port);
smsc->smpp_r_state = SMPP_STATE_CONNECTED;
/* Push a BIND_RECEIVER PDU on the [smsc->unsent] stack. */
pdu = pdu_new();
if(pdu == NULL) goto error;
pdu->id = SMPP_BIND_RECEIVER;
smsc->seq_r = 1;
pdu->sequence_no = 1;
bind_receiver = malloc(sizeof(struct smpp_pdu_bind_receiver));
if(bind_receiver==NULL) goto error;
memset(bind_receiver, 0, sizeof(struct smpp_pdu_bind_receiver));
strncpy(bind_receiver->system_id, system_id, 16);
strncpy(bind_receiver->password, password, 9);
strncpy(bind_receiver->system_type, system_type, 13);
strncpy(bind_receiver->address_range, address_range, 41);
pdu->message_body = bind_receiver;
fifo_push(smsc->fifo_r_out, pdu);
/* Push a BIND_TRANSMITTER PDU on the [smsc->unsent] stack. */
pdu = pdu_new();
if(pdu == NULL) goto error;
pdu->id = SMPP_BIND_TRANSMITTER;
smsc->seq_t = 1;
pdu->sequence_no = 1;
bind_transmitter = malloc(sizeof(struct smpp_pdu_bind_transmitter));
if(bind_transmitter==NULL) goto error;
memset(bind_transmitter, 0, sizeof(struct smpp_pdu_bind_transmitter));
strncpy(bind_transmitter->system_id, system_id, 16);
strncpy(bind_transmitter->password, password, 9);
strncpy(bind_transmitter->system_type, system_type, 13);
strncpy(bind_transmitter->address_range, address_range, 41);
pdu->message_body = bind_transmitter;
fifo_push(smsc->fifo_t_out, pdu);
/* Done, return */
return smsc;
error:
error(0, "smpp_open: could not open");
pdu_free(pdu);
/* Destroy FIFO stacks. */
fifo_free(smsc->unsent_mt);
fifo_free(smsc->sent_mt);
fifo_free(smsc->delivered_mt);
fifo_free(smsc->received_mo);
fifo_free(smsc->fifo_t_in);
fifo_free(smsc->fifo_t_out);
fifo_free(smsc->fifo_r_in);
fifo_free(smsc->fifo_r_out);
/* Destroy buffers */
data_free(smsc->data_t);
data_free(smsc->data_r);
smscenter_destruct(smsc);
return NULL;
}
int smpp_reopen(SMSCenter *smsc) {
struct smpp_pdu *pdu = NULL;
struct smpp_pdu_bind_receiver *bind_receiver = NULL;
struct smpp_pdu_bind_transmitter *bind_transmitter = NULL;
if(smsc==NULL) goto error;
/* Destroy FIFO stacks. */
fifo_free(smsc->unsent_mt);
fifo_free(smsc->sent_mt);
fifo_free(smsc->delivered_mt);
fifo_free(smsc->received_mo);
fifo_free(smsc->fifo_t_in);
fifo_free(smsc->fifo_t_out);
fifo_free(smsc->fifo_r_in);
fifo_free(smsc->fifo_r_out);
/* Destroy buffers */
data_free(smsc->data_t);
data_free(smsc->data_r);
/* Close sockets */
close(smsc->fd_t);
close(smsc->fd_r);
/* Create FIFO stacks */
smsc->unsent_mt = fifo_new();
if(smsc->unsent_mt == NULL) goto error;
smsc->sent_mt = fifo_new();
if(smsc->sent_mt == NULL) goto error;
smsc->delivered_mt = fifo_new();
if(smsc->delivered_mt == NULL) goto error;
smsc->received_mo = fifo_new();
if(smsc->received_mo == NULL) goto error;
smsc->fifo_t_in = fifo_new();
if(smsc->fifo_t_in == NULL) goto error;
smsc->fifo_t_out = fifo_new();
if(smsc->fifo_t_out == NULL) goto error;
smsc->fifo_r_in = fifo_new();
if(smsc->fifo_r_in == NULL) goto error;
smsc->fifo_r_out = fifo_new();
if(smsc->fifo_r_out == NULL) goto error;
/* Create buffers */
smsc->data_t = data_new();
if(smsc->data_t == NULL) goto error;
smsc->data_r = data_new();
if(smsc->data_r == NULL) goto error;
/* Open the transmitter connection */
smsc->fd_t = tcpip_connect_to_server(smsc->hostname, smsc->port);
if(smsc->fd_t == -1) goto error;
smsc->smpp_t_state = SMPP_STATE_CONNECTED;
/* Open the receiver connection */
smsc->fd_r = tcpip_connect_to_server(smsc->hostname, smsc->port);
if(smsc->fd_r == -1) goto error;
smsc->smpp_r_state = SMPP_STATE_CONNECTED;
/* Push a BIND_RECEIVER PDU on the [smsc->unsent] stack. */
pdu = pdu_new();
if(pdu == NULL) goto error;
pdu->id = SMPP_BIND_RECEIVER;
smsc->seq_r = 1;
pdu->sequence_no = 1;
bind_receiver = malloc(sizeof(struct smpp_pdu_bind_receiver));
if(bind_receiver==NULL) goto error;
memset(bind_receiver, 0, sizeof(struct smpp_pdu_bind_receiver));
strncpy(bind_receiver->system_id, smsc->smpp_system_id, 16);
strncpy(bind_receiver->password, smsc->smpp_password, 9);
strncpy(bind_receiver->system_type, smsc->smpp_system_type, 13);
strncpy(bind_receiver->address_range, smsc->smpp_address_range, 41);
pdu->message_body = bind_receiver;
fifo_push(smsc->fifo_r_out, pdu);
/* Push a BIND_TRANSMITTER PDU on the [smsc->unsent] stack. */
pdu = pdu_new();
if(pdu == NULL) goto error;
pdu->id = SMPP_BIND_TRANSMITTER;
smsc->seq_t = 1;
pdu->sequence_no = 1;
bind_transmitter = malloc(sizeof(struct smpp_pdu_bind_transmitter));
if(bind_transmitter==NULL) goto error;
memset(bind_transmitter, 0, sizeof(struct smpp_pdu_bind_transmitter));
strncpy(bind_transmitter->system_id, smsc->smpp_system_id, 16);
strncpy(bind_transmitter->password, smsc->smpp_password, 9);
strncpy(bind_transmitter->system_type, smsc->smpp_system_type, 13);
strncpy(bind_transmitter->address_range, smsc->smpp_address_range, 41);
pdu->message_body = bind_transmitter;
fifo_push(smsc->fifo_t_out, pdu);
/* Done, return */
return 1;
error:
error(0, "smpp_reopen: could not open");
pdu_free(pdu);
/* Destroy FIFO stacks. */
fifo_free(smsc->unsent_mt);
fifo_free(smsc->sent_mt);
fifo_free(smsc->delivered_mt);
fifo_free(smsc->received_mo);
fifo_free(smsc->fifo_t_in);
fifo_free(smsc->fifo_t_out);
fifo_free(smsc->fifo_r_in);
fifo_free(smsc->fifo_r_out);
/* Destroy buffers */
data_free(smsc->data_t);
data_free(smsc->data_r);
smscenter_destruct(smsc);
return -1;
}
int smpp_close(SMSCenter *smsc) {
struct smpp_pdu *pdu = NULL;
/* Push a UNBIND PDU on the [smsc->fifo_r_out] stack. */
pdu = pdu_new();
if(pdu == NULL) goto error;
pdu->id = SMPP_UNBIND;
pdu->length = 16;
pdu->status = 0;
pdu->sequence_no = 1;
pdu->message_body = NULL;
fifo_push(smsc->fifo_r_out, pdu);
/* Push a UNBIND PDU on the [smsc->fifo_t_out] stack. */
pdu = pdu_new();
if(pdu == NULL) goto error;
pdu->id = SMPP_UNBIND;
pdu->length = 16;
pdu->status = 0;
pdu->sequence_no = 1;
pdu->message_body = NULL;
fifo_push(smsc->fifo_t_out, pdu);
/* Write out the UNBIND PDUs. */
smpp_pending_smsmessage(smsc);
/* Wait a while. */
usleep(100);
/* Check states */
#if 0
/* XXX LATER, WHEN THIS IS IMPLEMENTED IN SMSGATEWAY.C XXX */
/* If states are BOUND then push UNBIND messages to
fifostack and return a failure. */
if(smsc->smpp_t_state == 1)
return 0;
if(smsc->smpp_r_state == 1)
return 0;
#endif
/* Close transmitter connection. */
close(smsc->fd_t);
/* Close receiver connection. */
close(smsc->fd_r);
/* Destroy FIFO stacks. */
fifo_free(smsc->unsent_mt);
fifo_free(smsc->sent_mt);
fifo_free(smsc->delivered_mt);
fifo_free(smsc->received_mo);
fifo_free(smsc->fifo_t_in);
fifo_free(smsc->fifo_t_out);
fifo_free(smsc->fifo_r_in);
fifo_free(smsc->fifo_r_out);
/* Destroy buffers */
data_free(smsc->data_t);
data_free(smsc->data_r);
return 0;
error:
return -1;
}
int smpp_submit_smsmessage(SMSCenter *smsc, SMSMessage *msg) {
struct smpp_pdu *pdu = NULL;
struct smpp_pdu_submit_sm *submit_sm = NULL;
/* Validate *msg. */
if(smsc == NULL) goto error;
if(msg == NULL) goto error;
/* If we cannot really send yet, push message to
smsc->unsent_mt where it will stay until
smpp_pdu_act_bind_transmitter_resp is called. */
if( smsc->smpp_t_state != SMPP_STATE_BOUND ) {
fifo_push_smsmessage(smsc->unsent_mt, msg);
return 1;
}
/* Push a SUBMIT_SM PDU on the smsc->fifo_t_out fifostack. */
pdu = pdu_new();
if(pdu == NULL) goto error;
memset(pdu, 0, sizeof(struct smpp_pdu));
submit_sm = malloc(sizeof(struct smpp_pdu_submit_sm));
if(submit_sm == NULL) goto error;
memset(submit_sm, 0, sizeof(struct smpp_pdu_submit_sm));
strncpy(submit_sm->source_addr, msg->sender, 21);
submit_sm->source_addr_npi = GSM_ADDR_NPI_UNKNOWN;
submit_sm->source_addr_ton = GSM_ADDR_TON_NETWORKSPECIFIC;
/* Notice that the +2 is to get rid of the 00 start. */
strncat(submit_sm->dest_addr, msg->receiver+2, 21);
submit_sm->dest_addr_npi = GSM_ADDR_NPI_E164;
submit_sm->dest_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
submit_sm->data_coding = 3;
submit_sm->sm_length = octstr_len(msg->text);
octstr_get_many_chars(submit_sm->short_message, msg->text, 0, 160);
charset_iso_to_smpp(submit_sm->short_message);
pdu->id = SMPP_SUBMIT_SM;
pdu->status = 0;
pdu->sequence_no = smsc->seq_t++;
pdu->message_body = submit_sm;
pdu->length = 16 +
strlen(submit_sm->service_type) + 1 +
1 + 1 +
strlen(submit_sm->source_addr) + 1 +
1 + 1 +
strlen(submit_sm->dest_addr) + 1 +
1 + 1 + 1 +
strlen(submit_sm->schedule_delivery_time) + 1 +
strlen(submit_sm->validity_period) + 1 +
1 + 1 + 1 + 1 + 1 +
strlen(submit_sm->short_message) + 1;
fifo_push(smsc->fifo_t_out, pdu);
return 0;
error:
return -1;
}
int smpp_receive_smsmessage(SMSCenter *smsc, SMSMessage **msg) {
SMSMessage *newmsg = NULL;
char *newnum = NULL;
/* Pop a SMSMessage message from the MSG_MO stack. */
if( fifo_pop_smsmessage(smsc->received_mo, &newmsg) == 1 ) {
/* Change the number format on msg->sender. */
newnum = malloc(strlen(newmsg->sender)+3);
if(newnum==NULL) goto error;
memset(newnum, 0, strlen(newmsg->sender)+3);
strcpy(newnum, "00");
strcat(newnum, newmsg->sender);
free(newmsg->sender);
newmsg->sender = newnum;
*msg = newmsg;
return 1;
}
return 0;
error:
error(errno, "smpp_receive_smsmessage: error");
return -1;
}
int smpp_pending_smsmessage(SMSCenter *smsc) {
Octstr *data = NULL;
smpp_pdu *pdu = NULL;
int ret = 0, funcret = 0;
/* Process the MT messages. */
/* Send whatever we need to send */
while( fifo_pop(smsc->fifo_t_out, &pdu) == 1 ) {
/* Encode the PDU to raw data. */
if( pdu_encode(pdu, &data) == 1 ) {
/* Send the PDU data. */
ret = data_send(smsc->fd_t, data);
data_free(data);
if(ret==-1) break;
}
pdu_free(pdu);
if(ret==-1) break;
}
/* Receive raw data */
ret = data_receive(smsc->fd_t, smsc->data_t);
if(ret == -1) {
warning(0, "smpp_pending_smsmessage: reopening connections");
smpp_reopen(smsc);
}
/* Interpret the raw data */
while( data_pop(smsc->data_t, &data) == 1 ) {
/* Decode the PDU from raw data. */
if( (ret = pdu_decode(&pdu, data)) ) {
/* Act on PDU. */
pdu->fd = smsc->fd_t;
ret = pdu_act(smsc, pdu);
pdu_free(pdu);
}
data_free(data);
}
/* Process the MO messages. */
ret = data_receive(smsc->fd_r, smsc->data_r);
if(ret == -1) {
warning(0, "smpp_pending_smsmessage: reopening connections");
smpp_reopen(smsc);
}
while( fifo_pop(smsc->fifo_r_out, &pdu) == 1 ) {
/* Encode the PDU to raw data. */
if( (ret = pdu_encode(pdu, &data)) ) {
/* Send the PDU data. */
ret = data_send(smsc->fd_r, data);
data_free(data);
if(ret==-1) break;
}
pdu_free(pdu);
if(ret==-1) break;
}
while( data_pop(smsc->data_r, &data) == 1 ) {
/* Decode the PDU from raw data. */
if( (ret = pdu_decode(&pdu, data)) ) {
/* Act on PDU. */
pdu->fd = smsc->fd_r;
ret = pdu_act(smsc, pdu);
pdu_free(pdu);
}
data_free(data);
}
/* Signal that we got a MO message */
if(smsc->received_mo->left != NULL) funcret = 1;
/* If it's been a "long time" (defined elsewhere) since
the last message, actively check the link status by
sending a LINK_STATUS pdu to the SMSC, thereby
(maybe) resetting the close-if-no-traffic timer.
Note: in practise we won't need this. */
/* XXX DO IT */
return funcret;
}
static smpp_pdu* pdu_new(void) {
struct smpp_pdu *newpdu = NULL;
newpdu = malloc(sizeof(struct smpp_pdu));
memset(newpdu, 0, sizeof(struct smpp_pdu));
return newpdu;
}
static int pdu_free(smpp_pdu *pdu) {
if(pdu == NULL) return 0;
smsmessage_destruct(pdu->smsmsg);
free(pdu->message_body);
free(pdu);
return 1;
}
static Octstr* data_new(void) {
struct Octstr *newstr = NULL;
newstr = octstr_create_empty();
return newstr;
}
static int data_free(Octstr *str) {
if(str == NULL) return 0;
octstr_destroy(str);
return 1;
}
static fifostack* fifo_new(void) {
struct fifostack *newfifo = NULL;
newfifo = malloc(sizeof(struct fifostack));
if(newfifo == NULL) goto error;
memset(newfifo, 0, sizeof(struct fifostack));
return newfifo;
error:
error(0, "fifo_new: memory allocation error");
return NULL;
}
static void fifo_free(fifostack *fifo) {
struct smpp_pdu *pdu = NULL;
if(fifo == NULL) return;
/* Drain the leftover PDUs to the bit sink. */
while( fifo_pop(fifo, &pdu) == 1 ) {
pdu_free(pdu);
pdu = NULL;
}
free(fifo);
return;
}
static int fifo_push(fifostack *fifo, smpp_pdu *pdu) {
if(fifo == NULL) {
error(0, "fifo_push: NULL input");
goto error;
}
if(pdu == NULL) {
error(0, "fifo_push: NULL input");
goto error;
}
/* If fifostack is completely empty. */
if( (fifo->left == NULL) && (fifo->right == NULL) ) {
fifo->left = pdu;
fifo->right = pdu;
pdu->left = NULL;
pdu->right = NULL;
goto a_ok;
}
/* Ok, insert the pdu on the left side. */
pdu->left = NULL;
(fifo->left)->left = pdu;
fifo->left = pdu;
a_ok:
return 1;
error:
error(0, "fifo_push: error");
return -1;
}
static int fifo_pop(fifostack *fifo, smpp_pdu **pdu) {
if(fifo == NULL) {
error(0, "fifo_pop: NULL input");
goto error;
}
if(pdu == NULL) {
error(0, "fifo_pop: NULL input");
goto error;
}
/* If fifostack is completely empty. */
if( (fifo->left == NULL) && (fifo->right == NULL) ) {
goto no_msgs;
}
/* Drop a message from the right side. */
*pdu = fifo->right;
/* If this was the last PDU and the fifostack is now empty. */
if(fifo->right->left == NULL) {
fifo->right = NULL;
fifo->left = NULL;
} else {
/* Set the new right edge. */
fifo->right = (fifo->right)->left;
/* Terminate. */
(fifo->right)->right = NULL;
}
return 1;
no_msgs:
return 0;
error:
error(0, "fifo_pop: returing error");
return -1;
}
static int fifo_push_smsmessage(fifostack *fifo, SMSMessage *msg) {
struct smpp_pdu *pdu = NULL;
pdu = pdu_new();
if(pdu == NULL) goto error;
memset(pdu, 0, sizeof(struct smpp_pdu));
pdu->smsmsg = msg;
fifo_push(fifo, pdu);
return 1;
error:
error(0, "fifo_push_smsmessage: returning error");
return -1;
}
static int fifo_pop_smsmessage(fifostack *fifo, SMSMessage **msg) {
struct smpp_pdu *pdu = NULL;
int ret;
ret = fifo_pop(fifo, &pdu);
if(ret == 0) goto no_msg;
if(ret <>
*msg = pdu->smsmsg;
if(*msg == NULL) goto error;
pdu->smsmsg = NULL;
pdu_free(pdu);
return 1;
no_msg:
return 0;
error:
error(0, "fifo_pop_smsmessage: returning error");
return -1;
}
/******************************************************************************
* data_pop
*
* from: The Octstr to cut from
* to: The Octstr to create and paste to
*
* Description:
*
* Returns:
* 1 if a PDU was found
* 0 if no PDU found
* -1 if an error occurred
*
*/
static int data_pop(Octstr *from, Octstr **to) {
int32 quadoct;
int32 realint;
unsigned int olen = 0;
olen = octstr_len(from);
/* Check if [from] has enough data to contain a PDU (>=16 octets) */
if(olen <>
/* Read the length (4 first octets) */
octstr_get_many_chars((char*)&quadoct, from, 0, 4);
/* Translate the length XXX MAKE THIS INTO 1 FUNCTION */
realint = ntohl(quadoct);
/* Check if we have [length] octets of data */
if(olen <>
/* Cut the PDU out, move data to fill the hole. */
*to = octstr_copy(from, 0, realint);
if(*to == NULL) goto error;
octstr_delete(from, 0, realint);
/* Okay, done */
return 1;
no_msg:
*to = NULL;
return -1;
error:
error(0, "data_pop: ERROR!!!");
*to = NULL;
return -1;
}
/******************************************************************************
* data_receive
*
* fd: the File Descriptor to read from
* to: The Octstr to append to
*
* Description:
* Receive data from [fd] and append it to [to].
*
* Returns:
* 1 if a PDU was found
* 0 if no PDU found
* -1 if an error occurred
*
*/
static int data_receive(int fd, Octstr *to) {
size_t length;
char data[1024];
Octstr *newstr = NULL;
fd_set rf;
struct timeval tox;
int ret;
memset(&data, 0, sizeof(data));
FD_ZERO(&rf);
FD_SET(fd, &rf);
tox.tv_sec = 0;
tox.tv_usec = 100;
ret = select(FD_SETSIZE, &rf, NULL, NULL, &tox);
if (ret == 0) {
goto no_data;
} else if (ret <>
if(errno == EBADF) {
error(errno, "data_receive: select failed");
}
goto error;
}
/* Create temp data structures. */
length = read(fd, &data, sizeof(data)-1);
if(length == -1) {
/* if(errno==EWOULDBLOCK) return -1; */
goto error;
} else if(length == 0) {
debug(0, "soketti <%i> kloused", fd);
goto error;
}
newstr = octstr_create_from_data(data, length);
if(newstr == NULL) goto error;
octstr_insert(to, newstr, octstr_len(to));
/* Okay, done */
return 1;
no_data:
return 0;
error:
debug(0, "data_receive: error");
return -1;
}
/******************************************************************************
* data_send
*
* fd: the File Descriptor to write to
* to: The Octstr to get the data from
*
* Description:
* Write all the data from [from] to [fd].
*
* Returns:
* 1 if a PDU was found
* 0 if no PDU found
* -1 if an error occurred
*
*/
static int data_send(int fd, Octstr *from) {
size_t length, curl, written = 0;
char *willy = NULL;
debug(0, "data_send: starting");
/* Create temp data structures. */
length = octstr_len(from);
if(length <= 0) return 0;
willy = malloc(length);
if(willy == NULL) goto error;
octstr_get_many_chars(willy, from, 0, length);
/* Write to socket */
for(;;) {
if(written >= length) break;
curl = write(fd, willy+written, length-written);
if(curl == -1) {
if(errno==EAGAIN) continue;
if(errno==EINTR) continue;
if(errno==EBADF) {
error(errno, "data_send: write(2) failed");
}
goto error;
} else if(curl == 0) {
goto socket_b0rken;
}
written += curl;
}
/* Okay, done */
free(willy);
return 1;
socket_b0rken:
debug(0, "data_send: broken socket!!!");
free(willy);
return -1;
error:
debug(0, "data_send: ERROR!!!");
free(willy);
return -1;
}
/* Append a single octet of data. Update where to reflect the
next byte to write to, decrease left by the number of
bytes written. */
static int smpp_append_oct(char** where, int* left, uint32_t data) {
/* Change this to reflect differences in endianness and
bytenesses. */
#if BYTE_ORDER == LITTLE_ENDIAN
memcpy(*where, &data, 1);
*where += 1;
#elif BYTE_ORDER == BIG_ENDIAN
memcpy(*where, (&data)+3, 1);
*where += 1;
#else
/* We have to write another section here for PDPs :) */
error(0, "smpp_append_oct: wrong endianness.");
#endif
return 1;
}
static int smpp_read_oct(char** where, int* left, Octet* data) {
return -1;
smpp_read_oct(where, left, data);
}
static int smpp_append_cstr(char** where, int* left, char* data) {
memcpy(*where, data, strlen(data)+1);
*where += (strlen(data) + 1);
return 1;
}
static int smpp_read_cstr(char** where, int* left, char** data) {
return -1;
smpp_read_cstr(where, left, data);
}
static int smpp_append_int32(char** where, int* left, int32 data) {
return -1;
smpp_append_int32(where, left, data);
}
static int smpp_read_int32(char** where, int* left, int32* data) {
return -1;
smpp_read_int32(where, left, data);
}
/******************************************************************************
* pdu_act
*
* Decide what to do with a PDU once we have managed to obtain one.
*
* Refer to:
* SMPP 3.3 specification section 5.5.2
*
* Returns:
* 1 if a PDU was found
* 0 if no PDU found
* -1 if an error occurred
*
*/
static int pdu_act(SMSCenter *smsc, smpp_pdu *pdu) {
int ret = -1;
switch(pdu->id) {
case SMPP_BIND_RECEIVER_RESP:
ret = pdu_act_bind_receiver_resp(smsc, pdu);
break;
case SMPP_BIND_TRANSMITTER_RESP:
ret = pdu_act_bind_transmitter_resp(smsc, pdu);
break;
case SMPP_UNBIND_RESP:
ret = pdu_act_unbind_resp(smsc, pdu);
break;
case SMPP_SUBMIT_SM_RESP:
ret = pdu_act_submit_sm_resp(smsc, pdu);
break;
case SMPP_SUBMIT_MULTI_RESP:
ret = pdu_act_submit_multi_resp(smsc, pdu);
break;
case SMPP_DELIVER_SM:
ret = pdu_act_deliver_sm(smsc, pdu);
break;
case SMPP_QUERY_SM_RESP:
ret = pdu_act_query_sm_resp(smsc, pdu);
break;
case SMPP_CANCEL_SM_RESP:
ret = pdu_act_cancel_sm_resp(smsc, pdu);
break;
case SMPP_REPLACE_SM_RESP:
ret = pdu_act_replace_sm_resp(smsc, pdu);
break;
case SMPP_ENQUIRE_LINK:
ret = pdu_act_enquire_link(smsc, pdu);
break;
case SMPP_ENQUIRE_LINK_RESP:
ret = pdu_act_enquire_link_resp(smsc, pdu);
break;
case SMPP_GENERIC_NAK:
ret = pdu_act_generic_nak(smsc, pdu);
break;
/* case SMPP_QUERY_LAST_MSGS_RESP:
ret = pdu_act_query_last_msgs_resp(smsc, pdu);
break;
case SMPP_QUERY_MSG_DETAILS_RESP:
ret = pdu_act_query_msg_details_resp(smsc, pdu);
break;
*/
}
return ret;
}
/******************************************************************************
* pdu_decode
*
* Description:
* Decode given raw data into a brand new SMPP PDU.
*
* Returns:
* 1 if a PDU was created
* 0 if no PDU could be created
* -1 if an error occurred
*
*/
static int pdu_decode(smpp_pdu **pdu, Octstr *from) {
int ret;
struct smpp_pdu *newpdu;
newpdu = pdu_new();
/* Decode the header */
ret = pdu_header_decode(newpdu, from);
switch(newpdu->id) {
case SMPP_BIND_RECEIVER_RESP:
ret = pdu_decode_bind(newpdu, from);
break;
case SMPP_BIND_TRANSMITTER_RESP:
ret = pdu_decode_bind(newpdu, from);
break;
case SMPP_UNBIND_RESP:
ret = pdu_decode_bind(newpdu, from);
break;
case SMPP_DELIVER_SM:
ret = pdu_decode_deliver_sm(newpdu, from);
break;
case SMPP_SUBMIT_SM_RESP:
ret = pdu_decode_submit_sm_resp(newpdu, from);
break;
#if 0
case SMPP_SUBMIT_MULTI_RESP:
ret = pdu_decode_submit_multi_resp(smsc, pdu);
break;
case SMPP_QUERY_SM_RESP:
ret = pdu_decode_query_sm_resp(smsc, pdu);
break;
/*
case SMPP_QUERY_LAST_MSGS_RESP:
ret = pdu_decode_query_last_msgs_resp(smsc, pdu);
break;
case SMPP_QUERY_MSG_DETAILS_RESP:
ret = pdu_decode_query_msg_details_resp(smsc, pdu);
break;
*/
case SMPP_CANCEL_SM_RESP:
ret = pdu_decode_cancel_sm_resp(smsc, pdu);
break;
case SMPP_REPLACE_SM_RESP:
ret = pdu_decode_replace_sm_resp(smsc, pdu);
break;
case SMPP_ENQUIRE_LINK:
ret = pdu_decode_enquire_link(smsc, pdu);
break;
case SMPP_ENQUIRE_LINK_RESP:
ret = pdu_decode_enquire_link_resp(smsc, pdu);
break;
case SMPP_GENERIC_NAK:
ret = pdu_decode_generic_nak(smsc, pdu);
break;
#endif
}
*pdu = newpdu;
return 1;
}
/******************************************************************************
* pdu_encode
*
* Description:
* Encode a given SMPP PDU structure to raw data.
*
* Returns:
* 1 if PDU was translated to raw data
* 0 if PDU couldn't be translated
* -1 if an error occurred
*
*/
static int pdu_encode(smpp_pdu *pdu, Octstr **rawdata) {
struct Octstr *body = NULL, *header = NULL, *whole = NULL;
int ret;
switch(pdu->id) {
case SMPP_BIND_RECEIVER:
ret = pdu_encode_bind(pdu, &body);
break;
case SMPP_BIND_RECEIVER_RESP:
ret = pdu_encode_bind(pdu, &body);
break;
case SMPP_BIND_TRANSMITTER:
ret = pdu_encode_bind(pdu, &body);
break;
case SMPP_BIND_TRANSMITTER_RESP:
ret = pdu_encode_bind(pdu, &body);
break;
case SMPP_UNBIND_RESP:
ret = pdu_encode_bind(pdu, &body);
break;
case SMPP_DELIVER_SM_RESP:
ret = pdu_encode_deliver_sm_resp(pdu, &body);
break;
case SMPP_SUBMIT_SM:
ret = pdu_encode_submit_sm(pdu, &body);
break;
#if 0
case SMPP_SUBMIT_MULTI:
ret = pdu_encode_submit_multi(pdu, &body);
break;
case SMPP_QUERY_SM:
ret = pdu_encode_query_sm(pdu, &body);
break;
/*
case SMPP_QUERY_LAST_MSGS:
ret = pdu_encode_query_last_msgs(pdu, &body);
break;
case SMPP_QUERY_MSG_DETAILS:
ret = pdu_encode_query_msg_details(pdu, &body);
break;
*/
case SMPP_CANCEL_SM:
ret = pdu_encode_cancel_sm(pdu, &body);
break;
case SMPP_REPLACE_SM:
ret = pdu_encode_replace_sm(pdu, &body);
break;
case SMPP_ENQUIRE_LINK:
ret = pdu_encode_enquire_link(pdu, &body);
break;
case SMPP_ENQUIRE_LINK_RESP:
ret = pdu_encode_enquire_link_resp(pdu, &body);
break;
case SMPP_GENERIC_NAK:
ret = pdu_encode_generic_nak(pdu, &body);
break;
#endif
}
pdu_header_encode(pdu, &header);
whole = octstr_cat(header, body);
octstr_destroy(header);
octstr_destroy(body);
*rawdata = whole;
return 1;
}
static int pdu_header_decode(smpp_pdu *pdu, Octstr *str) {
uint32_t header[4];
if(pdu == NULL) goto error;
if(str == NULL) goto error;
/* Read the header */
octstr_get_many_chars((char*)&header, str, 0, sizeof(header));
pdu->length = ntohl(header[0]);
pdu->id = ntohl(header[1]);
pdu->status = ntohl(header[2]);
pdu->sequence_no = ntohl(header[3]);
return 1;
error:
return -1;
}
static int pdu_header_encode(smpp_pdu *pdu, Octstr **rawdata) {
uint32_t length, id, status, seq;
Octstr *newdata = NULL;
char temp[16], *tempptr;
memset(temp, 0, sizeof(temp));
tempptr = temp;
length = htonl(pdu->length);
id = htonl(pdu->id);
status = htonl(pdu->status);
seq = htonl(pdu->sequence_no);
memcpy(tempptr, &length, 4);
tempptr += 4;
memcpy(tempptr, &id, 4);
tempptr += 4;
memcpy(tempptr, &status, 4);
tempptr += 4;
memcpy(tempptr, &seq, 4);
tempptr += 4;
newdata = octstr_create_from_data(temp, sizeof(temp));
*rawdata = newdata;
return 1;
}
static int pdu_decode_bind(smpp_pdu *pdu, Octstr *str) {
return 1;
}
static int pdu_encode_bind(smpp_pdu *pdu, Octstr **str) {
int length = 0;
char *data = NULL, *where = NULL;
Octstr *body_encoded;
int left;
struct smpp_pdu_bind_receiver *bind_receiver;
struct smpp_pdu_bind_receiver_resp *bind_receiver_resp;
struct smpp_pdu_bind_transmitter *bind_transmitter;
struct smpp_pdu_bind_transmitter_resp *bind_transmitter_resp;
switch(pdu->id) {
case SMPP_BIND_RECEIVER:
bind_receiver = (smpp_pdu_bind_receiver*) pdu->message_body;
length = strlen(bind_receiver->system_id) + 1 +
strlen(bind_receiver->password) + 1 +
strlen(bind_receiver->system_type) + 1 +
1 + 1 + 1 +
strlen(bind_receiver->address_range) + 1;
data = malloc(length);
if(data == NULL) goto error;
memset(data, 0, length);
where = data;
smpp_append_cstr(&where, &left, bind_receiver->system_id);
smpp_append_cstr(&where, &left, bind_receiver->password);
smpp_append_cstr(&where, &left, bind_receiver->system_type);
smpp_append_oct(&where, &left, bind_receiver->interface_version);
smpp_append_oct(&where, &left, bind_receiver->addr_ton);
smpp_append_oct(&where, &left, bind_receiver->addr_npi);
smpp_append_cstr(&where, &left, bind_receiver->address_range);
break;
case SMPP_BIND_RECEIVER_RESP:
length = strlen(bind_receiver_resp->system_id) + 1;
data = malloc(length);
if(data == NULL) goto error;
memset(data, 0, length);
where = data;
smpp_append_cstr(&where, &left, bind_receiver_resp->system_id);
break;
case SMPP_BIND_TRANSMITTER:
bind_transmitter = (smpp_pdu_bind_transmitter*) pdu->message_body;
length = strlen(bind_transmitter->system_id) + 1 +
strlen(bind_transmitter->password) + 1 +
strlen(bind_transmitter->system_type) + 1 +
1 + 1 + 1 +
strlen(bind_transmitter->address_range) + 1;
data = malloc(length);
if(data == NULL) goto error;
memset(data, 0, length);
where = data;
smpp_append_cstr(&where, &left, bind_transmitter->system_id);
smpp_append_cstr(&where, &left, bind_transmitter->password);
smpp_append_cstr(&where, &left, bind_transmitter->system_type);
smpp_append_oct(&where, &left, bind_transmitter->interface_version);
smpp_append_oct(&where, &left, bind_transmitter->addr_ton);
smpp_append_oct(&where, &left, bind_transmitter->addr_npi);
smpp_append_cstr(&where, &left, bind_transmitter->address_range);
break;
case SMPP_BIND_TRANSMITTER_RESP:
bind_transmitter_resp = (smpp_pdu_bind_transmitter_resp*) pdu->message_body;
length = strlen(bind_transmitter_resp->system_id) + 1;
data = malloc(length);
if(data == NULL) goto error;
smpp_append_cstr(&where, &left, bind_transmitter_resp->system_id);
break;
case SMPP_UNBIND:
data = NULL;
length = 0;
break;
case SMPP_UNBIND_RESP:
data = NULL;
length = 0;
break;
}
pdu->length = length + 16;
body_encoded = octstr_create_from_data(data, length);
*str = body_encoded;
free(data);
return 1;
error:
return -1;
}
/******************************************************************************
* PDUs
* BIND_TRANSMITTER, BIND_TRANSMITTER_RESP
*/
static int pdu_act_bind_transmitter_resp(SMSCenter *smsc, smpp_pdu *pdu) {
struct smpp_pdu *newpdu = NULL;
struct smpp_pdu_submit_sm *submit_sm = NULL;
SMSMessage *msg = NULL;
/* Validate *msg. */
if(smsc == NULL) goto error;
if(pdu == NULL) goto error;
smsc->smpp_t_state = SMPP_STATE_BOUND;
/* Process any messages that were sent through the HTTP
interface while the transmitter connection was not
bound. */
while( fifo_pop_smsmessage(smsc->unsent_mt, &msg) == 1 ) {
/* Push a SUBMIT_SM PDU on the smsc->fifo_t_out fifostack. */
newpdu = pdu_new();
if(newpdu == NULL) goto error;
memset(newpdu, 0, sizeof(struct smpp_pdu));
submit_sm = malloc(sizeof(struct smpp_pdu_submit_sm));
if(submit_sm == NULL) goto error;
memset(submit_sm, 0, sizeof(struct smpp_pdu_submit_sm));
strncpy(submit_sm->source_addr, msg->sender, 21);
submit_sm->source_addr_npi = GSM_ADDR_NPI_UNKNOWN;
submit_sm->source_addr_ton = GSM_ADDR_TON_NETWORKSPECIFIC;
/* Notice that the +2 is to get rid of the 00 start. */
strncat(submit_sm->dest_addr, msg->receiver+2, 21);
submit_sm->dest_addr_npi = GSM_ADDR_NPI_E164;
submit_sm->dest_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
submit_sm->data_coding = 3;
submit_sm->sm_length = octstr_len(msg->text);
octstr_get_many_chars(submit_sm->short_message, msg->text, 0, 160);
charset_iso_to_smpp(submit_sm->short_message);
newpdu->id = SMPP_SUBMIT_SM;
newpdu->status = 0;
newpdu->sequence_no = smsc->seq_t++;
newpdu->message_body = submit_sm;
newpdu->length = 16 +
strlen(submit_sm->service_type) + 1 +
1 + 1 +
strlen(submit_sm->source_addr) + 1 +
1 + 1 +
strlen(submit_sm->dest_addr) + 1 +
1 + 1 + 1 +
strlen(submit_sm->schedule_delivery_time) + 1 +
strlen(submit_sm->validity_period) + 1 +
1 + 1 + 1 + 1 + 1 +
strlen(submit_sm->short_message) + 1;
fifo_push(smsc->fifo_t_out, newpdu);
}
return 0;
error:
return -1;
}
/******************************************************************************
* PDUs
* BIND_RECEIVER, BIND_RECEIVER_RESP
*/
static int pdu_act_bind_receiver_resp(SMSCenter *smsc, smpp_pdu *pdu) {
smsc->smpp_r_state = SMPP_STATE_BOUND;
return 1;
}
/******************************************************************************
* PDUs
* UNBIND, UNBIND_RESP
*/
static int pdu_act_unbind_resp(SMSCenter *smsc, smpp_pdu *pdu) {
/* debug(0, "pdu_act_unbind_resp: start"); */
/* Remove the status flag CAN_RECEIVE or CAN_SEND */
return -1;
}
/******************************************************************************
* PDUs
* SUBMIT_SM, SUBMIT_SM_RESP
*/
static int pdu_act_submit_sm_resp(SMSCenter *smsc, smpp_pdu *pdu) {
debug(0, "pdu_act_submit_sm_resp: start");
/* Mark message the SUBMIT_SM_RESP refers to as
acknowledged and remove it from smsc->smpp_fifostack. */
debug(0, "pdu->length == %08x", pdu->length);
debug(0, "pdu->id == %08x", pdu->id);
debug(0, "pdu->status == %08x", pdu->status);
debug(0, "pdu->sequence_no == %08x", pdu->sequence_no);
return -1;
}
static int pdu_encode_submit_sm(smpp_pdu* pdu, Octstr** str) {
struct smpp_pdu_submit_sm *submit_sm = NULL;
int32 length;
int left;
char *data = NULL, *where = NULL;
Octstr *newstr = NULL;
submit_sm = (struct smpp_pdu_submit_sm*) pdu->message_body;
length = strlen(submit_sm->service_type) + 1 +
1 + 1 +
strlen(submit_sm->source_addr) + 1 +
1 + 1 +
strlen(submit_sm->dest_addr) + 1 +
1 + 1 + 1 +
strlen(submit_sm->schedule_delivery_time) + 1 +
strlen(submit_sm->validity_period) + 1 +
1 + 1 + 1 + 1 + 1 +
strlen(submit_sm->short_message) + 1;
data = malloc(length);
if(data == NULL) goto error;
memset(data, 0, length);
where = data;
smpp_append_cstr(&where, &left, submit_sm->service_type);
smpp_append_oct(&where, &left, submit_sm->source_addr_ton);
smpp_append_oct(&where, &left, submit_sm->source_addr_npi);
smpp_append_cstr(&where, &left, submit_sm->source_addr);
smpp_append_oct(&where, &left, submit_sm->dest_addr_ton);
smpp_append_oct(&where, &left, submit_sm->dest_addr_npi);
smpp_append_cstr(&where, &left, submit_sm->dest_addr);
smpp_append_oct(&where, &left, submit_sm->esm_class);
smpp_append_oct(&where, &left, submit_sm->protocol_id);
smpp_append_oct(&where, &left, submit_sm->priority_flag);
smpp_append_cstr(&where, &left, submit_sm->schedule_delivery_time);
smpp_append_cstr(&where, &left, submit_sm->validity_period);
smpp_append_oct(&where, &left, submit_sm->registered_delivery_flag);
smpp_append_oct(&where, &left, submit_sm->replace_if_present_flag);
smpp_append_oct(&where, &left, submit_sm->data_coding);
smpp_append_oct(&where, &left, submit_sm->sm_default_msg_id);
smpp_append_oct(&where, &left, submit_sm->sm_length);
smpp_append_cstr(&where, &left, submit_sm->short_message);
newstr = octstr_create_from_data(data, length);
*str = newstr;
return 1;
error:
return -1;
}
static int pdu_decode_submit_sm_resp(smpp_pdu* pdu, Octstr* str) {
return -1;
}
/******************************************************************************
* PDUs
* SUBMIT_MULTI, SUBMIT_SM_MULTI_RESP
*/
static int pdu_act_submit_multi_resp(SMSCenter *smsc, smpp_pdu *pdu) {
debug(0, "pdu_act_submit_multi_resp: start");
/* Mark messages reffer to by the SUBMIT_MULTI_RESP as
acknowledged and remove them from smsc->fifostack. */
return -1;
}
/******************************************************************************
* PDUs
* DELIVER_SM, DELIVER_SM_RESP
*/
static int pdu_act_deliver_sm(SMSCenter *smsc, smpp_pdu *pdu) {
struct smpp_pdu *newpdu = NULL;
struct smpp_pdu_deliver_sm *deliver_sm = NULL;
struct smpp_pdu_deliver_sm_resp *deliver_sm_resp = NULL;
SMSMessage *smsmsg = NULL;
/* If DELIVER_SM was sent to acknowledge that the terminal
has received the message, ignore. */
deliver_sm = (struct smpp_pdu_deliver_sm*) pdu->message_body;
if(deliver_sm==NULL) goto error;
/* Convert message from the Default Charset to ISO-8859-1. */
charset_smpp_to_iso(deliver_sm->short_message);
/* Convert the PDU into a SMSMessage structure. */
smsmsg = smsmessage_construct(
deliver_sm->source_addr,
deliver_sm->dest_addr,
octstr_create(deliver_sm->short_message));
/* Push the SMSMessage structure on the smsc->received_mo fifostack. */
fifo_push_smsmessage(smsc->received_mo, smsmsg);
/* Push a DELIVER_SM_RESP structure on the smsc->fifo_r_out fifostack. */
newpdu = pdu_new();
if(newpdu == NULL) goto error;
memset(newpdu, 0, sizeof(struct smpp_pdu));
deliver_sm_resp = malloc(sizeof(struct smpp_pdu_deliver_sm_resp));
if(deliver_sm_resp == NULL) goto error;
memset(deliver_sm_resp, 0, sizeof(struct smpp_pdu_deliver_sm_resp));
newpdu->length = 17;
newpdu->id = SMPP_DELIVER_SM_RESP;
newpdu->status = 0;
newpdu->sequence_no = pdu->sequence_no;
newpdu->message_body = deliver_sm_resp;
fifo_push(smsc->fifo_r_out, newpdu);
return 1;
error:
return -1;
}
static int pdu_encode_deliver_sm_resp(smpp_pdu *pdu, Octstr **str) {
Octstr *newstr = NULL;
struct smpp_pdu_deliver_sm_resp *deliver_sm_resp = NULL;
char data;
deliver_sm_resp = (struct smpp_pdu_deliver_sm_resp*) pdu->message_body;
/* As specified in SMPP 3.3 / 6.3.3.2 */
data = '\0';
newstr = octstr_create_from_data(&data, 1);
*str = newstr;
return 1;
}
static int pdu_decode_deliver_sm(smpp_pdu* pdu, Octstr* str) {
char *start, *end, *buff;
struct smpp_pdu_deliver_sm *deliver_sm;
Octet oct;
if(pdu==NULL) goto error;
if(str==NULL) goto error;
if(octstr_len(str) <>
warning(0, "pdu_decode_deliver_sm: incorrect input");
goto error;
}
deliver_sm = malloc(sizeof(struct smpp_pdu_deliver_sm));
if(deliver_sm==NULL) goto error;
memset(deliver_sm, 0, sizeof(struct smpp_pdu_deliver_sm));
pdu->message_body = deliver_sm;
buff = malloc(octstr_len(str));
if(buff == NULL) goto error;
octstr_get_many_chars(buff, str, 0, octstr_len(str));
start = buff + 16;
end = start + strlen(start);
strncpy(deliver_sm->service_type, start, 6);
start = end+1;
strncpy(&oct, start, 1);
deliver_sm->source_addr_ton = oct;
start++;
strncpy(&oct, start, 1);
deliver_sm->source_addr_npi = oct;
start++;
end = start + strlen(start);
strncpy(deliver_sm->source_addr, start, 21);
start = end+1;
strncpy(&oct, start, 1);
deliver_sm->dest_addr_ton = oct;
start++;
strncpy(&oct, start, 1);
deliver_sm->dest_addr_npi = oct;
start++;
end = start + strlen(start);
strncpy(deliver_sm->dest_addr, start, 21);
start = end+1;
strncpy(&oct, start, 1);
deliver_sm->esm_class = oct;
start++;
strncpy(&oct, start, 1);
deliver_sm->protocol_id = oct;
start++;
strncpy(&oct, start, 1);
deliver_sm->priority_flag = oct;
start++;
end = start + strlen(start);
strncpy(deliver_sm->schedule_delivery_time, start, 17);
start = end+1;
end = start + strlen(start);
strncpy(deliver_sm->validity_period, start, 17);
start = end+1;
strncpy(&oct, start, 1);
deliver_sm->registered_delivery_flag = oct;
start++;
strncpy(&oct, start, 1);
deliver_sm->replace_if_present_flag = oct;
start++;
strncpy(&oct, start, 1);
deliver_sm->data_coding = oct;
start++;
strncpy(&oct, start, 1);
deliver_sm->sm_default_msg_id = oct;
start++;
strncpy(&oct, start, 1);
deliver_sm->sm_length = oct;
start++;
/* Make sure that the upcoming SMPP 3.4 implementation
won't break our application with the new definition
of max short_message size. */
end = start + strlen(start);
strncpy(deliver_sm->short_message, start,
(deliver_sm->sm_length > sizeof(deliver_sm->short_message)) ?
sizeof(deliver_sm->short_message) : deliver_sm->sm_length);
start = end+1;
free(buff);
debug(0, "pdu->service_type == %s", deliver_sm->service_type);
debug(0, "pdu->source_addr_ton == %i", deliver_sm->source_addr_ton);
debug(0, "pdu->source_addr_npi == %i", deliver_sm->source_addr_npi);
debug(0, "pdu->source_addr == %s", deliver_sm->source_addr);
debug(0, "pdu->dest_addr_ton == %i", deliver_sm->dest_addr_ton);
debug(0, "pdu->dest_addr_npi == %i", deliver_sm->dest_addr_npi);
debug(0, "pdu->dest_addr == %s", deliver_sm->dest_addr);
debug(0, "pdu->esm_class == %i", deliver_sm->esm_class);
debug(0, "pdu->protocol_id == %i", deliver_sm->protocol_id);
debug(0, "pdu->priority_flag == %i", deliver_sm->priority_flag);
debug(0, "pdu->schedule_delivery_time == %s", deliver_sm->schedule_delivery_time);
debug(0, "pdu->validity_period == %s", deliver_sm->validity_period);
debug(0, "pdu->registered_delivery_flag == %i", deliver_sm->registered_delivery_flag);
debug(0, "pdu->replace_if_present_flag == %i", deliver_sm->replace_if_present_flag);
debug(0, "pdu->data_coding == %i", deliver_sm->data_coding);
debug(0, "pdu->sm_default_msg_id == %i", deliver_sm->sm_default_msg_id);
debug(0, "pdu->sm_length == %i", deliver_sm->sm_length);
start = malloc( 4 );
end = malloc( (deliver_sm->sm_length*3) + 1 );
if(start == NULL) goto error;
if(end == NULL) goto error;
memset(end, 0, (deliver_sm->sm_length*3) + 1);
for(oct=0; oct <>sm_length; oct++) {
sprintf(start, "%02x ", (unsigned char) deliver_sm->short_message[oct]);
strcat(end, start);
}
debug(0, "pdu->short_message == %s", end);
free(start);
free(end);
return 1;
error:
return -1;
}
/******************************************************************************
* PDUs
* QUERY_SM, QUERY_SM_RESP
*/
static int pdu_act_query_sm_resp(SMSCenter *smsc, smpp_pdu *pdu) {
/* Ignore, this version doesn't send messages which
get these responses. */
return -1;
}
#if 0
static int pdu_act_query_last_msgs_resp(SMSCenter *smsc, smpp_pdu *pdu) {
/* Ignore, this version doesn't send messages which
get these responses. */
return -1;
}
static int pdu_act_query_msg_details_resp(SMSCenter *smsc, smpp_pdu *pdu) {
/* Ignore, this version doesn't send messages which
get these responses. */
return -1;
}
#endif
static int pdu_act_cancel_sm_resp(SMSCenter *smsc, smpp_pdu *pdu) {
/* Ignore, this version doesn't send messages which
get these responses. */
return -1;
}
static int pdu_act_replace_sm_resp(SMSCenter *smsc, smpp_pdu *pdu) {
/* Ignore, this version doesn't send messages which
get these responses. */
return -1;
}
static int pdu_act_enquire_link(SMSCenter *smsc, smpp_pdu *pdu) {
struct smpp_pdu *newpdu = NULL;
/* Push a ENQUIRE_LINK_RESP on the appropriate fifostack. */
newpdu = pdu_new();
if(newpdu==NULL) goto error;
memset(newpdu, 0, sizeof(struct smpp_pdu));
newpdu->message_body = NULL;
newpdu->length = 16;
newpdu->id = SMPP_ENQUIRE_LINK_RESP;
newpdu->status = 0;
if(pdu->fd == smsc->fd_t) {
newpdu->sequence_no = smsc->seq_t++;
fifo_push(smsc->fifo_t_out, newpdu);
} else if(pdu->fd == smsc->fd_r) {
newpdu->sequence_no = smsc->seq_r++;
fifo_push(smsc->fifo_r_out, newpdu);
}
return 1;
error:
return -1;
}
static int pdu_act_enquire_link_resp(SMSCenter *smsc, smpp_pdu *pdu) {
/* Reset the status flag CAN_SEND or CAN_RECEIVE */
return 1;
}
static int pdu_act_generic_nak(SMSCenter *smsc, smpp_pdu *pdu) {
error(0, "pdu_act_generic_nak: SOMETHING IS DREADFULLY WRONG");
debug(0, "pdu->length == %08x", pdu->length);
debug(0, "pdu->id == %08x", pdu->id);
debug(0, "pdu->status == %08x", pdu->status);
debug(0, "pdu->sequence_no == %08x", pdu->sequence_no);
/* Panic */
return -1;
}
static int charset_smpp_to_iso(char* data) {
int i;
while(*data != '\0') {
i = 0;
while( translation_table[i].iso != 0 ) {
if( translation_table[i].smpp == *data ) {
*data = translation_table[i].iso;
break;
}
i++;
}
data++;
}
return 1;
}
static int charset_iso_to_smpp(char* data) {
int i;
while(*data != '\0') {
i = 0;
while( translation_table[i].iso != 0 ) {
if( translation_table[i].iso == *data ) {
*data = translation_table[i].smpp;
break;
}
i++;
}
data++;
}
return 1;
}
0 comments
Post a Comment