http协议下载bin数据

支持芯片: ESP32-S3系列

void wifi_httpdnbin(str url,int addr,int size,int mode);
//url: 访问页面的而URL
//addr: 存储地址,psram存储区地址
//size: 最大下载数据的大小(下载区大小)
//mode:模式

本函数是一个异步调用函数,wifi_httpdnbin()被调用后,会立即向后执行,在获取信息后,会调用void app.onWIFI32(int m);判断m==4后就可以通过wifi_getinfo来获取结果

本函数不仅支持GET下载二进制数据,还支持POST上传数据,当使用wifiup_addstr以及wifiup_addbin之后,本函数将以post方式上传数据后并下载结果回来;在本次http连接disconnect之后,将执行wifiup_clear清除上传标志为下一次下载做好准备;

有关mode的描述:
mode 描述 addr 备注
0 下载数据到flash ROM数据区 addr是ROM对应的地址,必须是4096的倍数 数据是先下载到psram中默认下载区
1 psram存储区域 psram数据存储区地址,建议是4096的倍数
2 OTA固件区 用于固件升级
3 下载到TF卡 位置为TF卡根目录,文件名为url对应的文件名
4 内部使用 用于比对式更新ROM数据

*mode中的bit7 为1的话,会自动绘制内存MAP图,用于ROM的下载

示例

void app.onWIFI32(int m){
    str s="1000:";
    int i;
    if (m==4){
        //wifi_httpdnbin
        for (i=0;i<100;i++){
            s=s+int2hex(psram_gv(0x1000+i,1),2)+" ";
        }
        m1.text=s;
    }
}
void s3.onclick()
{
    //从网站下载4096字节到0x1000地址的psram中
    wifi_httpdnbin("http://a-diy.cn/",0x1000,4096,1);
}
start();
wifi_getinfo对应的功能表:
编号 内容 返回 描述
0 wifi_m int WIFI事件编号,即app.onWIFI32(int m)中的m,本函数中==4
2 msgnum int 消息编号,详见下表
3 p1 int 下载内容长度,本参数是服务器端传回的长度
4 p2 int 实际下载长度
5 url str http下载的url
12 dn str 从psram中的下载区转换成字符串返回
13 defdnaddr int 获取系统默认的dn位置的addr,对应psram
14 defupaddr int 获取系统默认的post位置的addr,对应psram
15 dnmaxsize int 获取系统默认的dn下载区尺寸
16 upmaxsize int 获取系统默认的post上传区尺寸
17 dnaddr int 获取实际的dn下载addr
18 upaddr int 获取实际的post上传区addr
19 dnsize int 获取已经下载的内容尺寸大小
21 d1 int httperrid对应的错误值,详见下表
22 d2 int httpstatus对应的状态值,详见下表
httperrid对应的错误值
错误码 情况
0x8001 无网络
0x8001 域名不存在或DNS服务不通
0x8006 无法连接服务器
httpstatus对应的状态值
状态码 情况
200 正常下载成功
404 页面url不存在,但服务器会返回404页面,因此仍会调用onWIFI32()事件
有关URL合成的问题

对于一个url来说,传入的参数是需要经过转义的,比如url中参数是通过&来分割的,那么当参数含有&这种特殊字符的时候,就会影响整个url的解析,比如:

http://shmictrl.com/?sn=参数sn
//当参数sn="123&b=5"这个字符串的时候,合成为:
http://shmictrl.com/?sn=123&b=5
//于是解析就会出错,会解出一个新的参数b,不仅参数错误,而且可能有安全漏洞

于是,按照互联网的规范,所有的参数都需要经过urlencode函数,该函数可以将特殊字符转换成%XX的格式加入进去,于是在我们这个系统中,合成URL请参见下面代码示例:

    str url="http://a-diy.cn/demo.php?sn=";
    url=url+app.urlencode(s2.text)+"&name=";
    url=url+app.urlencode(s3.text)+"&tel=";
    url=url+app.urlencode(s4.text);
    echo(url);
    wifi_httpget(url);

其中需要在appbase全局控件代码中增加urlencode函数,具体函数内容如下:

str urlencode(str s){
    //合成url时用的函数,可以把特殊字符和汉字转成%XX的格式
    str us=" !#$%+@:=?";
    str o="";
    int i;
    int c;
    int len;
    len=strlen(s);
    for (i=0;i<len;i++){
        c=asc(s,i);
        if (strpos(us,substr(s,i,1)>=0)){
            o=o+"%"+int2hex(c,2);
        }else{
            if (c>=128){
                o=o+"%"+int2hex(c,2);
            }else{
                o=o+chr(c);
            }
        }
    }
    return o;
}

由于本系统使用的是GB2312内码,因此为了可靠起见,以上函数对于汉字也转换成%XX格式。