/**
* @fn nbServerSockInit
* @brief 网络交互升级进度线程socket创建初始化
* @param[in]
* @param[out]
* @return
*/
int nbServerSockInit(unsigned short cmdPort)
{
int listenfd = -1;
int ret = -1;
int flag = 1;
struct sockaddr_in serveraddr;
unsigned short nbServPort = cmdPort;
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
/*create socket if failure exit*/
perror("create socket error!");
return -1;
}
/*init serveraddr*/
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(nbServPort);
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (void*)&flag, sizeof(flag));
/*bind port and serveraddr to listenfd*/
while(1)
{
ret = bind(listenfd,(struct sockaddr *)&serveraddr,sizeof(struct sockaddr));
if(0 == ret)
{
break;
}
perror("bind error!");
sleep(1);
}
if (listen(listenfd, NB_SERVER_BACKLOG) < 0)
{
perror("listen error");
if(listenfd)
{
close(listenfd);
listenfd = -1;
}
return -1;
}
return listenfd;
}
/**
* @fn spellHttpReplyStr
* @brief 拼接socket层http升级进度json回复包
* @param[in]
* @param[out]
* @return
*/
int spellHttpReplyStr(char * httpReplyStr,int state,int percent)
{
char DataBuf[128];
char DateLen[32];
memset(DataBuf,0,sizeof(DataBuf));
memset(DateLen,0,sizeof(DateLen));
sprintf(DataBuf,"{\"stage\":\"%s\",\"percent\":%d}","testStage",percent);
sprintf(DateLen,"%d",strlen(DataBuf));
strcat(httpReplyStr, "HTTP/1.1 200 OK\r\n");
strcat(httpReplyStr, "Access-Control-Allow-Origin:*\r\n");
strcat(httpReplyStr, "Content-Type:application/json;charset=utf-8\r\n");
strcat(httpReplyStr, "Connection: close\r\n");
strcat(httpReplyStr, "Content-Length:");
strcat(httpReplyStr, DateLen);
strcat(httpReplyStr, "\r\n\r\n");
strcat(httpReplyStr, DataBuf);
//DEBUG("--------------------------------\n%s\n--------------------------------\n",httpReplyStr);
return 0;
}
/**
* @fn httpNetRefreshRoutine
* @brief http json格式交互升级进度线程
* @param[in]
* @param[out]
* @return
*/
#define WEBUI_MSGBUF (2048)
#define HTTP_HEAD_END "\r\n\r\n"
#define CONTENT_LENGTH_STR "Content-Length:"
void *httpNetRefreshRoutine(void *data)
{
int serverSock = -1; // bscp socket
int clientSock = -1; // peer socket
int ret = 0;
int oldpercent= 0;
unsigned int clientaddrlen = 0;
struct sockaddr_in clientaddr = {0};
SmBurnStateOutPara burnState = {0};
char httpReplyStr[WEBUI_MSGBUF] = {0};
char recvMsgBuf[WEBUI_MSGBUF] = {0};
struct timeval timeout;
char * ptmp = NULL;
int ContentLength = 0;
int n = 0;
DEBUG("%s:%d started\n", __func__, __LINE__);
serverSock = nbServerSockInit(g_cmdjsonPort);
if(serverSock < 0 )
{
DEBUG("create serversock failed\n");
ret=__LINE__;
goto EXIT0;
}
while (1)
{
memset(&clientaddr, 0, sizeof(clientaddr));
clientaddrlen = sizeof(clientaddr);
clientSock = accept(serverSock, (struct sockaddr*)&clientaddr, &clientaddrlen);
if(clientSock <0)
{
perror("accept()");
DEBUG("error accept.\n");
sleep(1);
continue;
}
timeout.tv_sec = 5;
timeout.tv_usec = 0;
if( setsockopt (clientSock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0 )
{
close(clientSock);
clientSock = -1;
perror("setsockopt<SO_RCVTIMEO>:");
sleep(1);
continue;
}
if( setsockopt (clientSock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0 )
{
close(clientSock);
clientSock = -1;
perror("setsockopt<SO_SNDTIMEO>:");
sleep(1);
continue;
}
memset(recvMsgBuf, 0, sizeof(recvMsgBuf));
n = read(clientSock, recvMsgBuf, WEBUI_MSGBUF);
if (n <= 0)
{
/** receive data error. need to close this connection */
close(clientSock);
perror("recv error!");
continue;
}
//DEBUG("recvMsgBuf = %s\n", recvMsgBuf);
ptmp = recvMsgBuf;
if(strncmp(ptmp, "GET", strlen("GET")) != 0)
{
close(clientSock);
clientSock = -1;
perror("strncmp GET error!");
usleep(50000);
continue;
}
for(ptmp = recvMsgBuf; ptmp < (recvMsgBuf + n); ptmp++)
{
if('\r' != *ptmp)
{
continue;
}
if(strncmp(ptmp, CONTENT_LENGTH_STR, strlen(CONTENT_LENGTH_STR)) == 0)
{
ContentLength = atoi(ptmp + strlen(CONTENT_LENGTH_STR));
}
if(strncmp(ptmp, HTTP_HEAD_END, strlen(HTTP_HEAD_END)) == 0)
{
break;
}
}
if(strlen(ptmp +strlen(HTTP_HEAD_END)) != ContentLength)
{
ret = read(clientSock, recvMsgBuf + n, WEBUI_MSGBUF - n);
if(ret < 0)
{
close(clientSock);
clientSock = -1;
perror("read tmpbuf error!");
usleep(50000);
continue;
}
}
#if 0
if(NULL == strstr(recvMsgBuf, "System.burnState"))
{
/** 接收数据不是 System.burnState 协议,关闭这个连接 */
close(clientSock);
clientSock = -1;
perror("strstr error!");
sleep(1);
continue;
}
#endif
burnState.stage = UPGRADE_WRITE;
burnState.percent = (g_percentage > 100 ? 100 : g_percentage);
if (oldpercent != burnState.percent)
{
DEBUG("percent %d\n", burnState.percent);
}
memset(httpReplyStr,0,sizeof(httpReplyStr));
spellHttpReplyStr(httpReplyStr, burnState.stage, burnState.percent);
ret = writen(clientSock,httpReplyStr,strlen(httpReplyStr));
if(ret < 0)
{
DEBUG("http reply fail:errno:%d\n",errno);
}else{
DEBUG("http reply ok:%d byte!\n", ret);
}
close(clientSock);
clientSock = -1;
}
EXIT0:
DEBUG("error occured. errcode=%d\n",ret);
return NULL;
}