A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://docs.espressif.com/projects/esp-at/en/latest/AT_Command_Set/BLE_AT_Commands.html below:

Website Navigation


Bluetooth® Low Energy AT Commands - ESP32

Bluetooth® Low Energy AT Commands

[中文]

Introduction

Currently, AT firmware for ESP32 series supports Bluetooth® Core Specification Version 4.2.

Important

The default AT firmware supports all the AT commands mentioned on this page. If you need to modify the commands supported by ESP32 by default, please compile the ESP-AT project by following the steps in Compile ESP-AT Project Locally documentation. In the project configuration during the fifth step, make the following selections (Each item below is independent. Choose it according to your needs):

AT+BLEINIT: Bluetooth LE Initialization Query Command

Function:

Check the initialization status of Bluetooth LE.

Command:

Response:

If Bluetooth LE is initialized, AT will return:

If Bluetooth LE is not initialized, AT will return:

Set Command

Function:

Initialize the role of Bluetooth LE.

Command:

Response:

Parameter Notes Example AT+BLEADDR: Query/Set Bluetooth LE Device Address Query Command

Function:

Query the Bluetooth LE Public Address.

Command:

Response:

+BLEADDR:<BLE_public_addr>
OK
Set Command

Function:

Set the Bluetooth LE address type.

Command:

AT+BLEADDR=<addr_type>[,<random_addr>]

Response:

Parameter Note Example
AT+BLEADDR=1,"f8:7f:24:87:1c:7b"    // Set Random Device Address, Static Address
AT+BLEADDR=1                        // Set Random Device Address, Private Address
AT+BLEADDR=0                        // Set Public Device Address
AT+BLENAME: Query/Set Bluetooth LE Device Name Query Command

Function:

Query the Bluetooth LE device name.

Command:

Response:

+BLENAME:<device_name>
OK
Set Command

Function:

Set the Bluetooth LE device name.

Command:

Response:

Parameter Note Example AT+BLESCANPARAM: Query/Set Parameters of Bluetooth LE Scanning Query Command

Function:

Query the parameters of Bluetooth LE scanning.

Command:

Response:

+BLESCANPARAM:<scan_type>,<own_addr_type>,<filter_policy>,<scan_interval>,<scan_window>
OK
Set Command

Function:

Set the parameters of Bluetooth LE scanning.

Command:

AT+BLESCANPARAM=<scan_type>,<own_addr_type>,<filter_policy>,<scan_interval>,<scan_window>

Response:

Parameters Example
AT+BLEINIT=1   // Role: client
AT+BLESCANPARAM=0,0,0,100,50
AT+BLESCAN: Enable Bluetooth LE Scanning Set Command

Function:

Enable/disable scanning.

Command:

AT+BLESCAN=<enable>[,<duration>][,<filter_type>,<filter_param>]

Response:

+BLESCAN:<addr>,<rssi>,<adv_data>,<scan_rsp_data>,<addr_type>
OK
+BLESCANDONE
Parameters Notes Example
AT+BLEINIT=1    // Role: client
AT+BLESCAN=1    // start scanning
AT+BLESCAN=0    // stop scanning
AT+BLESCAN=1,3,1,"24:0A:C4:96:E6:88"  // start scanning, filter type is MAC address
AT+BLESCAN=1,3,2,"ESP-AT"  // start scanning, filter type is device name
AT+BLESCANRSPDATA: Set Bluetooth LE Scan Response Set Command

Function:

Set scan response.

Command:

AT+BLESCANRSPDATA=<scan_rsp_data>

Response:

Parameter Example
AT+BLEINIT=2   // Role: server
AT+BLESCANRSPDATA="1122334455"
AT+BLEADVPARAM: Query/Set Parameters of Bluetooth LE Advertising Query Command

Function:

Query the parameters of advertising.

Command:

Response:

+BLEADVPARAM:<adv_int_min>,<adv_int_max>,<adv_type>,<own_addr_type>,<channel_map>,<adv_filter_policy>,<peer_addr_type>,<"peer_addr">
OK
Set Command

Function:

Set the parameters of advertising.

Command:

AT+BLEADVPARAM=<adv_int_min>,<adv_int_max>,<adv_type>,<own_addr_type>,<channel_map>[,<adv_filter_policy>][,<peer_addr_type>,<"peer_addr">]

Response:

Parameters Note Example
AT+BLEINIT=2   // Role: server
AT+BLEADDR=1,"c2:34:45:78:66:89"
AT+BLEADVPARAM=50,50,0,1,4,0,1,"12:34:45:78:66:88"
// At this time, the MAC of the ESP device scanned by the BLE client is "c2:34:45:78:66:89".
AT+BLEADVDATA: Set Bluetooth LE Advertising Data Set Command

Function:

Set advertising data.

Command:

Response:

Parameter Note Example
AT+BLEINIT=2   // Role: server
AT+BLEADVDATA="1122334455"
AT+BLEADVDATAEX: Automatically Set Bluetooth LE Advertising Data Query Command

Function:

Query the parameters of advertising data.

Command:

Response:

+BLEADVDATAEX:<dev_name>,<uuid>,<manufacturer_data>,<include_power>

OK
Set Command

Function:

Set the advertising data and start advertising.

Command:

AT+BLEADVDATAEX=<dev_name>,<uuid>,<manufacturer_data>,<include_power>

Response:

Parameters Note Example
AT+BLEINIT=2   // Role: server
AT+BLEADVDATAEX="ESP-AT","A002","0102030405",1
AT+BLEADVSTART: Start Bluetooth LE Advertising Execute Command

Function:

Start advertising.

Command:

Response:

Notes Example
AT+BLEINIT=2   // Role: server
AT+BLEADVSTART
AT+BLEADVSTOP: Stop Bluetooth LE Advertising Execute Command

Function:

Stop advertising.

Command:

Response:

Note Example
AT+BLEINIT=2   // Role: server
AT+BLEADVSTART
AT+BLEADVSTOP
AT+BLECONN: Establish Bluetooth LE Connection Query Command

Function:

Query the Bluetooth LE connection.

Command:

Response:

+BLECONN:<conn_index>,<remote_address>
OK

If the connection has not been established, there will be no <conn_index> and <remote_address> in the response.

Set Command

Function:

Establish the Bluetooth LE connection.

Command:

AT+BLECONN=<conn_index>,<remote_address>[,<addr_type>,<timeout>]

Response:

If the connection is established successfully, it will prompt:

+BLECONN:<conn_index>,<remote_address>

OK

If the connection fails, it will prompt:

+BLECONN:<conn_index>,-1

ERROR

If the connection fails due to parameters error or other reasons, it will prompt:

Parameters Notes Example
AT+BLEINIT=1   // Role: client
AT+BLECONN=0,"24:0a:c4:09:34:23",0,10
AT+BLECONNPARAM: Query/Update Parameters of Bluetooth LE Connection Query Command

Function:

Query the parameters of Bluetooth LE connection.

Command:

Response:

+BLECONNPARAM:<conn_index>,<min_interval>,<max_interval>,<cur_interval>,<latency>,<timeout>
OK
Set Command

Function:

Update the parameters of Bluetooth LE connection.

Command:

AT+BLECONNPARAM=<conn_index>,<min_interval>,<max_interval>,<latency>,<timeout>

Response:

If the setting fails, it will prompt the message below:

+BLECONNPARAM: <conn_index>,-1
Parameters Note Example
AT+BLEINIT=1   // Role: client
AT+BLECONN=0,"24:0a:c4:09:34:23"
AT+BLECONNPARAM=0,12,14,1,500
AT+BLEDISCONN: End Bluetooth LE Connection Execute Command

Function:

End the Bluetooth LE connection.

Command:

AT+BLEDISCONN=<conn_index>

Response:

OK  // The AT+BLEDISCONN command is received.
+BLEDISCONN:<conn_index>,<remote_address>  // The command is successful.
Parameters Example
AT+BLEINIT=1   // Role: client
AT+BLECONN=0,"24:0a:c4:09:34:23"
AT+BLEDISCONN=0
AT+BLEDATALEN: Set Bluetooth LE Data Packet Length Set Command

Function:

Set the length of Bluetooth LE data packet.

Command:

AT+BLEDATALEN=<conn_index>,<pkt_data_len>

Response:

Parameters Note Example
AT+BLEINIT=1   // Role: client
AT+BLECONN=0,"24:0a:c4:09:34:23"
AT+BLEDATALEN=0,30
AT+BLECFGMTU: Set Bluetooth LE MTU Length Query Command

Function:

Query the length of the maximum transmission unit (MTU).

Command:

Response:

+BLECFGMTU:<conn_index>,<mtu_size>
OK
Set Command

Function:

Set the length of the maximum transmission unit (MTU).

Command:

AT+BLECFGMTU=<conn_index>,<mtu_size>

Response:

OK  // The command is received.
Parameters
-  **<conn_index>**: index of Bluetooth LE connection. Range: [0,2].
-  **<mtu_size>**: MTU length. Unit: byte. Range: [23,517].
Notes
-  Bluetooth LE connection has to be established first.
-  Only the client can call this command to set the length of MTU.
-  The actual length of MTU needs to be negotiated. The ``OK`` response only indicates an attempt to negotiate the length. The actual length may not be the value you set. Therefore, it is recommended to run command :ref:`AT+BLECFGMTU? <cmd-BMTU>` to query the actual length.
Example
AT+BLEINIT=1   // Role: client
AT+BLECONN=0,"24:0a:c4:09:34:23"
AT+BLECFGMTU=0,300
AT+BLEGATTSSRVCRE: GATTS Creates Services Execute Command

Function:

The Generic Attributes Server (GATTS) creates Bluetooth LE services.

Command:

Response:

Notes Example
AT+BLEINIT=2   // Role: server
AT+BLEGATTSSRVCRE
AT+BLEGATTSSRVSTART: GATTS Starts Services Execute Command

Function:

GATTS starts all services.

Command:

Set Command

Function:

GATTS starts a specific service.

Command:

AT+BLEGATTSSRVSTART=<srv_index>

Response:

Parameter Example
AT+BLEINIT=2   // Role: server
AT+BLEGATTSSRVCRE
AT+BLEGATTSSRVSTART
AT+BLEGATTSSRVSTOP: GATTS Stops Services Execute Command

Function:

GATTS stops all services.

Command:

Set Command

Function:

GATTS stops a specific service.

Command:

AT+BLEGATTSSRVSTOP=<srv_index>

Response:

Parameter Example
AT+BLEINIT=2   // Role: server
AT+BLEGATTSSRVCRE
AT+BLEGATTSSRVSTART
AT+BLEGATTSSRVSTOP
AT+BLEGATTSSRV: GATTS Discovers Services Query Command

Function:

GATTS discovers services.

Command:

Response:

+BLEGATTSSRV:<srv_index>,<start>,<srv_uuid>,<srv_type>
OK
Parameters Example
AT+BLEINIT=2   // Role: server
AT+BLEGATTSSRVCRE
AT+BLEGATTSSRV?
AT+BLEGATTSCHAR: GATTS Discovers Characteristics Query Command

Function:

GATTS discovers characteristics.

Command:

Response:

The response for a characteristic:

+BLEGATTSCHAR:"char",<srv_index>,<char_index>,<char_uuid>,<char_prop>

The response for a descriptor:

+BLEGATTSCHAR:"desc",<srv_index>,<char_index>,<desc_index>
OK
Parameters Example
AT+BLEINIT=2   // Role: server
AT+BLEGATTSSRVCRE
AT+BLEGATTSSRVSTART
AT+BLEGATTSCHAR?
AT+BLEGATTSNTFY: Notify a Client of the Value of a Characteristic Value from the Server Set Command

Function:

Notify a client of the value of a characteristic value from the server.

Command:

AT+BLEGATTSNTFY=<conn_index>,<srv_index>,<char_index>,<length>

Response:

The symbol > indicates that AT is ready for receiving serial data, and you can enter data now. When the requirement of data length determined by the parameter <length> is met, the notification starts.

If the data transmission is successful, AT returns:

Parameters Example
AT+BLEINIT=2      // Role: server.
AT+BLEGATTSSRVCRE
AT+BLEGATTSSRVSTART
AT+BLEADVSTART    // Start advertising. After the client is connected, it must be configured to receive notifications.
AT+BLEGATTSCHAR?  // Query the characteristics which the client will be notified of.
// For example, to notify of 4-byte data using the 6th characteristic in the 3rd service, use the following command:
AT+BLEGATTSNTFY=0,3,6,4
// After the symbol ">" shows, enter the 4-byte data, such as "1234". Then the data will be transmitted automatically.
AT+BLEGATTSIND: Indicate the Characteristic Value from the Server to a Client Set Command

Function:

Indicate the characteristic value from the server to a client.

Command:

AT+BLEGATTSIND=<conn_index>,<srv_index>,<char_index>,<length>

Response:

The symbol > indicates that AT is ready for receiving serial data and you can enter data now. When the requirement of data length determined by the parameter <length> is met, the indication starts.

If the data transmission is successful, AT returns:

Parameters Example
AT+BLEINIT=2      // Role: server
AT+BLEGATTSSRVCRE
AT+BLEGATTSSRVSTART
AT+BLEADVSTART    // Start advertising. After the client is connected, it must be configured to receive indications.
AT+BLEGATTSCHAR?  // Query the characteristics which the client can receive indications.
// For example, to indicate 4 bytes of data using the 7th characteristic in the 3rd service, use the following command:
AT+BLEGATTSIND=0,3,7,4
// After the symbol ">" shows, input 4 bytes of data, such as "1234". Then the data will be transmitted automatically.
AT+BLEGATTSSETATTR: GATTS Sets Characteristics Set Command

Function:

GATTS sets its characteristic (descriptor).

Command:

AT+BLEGATTSSETATTR=<srv_index>,<char_index>,[<desc_index>],<length>

Response:

The symbol > indicates that AT is ready for receiving serial data and you can enter data now. When the requirement of data length determined by the parameter <length> is met, the setting starts.

If the setting is successful, AT returns:

Parameters Note Example
AT+BLEINIT=2   // Role: server.
AT+BLEGATTSSRVCRE
AT+BLEGATTSSRVSTART
AT+BLEGATTSCHAR?
// For example, to set 1 byte of data of the 1st characteristic in the 1st service, use the following command:
AT+BLEGATTSSETATTR=1,1,,1
// After the symbol ">" shows, input 1 byte of data, such as "8". Then the setting starts.
AT+BLEGATTCPRIMSRV: GATTC Discovers Primary Services Query Command

Function:

Generic Attributes Client (GATTC) discovers primary services.

Command:

AT+BLEGATTCPRIMSRV=<conn_index>

Response:

+BLEGATTCPRIMSRV:<conn_index>,<srv_index>,<srv_uuid>,<srv_type>
OK
Parameters Note Example
AT+BLEINIT=1   // Role: client
AT+BLECONN=0,"24:12:5f:9d:91:98"
AT+BLEGATTCPRIMSRV=0
AT+BLEGATTCINCLSRV: GATTC Discovers Included Services Set Command

Function:

GATTC discovers included services.

Command:

AT+BLEGATTCINCLSRV=<conn_index>,<srv_index>

Response:

+BLEGATTCINCLSRV:<conn_index>,<srv_index>,<srv_uuid>,<srv_type>,<included_srv_uuid>,<included_srv_type>
OK
Parameters Note Example
AT+BLEINIT=1   // Role: client
AT+BLECONN=0,"24:12:5f:9d:91:98"
AT+BLEGATTCPRIMSRV=0
AT+BLEGATTCINCLSRV=0,1  // set a specific index according to the result of the previous command
AT+BLEGATTCCHAR: GATTC Discovers Characteristics Set Command

Function:

GATTC discovers characteristics.

Command:

AT+BLEGATTCCHAR=<conn_index>,<srv_index>

Response:

The response for a characteristic:

+BLEGATTCCHAR:"char",<conn_index>,<srv_index>,<char_index>,<char_uuid>,<char_prop>

The response for a descriptor:

+BLEGATTCCHAR:"desc",<conn_index>,<srv_index>,<char_index>,<desc_index>,<desc_uuid>
OK
Parameters Note Example
AT+BLEINIT=1   // Role: client
AT+BLECONN=0,"24:12:5f:9d:91:98"
AT+BLEGATTCPRIMSRV=0
AT+BLEGATTCCHAR=0,1 // set a specific index according to the result of the previous command
AT+BLEGATTCRD: GATTC Reads Characteristics Set Command

Function:

GATTC reads a characteristic or descriptor.

Command:

AT+BLEGATTCRD=<conn_index>,<srv_index>,<char_index>[,<desc_index>]

Response:

+BLEGATTCRD:<conn_index>,<len>,<value>
OK
Parameters Notes Example
AT+BLEINIT=1   // Role: client.
AT+BLECONN=0,"24:12:5f:9d:91:98"
AT+BLEGATTCPRIMSRV=0
AT+BLEGATTCCHAR=0,3 // Set a specific index according to the result of the previous command.
// For example, to read 1st descriptor of the 2nd characteristic in the 3rd service, use the following command:
AT+BLEGATTCRD=0,3,2,1
AT+BLEGATTCWR: GATTC Writes Characteristics Set Command

Function:

GATTC writes characteristics or descriptors.

Command:

AT+BLEGATTCWR=<conn_index>,<srv_index>,<char_index>[,<desc_index>],<length>

Response:

The symbol > indicates that AT is ready for receiving serial data and you can enter data now. When the requirement of data length determined by the parameter <length> is met, the writing starts.

If the setting is successful, AT returns:

Parameters Notes Example
AT+BLEINIT=1   // Role: client.
AT+BLECONN=0,"24:12:5f:9d:91:98"
AT+BLEGATTCPRIMSRV=0
AT+BLEGATTCCHAR=0,3 // Set a specific index according to the result of the previous command.
// For example, to write 6 bytes of data to the 4th characteristic in the 3rd service, use the following command:
AT+BLEGATTCWR=0,3,4,,6
// After the symbol ">" shows, input 6 bytes of data, such as "123456". Then the writing starts.
AT+BLESPPCFG: Query/Set Bluetooth LE SPP Parameters Query Command

Function:

Query the parameters of Bluetooth LE Serial Port Profile (SPP).

Command:

Response:

+BLESPPCFG:<tx_service_index>,<tx_char_index>,<rx_service_index>,<rx_char_index>,<auto_conn>
OK
Set Command

Function:

Set or reset the parameters of Bluetooth LE SPP.

Command:

AT+BLESPPCFG=<cfg_enable>[,<tx_service_index>,<tx_char_index>,<rx_service_index>,<rx_char_index>][,<auto_conn>]

Response:

Parameters Notes Example
AT+BLESPPCFG=0          // reset Bluetooth LE SPP parameters
AT+BLESPPCFG=1,3,5,3,7  // set Bluetooth LE SPP parameters
AT+BLESPPCFG?           // query Bluetooth LE SPP parameters
AT+BLESPP: Enter Bluetooth LE SPP Mode Execute Command

Function:

Enter Bluetooth LE SPP mode.

Command:

Response:

This response indicates that AT has entered Bluetooth LE SPP mode and can send and receive data.

If the Bluetooth LE SPP status is wrong ( Notifications are not enabled at the opposite end after the Bluetooth LE connection is established ), the system returns:

Notes Example
AT+BLESPP   // enter Bluetooth LE SPP mode
AT+BLESECPARAM: Query/Set Bluetooth LE Encryption Parameters Query Command

Function:

Query the parameters of Bluetooth LE SMP.

Command:

Response:

+BLESECPARAM:<auth_req>,<iocap>,<enc_key_size>,<init_key>,<rsp_key>,<auth_option>
OK
Set Command

Function:

Set the parameters of Bluetooth LE SMP.

Command:

AT+BLESECPARAM=<auth_req>,<iocap>,<enc_key_size>,<init_key>,<rsp_key>[,<auth_option>]

Response:

Parameters Note Example
AT+BLESECPARAM=1,4,16,3,3,0
AT+BLEENC: Initiate Bluetooth LE Encryption Request Set Command

Function:

Start a pairing request

Command:

AT+BLEENC=<conn_index>,<sec_act>

Response:

Parameters Note Example
AT+RESTORE
AT+BLEINIT=2
AT+BLEGATTSSRVCRE
AT+BLEGATTSSRVSTART
AT+BLEADDR?
AT+BLESECPARAM=1,0,16,3,3
AT+BLESETKEY=123456
AT+BLEADVSTART
// Use your Bluetooth LE debugging app as a client to establish a Bluetooth LE connection with the ESP32
AT+BLEENC=0,3
AT+BLEENCRSP: Respond to the Pairing Request from the Peer Device Set Command

Function:

Respond to the pairing request from the peer device.

Command:

AT+BLEENCRSP=<conn_index>,<accept>

Response:

Parameters Note
+BLEAUTHCMPL:<conn_index>,<enc_result>
Example AT+BLEKEYREPLY: Reply the Key Value to the Peer Device Set Command

Function:

Reply a pairing key.

Command:

AT+BLEKEYREPLY=<conn_index>,<key>

Response:

Parameters Example AT+BLECONFREPLY: Reply the Confirm Value to the Peer Device in the Legacy Connection Stage Set Command

Function:

Reply a pairing result.

Command:

AT+BLECONFREPLY=<conn_index>,<confirm>

Response:

Parameters Example AT+BLEENCDEV: Query Bonded Bluetooth LE Encryption Device List Query Command

Function:

Query bonded Bluetooth LE encryption device list.

Command:

Response:

+BLEENCDEV:<enc_dev_index>,<mac_address>
OK
Parameters Note Example AT+BLEENCCLEAR: Clear Bluetooth LE Encryption Device List Set Command

Function:

Remove a device from the security database list with a specific index.

Command:

AT+BLEENCCLEAR=<enc_dev_index>

Response:

Execute Command

Function:

Remove all devices from the security database.

Command:

Response:

Parameter Example AT+BLESETKEY: Set Bluetooth LE Static Pair Key Query Command

Function:

Query the Bluetooth LE static pair key. If it is not set, AT will return -1.

Command:

Response:

+BLESETKEY:<static_key>
OK
Set Command

Function:

Set a Bluetooth LE static pair key for all Bluetooth LE connections.

Command:

AT+BLESETKEY=<static_key>

Response:

Parameter Example AT+BLEHIDINIT: Bluetooth LE HID Profile Initialization Query Command

Function:

Query the initialization status of Bluetooth LE HID profile.

Command:

Response:

If Bluetooth LE HID device profile is not initialized, AT will return:

If Bluetooth LE HID device profile is initialized, AT will return:

Set Command

Function:

Initialize the Bluetooth LE HID profile.

Command:

Response:

Parameter Note Example AT+BLEHIDKB: Send Bluetooth LE HID Keyboard Information Set Command

Function:

Send keyboard information.

Command:

AT+BLEHIDKB=<Modifier_keys>,<key_1>,<key_2>,<key_3>,<key_4>,<key_5>,<key_6>

Response:

Parameters Note Example
AT+BLEHIDKB=0,4,0,0,0,0,0   // input the string "a"
AT+BLEHIDMUS: Send Bluetooth LE HID Mouse Information Set Command

Function:

Send mouse information.

Command:

AT+BLEHIDMUS=<buttons>,<X_displacement>,<Y_displacement>,<wheel>

Response:

Parameters Note Example AT+BLEHIDCONSUMER: Send Bluetooth LE HID Consumer Information Set Command

Function:

Send consumer information.

Command:

AT+BLEHIDCONSUMER=<consumer_usage_id>

Response:

Parameter Note Example
AT+BLEHIDCONSUMER=233   // volume up
AT+BLUFI: Start or Stop BluFi Query Command

Function:

Query the status of BluFi.

Command:

Response:

If BluFi is not started, it will return:

If BluFi is started, it will return:

Set Command

Function:

Start or stop BluFi.

Command:

AT+BLUFI=<option>[,<auth floor>]

Response:

Parameter Note Example AT+BLUFINAME: Query/Set BluFi Device Name Query Command

Function:

Query the BluFi name.

Command:

Response:

+BLUFINAME:<device_name>
OK
Set Command

Function:

Set the BluFi device name.

Command:

AT+BLUFINAME=<device_name>

Response:

Parameter Notes Example
AT+BLUFINAME="BLUFI_DEV"
AT+BLUFINAME?
AT+BLUFISEND: Send User-Customized Data over BluFi Set Command

Function:

Send user-customized data from the ESP side to a phone over BluFi.

Command:

Response:

The symbol > indicates that AT is ready for receiving serial data and you can enter data now. When the requirement of data length determined by the parameter <length> is met, the transmission starts.

If the data transmission is successful, AT returns:

Parameters Notes Example
AT+BLUFISEND=4
// After the symbol ">" shows, input 4 bytes of data, such as "1234". Then the data will be transmitted automatically.

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4