u-blox / ubxlib

Portable C libraries which provide APIs to build applications with u-blox products and services. Delivered as add-on to existing microcontroller and RTOS SDKs.
Apache License 2.0
287 stars 82 forks source link

Cannot establish an MQTT connection from Thailand #228

Open alexmaron81 opened 2 months ago

alexmaron81 commented 2 months ago

Hi Rob, the connection to the APN is established in Thailand, but not to the MQTT. Other devices in Germany work well. Mobile provider 1nce (VPN)

ConnectionLogThai.txt

RobMeades commented 2 months ago

HI Alex. The command sequence looks fine, seems to just be getting no MQTT broker connection within the time given.

For your module type (SARA-R412M-02B-01 I believe) uMqttConnect() (the AT+UMQTTC=1 in the log) allows 15 seconds for the broker connection (see here). You could maybe try increasing that value 60000, as an experiment, to see if it just needs longer for some reason?

RobMeades commented 1 month ago

Hi @alexmaron81: how did this go in the end?

alexmaron81 commented 1 month ago

Hi Rob, I haven't been able to test any further yet. I was on holiday last week. Friday I have another meeting with thailand.

alexmaron81 commented 1 month ago

Can i ping an ip address?

RobMeades commented 1 month ago

The cellular module does support a command called AT+UPING but it is not something we have so far been asked to implement in ubxlib. If you wanted to add it yourself you could paste something like this into the end of u_cell_net.c:

int32_t uCellNetPing(uDeviceHandle_t cellHandle, const char *pDestination)
{
    int32_t errorCode = (int32_t) U_ERROR_COMMON_INVALID_PARAMETER;
    uCellPrivateInstance_t *pInstance;
    uAtClientHandle_t atHandle;

    if (gUCellPrivateMutex != NULL) {

        U_PORT_MUTEX_LOCK(gUCellPrivateMutex);

        pInstance = pUCellPrivateGetInstance(cellHandle);
        if ((pInstance != NULL) && (pDestination != NULL)) {
            atHandle = pInstance->atHandle;

            uAtClientLock(atHandle);
            uAtClientCommandStart(atHandle, "AT+UPING=");
            // Write destination
            uAtClientWriteString(atHandle, pDestination, true);
            uAtClientCommandStopReadResponse(atHandle);
            errorCode = uAtClientUnlock(atHandle);
        }

        U_PORT_MUTEX_UNLOCK(gUCellPrivateMutex);
    }

    return errorCode;
}

...adding a header for it as follows in u_cell_net.h:

/** Ping an address.
 *
 * @param cellHandle       the handle of the cellular instance.
 * @param[in] pDestination the destination IP address or domain; cannot be NULL.
 * @return                 zero on success or negative error code on
 *                         failure.
 */
int32_t uCellNetPing(uDeviceHandle_t cellHandle, const char *pDestination);
alexmaron81 commented 1 month ago

Hi Rob, I'm getting an error

AT+UPING="10.65.66.157"

ERROR CONNECT-BoxAT+UMQTT=3,"10.65.66.157"

is it true what is written in the following link?

https://portal.u-blox.com/s/question/0D52p00008qiQNOCA2/sarar41002b-with-ublox-nbiot-module-atuping-gives-error-even-though-device-is-attached-and-udp-data-transfer-works

RobMeades commented 1 month ago

Gah, yes, re-checking the SARA-R4 AT manual:

image

Sorry, no ping on SARA-R412M.

alexmaron81 commented 1 month ago

can i do it in a different way?

RobMeades commented 1 month ago

Not that I can think of I'm afraid. In theory you could connect at PPP-level and use the native ESP-IDF IP stack to do the ping but we have never tried making a PPP connection on a SARA-R412 and it would be a major change to the way your SW works to build and use PPP.

If what you would like to do is to check connectivity with a specific server or servers, what I would do is run a UDP echo client on a known/open port of that server, then you could send UDP packets to that server on that port and check for the echoed response coming back. Of course you would need access to the server-side to do this. Mind you, you might need access to the server-side in any case to be sure that it is configured to respond to ping.

Alternatively, beneath the MQTT protocol which I guess you are trying to test lies TCP, so if you opened a TCP connection on whatever your MQTT port is and that connection was successfully opened at TCP level then you have proved that there is connectivity, assuming that is your aim, you don't need to do any MQTT stuff at all. So you could just follow the pattern of the TLS sockets example (assuming you have TLS security) or otherwise the sockets example (if you don't have TLS security) to the IP address and port number of your MQTT broker.

But that is, of course, a more complicated arrangement than a UDP echo arrangement or ping.

alexmaron81 commented 4 weeks ago

Hi Rob, in the meantime we have inserted the SIM card into a smartphone and carried out a few tests. PIN via the 1nce SIM card (Android device) to the server was successful.

However, the smartphone has automatically activated with the following: Advanced Wireless Network Company (AIS) (MCC: 520, MNC: 03) But it is LTE image

alexmaron81 commented 4 weeks ago

... and it is Band 3 image

RobMeades commented 4 weeks ago

The network that an LTE module or an LTE phone chooses to connect to when fitted with a roaming SIM depends on many things I'm afraid: SIM preference list order, previous successful registrations, signal strength ranges, RF bands, probably other things.

If you do a network scan, i.e. something like:

char buffer[U_CELL_NET_MCC_MNC_LENGTH_BYTES];

for (int32_t x = uCellNetScanGetFirst(handle, NULL, 0, buffer, NULL, NULL);
     x >= 0;
     x = uCellNetScanGetNext(handle, NULL, 0, buffer, NULL)) {
    printf("%s\n", buffer);
}

...does 520:03 show up? If it does then at least it is broadcasting on radio bands that are compatible with the module, in which case you could potentially update the preference list on the SIM to put it at the top, or of course you could modify your code to manually select 520:03 but then you would have to do that specifically for the device(s) in Thailand, which would be a pain.

alexmaron81 commented 3 weeks ago

Hi Rob, the scan doesn't work somehow

image

RobMeades commented 3 weeks ago

Very strange: AT+COPS=? is one of the most basic AT commands, must be a timing thing. Maybe try waiting a few seconds before entering the for() loop?

alexmaron81 commented 3 weeks ago

Hi Rob, the scan is still not executed. Is there anything else I can do to ensure the success of the scan?

RobMeades commented 3 weeks ago

Not that I can think of: if the module is currently doing a scan, internally, itself, it might reject an attempt from the AT interface, but I would expect adding a delay or waiting a while and retrying to work in that case.

If that is not working, we could try a more direct approach, as an experiment, which would be to manually select 520:03, so in the uNetworkCfgCell_t you pass to uNetworkInterfaceUp(), populate the field pMccMnc with "52003" and see if that succeeds in registering with that network and allows you to make the connection you need.

This would be an experiment only, to verify that (a) the cellular network is there and (b) it does what you want.

alexmaron81 commented 3 weeks ago

I have already tried Manuel, but unfortunately no connection was established. Do I have to make any adjustments to the MNO, RAT or BAND?

RobMeades commented 3 weeks ago

Do I have to make any adjustments to the MNO, RAT or BAND?

Maybe band, but the most important thing is, for SARA-R412, the network must support CAT-M1 LTE (or GPRS). The phone that you put the SIM into will have been LTE, not CAT-M1 LTE. Does Advanced Wireless Network Company (AIS) support CAT-M1 LTE (or GPRS)?

alexmaron81 commented 3 weeks ago

1nce has informed me of the following: image

RobMeades commented 3 weeks ago

Ah, good, so you have 2G there. I expect you have configured the module into CAT-M1 only so you might get onto Advanced Wireless Network Company if you enable GPRS. Of course, if you have previously registered on an LTE network the device will go back there in preference but, for the purposes of this experiment, you can use manual selection to force it.

To add GPRS to your RAT list, ranked behind CAT-M1 (which will be at 0), call uCellCfgSetRatRank(devHandle, U_CELL_NET_RAT_GSM_GPRS_EGPRS, 1), so something like:

int32_t x = uCellCfgGetRatRank(devHandle, U_CELL_NET_RAT_GSM_GPRS_EGPRS);
if (x < 0) {
    x = 1;
    printf("Adding GPRS at rank %d.\n", x);
    x = uCellCfgSetRatRank(devHandle, U_CELL_NET_RAT_GSM_GPRS_EGPRS, x);
    if (x == 0) {
        if (uCellPwrRebootIsRequired(devHandle)) {
            printf("Rebooting to set RAT...\n");
            x = uCellPwrReboot(devHandle, NULL);
            if (x != 0) {
                printf("Unable to reboot (error code %d)!\n", x);
            }
        } else {
            printf("No reboot required to set RAT.\n");
        }
    } else {
        printf("Unable to add GPRS (error code %d)!\n", x);
    }
} else {
    printf("GPRS is at rank %d.\n", x);
}