change the getStateVariable method

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@1748 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
joss17 2009-10-30 00:34:51 +00:00
parent 79e02eb221
commit e7273b0453
3 changed files with 83 additions and 179 deletions

View File

@ -726,40 +726,32 @@ bool CUPnPService::Execute(
const std::string CUPnPService::GetStateVariable( const std::string CUPnPService::GetStateVariable(
const std::string &stateVariableName) const std::string &stateVariableName)
{ {
// DOMString StVarVal; //this getvar is just to make an event happening
// int ret = UpnpGetServiceVarStatus( DOMString StVarVal;
// m_UPnPControlPoint.GetUPnPClientHandle(), int ret = UpnpGetServiceVarStatus(
// GetAbsControlURL().c_str(), m_UPnPControlPoint.GetUPnPClientHandle(),
// stateVariableName.c_str(), GetAbsControlURL().c_str(),
// &StVarVal); stateVariableName.c_str(),
std::cerr << "GetAbsControlURL().c_str() : " << GetAbsControlURL().c_str() << std::endl; &StVarVal);
std::cerr << "stateVariableName.c_str() : " << stateVariableName.c_str() << std::endl; std::cerr << "GetStateVariable pausing in case of an UPnP event incomming.";
int ret = UpnpGetServiceVarStatusAsync( time_t begin_time = time(NULL);
m_UPnPControlPoint.GetUPnPClientHandle(), /** The handle of the control point. */ while (true) {
GetAbsControlURL().c_str(), /** The URL of the service. */ if (time(NULL) - begin_time > 7) {
stateVariableName.c_str(), /** The name of the variable to query. */ break;
static_cast<Upnp_FunPtr>(&CUPnPService::GetServiceVarStatusAsyncCallback), /** Pointer to a callback function to be invoked when the operation is complete. */ }
NULL /** Pointer to user data to pass to the callback function when invoked. */
);
if (ret != UPNP_E_SUCCESS) {
std::ostringstream msg;
msg << "GetStateVariable(\"" <<
stateVariableName <<
"\"): in a call to UpnpGetServiceVarStatus";
m_upnpLib.processUPnPErrorMessage(
msg.str(), ret, NULL, NULL);
return stdEmptyString;
} }
std::cerr << "UpnpGetServiceVarStatusAsync) called successfully" << std::endl; std::cerr << "GetStateVariable pause finished.";
//double lock for blocking it. It will be deblocked by the callback funtion GetServiceVarStatusAsyncCallback std::cerr << "GetStateVariable(" << stateVariableName << ") = ";
CUPnPControlPoint *upnpCP = CUPnPControlPoint::s_CtrlPoint; std::map<std::string, std::string>::iterator it;
upnpCP->m_getStateVariableMutex.lock(); it = propertyMap.find(stateVariableName);
std::cerr << "m_getStateVariableMutex.lock() 1 finished." << std::endl; if (it == propertyMap.end()) {
std::cerr << "Empty String" << std::endl;
//return StVarVal; return stdEmptyString;
return upnpCP->m_getStateVariableLastResult; } else {
std::cerr << (*it).second << std::endl;
return (*it).second;
}
} }
@ -903,7 +895,7 @@ m_WanService(NULL)
// on the mutex. // on the mutex.
// UpnpSetContentLength(m_UPnPClientHandle, 5000000); // UpnpSetContentLength(m_UPnPClientHandle, 5000000);
// UpnpSetMaxContentLength(5000000); // UpnpSetMaxContentLength(5000000);
ret = UpnpSearchAsync(m_UPnPClientHandle, 30, m_upnpLib.UPNP_DEVICE_IGW.c_str(), NULL); ret = UpnpSearchAsync(m_UPnPClientHandle, 20, m_upnpLib.UPNP_DEVICE_IGW.c_str(), NULL);
//ret = UpnpSearchAsync(m_UPnPClientHandle, 3, m_upnpLib.UPNP_DEVICE_IGW.c_str(), this); //ret = UpnpSearchAsync(m_UPnPClientHandle, 3, m_upnpLib.UPNP_DEVICE_IGW.c_str(), this);
//ret = UpnpSearchAsync(m_UPnPClientHandle, 3, m_upnpLib.UPNP_DEVICE_LAN.c_str(), this); //ret = UpnpSearchAsync(m_UPnPClientHandle, 3, m_upnpLib.UPNP_DEVICE_LAN.c_str(), this);
//ret = UpnpSearchAsync(m_UPnPClientHandle, 3, m_upnpLib.UPNP_DEVICE_WAN_CONNECTION.c_str(), this); //ret = UpnpSearchAsync(m_UPnPClientHandle, 3, m_upnpLib.UPNP_DEVICE_WAN_CONNECTION.c_str(), this);
@ -974,12 +966,12 @@ bool CUPnPControlPoint::AddPortMappings(
bool ok = false; bool ok = false;
// Check the number of port mappings before // Check the number of port mappings before
std::istringstream PortMappingNumberOfEntries( std::istringstream OldPortMappingNumberOfEntries(
m_WanService->GetStateVariable( m_WanService->GetStateVariable(
"PortMappingNumberOfEntries")); "PortMappingNumberOfEntries"));
unsigned long oldNumberOfEntries; int oldNumberOfEntries;
PortMappingNumberOfEntries >> oldNumberOfEntries; OldPortMappingNumberOfEntries >> oldNumberOfEntries;
// Add the enabled port mappings // Add the enabled port mappings
for (int i = 0; i < n; ++i) { for (int i = 0; i < n; ++i) {
if (upnpPortMapping[i].getEnabled() == "1") { if (upnpPortMapping[i].getEnabled() == "1") {
@ -992,37 +984,7 @@ bool CUPnPControlPoint::AddPortMappings(
PrivateAddPortMapping(upnpPortMapping[i]); PrivateAddPortMapping(upnpPortMapping[i]);
} }
} }
// Test some variables, this is deprecated, might not work
// with some routers
m_WanService->GetStateVariable("ConnectionType");
m_WanService->GetStateVariable("PossibleConnectionTypes");
m_WanService->GetStateVariable("ConnectionStatus");
m_WanService->GetStateVariable("Uptime");
m_WanService->GetStateVariable("LastConnectionError");
m_WanService->GetStateVariable("RSIPAvailable");
m_WanService->GetStateVariable("NATEnabled");
m_WanService->GetStateVariable("ExternalIPAddress");
m_WanService->GetStateVariable("PortMappingNumberOfEntries");
m_WanService->GetStateVariable("PortMappingLeaseDuration");
// Just for testing
// std::vector<CUPnPArgumentValue> argval;
// argval.resize(0);
// m_WanService->Execute("GetStatusInfo", argval);
#if 0
// These do not work. Their value must be requested for a
// specific port mapping.
m_WanService->GetStateVariable("PortMappingEnabled");
m_WanService->GetStateVariable("RemoteHost");
m_WanService->GetStateVariable("ExternalPort");
m_WanService->GetStateVariable("InternalPort");
m_WanService->GetStateVariable("PortMappingProtocol");
m_WanService->GetStateVariable("InternalClient");
m_WanService->GetStateVariable("PortMappingDescription");
#endif
// Debug only // Debug only
#ifdef UPNP_DEBUG #ifdef UPNP_DEBUG
std::cerr << "CUPnPControlPoint::AddPortMappings: " std::cerr << "CUPnPControlPoint::AddPortMappings: "
@ -1031,12 +993,13 @@ bool CUPnPControlPoint::AddPortMappings(
#endif #endif
// Not very good, must find a better test // Not very good, must find a better test
PortMappingNumberOfEntries.str( std::istringstream NewPortMappingNumberOfEntries(
m_WanService->GetStateVariable( m_WanService->GetStateVariable(
"PortMappingNumberOfEntries")); "PortMappingNumberOfEntries"));
unsigned long newNumberOfEntries; int newNumberOfEntries;
PortMappingNumberOfEntries >> newNumberOfEntries; NewPortMappingNumberOfEntries >> newNumberOfEntries;
ok = newNumberOfEntries - oldNumberOfEntries == 4; std::cerr << "newNumberOfEntries - oldNumberOfEntries : " << (newNumberOfEntries - oldNumberOfEntries) << std::endl;
ok = newNumberOfEntries - oldNumberOfEntries >= 1;
std::cerr << "CUPnPControlPoint::AddPortMappings finished. success : " << ok << std::endl; std::cerr << "CUPnPControlPoint::AddPortMappings finished. success : " << ok << std::endl;
@ -1062,9 +1025,6 @@ void CUPnPControlPoint::RefreshPortMappings()
++it) { ++it) {
PrivateAddPortMapping(it->second); PrivateAddPortMapping(it->second);
} }
// For testing
m_WanService->GetStateVariable("PortMappingNumberOfEntries");
} }
@ -1160,7 +1120,7 @@ bool CUPnPControlPoint::DeletePortMappings(
"PortMappingNumberOfEntries")); "PortMappingNumberOfEntries"));
unsigned long newNumberOfEntries; unsigned long newNumberOfEntries;
PortMappingNumberOfEntries >> newNumberOfEntries; PortMappingNumberOfEntries >> newNumberOfEntries;
ok = oldNumberOfEntries - newNumberOfEntries == 4; ok = oldNumberOfEntries - newNumberOfEntries >= 4;
return ok; return ok;
} }
@ -1414,9 +1374,8 @@ upnpEventSubscriptionExpired:
upnpCP->m_upnpLib.processUPnPErrorMessage( upnpCP->m_upnpLib.processUPnPErrorMessage(
msg.str(), sv_event->ErrCode, NULL, NULL); msg.str(), sv_event->ErrCode, NULL, NULL);
} else { } else {
std::cerr << sv_event->StateVarName << std::endl; //add the variable to the wanservice property map
std::cerr << sv_event->CtrlUrl << std::endl; (upnpCP->m_WanService->propertyMap)[std::string(sv_event->StateVarName)] = std::string(sv_event->CurrentVal);
std::cerr << sv_event->CurrentVal << std::endl;
#if 0 #if 0
// Warning: The use of UpnpGetServiceVarStatus and // Warning: The use of UpnpGetServiceVarStatus and
// UpnpGetServiceVarStatusAsync is deprecated by the // UpnpGetServiceVarStatusAsync is deprecated by the
@ -1459,53 +1418,6 @@ eventSubscriptionRequest:
return 0; return 0;
} }
// This function is static
int CUPnPService::GetServiceVarStatusAsyncCallback(Upnp_EventType EventType, void *Event, void * /*Cookie*/)
{
//fprintf(stderr, "Callback: %d, Cookie: %p\n", EventType, Cookie);
CUPnPControlPoint *upnpCP = CUPnPControlPoint::s_CtrlPoint;
switch (EventType) {
case UPNP_EVENT_RECEIVED: {
fprintf(stderr, "GetServiceVarStatusAsyncCallback: UPNP_EVENT_RECEIVED\n");
// Event reveived
struct Upnp_Event *e_event = (struct Upnp_Event *)Event;
const std::string Sid = e_event->Sid;
// Parses the event
upnpCP->OnEventReceived(Sid, e_event->EventKey, e_event->ChangedVariables);
break;
}
case UPNP_CONTROL_GET_VAR_COMPLETE: {
fprintf(stderr, "Callback GetServiceVarStatusAsyncCallback : UPNP_CONTROL_GET_VAR_COMPLETE\n");
struct Upnp_State_Var_Complete *sv_event =
(struct Upnp_State_Var_Complete *)Event;
if (sv_event->ErrCode != UPNP_E_SUCCESS) {
std::cerr << "error(UPNP_CONTROL_GET_VAR_COMPLETE) : ";
std::cerr << "Error Code : " << sv_event->ErrCode << std::endl;
} else {
std::cerr << sv_event->StateVarName << std::endl;
std::cerr << sv_event->CtrlUrl << std::endl;
std::cerr << sv_event->CurrentVal << std::endl;
upnpCP->m_getStateVariableLastResult = sv_event->CurrentVal;
}
break;
}
default:
// Humm, this is not good, we forgot to handle something...
fprintf(stderr,
"Callback: default... Unknown event:'%d', not good.\n",
EventType);
std::cerr << "error(UPnP::Callback): Event not handled:'" <<
EventType << "'." << std::endl;
// Better not throw in the callback. Who would catch it?
//throw CUPnPException(msg);
break;
}
std::cerr << "Unlocking m_getStateVariableMutex." << std::endl;
upnpCP->m_getStateVariableMutex.unlock();
return 0;
}
void CUPnPControlPoint::OnEventReceived( void CUPnPControlPoint::OnEventReceived(
const std::string &Sid, const std::string &Sid,
@ -1514,31 +1426,40 @@ void CUPnPControlPoint::OnEventReceived(
{ {
std::cerr << "UPNP_EVENT_RECEIVED:" << std::cerr << "UPNP_EVENT_RECEIVED:" <<
"\n SID: " << Sid << "\n SID: " << Sid <<
"\n Key: " << EventKey << "\n Key: " << EventKey << std::endl;
"\n Property list:"; std::cerr << "m_WanService->GetServiceId() : " << m_WanService->GetSID() << std::endl;
IXML_Element *root =
m_upnpLib.Element_GetRootElement(ChangedVariablesDoc); if (m_WanService->GetSID() == Sid) {
IXML_Element *child = //let's store the properties if it is an event of the wan device
m_upnpLib.Element_GetFirstChild(root); std::cerr << "\n Property list:";
if (child) {
while (child) { IXML_Element *root =
IXML_Element *child2 = m_upnpLib.Element_GetRootElement(ChangedVariablesDoc);
m_upnpLib.Element_GetFirstChild(child); IXML_Element *child =
const DOMString childTag = m_upnpLib.Element_GetFirstChild(root);
m_upnpLib.Element_GetTag(child2); if (child) {
std::string childValue = while (child) {
m_upnpLib.Element_GetTextValue(child2); IXML_Element *child2 =
std::cerr << "\n " << m_upnpLib.Element_GetFirstChild(child);
childTag << "='" << const DOMString childTag =
childValue << "'"; m_upnpLib.Element_GetTag(child2);
child = m_upnpLib.Element_GetNextSibling(child); std::string childValue =
} m_upnpLib.Element_GetTextValue(child2);
} else { std::cerr << "\n " <<
std::cerr << "\n Empty property list."; childTag << "='" <<
childValue << "'";
const std::string cTag(childTag);
const std::string cValue(childValue);
(m_WanService->propertyMap)[cTag] = cValue;
child = m_upnpLib.Element_GetNextSibling(child);
}
} else {
std::cerr << "\n Empty property list.";
}
std::cerr << std::endl;
// Freeing that doc segfaults. Probably should not be freed.
//ixmlDocument_free(ChangedVariablesDoc);
} }
std::cerr << std::endl;
// Freeing that doc segfaults. Probably should not be freed.
//ixmlDocument_free(ChangedVariablesDoc);
} }

View File

@ -430,6 +430,7 @@ private:
std::auto_ptr<CUPnPSCPD> m_SCPD; std::auto_ptr<CUPnPSCPD> m_SCPD;
public: public:
std::map<std::string, std::string> propertyMap;
CUPnPService( CUPnPService(
const CUPnPControlPoint &upnpControlPoint, const CUPnPControlPoint &upnpControlPoint,
CUPnPLib &upnpLib, CUPnPLib &upnpLib,
@ -476,12 +477,6 @@ public:
const std::string GetStateVariable( const std::string GetStateVariable(
const std::string &stateVariableName); const std::string &stateVariableName);
//callback Function
static int GetServiceVarStatusAsyncCallback(
Upnp_EventType EventType,
void* Event,
void* Cookie);
}; };

View File

@ -12,25 +12,8 @@ extern "C" {
#include "upnp/upnphandler.h" #include "upnp/upnphandler.h"
struct WanDevice {
char UDN[250];
char DescDocURL[250];
char FriendlyName[250];
char PresURL[250];
int AdvrTimeOut;
};
class uPnPConfigData
{
public:
struct WanDevice * WanDevice;
char lanaddr[16]; /* my ip address on the LAN */
};
#include "util/rsnet.h" #include "util/rsnet.h"
UpnpClient_Handle ctrlpt_handle = -1;
bool upnphandler::initUPnPState() bool upnphandler::initUPnPState()
{ {
std::cerr << "upnphandler::initUPnPState" << std::endl; std::cerr << "upnphandler::initUPnPState" << std::endl;
@ -105,6 +88,7 @@ bool upnphandler::background_setup_upnp(bool start, bool stop)
pthread_t tid; pthread_t tid;
/* launch thread */ /* launch thread */
std::cerr << "Creating upnp thread." << std::endl;
upnpThreadData *data = new upnpThreadData(); upnpThreadData *data = new upnpThreadData();
data->handler = this; data->handler = this;
data->start = start; data->start = start;
@ -186,9 +170,10 @@ bool upnphandler::start_upnp()
CUPnPPortMapping cUPnPPortMapping2 = CUPnPPortMapping(eport_curr, ntohs(localAddr.sin_port), "UDP", true, "udp retroshare redirection"); CUPnPPortMapping cUPnPPortMapping2 = CUPnPPortMapping(eport_curr, ntohs(localAddr.sin_port), "UDP", true, "udp retroshare redirection");
upnpPortMapping2.push_back(cUPnPPortMapping2); upnpPortMapping2.push_back(cUPnPPortMapping2);
bool res2 = cUPnPControlPoint->AddPortMappings(upnpPortMapping2); bool res2 = cUPnPControlPoint->AddPortMappings(upnpPortMapping2);
if (res) { if (res2) {
upnpState = RS_UPNP_S_ACTIVE; upnpState = RS_UPNP_S_ACTIVE;
} else { } else {
//upnpState = RS_UPNP_S_ACTIVE;
upnpState = RS_UPNP_S_UDP_FAILED; upnpState = RS_UPNP_S_UDP_FAILED;
} }
} }
@ -217,7 +202,7 @@ bool upnphandler::start_upnp()
toStart = false; toStart = false;
return true; return (upnpState == RS_UPNP_S_ACTIVE);
} }
@ -248,8 +233,8 @@ bool upnphandler::shutdown_upnp()
std::cerr << std::endl; std::cerr << std::endl;
std::vector<CUPnPPortMapping> upnpPortMapping1; std::vector<CUPnPPortMapping> upnpPortMapping1;
CUPnPPortMapping *cUPnPPortMapping1 = &CUPnPPortMapping(eport_curr, 0, eprot1, true, "tcp redirection"); CUPnPPortMapping cUPnPPortMapping1 = CUPnPPortMapping(eport_curr, 0, eprot1, true, "tcp redirection");
upnpPortMapping1.push_back(*cUPnPPortMapping1); upnpPortMapping1.push_back(cUPnPPortMapping1);
cUPnPControlPoint->DeletePortMappings(upnpPortMapping1); cUPnPControlPoint->DeletePortMappings(upnpPortMapping1);
std::cerr << "Attempting To Remove Redirection: port: " << eport2; std::cerr << "Attempting To Remove Redirection: port: " << eport2;
@ -257,8 +242,8 @@ bool upnphandler::shutdown_upnp()
std::cerr << std::endl; std::cerr << std::endl;
std::vector<CUPnPPortMapping> upnpPortMapping2; std::vector<CUPnPPortMapping> upnpPortMapping2;
CUPnPPortMapping *cUPnPPortMapping2 = &CUPnPPortMapping(eport_curr, 0, eprot2, true, "tcp redirection"); CUPnPPortMapping cUPnPPortMapping2 = CUPnPPortMapping(eport_curr, 0, eprot2, true, "udp redirection");
upnpPortMapping2.push_back(*cUPnPPortMapping2); upnpPortMapping2.push_back(cUPnPPortMapping2);
cUPnPControlPoint->DeletePortMappings(upnpPortMapping2); cUPnPControlPoint->DeletePortMappings(upnpPortMapping2);
//destroy the upnp object //destroy the upnp object
@ -329,6 +314,7 @@ void upnphandler::shutdown()
void upnphandler::restart() void upnphandler::restart()
{ {
/* non-blocking call to shutdown upnp, and startup again. */ /* non-blocking call to shutdown upnp, and startup again. */
std::cerr << "upnphandler::restart() called." << std::endl;
background_setup_upnp(true, true); background_setup_upnp(true, true);
} }
@ -349,6 +335,8 @@ bool upnphandler::getActive()
{ {
dataMtx.lock(); /*** LOCK MUTEX ***/ dataMtx.lock(); /*** LOCK MUTEX ***/
std::cerr <<"GetActive Called result : " << (upnpState == RS_UPNP_S_ACTIVE) << std::endl;
bool on = (upnpState == RS_UPNP_S_ACTIVE); bool on = (upnpState == RS_UPNP_S_ACTIVE);
dataMtx.unlock(); /*** UNLOCK MUTEX ***/ dataMtx.unlock(); /*** UNLOCK MUTEX ***/