46#include <httpreadwrite.hpp>
52#include <webserver.hpp>
54#ifndef COMPA_INTERNAL_CONFIG_HPP
55#error "No or wrong config.hpp header file included."
85constexpr char SOAP_URN[]{
"http://schemas.xmlsoap.org/soap/envelope/"};
117 strncpy(dest, src,
NAME_SIZE - (
size_t)1);
134 off_t content_length;
138 const char* start_body =
141 "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
142 "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/"
146 "<faultcode>s:Client</faultcode>\n"
147 "<faultstring>UPnPError</faultstring>\n"
149 "<UPnPError xmlns=\"urn:schemas-upnp-org:control-1-0\">\n"
151 const char* mid_body =
"</errorCode>\n"
152 "<errorDescription>";
153 const char* end_body =
"</errorDescription>\n"
159 char err_code_str[30];
162 memset(err_code_str, 0,
sizeof(err_code_str));
163 snprintf(err_code_str,
sizeof(err_code_str),
"%d", error_code);
166 (off_t)(strlen(start_body) + strlen(err_code_str) + strlen(mid_body) +
167 strlen(err_msg) + strlen(end_body));
177 err_msg, end_body) != 0) {
194 const char* var_value,
197 off_t content_length;
201 const char* start_body =
203 "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
204 "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/"
207 "<u:QueryStateVariableResponse "
208 "xmlns:u=\"urn:schemas-upnp-org:control-1-0\">\n"
210 const char* end_body =
"</return>\n"
211 "</u:QueryStateVariableResponse>\n"
219 (off_t)(strlen(start_body) + strlen(var_value) + strlen(end_body));
246 char* xml_response = NULL;
250 off_t content_length;
253 static const char* start_body =
255 "<s:Envelope xmlns:s=\"http://schemas.xmlsoap."
256 "org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap."
257 "org/soap/encoding/\"><s:Body>\n";
258 static const char* end_body =
"</s:Body> </s:Envelope>";
270 (off_t)(strlen(start_body) + strlen(xml_response) + strlen(end_body));
273 &headers, major, minor,
"RNsDsSXcc", HTTP_OK,
279 headers.
length, start_body, strlen(start_body),
280 xml_response, strlen(xml_response), end_body,
283 UpnpPrintf(UPNP_INFO, SOAP, __FILE__, __LINE__,
284 "Failed to send response: err code = %d\n", ret_code);
320 if (variable == NULL) {
336 UpnpPrintf(UPNP_INFO, SOAP, __FILE__, __LINE__,
337 "Return from callback for var request\n");
378 const char* err_str{};
384 action_name = soap_info->action_name;
385 save_char = action_name.
buf[action_name.
length];
386 action_name.
buf[action_name.
length] =
'\0';
395 if (err_code != IXML_SUCCESS) {
396 if (IXML_INSUFFICIENT_MEMORY == err_code) {
417 UpnpPrintf(UPNP_INFO, SOAP, __FILE__, __LINE__,
"Calling Callback\n");
422 if (strlen(err_str) <= 0) {
430 if (actionResultDoc == NULL) {
445 action_name.
buf[action_name.
length] = save_char;
474 const char* control_url;
484 &device_info, &serv_info) != HND_DEVICE)
492 soap_info->callback = device_info->
Callback;
493 soap_info->cookie = device_info->
Cookie;
519 memptr ns_value, dummy_quote, value;
522 assert(HTTPMETHOD_MPOST == request->
method);
568 char* hash_pos = NULL;
569 char *col_pos1, *col_pos2, *serv_type;
574 if (SOAPMETHOD_POST == request->
method) {
589 hash_pos = strchr(value.
buf,
'#');
590 if (NULL == hash_pos) {
595 value.
length - (
size_t)(hash_pos + 1 - value.
buf),
"%s",
596 &soap_info->action_name) !=
PARSE_OK) {
601 if (value.
buf[0] !=
'\"') {
602 serv_type = &value.
buf[0];
604 serv_type = &value.
buf[1];
606 col_pos1 = strrchr(serv_type,
':');
607 if (NULL == col_pos1) {
610 col_pos2 = strrchr(soap_info->service_type,
':');
612 assert(col_pos2 != NULL);
613 cp1_diff = (size_t)(col_pos1 - serv_type);
614 if (col_pos2 - soap_info->service_type == col_pos1 - serv_type &&
615 strncmp(soap_info->service_type, serv_type, cp1_diff) == 0) {
617 namecopy(soap_info->service_type, serv_type);
619 memptr_cmp(&soap_info->action_name,
"QueryStateVariable") == 0) {
621 soap_info->action_name.
buf = NULL;
622 soap_info->action_name.
length = 0;
629 if (hash_pos != NULL) {
659 if (NULL == envp_node) {
663 if (NULL == ns_uri || strcmp(ns_uri,
SOAP_URN) != 0) {
668 if (NULL == body_node) {
672 if (NULL == local_name || strcmp(local_name,
SOAP_BODY) != 0) {
677 if (NULL == action_node) {
682 if (NULL == ns_uri) {
686 if (NULL == local_name) {
689 if (NULL == soap_info->action_name.
buf) {
693 strcmp(local_name,
"QueryStateVariable") != 0) {
697 if (NULL == varname_node) {
701 if (strcmp(local_name,
"varName") != 0) {
705 if (NULL == nametxt_node ||
709 *req_node = nametxt_node;
712 if (strcmp(soap_info->service_type, ns_uri) != 0 ||
713 memptr_cmp(&soap_info->action_name, local_name) != 0) {
716 *req_node = action_node;
744 soap_devserv_t* soap_info = NULL;
749 soap_info = (soap_devserv_t*)malloc(
sizeof(soap_devserv_t));
750 if (NULL == soap_info) {
751 err_code = HTTP_INTERNAL_SERVER_ERROR;
756 err_code = HTTP_NOT_FOUND;
761 err_code = HTTP_UNSUPPORTED_MEDIA_TYPE;
769 err_code = HTTP_NOT_EXTENDED;
772 err_code = HTTP_INTERNAL_SERVER_ERROR;
775 err_code = HTTP_BAD_REQUEST;
782 if (err_code != IXML_SUCCESS) {
783 if (IXML_INSUFFICIENT_MEMORY == err_code)
784 err_code = HTTP_INTERNAL_SERVER_ERROR;
786 err_code = HTTP_BAD_REQUEST;
791 err_code = HTTP_BAD_REQUEST;
795 if (NULL == soap_info->action_name.buf)
807 if (err_code != HTTP_OK) {
@ UPNP_CONTROL_GET_VAR_REQUEST
@ UPNP_CONTROL_ACTION_REQUEST
int(* Upnp_FunPtr)(Upnp_EventType EventType, const void *Event, void *Cookie)
int http_SendMessage(SOCKINFO *info, int *TimeOut, const char *fmt,...)
Sends a message to the destination based on the format parameter.
void http_CalcResponseVersion(int request_major_vers, int request_minor_vers, int *response_major_vers, int *response_minor_vers)
Calculate HTTP response versions based on the request versions.
int http_SendStatusResponse(SOCKINFO *info, int http_status_code, int request_major_version, int request_minor_version)
Generate a response message for the status query and send the status response.
int http_MakeMessage(membuffer *buf, int http_major_version, int http_minor_version, const char *fmt,...)
Generate an HTTP message based on the format that is specified in the input parameters.
uri_type uri
Type of a uri, e.g. absolute, relative, etc.
http_method_t method
Http method of an outgoing request.
int major_version
Http major version.
memptr entity
message body(entity).
membuffer value
Raw-value; could be multi-lined; min-length = 0.
#define HDR_MAN
Type of a HTTP header.
#define HDR_USER_AGENT
Type of a HTTP header.
#define HDR_SOAPACTION
Type of a HTTP header.
int minor_version
Http minor version.
Structure of an HTTP parser object.
Structure of an HTTP message.
size_t size
Size of the buffer.
token pathquery
Member variable.
#define X_USER_AGENT
Can be overwritten by configure CFLAGS argument.
PUPNP_Api int UpnpActionRequest_get_ErrCode(const UpnpActionRequest *p)
PUPNP_Api int UpnpActionRequest_strncpy_Os(UpnpActionRequest *p, const char *s, size_t n)
PUPNP_Api void UpnpActionRequest_delete(UpnpActionRequest *p)
PUPNP_Api IXML_Document * UpnpActionRequest_get_ActionResult(const UpnpActionRequest *p)
PUPNP_Api int UpnpActionRequest_strcpy_ServiceID(UpnpActionRequest *p, const char *s)
PUPNP_Api int UpnpActionRequest_strcpy_DevUDN(UpnpActionRequest *p, const char *s)
PUPNP_Api const char * UpnpActionRequest_get_ErrStr_cstr(const UpnpActionRequest *p)
PUPNP_Api int UpnpActionRequest_set_ActionRequest(UpnpActionRequest *p, IXML_Document *n)
PUPNP_Api UpnpActionRequest * UpnpActionRequest_new(void)
PUPNP_Api int UpnpActionRequest_set_ErrCode(UpnpActionRequest *p, int n)
PUPNP_Api int UpnpActionRequest_set_ActionResult(UpnpActionRequest *p, IXML_Document *n)
PUPNP_Api int UpnpActionRequest_strcpy_ActionName(UpnpActionRequest *p, const char *s)
PUPNP_Api int UpnpActionRequest_set_CtrlPtIPAddr(UpnpActionRequest *p, const struct sockaddr_storage *buf)
With header typedef "protected" s_UpnpStateVarRequest.
Header file for UpnpStateVarRequest methods.
PUPNP_Api int UpnpStateVarRequest_set_CtrlPtIPAddr(UpnpStateVarRequest *p, const struct sockaddr_storage *buf)
PUPNP_Api const char * UpnpStateVarRequest_get_ErrStr_cstr(const UpnpStateVarRequest *p)
PUPNP_Api int UpnpStateVarRequest_set_ErrCode(UpnpStateVarRequest *p, int n)
PUPNP_Api UpnpStateVarRequest * UpnpStateVarRequest_new(void)
PUPNP_Api int UpnpStateVarRequest_get_ErrCode(const UpnpStateVarRequest *p)
PUPNP_Api const UpnpString * UpnpStateVarRequest_get_ErrStr(const UpnpStateVarRequest *p)
PUPNP_Api int UpnpStateVarRequest_strcpy_DevUDN(UpnpStateVarRequest *p, const char *s)
PUPNP_Api int UpnpStateVarRequest_strcpy_ServiceID(UpnpStateVarRequest *p, const char *s)
PUPNP_Api int UpnpStateVarRequest_strcpy_StateVarName(UpnpStateVarRequest *p, const char *s)
PUPNP_Api void UpnpStateVarRequest_delete(UpnpStateVarRequest *p)
PUPNP_Api const DOMString UpnpStateVarRequest_get_CurrentVal(const UpnpStateVarRequest *p)
PUPNP_Api size_t UpnpString_get_Length(const UpnpString *p)
Returns the length of the string.
Data structure common to all types of nodes.
Data structure representing the DOM Document.
PUPNP_Api DOMString ixmlPrintNode(IXML_Node *doc)
Renders a Node and all sub-elements into an XML text representation.
PUPNP_Api unsigned short ixmlNode_getNodeType(IXML_Node *nodeptr)
Retrieves the type of a Node. Note that not all possible return values are actually implemented.
PUPNP_Api int ixmlParseBufferEx(const char *buffer, IXML_Document **doc)
Parses an XML text buffer converting it into an IXML DOM representation.
#define DOMString
The type of DOM strings.
PUPNP_Api const DOMString ixmlNode_getNodeValue(IXML_Node *nodeptr)
Returns the value of the Node as a string.
PUPNP_Api const DOMString ixmlNode_getLocalName(IXML_Node *nodeptr)
Retrieves the local name of a Node, if present.
PUPNP_Api void ixmlFreeDOMString(DOMString buf)
Frees a DOMString.
PUPNP_Api const DOMString ixmlNode_getNamespaceURI(IXML_Node *nodeptr)
Retrieves the namespace URI for a Node as a DOMString.
PUPNP_Api IXML_Node * ixmlNode_getFirstChild(IXML_Node *nodeptr)
Retrieves the first child Node of a Node.
PUPNP_Api void ixmlDocument_free(IXML_Document *doc)
Frees a Document object and all Nodes associated with it.
http_header_t * httpmsg_find_hdr_str(http_message_t *msg, const char *header_name)
Compares the header name with the header names stored in the linked list of messages.
http_header_t * httpmsg_find_hdr(http_message_t *msg, int header_name_id, memptr *value)
Finds header from a list, with the given 'name_id'.
parse_status_t matchstr(char *str, size_t slen, const char *fmt,...)
Matches a variable parameter list with a string and takes actions based on the data type specified.
int memptr_cmp(memptr *m, const char *s)
Compares characters of strings passed for number of bytes. If equal for the number of bytes,...
void membuffer_destroy(membuffer *m)
Free's memory allocated for membuffer* m.
void membuffer_init(membuffer *m)
Wrapper to membuffer_initialize().
int membuffer_append_str(membuffer *m, const char *c_str)
Invokes function to appends data from a constant string to the buffer.
int membuffer_assign(membuffer *m, const void *buf, size_t buf_len)
Allocate memory to membuffer *m and copy the contents of the in parameter const void *buf.
size_t length
length of buffer without terminating null byte (read-only).
char * buf
mem buffer; must not write beyond buf[length-1] (read/write).
size_t length
length of memory (read-only).
char * buf
start of memory (read/write).
pointer to a chunk of memory.
Maintains a block of dynamically allocated memory.
#define UPNP_E_SUCCESS
The operation completed successfully.
#define UPNP_E_OUTOF_MEMORY
Not enough resources are currently available to complete the operation.
void send_action_response(SOCKINFO *info, IXML_Document *action_resp, http_message_t *request)
Sends the SOAP action response.
int get_dev_service(http_message_t *request, int AddressFamily, soap_devserv_t *soap_info)
Retrieve SOAP device/service information associated with request-URI.
constexpr char Soap_Invalid_Action[]
UPnP Device SOAP strings.
constexpr char Soap_Memory_out[]
UPnP Device SOAP strings.
constexpr char QUERY_STATE_VAR_URN[]
UPnP Device SOAP strings.
constexpr int SOAP_MEMORY_OUT
UPnP Device SOAP status.
int get_mpost_acton_hdrval(http_message_t *request, memptr *val)
Get the SOAPACTION header value for M-POST request.
constexpr int SOAP_INVALID_ACTION
UPnP Device SOAP status.
constexpr int SREQ_HDR_NOT_FOUND
UPnP Device SOAP status.
constexpr char SOAP_URN[]
UPnP Device SOAP strings.
int check_soapaction_hdr(http_message_t *request, soap_devserv_t *soap_info)
Check header validity, get action name and version of service.
constexpr int SREQ_NOT_EXTENDED
UPnP Device SOAP status.
int check_soap_request(soap_devserv_t *soap_info, IXML_Document *xml_doc, IXML_Node **req_node)
Check validity of the SOAP request per UPnP specification.
void namecopy(char dest[NAME_SIZE], const char *src)
Copy string with length NAME_SIZE and terminate with '\0'.
constexpr char SOAP_BODY[]
UPnP Device SOAP strings.
constexpr int SREQ_BAD_HDR_FORMAT
UPnP Device SOAP status.
constexpr char Soap_Invalid_Var[]
UPnP Device SOAP strings.
void send_var_query_response(SOCKINFO *info, const char *var_value, http_message_t *hmsg)
Sends response of get var status.
constexpr char Soap_Action_Failed[]
UPnP Device SOAP strings.
void handle_query_variable(SOCKINFO *info, http_message_t *request, soap_devserv_t *soap_info, IXML_Node *req_node)
Handles the SOAP requests to querry the state variables.
constexpr int SOAP_ACTION_FAILED
UPnP Device SOAP status.
void handle_invoke_action(SOCKINFO *info, http_message_t *request, soap_devserv_t *soap_info, IXML_Node *req_node)
Handles the SOAP action request.
void send_error_response(SOCKINFO *info, int error_code, const char *err_msg, http_message_t *hmsg)
Sends SOAP error response.
constexpr int SOAP_INVALID_VAR
UPnP Device SOAP status.
DOMString UDN
Part of Service information.
DOMString serviceId
Part of Service information.
DOMString serviceType
Part of Service information.
-brief Service information
Common SOAP declarations used for SOAP Devices and SOAP Control Points.
constexpr char ContentTypeHeader[]
Common SOAP constant string specifying the content type header.
void soap_device_callback(http_parser_t *parser, http_message_t *request, SOCKINFO *info)
This is a callback called by minisever after receiving the request from the control point.
SOAP declarations for UPnP Devices using SOAP.
sockaddr_storage foreign_sockaddr
Socket address of the remote node only filled in incoming requests.
Additional socket information for connections and ssl.
Manage "Step 1: Discovery" of the UPnP+™ specification with SSDP.
Upnp_Handle_Type GetDeviceHandleInfoForPath(const char *path, int AddressFamily, UpnpDevice_Handle *device_handle_out, struct Handle_Info **HndInfo, service_info **serv_info)
Retrieves the device handle and information of the first device of the address family specified,...
Inititalize the compatible library before it can be used.
#define UPNP_TIMEOUT
UPNP_TIMEOUT.
#define HandleUnlock()
HandleUnlock.
Upnp_FunPtr Callback
Callback function pointer.
#define HandleReadLock()
HandleReadLock.
Data to be stored in handle table for Handle Info.
UPnPsdk_VIS void UpnpPrintf(Upnp_LogLevel DLevel, Dbg_Module Module, const char *DbgFileName, int DbgLineNo, const char *FmtStr,...)
Prints the debug statement.