9#include <CXX/Objects.hxx>
29#define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO
57 ostr <<
"PyRouteWork(tid="<<
mTid<<
")";
85 ostr <<
"PyRouteMessageHandlerWork";
98 mMessageHandlerAction(messageHandlerAction)
116 DebugLog(<<
"creating new PyThreadState");
129 if(messageHandlerWork)
157 headers[
"DisplayName"] = Py::String(message.
header(resip::h_From).displayName().c_str());
160 if(message.
exists(resip::h_CallID))
162 headers[
"Call-ID"] = Py::String(message.
header(resip::h_CallID).value().c_str());
164 if(message.
exists(resip::h_ContentType))
170 resip::SipMessage::UnknownHeaders::const_iterator it = unknowns.begin();
171 for( ; it != unknowns.end(); it++)
174 StackLog(<<
"found unknown header: " << name);
184 WarningLog(<<
"ignoring additional values for header " << name);
189 Py::String transportType(
206 resip::CookieList::const_iterator it = _cookies.begin();
207 it != _cookies.end();
210 ErrLog(<<
"adding cookie: " << it->name());
211 cookies[Py::String(it->name().c_str())] = Py::String(it->value().c_str());
221 args[3] = transportType;
224 args[6] = newHeaders;
229 response =
mAction.apply(args);
231 catch (
const Py::Exception& ex)
233 WarningLog(<<
"PyRoute mAction failed: " << Py::value(ex));
242 if(response.isNumeric())
244 Py::Long responseCode(response);
255 if(response.isTuple())
258 Py::Tuple err(response);
261 ErrLog(<<
"Incomplete response object from PyRoute script");
267 WarningLog(<<
"Excessive values in response from PyRoute script");
269 if(!err[0].isNumeric())
271 ErrLog(<<
"First value in response tuple must be numeric");
275 Py::Long responseCode(err[0]);
276 Py::String responseMessage;
279 if(!err[1].isString())
281 ErrLog(<<
"Second value in response tuple must be a string, ignoring it");
283 responseMessage = err[1];
291 if(!response.isList())
293 ErrLog(<<
"Unexpected response object from PyRoute script");
298 Py::List routes(response);
299 DebugLog(<<
"got " << routes.size() <<
" result(s).");
301 Py::Sequence::iterator i = routes.begin();
305 Py::String target(*i);
307 DebugLog(<<
"processing result: " << target_s);
311 int newHeaderCount = newHeaders.size();
312 DebugLog(<<
"got " << newHeaderCount <<
" new/changed header(s)");
313 for(Py::Dict::iterator it = newHeaders.begin();
314 it != newHeaders.end();
317 const Py::Dict::value_type vt(*it);
320 DebugLog(<<
"processing a header: " << headerName <<
": " << value);
335 WarningLog(<<
"Discarding header '"<<headerName<<
"' from pyroute script, only extension headers permitted");
364 statusLine[
"response_code"] = Py::Long(sline.
responseCode());
365 statusLine[
"reason_text"] = Py::String(sline.
reason().
c_str());
369 ErrLog(<<
"neither request nor response");
375 headers[
"DisplayName"] = Py::String(message.
header(resip::h_From).displayName().c_str());
378 if(message.
exists(resip::h_CallID))
380 headers[
"Call-ID"] = Py::String(message.
header(resip::h_CallID).value().c_str());
382 if(message.
exists(resip::h_ContentType))
384 std::ostringstream os;
385 os << message.
header(resip::h_ContentType);
386 headers[
"Content-Type"] = Py::String(os.str());
391 resip::SipMessage::UnknownHeaders::const_iterator it = unknowns.begin();
392 for( ; it != unknowns.end(); it++)
395 StackLog(<<
"found unknown header: " << name);
405 WarningLog(<<
"ignoring additional values for header " << name);
410 Py::String transportType(
427 resip::CookieList::const_iterator it = _cookies.begin();
428 it != _cookies.end();
431 ErrLog(<<
"adding cookie: " << it->name());
432 cookies[Py::String(it->name().c_str())] = Py::String(it->value().c_str());
437 args[arg++] = statusLine;
439 args[arg++] = transportType;
441 args[arg++] = cookies;
445 ErrLog(<<
"No on_message method in the Python script");
450 StackLog(<<
"invoking mMessageHandlerAction");
453 catch (
const Py::Exception& ex)
455 WarningLog(<<
"PyRoute mMessageHandlerAction failed: " << Py::value(ex));
#define WarningLog(args_)
#define resip_assert(x)
This file needs to work for both C and C++ code.
virtual PyRouteMessageHandlerWork * clone() const
virtual EncodeStream & encode(EncodeStream &ostr) const
output the entire message to stream
std::shared_ptr< resip::SipMessage > mMessage
virtual EncodeStream & encodeBrief(EncodeStream &ostr) const
output a brief description to stream
PyRouteMessageHandlerWork(const resip::SipMessage &message)
virtual ~PyRouteMessageHandlerWork()
resip::Data mResponseMessage
resip::SipMessage & mMessage
virtual PyRouteWork * clone() const
virtual EncodeStream & encodeBrief(EncodeStream &ostr) const
output a brief description to stream
PyRouteWork(Processor &proc, const resip::Data &tid, resip::TransactionUser *passedtu, resip::SipMessage &message)
std::vector< resip::Data > mTargets
virtual EncodeStream & encode(EncodeStream &ostr) const
output the entire message to stream
virtual bool process(resip::ApplicationMessage *msg) override
bool processWork(PyRouteWork *work)
bool processMessageHandlerWork(PyRouteMessageHandlerWork *work)
resip::PyExtensionBase & mPy
std::unique_ptr< resip::PyExternalUser > mPyUser
virtual PyRouteWorker * clone() const override
PyRouteWorker(resip::PyExtensionBase &py, Py::Callable &action, Py::Callable &messageHandlerAction)
Py::Callable & mMessageHandlerAction
virtual void onStart() override
A base-class for messages used by applications.
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
const char * c_str() const
Returns a null-terminated string representing.
size_type size() const noexcept
Returns the number of bytes in this Data.
const char * data() const noexcept
Returns a pointer to the contents of this Data.
HeaderFieldValue & getHeaderField()
Container class for ParserCategory, used by SipMessage to represent multi-valued headers (Contact,...
iterator end()
Returns an iterator pointing to the last header field value.
iterator erase(iterator i)
Erases the header field value pointed to by i.
iterator begin()
Returns an iterator pointing to the first header field value.
void push_back(const T &t)
Inserts a header field value at the back of this container.
std::unique_ptr< PyExternalUser > createPyExternalUser()
Represents a SIP message.
std::list< std::pair< Data, HeaderFieldValueList * >, StlPoolAllocator< std::pair< Data, HeaderFieldValueList * >, PoolBase > > UnknownHeaders
bool isRequest() const
Returns true if message is a request, false otherwise.
const Tuple & getReceivedTransportTuple() const
const UnknownHeaders & getRawUnknownHeaders() const noexcept
const RequestLine & header(const RequestLineType &l) const
Returns the RequestLine. This is only valid for request messages.
bool isResponse() const
Returns true if message is a response, false otherwise.
bool exists(const HeaderBase &headerType) const
Returns true if the given header field is present, false otherwise.
const HeaderFieldValue & getRawBody() const noexcept
Return the raw body string (if it exists).
const CookieList & getWsCookies() const
Represents the "Status-Line" element in the RFC 3261 grammar.
Represents the "header-value" element in the RFC 3261 grammar (ie, an unknown header field value).
The base-class for an RFC 3261 Transaction User.
TransportType getType() const
This Class is used to implement a primitive form of RPC using loose XML formatting.
dcm! – add UnusedChecking(_enum) below;
StatusLineType h_StatusLine
std::string getTransportNameFromType(const TransportType typeEnum)
Function which translates a transport enum value to its corrisponding name.
const Data & getMethodName(MethodTypes t)
RequestLineType h_RequestLine
std::vector< Cookie > CookieList