-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmod_core.cpp
More file actions
234 lines (187 loc) · 7.36 KB
/
mod_core.cpp
File metadata and controls
234 lines (187 loc) · 7.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#include <switch.h>
#include "freeswitch_core.h"
#ifdef _CORE
#include <mscoree.h>
#define MOD_CORE_VERSION "CoreCLR Version"
#ifdef __cplusplus_cli
using namespace System;
using namespace System::Runtime::InteropServices;
#endif
#endif
SWITCH_BEGIN_EXTERN_C
SWITCH_MODULE_LOAD_FUNCTION(mod_core_load);
SWITCH_MODULE_DEFINITION_EX(mod_core, mod_core_load, NULL, NULL, SMODF_GLOBAL_SYMBOLS);
SWITCH_STANDARD_API(core_run_api_function); /* ExecuteBackground */
SWITCH_STANDARD_API(core_api_function); /* Execute */
SWITCH_STANDARD_APP(core_app_function); /* Run */
SWITCH_STANDARD_API(core_reload_api_function); /* Reload */
SWITCH_STANDARD_API(core_list_api_function); /* List modules */
#define MOD_CORE_ASM_NAME "FreeSwitch.Core"
#define MOD_CORE_ASM_V1 1
#define MOD_CORE_ASM_V2 0
#define MOD_CORE_ASM_V3 0
#define MOD_CORE_ASM_V4 0
#define MOD_CORE_DLL MOD_CORE_ASM_NAME ".dll"
#define MOD_CORE_IMAGE_NAME "FreeSwitch"
#define MOD_CORE_CLASS_NAME "Loader"
mod_core_globals core_globals = { 0 };
typedef int (*runFunction)(const char *data, void *sessionPtr);
typedef int (*executeFunction)(const char *cmd, void *stream, void *Event);
typedef int (*executeBackgroundFunction)(const char* cmd);
typedef int (*reloadFunction)(const char* cmd);
typedef int (*listFunction)(const char *cmd, void *stream, void *Event);
static runFunction runDelegate;
static executeFunction executeDelegate;
static executeBackgroundFunction executeBackgroundDelegate;
static reloadFunction reloadDelegate;
static listFunction listDelegate;
SWITCH_MOD_DECLARE_NONSTD(void) InitManagedDelegates(runFunction run, executeFunction execute, executeBackgroundFunction executeBackground, reloadFunction reload, listFunction list)
{
runDelegate = run;
executeDelegate = execute;
executeBackgroundDelegate = executeBackground;
reloadDelegate = reload;
listDelegate = list;
}
SWITCH_MOD_DECLARE_NONSTD(void) InitManagedSession(ManagedSession *session, inputFunction dtmfDelegate, hangupFunction hangupDelegate)
{
switch_assert(session);
if (!session) {
return;
}
session->setDTMFCallback(NULL, (char *)"");
session->setHangupHook(NULL);
session->dtmfDelegate = dtmfDelegate;
session->hangupDelegate = hangupDelegate;
}
#ifdef _CORE
#ifdef __cplusplus_cli
switch_status_t loadRuntime()
{
char filename[256];
switch_snprintf(filename, 256, "%s%s%s", SWITCH_GLOBAL_dirs.mod_dir, SWITCH_PATH_SEPARATOR, MOD_CORE_DLL);
wchar_t modpath[256];
mbstowcs(modpath, filename, 255);
try {
FreeSwitchCore::mod_dotnet_core = Assembly::LoadFrom(gcnew String(modpath));
}
catch(Exception^ ex) {
IntPtr msg = Marshal::StringToHGlobalAnsi(ex->ToString());
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Assembly::LoadFrom failed: %s\n", static_cast<const char*>(msg.ToPointer()));
Marshal::FreeHGlobal(msg);
return SWITCH_STATUS_FALSE;
}
return SWITCH_STATUS_SUCCESS;
}
switch_status_t findLoader()
{
try {
FreeSwitchCore::loadMethod = FreeSwitchCore::mod_dotnet_core->GetType(MOD_CORE_IMAGE_NAME "." MOD_CORE_CLASS_NAME)->GetMethod("Load");
}
catch(Exception^ ex) {
IntPtr msg = Marshal::StringToHGlobalAnsi(ex->ToString());
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not load " MOD_CORE_IMAGE_NAME "." MOD_CORE_CLASS_NAME " class: %s\n", static_cast<const char*>(msg.ToPointer()));
Marshal::FreeHGlobal(msg);
return SWITCH_STATUS_FALSE;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Found all %s.%s functions.\n", MOD_CORE_IMAGE_NAME, MOD_CORE_CLASS_NAME);
return SWITCH_STATUS_SUCCESS;
}
#endif
#endif
SWITCH_MODULE_LOAD_FUNCTION(mod_core_load)
{
int success;
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Loading mod_core (Common Language Infrastructure), " MOD_CORE_VERSION "\n");
core_globals.pool = pool;
#ifdef _CORE
#ifdef __cplusplus_cli
if (loadRuntime() != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
if (findLoader() != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
try {
Object^ objResult = FreeSwitchCore::loadMethod->Invoke(nullptr, nullptr);
success = *reinterpret_cast<bool^>(objResult);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Load completed successfully.\n");
}
catch(Exception^ ex) {
IntPtr msg = Marshal::StringToHGlobalAnsi(ex->ToString());
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load did not return true. %s\n", static_cast<const char*>(msg.ToPointer()));
Marshal::FreeHGlobal(msg);
return SWITCH_STATUS_FALSE;
}
#endif
#endif
if (success) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Load completed successfully.\n");
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Load did not return true.\n");
return SWITCH_STATUS_FALSE;
}
switch_api_interface_t *api_interface;
switch_application_interface_t *app_interface;
SWITCH_ADD_API(api_interface, "corerun", "Run a module (ExecuteBackground)", core_run_api_function, "<module> [<args>]");
SWITCH_ADD_API(api_interface, "core", "Run a module as an API function (Execute)", core_api_function, "<module> [<args>]");
SWITCH_ADD_APP(app_interface, "core", "Run CLI App", "Run an App on a channel", core_app_function, "<modulename> [<args>]", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_API(api_interface, "corereload", "Force [re]load of a file", core_reload_api_function, "<filename>");
SWITCH_ADD_API(api_interface, "corelist", "Log the list of available APIs and Apps", core_list_api_function, "");
return SWITCH_STATUS_NOUNLOAD;
}
#ifdef _CORE
#pragma unmanaged
#endif
SWITCH_STANDARD_API(core_run_api_function)
{
if (zstr(cmd)) {
stream->write_function(stream, "-ERR no args specified!\n");
return SWITCH_STATUS_SUCCESS;
}
if (executeBackgroundDelegate(cmd)) {
stream->write_function(stream, "+OK\n");
} else {
stream->write_function(stream, "-ERR ExecuteBackground returned false (unknown module or exception?).\n");
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(core_api_function)
{
if (zstr(cmd)) {
stream->write_function(stream, "-ERR no args specified!\n");
return SWITCH_STATUS_SUCCESS;
}
if (!(executeDelegate(cmd, stream, stream->param_event))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Execute failed for %s (unknown module or exception).\n", cmd);
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_APP(core_app_function)
{
if (zstr(data)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No args specified!\n");
return;
}
if (!(runDelegate(data, session))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Application run failed for %s (unknown module or exception).\n", data);
}
}
SWITCH_STANDARD_API(core_reload_api_function)
{
if (zstr(cmd)) {
stream->write_function(stream, "-ERR no args specified!\n");
return SWITCH_STATUS_SUCCESS;
}
if (!(reloadDelegate(cmd))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Execute failed for %s (unknown module or exception).\n", cmd);
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(core_list_api_function)
{
listDelegate(cmd, stream, stream->param_event);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_END_EXTERN_C