data push support for mobile devices
authorVictor Kirhenshtein <victor@netxms.org>
Wed, 12 Mar 2014 11:06:12 +0000 (13:06 +0200)
committerVictor Kirhenshtein <victor@netxms.org>
Wed, 12 Mar 2014 11:06:12 +0000 (13:06 +0200)
doc/misc/embedded_nxcp.c
src/server/core/mdsession.cpp
src/server/include/nms_core.h
src/server/tools/nxdbmgr/check.cpp

index 1f785ae..dfb2f53 100644 (file)
@@ -216,16 +216,42 @@ uint32_t nxcp_finalize()
 #if 0
 
 /**
- * Example
+ * Login
  */
-void example()
+void login(const char *login, const char *passwd, const char *deviceId)
 {
    nxcp_init_message();
-   nxcp_add_int16(1, 120);
-   nxcp_add_string(2, "test message");
+   nxcp_add_string(1, login);
+   nxcp_add_string(2, password);
+   nxcp_add_string(433, deviceId);
    uint32_t l = nxcp_finalize();
    /* now send l bytes from nxcp_message to the network */
    send(sock, nxcp_message, l, 0);
 }
 
+/**
+ * Data push example
+ */
+void data_push()
+{
+   nxcp_init_message();
+
+   uint32_t id = 0x10000000;
+   
+   // first parameter
+   nxcp_add_int32(id++, 0);
+   nxcp_add_string(id++, "Parameter1");
+   nxcp_add_string(id++, "value1");
+
+   // second parameter
+   nxcp_add_int32(id++, 0);
+   nxcp_add_string(id++, "Parameter2");
+   nxcp_add_string(id++, "value2");
+   
+   // parameter count
+   nxcp_add_int32(111, 2);
+   
+   send(sock, nxcp_message, l, 0);
+}
+
 #endif
index a44b108..2b008ac 100644 (file)
@@ -196,6 +196,13 @@ void MobileDeviceSession::readThread()
          break;
       }
 
+      // Receive timeout
+      if (iErr == 3)
+      {
+         debugPrintf(5, _T("RecvNXCPMessageEx: receive timeout"));
+         break;
+      }
+
       // Check if message is too large
       if (iErr == 1)
       {
@@ -225,7 +232,6 @@ void MobileDeviceSession::readThread()
          debugPrintf(8, _T("Message dump:\n%s"), (const TCHAR *)msgDump);
       }
 
-      // Special handling for raw messages
       WORD wFlags = ntohs(pRawMsg->wFlags);
       if (!(wFlags & MF_BINARY))
       {
@@ -376,6 +382,9 @@ void MobileDeviceSession::processingThread()
                        case CMD_REPORT_DEVICE_STATUS:
                                updateDeviceStatus(pMsg);
                                break;
+         case CMD_PUSH_DCI_DATA:
+            pushData(pMsg);
+            break;
          default:
             // Pass message to loaded modules
             for(i = 0; i < g_dwNumModules; i++)
@@ -711,3 +720,105 @@ void MobileDeviceSession::updateDeviceStatus(CSCPMessage *request)
 
    sendMessage(&msg);
 }
+
+/**
+ * Push DCI data
+ */
+void MobileDeviceSession::pushData(CSCPMessage *request)
+{
+   CSCPMessage msg;
+
+   msg.SetCode(CMD_REQUEST_COMPLETED);
+   msg.SetId(request->GetId());
+
+       MobileDevice *device = (MobileDevice *)FindObjectById(m_deviceObjectId, OBJECT_MOBILEDEVICE);
+       if (device != NULL)
+       {
+      int count = (int)request->GetVariableLong(VID_NUM_ITEMS);
+      if (count > 0)
+      {
+         DCItem **dciList = (DCItem **)malloc(sizeof(DCItem *) * count);
+         TCHAR **valueList = (TCHAR **)malloc(sizeof(TCHAR *) * count);
+         memset(valueList, 0, sizeof(TCHAR *) * count);
+
+         int i;
+         UINT32 varId = VID_PUSH_DCI_DATA_BASE;
+         bool ok = true;
+         for(i = 0; (i < count) && ok; i++)
+         {
+            ok = false;
+
+            // find DCI by ID or name (if ID==0)
+            UINT32 dciId = request->GetVariableLong(varId++);
+                     DCObject *pItem;
+            if (dciId != 0)
+            {
+               pItem = device->getDCObjectById(dciId);
+            }
+            else
+            {
+               TCHAR name[MAX_PARAM_NAME];
+               request->GetVariableStr(varId++, name, MAX_PARAM_NAME);
+               pItem = device->getDCObjectByName(name);
+            }
+
+            if ((pItem != NULL) && (pItem->getType() == DCO_TYPE_ITEM))
+            {
+               if (pItem->getDataSource() == DS_PUSH_AGENT)
+               {
+                  dciList[i] = (DCItem *)pItem;
+                  valueList[i] = request->GetVariableStr(varId++);
+                  ok = true;
+               }
+               else
+               {
+                  msg.SetVariable(VID_RCC, RCC_NOT_PUSH_DCI);
+               }
+            }
+            else
+            {
+               msg.SetVariable(VID_RCC, RCC_INVALID_DCI_ID);
+            }
+         }
+
+         // If all items was checked OK, push data
+         if (ok)
+         {
+            time_t t = (time_t)request->GetVariableLong(VID_TIMESTAMP);
+            if (t == 0)
+            {
+               time(&t);
+            }
+
+            for(i = 0; i < count; i++)
+            {
+                             if (_tcslen(valueList[i]) >= MAX_DCI_STRING_VALUE)
+                                     valueList[i][MAX_DCI_STRING_VALUE - 1] = 0;
+                             device->processNewDCValue(dciList[i], t, valueList[i]);
+                             dciList[i]->setLastPollTime(t);
+            }
+            msg.SetVariable(VID_RCC, RCC_SUCCESS);
+         }
+         else
+         {
+            msg.SetVariable(VID_FAILED_DCI_INDEX, i - 1);
+         }
+
+         // Cleanup
+         for(i = 0; i < count; i++)
+            safe_free(valueList[i]);
+         safe_free(valueList);
+         free(dciList);
+      }
+      else
+      {
+         msg.SetVariable(VID_RCC, RCC_INVALID_ARGUMENT);
+      }
+   }
+       else
+       {
+               msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
+       }
+
+   sendMessage(&msg);
+}
index 529b67c..56fd4d4 100644 (file)
@@ -338,6 +338,7 @@ private:
    void login(CSCPMessage *pRequest);
    void updateDeviceInfo(CSCPMessage *pRequest);
    void updateDeviceStatus(CSCPMessage *pRequest);
+   void pushData(CSCPMessage *request);
 
 public:
    MobileDeviceSession(SOCKET hSocket, struct sockaddr *addr);
index 333f9ae..e29a6a3 100644 (file)
@@ -194,11 +194,9 @@ static BOOL FindSubnetForNode(DWORD id, const TCHAR *name)
        return success;
 }
 
-
-//
-// Check zone objects
-//
-
+/**
+ * Check zone objects
+ */
 static void CheckZones()
 {
    DB_RESULT hResult, hResult2;