eclipse / paho.mqtt-sn.embedded-c

Paho C MQTT-SN gateway and libraries for embedded systems. Paho is an Eclipse IoT project.
https://eclipse.org/paho
Other
314 stars 179 forks source link

Mulicast hop limit for broadcasting GWINFO message #175

Closed LucDigi closed 4 years ago

LucDigi commented 4 years ago

I noticed that my nodes could not find the gateway if they connect to the border router through another router node, only if they would connect directly. When sniffing some packets I noticed that the multicast hop limit is set to 1, which is the default. Only this seems to limit nodes without a direct connection to be able to receive the GWINFO message. I'm not very familiar with sockets and so, but seem to have found the correct setting and added the following to SensorNetwork.cpp at line 288:

unsigned int hops = 5;
errnu = setsockopt(_sockfdMulticast, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops,sizeof(hops));
if(errnu <0)
{
    WRITELOG("UDP6::open - limit HOPS: %s",strerror(errnu));
    return errnu;
}

Now all nodes do receive the GWINFO message, the ttl now shows 5 and is re-transmitted by my thread router with ttl 4 so it seems to work as intended. Don't know how correct my quick fix is, but this seems a useful addition to the gateways functionality.

macpijan commented 4 years ago

@LucDigi I'm having similar issues with having router between the Border Router and the end device. Which wireless network are you using?

Have you tried increasing the Radius parameter in SEARCHGW message published by the node first? http://www.mqtt.org/new/wp-content/uploads/2009/06/MQTT-SN_spec_v1.2.pdf (5.4.2 section). IIUC the specification, the range of the GWINFO should be increased based on the parameter received in the SEARCHGW message. I have not being successful with that change though.

I am going to test your patch as well, although I'm also not sure whether this is the correct approach.

Paplewski commented 4 years ago

@ty4tw according to MQTTSN spec 5.4.2 the broadcast radius for GWINFO should be set as indicated in the GWSEARCH. Meanwhile, in the code the GWSEARCH message is not even parsed. MQTTSNGateway/src/MQTTSNGWConnectionHandler.cpp:51

/*
 *  SEARCHGW
 */
void MQTTSNConnectionHandler::handleSearchgw(MQTTSNPacket* packet)
{
    if (packet->getType() == MQTTSN_SEARCHGW)
    {
        MQTTSNPacket* gwinfo = new MQTTSNPacket();
        gwinfo->setGWINFO(_gateway->getGWParams()->gatewayId);
        Event* ev1 = new Event();
        ev1->setBrodcastEvent(gwinfo);
        _gateway->getClientSendQue()->post(ev1);
    }
}

Only the packet type is being checked. The solution above has helped, but it seems to modify the hop limit for all multicast messages. What is the proper way to configure the radius for the GWINFO broadcast? Or am I missing something?

ty4tw commented 4 years ago

Hi,

The specification 5.4.2 also states: The broadcast radius is also indicated to the underlying network layer when MQTT-SN gives this message for transmission.

ZigBee Transmit Request supports it. but not UDP. I think it's useless to parse it.

Hop count should be defined in the gateway.conf.

LucDigi commented 4 years ago

@ty4tw 6LoWPAN does support it with the Hop Limit parameter, so isn't it supposed to be set there as that is the type of packets nodes exchange?

edit: I agree that an option to set it in gateway.conf would be sufficient, as it isn't really a dynamic parameter.