blob: 58038f36bc6aa29dcec41c712a1bc4b2f22dc1cc [file] [log] [blame]
/************************************************************************
* *
* Netcwmp/Opencwmp Project *
* A software client for enabling TR-069 in embedded devices (CPE). *
* *
* Copyright (C) 2013-2014 netcwmp.netcwmp group *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the *
* Free Software Foundation, Inc., 59 Temple Place, Suite 330, *
* Boston, MA 02111-1307 USA *
* *
* Copyright 2013-2014 Mr.x(Mr.x) <netcwmp@gmail.com> *
* *
***********************************************************************/
#include "cwmp/periodic.h"
#include "cwmp_module.h"
#include "cwmp_agent.h"
#include <cwmp/session.h>
//#include "modules/data_model.h"
#include "soft_timer.h"
#define CWMP_TRUE 1
#define MAX_SESSION_RETRY 3
enum
{
CWMP_ST_START = 0,
CWMP_ST_INFORM,
CWMP_ST_SEND,
CWMP_ST_RESEMD,
CWMP_ST_RECV,
CWMP_ST_ANSLYSE,
CWMP_ST_RETRY,
CWMP_ST_END,
CWMP_ST_EXIT
};
#define SECHEDULE_INFORM_TIMER (31)
schedule_inform_info_st g_si;
int get_session_status()
{
return g_si.cwmp->session_running;
}
void *schedule_inform_timeout(void *arg)
{
FUNCTION_TRACE();
int i = 0;
schedule_inform_info_st *psi = (schedule_inform_info_st *)arg;
cwmp_log_info("push begin");
psi->timer_running = 2;
// while(1)
// {
// if(SESSION_NO_RUNNING == get_session_status())
// {
psi->cwmp->new_request = CWMP_YES;
cwmp_event_set_value(psi->cwmp, INFORM_SCHEDULED, 1, psi->commandKey, 0, 0, 0);
cwmp_log_info("commandkey is:%s", psi->commandKey);
psi->timer_running = 0;
cwmp_log_info("push ok");
return NULL;
// }
// else
// {
// cwmp_log_info("there is session running");
// psi->timer_running = 0;
// g_si.delaytime += 1;
// if(CWMP_OK != schedule_inform_create_timer(&g_si))
// {
// ;
// }
// }
// }
return NULL;
}
int schedule_inform_create_timer(schedule_inform_info_st* psi)
{
FUNCTION_TRACE();
if(2 == g_si.timer_running){
cwmp_log_info("there is other schedule inform running!");
return CWMP_OK;
}
else if(1 == g_si.timer_running)
{
// if exist one schedule inform timer, update
cwmp_log_info("there is other schedule inform active!");
sc_timer_delete(SECHEDULE_INFORM_TIMER);
}
else
{
cwmp_log_info("update schedule inform info, create timer");
}
TRstrncpy(g_si.commandKey, psi->commandKey, COMMAND_KEY_LEN);
g_si.delaytime = psi->delaytime;
g_si.cwmp = psi->cwmp;
cwmp_log_info("begin to create timer!");
long result = sc_timer_create(SECHEDULE_INFORM_TIMER, TIMER_FLAG_ONCE, psi->delaytime*1000, schedule_inform_timeout, &g_si);
g_si.timer_running = 1;
cwmp_log_info("end to create timer!");
cwmp_log_info("commandkey is:%s, delaytime:%d", psi->commandKey, psi->delaytime);
return CWMP_OK;
}
int cwmp_agent_retry_session(cwmp_session_t * session)
{
int sec = 0;
int count = 1;
srand(time(NULL));
switch (session->retry_count)
{
case 0:
{
count = 5; //5~10
break;
}
case 1:
{
count = 10; //5~15
break;
}
case 2:
{
count = 20; //5~25
break;
}
default:
{
count = 30; //5~35
break;
}
}
sec = 5 + rand()% count;
while (sec>0)
{
sleep(1);
sec--;
}
if (session->retry_count > MAX_SESSION_RETRY)
{
session->retry_count = 0;
return CWMP_TIMEOUT;
}
else
{
session->retry_count ++;
return CWMP_OK;
}
}
int cwmp_agent_create_datetimes(datatime_t *nowtime)
{
struct tm *t;
time_t tn;
//FUNCTION_TRACE();
tn = time(NULL);
#ifdef WIN32
cwmp_log_debug("inform datatime");
//localtime_s(&t, &tn);
t = MALLOC(sizeof(struct tm));
memset(t, 0, sizeof(struct tm));
#else
t = localtime(&tn);
#endif
if(NULL != t)
{
nowtime->year = t->tm_year + 1900;
nowtime->month = t->tm_mon + 1;
nowtime->day = t->tm_mday;
nowtime->hour = t->tm_hour;
nowtime->min = t->tm_min;
nowtime->sec = t->tm_sec;
}
else
{
cwmp_log_error("localtime return null");
}
return CWMP_OK;
}
//È¡µÃactive eventÒÔ¼°count
int cwmp_agent_get_active_event(cwmp_t *cwmp, cwmp_session_t * session, event_list_t **pevent_list)
{
event_list_t * el;
event_code_t * ev;
int i=0;
FUNCTION_TRACE();
el = cwmp_create_event_list(session->env, INFORM_MAX);
if(NULL == el)
{
cwmp_log_error("el cwmp_create_event_list return NULL");
return CWMP_ERROR;
}
event_code_t ** pec = cwmp->el->events;
int elsize = cwmp->el->count;
for(i=0; i<elsize; i++)
{
if(pec[i] && pec[i]->ref > 0)
{
event_code_t * ec = pec[i];
ev = cwmp_create_event_code(session->env);
if(NULL == ev)
{
cwmp_log_error("ev cwmp_create_event_code return null");
return CWMP_ERROR;
}
ev->event = ec->event;
ev->code = ec->code;
if (pec[i]->event == INFORM_MREBOOT || pec[i]->event == INFORM_BOOTSTRAP)
{
strncpy(ev->command_key , ec->command_key, COMMAND_KEY_LEN);
}
el->events[el->count++] = ev;
ev = NULL;
}
}
if (el->count == 0)
{
ev = cwmp_create_event_code(session->env);
if(NULL == ev)
{
cwmp_log_error("ev cwmp_create_event_code return null");
return CWMP_ERROR;
}
ev->event = INFORM_BOOT;
ev->code = CWMP_INFORM_EVENT_CODE_1;
el->events[el->count++] = ev;
}
*pevent_list = el;
return CWMP_OK;
}
int cwmp_agent_send_request(cwmp_session_t * session)
{
FUNCTION_TRACE();
return cwmp_session_send_request(session);
}
int cwmp_agent_recv_response(cwmp_session_t * session)
{
return cwmp_session_recv_response(session);
}
void cwmp_agent_start_session(cwmp_t * cwmp)
{
int rv;
cwmp_session_t * session;
int session_close = CWMP_NO;
xmldoc_t * newdoc;
FUNCTION_TRACE();
event_list_t *evtlist;
while (TRUE)
{
if (cwmp->new_request == CWMP_NO)
{
cwmp_log_debug("No new request from ACS\n");
sleep(2);
//cwmp->new_request = CWMP_YES;
continue;
}
cwmp_log_debug("New request from ACS\n");
cwmp_clean_periodic_inform(cwmp);
cwmp->new_request = CWMP_NO;
session = cwmp_session_create(cwmp);
if(NULL == session)
{
cwmp_log_error("session cwmp_session_create return NULL");
cwmp->new_request = CWMP_YES;
continue;
}
session_close = CWMP_NO;
session->timeout = cwmp_conf_get_int("cwmpd:http_timeout");
//cwmp_session_set_timeout(cwmp_conf_get_int("cwmpd:http_timeout"));
cwmp_log_debug("session timeout is %d", session->timeout);
cwmp_session_open(session);
while (!session_close)
{
//cwmp_log_debug("session status: %d", session->status);
switch (session->status)
{
case CWMP_ST_START:
//create a new connection to acs
cwmp_log_debug("session stutus: New START\n");
if (cwmp_session_connect(session, cwmp->acs_url) != CWMP_OK)
{
cwmp_log_error("connect to acs: %s failed.\n", cwmp->acs_url);
session->status = CWMP_ST_RETRY;
}
else
{
session->status = CWMP_ST_INFORM;
}
break;
case CWMP_ST_INFORM:
evtlist = NULL;
cwmp_log_debug("session stutus: INFORM\n");
cwmp_agent_get_active_event(cwmp, session, & evtlist);
if(evtlist != NULL)
{
cwmp_event_clear_active(cwmp);
}
else
{
cwmp_log_debug("evtlist is null");
session->status = CWMP_ST_EXIT;
break;
}
cwmp_log_debug("session stutus: INFORM2\n");
if (cwmp->acs_auth)
{
cwmp_session_set_auth(session, cwmp->acs_user, cwmp->acs_pwd );
}
cwmp_log_debug("session stutus: INFORM3\n");
newdoc = cwmp_session_create_inform_message(session, evtlist, session->envpool);
if(NULL != newdoc)
{
cwmp_write_doc_to_chunk(newdoc, session->writers, session->envpool);
session->last_method = CWMP_INFORM_METHOD;
session->status = CWMP_ST_SEND;
}
else
{
cwmp_log_error("newdoc is null");
session->last_method = CWMP_INFORM_METHOD;
session->status = CWMP_ST_EXIT;
}
break;
case CWMP_ST_SEND:
cwmp_log_debug("session stutus: SEND");
cwmp_log_debug("session data request length: %d", cwmp_chunk_length(session->writers));
session->newdata = CWMP_NO;
rv = cwmp_agent_send_request(session);
if (rv == CWMP_OK)
{
cwmp_log_debug("session data sended OK, rv=%d", rv);
session->status = CWMP_ST_RECV;
}
else
{
cwmp_log_debug("session data sended faild! rv=%d", rv);
session->status = CWMP_ST_EXIT;
/*
if (rv == CWMP_COULDNOT_CONNECT)
{
session->status = CWMP_ST_RETRY;
}
else
{
session->status = CWMP_ST_EXIT;
}
*/
}
break;
case CWMP_ST_RECV:
cwmp_log_debug("session stutus: RECV");
cwmp_chunk_clear(session->readers);
rv = cwmp_agent_recv_response(session);
if (rv == CWMP_OK)
{
session->status = CWMP_ST_ANSLYSE;
}
else
{
session->status = CWMP_ST_END;
}
break;
case CWMP_ST_ANSLYSE:
cwmp_log_debug("session stutus: ANSLYSE");
rv = cwmp_agent_analyse_session(session);
if (rv == CWMP_OK)
{
session->status = CWMP_ST_SEND;
}
else
{
session->status = CWMP_ST_END;
}
break;
case CWMP_ST_RETRY:
cwmp_log_debug("session stutus: RETRY");
if (cwmp_agent_retry_session(session) == CWMP_TIMEOUT)
{
cwmp_log_debug("session retry timeover, go out");
session->status = CWMP_ST_EXIT;
}
else
{
session->status = CWMP_ST_START;
}
break;
case CWMP_ST_END:
//close connection of ACS
cwmp_log_debug("session stutus: END");
//run task from queue
if (session->newdata == CWMP_YES)
{
session->status = CWMP_ST_SEND;
}
else
{
session->status = CWMP_ST_EXIT;
}
break;
case CWMP_ST_EXIT:
cwmp_log_debug("session stutus: EXIT");
cwmp_session_close(session);
if (session->reconnect == CWMP_YES)
{
session->reconnect = CWMP_NO;
session->status = CWMP_ST_START;
break;
}
session_close = CWMP_YES;
break;
default:
cwmp_log_debug("Unknown session stutus");
break;
}//end switch
}//end while(!session_close)
cwmp_log_debug("session stutus: EXIT");
cwmp_session_free(session);
session = NULL;
cwmp->session_running = SESSION_NO_RUNNING;
int newtaskres = cwmp_agent_run_tasks(cwmp);
if(newtaskres == CWMP_YES)
{
cwmp->new_request = CWMP_YES;
}
cwmp_reset_periodic_inform(cwmp);
}//end while(TRUE)
}
int cwmp_agent_analyse_session(cwmp_session_t * session)
{
pool_t * doctmppool = NULL;
char * xmlbuf;
cwmp_uint32_t len;
xmldoc_t * doc;
char * method;
xmldoc_t * newdoc = NULL;
int rc = CWMP_OK;
static char * xml_fault = "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:cwmp=\"urn:dslforum-org:cwmp-1-0\" xmlns=\"urn:dslforum-org:cwmp-1-0\"><SOAP-ENV:Body SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" id=\"_0\"><SOAP-ENV:Fault>Error Message</SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>";
cwmp_uint32_t msglength = 0;
FUNCTION_TRACE();
if(NULL == session)
{
cwmp_log_error("session is null");
return CWMP_ERROR;
}
cwmp_t * cwmp = session->cwmp;
if(NULL == cwmp)
{
cwmp_log_error("cwmp is null");
return CWMP_ERROR;
}
msglength = cwmp_chunk_length(session->readers);
if (msglength<= 0)
{
session->newdata = CWMP_NO;
cwmp_log_debug("analyse receive length is 0");
goto eventcheck;
// return CWMP_ERROR;
}
doctmppool = pool_create(POOL_DEFAULT_SIZE);
if(NULL == doctmppool)
{
cwmp_log_error("doctmppool is null");
return CWMP_ERROR;
}
xmlbuf = pool_palloc(doctmppool, msglength+32);
if(NULL == xmlbuf)
{
cwmp_log_error("xmlbuf is null");
return CWMP_ERROR;
}
len = sprintf(xmlbuf,"<cwmp>");
cwmp_chunk_copy(xmlbuf + len, session->readers, msglength);
strncpy(xmlbuf+len+msglength, "</cwmp>", 32-len-1);
cwmp_log_debug("agent analyse xml: \n%s", xmlbuf);
doc = XmlParseBuffer(doctmppool, xmlbuf);
if (!doc)
{
cwmp_log_debug("analyse create doc null\n");
cwmp_chunk_write_string(session->writers, xml_fault, TRstrlen(xml_fault), session->envpool);
goto finished;
}
method = cwmp_get_rpc_method_name(doc);
cwmp_log_debug("analyse method is: %s\n", method);
cwmp_chunk_clear(session->writers);
pool_clear(session->envpool);
cwmp_log_info("----------------------------");
if (TRstrcmp(method, CWMP_RPC_GETRPCMETHODS) == 0)
{
newdoc = cwmp_session_create_getrpcmethods_response_message(session, doc, doctmppool);
}
else if (TRstrcmp(method, CWMP_RPC_INFORMRESPONSE) == 0)
{
newdoc = NULL;
}
else if (TRstrcmp(method, CWMP_RPC_GETPARAMETERNAMES) == 0)
{
newdoc = cwmp_session_create_getparameternames_response_message(session, doc, doctmppool);
}
else if (TRstrcmp(method, CWMP_RPC_GETPARAMETERVALUES) == 0)
{
newdoc = cwmp_session_create_getparametervalues_response_message(session, doc, doctmppool);
}
else if (TRstrcmp(method, CWMP_RPC_SETPARAMETERVALUES) == 0)
{
newdoc = cwmp_session_create_setparametervalues_response_message(session, doc, doctmppool);
}
else if (TRstrcmp(method, CWMP_RPC_DOWNLOAD) == 0)
{
newdoc = cwmp_session_create_download_response_message(session, doc, doctmppool);
}
else if (TRstrcmp(method, CWMP_RPC_UPLOAD) == 0)
{
newdoc = cwmp_session_create_upload_response_message(session, doc, doctmppool);
}
else if (TRstrcmp(method, CWMP_RPC_TRANSFERCOMPLETERESPONSE) == 0)
{
newdoc = NULL;
}
else if (TRstrcmp(method, CWMP_RPC_REBOOT) == 0)
{
newdoc = cwmp_session_create_reboot_response_message(session, doc, doctmppool);
}
else if (TRstrcmp(method, CWMP_RPC_ADDOBJECT) == 0)
{
newdoc = cwmp_session_create_addobject_response_message(session, doc, doctmppool);
}
else if (TRstrcmp(method, CWMP_RPC_DELETEOBJECT) == 0)
{
newdoc = cwmp_session_create_deleteobject_response_message(session, doc, doctmppool);
}
else if (TRstrcmp(method, CWMP_RPC_FACTORYRESET) == 0)
{
newdoc = cwmp_session_create_factoryreset_response_message(session, doc, doctmppool);
}
else if (TRstrcmp(method, CWMP_RPC_GETPARAMETERATTRIBUTES) == 0)
{
newdoc = cwmp_session_create_getparamterattributes_response_message(session, doc, doctmppool);
}
else if (TRstrcmp(method, CWMP_RPC_SETPARAMETERATTRIBUTES) == 0)
{
newdoc = cwmp_session_create_setparamterattributes_response_message(session, doc, doctmppool);
}
else if (TRstrcmp(method, CWMP_RPC_SCHEDULEINFORM) == 0)
{
schedule_inform_info_st si;
si.cwmp = session->cwmp;
newdoc = cwmp_session_create_scheduleinform_response_message(session, doc, doctmppool, &si);
int rc = schedule_inform_create_timer(&si);
}
else
{
//check event queue
//newdoc = cwmp_session_create_event_response_message(session, doc, doctmppool);
cwmp_log_info("unknown method type:%s", method);
}
cwmp_log_info("----------------------------");
// cwmp_t * cwmp = session->cwmp;
if(newdoc == NULL)
{
cwmp_log_debug("agent analyse newdoc is null. ");
eventcheck:
{
cwmp_log_debug("agent analyse begin check global event, %d", cwmp->event_global.event_flag);
//check global event for transfercomplete
if(cwmp->event_global.event_flag & EVENT_REBOOT_TRANSFERCOMPLETE_FLAG)
{
cwmp->event_global.event_flag &= ~EVENT_REBOOT_TRANSFERCOMPLETE_FLAG;
if(!doctmppool)
{
doctmppool = pool_create(POOL_DEFAULT_SIZE);
}
if(!doctmppool)
{
cwmp_log_error("doctmppool pool create return null");
return CWMP_ERROR;
}
event_code_t ec;
ec.event = INFORM_TRANSFERCOMPLETE;
TRstrncpy(ec.command_key, cwmp->event_global.event_key, COMMAND_KEY_LEN);
ec.fault_code = cwmp->event_global.fault_code;
ec.start = cwmp->event_global.start;
ec.end = cwmp->event_global.end;
newdoc = cwmp_session_create_transfercomplete_message(session, &ec, doctmppool);
}
}
}
cwmp_log_debug("newdoc %p, msglength: %d", newdoc, msglength );
if(newdoc != NULL) // || (newdoc == NULL && msglength == 0 && session->retry_count < 2))
{
session->newdata = CWMP_YES;
cwmp_write_doc_to_chunk(newdoc, session->writers, session->envpool);
rc = CWMP_OK;
}
else if(/*newdoc == NULL && */msglength != 0)
{
session->newdata = CWMP_YES;
cwmp_write_doc_to_chunk(newdoc, session->writers, session->envpool);
rc = CWMP_OK;
}
else
{
rc = CWMP_ERROR;
}
finished:
if(doctmppool != NULL)
{
pool_destroy(doctmppool);
}
return rc;
}
static void print_param(parameter_node_t * param, int level)
{
if(!param) return;
parameter_node_t * child;
char fmt[128];
//cwmp_log_debug("name: %s, type: %s, level: %d\n", param->name, cwmp_get_type_string(param->type), level);
int i=0;
snprintf(fmt, 127, "|%%-%ds%%s, get:%%p set:%%p refresh:%%p\n", level*4);
cwmp_log_debug_src(fmt, "----", param->name, param->get, param->set, param->refresh);
child = param->child;
if(!child)
return;
print_param(child, level+1);
parameter_node_t * next = child->next_sibling;
while(next)
{
print_param(next, level+1);
next = next->next_sibling;
}
}
void cwmp_agent_session(cwmp_t * cwmp)
{
char name[1024] = {0};
char value[1024]= {0};
char local_ip[256];
char * envstr;
char * encstr;
envstr = "SOAP-ENV"; //cwmp_conf_get("cwmp:soap_env");
encstr = "SOAP-ENC"; // cwmp_conf_get("cwmp:soap_enc");
cwmp_set_envelope_ns(envstr, encstr);
#if 0
if (cwmp_session_get_localip(local_ip) == -1)
{
cwmp_log_error("get local ip error. exited.\n");
exit(-1);
}
#else
cwmp_session_get_localip(local_ip);
#endif
print_param(cwmp->root, 0);
CWMP_SPRINTF_PARAMETER_NAME(name, 3, InternetGatewayDeviceModule, ManagementServerModule, URLModule);
cwmp_data_set_parameter_value(cwmp, cwmp->root, name, cwmp->acs_url, TRstrlen(cwmp->acs_url), cwmp->pool);
CWMP_SPRINTF_PARAMETER_NAME(name, 3, InternetGatewayDeviceModule, ManagementServerModule, ConnectionRequestURLModule);
TRsnprintf(value, 1024, "http://%s:%d", local_ip, cwmp->httpd_port);
cwmp_data_set_parameter_value(cwmp, cwmp->root, name, value, TRstrlen(value), cwmp->pool);
cwmp_log_debug("set request name:%s, value:%s", name, value);
CWMP_SPRINTF_PARAMETER_NAME(name, 3, InternetGatewayDeviceModule, DeviceInfoModule, ManufacturerModule);
cwmp_data_set_parameter_value(cwmp, cwmp->root, name, cwmp->cpe_mf, TRstrlen(cwmp->cpe_mf), cwmp->pool);
CWMP_SPRINTF_PARAMETER_NAME(name, 3, InternetGatewayDeviceModule, DeviceInfoModule, ManufacturerOUIModule);
cwmp_data_set_parameter_value(cwmp, cwmp->root, name, cwmp->cpe_oui, TRstrlen(cwmp->cpe_oui), cwmp->pool);
CWMP_SPRINTF_PARAMETER_NAME(name, 3, InternetGatewayDeviceModule, DeviceInfoModule, ProductClassModule);
cwmp_data_set_parameter_value(cwmp, cwmp->root, name, cwmp->cpe_pc, TRstrlen(cwmp->cpe_pc), cwmp->pool);
CWMP_SPRINTF_PARAMETER_NAME(name, 3, InternetGatewayDeviceModule, DeviceInfoModule, SerialNumberModule);
cwmp_data_set_parameter_value(cwmp, cwmp->root, name, cwmp->cpe_sn, TRstrlen(cwmp->cpe_sn), cwmp->pool);
cwmp_agent_start_session(cwmp);
}
/*
int cwmp_agent_download_file(download_arg_t * dlarg)
{
int faultcode = 0;
char url[255];
if (TRstrncasecmp(dlarg->url, "ftp://", 6) == 0)
{
if (dlarg->username != NULL && strlen(dlarg->username) != 0)
{
TRsnprintf(url, 255, "ftp://%s:%s@%s", dlarg->username, dlarg->password, dlarg->url+6);
}
else
{
TRstrncpy(url, dlarg->url, 255);
}
}
else
{
TRstrncpy(url, dlarg->url, 255);
}
fetchIO * downfile = fetchGetURL(url, "");
if (!downfile)
{
cwmp_log_debug("download file fail: %s", url);
faultcode = 9001;
}
else
{
char readbuf[1024];
int readlen;
char targetfile[64];
if (dlarg->targetname != NULL && strlen(dlarg->targetname) != 0)
{
TRsnprintf(targetfile, 64, "/tmp/%s", dlarg->targetname);
}
else
{
TRsnprintf(targetfile, 64, "/tmp/%d.file", time(NULL));
}
FILE * df = fopen(targetfile, "wb+");
while (df != NULL)
{
readlen = fetchIO_read(downfile, readbuf, 1023);
if (readlen <= 0)
{
cwmp_log_debug("fetch io read zero. %s", readlen);
break;
}
readbuf[readlen] = 0;
fwrite(readbuf, readlen, 1, df);
}
if (df)
{
fclose(df);
}
else
{
faultcode = 9001;
}
cwmp_log_debug("download file ok: %s, %s", url, targetfile);
fetchIO_close(downfile);
}
return faultcode;
}
int cwmp_agent_upload_file(upload_arg_t * ularg)
{
int faultcode = 0;
char url[255];
if (TRstrncasecmp(ularg->url, "ftp://", 6) == 0)
{
if (ularg->username != NULL && strlen(ularg->username) != 0)
{
TRsnprintf(url, 255, "ftp://%s:%s@%s", ularg->username, ularg->password, ularg->url+6);
}
else
{
TRstrncpy(url, ularg->url, 255);
}
}
else
{
TRstrncpy(url, ularg->url, 255);
}
fetchIO * uploadfile = fetchPutURL(url, "");
if (!uploadfile)
{
cwmp_log_debug("upload file fail: %s", url);
faultcode = 9001;
}
else
{
char readbuf[1024];
int readlen;
char targetfile[64];
FILE * uf;
int rc;
if(strcmp(ularg->filetype, "1 Vendor Configuration File") == 0)
{
//¸ù¾Ýʵ¼ÊÇé¿ö, ÐÞ¸ÄÕâÀïµÄÅäÖÃÎļþ·¾¶
uf = fopen("/tmp/mysystem.cfg", "rb");
}
else if(strcmp(ularg->filetype, "2 Vendor Log File") == 0)
{
//¸ù¾Ýʵ¼ÊÇé¿ö, ÐÞ¸ÄÕâÀïµÄÅäÖÃÎļþ·¾¶
uf = fopen("/tmp/mysystem.log", "rb");
}
else
{
uf = fopen("/tmp/mysystem.log", "rb");
}
while (uf != NULL)
{
readlen = fread(readbuf, 1024, 1, uf);
if (readlen <= 0)
{
cwmp_log_debug("fetch io read zero. %s", readlen);
break;
}
readbuf[readlen] = 0;
rc = fetchIO_write(uploadfile, readbuf, readlen);
if(rc <= 0)
{
faultcode = 9001;
break;
}
}
if(uf)
{
fclose(uf);
}
else
{
faultcode = 9001;
}
cwmp_log_debug("upload file finished: %s, file:%s", url, targetfile);
fetchIO_close(uploadfile);
}
return faultcode;
}
*/
int cwmp_agent_download_file(download_arg_t * dlarg)
{
int faultcode = 0;
char * fromurl = dlarg->url;
char tofile[256+1] = {0};
char downloadroot[256+1] = {0};
FUNCTION_TRACE();
if(!fromurl)
{
cwmp_log_error("download src file path is null!");
return 9001;
}
if(NULL == dlarg->targetname)
{
if(TRstrcmp(dlarg->filetype, "1 Firmware Upgrade Image") == 0)
{
cwmp_conf_get("file:download_img_path", tofile);
}
else if(TRstrcmp(dlarg->filetype, "3 Vendor Configuration File") == 0)
{
cwmp_conf_get("file:download_cfg_path", tofile);
}
else
{
cwmp_conf_get("file:download_unknown_path", tofile);
}
}
else
{
cwmp_conf_get("file:download_root", downloadroot);
TRsnprintf(tofile, 256, "%s/%s", downloadroot, dlarg->targetname);
}
cwmp_log_info("file type:%s, save file(%s) to path:%s", dlarg->filetype, fromurl, tofile);
if(/*dlarg->url &&*/ TRstrncasecmp("ftp://", dlarg->url, 6) == 0)
{
cwmp_log_debug("Download url:%s", dlarg->url);
return 9001;
}
faultcode = http_receive_file(fromurl, tofile);
if(faultcode != CWMP_OK)
{
cwmp_log_debug("faultcode:%d", faultcode);
faultcode = 9001;
}
return faultcode;
}
int cwmp_agent_upload_file(upload_arg_t * ularg)
{
int faultcode = 0;
FUNCTION_TRACE();
char * fromfile;
char cfg_path[256] = {0};
char log_path[256] = {0};
FUNCTION_TRACE();
cwmp_conf_get("file:upload_cfg_path", cfg_path);
cwmp_conf_get("file:upload_log_path", log_path);
if(TRstrcmp(ularg->filetype, "1 Vendor Configuration File") == 0)
{
fromfile = cfg_path;
}
else if(TRstrcmp(ularg->filetype, "2 Vendor Log File") == 0)
{
fromfile = log_path;
}
else
{
fromfile = cfg_path;
}
cwmp_log_info("upload type:%s, send file:%s, url:%s", ularg->filetype, fromfile, ularg->url);
faultcode = http_send_file(fromfile, ularg->url);
if(faultcode != CWMP_OK)
{
cwmp_log_error("http send file return[%d], not CWMP_OK, set faultcode 9001", faultcode);
faultcode = 9001;
}
return faultcode;
}
int cwmp_agent_run_tasks(cwmp_t * cwmp)
{
void * data;
int tasktype = 0;;
int ok = CWMP_NO;
int rc = 0;
FUNCTION_TRACE();
while(1)
{
tasktype = queue_pop(cwmp->queue, &data);
if(tasktype == -1)
{
cwmp_log_debug("no more task to run");
break;
}
ok = CWMP_YES;
switch(tasktype)
{
case TASK_DOWNLOAD_TAG:
{
cwmp_log_debug("Download begin.....");
download_arg_t * dlarg = (download_arg_t*)data;
//begin download file
time_t starttime = time(NULL);
int faultcode = 0;
faultcode = cwmp_agent_download_file(dlarg);
time_t endtime = time(NULL);
cwmp_event_set_value(cwmp, INFORM_TRANSFERCOMPLETE, 1,dlarg->cmdkey, faultcode, starttime, endtime);
FREE(dlarg);
cwmp_log_debug("Download OK.....");
}
break;
case TASK_UPLOAD_TAG:
{
cwmp_log_debug("Upload begin.....");
upload_arg_t * ularg = (upload_arg_t*)data;
//begin download file
time_t starttime = time(NULL);
int faultcode = 0;
faultcode = cwmp_agent_upload_file(ularg);
time_t endtime = time(NULL);
cwmp_event_set_value(cwmp, INFORM_TRANSFERCOMPLETE, 1,ularg->cmdkey, faultcode, starttime, endtime);
FREE(ularg);
cwmp_log_debug("Upload OK.....");
}
break;
case TASK_REBOOT_TAG:
{
//begin reboot system
cwmp_log_debug("reboot ...");
cwmp_event_set_value(cwmp, INFORM_MREBOOT, 1, NULL, 0, 0, 0);
cwmp_event_clear_active(cwmp);
// inorder to save file ok
sleep(20);
rc = restart_request(MODULE_ID_TR069);
if(0 != rc)
{
cwmp_log_info("restart request fail! rc:%d", rc);
}
}
break;
case TASK_FACTORYRESET_TAG:
{
//begin factory reset system
cwmp_log_debug("factory reset begin...");
cwmp_event_clear_active(cwmp);
rc = reset_request(MODULE_ID_TR069);
if(0 != rc)
{
cwmp_log_info("reset request fail! rc:%d", rc);
}
cwmp_log_debug("factory reset OK.....");
}
break;
default:
break;
}
}
return ok;
}