hirotakaster / CoAP-simple-library

Other
111 stars 48 forks source link

coap.sendResponse doesn't working ESP32 #40

Closed ArtCodeZen closed 2 months ago

ArtCodeZen commented 1 year ago

I don't know what is the problem but the Coap-simple-library is not working to send response to client:

if (LEDSTATE) { digitalWrite(2, HIGH) ; coap.sendResponse(ip, port, packet.messageid, "1"); } else { digitalWrite(2, LOW) ; coap.sendResponse(ip, port, packet.messageid, "0"); }

even using your example test the response doesn't work. I had tested creating a client and server with 100% javascript + node working fine in tests. But When I send a PUT to Esp32 the led turn on and off, and the response to client is not OK! I used the the Coap Client on Android to confirm the problem. photo_2023-06-23_18-18-18

hirotakaster commented 1 year ago

Hi @ArtCodeZen ,

  1. Could you find the CoAP UDP message on your ESP32 Serial.println() in callback_light function from your CoAP app? Something CoAP UDP packet arrived, you could find that message.

  2. If you could not find "1. CoAP UDP message", have to check the UDP packet really arrived or not on Coap::loop function. exp) here is check the UDP packet length from network. packetlen = _udp->read(this->rx_buffer, packetlen >= coap_buf_size ? coap_buf_size : packetlen); to packetlen = _udp->read(this->rx_buffer, packetlen >= coap_buf_size ? coap_buf_size : packetlen); // check the UDP packet lenght. Serial.println(packetlen);

StarBridgeYoung commented 3 months ago

import asyncio from aiocoap import * from aiocoap.numbers import GET,PUT,POST

async def main(): protocol = await Context.create_client_context()

payload = b'0'  # Example payload (you may need to modify it)
request = Message(code=PUT, payload=payload, uri='coap://192.168.43.56:5683/led')
try:
    response = await protocol.request(request).response
    print('Result: %s\n%r' % (response.code, response.payload))
except Exception as e:
    print('Failed to fetch resource:')
    print(e)

if name == "main": asyncio.run(main())

I also encountered the same problem, using Python as the client, with the code shown above. The program will continue to block in request=Message (code=PUT, payload=payload, uri=' coap://192.168.43.56:5683/led On this code, no response was received.But the status of the LED has been switched, indicating that the server has received a response, but the client has not received a response from the server

hirotakaster commented 2 months ago

@StarBridgeYoung Maybe you use sample sketch code. aiocoap use CoAP token, so update source code like a following.

    coap.sendResponse(ip, port, packet.messageid, "1");
to
    coap.sendResponse(ip, port, packet.messageid, NULL, 0, COAP_VALID, COAP_TEXT_PLAIN, packet.token, packet.tokenlen);

This library is a basic implementation, so fit the implementation to fit the behavior of the library you are communicating with.

ArtCodeZen commented 2 months ago

Hi I had tested the library again, but I created a python aiocoap implementation, it works!

On arduino esp32 put the text and text lenght to coap.sendResponse:

 And python aiocoap example to test:
```python
import asyncio
from aiocoap import *

async def toggle_led(state):
    # Estado do LED: "1" para ligar e "0" para desligar
    uri = "coap://192.168.1.71/light"

    # Criando uma mensagem de PUT com o estado desejado
    request = Message(code=PUT, payload=state.encode('utf-8'))
    request.set_request_uri(uri)

    protocol = await Context.create_client_context()

    try:
        response = await protocol.request(request).response
        print(f'Received response: {response.payload.decode()}')
    except Exception as e:
        print(f'Failed to toggle LED: {e}')

async def main():
    while True:
        command = input("Digite 'ligar' para acender o LED ou 'desligar' para apagar o LED: ")
        if command.lower() == 'ligar':
            await toggle_led('1')
        elif command.lower() == 'desligar':
            await toggle_led('0')
        else:
            print("Comando inválido.")

# Inicia o loop assíncrono
if __name__ == "__main__":
    asyncio.run(main())
StarBridgeYoung commented 2 months ago

Hi I had tested the library again, but I created a python aiocoap implementation, it works!

On arduino esp32 put the text and text lenght to coap.sendResponse:

  • example hello -> length = 5 characters, it is just a example, real situation use .lenght
//coap.sendResponse(ip, port, packet.messageid, "hello");
    coap.sendResponse(ip, port, packet.messageid, "hello", 5, COAP_VALID, COAP_TEXT_PLAIN, packet.token, packet.tokenlen);

And python aiocoap example to test:

import asyncio
from aiocoap import *

async def toggle_led(state):
    # Estado do LED: "1" para ligar e "0" para desligar
    uri = "coap://192.168.1.71/light"

    # Criando uma mensagem de PUT com o estado desejado
    request = Message(code=PUT, payload=state.encode('utf-8'))
    request.set_request_uri(uri)

    protocol = await Context.create_client_context()

    try:
        response = await protocol.request(request).response
        print(f'Received response: {response.payload.decode()}')
    except Exception as e:
        print(f'Failed to toggle LED: {e}')

async def main():
    while True:
        command = input("Digite 'ligar' para acender o LED ou 'desligar' para apagar o LED: ")
        if command.lower() == 'ligar':
            await toggle_led('1')
        elif command.lower() == 'desligar':
            await toggle_led('0')
        else:
            print("Comando inválido.")

# Inicia o loop assíncrono
if __name__ == "__main__":
    asyncio.run(main())

Thank you, maybe I just used it in ESP32 Coap.sendResponse (IP, port, packet.messageid, 1); Incomplete parameters passed