Skip to content

drivers: modem_cellular: Automatic APN detection support #93390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

petrosyan-van
Copy link
Contributor

This PR adds run‑time APN selection to the cellular driver and the logic that programs the chosen APN into the modem before the normal dial sequence starts.

Highlights

  • New Kconfig options

    • CONFIG_MODEM_CELLULAR_AUTO_APN – enables the feature
    • CONFIG_MODEM_CELLULAR_AUTO_APN_PROFILES – string table mapping MCC/MNC codes to APNs (same as used in drivers/modem/ublox‑sara‑r4.c)
  • APN detection flow

    • After IMSI is read, the driver performs a six‑digit, then a five‑digit MCC/MNC lookup in the profiles table.
    • On a hit, the detected APN overwrites the static one; on a miss, the static APN is preserved.
  • Dynamic “set APN” chat script

    • Introduces a new driver state RUN_APN_SCRIPT inserted between open DLCI2 and run dial script.
    • modem_cellular_build_apn_script() builds the chat script at run time using buffers that already exist in struct modem_cellular_data.
    • Every modem executes AT+CGDCONT=1,"IP","". Sierra Wireless HL7800 additionally receives AT+KCNXCFG=1,"GPRS","",,,"IPV4" (added via DT compat guard).
    • On script success we move to run dial script
    • On failure we continue repeating?
  • Testing

    • Evaluated on a Quectel BG95 with Swisscom and Emnify SIMs; both boot to PPP with the correct APN.

I used this commit: fdd89ef from @hwilmers as inspiration.

My solution is not as elegant at all, as I couldn't find a really good way to handle the dynamic script build. i saw several discussions previously regarding this topic and some attempts to implement this feature, but for some reason the idea was dropped, perhaps due to the solution not being scalable. I found this discussion and PR here:

#67626
#67776

Nevertheless, I think this feature is important as it removes the need for per‑carrier firmware variants, which is a major practical gain. Feedback on improving scalability or restructuring the builder is highly appreciated :)

Note: Would be great to test the solution on other modems, especially on HL7800, which has 2 steps for APN script. Any help there would be great!

@petrosyan-van petrosyan-van force-pushed the modem_cellular_auto_apn branch 6 times, most recently from 3b2d190 to 3e9240b Compare July 21, 2025 08:51
* Add CONFIG_MODEM_CELLULAR_AUTO_APN and
  CONFIG_MODEM_CELLULAR_AUTO_APN_PROFILES Kconfig options.
* Detect APN from IMSI (MCC/MNC) and select profile at run‑time.
* Build APN SET script dynamically:
  - Always sends AT+CGDCONT=1,"IP","<apn>"
  - Adds AT+KCNXCFG for HL7800.
* Insert new MODEM_CELLULAR_STATE_RUN_APN_SCRIPT before the dial
  script to apply either the static or detected APN.
* Remove hard‑coded APN commands from dial scripts; all modems now
  share the common builder.

Signed-off-by: Van Petrosyan <[email protected]>
@petrosyan-van petrosyan-van force-pushed the modem_cellular_auto_apn branch from 3e9240b to 0586cde Compare July 21, 2025 09:53
@petrosyan-van petrosyan-van marked this pull request as ready for review July 21, 2025 10:16
@zephyrbot zephyrbot requested a review from rerickson1 July 21, 2025 10:17
Copy link

@jeffwelder-ellenbytech
Copy link
Contributor

This is really interesting!

A while ago I made some brute force edits to the modem_cellular state machine on a fork to switch between a primary and secondary APN with the cellular.h api to switch between a primary and secondary chat script.
(mpenate-ellenbytech@cd216ae)

Couple other bg95 goodies I never got time to implement are here:
https://github.com/mpenate-ellenbytech/zephyr/commits/v3.7.99-eti?author=jeffwelder-ellenbytech

@petrosyan-van
Copy link
Contributor Author

petrosyan-van commented Jul 21, 2025

This is really interesting!

A while ago I made some brute force edits to the modem_cellular state machine on a fork to switch between a primary and secondary APN with the cellular.h api to switch between a primary and secondary chat script. (mpenate-ellenbytech@cd216ae)

Couple other bg95 goodies I never got time to implement are here: https://github.com/mpenate-ellenbytech/zephyr/commits/v3.7.99-eti?author=jeffwelder-ellenbytech

Thanks for the feedback! You have some interesting stuff there :)
Would be great if you can get some of your improvements merged at some point, especially the Network Tower info. This is something that I actually need in my project :D

I've been also focused on BG95 improvements recently. Funny enough some things we did are matching, like those:
#93068
#93072

Copy link
Contributor

@bjarki-andreasen bjarki-andreasen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of making this a hardcoded part of a single cellular driver, I would highly recommend extending the cellular.h API with an entry like

int cellular_set_apn(const struct device *dev, const char *apn);

and allowing the application to store the list of APNs it knows of, either statically or dynamically (up to the application).
To know which APN to set, the application can already get IMSI itself using

static inline int cellular_get_modem_info(const struct device *dev,
const enum cellular_modem_info_type type, char *info,
size_t size)
and do whatever lookup it needs :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants