Exemple #1
0
static SMPP_PDU *handle_unbind(ESME *esme, SMPP_PDU *pdu)
{
    SMPP_PDU *resp;
    
    resp = smpp_pdu_create(unbind_resp, pdu->u.unbind.sequence_number);
    return resp;
}
Exemple #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__);
}
Exemple #3
0
static SMPP_PDU *handle_bind_receiver(ESME *esme, SMPP_PDU *pdu)
{
    SMPP_PDU *resp;
    
    esme->receiver = 1;
    esme->version = pdu->u.bind_receiver.interface_version;
    resp = smpp_pdu_create(bind_receiver_resp,
    	    	    	    pdu->u.bind_receiver.sequence_number);
#if 0 /* XXX system_id is not implemented in the PDU at the moment */
    resp->u.bind_receiver_resp.system_id = octstr_duplicate(smsc_system_id);
#endif
    return resp;
}
Exemple #4
0
static SMPP_PDU *handle_submit_sm(ESME *esme, SMPP_PDU *pdu)
{
    SMPP_PDU *resp;
    unsigned long id;
    
    debug("test.smpp", 0, "submit_sm: short_message = <%s>",
    	  octstr_get_cstr(pdu->u.submit_sm.short_message));
    id = counter_increase(num_from_esme) + 1;
    if (id == max_to_esme)
    	info(0, "ESME has submitted all messages to SMSC.");
    time(&last_from_esme);

    resp = smpp_pdu_create(submit_sm_resp, pdu->u.submit_sm.sequence_number);
#if 0 /* XXX message_id is not implemented in the PDU at the moment */
    resp->u.submit_sm_resp.message_id = 
    	octstr_format("%ld", counter_increase(message_id_counter));
#endif
    return resp;
}
Exemple #5
0
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; \
                    } \
                    NULTERMINATED(name, opt_len); \
                } 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(""); \
		    error(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) \
    	p->name = decode_integer(data_without_len, pos, octets); \
	pos += octets;
    #define NULTERMINATED(name, max_octets) \
    	p->name = copy_until_nul(data_without_len, &pos, max_octets);
    #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 'short_message', " \
                     "len is %ld but should have been %ld, dropping.", \
                     octstr_len(p->name), p->field_giving_octets); \
            return NULL; \
        } 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;
}
Exemple #6
0
static SMPP_PDU *handle_enquire_link(ESME *esme, SMPP_PDU *pdu)
{
    return smpp_pdu_create(enquire_link_resp, 
    	    	    	   pdu->u.enquire_link.sequence_number);
}
Exemple #7
0
SMPP_PDU *smpp_pdu_unpack(Octstr *smsc_id, 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) { \
                struct smpp_tlv *tlv; \
                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); \
                /* check configured TLVs */ \
                tlv = smpp_tlv_get_by_tag(smsc_id, opt_tag); \
                if (tlv != NULL) debug("sms.smpp", 0, "Found configured optional parameter `%s'", octstr_get_cstr(tlv->name));
    #define TLV_INTEGER(mname, octets) \
                if (SMPP_##mname == opt_tag) { \
                    /* check length */ \
                    if (opt_len > octets) { \
                        error(0, "SMPP: Optional field (%s) with invalid length (%ld) dropped.", #mname, opt_len); \
                        pos += opt_len; \
                        continue; \
                    } \
                    INTEGER(mname, opt_len); \
                    if (tlv != NULL) dict_put(p->tlv, tlv->name, octstr_format("%ld", p->mname)); \
                } else
    #define TLV_NULTERMINATED(mname, max_len) \
                if (SMPP_##mname == opt_tag) { \
                    /* check length */ \
                    if (opt_len > max_len || pos+opt_len > len) { \
                        error(0, "SMPP: Optional field (%s) with invalid length (%ld) dropped.", #mname, opt_len);  \
                        pos += opt_len; \
                        continue; \
                    } \
                    copy_until_nul(#mname, data_without_len, &pos, opt_len, &p->mname); \
                    if (tlv != NULL) dict_put(p->tlv, tlv->name, octstr_duplicate(p->mname)); \
                } else
    #define TLV_OCTETS(mname, min_len, max_len) \
                if (SMPP_##mname == 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.", \
                            #mname, opt_len, min_len, max_len);  \
                        pos += opt_len; \
                        continue; \
                    } \
                    p->mname = octstr_copy(data_without_len, pos, opt_len); \
                    pos += opt_len; \
                    if (tlv != NULL) dict_put(p->tlv, tlv->name, octstr_duplicate(p->mname)); \
                } else
    #define OPTIONAL_END \
                { \
                    Octstr *val = NULL; \
                    if (tlv != NULL) { \
                        /* found configured tlv */ \
                        /* check length */ \
                        if (opt_len > tlv->length) { \
                            error(0, "SMPP: Optional field (%s) with invalid length (%ld) (should be %ld) dropped.", \
                                  octstr_get_cstr(tlv->name), opt_len, tlv->length); \
                            pos += opt_len; \
                            continue; \
                        } \
                        switch (tlv->type) { \
                        case SMPP_TLV_INTEGER: { \
                            long val_i; \
                            if ((val_i = decode_integer(data_without_len, pos, opt_len)) == -1) \
                                goto err; \
                            val = octstr_format("%ld", val_i); \
                            dict_put(p->tlv, tlv->name, val); \
                            pos += opt_len; \
                            break; \
                        } \
                        case SMPP_TLV_OCTETS: { \
                            val = octstr_copy(data_without_len, pos, opt_len); \
                            dict_put(p->tlv, tlv->name, val); \
                            pos += opt_len; \
                            break; \
                        } \
                        case SMPP_TLV_NULTERMINATED: { \
                            if (copy_until_nul(octstr_get_cstr(tlv->name), data_without_len, &pos, opt_len, &val) == 0) \
                                dict_put(p->tlv, tlv->name, val); \
                            break; \
                        } \
                        default: \
                            panic(0, "SMPP: Internal error, unknown configured TLV type %d.", tlv->type); \
                            break; \
                        } \
                    }  else { \
                        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); \
                        octstr_destroy(val); \
                        pos += opt_len; \
                    } \
                } \
            } \
        }
    #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 0x%08lx, internal error while unpacking.", type);
    	break;
    }

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