summaryrefslogtreecommitdiff
path: root/orkaudio
diff options
context:
space:
mode:
authorHenri Herscher <henri@oreka.org>2005-12-10 04:19:16 +0000
committerHenri Herscher <henri@oreka.org>2005-12-10 04:19:16 +0000
commit1a3c290941ab8e79d70178194f70e3ed3ec2dbe9 (patch)
treec60beae0db627637d2373c74950330cc6fb36f1b /orkaudio
parent63e3499fd7ab68e79c9b4d85a2aa92fbfbf73d92 (diff)
VoIP plugin can now monitor multiple devices at the samle time
git-svn-id: https://oreka.svn.sourceforge.net/svnroot/oreka/trunk@104 09dcff7a-b715-0410-9601-b79a96267cd0
Diffstat (limited to 'orkaudio')
-rw-r--r--orkaudio/audiocaptureplugins/voip/VoIp.cpp127
-rw-r--r--orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp18
-rw-r--r--orkaudio/audiocaptureplugins/voip/VoIpConfig.h4
3 files changed, 102 insertions, 47 deletions
diff --git a/orkaudio/audiocaptureplugins/voip/VoIp.cpp b/orkaudio/audiocaptureplugins/voip/VoIp.cpp
index b7bb35b..30dcc47 100644
--- a/orkaudio/audiocaptureplugins/voip/VoIp.cpp
+++ b/orkaudio/audiocaptureplugins/voip/VoIp.cpp
@@ -13,12 +13,15 @@
#define _WINSOCKAPI_ // prevents the inclusion of winsock.h
+#include <list>
#include "ace/OS_NS_unistd.h"
#include "ace/OS_NS_string.h"
#include "ace/Singleton.h"
#include "ace/Min_Max.h"
#include "ace/OS_NS_arpa_inet.h"
#include "ace/OS_NS_ctype.h"
+#include "ace/Thread_Manager.h"
+#include "ace/Thread_Mutex.h"
#include "AudioCapturePlugin.h"
#include "AudioCapturePluginCommon.h"
#include "Utils.h"
@@ -41,9 +44,13 @@ static LoggerPtr s_skinnyPacketLog;
static LoggerPtr s_sipExtractionLog;
time_t lastHooveringTime;
+static ACE_Thread_Mutex s_mutex;
+
VoIpConfigTopObjectRef g_VoIpConfigTopObjectRef;
#define DLLCONFIG g_VoIpConfigTopObjectRef.get()->m_config
+#define PROMISCUOUS 1
+
// Convert a piece of memnory to hex string
void memToHex(unsigned char* input, size_t len, CStdString&output)
{
@@ -350,6 +357,7 @@ void HandlePacket(u_char *param, const struct pcap_pkthdr *header, const u_char
{
u_char* udpPayload = (u_char *)udpHeader + sizeof(UdpHeaderStruct);
+ MutexSentinel mutexSentinel(s_mutex); // serialize access for competing pcap threads
bool detectedUsefulPacket = TryRtp(ethernetHeader, ipHeader, udpHeader, udpPayload);
@@ -386,6 +394,8 @@ void HandlePacket(u_char *param, const struct pcap_pkthdr *header, const u_char
dbg.Format("Offset:%x Len:%u Type:%x %s", offset, skinnyHeader->len, skinnyHeader->messageType, SkinnyMessageToString(skinnyHeader->messageType));
LOG4CXX_DEBUG(s_skinnyPacketLog, dbg);
}
+ MutexSentinel mutexSentinel(s_mutex); // serialize access for competing pcap threads
+
HandleSkinnyMessage(skinnyHeader);
// Point to next skinny message within this TCP packet
@@ -403,6 +413,23 @@ void HandlePacket(u_char *param, const struct pcap_pkthdr *header, const u_char
}
+void SingleDeviceCaptureThreadHandler(pcap_t* pcapHandle)
+{
+ if(pcapHandle)
+ {
+ CStdString log;
+ 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);
+ }
+ else
+ {
+ LOG4CXX_ERROR(s_packetLog, "Cannot start capturing, pcap handle is null");
+ }
+}
+
class VoIp
{
public:
@@ -414,6 +441,7 @@ public:
void StopCapture(CStdString& port);
private:
pcap_t* m_pcapHandle;
+ std::list<pcap_t*> m_pcapHandles;
};
typedef ACE_Singleton<VoIp, ACE_Thread_Mutex> VoIpSingleton;
@@ -461,27 +489,12 @@ void VoIp::Initialize()
g_VoIpConfigTopObjectRef.reset(new VoIpConfigTopObject);
}
-/*
- char addr1[] = "10.1.2.3";
- char addr2[] = "192.168.5.6";
- char addr3[] = "45.168.5.6";
- struct in_addr addr;
- ACE_OS::inet_aton(addr1, &addr);
- bool result = DLLCONFIG.IsPartOfLan(addr);
- result = DLLCONFIG.IsMediaGateway(addr);
- ACE_OS::inet_aton(addr2, &addr);
- result = DLLCONFIG.IsPartOfLan(addr);
- result = DLLCONFIG.IsMediaGateway(addr);
- ACE_OS::inet_aton(addr3, &addr);
- result = DLLCONFIG.IsPartOfLan(addr);
- result = DLLCONFIG.IsMediaGateway(addr);
-*/
-
pcap_if_t* devices = NULL;
- pcap_if_t* lastDevice = NULL;
- pcap_if_t* deviceToSniff = NULL;
+ pcap_if_t* defaultDevice = NULL;
lastHooveringTime = time(NULL);
+ CStdString logMsg;
+
char * error = NULL;
if (pcap_findalldevs(&devices, error) == -1)
{
@@ -495,39 +508,63 @@ void VoIp::Initialize()
for (pcap_if_t* device = devices; device != NULL; device = device->next)
{
- LOG4CXX_INFO(s_packetLog, CStdString("\t* ") + device->description + " " + device->name );
- if(DLLCONFIG.m_device.Equals(device->name))
+ if(!device){break;}
+
+ LOG4CXX_INFO(s_packetLog, CStdString("* ") + device->description + " " + device->name );
+
+ CStdString deviceName(device->name);
+ deviceName.ToLower();
+ if( deviceName.Find("dialup") == -1 && // Don't want Windows dialup devices (still possible to force them using the configuration file)
+ deviceName.Find("lo") == -1 && // Don't want Unix loopback device
+ deviceName.Find("any") == -1 ) // Don't want Unix "any" device
{
- deviceToSniff = device;
+ defaultDevice = device;
}
- if(device)
+ if(DLLCONFIG.IsDeviceWanted(device->name))
{
- lastDevice = device;
+ // Open device
+ if ((m_pcapHandle = pcap_open_live(device->name, 1500, PROMISCUOUS,
+ 500, error)) == NULL)
+ {
+ LOG4CXX_ERROR(s_packetLog, "pcap error when opening device");
+ }
+ else
+ {
+ CStdString logMsg;
+ logMsg.Format("Successfully opened device. pcap handle:%x", m_pcapHandle);
+ LOG4CXX_INFO(s_packetLog, "Successfully opened device");
+
+ m_pcapHandles.push_back(m_pcapHandle);
+ }
}
}
- if (!deviceToSniff)
+ if(m_pcapHandles.size() == 0)
{
- if(!DLLCONFIG.m_device.IsEmpty())
+ if(DLLCONFIG.m_devices.size() > 0)
{
- LOG4CXX_ERROR(s_packetLog, CStdString("pcap could not find wanted device: ") + DLLCONFIG.m_device + " please check your config file");
+ LOG4CXX_ERROR(s_packetLog, "Could not find any of the devices listed in config file");
}
- if(lastDevice)
- {
- LOG4CXX_INFO(s_packetLog, CStdString("Defaulting to device: ") + lastDevice->name);
- deviceToSniff = lastDevice;
- }
- }
- if (deviceToSniff)
- {
- #define PROMISCUOUS 1
- if ((m_pcapHandle = pcap_open_live(deviceToSniff->name, 1500, PROMISCUOUS,
- 500, error)) == NULL)
+
+ // Let's open the default device
+ if(defaultDevice)
{
- LOG4CXX_ERROR(s_packetLog, CStdString("pcap error when opening device: ") + deviceToSniff->name);
+ if ((m_pcapHandle = pcap_open_live(defaultDevice->name, 1500, PROMISCUOUS,
+ 500, error)) == NULL)
+ {
+ logMsg.Format("pcap error when opening default device:%s", defaultDevice->name);
+ LOG4CXX_ERROR(s_packetLog, logMsg);
+ }
+ else
+ {
+ logMsg.Format("Successfully opened default device:%s pcap handle:%x", defaultDevice->name, m_pcapHandle);
+ LOG4CXX_INFO(s_packetLog, logMsg);
+
+ m_pcapHandles.push_back(m_pcapHandle);
+ }
}
else
{
- LOG4CXX_INFO(s_packetLog, CStdString("successfully opened device: ") + deviceToSniff->name);
+ LOG4CXX_ERROR(s_packetLog, "Could not determine the default device to monitor. If you want a specific device listed above, please specify it in your config file");
}
}
}
@@ -541,14 +578,12 @@ void VoIp::Initialize()
void VoIp::Run()
{
- if(m_pcapHandle)
- {
- LOG4CXX_INFO(s_packetLog, "Running VoIp.dll");
- pcap_loop(m_pcapHandle, 0, HandlePacket, NULL);
- }
- else
+ for(std::list<pcap_t*>::iterator it = m_pcapHandles.begin(); it != m_pcapHandles.end(); it++)
{
- LOG4CXX_INFO(s_packetLog, "No network device opened - VoIp.dll not starting");
+ if (!ACE_Thread_Manager::instance()->spawn(ACE_THR_FUNC(SingleDeviceCaptureThreadHandler), *it))
+ {
+ LOG4CXX_INFO(s_packetLog, CStdString("Failed to create pcap capture thread"));
+ }
}
}
diff --git a/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp b/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp
index a632bdc..c469e15 100644
--- a/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp
+++ b/orkaudio/audiocaptureplugins/voip/VoIpConfig.cpp
@@ -29,6 +29,7 @@ VoIpConfig::VoIpConfig()
void VoIpConfig::Define(Serializer* s)
{
s->StringValue(DEVICE_PARAM, m_device);
+ s->CsvValue("Devices", m_devices);
s->CsvValue("LanMasks", m_asciiLanMasks);
s->CsvValue("MediaGateways", m_asciiMediaGateways);
}
@@ -91,6 +92,23 @@ bool VoIpConfig::IsMediaGateway(struct in_addr addr)
return false;
}
+bool VoIpConfig::IsDeviceWanted(CStdString device)
+{
+ if(device.Equals(m_device))
+ {
+ // Old style single device configuration setting.
+ return true;
+ }
+ for(std::list<CStdString>::iterator it = m_devices.begin(); it != m_devices.end(); it++)
+ {
+ if(it->Equals(device))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
CStdString VoIpConfig::GetClassName()
{
diff --git a/orkaudio/audiocaptureplugins/voip/VoIpConfig.h b/orkaudio/audiocaptureplugins/voip/VoIpConfig.h
index 7bea647..5e799d5 100644
--- a/orkaudio/audiocaptureplugins/voip/VoIpConfig.h
+++ b/orkaudio/audiocaptureplugins/voip/VoIpConfig.h
@@ -35,8 +35,10 @@ public:
bool IsPartOfLan(struct in_addr);
bool IsMediaGateway(struct in_addr);
+ bool IsDeviceWanted(CStdString device);
- CStdString m_device;
+ CStdString m_device; // old style but can still be used for specifying single device
+ std::list<CStdString> m_devices; // new style devices csv
std::list<unsigned int> m_mediaGateways;
std::list<CStdString> m_asciiMediaGateways;
std::list<unsigned int> m_lanMasks;