diff --git a/trunk/src/app/srs_app_listener.cpp b/trunk/src/app/srs_app_listener.cpp index 7094bdbcf..ac5a0d6b3 100755 --- a/trunk/src/app/srs_app_listener.cpp +++ b/trunk/src/app/srs_app_listener.cpp @@ -48,9 +48,6 @@ using namespace std; // sleep in srs_utime_t for udp recv packet. #define SrsUdpPacketRecvCycleInterval 0 -// Set the byte at specified position. -#define _srs_set_byte(data, size, b, index) if (index < size) b = data[index] - ISrsUdpHandler::ISrsUdpHandler() { } @@ -549,9 +546,7 @@ srs_error_t SrsUdpMuxListener::cycle() // Append more information. if (true) { char* data = skt.data(); int size = skt.size(); - uint8_t b0 = 0, b1 = 0; _srs_set_byte(data, size, b0, 0); _srs_set_byte(data, size, b1, 1); uint8_t b2 = 0, b3 = 0; _srs_set_byte(data, size, b2, 2); _srs_set_byte(data, size, b3, 3); - uint8_t b4 = 0, b5 = 0; _srs_set_byte(data, size, b4, 4); _srs_set_byte(data, size, b5, 5); uint8_t b6 = 0, b7 = 0; _srs_set_byte(data, size, b6, 6); _srs_set_byte(data, size, b7, 7); - err = srs_error_wrap(err, "size=%u, data=[%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x]", size, b0, b1, b2, b3, b4, b5, b6, b7); + err = srs_error_wrap(err, "size=%u, data=[%s]", size, srs_string_dumps_hex(data, size, 8).c_str()); } srs_warn("handle udp pkt, count=%u, err: %s", pp_pkt_handler_err->nn_count, srs_error_desc(err).c_str()); } diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 5b7eda79b..18cc80b35 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -543,8 +543,10 @@ srs_error_t SrsRtcPlayStream::on_rtcp(char* data, int nb_data) { srs_error_t err = srs_success; + // TODO: Use SrsBuffer to parse it. char* ph = data; int nb_left = nb_data; + while (nb_left) { uint8_t payload_type = ph[1]; uint16_t length_4bytes = (((uint16_t)ph[2]) << 8) | ph[3]; @@ -552,7 +554,8 @@ srs_error_t SrsRtcPlayStream::on_rtcp(char* data, int nb_data) int length = (length_4bytes + 1) * 4; if (length > nb_data) { - return srs_error_new(ERROR_RTC_RTCP, "invalid rtcp packet, length=%u", length); + return srs_error_new(ERROR_RTC_RTCP, "invalid length=%u/%u, left=%u, bytes=%s", + length, nb_data, nb_left, srs_string_dumps_hex(ph, nb_left, 8).c_str()); } srs_verbose("on rtcp, payload_type=%u", payload_type); @@ -594,7 +597,7 @@ srs_error_t SrsRtcPlayStream::on_rtcp(char* data, int nb_data) } if (err != srs_success) { - return srs_error_wrap(err, "rtcp"); + return srs_error_wrap(err, "rtcp left=%u, bytes=%s", nb_left, srs_string_dumps_hex(ph, nb_left, 8).c_str()); } ph += length; diff --git a/trunk/src/app/srs_app_utility.cpp b/trunk/src/app/srs_app_utility.cpp index da186efb3..a6c72f722 100644 --- a/trunk/src/app/srs_app_utility.cpp +++ b/trunk/src/app/srs_app_utility.cpp @@ -1281,37 +1281,51 @@ void srs_api_dump_summaries(SrsJsonObject* obj) sys->set("conn_srs", SrsJsonAny::integer(nrs->nb_conn_srs)); } -string srs_string_dumps_hex(const std::string& str, const int& limit) +string srs_string_dumps_hex(const std::string& str) { - return srs_string_dumps_hex(str.c_str(), str.size(), limit); + return srs_string_dumps_hex(str.c_str(), str.size()); } -string srs_string_dumps_hex(const char* buf, const int length, const int& limit) +string srs_string_dumps_hex(const char* str, int length) { - string ret; + return srs_string_dumps_hex(str, length, INT_MAX); +} - char tmp_buf[1024*16]; - tmp_buf[0] = '\n'; - int len = 1; - - for (int i = 0; i < length && i < limit; ++i) { - int nb = snprintf(tmp_buf + len, sizeof(tmp_buf) - len - 2, "%02X ", (uint8_t)buf[i]); - if (nb <= 0) +string srs_string_dumps_hex(const char* str, int length, int limit) +{ + return srs_string_dumps_hex(str, length, limit, ' ', 128, '\n'); +} + +string srs_string_dumps_hex(const char* str, int length, int limit, char seperator, int line_limit, char newline) +{ + const int LIMIT = 1024*16; + static char buf[LIMIT]; + + int len = 0; + for (int i = 0; i < length && i < limit && i < LIMIT; ++i) { + int nb = snprintf(buf + len, LIMIT - len, "%02x", (uint8_t)str[i]); + if (nb < 0 || nb > LIMIT - len) { break; + } + len += nb; - len += nb; + // Only append seperator and newline when not last byte. + if (i < length - 1 && i < limit - 1 && i < LIMIT - 1) { + if (seperator && len < LIMIT) { + buf[len++] = seperator; + } - if (i % 48 == 47) { - tmp_buf[len++] = '\n'; - ret.append(tmp_buf, len); - len = 0; - } - } - tmp_buf[len] = '\0'; - ret.append(tmp_buf, len); - - return ret; + if (newline && line_limit && i > 0 && ((i + 1) % line_limit) == 0 && len < LIMIT) { + buf[len++] = newline; + } + } + } + // Empty string. + if (len <= 0) { + return ""; + } + return string(buf, len); } string srs_getenv(string key) diff --git a/trunk/src/app/srs_app_utility.hpp b/trunk/src/app/srs_app_utility.hpp index a4a73ef54..63bfef577 100644 --- a/trunk/src/app/srs_app_utility.hpp +++ b/trunk/src/app/srs_app_utility.hpp @@ -652,8 +652,11 @@ extern bool srs_is_boolean(std::string str); extern void srs_api_dump_summaries(SrsJsonObject* obj); // Dump string(str in length) to hex, it will process min(limit, length) chars. -extern std::string srs_string_dumps_hex(const std::string& str, const int& limit = INT_MAX); -extern std::string srs_string_dumps_hex(const char* str, const int length, const int& limit = INT_MAX); +// Append seperator between each elem, and newline when exceed line_limit, '\0' to ignore. +extern std::string srs_string_dumps_hex(const std::string& str); +extern std::string srs_string_dumps_hex(const char* str, int length); +extern std::string srs_string_dumps_hex(const char* str, int length, int limit); +extern std::string srs_string_dumps_hex(const char* str, int length, int limit, char seperator, int line_limit, char newline); // Get ENV variable, which may starts with $. // srs_getenv("EIP") === srs_getenv("$EIP") diff --git a/trunk/src/utest/srs_utest_rtc.cpp b/trunk/src/utest/srs_utest_rtc.cpp index 1d22ac897..9621f5d40 100644 --- a/trunk/src/utest/srs_utest_rtc.cpp +++ b/trunk/src/utest/srs_utest_rtc.cpp @@ -25,6 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include #include #include #include @@ -128,6 +129,41 @@ VOID TEST(KernelRTCTest, SequenceCompare) } } +VOID TEST(KernelRTCTest, DumpsHexToString) +{ + if (true) { + EXPECT_STREQ("", srs_string_dumps_hex(NULL, 0).c_str()); + } + + if (true) { + uint8_t data[] = {0, 0, 0, 0}; + EXPECT_STREQ("00 00 00 00", srs_string_dumps_hex((const char*)data, sizeof(data)).c_str()); + } + + if (true) { + uint8_t data[] = {0, 1, 2, 3}; + EXPECT_STREQ("00 01 02 03", srs_string_dumps_hex((const char*)data, sizeof(data)).c_str()); + } + + if (true) { + uint8_t data[] = {0xa, 3, 0xf, 3}; + EXPECT_STREQ("0a 03 0f 03", srs_string_dumps_hex((const char*)data, sizeof(data)).c_str()); + } + + if (true) { + uint8_t data[] = {0xa, 3, 0xf, 3}; + EXPECT_STREQ("0a,03,0f,03", srs_string_dumps_hex((const char*)data, sizeof(data), INT_MAX, ',', 0, 0).c_str()); + EXPECT_STREQ("0a030f03", srs_string_dumps_hex((const char*)data, sizeof(data), INT_MAX, '\0', 0, 0).c_str()); + EXPECT_STREQ("0a,03,\n0f,03", srs_string_dumps_hex((const char*)data, sizeof(data), INT_MAX, ',', 2, '\n').c_str()); + EXPECT_STREQ("0a,03,0f,03", srs_string_dumps_hex((const char*)data, sizeof(data), INT_MAX, ',', 2,'\0').c_str()); + } + + if (true) { + uint8_t data[] = {0xa, 3, 0xf}; + EXPECT_STREQ("0a 03", srs_string_dumps_hex((const char*)data, sizeof(data), 2).c_str()); + } +} + extern bool srs_is_stun(const uint8_t* data, size_t size); extern bool srs_is_dtls(const uint8_t* data, size_t len); extern bool srs_is_rtp_or_rtcp(const uint8_t* data, size_t len);