📄 smpp_pdu.c
字号:
default: error(0, "Unknown SMPP_PDU type, internal error while packing."); } temp = octstr_create(""); append_encoded_integer(temp, octstr_len(os) + 4, 4); octstr_insert(os, temp, 0); octstr_destroy(temp); return os;}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;}void smpp_pdu_dump(SMPP_PDU *pdu){ debug("sms.smpp", 0, "SMPP PDU %p dump:", (void *) pdu); debug("sms.smpp", 0, " type_name: %s", pdu->type_name); switch (pdu->type) { #define OPTIONAL_BEGIN #define TLV_INTEGER(name, max_len) \ if (p->name != -1) { \ INTEGER(name, max_len) \ } #define TLV_NULTERMINATED(name, max_len) \ if (p->name != NULL) { \ NULTERMINATED(name, max_len) \ } #define TLV_OCTETS(name, min_len, max_len) \ if (p->name != NULL) { \ OCTETS(name, max_len) \ } #define OPTIONAL_END #define INTEGER(name, octets) \ debug("sms.smpp", 0, " %s: %lu = 0x%08lx", #name, p->name, p->name); #define NULTERMINATED(name, max_octets) \ octstr_dump_short(p->name, 2, #name); #define OCTETS(name, field_giving_octets) \ octstr_dump_short(p->name, 2, #name); #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."); break; } debug("sms.smpp", 0, "SMPP PDU dump ends.");}long smpp_pdu_read_len(Connection *conn){ Octstr *os; char buf[4]; /* The length is 4 octets. */ long len; os = conn_read_fixed(conn, sizeof(buf)); if (os == NULL) return 0; octstr_get_many_chars(buf, os, 0, sizeof(buf)); octstr_destroy(os); len = decode_network_long(buf); if (len < MIN_SMPP_PDU_LEN) { error(0, "SMPP: PDU length was too small (%ld, minimum is %ld).", len, (long) MIN_SMPP_PDU_LEN); return -1; } if (len > MAX_SMPP_PDU_LEN) { error(0, "SMPP: PDU length was too large (%ld, maximum is %ld).", len, (long) MAX_SMPP_PDU_LEN); return -1; } return len;}Octstr *smpp_pdu_read_data(Connection *conn, long len){ Octstr *os; os = conn_read_fixed(conn, len - 4); /* `len' includes itself. */ return os;}/* * Return error string for given error code * NOTE: If you add new error strings here please use * error strings from SMPP spec. and please keep * error codes in switch statement sorted by error * code ID. */const char *smpp_error_to_string(enum SMPP_ERROR_MESSAGES error){ switch (error) { case SMPP_ESME_ROK: return "OK"; case SMPP_ESME_RINVMSGLEN: return "Message Length is invalid"; case SMPP_ESME_RINVCMDLEN: return "Command Length is invalid"; case SMPP_ESME_RINVCMDID: return "Invalid Command ID"; case SMPP_ESME_RINVBNDSTS: return "Incorrect BIND Status for given command"; case SMPP_ESME_RALYNBD: return "ESME Already in Bound State"; case SMPP_ESME_RINVREGDLVFLG: return "Invalid Registered Delivery Flag"; case SMPP_ESME_RSYSERR: return "System Error"; case SMPP_ESME_RINVSRCADR: return "Invalid Source Address"; case SMPP_ESME_RINVDSTADR: return "Invalid Dest Address"; case SMPP_ESME_RBINDFAIL: return "Bind Failed"; case SMPP_ESME_RINVPASWD: return "Invalid Password"; case SMPP_ESME_RINVSYSID: return "Invalid System ID"; case SMPP_ESME_RMSGQFUL: return "Message Queue Full"; case SMPP_ESME_RINVESMCLASS: return "Invalid esm_class field data"; case SMPP_ESME_RINVSRCTON: return "Invalid Source Address TON"; case SMPP_ESME_RTHROTTLED: return "Throttling error"; case SMPP_ESME_RINVSCHED: return "Invalid Scheduled Delivery Time"; case SMPP_ESME_RINVEXPIRY: return "Invalid message validity period"; case SMPP_ESME_RX_T_APPN: return "ESME Receiver Temporary App Error Code"; case SMPP_ESME_RX_P_APPN: return "ESME Receiver Permanent App Error Code"; case SMPP_ESME_RX_R_APPN: return "ESME Receiver Reject Message Error Code"; case SMPP_ESME_ROPTPARNOTALLWD: return "Optional Parameter not allowed"; case SMPP_ESME_RUNKNOWNERR: return "Unknown Error"; default: return "Unknown/Reserved"; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -