Commit | Line | Data |
---|---|---|
4899db4d | 1 | /* |
f22c4f7c | 2 | ** NetXMS - Network Management System |
db091a1f | 3 | ** Copyright (C) 2003-2016 Victor Kirhenshtein |
f22c4f7c VK |
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: mobile.cpp | |
f22c4f7c VK |
20 | **/ |
21 | ||
22 | #include "nxcore.h" | |
23 | ||
24 | /** | |
25 | * Default constructor | |
26 | */ | |
6fd6de0a | 27 | MobileDevice::MobileDevice() : DataCollectionTarget() |
f22c4f7c VK |
28 | { |
29 | m_lastReportTime = 0; | |
30 | m_deviceId = NULL; | |
31 | m_vendor = NULL; | |
32 | m_model = NULL; | |
33 | m_serialNumber = NULL; | |
34 | m_osName = NULL; | |
35 | m_osVersion = NULL; | |
36 | m_userId = NULL; | |
171c2fd6 | 37 | m_batteryLevel = -1; |
f22c4f7c VK |
38 | } |
39 | ||
40 | /** | |
41 | * Constructor for creating new mobile device object | |
42 | */ | |
6fd6de0a | 43 | MobileDevice::MobileDevice(const TCHAR *name, const TCHAR *deviceId) : DataCollectionTarget(name) |
f22c4f7c VK |
44 | { |
45 | m_lastReportTime = 0; | |
46 | m_deviceId = _tcsdup(deviceId); | |
47 | m_vendor = NULL; | |
48 | m_model = NULL; | |
49 | m_serialNumber = NULL; | |
50 | m_osName = NULL; | |
51 | m_osVersion = NULL; | |
52 | m_userId = NULL; | |
171c2fd6 | 53 | m_batteryLevel = -1; |
f22c4f7c VK |
54 | } |
55 | ||
56 | /** | |
57 | * Destructor | |
58 | */ | |
59 | MobileDevice::~MobileDevice() | |
60 | { | |
61 | safe_free(m_deviceId); | |
62 | safe_free(m_vendor); | |
63 | safe_free(m_model); | |
64 | safe_free(m_serialNumber); | |
65 | safe_free(m_osName); | |
66 | safe_free(m_osVersion); | |
67 | safe_free(m_userId); | |
68 | } | |
9aa67910 VK |
69 | |
70 | /** | |
71 | * Create object from database data | |
72 | */ | |
9bd1bace | 73 | bool MobileDevice::loadFromDatabase(DB_HANDLE hdb, UINT32 dwId) |
9aa67910 | 74 | { |
c42b4551 | 75 | m_id = dwId; |
9aa67910 | 76 | |
9bd1bace | 77 | if (!loadCommonProperties(hdb)) |
9aa67910 | 78 | { |
4dd963e9 | 79 | DbgPrintf(2, _T("Cannot load common properties for mobile device object %d"), dwId); |
9bd1bace | 80 | return false; |
9aa67910 VK |
81 | } |
82 | ||
83 | TCHAR query[256]; | |
c42b4551 | 84 | _sntprintf(query, 256, _T("SELECT device_id,vendor,model,serial_number,os_name,os_version,user_id,battery_level FROM mobile_devices WHERE id=%d"), (int)m_id); |
9bd1bace | 85 | DB_RESULT hResult = DBSelect(hdb, query); |
9aa67910 | 86 | if (hResult == NULL) |
9bd1bace | 87 | return false; |
9aa67910 VK |
88 | |
89 | m_deviceId = DBGetField(hResult, 0, 0, NULL, 0); | |
90 | m_vendor = DBGetField(hResult, 0, 1, NULL, 0); | |
91 | m_model = DBGetField(hResult, 0, 2, NULL, 0); | |
92 | m_serialNumber = DBGetField(hResult, 0, 3, NULL, 0); | |
93 | m_osName = DBGetField(hResult, 0, 4, NULL, 0); | |
94 | m_osVersion = DBGetField(hResult, 0, 5, NULL, 0); | |
95 | m_userId = DBGetField(hResult, 0, 6, NULL, 0); | |
171c2fd6 | 96 | m_batteryLevel = DBGetFieldLong(hResult, 0, 7); |
9aa67910 VK |
97 | DBFreeResult(hResult); |
98 | ||
99 | // Load DCI and access list | |
9bd1bace VK |
100 | loadACLFromDB(hdb); |
101 | loadItemsFromDB(hdb); | |
9aa67910 | 102 | for(int i = 0; i < m_dcObjects->size(); i++) |
9bd1bace VK |
103 | if (!m_dcObjects->get(i)->loadThresholdsFromDB(hdb)) |
104 | return false; | |
9aa67910 | 105 | |
9bd1bace | 106 | return true; |
9aa67910 VK |
107 | } |
108 | ||
109 | /** | |
110 | * Save object to database | |
111 | */ | |
b4277312 | 112 | bool MobileDevice::saveToDatabase(DB_HANDLE hdb) |
9aa67910 VK |
113 | { |
114 | // Lock object's access | |
c42b4551 | 115 | lockProperties(); |
9aa67910 | 116 | |
3d48d1b4 | 117 | bool success = saveCommonProperties(hdb); |
9aa67910 | 118 | |
3d48d1b4 VK |
119 | if (success && (m_modified & MODIFY_OTHER)) |
120 | { | |
121 | DB_STATEMENT hStmt; | |
122 | if (IsDatabaseRecordExist(hdb, _T("mobile_devices"), _T("id"), m_id)) | |
123 | hStmt = DBPrepare(hdb, _T("UPDATE mobile_devices SET device_id=?,vendor=?,model=?,serial_number=?,os_name=?,os_version=?,user_id=?,battery_level=? WHERE id=?")); | |
124 | else | |
125 | hStmt = DBPrepare(hdb, _T("INSERT INTO mobile_devices (device_id,vendor,model,serial_number,os_name,os_version,user_id,battery_level,id) VALUES (?,?,?,?,?,?,?,?,?)")); | |
126 | if (hStmt != NULL) | |
127 | { | |
128 | DBBind(hStmt, 1, DB_SQLTYPE_VARCHAR, CHECK_NULL_EX(m_deviceId), DB_BIND_STATIC); | |
129 | DBBind(hStmt, 2, DB_SQLTYPE_VARCHAR, CHECK_NULL_EX(m_vendor), DB_BIND_STATIC); | |
130 | DBBind(hStmt, 3, DB_SQLTYPE_VARCHAR, CHECK_NULL_EX(m_model), DB_BIND_STATIC); | |
131 | DBBind(hStmt, 4, DB_SQLTYPE_VARCHAR, CHECK_NULL_EX(m_serialNumber), DB_BIND_STATIC); | |
132 | DBBind(hStmt, 5, DB_SQLTYPE_VARCHAR, CHECK_NULL_EX(m_osName), DB_BIND_STATIC); | |
133 | DBBind(hStmt, 6, DB_SQLTYPE_VARCHAR, CHECK_NULL_EX(m_osVersion), DB_BIND_STATIC); | |
134 | DBBind(hStmt, 7, DB_SQLTYPE_VARCHAR, CHECK_NULL_EX(m_userId), DB_BIND_STATIC); | |
135 | DBBind(hStmt, 8, DB_SQLTYPE_INTEGER, m_batteryLevel); | |
136 | DBBind(hStmt, 9, DB_SQLTYPE_INTEGER, m_id); | |
137 | ||
138 | success = DBExecute(hStmt); | |
139 | ||
140 | DBFreeStatement(hStmt); | |
141 | } | |
142 | else | |
143 | { | |
144 | success = false; | |
145 | } | |
146 | } | |
9aa67910 VK |
147 | |
148 | // Save data collection items | |
3d48d1b4 | 149 | if (success && (m_modified & MODIFY_DATA_COLLECTION)) |
9aa67910 | 150 | { |
b06436f4 | 151 | lockDciAccess(false); |
9aa67910 | 152 | for(int i = 0; i < m_dcObjects->size(); i++) |
e7450f3b | 153 | m_dcObjects->get(i)->saveToDatabase(hdb); |
9aa67910 VK |
154 | unlockDciAccess(); |
155 | } | |
156 | ||
157 | // Save access list | |
3d48d1b4 VK |
158 | if (success) |
159 | success = saveACLToDB(hdb); | |
9aa67910 VK |
160 | |
161 | // Clear modifications flag and unlock object | |
3d48d1b4 VK |
162 | if (success) |
163 | m_modified = 0; | |
c42b4551 | 164 | unlockProperties(); |
9aa67910 | 165 | |
3d48d1b4 | 166 | return success; |
9aa67910 VK |
167 | } |
168 | ||
169 | /** | |
170 | * Delete object from database | |
171 | */ | |
c42b4551 | 172 | bool MobileDevice::deleteFromDatabase(DB_HANDLE hdb) |
9aa67910 | 173 | { |
c42b4551 | 174 | bool success = DataCollectionTarget::deleteFromDatabase(hdb); |
22ee6d97 VK |
175 | if (success) |
176 | success = executeQueryOnObject(hdb, _T("DELETE FROM mobile_devices WHERE id=?")); | |
177 | return success; | |
9aa67910 VK |
178 | } |
179 | ||
180 | /** | |
181 | * Create CSCP message with object's data | |
182 | */ | |
8fe90adb | 183 | void MobileDevice::fillMessageInternal(NXCPMessage *msg) |
9aa67910 | 184 | { |
8fe90adb | 185 | DataCollectionTarget::fillMessageInternal(msg); |
e83d726c | 186 | |
b368969c VK |
187 | msg->setField(VID_DEVICE_ID, CHECK_NULL_EX(m_deviceId)); |
188 | msg->setField(VID_VENDOR, CHECK_NULL_EX(m_vendor)); | |
189 | msg->setField(VID_MODEL, CHECK_NULL_EX(m_model)); | |
190 | msg->setField(VID_SERIAL_NUMBER, CHECK_NULL_EX(m_serialNumber)); | |
191 | msg->setField(VID_OS_NAME, CHECK_NULL_EX(m_osName)); | |
192 | msg->setField(VID_OS_VERSION, CHECK_NULL_EX(m_osVersion)); | |
193 | msg->setField(VID_USER_ID, CHECK_NULL_EX(m_userId)); | |
194 | msg->setField(VID_BATTERY_LEVEL, (UINT32)m_batteryLevel); | |
195 | msg->setField(VID_LAST_CHANGE_TIME, (QWORD)m_lastReportTime); | |
9aa67910 VK |
196 | } |
197 | ||
198 | /** | |
199 | * Modify object from message | |
200 | */ | |
8fe90adb | 201 | UINT32 MobileDevice::modifyFromMessageInternal(NXCPMessage *pRequest) |
9aa67910 | 202 | { |
8fe90adb | 203 | return DataCollectionTarget::modifyFromMessageInternal(pRequest); |
9aa67910 | 204 | } |
6583a0f8 VK |
205 | |
206 | /** | |
207 | * Update system information from NXCP message | |
208 | */ | |
b368969c | 209 | void MobileDevice::updateSystemInfo(NXCPMessage *msg) |
6583a0f8 | 210 | { |
c42b4551 | 211 | lockProperties(); |
6583a0f8 | 212 | |
63862632 VK |
213 | m_lastReportTime = time(NULL); |
214 | ||
3d48d1b4 | 215 | free(m_vendor); |
b368969c | 216 | m_vendor = msg->getFieldAsString(VID_VENDOR); |
6583a0f8 | 217 | |
3d48d1b4 | 218 | free(m_model); |
b368969c | 219 | m_model = msg->getFieldAsString(VID_MODEL); |
6583a0f8 | 220 | |
3d48d1b4 | 221 | free(m_serialNumber); |
b368969c | 222 | m_serialNumber = msg->getFieldAsString(VID_SERIAL_NUMBER); |
6583a0f8 | 223 | |
3d48d1b4 | 224 | free(m_osName); |
b368969c | 225 | m_osName = msg->getFieldAsString(VID_OS_NAME); |
6583a0f8 | 226 | |
3d48d1b4 | 227 | free(m_osVersion); |
b368969c | 228 | m_osVersion = msg->getFieldAsString(VID_OS_VERSION); |
6583a0f8 | 229 | |
3d48d1b4 | 230 | free(m_userId); |
b368969c | 231 | m_userId = msg->getFieldAsString(VID_USER_NAME); |
6583a0f8 | 232 | |
3d48d1b4 | 233 | setModified(MODIFY_OTHER); |
c42b4551 | 234 | unlockProperties(); |
6583a0f8 VK |
235 | } |
236 | ||
237 | /** | |
238 | * Update status from NXCP message | |
239 | */ | |
b368969c | 240 | void MobileDevice::updateStatus(NXCPMessage *msg) |
6583a0f8 | 241 | { |
c42b4551 | 242 | lockProperties(); |
6583a0f8 | 243 | |
63862632 VK |
244 | m_lastReportTime = time(NULL); |
245 | ||
4101571e | 246 | int type = msg->getFieldType(VID_BATTERY_LEVEL); |
b368969c VK |
247 | if (type == NXCP_DT_INT32) |
248 | m_batteryLevel = msg->getFieldAsInt32(VID_BATTERY_LEVEL); | |
249 | else if (type == NXCP_DT_INT16) | |
250 | m_batteryLevel = (int)msg->getFieldAsInt16(VID_BATTERY_LEVEL); | |
6583a0f8 VK |
251 | else |
252 | m_batteryLevel = -1; | |
253 | ||
5c44534b | 254 | if (msg->isFieldExist(VID_GEOLOCATION_TYPE)) |
4899db4d | 255 | { |
6583a0f8 | 256 | m_geoLocation = GeoLocation(*msg); |
4899db4d | 257 | addLocationToHistory(); |
258 | } | |
6583a0f8 | 259 | |
5c44534b | 260 | if (msg->isFieldExist(VID_IP_ADDRESS)) |
c75e9ee4 | 261 | m_ipAddress = msg->getFieldAsInetAddress(VID_IP_ADDRESS); |
6583a0f8 | 262 | |
c75e9ee4 | 263 | TCHAR temp[64]; |
6583a0f8 | 264 | DbgPrintf(5, _T("Mobile device %s [%d] updated from agent (battery=%d addr=%s loc=[%s %s])"), |
c75e9ee4 | 265 | m_name, (int)m_id, m_batteryLevel, m_ipAddress.toString(temp), |
6583a0f8 VK |
266 | m_geoLocation.getLatitudeAsString(), m_geoLocation.getLongitudeAsString()); |
267 | ||
3d48d1b4 | 268 | setModified(MODIFY_OTHER); |
c42b4551 | 269 | unlockProperties(); |
6583a0f8 | 270 | } |
eb0c0312 VK |
271 | |
272 | /** | |
273 | * Get value for server's internal parameter | |
274 | */ | |
17b1ab4a | 275 | UINT32 MobileDevice::getInternalItem(const TCHAR *param, size_t bufSize, TCHAR *buffer) |
eb0c0312 | 276 | { |
967893bb | 277 | UINT32 rc = DataCollectionTarget::getInternalItem(param, bufSize, buffer); |
192cb389 VK |
278 | if (rc != DCE_NOT_SUPPORTED) |
279 | return rc; | |
eb0c0312 VK |
280 | rc = DCE_SUCCESS; |
281 | ||
282 | if (!_tcsicmp(param, _T("MobileDevice.BatteryLevel"))) | |
283 | { | |
284 | _sntprintf(buffer, bufSize, _T("%d"), m_batteryLevel); | |
285 | } | |
286 | else if (!_tcsicmp(param, _T("MobileDevice.DeviceId"))) | |
287 | { | |
288 | nx_strncpy(buffer, CHECK_NULL_EX(m_deviceId), bufSize); | |
289 | } | |
290 | else if (!_tcsicmp(param, _T("MobileDevice.LastReportTime"))) | |
291 | { | |
292 | _sntprintf(buffer, bufSize, INT64_FMT, (INT64)m_lastReportTime); | |
293 | } | |
294 | else if (!_tcsicmp(param, _T("MobileDevice.Model"))) | |
295 | { | |
296 | nx_strncpy(buffer, CHECK_NULL_EX(m_model), bufSize); | |
297 | } | |
298 | else if (!_tcsicmp(param, _T("MobileDevice.OS.Name"))) | |
299 | { | |
300 | nx_strncpy(buffer, CHECK_NULL_EX(m_osName), bufSize); | |
301 | } | |
302 | else if (!_tcsicmp(param, _T("MobileDevice.OS.Version"))) | |
303 | { | |
304 | nx_strncpy(buffer, CHECK_NULL_EX(m_osVersion), bufSize); | |
305 | } | |
306 | else if (!_tcsicmp(param, _T("MobileDevice.SerialNumber"))) | |
307 | { | |
308 | nx_strncpy(buffer, CHECK_NULL_EX(m_serialNumber), bufSize); | |
309 | } | |
310 | else if (!_tcsicmp(param, _T("MobileDevice.Vendor"))) | |
311 | { | |
312 | nx_strncpy(buffer, CHECK_NULL_EX(m_vendor), bufSize); | |
313 | } | |
314 | else if (!_tcsicmp(param, _T("MobileDevice.UserId"))) | |
315 | { | |
316 | nx_strncpy(buffer, CHECK_NULL_EX(m_userId), bufSize); | |
317 | } | |
318 | else | |
319 | { | |
320 | rc = DCE_NOT_SUPPORTED; | |
321 | } | |
322 | ||
323 | return rc; | |
324 | } | |
26e2b253 VK |
325 | |
326 | /** | |
327 | * Calculate compound status | |
328 | */ | |
329 | void MobileDevice::calculateCompoundStatus(BOOL bForcedRecalc) | |
330 | { | |
331 | NetObj::calculateCompoundStatus(bForcedRecalc); | |
332 | ||
333 | // Assume normal status by default for mobile device | |
db091a1f | 334 | if (m_status == STATUS_UNKNOWN) |
26e2b253 | 335 | { |
c42b4551 | 336 | lockProperties(); |
db091a1f | 337 | m_status = STATUS_NORMAL; |
3d48d1b4 | 338 | setModified(MODIFY_RUNTIME); |
c42b4551 | 339 | unlockProperties(); |
26e2b253 VK |
340 | } |
341 | } | |
297a88eb VK |
342 | |
343 | /** | |
344 | * Create NXSL object for this object | |
345 | */ | |
346 | NXSL_Value *MobileDevice::createNXSLObject() | |
347 | { | |
348 | return new NXSL_Value(new NXSL_Object(&g_nxslMobileDeviceClass, this)); | |
349 | } | |
950b229b VK |
350 | |
351 | /** | |
352 | * Serialize object to JSON | |
353 | */ | |
354 | json_t *MobileDevice::toJson() | |
355 | { | |
356 | json_t *root = DataCollectionTarget::toJson(); | |
357 | json_object_set_new(root, "lastReportTime", json_integer(m_lastReportTime)); | |
358 | json_object_set_new(root, "deviceId", json_string_t(m_deviceId)); | |
359 | json_object_set_new(root, "vendor", json_string_t(m_vendor)); | |
360 | json_object_set_new(root, "model", json_string_t(m_model)); | |
361 | json_object_set_new(root, "serialNumber", json_string_t(m_serialNumber)); | |
362 | json_object_set_new(root, "osName", json_string_t(m_osName)); | |
363 | json_object_set_new(root, "osVersion", json_string_t(m_osVersion)); | |
364 | json_object_set_new(root, "userId", json_string_t(m_userId)); | |
365 | json_object_set_new(root, "batteryLevel", json_integer(m_batteryLevel)); | |
366 | json_object_set_new(root, "ipAddress", m_ipAddress.toJson()); | |
367 | return root; | |
368 | } |