AP05/net_utils/http_utils.c

1073 lines
30 KiB
C
Raw Normal View History

2025-04-06 06:41:47 +00:00
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netdb.h>
#include <regex.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <pthread.h>
#include "md5.h"
#include "main.h"
#include "http_utils.h"
#include "read_utils.h"
#include "json_utils.h"
#include "Base64.h"
#define PRINT_TIME_TAG
#define DBG_TAG "http_utils"
#define DBG_LVL DBG_INFO
#include "debug_print.h"
typedef struct
{
int status_code; //HTTP/1.1 '200' OK
char content_type[128]; //Content-Type: application/gzip
long content_length; //Content-Length: 11683079
}http_response_t;
int http_parse_url(const char url[1024], char domain[1024], int *port, char file_name[256])
{
char *patterns[] = {"http://", "https://", NULL};
int j = 0, i = 0;
int start = 0;
int ret = 0;
if ((url == NULL)||(domain == NULL)||(port == NULL)||(file_name == NULL)) {
LOG_I("param: NULL\n");
ret = -1;
goto error;
}
for (i = 0; patterns[i]; i++) {
if (strncmp(url, patterns[i], strlen(patterns[i])) == 0) {
start = strlen(patterns[i]);
}
}
//解析域名, 这里处理时域名后面的端口号会保留
for (i = start, j = 0; url[i] != '/' && url[i] != '\0'; i++, j++) {
domain[j] = url[i];
if((i >= (1024 - 1)) || (j >= (1024 - 1))) {
ret = -2;
goto error;
}
}
domain[j] = '\0';
//解析端口号, 如果没有, 那么设置端口为80
char *pos = strstr(domain, ":");
if (pos) {
sscanf(pos, ":%d", port);
} else {
*port = 80;
}
//删除域名端口号
for (i = 0; i < strlen(domain); i++) {
if (domain[i] == ':') {
domain[i] = '\0';
break;
}
}
//获取下载文件名
for (i = start, j = 0; url[i] != '\0'; i++) {
if (url[i] == '/') {
if (i != strlen(url) - 1) {
j = 0;
}
continue;
} else {
file_name[j++] = url[i];
if(j >= (256 - 1)) {
ret = -3;
goto error;
}
}
}
file_name[j] = '\0';
error:
return ret;
}
int is_ip_legal(const char *ip)
{
char str_ip[30] = "";
regex_t reg;
const char *pattern = "[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}";
int cflags = REG_EXTENDED;
const size_t nmatch = 1;
regmatch_t pmatch[1];
int ret = 0;
if (ip == NULL) {
LOG_I("param: NULL\n");
ret = -1;
goto error;
}
strcpy(str_ip, ip);
regcomp(&reg, pattern, cflags);
ret = regexec(&reg, str_ip, nmatch, pmatch, 0);
if(ret == REG_NOMATCH)
{
LOG_I("IP not match\n");
ret = -2;
goto error;
} else if(ret == REG_NOERROR) {
ret = 0;
}
regfree(&reg);
error:
return ret;
}
int get_ip_by_domain(char *domain, char dest[16], int dest_len)
{
struct hostent *host;
int ret = 0;
if ((domain == NULL)||(dest == NULL)) {
LOG_I("param: NULL\n");
ret = -1;
goto error;
}
host = gethostbyname(domain);
if (host == NULL) {
LOG_I("gethostbyname error\n");
ret = -2;
goto error;
} else {
if (dest_len >= 16 && dest != NULL) {
char **phe = NULL;
for ( phe=host->h_addr_list ; NULL != *phe ; ++phe) {
inet_ntop(host->h_addrtype, *phe, dest, dest_len);
}
}
}
error:
return ret;
}
int socket_client_connect(int socketfd, char ip[INET_ADDRSTRLEN], int port)
{
struct sockaddr_in addr;
int flag = 1;
fd_set fds;
struct timeval tv;
int ret = 0;
int len = sizeof(ret);
if (ip == NULL) {
LOG_I("param: NULL\n");
ret = -1;
goto error;
}
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
inet_pton(AF_INET, ip, &addr.sin_addr);
//当socket进行TCP连接的时候也就是调用connect时一旦网络不通或者是ip地址无效就可能使整个线程阻塞
//设置为非阻塞模式
ioctl(socketfd, FIONBIO, &flag);
ret = connect(socketfd, (struct sockaddr*)&addr, sizeof(addr));
if (ret < 0) {
tv.tv_sec = 1;
tv.tv_usec = 500*1000;
FD_ZERO(&fds);
FD_SET(socketfd, &fds);
ret = select(FD_SETSIZE, NULL, &fds, NULL, &tv);
if(ret < 0){
LOG_I("seclect error\n");
ret = -2;
goto error;
}else if(ret > 0){
if(FD_ISSET(socketfd, &fds)){
getsockopt(socketfd, SOL_SOCKET, SO_ERROR, &ret, (socklen_t *)&len);
if(ret != 0){
ret = -3;
goto error;
}
}
}else{//time out
ret = -4;
goto error;
}
}
flag = 0;
ioctl(socketfd, FIONBIO, &flag); //设置为阻塞模式
ret = socketfd;
error:
return ret;
}
int socket_client_open(void)
{
int socketfd;
socketfd = socket(AF_INET, SOCK_STREAM, 0);
if(socketfd < 0){
LOG_I("socket error\n");
}
return socketfd;
}
int socket_client_open_connect(char ip[INET_ADDRSTRLEN], int port)
{
int socketfd;
int ret = 0;
socketfd = socket_client_open();
ret = socket_client_connect(socketfd, ip, port);
if(ret < 0){
LOG_I("socket_client_connect error: %d\n", ret);
close(socketfd);
socketfd = -1;
}
return socketfd;
}
int get_http_response(const char *response, http_response_t *resp)
{
int ret = 0;
if ((response == NULL)||(resp == NULL)) {
LOG_I("param: NULL\n");
ret = -1;
goto error;
}
//LOG_I("response:%s\n",response);
char *pos = strstr(response, "HTTP/");
if (pos) {
sscanf(pos, "%*s %d", &resp->status_code); //返回状态码
} else {
ret = -2;
goto error;
}
pos = strstr(response, "Content-Type:"); //返回内容类型
if (pos) {
sscanf(pos, "%*s %s", resp->content_type);
} else {
ret = -3;
goto error;
}
pos = strstr(response, "Content-Length:"); //内容的长度(字节)
if (pos) {
sscanf(pos, "%*s %ld", &resp->content_length);
} else {
ret = -4;
goto error;
}
error:
return ret;
}
int http_response_debug(http_response_t *resp)
{
int ret = 0;
if (resp == NULL) {
LOG_I("param: NULL\n");
ret = -1;
goto error;
}
LOG_I("status_code = %d\n", resp->status_code);
LOG_I("content_type = %s\n", resp->content_type);
LOG_I("content_length = %ld\n", resp->content_length);
error:
return ret;
}
void progress_bar(long cur_size, long total_size)
{
/*用于显示下载进度条*/
float percent = cur_size*1.0 / total_size;
const int numTotal = 50;
int numShow = (int)(numTotal * percent);
if (numShow == 0)
numShow = 1;
if (numShow > numTotal)
numShow = numTotal;
char sign[51] = {0};
memset(sign, '=', numTotal);
LOG_I("\r%.2f%%\t[%-*.*s] %ld/%ld", percent * 100, numTotal, numShow, sign, cur_size, total_size);
fflush(stdout);
if (numShow == numTotal)
LOG_I("\n");
}
#if 0
int http_download(int client_socket, char path[256], char file_name[256], http_response_t *http_response)
{
int length = 0;
int written_len = 0;
char receive[2048] = "";
char path_name[512] = {0};
int ret = 0;
if ((path == NULL)||(file_name == NULL)) {
LOG_I("param: NULL\n");
ret = -3;
goto error;
}
//创建文件描述符
snprintf(path_name, sizeof(path_name), "%s/%s", path, file_name);
int fd = open(path_name, O_CREAT | O_WRONLY | O_TRUNC, S_IRWXG | S_IRWXO | S_IRWXU);
if (fd < 0) {
LOG_I("Create file failed\n");
ret = -1;
goto error;
}
//从套接字中读取文件流
while(1) {
length = read_data_until_time(client_socket, receive, sizeof(receive), 3000, 50);
if(length < 0){
LOG_I("read_data_until_str error\n");
ret = -2;
goto error;
}else if(length == 0){
LOG_I("read_data_until_str end\n");
break;
}
write(fd, receive, length);
written_len += length;
progress_bar(written_len, http_response->content_length);
if(written_len >= http_response->content_length) {
break;
}
}
if (written_len == http_response->content_length) {
LOG_I("Download %s successed\n", file_name);
ret = 0;
} else {
LOG_I("Download %s failed\n", file_name);
ret = -3;
}
close(fd);
error:
return ret;
}
int http_get(const char url[1024], const char path[256], char file_dest[512], int file_dest_len)
{
char domain[1024] = {0};
char server_ip[20] = {0};
int server_port = 80;
char file_name[256] = {0};
char request[2048] = {0};
char response[2048] = {0};
int length = 0;
int ret = 0;
int client_socket;
#if 0
if ((url == NULL)||(path == NULL)) {
LOG_I("param: NULL\n");
ret = -7;
goto error;
}
#endif
http_parse_url(url, domain, &server_port, file_name);
LOG_I("url:%s\n", url);
LOG_I("domain:%s\n", domain);
get_ip_by_domain(domain, server_ip, sizeof(server_ip));
if(is_ip_legal(server_ip)) {
ret = -1;
goto error;
}
LOG_I("server_ip:%s, port:%d\n", server_ip, server_port);
LOG_I("file_name:%s\n", file_name);
//设置http请求头信息
length = snprintf(request, sizeof(request),
"GET %s HTTP/1.1\r\n"
"User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537(KHTML, like Gecko) Chrome/47.0.2526Safari/537.36\r\n"
"Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n"
"Host:%s\r\n"
"Connection:close\r\n"
"\r\n",
url, domain);
client_socket = socket_client_open_connect(server_ip, server_port);
if(client_socket < 0){
close(client_socket);
ret = -2;
goto error;
}
//发送请求消息
write(client_socket, request, strlen(request));
length = read_data_until_str(client_socket, response, sizeof(response), "\r\n\r\n", strlen("\r\n\r\n"), 3000, 50);
if(length < 0){
LOG_I("read_data_until_str error\n");
ret = -3;
goto error;
}else if(length == 0){
LOG_I("read_data_until_str end\n");
ret = -4;
goto error;
}
//print_buffer("\n>>>>response<<<<\n", response, length);
//print_buffer_char("\n>>>>response<<<<\n", response, length);
http_response_t http_response;
get_http_response(response, &http_response);
http_response_debug(&http_response);
#if 0
if(http_response.status_code == 200) {
if (file_dest != NULL) {
memset(file_dest, 0, file_dest_len);
LOG_I("path:[%s]\n", path);
LOG_I("file_name:[%s]\n", file_name);
snprintf(file_dest, file_dest_len, "%s/%s", path, file_name);
}
ret = http_down(client_socket, (char *)path, file_name, &http_response);
if(ret < 0){
LOG_I("http_down error\n");
ret = -5;
goto error;
}
} else {
ret = -6;
goto error;
}
#endif
error:
return ret;
}
#endif
#define UPLOAD_REQUEST "--myfengefu\r\n"\
"Content-Disposition: form-data; name=\"file\"; filename=%s\r\n"\
"Content-Type: application/octet-stream\r\n\r\n"
#define HTTP_HEAD "POST %s HTTP/1.1\r\n"\
"Host: %s\r\n"\
"key: device\r\n"\
"nonce: %s\r\n"\
"timestamp: %s\r\n"\
"sign: %s\r\n"\
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)\r\n"\
"Content-Type: multipart/form-data; boundary=myfengefu\r\n"\
"Content-Length: %ld\r\n"\
"Connection: keep-alive\r\n\r\n"
#define HTTP_HEAD_GETDEVINFO "POST %s HTTP/1.1\r\n"\
"Host: %s\r\n"\
"key: device\r\n"\
"nonce: %s\r\n"\
"timestamp: %s\r\n"\
"sign: %s\r\n"\
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)\r\n"\
"Content-Type: application/json\r\n"\
"Content-Length: %ld\r\n"\
"Connection: keep-alive\r\n\r\n"
#define HTTP_HEAD_GETDEVINFO_J "POST %s HTTP/1.1\r\n"\
"Host: %s\r\n"\
"x-appKey: d577e7b5024ad20446e10\r\n"\
"x-datadigest: %s\r\n"\
"Content-Type: application/json\r\n"\
"Content-Length: %ld\r\n"\
"Connection: keep-alive\r\n\r\n"
#define HTTP_HEAD_GETDEVINFO_T "POST %s HTTP/1.1\r\n"\
"Host: %s\r\n\r\n"
#define HTTP_HEAD_GETDEVREGISTERSTATUS "GET %s HTTP/1.1\r\n"\
"Host: %s\r\n"\
"key: device\r\n"\
"nonce: %s\r\n"\
"timestamp: %s\r\n"\
"sign: %s\r\n"\
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)\r\n"\
"Content-Type: application/json\r\n"\
"Content-Length: %ld\r\n"\
"Connection: keep-alive\r\n\r\n"
unsigned long get_file_size(const char *path)
{
unsigned long filesize = -1;
struct stat statbuff;
if(stat(path, &statbuff) < 0){
return filesize;
}else{
filesize = statbuff.st_size;
}
return filesize;
}
void get_rand_str(char s[],int num)
{
//定义随机生成字符串表
char *str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
int i,lstr;
char ss[2] = {0};
lstr = strlen(str);//计算字符串长度
srand((unsigned int)time((time_t *)NULL));//使用系统时间来初始化随机数发生器
for(i = 1; i <= num; i++){//按指定大小返回相应的字符串
sprintf(ss,"%c",str[(rand()%lstr)]);//rand()%lstr 可随机返回0-71之间的整数, str[0-71]可随机得到其中的字符
strcat(s,ss);//将随机生成的字符串连接到指定数组后面
}
}
int http_post_uploadlog(char *url, char *msg_id,char *logfilename)
{
char domain[1024] = {0};
char server_ip[20] = {0};
int server_port = 80;
char file_name[256] = {0};
char response[2048] = {0};
char fileurl[2048] = {0};
int sendsuccess = 0;
int length = 0;
int ret = 0;
int client_socket;
int readbyte=0;
unsigned char header[1024]={0};
unsigned char send_request[1024]={0};
unsigned char send_end[1024]={0};
unsigned char http_boundary[64]={0};
unsigned char nonce[32]={0};
unsigned char timestamp[64]={0};
unsigned char sign[256]={0};
unsigned char signtmp[256]={0};
get_rand_str(nonce,6);
//LOG_I("nonce:%s\n",nonce);
struct timeval begin;
gettimeofday(&begin,NULL);
long long beginTime = (long long)begin.tv_sec * 1000 + (long long)begin.tv_usec / 1000;
sprintf(timestamp,"%lld",beginTime);
//LOG_I("timestamp:%s\n",timestamp);
snprintf(signtmp, sizeof(sign), "device|%s|%s|wdewdilpvy",nonce,timestamp);
//LOG_I("signtmp:%s\n",signtmp);
get_md5_from_string(sign, sizeof(sign), signtmp, strlen(signtmp));
//LOG_I("sign:%s\n",sign);
#if 0
if ((url == NULL)||(path == NULL)) {
LOG_I("param: NULL\n");
ret = -7;
goto error;
}
#endif
//LOG_I("POST\n");
http_parse_url(url, domain, &server_port, file_name);
//LOG_I("url:%s\n", url);
//LOG_I("domain:%s\n", domain);
get_ip_by_domain(domain, server_ip, sizeof(server_ip));
if(is_ip_legal(server_ip)) {
ret = -1;
goto error;
}
//LOG_I("server_ip:%s, port:%d\n", server_ip, server_port);
//LOG_I("file_name:%s\n", file_name);
unsigned long totalsize = 0;
unsigned long filesize = get_file_size(logfilename); //文件大小
unsigned long request_len = snprintf(send_request,1024,UPLOAD_REQUEST,logfilename); //请求信息
unsigned long end_len = snprintf(send_end,1024,"\r\n--myfengefu--\r\n"); //结束信息
totalsize = filesize + request_len + end_len;
//unsigned long head_len = snprintf(header,1024,HTTP_HEAD,"/open/api/device/log/upload",domain,nonce,timestamp,sign,totalsize); //头信息
unsigned long head_len = snprintf(header,1024,HTTP_HEAD,url,domain,nonce,timestamp,sign,totalsize); //头信息
totalsize += head_len;
//LOG_I("filesize:%d,request_len:%d,end_len:%d,head_len:%d,totalsize:%d\n",filesize,request_len,end_len,head_len,totalsize);
char* request = (char*)malloc(totalsize); //申请内存用于存放要发送的数据
if (request == NULL){
printf("malloc request fail !\r\n");
return -1;
}
request[0] = '\0';
strcat(request,header); //http头信息
strcat(request,send_request); //文件请求信息
FILE* fp = fopen(logfilename, "rb+");//打开要上传的文件
if (fp == NULL){
LOG_I("open file fail!\r\n");
return -1;
}
readbyte = fread(request+head_len+request_len, 1, filesize, fp);//读取上传的文件信息
LOG_I("logfile %s size:%d\n",logfilename,readbyte);
memcpy(request+head_len+request_len+filesize,send_end,end_len); //http结束信息
//LOG_I("request:%s\n",request);
client_socket = socket_client_open_connect(server_ip, server_port);
if(client_socket < 0){
close(client_socket);
ret = -2;
goto error;
}
if(write(client_socket, request, totalsize)==-1){
LOG_I("write fail\r\n");
}
if((readbyte = read(client_socket,response,2048))==-1){
LOG_I("read http ACK fail !\r\n");
return -1;
}
//LOG_I("ACK readbyte:%d\n",readbyte);
response[readbyte]='\0';
//LOG_I("response:%s\n",response);
int index = 0,start_flag = 0;
int ack_json_len = 0;
char ack_json[256]={0};
for(index = 0; index<readbyte; index++){
if(response[index] == '{'){
start_flag = 1;
}
if(start_flag)
ack_json[ack_json_len++] = response[index]; //遇到左大括号则开始拷贝
}
//LOG_I("Receive:%s\n",ack_json);
if(ack_json_len > 0){
get_string_from_json_string_by_key_unescape(ack_json, "data", fileurl, sizeof(fileurl));
//LOG_I("data:%s\n",fileurl);
get_int_from_json_string_by_key(ack_json, "code", &sendsuccess);
//LOG_I("code:%d\n",sendsuccess);
}else{
ack_json[0] = '\0';
LOG_I("Receive http ACK fail!!\n");
//LOG_I("--- ack_json_len = %d\n",ack_json_len);
}
error:
return ret;
}
int http_get_getdevregisterstatus(char *url)
{
char domain[1024] = {0};
char server_ip[20] = {0};
int server_port = 80;
char file_name[256] = {0};
char response[3072] = {0};
int sendsuccess = 0;
int length = 0;
int ret = 0;
int client_socket;
int readbyte=0;
unsigned char header[1024]={0};
unsigned char send_request[1024]={0};
unsigned char send_end[1024]={0};
unsigned char http_boundary[64]={0};
unsigned char nonce[32]={0};
unsigned char timestamp[64]={0};
unsigned char sign[256]={0};
unsigned char signtmp[256]={0};
get_rand_str(nonce,6);
//LOG_I("nonce:%s\n",nonce);
struct timeval begin;
gettimeofday(&begin,NULL);
long long beginTime = (long long)begin.tv_sec * 1000 + (long long)begin.tv_usec / 1000;
sprintf(timestamp,"%lld",beginTime);
//LOG_I("timestamp:%s\n",timestamp);
snprintf(signtmp, sizeof(sign), "device|%s|%s|wdewdilpvy",nonce,timestamp);
//LOG_I("signtmp:%s\n",signtmp);
get_md5_from_string(sign, sizeof(sign), signtmp, strlen(signtmp));
http_parse_url(url, domain, &server_port, file_name);
//LOG_I("url:%s\n", url);
//LOG_I("domain:%s\n", domain);
get_ip_by_domain(domain, server_ip, sizeof(server_ip));
if(is_ip_legal(server_ip)) {
ret = -1;
goto error;
}
//LOG_I("server_ip:%s, port:%d\n", server_ip, server_port);
//LOG_I("json code:%s\n",devcode);
unsigned long totalsize = 0;
unsigned long head_len = snprintf(header,1024,HTTP_HEAD_GETDEVREGISTERSTATUS,url,domain,nonce,timestamp,sign,totalsize); //头信息
totalsize+=head_len;
char* request = (char*)malloc(totalsize); //申请内存用于存放要发送的数据
if (request == NULL){
printf("malloc request fail !\r\n");
ret= -1;
goto error;
}
request[0] = '\0';
memcpy(request,header,head_len); //http结束信息
//LOG_I("request:%s\n",request);
client_socket = socket_client_open_connect(server_ip, server_port);
if(client_socket < 0){
close(client_socket);
ret = -2;
goto error;
}
if(write(client_socket, request, strlen(request))==-1){
LOG_I("write fail\r\n");
}
if((readbyte = read(client_socket,response,4096))==-1){
LOG_I("read http ACK fail !\r\n");
ret= -1;
goto error;
}
//LOG_I("ACK readbyte:%d\n",readbyte);
response[readbyte]='\0';
//LOG_I("response:%s\n",response);
#if 1
int index = 0,start_flag = 0;
int count=0;
int ack_json_len = 0;
int ack_json_tmplen = 0;
char ack_tmpjson[3072]={0};
char ack_json[3072]={0};
for(index = 0; index<readbyte; index++){
if(response[index] == '{'){
start_flag = 1;
}
if(start_flag)
ack_tmpjson[ack_json_tmplen++] = response[index]; //遇到左大括号则开始拷贝
}
//LOG_I("ack_json_tmplen:%d,ack_tmpjson:%s\n",ack_json_tmplen,ack_tmpjson);
start_flag=0;
for(index = 0; index<ack_json_tmplen; index++){
if(ack_tmpjson[index] == '{'){
count++;
if(ack_json_len>2){
break;
}
if(count>=2){
start_flag = 1;
}
}
if(start_flag)
ack_json[ack_json_len++] = ack_tmpjson[index]; //遇到左大括号则开始拷贝
}
ack_json[ack_json_len]='"';
ack_json[ack_json_len+1]='}';
//LOG_I("Receive len:%d\n",ack_json_len);
//LOG_I("Receive :%s\n",ack_json);
//LOG_I("Receive :%s\n",ack_json+1650);
if(ack_json_len > 0){
//LOG_I("deviceSecret:%s\n",deviceSecrets);
}else{
ack_json[0] = '\0';
LOG_I("Receive http ACK fail!!\n");
//LOG_I("--- ack_json_len = %d\n",ack_json_len);
ret=-1;
goto error;
}
#endif
error:
return ret;
}
int http_post_getdevinfo(char *url, char *devcodetmp,char *devcode)
{
char domain[1024] = {0};
char server_ip[20] = {0};
int server_port = 80;
char file_name[256] = {0};
char response[2048] = {0};
char tmpdata[2048] = {0};
char jsondata[2048] = {0};
int sendsuccess = 0;
int length = 0;
int ret = 0;
int client_socket;
int readbyte=0;
unsigned char header[1024]={0};
unsigned char send_request[1024]={0};
unsigned char send_end[1024]={0};
unsigned char http_boundary[64]={0};
unsigned char nonce[32]={0};
unsigned char timestamp[64]={0};
char signbase64[256]={0};
char signtmp[256]={0};
get_rand_str(nonce,6);
//LOG_I("nonce:%s\n",nonce);
struct timeval begin;
gettimeofday(&begin,NULL);
long long beginTime = (long long)begin.tv_sec * 1000 + (long long)begin.tv_usec / 1000;
sprintf(timestamp,"%lld",beginTime);
//LOG_I("timestamp:%s\n",timestamp);
strcpy(signtmp,devcodetmp);
strcat(signtmp,"0e8e9457d493666ee2f5adb783e69abb");
//strcpy(signtmp,"0e8e9457d493666ee2f5adb783e69abb");
LOG_I("signtmp:%s\n",signtmp);
get_base64_md5_from_string(signbase64, sizeof(signbase64), signtmp, strlen(signtmp));
LOG_I("signbase64:%s\n",signbase64);
sprintf(send_request,"curl -X POST -H 'x-appKey:d577e7b5024ad20446e10' -H 'x-datadigest:%s' -H 'Content-Type: application/json' -d '%s' %s",signbase64,devcodetmp,url);
LOG_I("send_request:%s\n",send_request);
//system(send_request);
FILE *fp;
char buffer[128];
fp=popen(send_request,"r");
fgets(buffer,sizeof(buffer),fp);
get_string_from_json_string_by_key_unescape(buffer, "message", tmpdata, sizeof(tmpdata));
LOG_I("hyx %s\n",tmpdata);
#if 0
http_parse_url(url, domain, &server_port, file_name);
LOG_I("url:%s\n", url);
LOG_I("domain:%s\n", domain);
get_ip_by_domain(domain, server_ip, sizeof(server_ip));
if(is_ip_legal(server_ip)) {
playAudio(SND_DEVSNGETFAIL);
ret = -1;
goto error;
}
LOG_I("server_ip:%s, port:%d\n", server_ip, server_port);
LOG_I("json code:%s\n",devcode);
unsigned long totalsize = 0;
unsigned long jsonsize = strlen(devcode);
totalsize = jsonsize;
LOG_I("totalsize1:%d\n",totalsize);
unsigned long head_len = snprintf(header,1024,HTTP_HEAD_GETDEVINFO_J,"/device/modifyRegisterInfo",domain,signbase64); //头信息
totalsize += head_len;
LOG_I("totalsize2:%d\n",totalsize);
char* request = (char*)malloc(totalsize); //申请内存用于存放要发送的数据
if (request == NULL){
printf("malloc request fail !\r\n");
ret= -1;
goto error;
}
request[0] = '\0';
memcpy(request,header,head_len); //http结束信息
memcpy(request+head_len,devcode,jsonsize); //http结束信息
LOG_I("request:%s\n",request);
client_socket = socket_client_open_connect(server_ip, server_port);
if(client_socket < 0){
LOG_I("socket error\r\n");
close(client_socket);
//playAudio(SND_DEVSNGETFAIL);
ret = -2;
goto error;
}
if(write(client_socket, request, strlen(request))==-1){
LOG_I("write fail\r\n");
}
if((readbyte = read(client_socket,response,2048))==-1){
LOG_I("read http ACK fail !\r\n");
//playAudio(SND_DEVSNGETFAIL);
ret= -1;
goto error;
}
LOG_I("ACK readbyte:%d\n",readbyte);
response[readbyte]='\0';
LOG_I("response:%s\n",response);
#if 1
int index = 0,start_flag = 0;
int ack_json_len = 0;
char ack_json[512]={0};
for(index = 0; index<readbyte; index++){
if(response[index] == '{'){
start_flag = 1;
}
if(start_flag)
ack_json[ack_json_len++] = response[index]; //遇到左大括号则开始拷贝
//if(response[index] == '}'){
// ack_json[ack_json_len] = '\0';
// break;
//}
}
//LOG_I("Receive:%s\n",ack_json);
if(ack_json_len > 0){
get_string_from_json_string_by_key_unescape(ack_json, "data", tmpdata, sizeof(tmpdata));
snprintf(jsondata, sizeof(jsondata), "{%s}", tmpdata);
//LOG_I("jsondata:%s\n",jsondata);
memset(devOwnSn,0,64);
get_string_from_json_string_by_key_unescape(jsondata, "devOwnSn", devOwnSn, sizeof(devOwnSn));
LOG_I("devOwnSn:%s\n",devOwnSn);
if(strcmp(devOwnSn,"")!=0){
memset(devOwnSn_save,0,64);
strcpy(devOwnSn_save,devOwnSn);
LOG_I("devOwnSn_save:%s\n",devOwnSn_save);
if(!hgz_judge_sn_exist_devin(devOwnSn_save)){
if(optBatchIn){
openDoorWaited=false;
playAudio(SND_SCANSUCCESS);
}else{
int len=0;
char *result=NULL;
result=file_to_buffer(devOwnSn,&len);
if(result==NULL){
//LOG_I("devOwnSn file not exist\n");
char openCell[4]={0};
if(hgz_judge_sn_exist_devout(devOwnSn_save,openCell)){
playAudio(SND_SCANSUCCESS);
returnDevs_multy(openCell);
}else{
LOG_I("dev not in\n");
//playAudio(SND_DEVNOTBORROWED);
}
}else{
//LOG_I("devOwnSn file exist:%s\n",result);
playAudio(SND_SCANSUCCESS);
repairReturnDevs_multy(result);
}
}
}else{
playAudio(SND_DEVSNALREADYEXIST);
}
}else{
playAudio(SND_DEVSNGETFAIL);
}
//get_string_from_json_string_by_key_unescape(jsondata, "devPro", devPRO, sizeof(devPRO));
//LOG_I("devPro:%s\n",devPRO);
//get_string_from_json_string_by_key_unescape(jsondata, "devMfg", devMFG, sizeof(devMFG));
//LOG_I("devMfg:%s\n",devMFG);
}else{
ack_json[0] = '\0';
LOG_I("Receive http ACK fail!!\n");
//LOG_I("--- ack_json_len = %d\n",ack_json_len);
//playAudio(SND_DEVSNGETFAIL);
ret=-1;
goto error;
}
#endif
#endif
error:
return ret;
}
int http_download(char *url, char *msg_id,int task_id,char *filepath)
{
int length = 0;
int written_len = 0;
char receive[2048] = "";
char path_name[512] = {0};
int ret = 0;
char domain[1024] = {0};
char server_ip[20] = {0};
int server_port = 80;
int client_socket;
char request[2048] = {0};
char response[2048] = {0};
char file_name[256] = {0};
//创建文件描述符
int fd = open(filepath, O_CREAT | O_WRONLY | O_TRUNC, S_IRWXG | S_IRWXO | S_IRWXU);
if (fd < 0) {
LOG_I("Create file failed\n");
ret = -1;
goto error;
}
sscanf(url, "%*[^//]//%[^/]%s", domain, file_name);
LOG_I("msgid:%s\n", msg_id);
LOG_I("taskid:%d\n", task_id);
LOG_I("filepath:%s\n", filepath);
LOG_I("url:%s\n", url);
LOG_I("domain:%s\n", domain);
LOG_I("file_name:%s\n", file_name);
get_ip_by_domain(domain, server_ip, sizeof(server_ip));
LOG_I("server_ip:%s\n",server_ip);
if(is_ip_legal(server_ip)) {
ret = -1;
goto error;
}
//设置http请求头信息
length = snprintf(request, sizeof(request),
"GET %s HTTP/1.1\r\n"
"HOST: %s\r\n"
"Cache-Control: no-cache\r\n"
"Connection: close\r\n\r\n",
file_name, domain);
client_socket = socket_client_open_connect(server_ip, server_port);
if(client_socket < 0){
close(client_socket);
ret = -2;
goto error;
}
//发送请求消息
write(client_socket, request, strlen(request));
length = read_data_until_str(client_socket, response, sizeof(response), "\r\n\r\n", strlen("\r\n\r\n"), 3000, 50);
if(length < 0){
LOG_I("read_data_until_str error\n");
ret = -3;
goto error;
}else if(length == 0){
LOG_I("read_data_until_str end\n");
ret = -4;
goto error;
}
http_response_t http_response;
get_http_response(response, &http_response);
http_response_debug(&http_response);
if(http_response.status_code == 200){
while(1) {
length = read_data_until_time(client_socket, receive, sizeof(receive), 3000, 50);
if(length < 0){
LOG_I("read_data_until_str error\n");
ret = -2;
goto error;
}else if(length == 0){
LOG_I("read_data_until_str end\n");
break;
}
write(fd, receive, length);
written_len += length;
//progress_bar(written_len, http_response.content_length);
if(written_len >= http_response.content_length) {
break;
}
}
if (written_len == http_response.content_length) {
LOG_I("Download %s successed\n", file_name);
sleep(2);
2025-05-04 10:17:27 +00:00
//newappDownloaded=true;
2025-04-06 06:41:47 +00:00
ret = 0;
} else {
LOG_I("Download %s failed\n", file_name);
ret = -3;
}
}else{
LOG_I("code not 200\n");
}
close(fd);
error:
return ret;
}