Browse code

Refurbished event header field parser.

This is a new refurbished version of the Event header parser which adds
support for extra event packages and parameters needed by kamailio
presence modules, however both the implementation and the parser API
are different. It turned out that the original k. event parser (which
is an extended version of the same parser in ser) did not parse dialog
event packages correctly. The parser relies on the recently added
extensions to the generic parameter parser.

First off, the event structure contains different fields now, field
text has been renamed to name and field parsed has been renamed to type.
In addition that that there is a new structure dialog which contains
the linked list of all parsed parameters in variable list and pointers
to well known dialog event package parameters in structure dialog.

The test for the presence of the sla dialog event parameter would then
look like this:

if (e->type == EVENT_DIALOG && e->params.dialog.sla) ...

Support for new event types can be easily added by extending the global
variable events in parse_event.c, previously it was necessary to modify
the parser function, in the refurbished version it is sufficient just
to add a new element in the array and define a new event type in
parse_event.h

The original k. version handled "dialog;sla" and "dialog" as different
event types. This is no more so, in both cases event->type will be set
to EVENT_DIALOG and the caller can descriminate them by testing for
the presence of the sla parameter as described in the text above.

Function free_event has been modified to free the linked list of parsed
parameters in event->params.list.

Jan Janak authored on 17/03/2009 16:41:19
Showing 2 changed files
... ...
@@ -44,18 +44,19 @@
44 44
 #include <stdio.h>         /* printf */
45 45
 #include "../ut.h"
46 46
 
47
-
48
-#define PRES_STR "presence"
49
-#define PRES_STR_LEN 8
50
-
51
-#define PRES_WINFO_STR "presence.winfo"
52
-#define PRES_WINFO_STR_LEN 14
53
-
54
-#define PRES_XCAP_CHANGE_STR "xcap-change"
55
-#define PRES_XCAP_CHANGE_STR_LEN 11
56
-
57
-#define PRES_SIP_PROFILE_STR "sip-profile"
58
-#define PRES_SIP_PROFILE_STR_LEN 11
47
+static struct {
48
+	str name;
49
+	int type;	
50
+} events[] = {
51
+	{STR_STATIC_INIT("presence"),        EVENT_PRESENCE},
52
+	{STR_STATIC_INIT("presence.winfo"),  EVENT_PRESENCE_WINFO},
53
+	{STR_STATIC_INIT("xcap-change"),     EVENT_XCAP_CHANGE},
54
+	{STR_STATIC_INIT("sip-profile"),     EVENT_SIP_PROFILE},
55
+	{STR_STATIC_INIT("message-summary"), EVENT_MESSAGE_SUMMARY},
56
+	{STR_STATIC_INIT("dialog"),          EVENT_DIALOG},
57
+	/* The following must be the last element in the array */
58
+	{STR_NULL,                           EVENT_OTHER}
59
+};
59 60
 
60 61
 
61 62
 static inline char* skip_token(char* _b, int _l)
... ...
@@ -77,41 +78,58 @@ static inline char* skip_token(char* _b, int _l)
77 78
 }
78 79
 
79 80
 
80
-static inline int event_parser(char* _s, int _l, event_t* _e)
81
+int event_parser(char* s, int len, event_t* e)
81 82
 {
83
+	int i;
82 84
 	str tmp;
83 85
 	char* end;
86
+	param_hooks_t* phooks = NULL;
87
+	enum pclass pclass = CLASS_ANY;
84 88
 
85
-	tmp.s = _s;
86
-	tmp.len = _l;
89
+	if (e == NULL) {
90
+		ERR("event_parser: Invalid parameter value\n");
91
+		return -1;
92
+	}
87 93
 
94
+	tmp.s = s;
95
+	tmp.len = len;
88 96
 	trim_leading(&tmp);
89 97
 
90 98
 	if (tmp.len == 0) {
91
-		LOG(L_ERR, "event_parser(): Empty body\n");
99
+		LOG(L_ERR, "event_parser: Empty body\n");
92 100
 		return -1;
93 101
 	}
94 102
 
95
-	_e->text.s = tmp.s;
96
-
103
+	e->name.s = tmp.s;
97 104
 	end = skip_token(tmp.s, tmp.len);
105
+	e->name.len = end - tmp.s;
106
+
107
+	e->type = EVENT_OTHER;
108
+	for(i = 0; events[i].name.len; i++) {
109
+		if (e->name.len == events[i].name.len &&
110
+			!strncasecmp(e->name.s, events[i].name.s, e->name.len)) {
111
+			e->type = events[i].type;
112
+			break;
113
+		}
114
+	}
115
+
116
+	tmp.len -= end - tmp.s;
117
+	tmp.s = end;
118
+	trim_leading(&tmp);
119
+
120
+	if (tmp.s[0] == ';') {
121
+		/* We have parameters to parse */
122
+		if (e->type == EVENT_DIALOG) {
123
+			pclass = CLASS_EVENT_DIALOG;
124
+			phooks = (param_hooks_t*)&e->params.dialog;
125
+		}
98 126
 
99
-	_e->text.len = end - tmp.s;
100
-
101
-	if ((_e->text.len == PRES_STR_LEN) && 
102
-	    !strncasecmp(PRES_STR, tmp.s, _e->text.len)) {
103
-		_e->parsed = EVENT_PRESENCE;
104
-	} else if ((_e->text.len == PRES_XCAP_CHANGE_STR_LEN) && 
105
-		   !strncasecmp(PRES_XCAP_CHANGE_STR, tmp.s, _e->text.len)) {
106
-		_e->parsed = EVENT_XCAP_CHANGE;
107
-	} else if ((_e->text.len == PRES_WINFO_STR_LEN) && 
108
-		   !strncasecmp(PRES_WINFO_STR, tmp.s, _e->text.len)) {
109
-		_e->parsed = EVENT_PRESENCE_WINFO;
110
-	} else if ((_e->text.len == PRES_SIP_PROFILE_STR_LEN) && 
111
-		   !strncasecmp(PRES_SIP_PROFILE_STR, tmp.s, _e->text.len)) {
112
-		_e->parsed = EVENT_SIP_PROFILE;
127
+		if (parse_params(&tmp, pclass, phooks, &e->params.list) < 0) {
128
+			ERR("event_parser: Error while parsing parameters parameters\n");
129
+			return -1;
130
+		}
113 131
 	} else {
114
-		_e->parsed = EVENT_OTHER;
132
+		e->params.list = NULL;
115 133
 	}
116 134
 
117 135
 	return 0;
... ...
@@ -153,19 +171,24 @@ int parse_event(struct hdr_field* _h)
153 171
  */
154 172
 void free_event(event_t** _e)
155 173
 {
156
-	if (*_e) pkg_free(*_e);
157
-	*_e = 0;
174
+	if (*_e) {
175
+		if ((*_e)->params.list) free_params((*_e)->params.list);
176
+		pkg_free(*_e);
177
+		*_e = NULL;
178
+	}
158 179
 }
159 180
 
160 181
 
161 182
 /*
162 183
  * Print structure, for debugging only
163 184
  */
164
-void print_event(event_t* _e)
185
+void print_event(event_t* e)
165 186
 {
166 187
 	printf("===Event===\n");
167
-	printf("text  : \'%.*s\'\n", _e->text.len, ZSW(_e->text.s));
168
-	printf("parsed: %s\n", 
169
-	       (_e->parsed == EVENT_PRESENCE) ? ("EVENT_PRESENCE") : ("EVENT_OTHER"));
188
+	printf("name  : \'%.*s\'\n", STR_FMT(&e->name));
189
+	printf("type: %d\n", e->type);
190
+	if (e->params.list) {
191
+		print_params(stdout, e->params.list);
192
+	}
170 193
 	printf("===/Event===\n");
171 194
 }
... ...
@@ -1,12 +1,6 @@
1 1
 /*
2 2
  * $Id$
3 3
  *
4
- * Event header field body parser
5
- * This parser was written for Presence Agent module only.
6
- * it recognizes presence package only, no subpackages, no parameters
7
- * It should be replaced by a more generic parser if subpackages or
8
- * parameters should be parsed too.
9
- *
10 4
  * Copyright (C) 2001-2003 FhG Fokus
11 5
  *
12 6
  * This file is part of ser, a free SIP server.
... ...
@@ -37,35 +31,51 @@
37 31
 
38 32
 #include "../str.h"
39 33
 #include "hf.h"
34
+#include "parse_param.h"
35
+
36
+/* Recognized event types */
37
+enum event_type {
38
+	EVENT_OTHER = 0,
39
+	EVENT_PRESENCE,
40
+	EVENT_PRESENCE_WINFO,
41
+	EVENT_SIP_PROFILE,
42
+	EVENT_XCAP_CHANGE,
43
+	EVENT_DIALOG,
44
+	EVENT_MESSAGE_SUMMARY
45
+};
46
+
47
+
48
+struct event_params {
49
+	struct event_dialog_hooks dialog; /* Well known dialog package params */
50
+	param_t* list; /* Linked list of all parsed parameters */
51
+};
40 52
 
41
-#define EVENT_OTHER          0
42
-#define EVENT_PRESENCE       1
43
-#define EVENT_PRESENCE_WINFO 2
44
-#define EVENT_SIP_PROFILE    3
45
-#define EVENT_XCAP_CHANGE    4
46 53
 
47 54
 typedef struct event {
48
-	str text;       /* Original string representation */
49
-	int parsed;     /* Parsed variant */
55
+	enum event_type type; /* Parsed variant */
56
+	str name;             /* Original string representation */
57
+	struct event_params params;
50 58
 } event_t;
51 59
 
52 60
 
53 61
 /*
54 62
  * Parse Event HF body
55 63
  */
56
-int parse_event(struct hdr_field* _h);
64
+int parse_event(struct hdr_field* hf);
57 65
 
58 66
 
59 67
 /*
60 68
  * Release memory
61 69
  */
62
-void free_event(event_t** _e);
70
+void free_event(event_t** e);
63 71
 
64 72
 
65 73
 /*
66 74
  * Print structure, for debugging only
67 75
  */
68
-void print_event(event_t* _e);
76
+void print_event(event_t* e);
77
+
78
+int event_parser(char* s, int l, event_t* e);
69 79
 
70 80
 
71 81
 #endif /* PARSE_EVENT_H */