vs2003->vs2005时就注意的事项(转)

本文分享了将CommunityServer从ASP.NET 1.1迁移到ASP.NET 2.0的过程及经验教训,包括解决语法错误、去除冗余声明以及更新Membership配置等方面的内容。

费了好一袋烟工夫把CommunityServer升级到了Asp.Net2.0平台,一点心得:

vs2005可以很方便的帮我们把vs2003开发的asp.net1.1版本项目升级到vs2005开发的asp.net2.0版本,从vs2005里面打开vs2003的解决方案或者项目文件,会有向导帮我们自己完成升级工作。一部分asp.net1.1的项目做完这个工作就足够了。

不过更多的时候不会这么顺利,还要注意一些问题:

  • vs2003开发的asp.net1.1程序,不会检查aspx、aspcx等文件中的语法错误,而vs2005会检查项目中所有的aspx、aspcx等文件中的语法,所以如果有语法错误,会导致编译无法通过。
  • vs2003中,如果用的是默认的代码绑定方式,那么在aspx文件(以aspx文件为例,ascx文件也有这个问题)中申明的服务器端控件,会在aspx文件对应的aspx.cs文件中,生成一个对应的申明,例如aspx中有一个TextBox,ID是MyTextBox,那么在aspx.cs中,会申明一个"protected TextBox MyTextBox;",而在vs2005中,这个申明是多余的,所以升级后要去除这些多余的申明。
  • 如果有程序采用了asp.net1.1下的Membership——使用MemberRole.dll,要升级到asp.net2.0下的Membership,需要做如下工作:
    • 删除所有项目中对"MemberRole.dll"的引用,添加"System.Configration"的引用
    • 改变命名空间ScalableHosting.Profile -> System.Web.Profile;ScalableHosting.Security -> System.Web.Security; 同时添加using System.Configuration;
    • 移除所有MemberRole.dll相关的Membership配置,参照以前的Membership配置,增加asp.net2.0支持的Membership配置,更新Membership的存储过程。
  • CCS1.1 for asp.net2.0的下载:http://www.communityserver.cn/builds 
/****************************************************************************** Copyright © 2018-2018 TP-Link Systems Inc. Filename: soap.c Version: 1.0 Description: soap 处理函数 Author: liyijieliyijie@tp-link.com.cn Date: 2018-12-03 ******************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <arpa/inet.h> #include “onvif_passthrough.h” #include “soap_global.h” #include “soap_parse.h” #include “soap_pack.h” #define SOAP_TAG_NUM 256 /定义最多可以注册256个标签处理函数/ typedef struct _SOAP_TAG_HANDLE { char tag[LEN_TAG]; S32 (*handle)(SOAP_CONTEXT *soap); }SOAP_TAG_HANDLE; /SOAP_TAG_HANDLE:结构体,包含一个标签字符串和一个处理函数指针/ LOCAL SOAP_TAG_HANDLE g_soap_tag_handle[SOAP_TAG_NUM]; /全局数组,用于存储注册的标签处理函数。/ /****************************************************************************** 函数名称: new_soap() 函数描述: 申请soap结构体 输 入: N/A 输 出: N/A 返 回 值: soap结构体地址 ******************************************************************************/ SOAP_CONTEXT *new_soap() { SOAP_CONTEXT *soap = NULL; soap = (SOAP_CONTEXT *)ONVIF_MALLOC(sizeof(SOAP_CONTEXT)); if (soap == NULL) { ONVIF_ERROR(“malloc g_soap_for_discv failed”); return NULL; } memset(soap, 0, sizeof(SOAP_CONTEXT)); if (OK != onvif_create_buf(&soap->xml_buf, ONVIF_DISCV_BUF_LEN)) { ONVIF_FREE(soap); return NULL; } return soap; } /****************************************************************************** 函数名称: free_soap() 函数描述: 释放soap结构体 输 入: soap – soap结构体地址 输 出: N/A 返 回 值: N/A ******************************************************************************/ void free_soap(SOAP_CONTEXT *soap) { if (soap == NULL) { return; } if (soap->fault != NULL) { ONVIF_FREE(soap->fault->soap_env_value); ONVIF_FREE(soap->fault->soap_env_subcode_1); ONVIF_FREE(soap->fault->soap_env_subcode_2); ONVIF_FREE(soap->fault->soap_env_reason); ONVIF_FREE(soap->fault); } onvif_free_buf(&soap->xml_buf); ONVIF_FREE(soap); return; } /****************************************************************************** 函数名称: soap_init() 函数描述: 初始化soap结构体 输 入: soap – soap结构体地址 输 出: N/A 返 回 值: N/A ******************************************************************************/ void soap_init(SOAP_CONTEXT *soap) { if (soap == NULL) { ONVIF_WARN(“soap == NULL.); return; } soap->error = OK; soap->in_ip = 0; soap->ifindex = -1; soap->has_header = FALSE; memset(&soap->header, 0, sizeof(SOAP_ENV_HEADER)); if (soap->fault != NULL) { ONVIF_FREE(soap->fault->soap_env_value); ONVIF_FREE(soap->fault->soap_env_subcode_1); ONVIF_FREE(soap->fault->soap_env_subcode_2); ONVIF_FREE(soap->fault->soap_env_reason); ONVIF_FREE(soap->fault); soap->fault = NULL; } soap->tag[0] = ‘\0’; soap->request_begin = NULL; soap->request_end = NULL; soap->types[0] = ‘\0’; soap->scopes_item[0] = ‘\0’; soap->scopes_matchby[0] = ‘\0’; if (soap->xml_buf.start == NULL || (soap->xml_buf.end - soap->xml_buf.start) > ONVIF_DISCV_BUF_LEN) { if (OK != onvif_create_buf(&soap->xml_buf, ONVIF_DISCV_BUF_LEN)) { soap->xml_buf.start = NULL; soap->xml_buf.last = NULL; soap->xml_buf.end = NULL; } } soap->xml_buf.last = soap->xml_buf.start; return; } /****************************************************************************** 函数名称: soap_out_env_fault() 函数描述: 组装错误信息报文内容 输 入: xml_buf – 存放输出xml字串的内存地址 fault_data -- 错误信息 输 出: N/A 返 回 值: ERROR/OK ******************************************************************************/ LOCAL S32 soap_out_env_fault(ONVIF_BUF *xml_buf, SOAP_ENV_FAULT *fault_data) { char attr[LEN_ANY] = {0}; if (xml_buf == NULL) { ONVIF_WARN(“xml_buf == NULL.); return ERROR; } /* SOAP-ENV:Fault begin */ SOAP_IF_FAIL_RET(soap_element_begin_out(xml_buf, G_SOAP_ENV_FAULT_STR, NULL)); /* SOAP-ENV:Code begin */ SOAP_IF_FAIL_RET(soap_element_begin_out(xml_buf, “SOAP-ENV:Code”, NULL)); /* SOAP-ENV:Value */ SOAP_IF_FAIL_RET(soap_element(xml_buf, “SOAP-ENV:Value”, fault_data->soap_env_value, NULL)); if (fault_data && fault_data->soap_env_subcode_1) { /* SOAP-ENV:Subcode begin */ SOAP_IF_FAIL_RET(soap_element_begin_out(xml_buf, “SOAP-ENV:Subcode”, NULL)); /* SOAP-ENV:Value */ SOAP_IF_FAIL_RET(soap_element(xml_buf, "SOAP-ENV:Value", fault_data->soap_env_subcode_1, NULL)); if (fault_data->soap_env_subcode_2) { /* SOAP-ENV:Subcode begin */ SOAP_IF_FAIL_RET(soap_element_begin_out(xml_buf, "SOAP-ENV:Subcode", NULL)); /* SOAP-ENV:Value */ SOAP_IF_FAIL_RET(soap_element(xml_buf, "SOAP-ENV:Value", fault_data->soap_env_subcode_2, NULL)); /* SOAP-ENV:Subcode end */ SOAP_IF_FAIL_RET(soap_element_end_out(xml_buf, "SOAP-ENV:Subcode")); } /* SOAP-ENV:Subcode end */ SOAP_IF_FAIL_RET(soap_element_end_out(xml_buf, "SOAP-ENV:Subcode")); } /* SOAP-ENV:Code end */ SOAP_IF_FAIL_RET(soap_element_end_out(xml_buf, “SOAP-ENV:Code”)); /* SOAP-ENV:Reason begin */ SOAP_IF_FAIL_RET(soap_element_begin_out(xml_buf, “SOAP-ENV:Reason”, NULL)); /* SOAP-ENV:Text */ snprintf(attr, sizeof(attr), “xml:lang="en"”); SOAP_IF_FAIL_RET(soap_element(xml_buf, “SOAP-ENV:Text”, fault_data->soap_env_reason, attr)); /* SOAP-ENV:Reason end */ SOAP_IF_FAIL_RET(soap_element_end_out(xml_buf, “SOAP-ENV:Reason”)); /* SOAP-ENV:Fault end */ SOAP_IF_FAIL_RET(soap_element_end_out(xml_buf, G_SOAP_ENV_FAULT_STR)); return OK; } /****************************************************************************** 函数名称: soap_fault() 函数描述: 填充错误信息结构体内容 输 入: soap – soap结构体地址 code -- 错误码 subcode1 -- 子错误码1 subcode2 -- 子错误码2 reason -- 错误原因 输 出: N/A 返 回 值: ERROR/OK ******************************************************************************/ S32 soap_fault(SOAP_CONTEXT *soap, char *code, char *subcode1, char *subcode2, char *reason) { ONVIF_TRACE(“Onvif_fault\n”); if (soap == NULL || code == NULL || subcode1 == NULL) { ONVIF_TRACE(“soap == NULL || code == NULL || subcode1 == NULL.); return ERROR; } if (soap->fault) { ONVIF_FREE(soap->fault->soap_env_value); ONVIF_FREE(soap->fault->soap_env_subcode_1); ONVIF_FREE(soap->fault->soap_env_subcode_2); ONVIF_FREE(soap->fault->soap_env_reason); } else { soap->fault = ONVIF_MALLOC(sizeof(SOAP_ENV_FAULT)); } if (NULL == soap->fault) { ONVIF_WARN(“ONVIF_MALLOC fault failed.); return ERROR; } memset(soap->fault, 0, sizeof(SOAP_ENV_FAULT)); soap->fault->soap_env_value = ONVIF_STRDUP(code); if (NULL == soap->fault->soap_env_value) { ONVIF_WARN(“ONVIF_STRDUP soap_env_value failed.); return ERROR; } soap->fault->soap_env_subcode_1 = ONVIF_STRDUP(subcode1); if (NULL == soap->fault->soap_env_subcode_1) { ONVIF_WARN(“ONVIF_STRDUP soap_env_subcode_1 failed.); return ERROR; } if (subcode2) { soap->fault->soap_env_subcode_2 = ONVIF_STRDUP(subcode2); if (NULL == soap->fault->soap_env_subcode_2) { ONVIF_WARN(“ONVIF_STRDUP soap_env_subcode_2 failed.); return ERROR; } } if (reason) { soap->fault->soap_env_reason = ONVIF_STRDUP(reason); if (NULL == soap->fault->soap_env_reason) { ONVIF_WARN(“ONVIF_STRDUP soap_env_reason failed.); return ERROR; } } return OK; } /****************************************************************************** 函数名称: soap_generate_fault() 函数描述: 组装错误报文xml内容 输 入: soap – soap结构体地址 输 出: N/A 返 回 值: ERROR/OK ******************************************************************************/ LOCAL S32 soap_generate_fault(SOAP_CONTEXT *soap) { if (soap == NULL) { ONVIF_WARN(“soap == NULL.); return ERROR; } //soap_set_fault(soap); if (soap->fault == NULL) { return ERROR; } if (soap->error < 200 && soap->error != SOAP_FAULT) { soap->has_header = FALSE; } return soap_generate_xml((p_out_fun)(soap_out_env_fault), soap, soap->fault); } /****************************************************************************** 函数名称: soap_serve_request() 函数描述: soap请求处理函数入口 输 入: soap – soap结构体地址 输 出: N/A 返 回 值: ERROR/OK ******************************************************************************/ S32 soap_serve_request(SOAP_CONTEXT *soap) { U32 index = 0; PASSTHROUGH_RET ret = 0; if (soap == NULL || soap->tag[0] == ‘\0’) { return ERROR; } ret = onvif_serve_passthrough(soap); if (PASSTHROUGH_ERROR == ret) { return ERROR; } else if (PASSTHROUGH_SOAP_FAULT == ret) { SOAP_IF_FAIL_RET(soap_generate_fault(soap)); } else if (PASSTHROUGH_NOT_MATCH == ret) { for (index = 0; index < SOAP_TAG_NUM; index++) { if (NULL == g_soap_tag_handle[index].handle) { SOAP_IF_FAIL_RET(soap_fault(soap, “SOAP-ENV:Receiver”, “ter:ActionNotSupported”, NULL, NULL)); soap->error = SOAP_FAULT; SOAP_IF_FAIL_RET(soap_generate_fault(soap)); break; } if (soap_match_tag(soap->tag, g_soap_tag_handle[index].tag)) { if (g_soap_tag_handle[index].handle(soap)) { if (soap->fault == NULL) { soap_fault(soap, "SOAP-ENV:Sender", "ter:InvalidArgVal", NULL, "error"); soap->error = SOAP_FAULT; } SOAP_IF_FAIL_RET(soap_generate_fault(soap)); } break; } } if (index >= SOAP_TAG_NUM) { SOAP_IF_FAIL_RET(soap_fault(soap, "SOAP-ENV:Receiver", "ter:ActionNotSupported", NULL, NULL)); soap->error = SOAP_FAULT; SOAP_IF_FAIL_RET(soap_generate_fault(soap)); } } /* UDP直接回复,HTTP在上一层回复 */ if (soap->use_udp == TRUE && soap->xml_buf.start != NULL && soap->xml_buf.start != soap->xml_buf.last) { return onvif_send_udp_packet(soap->sock, soap->in_ip, soap->sin_port, soap->xml_buf.start, (soap->xml_buf.last - soap->xml_buf.start)); } return OK; } LOCAL S32 soap_env_fault_handle(SOAP_CONTEXT *soap) { if (soap == NULL) { ONVIF_WARN(“soap == NULL.); return ERROR; } ONVIF_TRACE("SOAP-ENV:Fault handle."); /* do nothing and no response */ return OK; } /****************************************************************************** 函数名称: soap_tag_handle_add() 函数描述: 注册soap请求处理函数 输 入: tag – 请求tag handle -- 处理函数 输 出: N/A 返 回 值: ERROR/OK ******************************************************************************/ void soap_tag_handle_add(char *tag, void *handle) { U32 index = 0; if ((NULL == tag) || (strlen(tag) >= 64) || (NULL == handle)) { ONVIF_ERROR(“soap handle add error, invalid arg.); return; } while ((index < SOAP_TAG_NUM) && (NULL != g_soap_tag_handle[index].handle)) { index++; } if (index >= SOAP_TAG_NUM) { ONVIF_ERROR(“soap handle add error, max support %d tags.”, SOAP_TAG_NUM); return; } snprintf(g_soap_tag_handle[index].tag, sizeof(g_soap_tag_handle[index].tag), “%s”, tag); g_soap_tag_handle[index].handle = handle; return; } /****************************************************************************** 函数名称: soap_tag_handle_init() 函数描述: 初始化soap请求处理函数 输 入: N/A 输 出: N/A 返 回 值: ERROR/OK ******************************************************************************/ void soap_tag_handle_init() { U32 index = 0; for (index = 0; index < SOAP_TAG_NUM; index++) { memset(g_soap_tag_handle[index].tag, 0, sizeof(g_soap_tag_handle[index].tag)); g_soap_tag_handle[index].handle = NULL; } soap_tag_handle_add(“SOAP-ENV:Fault”, soap_env_fault_handle); return; } /****************************************************************************** 整体模块结构 初始化:调用soap_tag_handle_init初始化路由表。 创建上下文:new_soap创建一个新的SOAP上下文。 初始化上下文:soap_init初始化或重置上下文。 解析请求:由外部函数(如soap_parse_request)解析请求,填充上下文(如设置tag)。 处理请求:调用soap_serve_request,根据标签查找处理函数并执行。 错误处理:若处理出错,使用soap_fault设置错误信息,然后soap_generate_fault生成错误报文。 发送响应:如果是UDP,直接发送;如果是HTTP,由上层发送。 释放资源:调用free_soap释放上下文。 对外接口 soap_serve_request:请求处理入口。 soap_fault:业务函数用于报告错误。 soap_tag_handle_add:业务模块注册处理函数。 soap_tag_handle_init:模块初始化(系统启动调用)。 // Copyright © 2018-2018 TP-Link Systems Inc. Filename: soap_parse.c Version: 1.0 Description: soap 报文解析函数 Author: liyijieliyijie@tp-link.com.cn Date: 2018-11-29 ******************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <ctype.h> #include “soap_global.h” #include “soap_parse.h” LOCAL const SOAP_CODE_MAP g_xml_entity_table[] = { {(S32)‘&’, “amp”}, {(S32)‘'’, “apos”}, {(S32)‘>’, “gt”}, {(S32)‘<’, “lt”}, {(S32)‘"’, “quot”} }; /* abbr表示namespace的缩写,num表示该namespace在G_TP_NAMESPACE_LIST中的序号 */ struct recv_namespace_t { unsigned char num; char abbr[MAX_NAMESPACE_ABBR_LEN]; }; struct recv_namespaces { unsigned char ns_count; struct recv_namespace_t recv_namespace_list[MAX_TP_NAME_SPACE_COUNT]; }; LOCAL struct recv_namespaces g_recv_ns = {0}; LOCAL BOOL g_need_get_global_namespace = FALSE; LOCAL BOOL g_need_get_tag_namespace = FALSE; LOCAL int g_tag_namespace = -1; /**************************************************************************** Function : soap_ipv4_ntop Description: 将十进制形式的IPv4地址换为字符串形式 Input : ip_str : IPv4地址字符串形式指针 ip_dec : IPv4地址十进制形式指针 str_len : IPv4地址缓存长度 Output : N/A Return : 成功返回OK,出错返回ERROR ****************************************************************************/ STATUS soap_ipv4_ntop(u_int32 ip_dec, char *ip_str, u_int32 str_len) { struct in_addr in_addr; if (!ip_str || str_len < 8) { return ERROR; } in_addr.s_addr = htonl(ip_dec); if (inet_ntop(AF_INET, &in_addr, ip_str, str_len) == NULL) { return ERROR; } return OK; } /****************************************************************************** 函数名称: soap_match_tag() 函数描述: 匹配soap tag 输 入: str – 需要比对的字符串 tag -- 输入的tag 输 出: N/A 返 回 值: TRUE/FALSE ******************************************************************************/ BOOL soap_match_tag(char *str, const char *tag) { char *ptr_str = NULL; char *ptr_tag = NULL; S32 i = 0; if (str == NULL || tag == NULL) { return FALSE; } ptr_tag = strchr(tag, '😂; ptr_str = strchr(str, '😂; /* 当tag和str中都有’:',将两个字符串分成:前和:后,作两次比较 */ if (ptr_tag != NULL && ptr_str != NULL) { char *prev_str = str; while (prev_str && *prev_str == '/') { prev_str++; } /*比较:前的部分*/ if (!prev_str || strncasecmp((const char *)prev_str, tag, ptr_tag - tag) != 0 || strncasecmp((const char *)prev_str, tag, ptr_str - prev_str) != 0) { return FALSE; } /*继续比较:后的部分*/ ptr_str = ptr_str + 1; ptr_tag = ptr_tag + 1; } /* 当tag和str中都没有’:‘,完整比对两个字符串 */ else if (ptr_tag == NULL && ptr_str == NULL) { ptr_str = str; ptr_tag = (char )tag; } / 当tag和str中有一个字符串有’:‘,该字符串跳过’:',然后再进行比对 */ else { ptr_tag = (ptr_tag == NULL) ? (char *)tag : ptr_tag + 1; ptr_str = (ptr_str == NULL) ? str : ptr_str + 1; } while (ptr_str && *ptr_str == ‘/’) { ptr_str++; } if (!ptr_str || !ptr_tag) { return FALSE; } for (i = 0; i < strlen(ptr_tag); i++) { if (!ptr_str || *ptr_str == ‘\0’ || TOLOWER(*ptr_str) != TOLOWER(ptr_tag[i])) { return FALSE; } ptr_str++; } if (!ptr_str || *ptr_str != ‘\0’) { return FALSE; } return TRUE; } /****************************************************************************** 函数名称: soap_get_char() 函数描述: 从需要解析的xml字串中从获取一个字符 输 入: str – xml字串地址 输 出: N/A 返 回 值: 获取的字符 ******************************************************************************/ S32 soap_get_char(char **str) { S32 ch; const char **ps; if (str == NULL || *str == NULL) { return EOF; } ps = (const char **)str; if ((ch = (*ps)[0]) != 0) { (*ps)++; return ch; } return EOF; } /****************************************************************************** 函数名称: soap_add_char() 函数描述: 将一个字符加入指定buf中 输 入: ch – 需要添加的字符 pch -- buf最后一个有效字符的地址 buf -- 指定buf size -- 指定buf的大小 输 出: N/A 返 回 值: ERROR/OK ******************************************************************************/ S32 soap_add_char(S32 ch, char **pch, char *buf, S32 size) { if (pch == NULL || *pch == NULL || buf == NULL) { return ERROR; } if (*pch >= buf + size - 1) { return ERROR; } *(*pch)++ = ch & 0xff; return OK; } /****************************************************************************** 函数名称: soap_get_entity_value() 函数描述: 将xml字串中的义字符串换成实际字符 输 入: entity – 义字符串 输 出: N/A 返 回 值: 获取的字符 ******************************************************************************/ LOCAL S32 soap_get_entity_value(const char *entity) { U32 index = 0; U32 size = sizeof(g_xml_entity_table) / sizeof(g_xml_entity_table[0]); if (NULL == entity) { return -1; } for (index = 0; index < size; index++) { if (0 == strncmp(g_xml_entity_table[index].str, entity, strlen(g_xml_entity_table[index].str))) { return g_xml_entity_table[index].code; } } return -1; } /****************************************************************************** 函数名称: soap_get_entity() 函数描述: 获取xml字串中的义字符串并换成实际字符 输 入: str – xml字串地址 输 出: N/A 返 回 值: 获取的字符 ******************************************************************************/ LOCAL S32 soap_get_entity(char **str) { S32 ch = 0; char *entptr = NULL; char entity[32] = {0}; if (str == NULL || *str == NULL) { return EOF; } entptr = entity; while ((ch = soap_get_char(str)) != EOF) { if (ch > 126 || (!isalnum(ch) && ch != ‘#’)) { break; } else if (entptr < entity + sizeof(entity) - 1) { *entptr++ = ch; } else { break; } } *entptr = ‘\0’; if (ch != ‘;’) { return EOF; } if (entity[0] == ‘#’) { if (entity[1] == ‘x’) { ch = strtol(entity + 2, NULL, 16); } else { ch = strtol(entity + 1, NULL, 10); } } else { ch = soap_get_entity_value(entity); } return ch; } /****************************************************************************** 函数名称: soap_get_tag() 函数描述: 获取xml字串中element tag 输 入: str_start – xml字串起始地址 xml_str_len -- xml字串长度 p -- 已经解析的xml字串地址 out_buf -- tag输出buf地址 out_buf_len -- tag输出buf大小 输 出: 获得的tag 返 回 值: 获得完整tag后的下一个字符 ******************************************************************************/ S32 soap_get_tag(char *str_start, S32 xml_str_len, char **p, char *out_buf, S32 out_buf_len) { S32 ch = 0; char *pch = out_buf; if (str_start == NULL || out_buf == NULL || *p < str_start || xml_str_len <= 0 || out_buf_len <= 0 || (*p - str_start) >= xml_str_len) { return EOF; } memset(out_buf, 0, out_buf_len); while ((*p - str_start) < xml_str_len) { ch = soap_get_char(p); if (ch == ‘<’) { pch = out_buf; while ((*p - str_start) < xml_str_len) { ch = soap_get_char(p); if (IS_WHITE_SPACE(ch) || ch == ‘>’ || (ch == ‘/’ && pch > out_buf)) { break; } else if (ch == ‘&’) { if ((ch = soap_get_entity(p)) == EOF) { return EOF; } } if(soap_add_char(ch, &pch, out_buf, out_buf_len)) { return EOF; } } pch[0] = '\0'; break; } } ONVIF_TRACE(“tag:%s”, out_buf); return ch; } int soap_rearrange_tag(const char *src_tag, char *dest_tag) { char *temp_ptr = NULL; int namespace_num = g_tag_namespace; struct recv_namespaces *recv_ns = &g_recv_ns; char tag_abbr[MAX_NAMESPACE_ABBR_LEN] = {0}; char temp_abbr[MAX_NAMESPACE_ABBR_LEN] = {0}; int i = 0; if (!src_tag || !dest_tag) { ONVIF_ERROR("!src_tag || !dest_tag"); return ERROR; } if (namespace_num == -1 && recv_ns->ns_count == 0) { ONVIF_DEBUG("No need to rearrange tag."); return OK; } /* 获取tag内自带的abbr */ temp_ptr = strchr(src_tag, ':'); if (temp_ptr) { snprintf(tag_abbr, temp_ptr - src_tag + 1, "%s", src_tag); temp_ptr++; } else { temp_ptr = (char *)src_tag; } /* 获取abbr,首先使用tag后面指定的namespace */ if (namespace_num != -1) { if(namespace_num < 0 || namespace_num >= MAX_TP_NAME_SPACE_COUNT || G_TP_NAMESPACE_LIST[namespace_num].namespace[0] == 0 || G_TP_NAMESPACE_LIST[namespace_num].namespace_abbr[0] == 0) { ONVIF_ERROR("Get local namespace abbr fail, namespace_num=%d", namespace_num); return ERROR; } snprintf(temp_abbr, MAX_NAMESPACE_ABBR_LEN, "%s", G_TP_NAMESPACE_LIST[namespace_num].namespace_abbr); } /* 其次从g_recv_ns中获取 */ else if (tag_abbr[0] != 0) { for (i = 0; i < recv_ns->ns_count && i < MAX_TP_NAME_SPACE_COUNT; ++i) { if (strcmp(tag_abbr, recv_ns->recv_namespace_list[i].abbr) == 0 && recv_ns->recv_namespace_list[i].num < MAX_TP_NAME_SPACE_COUNT) { snprintf(temp_abbr, MAX_NAMESPACE_ABBR_LEN, "%s", G_TP_NAMESPACE_LIST[recv_ns->recv_namespace_list[i].num].namespace_abbr); //如果命名空间相同,取最新的,防重名 } } } /* 如果通过上面两种方式未获取到namespace,则直接退出,不重组tag */ if (0 == temp_abbr[0]) { return OK; } memset(dest_tag, 0, LEN_TAG); snprintf(dest_tag, LEN_TAG, "%s:%s", temp_abbr, temp_ptr); ONVIF_DEBUG("Tag changes, %s -> %s", src_tag, dest_tag); return OK; } /* 如果abbr为NULL,表示需要获取形如的 namespace,返回值为http://www.onvif.org/ver10/device/wsdl在G_TP_NAMESPACE_LIST中的下标值; 如果abbr不为空,表示需要获取形如<s:Envelope xmlns:s=“http://www.w3.org/2003/05/soap-envelope”>的 namespace,将这里定义的缩写s传到abbr中,并返回http://www.w3.org/2003/05/soap-envelope在 G_TP_NAMESPACE_LIST中的下标值; 如果没有匹配到namespace,或者tag里的namespace与缩写和已有的一致,则返回-1 */ int soap_get_namespace(const char *attr_name, const char *attr_value, char *abbr) { int i = -1; if (!attr_name || !attr_value) { ONVIF_ERROR("!attr_name || !attr_value"); return -1; } /* 确认是否是namespace */ if (NULL == strstr(attr_name, "xmlns")) { ONVIF_ERROR("Not a namespace: %s", attr_name); return -1; } /* 获取abbr */ if (abbr) { memset(abbr, 0, MAX_NAMESPACE_ABBR_LEN); if (1 == sscanf(attr_name, "xmlns:%15s", abbr) && 0 < strlen(abbr)) { ONVIF_DEBUG("Get abbr=%s", abbr); } else { ONVIF_DEBUG("Get abbr fail, attr_name=%s", attr_name); abbr[0] = 0; } } /* 查找对应namespace的下标 */ for (i = 0; i < MAX_TP_NAME_SPACE_COUNT; ++i) { if (0 != G_TP_NAMESPACE_LIST[i].namespace[0] && 0 == strcmp(G_TP_NAMESPACE_LIST[i].namespace, attr_value)) { /* 如果获取的是local namespace,或者获取到的abbr与已有的不一致,那就直接返回 */ if (!abbr) { ONVIF_DEBUG("Find a local namespace-%s, ret-%d", attr_value, i); return i; } else if (0 != abbr[0]) { if (0 != strcmp(G_TP_NAMESPACE_LIST[i].namespace_abbr, abbr)) { ONVIF_DEBUG("Find a global namespace-%s(%s), ret-%d", attr_value, abbr, i); return i; } else { ONVIF_DEBUG("This global namespace(%s-%s) has already exist.", abbr, attr_value); return -1; } } else { ONVIF_DEBUG("Find a local namespace-%s, ret-%d", attr_value, i); return i; } } } ONVIF_DEBUG("Can not find this namespace:%s", attr_value); return -1; } /****************************************************************************** 函数名称: soap_parse_element_attr() 函数描述: Parse an element for any attributes 输 入: str_start – xml字串起始地址 buf_len -- xml字串长度 p -- 已经解析的xml字串地址 输 出: 获得的tag 返 回 值: 解析完所有attr后的下一个字符 ******************************************************************************/ S32 soap_parse_element_attr(char *str_start, S32 buf_len, char **p) { char attr_name[LEN_TAG] = {0}; char attr_value[LEN_INFO] = {0}; char *ptr = NULL; S32 ch = 0; S32 quote = 0; BOOL need_get_tag_namespace = FALSE; BOOL need_get_global_namespace = FALSE; int temp_abbr_num = -1; char temp_abbr[MAX_NAMESPACE_ABBR_LEN] = {0}; need_get_tag_namespace = g_need_get_tag_namespace; g_need_get_tag_namespace = FALSE; need_get_global_namespace = g_need_get_global_namespace; g_need_get_global_namespace = FALSE; if (str_start == NULL || p == NULL || *p == NULL) { return EOF; } while ((p - str_start) < buf_len) { ch = soap_get_char(p); / Skip leading whitespace */ if (IS_WHITE_SPACE(ch)) { continue; } if (ch == '/' || ch == '?') { quote = soap_get_char(p); if (quote != '>') { return EOF; } (*p)--; break; } else if (ch == '<') { return EOF; } else if (ch == '>') { break; } attr_name[0] = ch; if (ch == '\"' || ch == '\'') /* Name is in quotes, so get a quoted string */ { quote = ch; ptr = attr_name; while ((*p - str_start) < buf_len) { ch = soap_get_char(p); if (ch == '&') { if ((ch = soap_get_entity(p)) == EOF) { return EOF; } } if(soap_add_char(ch, &ptr, attr_name, sizeof(attr_name))) { return EOF; } if (ch == quote) { break; } } } else { ptr = attr_name + 1; while ((*p - str_start) < buf_len) { ch = soap_get_char(p); if (IS_WHITE_SPACE(ch) || ch == '=' || ch == '/' || ch == '>' || ch == '?') { break; } if (ch == '&') { if ((ch = soap_get_entity(p)) == EOF) { return EOF; } } if(soap_add_char(ch, &ptr, attr_name, sizeof(attr_name))) { return EOF; } } } *ptr = '\0'; while ((*p - str_start) < buf_len && IS_WHITE_SPACE(ch)) { ch = soap_get_char(p); } if (ch != '=') { return EOF; } /* Read the attribute value */ while ((*p - str_start) < buf_len) { ch = soap_get_char(p); if (!IS_WHITE_SPACE(ch)) { break; } } if (ch == '\"' || ch == '\'') { quote = ch; ptr = attr_value; while ((*p - str_start) < buf_len) { ch = soap_get_char(p); if (ch == quote) { break; } if (ch == '&') { if ((ch = soap_get_entity(p)) == EOF) { return EOF; } } if(soap_add_char(ch, &ptr, attr_value, sizeof(attr_value))) { return EOF; } } } else { attr_value[0] = ch; ptr = attr_value + 1; while ((*p - str_start) < buf_len) { ch = soap_get_char(p); if (IS_WHITE_SPACE(ch) || ch == '=' || ch == '/' || ch == '>') { break; } if (ch == '&') { if ((ch = soap_get_entity(p)) == EOF) { return EOF; } } if(soap_add_char(ch, &ptr, attr_value, sizeof(attr_value))) { return EOF; } } } *ptr = '\0'; if (need_get_tag_namespace || need_get_global_namespace) { ONVIF_DEBUG("attr_name=%s, attr_value=%s", attr_name, attr_value); temp_abbr_num = soap_get_namespace(attr_name, attr_value, temp_abbr); ONVIF_DEBUG("temp_abbr_num=%d", temp_abbr_num); /* 通过temp_abbr[0]是否为0来区分是local还是global的abbr */ if (need_get_tag_namespace && temp_abbr_num > 0 && temp_abbr[0] == 0) { g_tag_namespace = temp_abbr_num; ONVIF_DEBUG("g_tag_namespace=%d", temp_abbr_num); } else if (need_get_global_namespace && temp_abbr_num != -1 && g_recv_ns.ns_count < MAX_TP_NAME_SPACE_COUNT && temp_abbr[0] != 0) { g_recv_ns.recv_namespace_list[g_recv_ns.ns_count].num = temp_abbr_num; snprintf(g_recv_ns.recv_namespace_list[g_recv_ns.ns_count].abbr, MAX_NAMESPACE_ABBR_LEN, "%s", temp_abbr); ONVIF_DEBUG("Recv global ns, ns_count=%d, num=%d, abbr=%s", g_recv_ns.ns_count, g_recv_ns.recv_namespace_list[g_recv_ns.ns_count].num, g_recv_ns.recv_namespace_list[g_recv_ns.ns_count].abbr); g_recv_ns.ns_count++; } } /* process attribute */ //if (soap_check_namespace(attr_value) == FALSE) //{ // ONVIF_WARN("soap_check_namespace failed, attr is %s:%s", attr_name, attr_value); // return EOF; //} if (ch == '/' || ch == '?') { quote = soap_get_char(p); if (quote != '>') { return EOF; } (*p)--; break; } else if (ch == '>') { break; } } return ch; } /****************************************************************************** 函数名称: soap_parse_element_attr_out_len() 函数描述: Parse an element for any attributes 输 入: str_start – xml字串起始地址 buf_len -- xml字串长度 p -- 已经解析的xml字串地址 attr_num -- 想要从<>中获取的attr的个数 attr_in_name -- 二维数组,想要获取的attr的名字 name_str_len -- attr_in_name二维数组每个元素的长度 value_str_len -- attr_out_value二维数组每个元素的长度 输 出: attr_out_value – 二维数组,存放attr_in_name对应的属性值 返 回 值: 解析完所有attr后的下一个字符 参数示例: 例如,想要取出<tt:SimpleItem Value=“60” Name=“Sensitivity”/>中, attr “Value”、"Name"的值,则为本函数传入如下参数: int attr_num = 2, char attr_in_name[2][10] = {{“Value”}, {“Name”}}; char attr_out_buf[2][30] = {{0}, {0}}; int name_str_len = sizeof(attr_in_name[0]); int value_str_len = sizeof(attr_out_buf[0]); 调用: ch = soap_parse_element_attr_out_len(str_start, buf_len, p, attr_num, (char *)attr_in_name, name_str_len, (char *)attr_out_buf, value_str_len); ******************************************************************************/ S32 soap_parse_element_attr_out_len(char *str_start, S32 buf_len, char p, int attr_num, char attr_in_name, int name_str_len, char attr_out_value, int value_str_len) { char* attr_name = NULL; char* attr_value = NULL; char *ptr = NULL; S32 ch = 0; S32 quote = 0; S32 i = 0; char *pn = NULL; char *pv = NULL; if (str_start == NULL || p == NULL || *p == NULL || attr_num <= 0 || attr_in_name == NULL || name_str_len <= 0 || attr_out_value == NULL || value_str_len <= 0) { ONVIF_ERROR("param is error."); return EOF; } attr_name = SAFE_MALLOC(name_str_len); attr_value = SAFE_MALLOC(value_str_len); if (NULL == attr_name || NULL == attr_value) { ONVIF_ERROR("malloc fail"); goto error_end; } memset(attr_name, 0, name_str_len); memset(attr_value, 0, value_str_len); ONVIF_TRACE("before while"); while ((*p - str_start) < buf_len) { ch = soap_get_char(p); /* Skip leading whitespace */ if (IS_WHITE_SPACE(ch)) { continue; } if (ch == '/' || ch == '?') { quote = soap_get_char(p); if (quote != '>') { goto error_end; } (*p)--; break; } else if (ch == '<') { goto error_end; } else if (ch == '>') { break; } attr_name[0] = ch; if (ch == '\"' || ch == '\'') /* Name is in quotes, so get a quoted string */ { quote = ch; ptr = attr_name; while ((*p - str_start) < buf_len) { ch = soap_get_char(p); if (ch == '&') { if ((ch = soap_get_entity(p)) == EOF) { goto error_end; } } if(soap_add_char(ch, &ptr, attr_name, name_str_len)) { goto error_end; } if (ch == quote) { break; } } } else { ptr = attr_name + 1; while ((*p - str_start) < buf_len) { ch = soap_get_char(p); if (IS_WHITE_SPACE(ch) || ch == '=' || ch == '/' || ch == '>' || ch == '?') { break; } if (ch == '&') { if ((ch = soap_get_entity(p)) == EOF) { goto error_end; } } if(soap_add_char(ch, &ptr, attr_name, name_str_len)) { //goto error_end; } } } *ptr = '\0'; while ((*p - str_start) < buf_len && IS_WHITE_SPACE(ch)) { ch = soap_get_char(p); } if (ch != '=') { goto error_end; } /* Read the attribute value */ while ((*p - str_start) < buf_len) { ch = soap_get_char(p); if (!IS_WHITE_SPACE(ch)) { break; } } if (ch == '\"' || ch == '\'') { quote = ch; ptr = attr_value; while ((*p - str_start) < buf_len) { ch = soap_get_char(p); if (ch == quote) { break; } if (ch == '&') { if ((ch = soap_get_entity(p)) == EOF) { goto error_end; } } if(soap_add_char(ch, &ptr, attr_value, value_str_len)) { goto error_end; } } } else { attr_value[0] = ch; ptr = attr_value + 1; while ((*p - str_start) < buf_len) { ch = soap_get_char(p); if (IS_WHITE_SPACE(ch) || ch == '=' || ch == '/' || ch == '>') { break; } if (ch == '&') { if ((ch = soap_get_entity(p)) == EOF) { goto error_end; } } if(soap_add_char(ch, &ptr, attr_value, value_str_len)) { goto error_end; } } } *ptr = '\0'; ONVIF_TRACE("%s:%s", attr_name, attr_value); for (i = 0; i < attr_num; i++) { pn = attr_in_name + i * name_str_len; pv = attr_out_value + i * value_str_len; if (0 != *pv) { ONVIF_TRACE("%d has been set", i); continue; } ONVIF_TRACE("attr_name:\nwant:%s; get:%s", pn, attr_name); if (0 == strncmp(attr_name, pn, strlen(attr_name))) { strcpy(pv, attr_value); ONVIF_TRACE("%s:%s", pn, pv); memset(attr_name, 0, name_str_len); memset(attr_value, 0, value_str_len); break; } } /* process attribute */ //if (soap_check_namespace(attr_value) == FALSE) //{ // ONVIF_WARN("soap_check_namespace failed, attr is %s:%s", attr_name, attr_value); // return EOF; //} if (ch == '/' || ch == '?') { quote = soap_get_char(p); if (quote != '>') { goto error_end; } (*p)--; break; } else if (ch == '>') { break; } } ONVIF_FREE(attr_name); ONVIF_FREE(attr_value); return ch; error_end: ONVIF_FREE(attr_name); ONVIF_FREE(attr_value); return EOF; } /****************************************************************************** 函数名称: soap_parse_element_value() 函数描述: 解析element内容 输 入: str_start – xml字串起始地址 xml_str_len -- xml字串长度 p -- 已经解析的xml字串地址 ch -- 当前需要解析的下一个字符 out_buf -- tag输出buf地址 out_buf_len -- tag输出buf大小 输 出: element内容 返 回 值: ERROR/OK ******************************************************************************/ S32 soap_parse_element_value(char *str_start, S32 buf_len, char **p, S32 ch, char *out_buf, S32 out_buf_len) { S32 tmp_ch = ch; char *pch = out_buf; if (str_start == NULL || buf_len <= 0 || p == NULL || *p == NULL || out_buf == NULL || out_buf_len <=0) { return ERROR; } if (IS_WHITE_SPACE(tmp_ch)) { tmp_ch = soap_parse_element_attr(str_start, buf_len, p); /* parse attribute */ if (tmp_ch == EOF) { ONVIF_WARN(“soap_parse_element_attr error.); return ERROR; } } if (tmp_ch == ‘/’) { tmp_ch = soap_get_char(p); if (tmp_ch != ‘>’) { ONVIF_WARN(“should be '>'(%d) but is %d.”, (S32)‘>’, tmp_ch); return ERROR; } return OK; } else if (tmp_ch == ‘>’) { while ((*p - str_start) < buf_len) { tmp_ch = soap_get_char(p); if (tmp_ch == ‘<’) { (*p)–; break; } else if (tmp_ch == ‘&’) { if ((tmp_ch = soap_get_entity(p)) == EOF) { ONVIF_WARN(“soap_get_entity error.); return ERROR; } } if(soap_add_char(tmp_ch, &pch, out_buf, out_buf_len)) { ONVIF_WARN("soap_add_char failed."); return ERROR; } } pch[0] = '\0'; } else { ONVIF_WARN(“should be '>'(%d) but is %d.”, (S32)‘>’, tmp_ch); return ERROR; } return OK; } /****************************************************************************** 函数名称: soap_parse_header_element() 函数描述: 解析所有头部元素,并做相应处理 输 入: soap – soap结构体地址 tag -- 头部元素tag str_start -- xml字串起始地址 buf_len -- xml字串长度 p -- 已经解析的xml字串地址 ch -- 当前需要解析的下一个字符 输 出: N/A 返 回 值: ERROR/OK ******************************************************************************/ LOCAL S32 soap_parse_header_element(SOAP_CONTEXT *soap, char *tag, char *str_start, S32 buf_len, char **p, S32 ch) { char charbuf[LEN_INFO] = {0}; char tag_rearrange[LEN_TAG] = {0}; char *p1 = NULL; if (soap == NULL || tag == NULL || str_start == NULL || buf_len <= 0 || p == NULL || *p == NULL) { return ERROR; } p1 = *p; g_tag_namespace = -1; g_need_get_global_namespace = TRUE; g_need_get_tag_namespace = TRUE; if (OK != soap_parse_element_value(str_start, buf_len, p, ch, charbuf, sizeof(charbuf))) { return ERROR; } ONVIF_TRACE(“%s: %s”, tag, charbuf); if (charbuf[0] == ‘\0’) { return OK; } /* 根据命名空间跟换tag 如: request中Envelope 有内容:xmlns:a=“http://www.w3.org/2005/08/addressing” header中有: <a:MessageID>urn:uuid:7f52d7e1-63c4-4124-943c-c24d4825f15d</a:MessageID> 获取的tag为 a:MessageID 根据本地G_TP_NAMESPACE_LIST中的命名空间:{“wsa5”, “http://www.w3.org/2005/08/addressing”} 替换tag为 wsa5:MessageID reponse中Envelope 有内容:xmlns:wsa5=“http://www.w3.org/2005/08/addressing” header中有: wsa5:MessageIDurn:uuid:7f52d7e1-63c4-4124-943c-c24d4825f15d</wsa5:MessageID> */ soap_rearrange_tag(tag, tag_rearrange); ONVIF_TRACE(“[%s]: %s”, tag_rearrange, charbuf); if (TRUE == soap_match_tag(tag_rearrange, “wsa:MessageID”)) { snprintf(soap->header.wsa_msg_id, sizeof(soap->header.wsa_msg_id), “%s”, charbuf); } else if(TRUE == soap_match_tag(tag_rearrange, “wsa:RelatesTo”)) { if ((ch = soap_get_tag(str_start, buf_len, p, charbuf, sizeof(charbuf))) != EOF && TRUE == soap_match_tag(charbuf, “Relationship”) && OK == soap_parse_element_value(str_start, buf_len, p, ch, charbuf, sizeof(charbuf))) { snprintf(soap->header.wsa_relates_to, sizeof(soap->header.wsa_relates_to), “%s”, charbuf); } } else if(TRUE == soap_match_tag(tag_rearrange, “wsa:From”)) { if ((ch = soap_get_tag(str_start, buf_len, p, charbuf, sizeof(charbuf))) != EOF && TRUE == soap_match_tag(charbuf, “Address”) && OK == soap_parse_element_value(str_start, buf_len, p, ch, charbuf, sizeof(charbuf))) { snprintf(soap->header.wsa_from_addr, sizeof(soap->header.wsa_from_addr), “%s”, charbuf); } } else if(TRUE == soap_match_tag(tag_rearrange, “wsa:ReplyTo”)) { if ((ch = soap_get_tag(str_start, buf_len, p, charbuf, sizeof(charbuf))) != EOF && TRUE == soap_match_tag(charbuf, “Address”) && OK == soap_parse_element_value(str_start, buf_len, p, ch, charbuf, sizeof(charbuf))) { snprintf(soap->header.wsa_reply_to_addr, sizeof(soap->header.wsa_reply_to_addr), “%s”, charbuf); } } else if(TRUE == soap_match_tag(tag_rearrange, “wsa:FaultTo”)) { if ((ch = soap_get_tag(str_start, buf_len, p, charbuf, sizeof(charbuf))) != EOF && TRUE == soap_match_tag(charbuf, “Address”) && OK == soap_parse_element_value(str_start, buf_len, p, ch, charbuf, sizeof(charbuf))) { snprintf(soap->header.wsa_fault_to_addr, sizeof(soap->header.wsa_fault_to_addr), “%s”, charbuf); } } else if(TRUE == soap_match_tag(tag_rearrange, “wsa:To”)) { snprintf(soap->header.wsa_to, sizeof(soap->header.wsa_to), “%s”, charbuf); } else if(TRUE == soap_match_tag(tag_rearrange, “wsa:Action”)) { snprintf(soap->header.wsa_action, sizeof(soap->header.wsa_action), “%s”, charbuf); } else if(TRUE == soap_match_tag(tag_rearrange, “wsdd:AppSequence”)) { snprintf(soap->header.wsdd_app_sequence, sizeof(soap->header.wsdd_app_sequence), “%s”, charbuf); } else if (TRUE == soap_match_tag(tag_rearrange, “wsa5:MessageID”)) { snprintf(soap->header.wsa5_msg_id, sizeof(soap->header.wsa5_msg_id), “%s”, charbuf); } else if(TRUE == soap_match_tag(tag_rearrange, “wsa5:RelatesTo”)) { if ((ch = soap_get_tag(str_start, buf_len, p, charbuf, sizeof(charbuf))) != EOF && TRUE == soap_match_tag(charbuf, “RelatesToType”) && OK == soap_parse_element_value(str_start, buf_len, p, ch, charbuf, sizeof(charbuf))) { snprintf(soap->header.wsa5_relates_to, sizeof(soap->header.wsa5_relates_to), “%s”, charbuf); } } else if(TRUE == soap_match_tag(tag_rearrange, “wsa5:From”)) { if ((ch = soap_get_tag(str_start, buf_len, p, charbuf, sizeof(charbuf))) != EOF && TRUE == soap_match_tag(charbuf, “Address”) && OK == soap_parse_element_value(str_start, buf_len, p, ch, charbuf, sizeof(charbuf))) { snprintf(soap->header.wsa5_from_addr, sizeof(soap->header.wsa5_from_addr), “%s”, charbuf); } } else if(TRUE == soap_match_tag(tag_rearrange, “wsa5:ReplyTo”)) { if ((ch = soap_get_tag(str_start, buf_len, p, charbuf, sizeof(charbuf))) != EOF && TRUE == soap_match_tag(charbuf, “Address”) && OK == soap_parse_element_value(str_start, buf_len, p, ch, charbuf, sizeof(charbuf))) { snprintf(soap->header.wsa5_reply_to_addr, sizeof(soap->header.wsa5_reply_to_addr), “%s”, charbuf); } } else if(TRUE == soap_match_tag(tag_rearrange, “wsa5:FaultTo”)) { if ((ch = soap_get_tag(str_start, buf_len, p, charbuf, sizeof(charbuf))) != EOF && TRUE == soap_match_tag(charbuf, “Address”) && OK == soap_parse_element_value(str_start, buf_len, p, ch, charbuf, sizeof(charbuf))) { snprintf(soap->header.wsa5_fault_to_addr, sizeof(soap->header.wsa5_fault_to_addr), “%s”, charbuf); } } else if(TRUE == soap_match_tag(tag_rearrange, “wsa5:To”)) { snprintf(soap->header.wsa5_to, sizeof(soap->header.wsa5_to), “%s”, charbuf); } else if(TRUE == soap_match_tag(tag_rearrange, “wsa5:Action”)) { snprintf(soap->header.wsa5_action, sizeof(soap->header.wsa5_action), “%s”, charbuf); } else if(TRUE == soap_match_tag(tag, “Username”)) { snprintf(soap->header.username, sizeof(soap->header.username), “%s”, charbuf); } else if(TRUE == soap_match_tag(tag, “Password”)) { soap_parse_element_attr_out_len(str_start, buf_len, &p1, 1, “Type”, LEN_IFNAME, (char *)soap->header.password_type, sizeof(soap->header.password_type)); snprintf(soap->header.password, sizeof(soap->header.password), "%s", charbuf); } else if(TRUE == soap_match_tag(tag, “Nonce”)) { snprintf(soap->header.nonce, sizeof(soap->header.nonce), “%s”, charbuf); } else if(TRUE == soap_match_tag(tag, “Created”)) { snprintf(soap->header.created, sizeof(soap->header.created), “%s”, charbuf); } /* 下面的内容是为了适配onvif device manager的异常tag { / else if (TRUE == soap_match_tag(tag, “MessageID”)) { if (‘\0’ == soap->header.wsa_msg_id[0]) { snprintf(soap->header.wsa_msg_id, sizeof(soap->header.wsa_msg_id), “%s”, charbuf); } } else if(TRUE == soap_match_tag(tag, “ReplyTo”)) { if ((ch = soap_get_tag(str_start, buf_len, p, charbuf, sizeof(charbuf))) != EOF && TRUE == soap_match_tag(charbuf, “Address”) && OK == soap_parse_element_value(str_start, buf_len, p, ch, charbuf, sizeof(charbuf)) && ‘\0’ == soap->header.wsa_reply_to_addr[0]) { snprintf(soap->header.wsa_reply_to_addr, sizeof(soap->header.wsa_reply_to_addr), “%s”, charbuf); } } else if(TRUE == soap_match_tag(tag, “To”)) { if (‘\0’ == soap->header.wsa_to[0]) { snprintf(soap->header.wsa_to, sizeof(soap->header.wsa_to), “%s”, charbuf); } } else if(TRUE == soap_match_tag(tag, “Action”)) { if (‘\0’ == soap->header.wsa_action[0]) { snprintf(soap->header.wsa_action, sizeof(soap->header.wsa_action), “%s”, charbuf); } } / 适配onvif device manager的异常tag end} */ return OK; } /****************************************************************************** 函数名称: soap_xml_parse() 函数描述: xml字串解析函数 输 入: soap – soap结构体地址 xml_str -- xml字串起始地址 buf_len -- xml字串长度 输 出: N/A 返 回 值: ERROR/OK ******************************************************************************/ S32 soap_xml_parse(SOAP_CONTEXT *soap, char **xml_str, S32 buf_len) { BOOL request_have_header = FALSE; S32 ch = 0; char charbuf[4 * LEN_INFO] = {0}; char *str_start = NULL; char **p = xml_str; if (soap == NULL || xml_str == NULL || *xml_str == NULL || buf_len <= 0) { ONVIF_WARN(“soap == NULL || xml_str == NULL || buf_len <= 0.); return ERROR; } str_start = *xml_str; memset(&g_recv_ns, 0, sizeof(struct recv_namespaces)); /* onvif device manager发送的probe中不包含version行,导致设备探测失败; 当前也没有对version行进行处理,因此参考slp,不对version进行处理,先 去除这部分内容,从Envelope开始处理 */ // char pch = charbuf; #if 0 / parse version line */ while ((p - str_start) < buf_len) { ch = soap_get_char(p); if (ch == ‘<’) { pch = charbuf; ch = soap_get_char(p); if (ch == ‘?’) { / macth version line */ if(soap_add_char(ch, &pch, charbuf, sizeof(charbuf))) { goto error_parse; } while ((*p - str_start) < buf_len) { ch = soap_get_char(p); if (ch == '>' && pch > charbuf && pch[-1] == '?') { break; } else if (ch == '&') { if ((ch = soap_get_entity(p)) == EOF) { return EOF; } } if(soap_add_char(ch, &pch, charbuf, sizeof(charbuf))) { goto error_parse; } } if (ch != '>') { goto error_parse; } /* get version line, to do something */ pch[0] = '\0'; ONVIF_TRACE("version line: <%s>", charbuf); break; } else { continue; } } } #endif /* parse Envelope, request must have Envelope */ while ((*p - str_start) < buf_len) { if ((ch = soap_get_tag(str_start, buf_len, p, charbuf, sizeof(charbuf))) == EOF) { goto error_parse; } if (TRUE == soap_match_tag(charbuf, "Envelope")) { break; } } /* start parse Envelope attribute / if (IS_WHITE_SPACE(ch)) { g_need_get_global_namespace = TRUE; ch = soap_parse_element_attr(str_start, buf_len, p); / parse attribute */ if (ch == EOF) { goto error_parse; } } while ((*p - str_start) < buf_len) { if ((ch = soap_get_tag(str_start, buf_len, p, charbuf, sizeof(charbuf))) == EOF) { goto error_parse; } if (TRUE == soap_match_tag(charbuf, "Header") || TRUE == soap_match_tag(charbuf, "Body")) { break; } } soap->has_header = FALSE; /* parse Header, request maybe have Header / if (TRUE == soap_match_tag(charbuf, “Header”)) { request_have_header = TRUE; / parse Header value / / start parse Envelope attribute / if (IS_WHITE_SPACE(ch)) { ch = soap_parse_element_attr(str_start, buf_len, p); / parse attribute */ if (ch == EOF) { goto error_parse; } } if (ch == '/') { ch = soap_get_char(p); if (ch != '>') { goto error_parse; } goto parse_body; } soap->has_header = TRUE; while ((*p - str_start) < buf_len) { if ((ch = soap_get_tag(str_start, buf_len, p, charbuf, sizeof(charbuf))) == EOF) { goto error_parse; } if (charbuf[0] == '/') { if (TRUE == soap_match_tag(charbuf, "Header")) { /* end of Header */ ONVIF_TRACE("end of Header"); break; } else { continue; } } if (ERROR == soap_parse_header_element(soap, charbuf, str_start, buf_len, p, ch)) { goto error_parse; } } } else { request_have_header = FALSE; } parse_body: /* parse Body, request must have Body */ if (request_have_header == TRUE) { while ((*p - str_start) < buf_len) { if ((ch = soap_get_tag(str_start, buf_len, p, charbuf, sizeof(charbuf))) == EOF) { goto error_parse; } if (TRUE == soap_match_tag(charbuf, "Body")) { break; } } } if (IS_WHITE_SPACE(ch)) { g_need_get_global_namespace = TRUE; ch = soap_parse_element_attr(str_start, buf_len, p); /* parse attribute */ if (ch == EOF) { goto error_parse; } } if (ch == '/') { ch = soap_get_char(p); if (ch != '>') { goto error_parse; } goto end_parse; } /* parse Body value */ if ((ch = soap_get_tag(str_start, buf_len, p, charbuf, sizeof(charbuf))) == EOF) { goto error_parse; } snprintf(soap->tag, sizeof(soap->tag), "%s", charbuf); ONVIF_TRACE("get soap->tag: %s", soap->tag); g_tag_namespace = -1; if (IS_WHITE_SPACE(ch)) { g_need_get_global_namespace = TRUE; g_need_get_tag_namespace = TRUE; ch = soap_parse_element_attr(str_start, buf_len, p); /* parse attribute */ if (ch == EOF) { goto error_parse; } } if (ch == '/') { ch = soap_get_char(p); if (ch != '>') { goto error_parse; } soap->request_begin = NULL; soap->request_end = NULL; } else if (ch == '>') { soap->request_begin = *p; while ((*p - str_start) < buf_len) { ch = soap_get_char(p); if (ch == '/' && 0 == strncmp(*p, soap->tag, strlen(soap->tag))) { while (**p != '<') { (*p)--; } soap->request_end = *p; break; } } } else { goto error_parse; } soap_rearrange_tag(charbuf, soap->tag); end_parse: return OK; error_parse: return ERROR; } ——这个是soap.c和soap_parse.c文件,并注意Digest认证的验证函数直接写在onvif_srv.c就行,重新回答前面的Digest认证的实现的问题
09-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值