Browse code

multi-mime: dsm: mod_dlg: actions/conditions for explicit body handling (sipRequest/sipReply)

Stefan Sayer authored on 17/02/2012 13:22:31 • Raphael Coeffic committed on 20/02/2012 15:16:13
Showing 4 changed files
... ...
@@ -273,13 +273,6 @@ void DSMCall::onSipRequest(const AmSipRequest& req) {
273 273
     params["from"] = req.from;
274 274
     params["to"] = req.to;
275 275
     params["hdrs"] = req.hdrs;
276
-
277
-    //TODO: find some sort of solution for this one....
278
-    //      Stefan? any clue?????
279
-    //
280
-    //params["content_type"] = req.content_type;
281
-    //params["body"] = req.body;
282
-
283 276
     params["cseq"] = int2str(req.cseq);
284 277
 
285 278
     // pass AmSipRequest for use by mod_dlg
... ...
@@ -49,9 +49,21 @@ MOD_ACTIONEXPORT_BEGIN(MOD_CLS_NAME) {
49 49
   DEF_CMD("dlg.connectCalleeRelayed", DLGConnectCalleeRelayedAction);
50 50
   DEF_CMD("dlg.dialout", DLGDialoutAction);
51 51
 
52
+  DEF_CMD("dlg.getRequestBody", DLGGetRequestBodyAction)
53
+  DEF_CMD("dlg.getReplyBody", DLGGetReplyBodyAction)
52 54
 } MOD_ACTIONEXPORT_END;
53 55
 
54
-MOD_CONDITIONEXPORT_NONE(MOD_CLS_NAME);
56
+//MOD_CONDITIONEXPORT_NONE(MOD_CLS_NAME);
57
+
58
+
59
+MOD_CONDITIONEXPORT_BEGIN(MOD_CLS_NAME) {
60
+  if (cmd == "dlg.replyHasContentType")
61
+    return new DLGReplyHasContentTypeCondition(params, false);
62
+
63
+  if (cmd == "dlg.requestHasContentType")
64
+    return new DLGRequestHasContentTypeCondition(params, false);
65
+
66
+} MOD_CONDITIONEXPORT_END;
55 67
 
56 68
 bool DLGModule::onInvite(const AmSipRequest& req, DSMSession* sess) {
57 69
   // save inivital invite to last_req 
... ...
@@ -290,3 +302,95 @@ EXEC_ACTION_START(DLGDialoutAction) {
290 302
   }
291 303
 
292 304
 } EXEC_ACTION_END;
305
+
306
+MATCH_CONDITION_START(DLGReplyHasContentTypeCondition) {
307
+  AVarMapT::iterator it = sc_sess->avar.find(DSM_AVAR_REPLY);
308
+  if (it == sc_sess->avar.end()) {
309
+    ERROR("DSM script error: dlg.replyHasContentType condition used for "
310
+	  "other event than sipReply event\n");
311
+    return false;
312
+  }
313
+
314
+  DSMSipReply* dsm_reply = NULL;
315
+  if (!isArgAObject(sc_sess->avar[DSM_AVAR_REPLY]) ||
316
+      (NULL ==
317
+       (dsm_reply = dynamic_cast<DSMSipReply*>(sc_sess->avar[DSM_AVAR_REPLY].asObject())))) {
318
+    ERROR("internal: DSM could not get DSMSipReply\n");
319
+    return false;
320
+  }
321
+
322
+  bool res = dsm_reply->reply->body.hasContentType(arg);
323
+
324
+  DBG("checking for content_type '%s': %s\n", arg.c_str(), res?"has it":"doesn't have it");
325
+  return res;
326
+} MATCH_CONDITION_END;
327
+
328
+MATCH_CONDITION_START(DLGRequestHasContentTypeCondition) {
329
+  AVarMapT::iterator it = sc_sess->avar.find(DSM_AVAR_REQUEST);
330
+  if (it == sc_sess->avar.end()) {
331
+    ERROR("DSM script error: dlg.requestHasContentType condition used for "
332
+	  "other event than sipRequest event\n");
333
+    return false;
334
+  }
335
+
336
+  DSMSipRequest* dsm_req = NULL;
337
+  if (!isArgAObject(sc_sess->avar[DSM_AVAR_REQUEST]) ||
338
+      (NULL ==
339
+       (dsm_req = dynamic_cast<DSMSipRequest*>(sc_sess->avar[DSM_AVAR_REQUEST].asObject())))) {
340
+    ERROR("internal: DSM could not get DSMSipRequest\n");
341
+    return false;
342
+  }
343
+
344
+  bool res = dsm_req->req->body.hasContentType(arg);
345
+
346
+  DBG("checking for content_type '%s': %s\n", arg.c_str(), res?"has it":"doesn't have it");
347
+  return res;
348
+} MATCH_CONDITION_END;
349
+
350
+CONST_ACTION_2P(DLGGetRequestBodyAction, ',', false);
351
+EXEC_ACTION_START(DLGGetRequestBodyAction) {
352
+  DSMSipRequest* sip_req;
353
+
354
+  AVarMapT::iterator it = sc_sess->avar.find(DSM_AVAR_REQUEST);
355
+  if (it == sc_sess->avar.end() ||
356
+      !isArgAObject(it->second) ||
357
+      !(sip_req = dynamic_cast<DSMSipRequest*>(it->second.asObject()))) {
358
+    throw DSMException("dlg", "cause", "no request");
359
+  }
360
+
361
+  string content_type = resolveVars(par1, sess, sc_sess, event_params);
362
+  string dstvar = resolveVars(par2, sess, sc_sess, event_params);
363
+
364
+  const AmMimeBody* msg_body = sip_req->req->body.hasContentType(content_type);
365
+  if (NULL == msg_body) {
366
+    DBG("body with content_type %s not found\n", content_type.c_str());
367
+    sc_sess->var.erase(dstvar);
368
+  } else {
369
+    sc_sess->var[dstvar] = string((const char*)msg_body->getPayload());
370
+    DBG("set $%s='%s'\n", dstvar.c_str(), sc_sess->var[dstvar].c_str());
371
+  }
372
+} EXEC_ACTION_END;
373
+
374
+CONST_ACTION_2P(DLGGetReplyBodyAction, ',', false);
375
+EXEC_ACTION_START(DLGGetReplyBodyAction) {
376
+  DSMSipReply* sip_req;
377
+
378
+  AVarMapT::iterator it = sc_sess->avar.find(DSM_AVAR_REPLY);
379
+  if (it == sc_sess->avar.end() ||
380
+      !isArgAObject(it->second) ||
381
+      !(sip_req = dynamic_cast<DSMSipReply*>(it->second.asObject()))) {
382
+    throw DSMException("dlg", "cause", "no reply");
383
+  }
384
+
385
+  string content_type = resolveVars(par1, sess, sc_sess, event_params);
386
+  string dstvar = resolveVars(par2, sess, sc_sess, event_params);
387
+
388
+  const AmMimeBody* msg_body = sip_req->reply->body.hasContentType(content_type);
389
+  if (NULL == msg_body) {
390
+    DBG("body with content_type %s not found\n", content_type.c_str());
391
+    sc_sess->var.erase(dstvar);
392
+  } else {
393
+    sc_sess->var[dstvar] = string((const char*)msg_body->getPayload());
394
+    DBG("set $%s='%s'\n", dstvar.c_str(), sc_sess->var[dstvar].c_str());
395
+  }
396
+} EXEC_ACTION_END;
... ...
@@ -40,4 +40,9 @@ DEF_ACTION_2P(DLGAcceptInviteAction);
40 40
 DEF_ACTION_2P(DLGConnectCalleeRelayedAction);
41 41
 DEF_ACTION_1P(DLGByeAction);
42 42
 DEF_ACTION_1P(DLGDialoutAction);
43
+
44
+DEF_SCCondition(DLGReplyHasContentTypeCondition);
45
+DEF_SCCondition(DLGRequestHasContentTypeCondition);
46
+DEF_ACTION_2P(DLGGetRequestBodyAction);
47
+DEF_ACTION_2P(DLGGetReplyBodyAction);
43 48
 #endif
... ...
@@ -3,7 +3,12 @@
3 3
 * set connect_session to 0 with set(connect_session=0)
4 4
   if you want to reply with other than the standard 200 OK 
5 5
   to initial INVITE received.
6
-* for processing of other requests, use enable_request_events and replyRequest
6
+* for processing of other requests, use set($enable_request_events="true") and replyRequest
7
+* for processing of other requests, use set($enable_reply_events="true") and replyRequest
8
+
9
+* Request/Reply body handling with 
10
+ dlg.requestHasContentType condition and dlg.getRequestBody action
11
+ dlg.replyHasContentType condition and dlg.getReplyBody action
7 12
 
8 13
 dlg.reply(code,reason);
9 14
  reply to the request in DSMSession::last_req 
... ...
@@ -56,6 +61,20 @@ dlg.dialout(string arrayname)
56 61
 
57 62
   returns $arrayname_ltag (if successful) and sets ERRNO.
58 63
    
64
+Request/Reply Body handling in sipRequest/sipReply events:
65
+
66
+actions (applicable only in sipRequest/sipReply event handling blocks):
67
+dlg.getRequestBody(content_type, dstvar)  - get body of content_type in $dstvar
68
+dlg.getReplyBody(content_type, dstvar)    - get body of content_type in $dstvar
69
+
70
+conditions: 
71
+  dlg.replyHasContentType(content_type) and dlg.requestHasContentType(content_type)
59 72
 
73
+  checks whether request/reply has a certain content type
60 74
 
75
+ example: 
61 76
 
77
+transition "msg recvd" A - sipRequest; dlg.requestHasContentType(application/ISUP) / {
78
+  dlg.getRequestBody(application/ISUP, isup_body);
79
+  ... do sth with $isup_body ...
80
+} -> B;