SOAP_FMAC3 void SOAP_FMAC4 soap_header(struct soap *soap) { if (!soap->header) { if ((soap->header = soap_new_SOAP_ENV__Header(soap, -1))) soap_default_SOAP_ENV__Header(soap, soap->header); } }
SOAP_FMAC3 void SOAP_FMAC4 soap_header(struct soap *soap) { if (!soap->header) { soap->header = (struct SOAP_ENV__Header*)soap_malloc(soap, sizeof(struct SOAP_ENV__Header)); soap_default_SOAP_ENV__Header(soap, soap->header); } }
int main(int argc, char **argv) { int result = -1; int id_count = 1; struct Namespace namespaces[] = { // {"ns-prefix", "ns-name"} {"SOAP-ENV", "http://www.w3.org/2003/05/soap-envelope"}, // MUST be first {"d", "http://schemas.xmlsoap.org/ws/2005/04/discovery"}, {"wsa", "http://schemas.xmlsoap.org/ws/2004/08/addressing"}, {"dn", "http://www.onvif.org/ver10/network/wsdl"}, // given by the service description {NULL, NULL} // end of table }; // Get UUID uuid_t uuid; char szUuid[36] = {0}; char szMsgID[50] = {0}; uuid_generate_time(uuid); uuid_unparse(uuid, szUuid); snprintf(szMsgID, sizeof(szMsgID), "uuid:%s", szUuid); struct soap soap; struct SOAP_ENV__Header header; // the SOAP Header soap_init(&soap); soap.send_timeout = 1; // 1s timeout soap.recv_timeout = 1; // 1s timeout soap_set_namespaces(&soap, namespaces); soap_default_SOAP_ENV__Header(&soap, &header); // init SOAP Header header.wsa__MessageID = szMsgID; header.wsa__To = "urn:schemas-xmlsoap-org:ws:2005:04:discovery"; header.wsa__Action = "http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe"; soap.header = &header; struct d__ProbeMatchType r; // Send and receive messages over UDP: if (soap_send_d__Probe(&soap, "soap.udp://239.255.255.250:3702", NULL, "", "")) { soap_print_fault(&soap, stderr); } // Send and receive messages over UDP: if (soap_send_d__ProbeMatches(&soap, "soap.udp://239.255.255.250:3702", NULL, NULL)) { soap_print_fault(&soap, stderr); } soap_destroy(&soap); // cleanup soap_end(&soap); // cleanup soap_done(&soap); // close connection (should not use soap struct after this) return 0; }
SOAP_FMAC1 struct SOAP_ENV__Header * SOAP_FMAC2 soap_in_SOAP_ENV__Header(struct soap *soap, const char *tag, struct SOAP_ENV__Header *a, const char *type) {; if (soap_element_begin_in(soap, tag)) return NULL; if (*soap->type && soap_match_tag(soap, soap->type, type)) { soap->error = SOAP_TYPE_MISMATCH; soap_revert(soap); return NULL; } if (soap->null) { if (soap->enable_null) { soap->error = SOAP_NULL; return NULL; } else return a; } if (soap->body && !*soap->href) { a = (struct SOAP_ENV__Header *)soap_id_enter(soap, soap->id, a, SOAP_SOAP_ENV__Header, sizeof(struct SOAP_ENV__Header), 0); if (!a) return NULL; if (soap->alloced) soap_default_SOAP_ENV__Header(soap, a); for (;;) { soap->error = SOAP_TAG_MISMATCH; /* transient dummy skipped */ if (soap->error == SOAP_TAG_MISMATCH) soap->error = soap_ignore_element(soap); if (soap->error == SOAP_NO_TAG) break; if (soap->error) { return NULL; } } if (soap_element_end_in(soap, tag)) return NULL; } else { a = (struct SOAP_ENV__Header *)soap_id_forward(soap, soap->href, (void**)soap_id_enter(soap, soap->id, a, SOAP_SOAP_ENV__Header, sizeof(struct SOAP_ENV__Header), 0), SOAP_SOAP_ENV__Header, sizeof(struct SOAP_ENV__Header)); if (soap->alloced) soap_default_SOAP_ENV__Header(soap, a); if (soap->body && soap_element_end_in(soap, tag)) return NULL; } return a; }
//初始化soap函数 static struct soap* ONVIF_Initsoap(struct SOAP_ENV__Header *header, const char *was_To, const char *was_Action, int timeout) { struct soap *soap = NULL; unsigned char macaddr[6]; char _HwId[1024]; unsigned int Flagrand; soap = soap_new(); if(soap == NULL) { printf("[%d]soap = NULL\n", __LINE__); return NULL; } soap_set_namespaces( soap, namespaces); //超过5秒钟没有数据就退出 if (timeout > 0) { soap->recv_timeout = timeout; soap->send_timeout = timeout; soap->connect_timeout = timeout; } else { //如果外部接口没有设备默认超时时间的话,我这里给了一个默认值10s soap->recv_timeout = 10; soap->send_timeout = 10; soap->connect_timeout = 10; } soap_default_SOAP_ENV__Header(soap, header); // 为了保证每次搜索的时候MessageID都是不相同的!因为简单,直接取了随机值 srand((int)time(0)); Flagrand = rand()%9000 + 1000; //保证四位整数 macaddr[0] = 0x1; macaddr[1] = 0x2; macaddr[2] = 0x3; macaddr[3] = 0x4; macaddr[4] = 0x5; macaddr[5] = 0x6; sprintf(_HwId,"urn:uuid:%ud68a-1dd2-11b2-a105-%02X%02X%02X%02X%02X%02X", Flagrand, macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]); header->wsa__MessageID =(char *)malloc( 100); memset(header->wsa__MessageID, 0, 100); strncpy(header->wsa__MessageID, _HwId, strlen(_HwId)); if (was_Action != NULL) { header->wsa__Action =(char *)malloc(1024); memset(header->wsa__Action, '\0', 1024); strncpy(header->wsa__Action, was_Action, 1024);//"http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe"; } if (was_To != NULL) { header->wsa__To =(char *)malloc(1024); memset(header->wsa__To, '\0', 1024); strncpy(header->wsa__To, was_To, 1024);//"urn:schemas-xmlsoap-org:ws:2005:04:discovery"; } soap->header = header; return soap; }
struct soap* CSoapUtils::newSoap(CBaseSoapSecurityInfo* securityInfo) { struct soap* psoap = NULL; psoap = soap_new(); if (NULL == psoap) { printf("soap new error\r\n"); return NULL; } soap_set_namespaces(psoap, namespaces); psoap->recv_timeout = SOAP_RECV_TIMEOUT; psoap->send_timeout = SOAP_SEND_TIMEOUT; psoap->connect_timeout = SOAP_CONNECT_TIMEOUT; struct SOAP_ENV__Header* header = static_cast<struct SOAP_ENV__Header*>(my_soap_malloc(psoap, sizeof(struct SOAP_ENV__Header))); soap_default_SOAP_ENV__Header(psoap, header); char guid_string[100] = { 0 }; GUID guid; if (CoCreateGuid(&guid)) { deleteSoap(psoap); printf("create guid error\r\n"); return NULL; } header->wsa__MessageID = static_cast<char*>(my_soap_malloc(psoap, 100)); strcpy(header->wsa__MessageID, guid_string); psoap->header = header; if ((NULL != securityInfo) && (securityInfo->getUserName().length() > 0)){ std::auto_ptr<ISetSoapSecurity> ap(CFactoryImpl::getInstance().createSetSoapSecurity()); if (!CAppTools::getInstance().isRetSuccess(ap->setSecurity(psoap, securityInfo))) { deleteSoap(psoap); printf("set security error\r\n"); return NULL; } } return psoap; }
int main(int argc, char *argv[]) { /* 变量声明 */ struct soap *soap; //soap环境变量 struct wsdd__ProbeType req; //用于发送消息描述 struct wsdd__ProbeType wsdd__Probe; struct __wsdd__ProbeMatches resp; //struct wsdd__ProbeMatchesType resp; //请求消息的回应 struct wsdd__ScopesType sScope; //描述查找哪类的Web服务 struct SOAP_ENV__Header header; //soap消息头描述 int count = 0; //获得的设信息备个数 int result = 0; //返回值 unsigned char macaddr[6]; char _HwId[1024]; unsigned int Flagrand; // Create SessionID randomly srand((int)time(0)); Flagrand = rand()%9000 + 8888; macaddr[0] = 0x1; macaddr[1] = 0x2; macaddr[2] = 0x3; macaddr[3] = 0x4; macaddr[4] = 0x5; macaddr[5] = 0x6; sprintf(_HwId,"urn:uuid:%ud68a-1dd2-11b2-a105-%02X%02X%02X%02X%02X%02X", Flagrand, macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]); /************初始化*************/ soap = soap_new(); //为soap申请变量空间,并初始化 if ( soap == NULL) { return -1; } soap_set_namespaces(soap, namespaces); //设置soap的namespaces soap->recv_timeout = 5; //超过5秒钟没有数据就退出 soap_default_SOAP_ENV__Header(soap, &header);//将header设置为soap消息 头属性 header.wsa__MessageID = _HwId; header.wsa__To = "urn:schemas-xmlsoap-org:ws:2005:04:discovery"; header.wsa__Action = "http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe"; soap->header = &header; //设置soap头消息的ID //设置soap消息的请求服务属性 soap_default_wsdd__ScopesType(soap, &sScope); sScope.__item = ""; //sScope.__item = "onvif://www.onvif.org"; soap_default_wsdd__ProbeType(soap, &req); req.Scopes = &sScope; //req.Types = "tdn:NetworkVideoTransmitter"; req.Types = "tds:Device"; //调用gSoap接口 //soap_wsdd_Probe result = soap_send___wsdd__Probe(soap, "soap.udp://239.255.255.250:3702", NULL, &req); printf("%s: %d, send probe request success!\n",__FUNCTION__, __LINE__); if ( result == -1 ) { printf ( "soap error: %d, %s, %s\n", soap->error, *soap_faultcode(soap), *soap_faultstring(soap)); result = soap->error; } else { do { printf("%s: %d, begin receive probematch... \n",__FUNCTION__, __LINE__); printf("count=%d \n",count); //接收ProbeMatches,成功返回0,否则-1 result = soap_recv___wsdd__ProbeMatches(soap, &resp); printf(" --soap_recv___wsdd__ProbeMatches() result=%d \n",result); if (result==-1) { printf("Find %d devices!\n", count); break; } else { //读取服务端回应的Probematch消息 if ( resp.wsdd__ProbeMatches){ /*** printf("soap_recv___wsdd__Probe: __sizeProbeMatch=%d\r\n",resp.wsdd__ProbeMatches->__sizeProbeMatch); printf("Target EP Address : %s\r\n", resp.wsdd__ProbeMatches->ProbeMatch->wsa__EndpointReference.Address); printf("Target Type : %s\r\n", resp.wsdd__ProbeMatches->ProbeMatch->Types); printf("Target Service Address : %s\r\n", resp.wsdd__ProbeMatches->ProbeMatch->XAddrs); printf("Target Metadata Version : %d\r\n",resp.wsdd__ProbeMatches->ProbeMatch->MetadataVersion); printf("Target Scopes Address : %s\r\n", resp.wsdd__ProbeMatches->ProbeMatch->Scopes->__item); **/ DeviceInfo device; device.dev_uuid = resp.wsdd__ProbeMatches->ProbeMatch->wsa__EndpointReference.Address; device.dev_server_address = resp.wsdd__ProbeMatches->ProbeMatch->XAddrs; char duplicate = 0; int index = 0; while ( index < MAX_DEVICE) { char *uuid = g_device_list[ index].dev_uuid; if ( uuid != NULL && strcmp( uuid, device.dev_uuid) == 0 ) { duplicate = 1; break; } ++index; } if ( duplicate == 0) { printf ( " find device no :%d \n" , ( count +1)); printf ( " uuid : %s \n" , device.dev_uuid); printf ( " server address : %s \n" , device.dev_server_address); g_device_list[ count] = device; count += 1; } } } } while ( 1); } //清除soap soap_end(soap); // clean up and remove deserialized data soap_free(soap);//detach and free runtime context soap_done(soap); // detach context (last use and no longer in scope) return result; }
int ONVIF_ClientDiscovery( ) { int retval = SOAP_FAULT; wsdd__ProbeType req; struct __wsdd__ProbeMatches resp; wsdd__ScopesType sScope; struct soap *soap = NULL; struct SOAP_ENV__Header header; const char *was_To = "urn:schemas-xmlsoap-org:ws:2005:04:discovery"; const char *was_Action = "http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe"; //这个就是传递过去的组播的ip地址和对应的端口发送广播信息 const char *soap_endpoint = "soap.udp://239.255.255.250:3702/"; //这个接口填充一些信息并new返回一个soap对象,本来可以不用额外接口, // 但是后期会作其他操作,此部分剔除出来后面的操作就相对简单了,只是调用接口就好 soap = ONVIF_Initsoap(&header, was_To, was_Action, 5); soap_default_SOAP_ENV__Header(soap, &header); soap->header = &header; soap_default_wsdd__ScopesType(soap, &sScope); sScope.__item = ""; soap_default_wsdd__ProbeType(soap, &req); req.Scopes = &sScope; req.Types = "tdn:NetworkVideoTransmitter"; retval = soap_send___wsdd__Probe(soap, soap_endpoint, NULL, &req); //发送组播消息成功后,开始循环接收各位设备发送过来的消息 while (retval == SOAP_OK) { retval = soap_recv___wsdd__ProbeMatches(soap, &resp);//这个函数用来接受probe消息,存在resp里面 if (retval == SOAP_OK) { if (soap->error) { printf("[%d]: recv soap error :%d, %s, %s\n", __LINE__, soap->error, *soap_faultcode(soap), *soap_faultstring(soap)); retval = soap->error; } else //成功接收某一个设备的消息 { HasDev ++; if (resp.wsdd__ProbeMatches->ProbeMatch != NULL && resp.wsdd__ProbeMatches->ProbeMatch->XAddrs != NULL) { printf(" ################ recv %d devices info #### \n", HasDev ); printf("Target Service Address : %s\n", resp.wsdd__ProbeMatches->ProbeMatch->XAddrs); printf("Target EP Address : %s\n", resp.wsdd__ProbeMatches->ProbeMatch->wsa__EndpointReference.Address); printf("Target Type : %s\n", resp.wsdd__ProbeMatches->ProbeMatch->Types); printf("Target Metadata Version : %d\n", resp.wsdd__ProbeMatches->ProbeMatch->MetadataVersion); ONVIF_Capabilities(&resp);//这里可以调用能力值获取函数 sleep(1); } } } else if (soap->error) { if (HasDev == 0) { printf("[%s][%s][Line:%d] Thers Device discovery or soap error: %d, %s, %s \n",__FILE__, __func__, __LINE__, soap->error, *soap_faultcode(soap), *soap_faultstring(soap)); retval = soap->error; } else { printf(" [%s]-[%d] Search end! It has Searched %d devices! \n", __func__, __LINE__, HasDev); retval = 0; } break; } } soap_destroy(soap); soap_end(soap); soap_free(soap); return retval; }
int main(int argc, char **argv) { struct soap soap; struct SOAP_ENV__Header header; // struct wsa__EndpointReferenceType replyTo; // char *res; char *mid0 = "packet0"; char *mid1 = "packet1"; soap_init(&soap); soap.send_timeout = 10; soap.recv_timeout = 10; /* To compress the request message (compile with -DWITH_GZIP): */ #ifdef WITH_GZIP soap_set_omode(&soap, SOAP_ENC_ZLIB); #endif /* To transmit MIME attachments: soap_set_mime(&soap, NULL, NULL); soap_set_mime_attachment(&soap, "abc", 3, SOAP_MIME_7BIT, "text/xml", "cid:abc", NULL, NULL); */ /* To transmit DIME attachments: soap_set_dime(&soap); soap_set_dime_attachment(&soap, "abc", 3, "cid:abc", "text/xml", 0, NULL); */ ///* Prepare SOAP Header */ //soap_default_SOAP_ENV__Header(&soap, &header); //soap.header = &header; //soap_default_wsa__EndpointReferenceType(&soap, &replyTo); //replyTo.Address = "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"; ///* Set WS-Addressing elements for request-response unicast */ //header.wsa__MessageID = mid0; //header.wsa__To = "http://genivia.com/udp/server"; //header.wsa__Action = "http://genivia.com/udp/echoString"; //header.wsa__ReplyTo = &replyTo; ///* Make request-response call */ //if (soap_call_ns__echoString(&soap, NULL, NULL, "hello world!", &res)) //{ // if (soap.error == SOAP_EOF && soap.errnum == 0) // printf("Timeout: message probably already delivered\n"); //else // soap_print_fault(&soap, stderr); //} //else // printf("UDP server response: %s\n", res); for (int packet_id = 0;; packet_id =(packet_id ? 0 : 1) ) { /* Reset the SOAP Header */ soap_default_SOAP_ENV__Header(&soap, &header); soap.header = &header; /* Set WS-Addressing elements for one-way unicast */ if (0 == packet_id) header.wsa__MessageID = mid0; else header.wsa__MessageID = mid1; header.wsa__To = "http://genivia.com/udp/server"; header.wsa__Action = "http://genivia.com/udp/sendString"; /* Send one-way message */ if (soap_send_ns__sendString(&soap, SERVER_ADDRESS, NULL, "ABET!")) soap_print_fault(&soap, stderr); soap_destroy(&soap); soap_end(&soap); //Spacing between packet0 and packet1 Sleep(SPACING_IN); } soap_done(&soap); return 0; }
static struct soap* ONVIF_Initsoap(struct SOAP_ENV__Header *header, const char *was_To, const char *was_Action, int timeout, UserInfo_S *pUserInfo) { struct soap *soap = NULL; unsigned char macaddr[6]; char _HwId[1024]; unsigned int Flagrand; soap = soap_new(); if(soap == NULL) { printf("[%d]soap = NULL\n", __LINE__); return NULL; } /* soap_set_namespaces( soap, ); */ //超过5秒钟没有数据就退出 if (timeout > 0) { soap->recv_timeout = timeout; soap->send_timeout = timeout; soap->connect_timeout = timeout; } else { //如果外部接口没有设备默认超时时间的话,我这里给了一个默认值10s soap->recv_timeout = 10; soap->send_timeout = 10; soap->connect_timeout = 10; } soap_default_SOAP_ENV__Header(soap, header); // 为了保证每次搜索的时候MessageID都是不相同的!因为简单,直接取了随机值 srand((int)time(0)); Flagrand = rand()%9000 + 1000; //保证四位整数 macaddr[0] = 0x1; macaddr[1] = 0x2; macaddr[2] = 0x3; macaddr[3] = 0x4; macaddr[4] = 0x5; macaddr[5] = 0x6; sprintf(_HwId,"urn:uuid:%ud68a-1dd2-11b2-a105-%02X%02X%02X%02X%02X%02X", Flagrand, macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]); header->wsa__MessageID =(char *)malloc( 100); memset(header->wsa__MessageID, 0, 100); strncpy(header->wsa__MessageID, _HwId, strlen(_HwId)); if( pUserInfo != NULL ) { header->wsse__Security = (struct _wsse__Security *)malloc(sizeof(struct _wsse__Security)); memset(header->wsse__Security, 0 , sizeof(struct _wsse__Security)); header->wsse__Security->UsernameToken = (struct _wsse__UsernameToken *)calloc(1,sizeof(struct _wsse__UsernameToken)); header->wsse__Security->UsernameToken->Username = (char *)malloc(64); memset(header->wsse__Security->UsernameToken->Username, '\0', 64); header->wsse__Security->UsernameToken->Nonce = (char*)malloc(64); memset(header->wsse__Security->UsernameToken->Nonce, '\0', 64); strcpy(header->wsse__Security->UsernameToken->Nonce,"LKqI6G/AikKCQrN0zqZFlg=="); //\u6ce8\u610f\u8fd9\u91cc header->wsse__Security->UsernameToken->wsu__Created = (char*)malloc(64); memset(header->wsse__Security->UsernameToken->wsu__Created, '\0', 64); strcpy(header->wsse__Security->UsernameToken->wsu__Created,"2010-09-16T07:50:45Z"); strcpy(header->wsse__Security->UsernameToken->Username, pUserInfo->username); header->wsse__Security->UsernameToken->Password = (struct _wsse__Password *)malloc(sizeof(struct _wsse__Password)); header->wsse__Security->UsernameToken->Password->Type = (char*)malloc(128); memset(header->wsse__Security->UsernameToken->Password->Type, '\0', 128); strcpy(header->wsse__Security->UsernameToken->Password->Type,\ "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"); header->wsse__Security->UsernameToken->Password->__item = (char*)malloc(128); ONVIF_GenrateDigest((unsigned char*)header->wsse__Security->UsernameToken->Password->__item,\ (unsigned char*)pUserInfo->password,header->wsse__Security->UsernameToken->Nonce,header->wsse__Security->UsernameToken->wsu__Created); } if (was_Action != NULL) { header->wsa__Action =(char *)malloc(1024); memset(header->wsa__Action, '\0', 1024); strncpy(header->wsa__Action, was_Action, 1024);//"http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe"; } if (was_To != NULL) { header->wsa__To =(char *)malloc(1024); memset(header->wsa__To, '\0', 1024); strncpy(header->wsa__To, was_To, 1024);//"urn:schemas-xmlsoap-org:ws:2005:04:discovery"; } soap->header = header; return soap; }