summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Begumisa <ben_g@users.sourceforge.net>2008-10-23 21:02:24 +0000
committerGerald Begumisa <ben_g@users.sourceforge.net>2008-10-23 21:02:24 +0000
commit0bce8eed98acce2532bbbf9878fc4a477735a33e (patch)
tree48e12a969c21d7ac9a03b19c2f4ddd8c1e866c9a
parent6d5d6c2811fbe5dee96cedcae0b7fb5859860244 (diff)
Modified VoIp capture plugin so that if any of the network devices being captured from go offline, orkaudio does not simply stop but attempts to re-open the device. In such a case, orkaudio attempts to re-open the device after 60 seconds from when the device went offline. If it fails to re-open i.e is still offline, orkaudio shall keep trying every 60 seconds.
git-svn-id: https://oreka.svn.sourceforge.net/svnroot/oreka/trunk@564 09dcff7a-b715-0410-9601-b79a96267cd0
-rw-r--r--orkaudio/audiocaptureplugins/voip/VoIp.cpp128
1 files changed, 127 insertions, 1 deletions
diff --git a/orkaudio/audiocaptureplugins/voip/VoIp.cpp b/orkaudio/audiocaptureplugins/voip/VoIp.cpp
index 37a2f84..7731743 100644
--- a/orkaudio/audiocaptureplugins/voip/VoIp.cpp
+++ b/orkaudio/audiocaptureplugins/voip/VoIp.cpp
@@ -86,6 +86,10 @@ public:
void StartCapture(CStdString& port);
void StopCapture(CStdString& port);
void ReportPcapStats();
+ pcap_t* OpenDevice(CStdString& name);
+ void AddPcapDeviceToMap(CStdString& deviceName, pcap_t* pcapHandle);
+ void RemovePcapDeviceFromMap(pcap_t* pcapHandle);
+ CStdString GetPcapDeviceName(pcap_t* pcapHandle);
private:
void OpenDevices();
void OpenPcapFile(CStdString& filename);
@@ -95,6 +99,9 @@ private:
pcap_t* m_pcapHandle;
std::list<pcap_t*> m_pcapHandles;
+
+ std::map<pcap_t*, CStdString> m_pcapDeviceMap;
+ ACE_Thread_Mutex m_pcapDeviceMapMutex;
};
typedef ACE_Singleton<VoIp, ACE_Thread_Mutex> VoIpSingleton;
@@ -2695,6 +2702,56 @@ void SingleDeviceCaptureThreadHandler(pcap_t* pcapHandle)
}
log.Format("Stop Capturing: pcap handle:%x", pcapHandle);
LOG4CXX_INFO(s_packetLog, log);
+
+ if(s_liveCapture == true)
+ {
+ CStdString deviceName;
+ pcap_t* oldHandle = NULL;
+
+ deviceName = VoIpSingleton::instance()->GetPcapDeviceName(pcapHandle);
+ if(deviceName.size())
+ {
+ oldHandle = pcapHandle;
+ VoIpSingleton::instance()->RemovePcapDeviceFromMap(pcapHandle);
+ pcap_close(pcapHandle); // XXX this can cause a crash if later other code is added to close all handles in the m_pcapHandles list
+
+ while(1)
+ {
+ struct timespec ts;
+
+ ts.tv_sec = 60; // Try re-open after a minute
+ ts.tv_nsec = 0;
+ ACE_OS::nanosleep (&ts, NULL);
+
+ log.Format("Attempting to re-open device:%s - old handle:%x was closed", deviceName, oldHandle);
+ LOG4CXX_INFO(s_packetLog, log);
+
+ pcapHandle = VoIpSingleton::instance()->OpenDevice(deviceName);
+ if(pcapHandle != NULL)
+ {
+ VoIpSingleton::instance()->AddPcapDeviceToMap(deviceName, pcapHandle);
+
+ log.Format("Start Capturing: pcap handle:%x", pcapHandle);
+ LOG4CXX_INFO(s_packetLog, log);
+
+ pcap_loop(pcapHandle, 0, HandlePacket, NULL);
+
+ log.Format("Stop Capturing: pcap handle:%x", pcapHandle);
+ LOG4CXX_INFO(s_packetLog, log);
+
+ oldHandle = pcapHandle;
+ VoIpSingleton::instance()->RemovePcapDeviceFromMap(pcapHandle);
+ pcap_close(pcapHandle);
+ }
+ }
+ }
+ else
+ {
+ log.Format("Running in live capture mode but unable to determine which device handle:%x belongs to. Will not restart capture", pcapHandle);
+ LOG4CXX_INFO(s_packetLog, log);
+ pcap_close(pcapHandle); // XXX this can cause a crash if later other code is added to close all handles in the m_pcapHandles list
+ }
+ }
}
else
{
@@ -2855,6 +2912,68 @@ void VoIp::SetPcapSocketBufferSize(pcap_t* pcapHandle)
#endif
}
+void VoIp::AddPcapDeviceToMap(CStdString& deviceName, pcap_t* pcapHandle)
+{
+ MutexSentinel mutexSentinel(m_pcapDeviceMapMutex);
+
+ m_pcapDeviceMap.insert(std::make_pair(pcapHandle, deviceName));
+}
+
+void VoIp::RemovePcapDeviceFromMap(pcap_t* pcapHandle)
+{
+ MutexSentinel mutexSentinel(m_pcapDeviceMapMutex);
+
+ m_pcapDeviceMap.erase(pcapHandle);
+}
+
+CStdString VoIp::GetPcapDeviceName(pcap_t* pcapHandle)
+{
+ MutexSentinel mutexSentinel(m_pcapDeviceMapMutex);
+ std::map<pcap_t*, CStdString>::iterator pair;
+ CStdString deviceName;
+
+ pair = m_pcapDeviceMap.find(pcapHandle);
+ if(pair != m_pcapDeviceMap.end())
+ {
+ deviceName = pair->second;
+ }
+
+ return deviceName;
+}
+
+pcap_t* VoIp::OpenDevice(CStdString& name)
+{
+ char error[PCAP_ERRBUF_SIZE];
+ char *perror = NULL;
+ MutexSentinel mutexSentinel(m_pcapDeviceMapMutex);
+ CStdString logMsg;
+
+ m_pcapHandle = NULL;
+ memset(error, 0, sizeof(error));
+ m_pcapHandle = pcap_open_live((char*)name.c_str(), 1500, PROMISCUOUS, 500, error);
+
+ if(!strlen(error))
+ {
+ perror = ApplyPcapFilter();
+ if(perror != NULL)
+ {
+ snprintf(error, PCAP_ERRBUF_SIZE, "%s", perror);
+ }
+ }
+ if(strlen(error))
+ {
+ LOG4CXX_ERROR(s_packetLog, CStdString("pcap error when opening device; error message:") + error);
+ }
+ else
+ {
+ logMsg.Format("Successfully opened device. pcap handle:%x", m_pcapHandle);
+ LOG4CXX_INFO(s_packetLog, logMsg);
+ SetPcapSocketBufferSize(m_pcapHandle);
+ }
+
+ return m_pcapHandle;
+}
+
void VoIp::OpenDevices()
{
pcap_if_t* devices = NULL;
@@ -2910,12 +3029,15 @@ void VoIp::OpenDevices()
}
else
{
- CStdString logMsg;
+ CStdString logMsg, deviceName;
+
+ deviceName = device->name;
logMsg.Format("Successfully opened device. pcap handle:%x", m_pcapHandle);
LOG4CXX_INFO(s_packetLog, logMsg);
SetPcapSocketBufferSize(m_pcapHandle);
m_pcapHandles.push_back(m_pcapHandle);
+ AddPcapDeviceToMap(deviceName, m_pcapHandle);
}
}
}
@@ -2942,11 +3064,15 @@ void VoIp::OpenDevices()
}
else
{
+ CStdString deviceName;
+
logMsg.Format("Successfully opened default device:%s pcap handle:%x", defaultDevice->name, m_pcapHandle);
LOG4CXX_INFO(s_packetLog, logMsg);
SetPcapSocketBufferSize(m_pcapHandle);
m_pcapHandles.push_back(m_pcapHandle);
+ deviceName = defaultDevice->name;
+ AddPcapDeviceToMap(deviceName, m_pcapHandle);
}
}
else