Пример #1
0
static void smsbox_thread(void *arg)
{
    Connection *conn;
    Msg *msg;
    Octstr *os;
    Octstr *reply_msg;
    unsigned long count;
    
    msg = msg_create(sms);
    msg->sms.sender = octstr_create("123");
    msg->sms.receiver = octstr_create("456");
    msg->sms.msgdata = octstr_create("hello world");
    reply_msg = msg_pack(msg);
    msg_destroy(msg);

    gwthread_sleep(1.0);
    conn = conn_open_tcp(bearerbox_host, port_for_smsbox, NULL);
    if (conn == NULL) {
	gwthread_sleep(2.0);
	conn = conn_open_tcp(bearerbox_host, port_for_smsbox, NULL);
    	if (conn == NULL)
	    panic(0, "Couldn't connect to bearerbox as smsbox");
    }

    while (!quitting && conn_wait(conn, -1.0) != -1) {
    	for (;;) {
	    os = conn_read_withlen(conn);
	    if (os == NULL) {
		if (conn_eof(conn) || conn_error(conn))
		    goto error;
		break;
	    }
	    
	    msg = msg_unpack(os);
	    if (msg == NULL || msg->type == wdp_datagram)
		error(0, "Bearerbox sent garbage to smsbox");

	    if (msg->type == sms) {
		if (first_from_bb == (time_t) -1)
		    time(&first_from_bb);
		count = counter_increase(num_from_bearerbox) + 1;
		debug("test.smpp", 0, 
		      "Bearerbox sent sms #%ld <%s> to smsbox, sending reply.",
		      count, octstr_get_cstr(msg->sms.msgdata));
		if (count == max_to_esme)
		    info(0, "Bearerbox has sent all messages to smsbox.");
		conn_write_withlen(conn, reply_msg);
		counter_increase(num_to_bearerbox);
	    }
	    msg_destroy(msg);
	    octstr_destroy(os);
	    time(&last_to_bb);
	}
    }
    
error:
    conn_destroy(conn);
    octstr_destroy(reply_msg);
    debug("test.smpp", 0, "%s terminates.", __func__);
}
Пример #2
0
static void cgw_receiver(SMSCConn *conn, Connection *server)
{
    PrivData *privdata = conn->data;
    Octstr *str = NULL;
    struct cgwop *cgwop;

    while (1) {
        if (conn_eof(server)) {
            info(0, "cgw: receive connection closed by SMSC");
            return ;
        }
        if (conn_error(server)) {
            error(0, "cgw: receive connection broken");
            return ;
        }
        if (conn->is_stopped)
	    str = NULL;

        cgwop = cgw_read_op(conn->data, conn, server, 0);

        if (cgwop != NULL) {
            cgw_handle_op(conn, server, cgwop);
            cgwop_destroy(cgwop);
        } else
            conn_wait(server, -1);

        if (privdata->shutdown)
            break;
    }
    return ;
}
Пример #3
0
static void receive_smpp_thread(void *arg)
{
    ESME *esme;
    Octstr *os;
    long len;
    long sender_id;
    SMPP_PDU *pdu;

    esme = arg;
    
    sender_id = -1;
    len = 0;
    while (!quitting && conn_wait(esme->conn, -1.0) != -1) {
    	for (;;) {
	    if (len == 0) {
		len = smpp_pdu_read_len(esme->conn);
		if (len == -1) {
		    error(0, "Client sent garbage, closing connection.");
		    goto error;
		} else if (len == 0) {
		    if (conn_eof(esme->conn) || conn_error(esme->conn))
		    	goto error;
		    break;
		}
	    }
    
    	    gw_assert(len > 0);
	    os = smpp_pdu_read_data(esme->conn, len);
	    if (os != NULL) {
    	    	len = 0;
		pdu = smpp_pdu_unpack(NULL, os);
		if (pdu == NULL) {
		    error(0, "PDU unpacking failed!");
		    octstr_dump(os, 0);
		} else {
		    handle_pdu(esme, pdu);
		    smpp_pdu_destroy(pdu);
		}
		octstr_destroy(os);
	    } else if (conn_eof(esme->conn) || conn_error(esme->conn))
	    	goto error;
	    else
		break;
	}

    	if (!quitting && esme->receiver && sender_id == -1)
	    sender_id = gwthread_create(send_smpp_thread, esme);
    }

error:
    if (sender_id != -1) {
	quit();
	gwthread_join(sender_id);
    }
    esme_destroy(esme);
    quit();
    debug("test.smpp", 0, "%s terminates.", __func__);
}
Пример #4
0
int read_from_bearerbox_real(Connection *conn, Msg **msg, double seconds)
{
    int ret;
    Octstr *pack;

    pack = NULL;
    *msg = NULL;
    while (program_status != shutting_down) {
        pack = conn_read_withlen(conn);
        gw_claim_area(pack);
        if (pack != NULL)
            break;

        if (conn_error(conn)) {
            error(0, "Error reading from bearerbox, disconnecting.");
            return -1;
        }
        if (conn_eof(conn)) {
            error(0, "Connection closed by the bearerbox.");
            return -1;
        }

        ret = conn_wait(conn, seconds);
        if (ret < 0) {
            error(0, "Connection to bearerbox broke.");
            return -1;
        }
        else if (ret == 1) {
            /* debug("gwlib.gwlib", 0, "Connection to bearerbox timed out after %.2f seconds.", seconds); */
            return 1;
        }
    }

    if (pack == NULL)
        return -1;

    *msg = msg_unpack(pack);
    octstr_destroy(pack);

    if (*msg == NULL) {
        error(0, "Failed to unpack data!");
        return -1;
    }

    return 0;
}
Пример #5
0
static Msg *read_from_box(Boxc *boxconn)
{
    int ret;
    Octstr *pack;
    Msg *msg;

    pack = NULL;
    while (bb_status != BB_DEAD && boxconn->alive) {
            /* XXX: if box doesn't send (just keep conn open) we block here while shutdown */
	    pack = conn_read_withlen(boxconn->conn);
	    gw_claim_area(pack);
	    if (pack != NULL)
	        break;
	    if (conn_error(boxconn->conn)) {
	        info(0, "Read error when reading from box <%s>, disconnecting",
		         octstr_get_cstr(boxconn->client_ip));
	        return NULL;
	    }
	    if (conn_eof(boxconn->conn)) {
	        info(0, "Connection closed by the box <%s>",
		         octstr_get_cstr(boxconn->client_ip));
	        return NULL;
	    }

	    ret = conn_wait(boxconn->conn, -1.0);
	    if (ret < 0) {
	        error(0, "Connection to box <%s> broke.",
		          octstr_get_cstr(boxconn->client_ip));
	        return NULL;
	    }
    }

    if (pack == NULL)
    	return NULL;

    msg = msg_unpack(pack);
    octstr_destroy(pack);

    if (msg == NULL)
	    error(0, "Failed to unpack data!");
    return msg;
}
Пример #6
0
int cgw_wait_command(PrivData *privdata, SMSCConn *conn, Connection *server, int timeout)
{
    int ret;
    struct cgwop *cgwop;

    /* is there data to be read? */
    ret = gwthread_pollfd(privdata->send_socket, POLLIN, 0.2); 
    
    if (ret != -1) {
        /* read all waiting ops */
	cgwop = cgw_read_op(privdata, conn, server, timeout);
        if (cgwop != NULL) {
	    do {
		if (conn_eof(server)) {
		    info(0, "cgw: Connection closed by SMSC");
		    conn->status = SMSCCONN_DISCONNECTED;
		    if (cgwop != NULL) cgwop_destroy(cgwop);
		    return -1;
		}
		if (conn_error(server)) {
		    error(0, "cgw: Error trying to read ACKs from SMSC");
		    if (cgwop != NULL) cgwop_destroy(cgwop);
		    return -1;
		}

		cgw_handle_op(conn, server, cgwop);
		cgwop_destroy(cgwop);
	    } while ((cgwop = cgw_read_op(privdata, conn, server, timeout)) != NULL);
	} else 
	    conn_wait(server, 1); /* added because gwthread_pollfd
				     seems to always return 1. This will keep
				     the load on a reasonable level */
    }

    return 0;
}
Пример #7
0
/* The main program. */
int main(int argc, char **argv) 
{
    Connection *server;
    Octstr *line;
    Octstr **msgs;
    int i;
    int mptr, num_msgs;
    long num_received, num_sent;
    double first_received_at, last_received_at;
    double first_sent_at, last_sent_at;
    double start_time, end_time;
    double delta;
    int interactive, maxfd;
    char *cptr;
    char buffer[IN_BUFSIZE];
    fd_set rset;
    struct timeval alarm;
    FILE *fp;

    gwlib_init();
    setup_signal_handlers();
    host = octstr_create("localhost");
    start_time = get_current_time();

    mptr = get_and_set_debugs(argc, argv, check_args);
    num_msgs = argc - mptr;
		
    interactive = 0;
    msgs = NULL;
    fp = NULL;
    if (num_msgs <= 0) {
        interactive = 1;
        num_msgs = 0;
        info(0, "Entering interactive mode. Type your message on the command line");
        /* set up file pointer to stdin */
        fp = stdin;
        /* initialize set for select */
        FD_ZERO(&rset);	
    } else {
        msgs = gw_malloc(sizeof(Octstr *) * num_msgs);
        for (i = 0; i < num_msgs; i ++) {
            msgs[i] = octstr_create(argv[mptr + i]);
            octstr_append_char(msgs[i], 10); /* End of line */
        }
        info(0, "Host %s Port %d interval %.3f max-messages %ld",
             octstr_get_cstr(host), port, interval, max_send);

        srand((unsigned int) time(NULL));
    }
    info(0, "fakesmsc starting");
    server = conn_open_tcp(host, port, NULL);
    if (server == NULL)
       panic(0, "Failed to open connection");

    num_sent = 0;
    num_received = 0;

    first_received_at = 0;
    first_sent_at = 0;
    last_received_at = 0;
    last_sent_at = 0;

    /* infinitely loop */
    while (1) {
        /* Are we on interactive mode? */ 
        if (interactive == 1) {
            /* Check if we need to clean things up beforehand */
            if ( num_msgs > 0 ) {
                for (i = 0; i < num_msgs; i ++)
                    octstr_destroy(msgs[i]);
                gw_free(msgs);
                num_msgs = 0;
            }

            /* we want either the file pointer or timer */
            FD_SET(fileno(fp), &rset);
            /* get the largest file descriptor */
            maxfd = fileno(fp) + 1;
        
            /* set timer to go off in 3 seconds */
            alarm.tv_sec = IN_TIMEOUT;
            alarm.tv_usec = 0;
        
            if (select(maxfd, &rset, NULL, NULL, &alarm) == -1)
                goto over;
            /* something went off, let's see if it's stdin */
            if (FD_ISSET(fileno(fp), &rset)) { /* stdin is readable */
                cptr = fgets(buffer, IN_BUFSIZE, stdin);
                if( strlen( cptr ) < 2 )
                    goto rcv;
            } else { /* timer kicked in */
                goto rcv;
            }
            num_msgs = 1;
            msgs = gw_malloc(sizeof(Octstr*));
            msgs[0] = octstr_create(cptr);
        }
        /* if we still have something to send as MO message */
        if (num_sent < max_send) {
            Octstr *os = choose_message(msgs, num_msgs);
            Octstr *msg = rnd > 0 ? randomize(os) : os;
 
            if (conn_write(server, msg) == -1)
                panic(0, "write failed");

            ++num_sent;
            if (num_sent == max_send)
                info(0, "fakesmsc: sent message %ld", num_sent);
            else
                debug("send", 0, "fakesmsc: sent message %ld", num_sent);
      
            if (rnd > 0)
                octstr_destroy(msg);

            last_sent_at = get_current_time();
            if (first_sent_at == 0)    
                first_sent_at = last_sent_at;
        }
rcv:
        do {
            delta = interval * num_sent - (get_current_time() - first_sent_at);
            if (delta < 0)
                delta = 0;
            if (num_sent >= max_send)
                delta = -1;
            conn_wait(server, delta);
            if (conn_error(server) || conn_eof(server) || sigint_received)
                goto over;

            /* read as much as the smsc module provides us */
            while ((line = conn_read_line(server))) {
                last_received_at = get_current_time();
                if (first_received_at == 0)
                    first_received_at = last_received_at;
                ++num_received;
                if (num_received == max_send) {
                    info(0, "Got message %ld: <%s>", num_received,
                           octstr_get_cstr(line));
                } else {
                    debug("receive", 0, "Got message %ld: <%s>", num_received,
                          octstr_get_cstr(line));
                }
                octstr_destroy(line);
            }
        } while (delta > 0 || num_sent >= max_send);
    }

over:
    conn_destroy(server);

    /* destroy the MO messages */
    for (i = 0; i < num_msgs; i ++)
        octstr_destroy(msgs[i]);
    gw_free(msgs);

    end_time = get_current_time();

    info(0, "fakesmsc: %ld messages sent and %ld received", num_sent, num_received);
    info(0, "fakesmsc: total running time %.1f seconds", end_time - start_time);
    delta = last_sent_at - first_sent_at;
    if (delta == 0)
        delta = .01;
    if (num_sent > 1)
        info(0, "fakesmsc: from first to last sent message %.1f s, "
                "%.1f msgs/s", delta, (num_sent - 1) / delta);
    delta = last_received_at - first_received_at;
    if (delta == 0)
        delta = .01;
    if (num_received > 1)
        info(0, "fakesmsc: from first to last received message %.1f s, "
                "%.1f msgs/s", delta, (num_received - 1) / delta);
    info(0, "fakesmsc: terminating");
    
    return 0;
}
Пример #8
0
static void main_connection_loop(SMSCConn *conn, Connection *client)
{
    PrivData *privdata = conn->data;
    Octstr *line;
    Msg	*msg;
    double delay = 0;

    if (conn->throughput > 0) {
        delay = 1.0 / conn->throughput;
    }

    while (1) {
        while (!conn->is_stopped && !privdata->shutdown &&
                (line = conn_read_line(client)))
            msg_to_bb(conn, line);
        if (conn_error(client))
            goto error;
        if (conn_eof(client))
            goto eof;

        /* 
         * We won't get DLRs from fakesmsc itself, due that we don't have
         * corresponding message IDs etc. We threat the DLR receiving here. So
         * DLR "originate" from the protocol layer towards abstraction layer.
         * This is all for pure debugging and testing.
         */

        while ((msg = gwlist_extract_first(privdata->outgoing_queue)) != NULL) {

            /* pass msg to fakesmsc daemon */            
            if (sms_to_client(client, msg) == 1) {
                Msg *copy = msg_duplicate(msg);
                
                /* 
                 * Actually no guarantee of it having been really sent,
                 * but I suppose that doesn't matter since this interface
                 * is just for debugging anyway. The upper layer will send
                 * a SMSC success DLR if mask is set. Be aware that msg is
                 * destroyed in abstraction layer, that's why we use a copy
                 * afterwards to handle the final DLR. 
                 */
                bb_smscconn_sent(conn, msg, NULL);

                /* and now the final DLR */
                if (DLR_IS_SUCCESS_OR_FAIL(copy->sms.dlr_mask)) {
                    Msg *dlrmsg;
                    Octstr *tmp;
                    int dlrstat = DLR_SUCCESS;
                    char id[UUID_STR_LEN + 1];

                    uuid_unparse(copy->sms.id, id);
                    tmp = octstr_create(id);
                    dlrmsg = dlr_find(conn->id,
                                      tmp, /* smsc message id */
                                      copy->sms.receiver, /* destination */
                                      dlrstat, 0);
                    if (dlrmsg != NULL) {
                        /* XXX TODO: Provide a SMPP DLR text in msgdata */
                        bb_smscconn_receive(conn, dlrmsg);
                    } else {
                        error(0,"smsc_fale: got DLR but could not find message or "
                        		"was not interested in it");
                    }
                    octstr_destroy(tmp);
                }
                msg_destroy(copy);

            } else {
                bb_smscconn_send_failed(conn, msg,
		            SMSCCONN_FAILED_REJECTED, octstr_create("REJECTED"));
                goto error;
            }

            /* obey throughput speed limit, if any */
            if (conn->throughput > 0) {
                gwthread_sleep(delay);
            }
        }
        if (privdata->shutdown) {
            debug("bb.sms", 0, "smsc_fake shutting down, closing client socket");
            conn_destroy(client);
            return;
        }
        conn_wait(client, -1);
        if (conn_error(client))
            goto error;
        if (conn_eof(client))
            goto eof;
    }
error:
    info(0, "IO error to fakesmsc client. Closing connection.");
    conn_destroy(client);
    return;
eof:
    info(0, "EOF from fakesmsc client. Closing connection.");
    conn_destroy(client);
    return;
}