예제 #1
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__);
}
예제 #2
0
static void send_smpp_thread(void *arg)
{
    ESME *esme;
    Octstr *os;
    SMPP_PDU *pdu;
    unsigned long id;

    esme = arg;
    
    id = 0;
    while (!quitting && counter_value(num_to_esme) < max_to_esme) {
        id = counter_increase(num_to_esme) + 1;
        while (!quitting && counter_value(num_from_esme) + 500 < id)
            gwthread_sleep(1.0);
        if (quitting)
            break;
        pdu = smpp_pdu_create(deliver_sm, counter_increase(message_id_counter));
        pdu->u.deliver_sm.source_addr = octstr_create("456");
        pdu->u.deliver_sm.destination_addr = octstr_create("123");
        pdu->u.deliver_sm.short_message = octstr_format("%ld", id);
        if (esme->version > 0x33)
            pdu->u.deliver_sm.receipted_message_id = octstr_create("receipted_message_id\0");
        os = smpp_pdu_pack(NULL, pdu);
        conn_write(esme->conn, os);
        octstr_destroy(os);
        smpp_pdu_destroy(pdu);
        if (first_to_esme == (time_t) -1)
            time(&first_to_esme);
        debug("test.smpp", 0, "Delivered SMS %ld of %ld to bearerbox via SMPP.",
              id, max_to_esme);

        if ((id % enquire_interval) == 0) {
            pdu = smpp_pdu_create(enquire_link, counter_increase(message_id_counter));
            os = smpp_pdu_pack(NULL, pdu);
            conn_write(esme->conn, os);
            octstr_destroy(os);
            smpp_pdu_destroy(pdu);
            debug("test.smpp", 0, "Sent enquire_link to bearerbox.");
        }
    }
    time(&last_to_esme);
    if (id == max_to_esme)
	info(0, "All messages sent to ESME.");
    debug("test.smpp", 0, "%s terminates.", __func__);
}
예제 #3
0
static void handle_pdu(ESME *esme, SMPP_PDU *pdu)
{
    SMPP_PDU *resp;
    Octstr *os;
    int i;

    debug("test.smpp", 0, "Handling SMPP PDU of type %s", pdu->type_name);
    for (i = 0; i < num_handlers; ++i) {
    	if (handlers[i].type == pdu->type) {
	    resp = handlers[i].handler(esme, pdu);
	    if (resp != NULL) {
	    	os = smpp_pdu_pack(NULL, resp);
		conn_write(esme->conn, os);
		octstr_destroy(os);
		smpp_pdu_destroy(resp);
	    }
	    return;
	}
    }

    error(0, "Unhandled SMPP PDU.");
    smpp_pdu_dump(octstr_imm(""), pdu);
}
예제 #4
0
파일: smpp_pdu.c 프로젝트: frese/mbuni
SMPP_PDU *smpp_pdu_unpack(Octstr *data_without_len)
{
    SMPP_PDU *pdu;
    unsigned long type;
    long len, pos;

    len = octstr_len(data_without_len);

    if (len < 4) {
        error(0, "SMPP: PDU was too short (%ld bytes).",
              octstr_len(data_without_len));
        return NULL;
    }

    /* get the PDU type */
    if ((type = decode_integer(data_without_len, 0, 4)) == -1)
        return NULL;

    /* create a coresponding representation structure */
    pdu = smpp_pdu_create(type, 0);
    if (pdu == NULL)
        return NULL;

    pos = 0;

    switch (type) {
    #define OPTIONAL_BEGIN  \
        {   /* Read optional parameters */  \
            while (pos + 4 <= len) { \
                unsigned long opt_tag, opt_len; \
                opt_tag = decode_integer(data_without_len, pos, 2); pos += 2; \
                debug("sms.smpp", 0, "Optional parameter tag (0x%04lx)", opt_tag);   \
                opt_len = decode_integer(data_without_len, pos, 2); pos += 2;  \
                debug("sms.smpp", 0, "Optional parameter length read as %ld", opt_len);
    #define TLV_INTEGER(name, octets) \
                if (SMPP_##name == opt_tag) { \
                    /* check length */ \
                    if (opt_len > octets) { \
                        error(0, "SMPP: Optional field (%s) with invalid length (%ld) dropped.", #name, opt_len); \
                        pos += opt_len; \
                        continue; \
                    } \
                    INTEGER(name, opt_len); \
                } else
    #define TLV_NULTERMINATED(name, max_len) \
                if (SMPP_##name == opt_tag) { \
                    /* check length */ \
                    if (opt_len > max_len || pos+opt_len > len) { \
                        error(0, "SMPP: Optional field (%s) with invalid length (%ld) dropped.", #name, opt_len);  \
                        pos += opt_len; \
                        continue; \
                    } \
                    copy_until_nul(#name, data_without_len, &pos, opt_len, &p->name); \
                } else
    #define TLV_OCTETS(name, min_len, max_len) \
                if (SMPP_##name == opt_tag) { \
                    /* check length */ \
                    if (opt_len < min_len || opt_len > max_len || pos + opt_len > len) { \
                        error(0, "SMPP: Optional field (%s) with invalid length (%ld) (should be %d - %d) dropped.", \
                            #name, opt_len, min_len, max_len);  \
                        pos += opt_len; \
                        continue; \
                    } \
                    p->name = octstr_copy(data_without_len, pos, opt_len); \
                    pos += opt_len; \
                } else
    #define OPTIONAL_END \
                { \
                    Octstr *val = octstr_copy(data_without_len, pos, opt_len); \
                    if (val) octstr_binary_to_hex(val, 0); \
                    else val = octstr_create(""); \
                    warning(0, "SMPP: Unknown TLV(0x%04lx,0x%04lx,%s) for PDU type (%s) received!", \
                            opt_tag, opt_len, octstr_get_cstr(val), pdu->type_name); \
                    pos += opt_len; \
                    octstr_destroy(val); \
                } \
            } \
        }
    #define INTEGER(name, octets) \
        if ((p->name = decode_integer(data_without_len, pos, octets)) == -1) \
            goto err; \
        pos += octets;
    #define NULTERMINATED(name, max_octets) \
        /* just warn about errors but not fail */ \
        copy_until_nul(#name, data_without_len, &pos, max_octets, &p->name);
    #define OCTETS(name, field_giving_octets) \
    	p->name = octstr_copy(data_without_len, pos, \
	    	    	      p->field_giving_octets); \
        if (p->field_giving_octets != (unsigned long) octstr_len(p->name)) { \
            error(0, "smpp_pdu: error while unpacking '" #name "', " \
                     "len is %ld but should have been %ld, dropping.", \
                     octstr_len(p->name), p->field_giving_octets); \
            goto err; \
        } else { \
            pos += p->field_giving_octets; \
        }
    #define PDU(name, id, fields) \
    	case id: { struct name *p = &pdu->u.name; fields } break;
    #include "smpp_pdu.def"
    default:
    	error(0, "Unknown SMPP_PDU type, internal error while unpacking.");
    }

    return pdu;
    
err:
    smpp_pdu_destroy(pdu);
    octstr_dump(data_without_len, 0);
    return NULL;
}