1. 简直是个噩梦。
2. 下载GSOAP 2.8.15, 下载cwmp-1-0.xsd
3. 下载VS 2010插件 WSCF.blue,从cwmp-1-0.xsd生成WSDL文件 cwmp_agent.wsdl
4. 修改cwmp_agent.wsdl文件中的 Header部分
5. 用wsdl2h生成 cwmp_agent.wsdl文件
wsd2h -c cwmp_agent.wsdl
6. 用soapcpp2 生成代码
soapcpp2 -c -L cwmp_agent.h
7. 修改生成的代码
7.1 修改 soapC.c 中的部分代码, 消除属性重复问题
SOAP_FMAC3 int SOAP_FMAC4 soap_out_SOAP_ENV__Header(struct soap *soap, const char *tag, int id, const struct SOAP_ENV__Hea
der *a, const char *type)
{
(void)soap; (void)tag; (void)id; (void)type;
if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, a, SOAP_TYPE_SOAP_ENV__Header), type))
return soap->error;
soap->mustUnderstand = 0; // 原代码为soap->mustUnderstand = 1,导致SOAP-ENV:mustUnderstand="1" 被重复
if (soap_out_PointerTo_ns1__HoldRequests(soap, "ns1:HoldRequests", -1, &a->ns1__HoldRequests, ""))
return soap->error;
soap->mustUnderstand = 0; // 原代码为soap->mustUnderstand = 1,导致SOAP-ENV:mustUnderstand="1" 被重复
if (soap_out_PointerTo_ns1__ID(soap, "ns1:ID", -1, &a->ns1__ID, ""))
return soap->error;
return soap_element_end_out(soap, tag);
}
7.2 增加对 客户端发送 EMPTY HTTP POST消息的支持
第一处修改stdsoap.c:
在行14934以下,增加下面红色代码,防止HTTP CONTENT-LENGTH = 0时,继续读取body照成的阻塞
if (soap->length == 0 && soap->body == 0)
{
return soap->error = SOAP_NO_DATA;
}
if (soap_get0(soap) == (int)EOF)
{ if (soap->status == 0 || soap->status == 200)
return soap->error = SOAP_NO_DATA; /* HTTP OK: always expect data */
return soap->error = soap->status;
}
第二处修改soapServer.c
函数SOAP_FMAC5 int SOAP_FMAC6 soap_serve(struct soap *soap),33行位置
if (soap_begin_serve(soap))
{
if(soap->error == SOAP_NO_DATA)
{
// empty HTTP POST
}
else
{
if (soap->error >= SOAP_STOP)
continue;
return soap->error;
}
}
第三处修改soapServer.c
函数SOAP_FMAC5 int SOAP_FMAC6 soap_serve_request(struct soap *soap)
{
if(soap->error == SOAP_NO_DATA)
return soap_serve___ns1__EmptyHTTPRequest(soap);
增加相应的 soap_serve___ns1__EmptyHTTPRequest函数就行了。
7.3 keep-alive问题:
默认的情况下,未启用KEE_ALIVE,启用keep-alive,可以在main函数中,加入如下代码
soap_init2(&soap,SOAP_IO_KEEPALIVE, SOAP_IO_KEEPALIVE);
对于要采用mod_gsoap的方式,需要修改 mod_gsoap.c文件中的以下部分,以允许处理CPE上报的空HTTP POST
static int
gsoap_handler(request_rec * r)
{
if (0 == nRet)
{
//SendErrorMessage(r, "No body received");
return OK;
}
}
7.4 apache 插件模式下支持cookie需要修改mod_gsoap.c
static int
http_post_header(struct soap *soap, const char *key, const char *value)
{
gsoapRequestConfiguration *pRqConf = getRequestConfiguration(soap);
request_rec *r = NULL == pRqConf ? NULL : pRqConf->r;
if (NULL != value)
{
if (0 == strcasecmp(key, "SOAPAction"))
{
apr_table_set(r->headers_out, key, value);
}
else if (0 == strcasecmp(key, "Content-Type"))
{
r->content_type = apr_pstrdup(r->pool, value);
}
else if (0 == strcasecmp(key, "Content-Length"))
{
ap_set_content_length(r, atoi(value));
}
else if(0 == strcasecmp(key, "Set-Cookie"))
{
apr_table_set(r->headers_out, key, value);
}
}
return SOAP_OK;
}