aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2013-11-29 13:43:44 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2013-12-05 10:27:32 +0100
commit2bee7f96ff46f2f7e563d7aca5c4703214b6cd0e (patch)
treef622fe7005b629bd5654cf845a35a3a96cf1ee79 /openbsc
parenta01bd60851c2d2b613cda6148fb1ca5976887a93 (diff)
mgcp: Add new for_each_line macro that also returns empty lines
This patch add the for_each_line macro based on a strline_r() function (similar to strtok_r()), that is also part of this patch. This strline_r() function is tolerant with respect to line endings, it supports CR-only, CRLF, and LF-only and any combinations thereof (note that a CRLF is always detected as a single line break). Similar to for_each_non_empty_line (the former for_each_line) where the 'save' pointer needed to be initialised by a call to strtok_r(), the new for_each_line macro expects, that the 'save' pointer has been initialised by a call to strline_r(). Also note, that for_each_line/strline_r and for_each_non_empty_line/strtok_r may use the 'save' pointer differently, so calls to them can not be mixed. Sponsored-by: On-Waves ehf
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/src/libmgcp/mgcp_protocol.c32
-rw-r--r--openbsc/tests/mgcp/mgcp_test.c35
-rw-r--r--openbsc/tests/mgcp/mgcp_test.ok13
3 files changed, 80 insertions, 0 deletions
diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c
index c040ab1b4..19a6f5325 100644
--- a/openbsc/src/libmgcp/mgcp_protocol.c
+++ b/openbsc/src/libmgcp/mgcp_protocol.c
@@ -40,6 +40,38 @@
for (line = strtok_r(NULL, "\r\n", &save); line;\
line = strtok_r(NULL, "\r\n", &save))
+#define for_each_line(line, save) \
+ for (line = strline_r(NULL, &save); line;\
+ line = strline_r(NULL, &save))
+
+char *strline_r(char *str, char **saveptr)
+{
+ char *result;
+
+ if (str)
+ *saveptr = str;
+
+ result = *saveptr;
+
+ if (*saveptr != NULL) {
+ *saveptr = strpbrk(*saveptr, "\r\n");
+
+ if (*saveptr != NULL) {
+ char *eos = *saveptr;
+
+ if ((*saveptr)[0] == '\r' && (*saveptr)[1] == '\n')
+ (*saveptr)++;
+ (*saveptr)++;
+ if ((*saveptr)[0] == '\0')
+ *saveptr = NULL;
+
+ *eos = '\0';
+ }
+ }
+
+ return result;
+}
+
/* Assume audio frame length of 20ms */
#define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20
#define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000
diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c
index d36aaa8c6..362f02986 100644
--- a/openbsc/tests/mgcp/mgcp_test.c
+++ b/openbsc/tests/mgcp/mgcp_test.c
@@ -25,6 +25,40 @@
#include <string.h>
#include <limits.h>
+char *strline_r(char *str, char **saveptr);
+
+const char *strline_test_data =
+ "one CR\r"
+ "two CR\r"
+ "\r"
+ "one CRLF\r\n"
+ "two CRLF\r\n"
+ "\r\n"
+ "one LF\n"
+ "two LF\n"
+ "\n"
+ "mixed (4 lines)\r\r\n\n\r\n";
+
+#define EXPECTED_NUMBER_OF_LINES 13
+
+static void test_strline(void)
+{
+ char *save = NULL;
+ char *line;
+ char buf[2048];
+ int counter = 0;
+
+ strncpy(buf, strline_test_data, sizeof(buf));
+
+ for (line = strline_r(buf, &save); line;
+ line = strline_r(NULL, &save)) {
+ printf("line: '%s'\n", line);
+ counter++;
+ }
+
+ OSMO_ASSERT(counter == EXPECTED_NUMBER_OF_LINES);
+}
+
#define AUEP1 "AUEP 158663169 ds/e1-1/2@172.16.6.66 MGCP 1.0\r\n"
#define AUEP1_RET "200 158663169 OK\r\n"
#define AUEP2 "AUEP 18983213 ds/e1-2/1@172.16.6.66 MGCP 1.0\r\n"
@@ -463,6 +497,7 @@ int main(int argc, char **argv)
{
osmo_init_logging(&log_info);
+ test_strline();
test_messages();
test_retransmission();
test_packet_loss_calc();
diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok
index 5666424bd..429e0df68 100644
--- a/openbsc/tests/mgcp/mgcp_test.ok
+++ b/openbsc/tests/mgcp/mgcp_test.ok
@@ -1,3 +1,16 @@
+line: 'one CR'
+line: 'two CR'
+line: ''
+line: 'one CRLF'
+line: 'two CRLF'
+line: ''
+line: 'one LF'
+line: 'two LF'
+line: ''
+line: 'mixed (4 lines)'
+line: ''
+line: ''
+line: ''
Testing AUEP1
Testing AUEP2
Testing MDCX1