Merged revisions 29464 via svnmerge from
[asterisk/asterisk.git] / channels / chan_local.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \author Mark Spencer <markster@digium.com>
22  *
23  * \brief Local Proxy Channel
24  * 
25  * \ingroup channel_drivers
26  */
27
28 #include <stdio.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <sys/socket.h>
32 #include <errno.h>
33 #include <stdlib.h>
34 #include <fcntl.h>
35 #include <netdb.h>
36 #include <netinet/in.h>
37 #include <arpa/inet.h>
38 #include <sys/signal.h>
39
40 #include "asterisk.h"
41
42 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
43
44 #include "asterisk/lock.h"
45 #include "asterisk/channel.h"
46 #include "asterisk/config.h"
47 #include "asterisk/logger.h"
48 #include "asterisk/module.h"
49 #include "asterisk/pbx.h"
50 #include "asterisk/options.h"
51 #include "asterisk/lock.h"
52 #include "asterisk/sched.h"
53 #include "asterisk/io.h"
54 #include "asterisk/rtp.h"
55 #include "asterisk/acl.h"
56 #include "asterisk/callerid.h"
57 #include "asterisk/file.h"
58 #include "asterisk/cli.h"
59 #include "asterisk/app.h"
60 #include "asterisk/musiconhold.h"
61 #include "asterisk/manager.h"
62 #include "asterisk/stringfields.h"
63 #include "asterisk/devicestate.h"
64
65 static const char tdesc[] = "Local Proxy Channel Driver";
66
67 #define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
68
69 static struct ast_channel *local_request(const char *type, int format, void *data, int *cause);
70 static int local_digit(struct ast_channel *ast, char digit);
71 static int local_call(struct ast_channel *ast, char *dest, int timeout);
72 static int local_hangup(struct ast_channel *ast);
73 static int local_answer(struct ast_channel *ast);
74 static struct ast_frame *local_read(struct ast_channel *ast);
75 static int local_write(struct ast_channel *ast, struct ast_frame *f);
76 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
77 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
78 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
79 static int local_sendtext(struct ast_channel *ast, const char *text);
80 static int local_devicestate(void *data);
81
82 /* PBX interface structure for channel registration */
83 static const struct ast_channel_tech local_tech = {
84         .type = "Local",
85         .description = tdesc,
86         .capabilities = -1,
87         .requester = local_request,
88         .send_digit = local_digit,
89         .call = local_call,
90         .hangup = local_hangup,
91         .answer = local_answer,
92         .read = local_read,
93         .write = local_write,
94         .write_video = local_write,
95         .exception = local_read,
96         .indicate = local_indicate,
97         .fixup = local_fixup,
98         .send_html = local_sendhtml,
99         .send_text = local_sendtext,
100         .devicestate = local_devicestate,
101 };
102
103 struct local_pvt {
104         ast_mutex_t lock;                       /* Channel private lock */
105         char context[AST_MAX_CONTEXT];          /* Context to call */
106         char exten[AST_MAX_EXTENSION];          /* Extension to call */
107         int reqformat;                          /* Requested format */
108         int glaredetect;                        /* Detect glare on hangup */
109         int cancelqueue;                        /* Cancel queue */
110         int alreadymasqed;                      /* Already masqueraded */
111         int launchedpbx;                        /* Did we launch the PBX */
112         int nooptimization;                     /* Don't leave masq state */
113         struct ast_channel *owner;              /* Master Channel */
114         struct ast_channel *chan;               /* Outbound channel */
115         AST_LIST_ENTRY(local_pvt) list;         /* Next entity */
116 };
117
118 static AST_LIST_HEAD_STATIC(locals, local_pvt);
119
120 /*! \brief Adds devicestate to local channels */
121 static int local_devicestate(void *data)
122 {
123         char *exten;
124         char *context;
125
126         int res;
127                 
128         exten = ast_strdupa(data);
129         if ((context  = strchr(exten, '@'))) {
130                 *context = '\0';
131                 context = context + 1;
132         }
133         if (option_debug > 2)
134                 ast_log(LOG_DEBUG, "Checking if extension %s@%s exists (devicestate)\n", exten, context);
135         res = ast_exists_extension(NULL, context, exten, 1, NULL);
136         if (!res)
137                 return AST_DEVICE_NOT_INUSE;
138         else
139                 return AST_DEVICE_INUSE;
140 }
141
142 static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us)
143 {
144         struct ast_channel *other;
145 retrylock:              
146         /* Recalculate outbound channel */
147         if (isoutbound) {
148                 other = p->owner;
149         } else {
150                 other = p->chan;
151         }
152         /* Set glare detection */
153         p->glaredetect = 1;
154         if (p->cancelqueue) {
155                 /* We had a glare on the hangup.  Forget all this business,
156                 return and destroy p.  */
157                 ast_mutex_unlock(&p->lock);
158                 ast_mutex_destroy(&p->lock);
159                 free(p);
160                 return -1;
161         }
162         if (!other) {
163                 p->glaredetect = 0;
164                 return 0;
165         }
166         if (ast_mutex_trylock(&other->lock)) {
167                 /* Failed to lock.  Release main lock and try again */
168                 ast_mutex_unlock(&p->lock);
169                 if (us) {
170                         if (ast_mutex_unlock(&us->lock)) {
171                                 ast_log(LOG_WARNING, "%s wasn't locked while sending %d/%d\n",
172                                         us->name, f->frametype, f->subclass);
173                                 us = NULL;
174                         }
175                 }
176                 /* Wait just a bit */
177                 usleep(1);
178                 /* Only we can destroy ourselves, so we can't disappear here */
179                 if (us)
180                         ast_mutex_lock(&us->lock);
181                 ast_mutex_lock(&p->lock);
182                 goto retrylock;
183         }
184         ast_queue_frame(other, f);
185         ast_mutex_unlock(&other->lock);
186         p->glaredetect = 0;
187         return 0;
188 }
189
190 static int local_answer(struct ast_channel *ast)
191 {
192         struct local_pvt *p = ast->tech_pvt;
193         int isoutbound;
194         int res = -1;
195
196         ast_mutex_lock(&p->lock);
197         isoutbound = IS_OUTBOUND(ast, p);
198         if (isoutbound) {
199                 /* Pass along answer since somebody answered us */
200                 struct ast_frame answer = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
201                 res = local_queue_frame(p, isoutbound, &answer, ast);
202         } else
203                 ast_log(LOG_WARNING, "Huh?  Local is being asked to answer?\n");
204         ast_mutex_unlock(&p->lock);
205         return res;
206 }
207
208 static void check_bridge(struct local_pvt *p, int isoutbound)
209 {
210         if (p->alreadymasqed || p->nooptimization)
211                 return;
212         if (!p->chan || !p->owner)
213                 return;
214         if (isoutbound&& p->chan->_bridge /* Not ast_bridged_channel!  Only go one step! */ && !p->owner->readq) {
215                 /* Masquerade bridged channel into owner */
216                 /* Lock everything we need, one by one, and give up if
217                    we can't get everything.  Remember, we'll get another
218                    chance in just a little bit */
219                 if (!ast_mutex_trylock(&(p->chan->_bridge)->lock)) {
220                         if (!p->chan->_bridge->_softhangup) {
221                                 if (!ast_mutex_trylock(&p->owner->lock)) {
222                                         if (!p->owner->_softhangup) {
223                                                 ast_channel_masquerade(p->owner, p->chan->_bridge);
224                                                 p->alreadymasqed = 1;
225                                         }
226                                         ast_mutex_unlock(&p->owner->lock);
227                                 }
228                                 ast_mutex_unlock(&(p->chan->_bridge)->lock);
229                         }
230                 }
231         } else if (!isoutbound && p->owner && p->owner->_bridge && p->chan && !p->chan->readq) {
232                 /* Masquerade bridged channel into chan */
233                 if (!ast_mutex_trylock(&(p->owner->_bridge)->lock)) {
234                         if (!p->owner->_bridge->_softhangup) {
235                                 if (!ast_mutex_trylock(&p->chan->lock)) {
236                                         if (!p->chan->_softhangup) {
237                                                 ast_channel_masquerade(p->chan, p->owner->_bridge);
238                                                 p->alreadymasqed = 1;
239                                         }
240                                         ast_mutex_unlock(&p->chan->lock);
241                                 }
242                         }
243                         ast_mutex_unlock(&(p->owner->_bridge)->lock);
244                 }
245         }
246 }
247
248 static struct ast_frame  *local_read(struct ast_channel *ast)
249 {
250         return &ast_null_frame;
251 }
252
253 static int local_write(struct ast_channel *ast, struct ast_frame *f)
254 {
255         struct local_pvt *p = ast->tech_pvt;
256         int res = -1;
257         int isoutbound;
258
259         /* Just queue for delivery to the other side */
260         ast_mutex_lock(&p->lock);
261         isoutbound = IS_OUTBOUND(ast, p);
262         if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO))
263                 check_bridge(p, isoutbound);
264         if (!p->alreadymasqed)
265                 res = local_queue_frame(p, isoutbound, f, ast);
266         else {
267                 if (option_debug)
268                         ast_log(LOG_DEBUG, "Not posting to queue since already masked on '%s'\n", ast->name);
269                 res = 0;
270         }
271         ast_mutex_unlock(&p->lock);
272         return res;
273 }
274
275 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
276 {
277         struct local_pvt *p = newchan->tech_pvt;
278         ast_mutex_lock(&p->lock);
279
280         if ((p->owner != oldchan) && (p->chan != oldchan)) {
281                 ast_log(LOG_WARNING, "Old channel wasn't %p but was %p/%p\n", oldchan, p->owner, p->chan);
282                 ast_mutex_unlock(&p->lock);
283                 return -1;
284         }
285         if (p->owner == oldchan)
286                 p->owner = newchan;
287         else
288                 p->chan = newchan;
289         ast_mutex_unlock(&p->lock);
290         return 0;
291 }
292
293 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
294 {
295         struct local_pvt *p = ast->tech_pvt;
296         int res = -1;
297         struct ast_frame f = { AST_FRAME_CONTROL, };
298         int isoutbound;
299
300         /* Queue up a frame representing the indication as a control frame */
301         ast_mutex_lock(&p->lock);
302         isoutbound = IS_OUTBOUND(ast, p);
303         f.subclass = condition;
304         res = local_queue_frame(p, isoutbound, &f, ast);
305         ast_mutex_unlock(&p->lock);
306         return res;
307 }
308
309 static int local_digit(struct ast_channel *ast, char digit)
310 {
311         struct local_pvt *p = ast->tech_pvt;
312         int res = -1;
313         struct ast_frame f = { AST_FRAME_DTMF, };
314         int isoutbound;
315
316         ast_mutex_lock(&p->lock);
317         isoutbound = IS_OUTBOUND(ast, p);
318         f.subclass = digit;
319         res = local_queue_frame(p, isoutbound, &f, ast);
320         ast_mutex_unlock(&p->lock);
321         return res;
322 }
323
324 static int local_sendtext(struct ast_channel *ast, const char *text)
325 {
326         struct local_pvt *p = ast->tech_pvt;
327         int res = -1;
328         struct ast_frame f = { AST_FRAME_TEXT, };
329         int isoutbound;
330
331         ast_mutex_lock(&p->lock);
332         isoutbound = IS_OUTBOUND(ast, p);
333         f.data = (char *) text;
334         f.datalen = strlen(text) + 1;
335         res = local_queue_frame(p, isoutbound, &f, ast);
336         ast_mutex_unlock(&p->lock);
337         return res;
338 }
339
340 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
341 {
342         struct local_pvt *p = ast->tech_pvt;
343         int res = -1;
344         struct ast_frame f = { AST_FRAME_HTML, };
345         int isoutbound;
346
347         ast_mutex_lock(&p->lock);
348         isoutbound = IS_OUTBOUND(ast, p);
349         f.subclass = subclass;
350         f.data = (char *)data;
351         f.datalen = datalen;
352         res = local_queue_frame(p, isoutbound, &f, ast);
353         ast_mutex_unlock(&p->lock);
354         return res;
355 }
356
357 /*! \brief Initiate new call, part of PBX interface 
358  *      dest is the dial string */
359 static int local_call(struct ast_channel *ast, char *dest, int timeout)
360 {
361         struct local_pvt *p = ast->tech_pvt;
362         int res;
363         struct ast_var_t *varptr = NULL, *new;
364         size_t len, namelen;
365         
366         ast_mutex_lock(&p->lock);
367
368         p->chan->cid.cid_num = ast_strdup(p->owner->cid.cid_num);
369         p->chan->cid.cid_name = ast_strdup(p->owner->cid.cid_name);
370         p->chan->cid.cid_rdnis = ast_strdup(p->owner->cid.cid_rdnis);
371         p->chan->cid.cid_ani = ast_strdup(p->owner->cid.cid_ani);
372         p->chan->cid.cid_pres = p->owner->cid.cid_pres;
373         ast_string_field_set(p->chan, language, p->owner->language);
374         ast_string_field_set(p->chan, accountcode, p->owner->accountcode);
375         p->chan->cdrflags = p->owner->cdrflags;
376
377         /* copy the channel variables from the incoming channel to the outgoing channel */
378         /* Note that due to certain assumptions, they MUST be in the same order */
379         AST_LIST_TRAVERSE(&p->owner->varshead, varptr, entries) {
380                 namelen = strlen(varptr->name);
381                 len = sizeof(struct ast_var_t) + namelen + strlen(varptr->value) + 2;
382                 if ((new = ast_calloc(1, len))) {
383                         memcpy(new, varptr, len);
384                         new->value = &(new->name[0]) + namelen + 1;
385                         AST_LIST_INSERT_TAIL(&p->chan->varshead, new, entries);
386                 }
387         }
388
389         p->launchedpbx = 1;
390
391         /* Start switch on sub channel */
392         res = ast_pbx_start(p->chan);
393         ast_mutex_unlock(&p->lock);
394         return res;
395 }
396
397 #if 0
398 static void local_destroy(struct local_pvt *p)
399 {
400         struct local_pvt *cur;
401
402         AST_LIST_LOCK(&locals);
403         AST_LIST_TRAVERSE_SAFE_BEGIN(&locals, cur, list) {
404                 if (cur == p) {
405                         AST_LIST_REMOVE_CURRENT(&locals, list);
406                         ast_mutex_destroy(&cur->lock);
407                         free(cur);
408                         break;
409                 }
410         }
411         AST_LIST_TRAVERSE_SAFE_END
412         AST_LIST_UNLOCK(&locals);
413         if (!cur)
414                 ast_log(LOG_WARNING, "Unable ot find local '%s@%s' in local list\n", p->exten, p->context);
415 }
416 #endif
417
418 /*! \brief Hangup a call through the local proxy channel */
419 static int local_hangup(struct ast_channel *ast)
420 {
421         struct local_pvt *p = ast->tech_pvt;
422         int isoutbound;
423         struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
424         struct ast_channel *ochan = NULL;
425         int glaredetect;
426
427         ast_mutex_lock(&p->lock);
428         isoutbound = IS_OUTBOUND(ast, p);
429         if (isoutbound) {
430                 const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
431                 if ((status) && (p->owner))
432                         pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
433                 p->chan = NULL;
434                 p->launchedpbx = 0;
435         } else
436                 p->owner = NULL;
437         ast->tech_pvt = NULL;
438         
439         ast_atomic_fetchadd_int(&__mod_desc->usecnt, -1);
440         
441         if (!p->owner && !p->chan) {
442                 /* Okay, done with the private part now, too. */
443                 glaredetect = p->glaredetect;
444                 /* If we have a queue holding, don't actually destroy p yet, but
445                    let local_queue do it. */
446                 if (p->glaredetect)
447                         p->cancelqueue = 1;
448                 ast_mutex_unlock(&p->lock);
449                 /* Remove from list */
450                 AST_LIST_LOCK(&locals);
451                 AST_LIST_REMOVE(&locals, p, list);
452                 AST_LIST_UNLOCK(&locals);
453                 /* Grab / release lock just in case */
454                 ast_mutex_lock(&p->lock);
455                 ast_mutex_unlock(&p->lock);
456                 /* And destroy */
457                 if (!glaredetect) {
458                         ast_mutex_destroy(&p->lock);
459                         free(p);
460                 }
461                 return 0;
462         }
463         if (p->chan && !p->launchedpbx)
464                 /* Need to actually hangup since there is no PBX */
465                 ochan = p->chan;
466         else
467                 local_queue_frame(p, isoutbound, &f, NULL);
468         ast_mutex_unlock(&p->lock);
469         if (ochan)
470                 ast_hangup(ochan);
471         return 0;
472 }
473
474 /*! \brief Create a call structure */
475 static struct local_pvt *local_alloc(const char *data, int format)
476 {
477         struct local_pvt *tmp;
478         char *c;
479         char *opts;
480
481         if (!(tmp = ast_calloc(1, sizeof(*tmp))))
482                 return NULL;
483         
484         ast_mutex_init(&tmp->lock);
485         ast_copy_string(tmp->exten, data, sizeof(tmp->exten));
486         opts = strchr(tmp->exten, '/');
487         if (opts) {
488                 *opts++ = '\0';
489                 if (strchr(opts, 'n'))
490                         tmp->nooptimization = 1;
491         }
492         c = strchr(tmp->exten, '@');
493         if (c)
494                 *c++ = '\0';
495         ast_copy_string(tmp->context, c ? c : "default", sizeof(tmp->context));
496         tmp->reqformat = format;
497         if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) {
498                 ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->exten, tmp->context);
499                 ast_mutex_destroy(&tmp->lock);
500                 free(tmp);
501                 tmp = NULL;
502         } else {
503                 /* Add to list */
504                 AST_LIST_LOCK(&locals);
505                 AST_LIST_INSERT_HEAD(&locals, tmp, list);
506                 AST_LIST_UNLOCK(&locals);
507         }
508         
509         return tmp;
510 }
511
512 /*! \brief Start new local channel */
513 static struct ast_channel *local_new(struct local_pvt *p, int state)
514 {
515         struct ast_channel *tmp, *tmp2;
516         int randnum = ast_random() & 0xffff;
517
518         tmp = ast_channel_alloc(1);
519         tmp2 = ast_channel_alloc(1);
520         if (!tmp || !tmp2) {
521                 if (tmp)
522                         ast_channel_free(tmp);
523                 if (tmp2)
524                         ast_channel_free(tmp2);
525                 ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
526                 return NULL;
527         } 
528
529         tmp2->tech = tmp->tech = &local_tech;
530         tmp->nativeformats = p->reqformat;
531         tmp2->nativeformats = p->reqformat;
532         ast_string_field_build(tmp, name, "Local/%s@%s-%04x,1", p->exten, p->context, randnum);
533         ast_string_field_build(tmp2, name, "Local/%s@%s-%04x,2", p->exten, p->context, randnum);
534         ast_setstate(tmp, state);
535         ast_setstate(tmp2, AST_STATE_RING);
536         tmp->writeformat = p->reqformat;
537         tmp2->writeformat = p->reqformat;
538         tmp->rawwriteformat = p->reqformat;
539         tmp2->rawwriteformat = p->reqformat;
540         tmp->readformat = p->reqformat;
541         tmp2->readformat = p->reqformat;
542         tmp->rawreadformat = p->reqformat;
543         tmp2->rawreadformat = p->reqformat;
544         tmp->tech_pvt = p;
545         tmp2->tech_pvt = p;
546         p->owner = tmp;
547         p->chan = tmp2;
548         ast_atomic_fetchadd_int(&__mod_desc->usecnt, +2);       /* we allocate 2 new channels */
549         ast_update_use_count();
550         ast_copy_string(tmp->context, p->context, sizeof(tmp->context));
551         ast_copy_string(tmp2->context, p->context, sizeof(tmp2->context));
552         ast_copy_string(tmp2->exten, p->exten, sizeof(tmp->exten));
553         tmp->priority = 1;
554         tmp2->priority = 1;
555
556         return tmp;
557 }
558
559
560 /*! \brief Part of PBX interface */
561 static struct ast_channel *local_request(const char *type, int format, void *data, int *cause)
562 {
563         struct local_pvt *p;
564         struct ast_channel *chan = NULL;
565
566         p = local_alloc(data, format);
567         if (p)
568                 chan = local_new(p, AST_STATE_DOWN);
569         return chan;
570 }
571
572 /*! \brief CLI command "local show channels" */
573 static int locals_show(int fd, int argc, char **argv)
574 {
575         struct local_pvt *p;
576
577         if (argc != 3)
578                 return RESULT_SHOWUSAGE;
579         if (AST_LIST_EMPTY(&locals))
580                 ast_cli(fd, "No local channels in use\n");
581         AST_LIST_LOCK(&locals);
582         AST_LIST_TRAVERSE(&locals, p, list) {
583                 ast_mutex_lock(&p->lock);
584                 ast_cli(fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "<unowned>", p->exten, p->context);
585                 ast_mutex_unlock(&p->lock);
586         }
587         AST_LIST_UNLOCK(&locals);
588         return RESULT_SUCCESS;
589 }
590
591 static char show_locals_usage[] = 
592 "Usage: local show channels\n"
593 "       Provides summary information on active local proxy channels.\n";
594
595 static struct ast_cli_entry cli_show_locals = {
596         { "local", "show", "channels", NULL }, locals_show, 
597         "Show status of local channels", show_locals_usage, NULL };
598
599 /*! \brief Load module into PBX, register channel */
600 static int load_module(void *mod)
601 {
602         __mod_desc = mod;
603
604         /* Make sure we can register our channel type */
605         if (ast_channel_register(&local_tech)) {
606                 ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
607                 return -1;
608         }
609         ast_cli_register(&cli_show_locals);
610         return 0;
611 }
612
613 /*! \brief Unload the local proxy channel from Asterisk */
614 static int unload_module(void *mod)
615 {
616         struct local_pvt *p;
617
618         /* First, take us out of the channel loop */
619         ast_cli_unregister(&cli_show_locals);
620         ast_channel_unregister(&local_tech);
621         if (!AST_LIST_LOCK(&locals)) {
622                 /* Hangup all interfaces if they have an owner */
623                 AST_LIST_TRAVERSE(&locals, p, list) {
624                         if (p->owner)
625                                 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
626                 }
627                 AST_LIST_UNLOCK(&locals);
628                 AST_LIST_HEAD_DESTROY(&locals);
629         } else {
630                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
631                 return -1;
632         }               
633         return 0;
634 }
635
636 static const char *key(void)
637 {
638         return ASTERISK_GPL_KEY;
639 }
640
641 static const char *description(void)
642 {
643         return "Local Proxy Channel";
644 }
645
646 STD_MOD(MOD_1, NULL, NULL, NULL);