[SR-Dev] git:master: Refurbished event header field parser.
Jan Janak
jan at iptel.org
Fri Mar 20 10:21:30 CET 2009
Yes, of course, on their respective branches. This change was done to make the
presence_* modules work with sr.
Jan.
On 20-03 10:14, Klaus Darilion wrote:
> Hi Jan!
>
> Have you also upated the affected modules (presence_dialoginfo ....)?
>
> regards
> klaus
>
> Jan Janak schrieb:
>> Module: sip-router
>> Branch: master
>> Commit: 1ee365faf8047d7a921da5a0bf5cc7d20f766a27
>> URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=1ee365faf8047d7a921da5a0bf5cc7d20f766a27
>>
>> Author: Jan Janak <jan at iptel.org>
>> Committer: Jan Janak <jan at iptel.org>
>> Date: Tue Mar 17 17:41:19 2009 +0100
>>
>> 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.
>>
>> ---
>>
>> parser/parse_event.c | 101 ++++++++++++++++++++++++++++++-------------------
>> parser/parse_event.h | 42 +++++++++++++--------
>> 2 files changed, 88 insertions(+), 55 deletions(-)
>>
>> diff --git a/parser/parse_event.c b/parser/parse_event.c
>> index 75b7017..98ca5e5 100644
>> --- a/parser/parse_event.c
>> +++ b/parser/parse_event.c
>> @@ -44,18 +44,19 @@
>> #include <stdio.h> /* printf */
>> #include "../ut.h"
>> -
>> -#define PRES_STR "presence"
>> -#define PRES_STR_LEN 8
>> -
>> -#define PRES_WINFO_STR "presence.winfo"
>> -#define PRES_WINFO_STR_LEN 14
>> -
>> -#define PRES_XCAP_CHANGE_STR "xcap-change"
>> -#define PRES_XCAP_CHANGE_STR_LEN 11
>> -
>> -#define PRES_SIP_PROFILE_STR "sip-profile"
>> -#define PRES_SIP_PROFILE_STR_LEN 11
>> +static struct {
>> + str name;
>> + int type;
>> +} events[] = {
>> + {STR_STATIC_INIT("presence"), EVENT_PRESENCE},
>> + {STR_STATIC_INIT("presence.winfo"), EVENT_PRESENCE_WINFO},
>> + {STR_STATIC_INIT("xcap-change"), EVENT_XCAP_CHANGE},
>> + {STR_STATIC_INIT("sip-profile"), EVENT_SIP_PROFILE},
>> + {STR_STATIC_INIT("message-summary"), EVENT_MESSAGE_SUMMARY},
>> + {STR_STATIC_INIT("dialog"), EVENT_DIALOG},
>> + /* The following must be the last element in the array */
>> + {STR_NULL, EVENT_OTHER}
>> +};
>> static inline char* skip_token(char* _b, int _l)
>> @@ -77,41 +78,58 @@ static inline char* skip_token(char* _b, int _l)
>> }
>> -static inline int event_parser(char* _s, int _l, event_t* _e)
>> +int event_parser(char* s, int len, event_t* e)
>> {
>> + int i;
>> str tmp;
>> char* end;
>> + param_hooks_t* phooks = NULL;
>> + enum pclass pclass = CLASS_ANY;
>> - tmp.s = _s;
>> - tmp.len = _l;
>> + if (e == NULL) {
>> + ERR("event_parser: Invalid parameter value\n");
>> + return -1;
>> + }
>> + tmp.s = s;
>> + tmp.len = len;
>> trim_leading(&tmp);
>> if (tmp.len == 0) {
>> - LOG(L_ERR, "event_parser(): Empty body\n");
>> + LOG(L_ERR, "event_parser: Empty body\n");
>> return -1;
>> }
>> - _e->text.s = tmp.s;
>> -
>> + e->name.s = tmp.s;
>> end = skip_token(tmp.s, tmp.len);
>> + e->name.len = end - tmp.s;
>> +
>> + e->type = EVENT_OTHER;
>> + for(i = 0; events[i].name.len; i++) {
>> + if (e->name.len == events[i].name.len &&
>> + !strncasecmp(e->name.s, events[i].name.s, e->name.len)) {
>> + e->type = events[i].type;
>> + break;
>> + }
>> + }
>> +
>> + tmp.len -= end - tmp.s;
>> + tmp.s = end;
>> + trim_leading(&tmp);
>> +
>> + if (tmp.s[0] == ';') {
>> + /* We have parameters to parse */
>> + if (e->type == EVENT_DIALOG) {
>> + pclass = CLASS_EVENT_DIALOG;
>> + phooks = (param_hooks_t*)&e->params.dialog;
>> + }
>> - _e->text.len = end - tmp.s;
>> -
>> - if ((_e->text.len == PRES_STR_LEN) && - !strncasecmp(PRES_STR,
>> tmp.s, _e->text.len)) {
>> - _e->parsed = EVENT_PRESENCE;
>> - } else if ((_e->text.len == PRES_XCAP_CHANGE_STR_LEN) && -
>> !strncasecmp(PRES_XCAP_CHANGE_STR, tmp.s, _e->text.len)) {
>> - _e->parsed = EVENT_XCAP_CHANGE;
>> - } else if ((_e->text.len == PRES_WINFO_STR_LEN) && -
>> !strncasecmp(PRES_WINFO_STR, tmp.s, _e->text.len)) {
>> - _e->parsed = EVENT_PRESENCE_WINFO;
>> - } else if ((_e->text.len == PRES_SIP_PROFILE_STR_LEN) && -
>> !strncasecmp(PRES_SIP_PROFILE_STR, tmp.s, _e->text.len)) {
>> - _e->parsed = EVENT_SIP_PROFILE;
>> + if (parse_params(&tmp, pclass, phooks, &e->params.list) < 0) {
>> + ERR("event_parser: Error while parsing parameters parameters\n");
>> + return -1;
>> + }
>> } else {
>> - _e->parsed = EVENT_OTHER;
>> + e->params.list = NULL;
>> }
>> return 0;
>> @@ -153,19 +171,24 @@ int parse_event(struct hdr_field* _h)
>> */
>> void free_event(event_t** _e)
>> {
>> - if (*_e) pkg_free(*_e);
>> - *_e = 0;
>> + if (*_e) {
>> + if ((*_e)->params.list) free_params((*_e)->params.list);
>> + pkg_free(*_e);
>> + *_e = NULL;
>> + }
>> }
>> /*
>> * Print structure, for debugging only
>> */
>> -void print_event(event_t* _e)
>> +void print_event(event_t* e)
>> {
>> printf("===Event===\n");
>> - printf("text : \'%.*s\'\n", _e->text.len, ZSW(_e->text.s));
>> - printf("parsed: %s\n", - (_e->parsed == EVENT_PRESENCE) ?
>> ("EVENT_PRESENCE") : ("EVENT_OTHER"));
>> + printf("name : \'%.*s\'\n", STR_FMT(&e->name));
>> + printf("type: %d\n", e->type);
>> + if (e->params.list) {
>> + print_params(stdout, e->params.list);
>> + }
>> printf("===/Event===\n");
>> }
>> diff --git a/parser/parse_event.h b/parser/parse_event.h
>> index 03feb5e..4e90a52 100644
>> --- a/parser/parse_event.h
>> +++ b/parser/parse_event.h
>> @@ -1,12 +1,6 @@
>> /*
>> * $Id$
>> *
>> - * Event header field body parser
>> - * This parser was written for Presence Agent module only.
>> - * it recognizes presence package only, no subpackages, no parameters
>> - * It should be replaced by a more generic parser if subpackages or
>> - * parameters should be parsed too.
>> - *
>> * Copyright (C) 2001-2003 FhG Fokus
>> *
>> * This file is part of ser, a free SIP server.
>> @@ -37,35 +31,51 @@
>> #include "../str.h"
>> #include "hf.h"
>> +#include "parse_param.h"
>> +
>> +/* Recognized event types */
>> +enum event_type {
>> + EVENT_OTHER = 0,
>> + EVENT_PRESENCE,
>> + EVENT_PRESENCE_WINFO,
>> + EVENT_SIP_PROFILE,
>> + EVENT_XCAP_CHANGE,
>> + EVENT_DIALOG,
>> + EVENT_MESSAGE_SUMMARY
>> +};
>> +
>> +
>> +struct event_params {
>> + struct event_dialog_hooks dialog; /* Well known dialog package params */
>> + param_t* list; /* Linked list of all parsed parameters */
>> +};
>> -#define EVENT_OTHER 0
>> -#define EVENT_PRESENCE 1
>> -#define EVENT_PRESENCE_WINFO 2
>> -#define EVENT_SIP_PROFILE 3
>> -#define EVENT_XCAP_CHANGE 4
>> typedef struct event {
>> - str text; /* Original string representation */
>> - int parsed; /* Parsed variant */
>> + enum event_type type; /* Parsed variant */
>> + str name; /* Original string representation */
>> + struct event_params params;
>> } event_t;
>> /*
>> * Parse Event HF body
>> */
>> -int parse_event(struct hdr_field* _h);
>> +int parse_event(struct hdr_field* hf);
>> /*
>> * Release memory
>> */
>> -void free_event(event_t** _e);
>> +void free_event(event_t** e);
>> /*
>> * Print structure, for debugging only
>> */
>> -void print_event(event_t* _e);
>> +void print_event(event_t* e);
>> +
>> +int event_parser(char* s, int l, event_t* e);
>> #endif /* PARSE_EVENT_H */
>>
>>
>> _______________________________________________
>> sr-dev mailing list
>> sr-dev at lists.sip-router.org
>> http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
More information about the sr-dev
mailing list