source: trunk/ETSI-Testsuites/ETSI_auto_IOT/adapter/src/Capture/ConnectionController.cpp @ 27

Last change on this file since 27 was 22, checked in by rings, 14 years ago
  • Property svn:executable set to *
File size: 7.6 KB
Line 
1/**
2 * @file ConnectionController.cpp
3 * @author Tomas Urban
4 * @version 0.5
5 * @date 23/07/2009
6 */
7#include "ConnectionController.h"
8#include "PCAPLiveCapture.h"
9#include "Logger/Logger.h"
10#include "CaptureFactory.h"
11#include "Messages/TrafficCaptureMessageFactory.h"
12#include "Messages/CommonTrafficCaptureMessages.h"
13#include <boost/filesystem.hpp>
14
15ConnectionController::ConnectionController(SOCKET_TYPE hSocket) :
16        m_hSocket(hSocket),
17        m_pCapture(0)
18{
19}
20
21ConnectionController::~ConnectionController(void)
22{
23        CaptureFactory::Instance().DisposeCaptureInstance(m_pCapture);
24}
25
26void ConnectionController::SendSimpleReply(CommonReplyMessage & reply, bool bRes)
27{
28        reply.SetResult(bRes);
29        send(m_hSocket, reply.GetEncodedMessage(), reply.GetEncodedDataLength(), 0);
30}
31
32void ConnectionController::ProcessMessage(const struct TMessageHeader & header, const char * pPayload,
33                                                                                  TcpipDispatch &td)
34{
35        std::string s = "Control message received (id: ";
36        s += boost::lexical_cast<std::string>(header.nMsgType);
37        s += ", len: ";
38        s += boost::lexical_cast<std::string>(header.nMsgLen);
39        s += ")";
40        Logger::Instance().LogDebug(s);
41        TrafficCaptureMessage * pMsg = TrafficCaptureMessageFactory::Instance().CreateMessage(
42                header.nMsgType, pPayload, header.nMsgLen);
43        if (!pMsg)
44                return;
45        const char * pszIgnoreWarn = "Warning: message ignored; the capturing device hasn't been created yet";
46        switch (pMsg->GetId())
47        {
48        case OPEN_DEVICE_REQ:
49                {
50                        Logger::Instance().LogInfo("OpenDeviceRequest message received");
51                        ECaptureInitResult res = ECaptureInit_Failed;
52                        if (m_pCapture == 0)
53                        {
54                                Logger::Instance().LogDebug("Creating capture instance...");
55                                OpenDeviceRequest * pReq = dynamic_cast<OpenDeviceRequest*>(pMsg);
56                                m_pCapture = CaptureFactory::Instance().CreateCaptureInstance(
57                                        pReq->GetCaptureType(), pReq->GetCaptureMode());                               
58                                if (m_pCapture != 0)
59                                {
60                                        m_pCapture->InitDispatch(&td);
61                                        m_pCapture->SetStartOffset(pReq->GetTimestamp());
62                                        Logger::Instance().LogDebug("Initializing capture instance...");
63                                        res = m_pCapture->OpenDevice(pReq->GetParameters());
64                                        std::string sFile = pReq->GetCaptureFile();
65                                        if (res != ECaptureInit_Failed && sFile.length() > 0)
66                                        {
67                                                if (!m_pCapture->SetCaptureFile(sFile))
68                                                        res = ECaptureInit_Failed;
69                                        }
70                                        if (res == ECaptureInit_Failed)
71                                        {
72                                                CaptureFactory::Instance().DisposeCaptureInstance(m_pCapture);
73                                                m_pCapture = 0;
74                                        }
75                                }                               
76                        }
77                        else
78                                Logger::Instance().LogWarning("Capture device has been already created");
79                        OpenDeviceReply reply;
80                        reply.SetResult(res);
81                        send(m_hSocket, reply.GetEncodedMessage(), reply.GetEncodedDataLength(), 0);
82                        Logger::Instance().LogDebug("OpenDeviceReply message sent");
83                }
84                break;
85        case SET_FILTER_REQ:
86                Logger::Instance().LogInfo("SetFilterRequest message received");
87                {
88                        bool bRes = (m_pCapture != 0);
89                        if (bRes)
90                        {
91                                SetFilterRequest * pReq = dynamic_cast<SetFilterRequest*>(pMsg);
92                                std::string sFilter = pReq->GetFilter();
93                                std::string s = "The received filter value is: ";
94                                s += sFilter;
95                                Logger::Instance().LogDebug(s);
96                                bRes = m_pCapture->SetFilter(sFilter);
97                        }
98                        else
99                                Logger::Instance().LogWarning(pszIgnoreWarn);
100                        SetFilterReply reply;
101                        SendSimpleReply(reply, !bRes);
102                        Logger::Instance().LogDebug("SetFilterReply message sent");
103                }
104                break;
105        case START_CAPTURE_REQ:
106                {
107                        Logger::Instance().LogInfo("StartCaptureRequest message received");
108                        if (m_pCapture)
109                                m_pCapture->StartCapture();
110                        else
111                                Logger::Instance().LogWarning(pszIgnoreWarn);
112                        StartCaptureReply reply;
113                        SendSimpleReply(reply, m_pCapture == 0);
114                }
115                Logger::Instance().LogDebug("StartCaptureReply message sent");
116                break;
117        case STOP_CAPTURE_REQ:
118                {
119                        Logger::Instance().LogInfo("StopCaptureRequest message received");
120                        if (m_pCapture)
121                                m_pCapture->StopCapture();
122                        else
123                                Logger::Instance().LogWarning(pszIgnoreWarn);
124                        StopCaptureReply reply;
125                        SendSimpleReply(reply, m_pCapture == 0);
126                        Logger::Instance().LogDebug("StopCaptureReply message sent");
127                }
128                break;
129        case MERGE_FILES_REQ:
130                {
131                        MergePcapFilesRequest * pReq = dynamic_cast<MergePcapFilesRequest*>(pMsg);
132                        Logger::Instance().LogInfo("MergePcapFilesRequest message received");
133                        MergePcapFilesReply reply;
134                        bool bRes;
135                        std::vector<std::string> vsFiles = pReq->GetFilesToMerge();
136                        if (bRes = vsFiles.size() > 0)
137                        {
138                                boost::filesystem::path targetFile = pReq->GetMergePath();
139                                targetFile /= "mergefile.pcap";                         
140                                if (boost::filesystem::exists(targetFile))
141                                        try
142                                        {
143                                                boost::filesystem::remove(targetFile);
144                                                Logger::Instance().LogDebug(
145                                                        "Merge file from a previous session has been successfully removed");
146                                        }
147                                        catch (boost::filesystem::filesystem_error)                                     
148                                        {
149                                                Logger::Instance().LogError(
150                                                        "Merge file from a previous session could not be removed");
151                                                bRes = false;
152                                        }
153                                else
154                                        Logger::Instance().LogDebug("No merge file from a previous session");
155                                if (bRes)
156                                {
157                                        boost::filesystem::path mergecapPath = pReq->GetMergecapDirectory();
158                                        mergecapPath /= "mergecap";
159                                        std::string sCmd = "\"";
160#ifdef WIN32
161                                        sCmd += "\"";
162#endif
163                                        sCmd += mergecapPath.string();
164                                        sCmd += "\" -w \"";
165                                        sCmd += targetFile.string();
166                                        sCmd += "\"";
167                                        for (unsigned int i = 0; i < vsFiles.size(); ++i)
168                                        {
169                                                sCmd += " \"";
170                                                sCmd += vsFiles[i];
171                                                sCmd += "\"";
172                                        }
173#ifdef WIN32
174                                        sCmd += "\"";
175#endif
176                                        Logger::Instance().LogDebug("Starting mergecap...");
177                                        Logger::Instance().LogDebug(sCmd);
178                                        system(sCmd.c_str());
179                                        reply.SetMergeFile(targetFile.string());
180                                        if (bRes = boost::filesystem::exists(targetFile))
181                                                Logger::Instance().LogDebug("Files merged successfully");
182                                        else
183                                                Logger::Instance().LogError("File merging failed");
184                                }
185                                       
186                        }
187                        SendSimpleReply(reply, bRes);
188                        Logger::Instance().LogDebug("MergePcapFilesReply message sent");
189                }
190                break;
191        default:
192                Logger::Instance().LogWarning("Warning: the received control message is not supported");
193        }       
194        TrafficCaptureMessageFactory::Instance().DisposeMessage(pMsg);
195}
196
197void ConnectionController::Run()
198{
199        TcpipDispatch td(m_hSocket);
200        Logger::Instance().LogInfo("Waiting for control messages to inialize capturing...");
201
202        // infinite receiving loop: interrupted when the connection is closed
203        TMessageHeader header;
204        int nReceived = 0, nLen, nRemaining;
205        char * pBuf = NULL;
206        while (-1)
207        {
208                if (nReceived < sizeof(header))
209                {
210                        nRemaining = sizeof(header) - nReceived;
211                        if ((nLen = recv(m_hSocket, reinterpret_cast<char*>(&header) + nReceived, nRemaining, 0)) <= 0)
212                                break;
213                        nReceived += nLen;
214                }
215                else
216                {
217                        if (header.nMsgLen > 0)
218                        {
219                                if (pBuf == NULL)
220                                        pBuf = new char[header.nMsgLen];
221                                nRemaining = sizeof(header) + header.nMsgLen - nReceived;
222                                if ((nLen = recv(m_hSocket, pBuf + nReceived - sizeof(header), nRemaining , 0)) <= 0)
223                                        break;
224                                nReceived += nLen;
225                        }
226                        if (nReceived == sizeof(header) + header.nMsgLen)
227                        {
228                                ProcessMessage(header, pBuf, td);
229                                delete[] pBuf;
230                                pBuf = NULL;
231                                nReceived = 0;
232                                if (!m_hSocket)
233                                        break;
234                        }
235                }
236        }
237
238        boost::mutex::scoped_lock cond(m_mutex);
239        td.Stop();
240        CaptureFactory::Instance().DisposeCaptureInstance(m_pCapture);
241        m_pCapture = NULL;
242        Logger::Instance().LogInfo("Client connection terminated");
243        if (m_hSocket != SOCKET_CALL_ERROR)
244        {
245                CLOSE_SOCKET(m_hSocket);
246                m_hSocket = SOCKET_CALL_ERROR;
247        }
248        m_captureClosed.notify_one();
249       
250}
251
252void ConnectionController::Stop()
253{
254        boost::mutex::scoped_lock cond(m_mutex);
255        if (m_hSocket != SOCKET_CALL_ERROR)
256        {
257                CLOSE_SOCKET(m_hSocket);
258                m_hSocket = SOCKET_CALL_ERROR;
259                m_captureClosed.wait(cond);             
260        }
261}
Note: See TracBrowser for help on using the repository browser.