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
303 stars 90 forks source link

Cannot establish a connection for the first time #151

Closed alexmaron81 closed 11 months ago

alexmaron81 commented 11 months ago

Cannot establish a connection for the first time. When the SIM card (1nce.com) is inserted into a smartphone, the connection is established successfully. The card is then installed in the actual embedded device (SARA-R412M-02B) and only then will the connection be successful.

RobMeades commented 11 months ago

Hi Alex. This is the "airport" scenario, when a device, or in this case a SIM card, has no previous registration information to take advantage of. Under these circumstances registration can take a long time: it will depend how you have configured the module (number of RATs, order of RATs, number of bands, etc.) as to how long this takes. This can be particularly bad with the "international" SIM cards (MCC in the 9xx range) often used in IoT applications, which have no basis in geography to help with.

The hardware and software in the phone is different: supporting, or configuring, different RATs, bands, etc. and so may gain service more quickly: after all, it is not an IoT device that expects to be buried in a basement, it just wants to make phone calls.

Once registration has been achieved, information is written to the SIM card which directs future registration attempts, and if you move the SIM from the phone to your embedded device, the information will go with it.

If you believe this is an issue with ubxlib, please attach an AT log of each of the two scenarios: the "not registering 'cos you haven't put this SIM into a phone yet" scenario and the "registering nice and quick now that the SIM has once registered". It may be that changing the way you configure the module, to make it more like that in your phone, will speed things up, though of course that ultimately means scanning fewer things, and so the range of network types on which your embedded device can register will likely be reduced.

alexmaron81 commented 11 months ago

first_start_log.txt

RobMeades commented 11 months ago

Thanks for the log. What I see is:

If you like, you could run code something like this to determine what the module is set to in terms of current RAT combination and band mask (I've not compiled this code, just a sketch for you to start from):

int32_t x;
uCellNetRat_t rat[3];
uint64_t readBandMask1;
uint64_t readBandMask2;

x = uCellCfgGetMnoProfile(devHandle);
printf("MNO profile is %d.\n", x);
for (x = 0; x < 3; x++) {
    rat[x] = uCellCfgGetRat(devHandle, x);
    if (rat[x] >= 0) {
        printf("RAT[%d] is %d.\n", x, rat[x]);
        if (uCellCfgGetBandMask(devHandle, rat[x],
                                &readBandMask1, &readBandMask2) == 0) {
       printf("Band mask for RAT %d is 0x%08x%08x %08x%08x.\n", rat[x],
              (uint32_t) (readBandMask2 >> 32), (uint32_t) readBandMask2,
              (uint32_t) (readBandMask1 >> 32), (uint32_t) readBandMask1);
        }
    }
}

If the RAT inside the module really is set to 7 (LTE Cat-M1) only, we can see that the module is saying that it has found no network coverage whatsoever, it has already given up scanning in fact:

AT+CEREG?
+CEREG: 4,0 <<< 4, from section 13.14.4 of the AT manual, means "unknown (e.g. out of E-UTRAN coverage)" for E-UTRAN (i.e. LTE) registration
OK

The odd thing is that the responses for CREG and CGREG are 2,0 which, from sections 7.11.3 and 13.11.3 of the AT manual, indicates "not registered, but the MT is currently trying to attach or searching an operator to register to". This seems strange if the RAT is set to 7 only: I would expect pretty much the opposite, searching on LTE (so a +CEREG: 2,0 response to AT+CEREG? and a +C[G]REG: 4,0 response to AT+C[G]REG?).

Anyway, the question then becomes, when the module does successfully register with the network, which RAT does it register on?

alexmaron81 commented 11 months ago

Hi Rob, I inserted the code like this and the following comes out:

uCellCfgGetMnoProfile.txt

RobMeades commented 11 months ago

Can you try moving it to after the network connection has been made?

alexmaron81 commented 11 months ago

uCellCfgGetMnoProfile_connection_has_been_made.txt

RobMeades commented 11 months ago

The only reason I can think of for the module to return "not supported" to the AT+URAT? command (which is supported by all LTE-capable modules without exception) is if the AT+UMNOPROFILE setting does not permit it. You are unusual in that you are on MNO Profile 0, the factory default, which is not something I've seen before.

Most customers set this to 90 (global) or 100 (Europe).

So could you put the code block back to where it was before and try changing it to (again, code not compiled by me, a sketch to get you working, please adjust for any missing semicolons etc.):

#define MY_MNO_PROFILE 100

int32_t x;
uCellNetRat_t rat[3];
uint64_t readBandMask1;
uint64_t readBandMask2;

x = uCellCfgGetMnoProfile(devHandle);
if (x >= 0) {
    if (x != MY_MNO_PROFILE) {
        printf("MNO profile is %d, setting it to %d.\n", x, MY_MNO_PROFILE);
        x = uCellCfgSetMnoProfile(devHandle, MY_MNO_PROFILE);
        if (x == 0) {
            uCellPwrReboot(devHandle, NULL);
        } else {
            printf("Unable to set MNO profile (%d)!"\n", x);
        }
    }
    x = uCellCfgGetMnoProfile(devHandle);
    printf("MNO profile is %d.\n", x);
} else {
    printf("Unable to read MNO Profile (%d)!\n", x);
}
for (x = 0; x < 3; x++) {
    rat[x] = uCellCfgGetRat(devHandle, x);
    if (rat[x] >= 0) {
        printf("RAT[%d] is %d.\n", x, rat[x]);
        if (uCellCfgGetBandMask(devHandle, rat[x],
                                &readBandMask1, &readBandMask2) == 0) {
       printf("Band mask for RAT %d is 0x%08x%08x %08x%08x.\n", rat[x],
              (uint32_t) (readBandMask2 >> 32), (uint32_t) readBandMask2,
              (uint32_t) (readBandMask1 >> 32), (uint32_t) readBandMask1);
        }
    }
}
alexmaron81 commented 11 months ago

uCellCfgGetMnoProfile_with_uCellCfgSetMnoProfile.txt

RobMeades commented 11 months ago

Excellent. Now, that has set your RATs to 7,8,9 (Cat-M1, NBIoT and GPRS, in that order).

The next question is, which RATs do you require?

My recommendation, unless you specifically need it, is to leave out NBIoT or, if you really need it, to move it to the end. This is because a search of all of the NBIoT bands in the "airport" scenario (with no prior knowledge of the radio landscape) takes about 20 minutes, as the module has to search down into the noise. I suspect you don't want to wait that long.

Here is some code that will do that for you, which you may add after the code block you already have:

uCellNetRat_t rat[3];
// EDIT below: should be 10 and then 1 for LTE and then 2G; I had previously written 7 and 8, but those are the module RAT numbers, not the uCellNetRat_t numbers
uCellNetRat_t myRatList[] = {10, 1, U_CELL_NET_RAT_UNKNOWN_OR_NOT_USED};  // LTE, then 2G, then nothing

for (x = 0; x < 3; x++) {
    // Get the RAT at rank x
    rat[x] = uCellCfgGetRat(devHandle, x);
    if (rat[x] >= 0) {
        printf("RAT at rank %d is %d.\n", x, rat[x]);
        if (((myRatList[x] > U_CELL_NET_RAT_UNKNOWN_OR_NOT_USED) || (x > 0)) &&
            (myRatList[x] != rat[x])) {
            // The RAT at this rank is not what we wanted, so set it
            printf("Setting the RAT at rank %d to %d...\n", x, myRatList[x]);
            int32_t y = uCellCfgSetRatRank(devHandle, myRatList[x], x);
            if (y != 0) {
                printf("Unable to set RAT at rank %d to %d (error code y)!\n", x, myRatList[x], y);
            }
        }
    }
}

if (uCellPwrRebootIsRequired(devHandle)) {
    printf("Rebooting module.\n");
    uCellPwrReboot(devHandle, NULL);
}

Again, code not compiled by me, just a sketch to get you working, please adjust as necessary.

With all of this in place you will (a) have a global MNO profile and (b) have the RATs set as you wish. There is no harm in keeping all of this code in place, it will ensure that any module you use it on is set up correctly.

After all of that, you should try you original "new SIM" scenario again.

alexmaron81 commented 11 months ago

uCellCfgSetRatRank.txt

RobMeades commented 11 months ago

OK, so all of that has made no difference whatsoever (though we do know exactly where we are now).

Let me consult with someone from the module side who knows SARA-R412M and see if they can advise.

RobMeades commented 11 months ago

For information, how long does the code wait for registration to succeed?

alexmaron81 commented 11 months ago

Do you mean with someone who can already build successfully?

registration_to_succeed.txt

RobMeades commented 11 months ago

I mean, when you begin the registration attempt your code will set some sort of timeout before you decide it is not going to work and give up. What is that timeout?

alexmaron81 commented 11 months ago

image

RobMeades commented 11 months ago

Apologies, the engineer I just talked to pointed out that NBIoT is still enabled, so that could still be the cause of this problem. In the code I gave you above I had put the wrong numbers in the myRatList[] array: I had used the RAT numbering scheme from the module and not the uCellNetRat_t numbering scheme.

I have edited the code above to use the correct numbers (10 and 1). Please try again with that.

alexmaron81 commented 11 months ago

Thank you very much Rob, that was successful!

sucsessful_connected.txt

RobMeades commented 11 months ago

Phew! Apologies for wasting your time with the mis-step above. Gonna close this one now; please re-open if you think otherwise,