changes in SMS drivers and module API (added pointer to server config object in init...
[public/netxms.git] / src / server / core / sms.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2016 Victor Kirhenshtein
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 **
19 ** File: sms.cpp
20 **
21 **/
22
23 #include "nxcore.h"
24
25 /**
26 * Server config
27 */
28 extern Config g_serverConfig;
29
30 /**
31 * SMS structure
32 */
33 typedef struct
34 {
35 TCHAR szRcpt[MAX_RCPT_ADDR_LEN];
36 TCHAR szText[160];
37 } SMS;
38
39 /**
40 * Static data
41 */
42 static Queue s_smsQueue;
43 static bool (* s_fpDrvSendMsg)(const TCHAR *, const TCHAR *);
44 static void (* s_fpDrvUnload)();
45 static THREAD s_senderThread = INVALID_THREAD_HANDLE;
46
47 /**
48 * Sender thread
49 */
50 static THREAD_RESULT THREAD_CALL SenderThread(void *pArg)
51 {
52 SMS *pMsg;
53
54 while(1)
55 {
56 pMsg = (SMS *)s_smsQueue.getOrBlock();
57 if (pMsg == INVALID_POINTER_VALUE)
58 break;
59
60 DbgPrintf(4, _T("SMS sender: rcpt=%s text=\"%s\""), pMsg->szRcpt, pMsg->szText);
61 int tries = 3;
62 do
63 {
64 if (s_fpDrvSendMsg(pMsg->szRcpt, pMsg->szText))
65 break;
66 DbgPrintf(3, _T("Failed to send SMS (will%s retry)"), (tries > 1) ? _T("") : _T(" not"));
67 }
68 while(--tries > 0);
69
70 if (tries == 0)
71 {
72 DbgPrintf(3, _T("Failed to send SMS (complete failure)"));
73 PostEvent(EVENT_SMS_FAILURE, g_dwMgmtNode, "s", pMsg->szRcpt);
74 }
75
76 free(pMsg);
77 }
78 return THREAD_OK;
79 }
80
81 /**
82 * Initialize SMS subsystem
83 */
84 void InitSMSSender()
85 {
86 TCHAR szDriver[MAX_PATH], szDrvConfig[MAX_CONFIG_VALUE];
87
88 ConfigReadStr(_T("SMSDriver"), szDriver, MAX_PATH, _T("<none>"));
89 ConfigReadStr(_T("SMSDrvConfig"), szDrvConfig, MAX_CONFIG_VALUE, _T(""));
90 if (_tcsicmp(szDriver, _T("<none>")))
91 {
92 TCHAR szErrorText[256];
93 HMODULE hModule;
94
95 hModule = DLOpen(szDriver, szErrorText);
96 if (hModule != NULL)
97 {
98 bool (* DrvInit)(const TCHAR *, Config *);
99
100 DrvInit = (bool (*)(const TCHAR *, Config *))DLGetSymbolAddr(hModule, "SMSDriverInit", szErrorText);
101 s_fpDrvSendMsg = (bool (*)(const TCHAR *, const TCHAR *))DLGetSymbolAddr(hModule, "SMSDriverSend", szErrorText);
102 s_fpDrvUnload = (void (*)())DLGetSymbolAddr(hModule, "SMSDriverUnload", szErrorText);
103 if ((DrvInit != NULL) && (s_fpDrvSendMsg != NULL) && (s_fpDrvUnload != NULL))
104 {
105 if (DrvInit(szDrvConfig, &g_serverConfig))
106 {
107 s_senderThread = ThreadCreateEx(SenderThread, 0, NULL);
108 }
109 else
110 {
111 nxlog_write(MSG_SMSDRV_INIT_FAILED, EVENTLOG_ERROR_TYPE, "s", szDriver);
112 DLClose(hModule);
113 }
114 }
115 else
116 {
117 nxlog_write(MSG_SMSDRV_NO_ENTRY_POINTS, EVENTLOG_ERROR_TYPE, "s", szDriver);
118 DLClose(hModule);
119 }
120 }
121 else
122 {
123 nxlog_write(MSG_DLOPEN_FAILED, EVENTLOG_ERROR_TYPE, "ss", szDriver, szErrorText);
124 }
125 }
126 }
127
128 /**
129 * Shutdown SMS sender
130 */
131 void ShutdownSMSSender()
132 {
133 s_smsQueue.clear();
134 s_smsQueue.put(INVALID_POINTER_VALUE);
135 if (s_senderThread != INVALID_THREAD_HANDLE)
136 ThreadJoin(s_senderThread);
137 }
138
139 /**
140 * Post SMS to queue
141 */
142 void NXCORE_EXPORTABLE PostSMS(const TCHAR *pszRcpt, const TCHAR *pszText)
143 {
144 SMS *pMsg = (SMS *)malloc(sizeof(SMS));
145 nx_strncpy(pMsg->szRcpt, pszRcpt, MAX_RCPT_ADDR_LEN);
146 nx_strncpy(pMsg->szText, pszText, 160);
147 s_smsQueue.put(pMsg);
148 }