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

Unable to create HTTP instance! #251

Closed mos216 closed 1 week ago

mos216 commented 3 weeks ago

Hi,

running the sample assist_now_main.c causes error Unable to create HTTP instance! By debugging the error, I noticed that uCellHttpOpen in u_http_client.c returning error -4. this error occurs exactly at this macro U_CELL_HTTP_ENTRY_FUNCTION(cellHandle, -1, &pCellInstance, NULL, &errorCodeOrHandle); in u_cell_http.c

logs out

U_PORT_BOARD_CFG: using GNSS device "cfg-device-gnss" from the device tree, module-type 2 with pin-enable-power 38 (0x26), pin-data-ready -1 (0xffffffff)... U_PORT_BOARD_CFG: ...GNSS on UART 1, uart-baud-rate 38400. U_GNSS: initialising with ENABLE_POWER pin 38 (0x26), set to 1 to power on GNSS, transport type UART. U_GNSS: sent command b5 62 0a 06 00 00 10 3a. U_GNSS: decoded UBX response 0x0a 0x06: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [body 120 byte(s)]. U_GNSS: sent command b5 62 06 04 04 00 00 00 09 00 17 76. U_GNSS: sent command b5 62 0a 06 00 00 10 3a. U_GNSS: decoded UBX response 0x0a 0x06: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [body 120 byte(s)]. Opened GNSS device with return code 0. U_PORT_BOARD_CFG: using CELLULAR device "cfg-device-cellular" from the device tree, module-type 8 on UART 2, uart-baud-rate 115200 with pin-enable-power -1 (0xffffffff), pin-pwr-on 38 (0x26), pin-vint 39 (0x27), pin-dtr-power-saving -1 (0xffffffff). U_CELL: initialising with enable power pin not connected, PWR_ON pin 38 (0x26) (and is toggled from 1 to 0) and VInt pin 39 (0x27) (and is 1 when module is on). AT

OK U_CELL_PWR: powering on, module is already on. ATE0

OK AT+CMEE=2

OK AT+UDCONF=1,0

OK ATI9

02.00,A01.40

OK AT&C1

OK AT&D0

OK AT&K0

OK AT+UPSV=4,1300

OK AT+UGPRF?

+UGPRF:2,0,""

OK AT+CFUN=4

OK Opened HTTP device with return code 0. Bringing up the network for HTTP... U_PORT_BOARD_CFG: using CELLULAR network configuration associated with device "cfg-device-cellular" from the device tree, timeout-seconds 280, APN "iot.1nce.net", username "", password "", authentication-mode 0, MCC/MNC NULL, async-connect false, uart-ppp: NULL. U_CELL_NET: preparing to register/connect... AT+CREG=2

OK AT+CGREG=2

OK AT+CEREG=4

OK AT+CIMI

901405112793458

OK U_CELL_NET: user-specified APN is "iot.1nce.net". AT+CGDCONT=1,"IP","iot.1nce.net"

OK AT+UAUTHREQ=1,0,"",""

OK U_CELL_NET: setting automatic network selection mode... AT+COPS?

+COPS: 0

OK AT+CFUN=1

OK AT+CREG?

+CREG: 0,"0000","0000",0

OK -1: NReg AT+CGREG?

+CGREG: 2,0,"0000","0000"

OK -1: NReg AT+CEREG?

+CEREG: 4,0,"0000","00000000", 0,0,0,"00000000","00000000"

OK -1: NReg

+CREG: 5,"546e","01937303",7

+CEREG: 5,"546e","01937303",7

+CREG: 5,"546E","0193"

+CGREG:7: RegR 7: RegR 0: RegR 0,"0000","0000" -1: NReg AT+COPS=3,0

OK AT+COPS?

+COPS: 0,0,"vodafone NL",7

OK AT+CGATT?

+CGATT:1

OK AT+CGACT?

+CGACT: 0,1

OK AT+CGACT=1,1

OK AT+CGACT?

+CGACT: 1,1

OK AT+CEER

+CEER:No Error Call

OK U_CELL_NET: connected after 8 second(s). AT+CGACT?

+CGACT: 1,1

OK AT+CGPADDR=1

+CGPADDR: 1,"10.42.63.5"

OK U_CELL_NET: IP address "10.42.63.5". AT+CGCONTRDP=1

+CGCONTRDP: 1,5,"iot.1nce.net.mnc040.mcc901.gprs","0.0.0.0.0.0.0.0"

OK U_CELL_NET: unable to read DNS addresses. AT+USECPRF=0

+CREG OK AT+USECPRF=0,0,0

OK AT+USECPRF=0,10,"online-live1.services.u-blox.com"

OK Unable to create HTTP instance! Taking down network... AT

OK AT+COPS?

+COPS: 0,0,"vodafone NL",7

OK AT+CFUN=4

OK

+CREG: 0,"0000","0000",0

+CEREG: 0,"0000","00000000", 0,,,"00000000","00000000"

+CREG: 0,"0000","0000"

+CGREG: 0,"0000","0000" -1: NReg -1: NReg -1: NReg -1: NReg AT+CREG?

+CREG: 0,"0000","0000",0

OK -1: NReg AT+CGREG?

+CGREG: 2,0,"0000","0000"

OK -1: NReg AT+CEREG?

+CEREG: 4,0,"0000","00000000", 0,0,0,"00000000","00000000"

OK -1: NReg AT+CGATT?

+CGATT:0

OK -1: NReg U_CELL_NET: disconnected. AT+CEER

+CEER:No Error Call

OK Done.

RobMeades commented 3 weeks ago

Hi again: unfortunately ubxlib does not support HTTP on LENA-R8 (-4 is U_ERROR_COMMON_NOT_SUPPORTED). The LENA-R8 HTTP interface doesn't work the same way as every other u-blox module HTTP interface; for instance, should the HTTP server respond with a non-2xx error code, the module does not save the response to file (in fact it leaves any previous response file there, unchanged) and returns an error at the HTTP interface rather than success, which makes it impossible for ubxlib to determine the HTTP response code in any failure case.

There are more notes about the limitations of LENA-R8 here:

https://github.com/u-blox/ubxlib/releases/tag/v1.4.0

Sorry for the misdirection, I will add notes to the HTTP example and on the HTTP interfaces to say that they will not work with LENA-R8 in the hope of avoiding future confusion.

mos216 commented 3 weeks ago

Hi thanks again for your reply. in this case what is the best way to get Assis-now working on LENA. currently I'm using mqtt with AWS IoT.

RobMeades commented 3 weeks ago

A few options:

  1. Use the native Zephyr IP stack and its HTTP: to do this you would follow the instructions here; basically define U_CFG_PPP_ENABLE when compiling ubxlib, add a few flags to your prj.conf file and add a zephyr,ppp-uart entry to your .overlay file. With this done, after uNetworkInterfaceUp(), you should have native connectivity to the cellular network from within Zephyr. Ignore the caveats about usernames/passwords and CHAP authentication, 1NCE doesn't need those (we use 1NCE SIMs here in our test system).
  2. Do the HTTP operation inside AWS and pass the results to an MQTT topic that the LENA-R8 MQTT client can subscribe to; I don't know whether you have enough capability at the AWS end to do this or not.
  3. It might be possible to get the AssistNow information over MQTT; I'm still trying to bottom-out whether I've understood the answer I was given correctly, or whether the person being asked understood the question correctly. I will get back to you on this.
RobMeades commented 3 weeks ago

Right then, on (3): you have an AssistNow access token, and therefore a Thingstream account from which you obtained that. In the Thingstream account you will see a Data Flow Manager. Using this it is possible, and I quote, to set up "a flow with an assist now node which is deployed to a topic the device publishes to which then publishes the response to another MQTT topic that the device is subscribed to". What I think this means is that an MQTT publish will trigger, in the back-end, an HTTP request to AssistNow and you can subscribe to an MQTT topic to obtain the response.

I've never used the flow manager myself, but it is described here:

https://developer.thingstream.io/guides/location-services/assistnow-getting-started-guide

...including a video demo.

It might be that this way you can do everything you need over Thingstream MQTT.

RobMeades commented 3 weeks ago

Hopefully improved documentation of the limitations of LENA-R8 in ba0a0f17cbd3028dfa2097decccd48458e08b021.

mos216 commented 3 weeks ago

Hi Rob, Thanks again for the info. I started with first suggestion to implement zephyr IP stack but I got strange error regarding

uart2: uart-ppp@8000 {
    compatible = "u-blox,uart-ppp";
    reg = <0x8000  0x1000>;
    status = "okay";
};

I'm using nrf5340, so I'm not sure about the right configuration in dts.

devicetree error: Label 'uart2' appears on /soc/peripheral@50000000/uart@b000 and on /uart-ppp@8000

I didn't try the mqtt but I was wondering about IP stack first.

mos216 commented 3 weeks ago

Another question regarding the second suggestion: after receiving the location data by mqtt, how can this data be transferred to GNSS since it is connected directly to the MCU?

RobMeades commented 3 weeks ago

devicetree error: Label 'uart2' appears on /soc/peripheral@50000000/uart@b000 and on /uart-ppp@8000

I think you just need to invent a label that doesn't appear anywhere else: in our case I used uart99. The label is only used in the chosen statement:

chosen {
        zephyr,ppp-uart = &uart99;
    };

...so you can use whatever you like, just not one that conflicts.

after receiving the location data by mqtt, how can this data be transferred to GNSS since it is connected directly to the MCU?

The data you get back from the AssistNow service is purely a set of pre-encoded UBX format binary messages that can just be fired at the GNSS chip with uGnssMgaResponseSend(). Whether this arrives in the body of an HTTP response or is brought down via MQTT doesn't matter, it is just a blob of binary data. See also the assist_now_main.c example.

mos216 commented 2 weeks ago

Hi Rob, Finally, I could get PPP working in Zephyr, thanks to you, of course. But now I have two questions.

RobMeades commented 2 weeks ago

Phew! Some progress, that's good. One thing to keep in mind, if I've not said it already, is that since PPP is a framed protocol, and it will be running over CMUX, which is also a framed protocol, the UART link will be critically sensitive to data loss: i.e. if you lose one byte then an entire frame will go and the MCU may no longer be able to communicate with the module. So, in your final application, make sure to connect the UART flow control lines between the MCU and the module.

On your questions, Cloud Locate relies on cell parameters but AssistNow does not: when you use AssistNow you can see in our AT logs a pure HTTP GET request is assembled, along the lines of:

GetOnlineData.ashx?token=xxxxxxxxxxxx;gnss=gps;datatype=eph;latency=0;tacc=0

...to get the ephemeris data for GPS only. But yes, the Cloud Locate and Cell Locate services do require cell tower data that the UPOS entity within the cellular-side of the LENA-R8xxxM10 module obtains and sends to the u-blox server. However, those services don't require GNSS, the whole point is that they can work without it, though of course they will only give position to within the size of a cell (hundreds of metres) in that case. To use Cloud Locate/Cell Locate without GNSS you would need to call uCellLocSetGnssEnable() with false (once) before doing the Cloud Locate or Cell Locate position requests. We have probably not used ubxlib in this configuration before so, when you do this we should check the AT log to see if ubxlib hasn't snuck in a AT+UGPS=1,xxx command to power up the GNSS chip (which would cause UPOS to start chattering to it) as a side-effect.

On the IP stack, the Zephyr one is quite new and there are a lot of things that seem to need tuning in it, while the one inside the u-blox modem is quite old and relatively well tested. In terms of speed, difficult to say: usually the PPP approach is faster, since the AT interface is a bit of a ping-pong clunky kind of thing, but with the approach we have to take to make Zephyr work with PPP my guess (and it is only a guess) is that the AT interface is probably faster.

RobMeades commented 1 week ago

Going to close this one now as I think we have concluded: please feel free to re-open it, or open a new issue, if there is more to discuss.