Implementation of the CellularInterface for u-blox C030 boards with N2xx modems. Note: requires the N211 module firmware to be at least 06.57 A01.02.
Dependents: example-ublox-cellular-interface HelloMQTT example-ublox-cellular-interface_r410M example-ublox-mbed-client ... more
UbloxATCellularInterfaceN2xx.h
00001 /* Copyright (c) 2017 ARM Limited 00002 * 00003 * Licensed under the Apache License, Version 2.0 (the "License"); 00004 * you may not use this file except in compliance with the License. 00005 * You may obtain a copy of the License at 00006 * 00007 * http://www.apache.org/licenses/LICENSE-2.0 00008 * 00009 * Unless required by applicable law or agreed to in writing, software 00010 * distributed under the License is distributed on an "AS IS" BASIS, 00011 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 * See the License for the specific language governing permissions and 00013 * limitations under the License. 00014 */ 00015 00016 #ifndef _UBLOX_AT_CELLULAR_INTERFACE_N2XX_ 00017 #define _UBLOX_AT_CELLULAR_INTERFACE_N2XX_ 00018 00019 #include "UbloxCellularBaseN2xx.h" 00020 #include "CellularBase.h" 00021 #include "NetworkStack.h" 00022 00023 /** UbloxATCellularInterface class. 00024 * 00025 * This uses the cellular-tuned IP stack that 00026 * is on-board the cellular modem instead of the 00027 * LWIP stack on the mbed MCU. 00028 * 00029 * There are three advantages to using this mechanism: 00030 * 00031 * 1. Since the modem interface remains in AT mode 00032 * throughout, it is possible to continue using 00033 * any AT commands (e.g. send SMS, use the module's 00034 * file system, etc.) while the connection is up. 00035 * 00036 * 2. The UbloxATCellularInterfaceExt class can 00037 * be used to perform very simple HTTP and FTP 00038 * operations using the modem's on-board clients. 00039 * 00040 * 3. LWIP is not required (and hence RAM is saved). 00041 * 00042 * The disadvantage is that some additional parsing 00043 * (at the AT interface) has to go on in order to exchange 00044 * IP packets, so this is less efficient under heavy loads. 00045 * Also TCP Server and getting/setting of socket options is 00046 * currently not supported. 00047 */ 00048 00049 // Forward declaration 00050 class NetworkStack; 00051 00052 /* 00053 * NOTE: order is important in the inheritance below! PAL takes this class 00054 * and casts it to CellularInterface and so CellularInterface has to be first 00055 * in the last for that to work. 00056 */ 00057 00058 /** UbloxATCellularInterface class. 00059 * 00060 * This class implements the network stack interface into the cellular 00061 * modems on the C030 and C027 boards for 2G/3G/4G modules using 00062 * the IP stack running on the cellular module. 00063 */ 00064 class UbloxATCellularInterfaceN2xx : public CellularBase, public NetworkStack, virtual public UbloxCellularBaseN2xx { 00065 00066 public: 00067 00068 /** Constructor. 00069 * 00070 * @param tx the UART TX data pin to which the modem is attached. 00071 * @param rx the UART RX data pin to which the modem is attached. 00072 * @param baud the UART baud rate. 00073 * @param debug_on true to switch AT interface debug on, otherwise false. 00074 */ 00075 UbloxATCellularInterfaceN2xx(PinName tx = MDMTXD, 00076 PinName rx = MDMRXD, 00077 int baud = MBED_CONF_UBLOX_CELL_N2XX_BAUD_RATE, 00078 bool debug_on = false); 00079 00080 /* Destructor. 00081 */ 00082 virtual ~UbloxATCellularInterfaceN2xx(); 00083 00084 /** The amount of extra space needed in terms of AT interface 00085 * characters to get a chunk of user data (i.e. one UDP packet 00086 * or a portion of a TCP packet) across the AT interface. 00087 */ 00088 #define AT_PACKET_OVERHEAD 77 00089 00090 /** The profile to use (on board the modem). 00091 */ 00092 #define PROFILE "0" 00093 00094 /** Translates a host name to an IP address with specific IP version. 00095 * 00096 * The host name may be either a domain name or an IP address. If the 00097 * host name is an IP address, no network transactions will be performed. 00098 * 00099 * If no stack-specific DNS resolution is provided, the host name 00100 * will be resolved using a UDP socket on the stack. 00101 * 00102 * @param host Host name to resolve. 00103 * @param address Destination for the host SocketAddress. 00104 * @param version IP version of address to resolve, NSAPI_UNSPEC indicates 00105 * version is chosen by the stack (defaults to NSAPI_UNSPEC). 00106 * @return 0 on success, negative error code on failure. 00107 */ 00108 virtual nsapi_error_t gethostbyname(const char *host, 00109 SocketAddress *address, 00110 nsapi_version_t version = NSAPI_UNSPEC); 00111 00112 /** Set the authentication scheme. 00113 * 00114 * @param auth The authentication scheme, chose from 00115 * NSAPI_SECURITY_NONE, NSAPI_SECURITY_PAP, 00116 * NSAPI_SECURITY_CHAP or NSAPI_SECURITY_UNKNOWN; 00117 * use NSAPI_SECURITY_UNKNOWN to try all of none, 00118 * PAP and CHAP. 00119 */ 00120 virtual void set_authentication(nsapi_security_t auth); 00121 00122 /** Set the cellular network credentials. 00123 * 00124 * Please check documentation of connect() for default behaviour of APN settings. 00125 * 00126 * @param apn Access point name. 00127 * @param uname Optionally, user name. 00128 * @param pwd Optionally, password. 00129 */ 00130 virtual void set_credentials(const char *apn, const char *uname = 0, 00131 const char *pwd = 0); 00132 00133 /** Set the PIN code for the SIM card. 00134 * 00135 * @param sim_pin PIN for the SIM card. 00136 */ 00137 virtual void set_sim_pin(const char *sim_pin); 00138 00139 /** Set the local listen port when opening a UDP socket 00140 * 00141 */ 00142 void set_LocalListenPort(int port); 00143 00144 /** 00145 * Turns on the modem and reads the module information 00146 */ 00147 bool initialise(); 00148 00149 /** Connect to the cellular network and start the interface. 00150 * 00151 * Attempts to connect to a cellular network. Note: if initialise() has 00152 * not been called beforehand, connect() will call it first. 00153 * 00154 * @param sim_pin PIN for the SIM card. 00155 * @param apn Optionally, access point name. 00156 * @param uname Optionally, user name. 00157 * @param pwd Optionally, password. 00158 * @return NSAPI_ERROR_OK on success, or negative error code on failure. 00159 */ 00160 virtual nsapi_error_t connect(const char *sim_pin, const char *apn = 0, 00161 const char *uname = 0, const char *pwd = 0); 00162 00163 /** Attempt to connect to the cellular network. 00164 * 00165 * Brings up the network interface. Connects to the cellular radio 00166 * network and then brings up IP stack on the cellular modem to be used 00167 * indirectly via AT commands, rather than LWIP. Note: if init() has 00168 * not been called beforehand, connect() will call it first. 00169 * NOTE: even a failed attempt to connect will cause the modem to remain 00170 * powered up. To power it down, call deinit(). 00171 * 00172 * For APN setup, default behaviour is to use 'internet' as APN string 00173 * and assuming no authentication is required, i.e., user name and password 00174 * are not set. Optionally, a database lookup can be requested by turning 00175 * on the APN database lookup feature. The APN database is by no means 00176 * exhaustive (feel free to submit a pull request with additional values). 00177 * It contains a short list of some public APNs with publicly available 00178 * user names and passwords (if required) in some particular countries only. 00179 * Lookup is done using IMSI (International mobile subscriber identifier). 00180 * 00181 * The preferred method is to setup APN using 'set_credentials()' API. 00182 * 00183 * If you find that the AT interface returns "CONNECT" but shortly afterwards 00184 * drops the connection then 99% of the time this will be because the APN 00185 * is incorrect. 00186 * 00187 * @return 0 on success, negative error code on failure. 00188 */ 00189 virtual nsapi_error_t connect(); 00190 00191 /** Attempt to disconnect from the network. 00192 * 00193 * Brings down the network interface. 00194 * Does not bring down the Radio network. 00195 * 00196 * @return 0 on success, negative error code on failure. 00197 */ 00198 virtual nsapi_error_t disconnect(); 00199 00200 /** Adds or removes a SIM facility lock. 00201 * 00202 * Can be used to enable or disable SIM PIN check at device startup. 00203 * 00204 * @param set Can be set to true if the SIM PIN check is supposed 00205 * to be enabled and vice versa. 00206 * @param immediate If true, change the SIM PIN now, else set a flag 00207 * and make the change only when connect() is called. 00208 * If this is true and init() has not been called previously, 00209 * it will be called first. 00210 * @param sim_pin The current SIM PIN, must be a const. If this is not 00211 * provided, the SIM PIN must have previously been set by a 00212 * call to set_sim_pin(). 00213 * @return 0 on success, negative error code on failure. 00214 */ 00215 nsapi_error_t set_sim_pin_check(bool set, bool immediate = false, 00216 const char *sim_pin = NULL); 00217 00218 /** Change the PIN for the SIM card. 00219 * 00220 * Provide the new PIN for your SIM card with this API. It is ONLY possible to 00221 * change the SIM PIN when SIM PIN checking is ENABLED. 00222 * 00223 * @param new_pin New PIN to be used in string format, must be a const. 00224 * @param immediate If true, change the SIM PIN now, else set a flag 00225 * and make the change only when connect() is called. 00226 * If this is true and init() has not been called previously, 00227 * it will be called first. 00228 * @param old_pin Old PIN, must be a const. If this is not provided, the SIM PIN 00229 * must have previously been set by a call to set_sim_pin(). 00230 * @return 0 on success, negative error code on failure. 00231 */ 00232 nsapi_error_t set_new_sim_pin(const char *new_pin, bool immediate = false, 00233 const char *old_pin = NULL); 00234 00235 /** Check if the connection is currently established or not. 00236 * 00237 * @return True if connected to a data network, otherwise false. 00238 */ 00239 virtual bool is_connected(); 00240 00241 /** Get the local IP address 00242 * 00243 * @return Null-terminated representation of the local IP address 00244 * or null if no IP address has been received. 00245 */ 00246 virtual const char *get_ip_address(); 00247 00248 /** Get the local network mask. 00249 * 00250 * @return Null-terminated representation of the local network mask 00251 * or null if no network mask has been received. 00252 */ 00253 virtual const char *get_netmask(); 00254 00255 /** Get the local gateways. 00256 * 00257 * @return Null-terminated representation of the local gateway 00258 * or null if no network mask has been received. 00259 */ 00260 virtual const char *get_gateway(); 00261 00262 /** Set the plmn. PLMN controls to what network device registers. 00263 * 00264 * @param plmn user to force what network to register. 00265 */ 00266 virtual void set_plmn(const char *plmn); 00267 00268 /** Call back in case connection is lost. 00269 * 00270 * @param cb The function to call. 00271 */ 00272 void connection_status_cb(Callback<void(nsapi_error_t)> cb); 00273 00274 protected: 00275 00276 /** Socket "unused" value. 00277 */ 00278 #define SOCKET_UNUSED -1 00279 00280 /** Socket timeout value in milliseconds. 00281 * Note: the sockets layer above will retry the 00282 * call to the functions here when they return NSAPI_ERROR_WOULD_BLOCK 00283 * and the user has set a larger timeout or full blocking. 00284 */ 00285 #define SOCKET_TIMEOUT 1000 00286 00287 /** The maximum number of bytes in a packet that can be written 00288 * to the AT interface in one go. 00289 */ 00290 #define MAX_WRITE_SIZE_N2XX 512 00291 00292 /** The maximum number of bytes in a packet that can be read from 00293 * from the AT interface in one go. 00294 */ 00295 #define MAX_READ_SIZE_N2XX 512 00296 00297 /** Management structure for sockets. 00298 */ 00299 typedef struct { 00300 int modem_handle; //!< The modem's handle for the socket. 00301 volatile nsapi_size_t pending; //!< The number of received bytes pending. 00302 void (*callback)(void *); //!< A callback for events. 00303 void *data; //!< A data pointer that must be passed to the callback. 00304 } SockCtrl; 00305 00306 /** Sockets storage. 00307 */ 00308 SockCtrl _sockets[7]; 00309 00310 /** Storage for a single IP address. 00311 */ 00312 char *_ip; 00313 00314 /** The APN to use. 00315 */ 00316 const char *_apn; 00317 00318 /** The user name to use. 00319 */ 00320 const char *_uname; 00321 00322 /** The password to use. 00323 */ 00324 const char *_pwd; 00325 00326 /** The type of authentication to use. 00327 */ 00328 nsapi_security_t _auth; 00329 00330 /** Get the next set of credentials from the database. 00331 */ 00332 virtual void get_next_credentials(const char * config); 00333 00334 /** Provide access to the NetworkStack object 00335 * 00336 * @return The underlying NetworkStack object. 00337 */ 00338 virtual NetworkStack *get_stack(); 00339 00340 protected: 00341 00342 /** Open a socket. 00343 * 00344 * Creates a network socket and stores it in the specified handle. 00345 * The handle must be passed to following calls on the socket. 00346 * 00347 * @param handle Destination for the handle to a newly created socket. 00348 * @param proto Protocol of socket to open, NSAPI_TCP or NSAPI_UDP. 00349 * @return 0 on success, negative error code on failure. 00350 */ 00351 virtual nsapi_error_t socket_open(nsapi_socket_t *handle, 00352 nsapi_protocol_t proto); 00353 00354 /** Close a socket. 00355 * 00356 * Closes any open connection and deallocates any memory associated 00357 * with the socket. 00358 * 00359 * @param handle Socket handle. 00360 * @return 0 on success, negative error code on failure. 00361 */ 00362 virtual nsapi_error_t socket_close(nsapi_socket_t handle); 00363 00364 /** Bind a specific port to a socket. 00365 * 00366 * Binding a socket specifies port on which to receive 00367 * data. The IP address is ignored. Note that binding 00368 * a socket involves closing it and reopening and so the 00369 * bind operation should be carried out before any others. 00370 * 00371 * @param handle Socket handle. 00372 * @param address Local address to bind (of which only the port is used). 00373 * @return 0 on success, negative error code on failure. 00374 */ 00375 virtual nsapi_error_t socket_bind(nsapi_socket_t handle, 00376 const SocketAddress &address); 00377 00378 /** Connects TCP socket to a remote host. 00379 * 00380 * Initiates a connection to a remote server specified by the 00381 * indicated address. 00382 * 00383 * @param handle Socket handle. 00384 * @param address The SocketAddress of the remote host. 00385 * @return 0 on success, negative error code on failure. 00386 */ 00387 virtual nsapi_error_t socket_connect(nsapi_socket_t handle, 00388 const SocketAddress &address); 00389 00390 /** Send data over a TCP socket. 00391 * 00392 * The socket must be connected to a remote host. Returns the number of 00393 * bytes sent from the buffer. This class sets no upper buffer limit on 00394 * buffer size and the maximum packet size is not connected with the 00395 * platform.buffered-serial-txbuf-size/platform.buffered-serial-rxbuf-size 00396 * definitions. 00397 * 00398 * @param handle Socket handle. 00399 * @param data Buffer of data to send to the host. 00400 * @param size Size of the buffer in bytes. 00401 * @return Number of sent bytes on success, negative error 00402 * code on failure. 00403 */ 00404 virtual nsapi_size_or_error_t socket_send(nsapi_socket_t handle, 00405 const void *data, nsapi_size_t size); 00406 00407 /** Send a packet over a UDP socket. 00408 * 00409 * Sends data to the specified address. Returns the number of bytes 00410 * sent from the buffer. 00411 * 00412 * PACKET SIZES: the maximum packet size that can be sent in a single 00413 * UDP packet is limited by the configuration value 00414 * platform.buffered-serial-txbuf-size (defaults to 256). 00415 * The maximum UDP packet size is: 00416 * 00417 * platform.buffered-serial-txbuf-size - AT_PACKET_OVERHEAD 00418 * 00419 * ...with a limit of 1024 bytes (at the AT interface). So, to allow sending 00420 * of a 1024 byte UDP packet, edit your mbed_app.json to add a target override 00421 * setting platform.buffered-serial-txbuf-size to 1101. However, for 00422 * UDP packets, 508 bytes is considered a more realistic size, taking into 00423 * account fragmentation sizes over the public internet, which leads to a 00424 * platform.buffered-serial-txbuf-size/platform.buffered-serial-rxbuf-size 00425 * setting of 585. 00426 * 00427 * If size is larger than this limit, the data will be split across separate 00428 * UDP packets. 00429 * 00430 * @param handle Socket handle. 00431 * @param address The SocketAddress of the remote host. 00432 * @param data Buffer of data to send to the host. 00433 * @param size Size of the buffer in bytes. 00434 * @return Number of sent bytes on success, negative error 00435 * code on failure. 00436 */ 00437 virtual nsapi_size_or_error_t socket_sendto(nsapi_socket_t handle, 00438 const SocketAddress &address, 00439 const void *data, 00440 nsapi_size_t size); 00441 00442 /** Receive data over a TCP socket. 00443 * 00444 * The socket must be connected to a remote host. Returns the number of 00445 * bytes received into the buffer. This class sets no upper limit on the 00446 * buffer size and the maximum packet size is not connected with the 00447 * platform.buffered-serial-txbuf-size/platform.buffered-serial-rxbuf-size 00448 * definitions. 00449 * 00450 * @param handle Socket handle. 00451 * @param data Destination buffer for data received from the host. 00452 * @param size Size of the buffer in bytes. 00453 * @return Number of received bytes on success, negative error 00454 * code on failure. 00455 */ 00456 virtual nsapi_size_or_error_t socket_recv(nsapi_socket_t handle, 00457 void *data, nsapi_size_t size); 00458 00459 /** Receive a packet over a UDP socket. 00460 * 00461 * Receives data and stores the source address in address if address 00462 * is not NULL. Returns the number of bytes received into the buffer. 00463 * 00464 * PACKET SIZES: the maximum packet size that can be retrieved in a 00465 * single call to this method is limited by the configuration value 00466 * platform.buffered-serial-rxbuf-size (default 256). The maximum 00467 * UDP packet size is: 00468 * 00469 * platform.buffered-serial-rxbuf-size - AT_PACKET_OVERHEAD 00470 * 00471 * ...with a limit of 1024 (at the AT interface). So to allow reception of a 00472 * 1024 byte UDP packet in a single call, edit your mbed_app.json to add a 00473 * target override setting platform.buffered-serial-rxbuf-size to 1101. 00474 * 00475 * If the received packet is larger than this limit, any remainder will 00476 * be returned in subsequent calls to this method. Once a single UDP 00477 * packet has been received, this method will return. 00478 * 00479 * @param handle Socket handle. 00480 * @param address Destination for the source address or NULL. 00481 * @param data Destination buffer for data received from the host. 00482 * @param size Size of the buffer in bytes. 00483 * @return Number of received bytes on success, negative error 00484 * code on failure. 00485 */ 00486 virtual nsapi_size_or_error_t socket_recvfrom(nsapi_socket_t handle, 00487 SocketAddress *address, 00488 void *data, nsapi_size_t size); 00489 00490 /** Register a callback on state change of the socket. 00491 * 00492 * The specified callback will be called on state changes such as when 00493 * the socket can recv/send/accept successfully and on when an error 00494 * occurs. The callback may also be called spuriously without reason. 00495 * 00496 * The callback may be called in an interrupt context and should not 00497 * perform expensive operations such as recv/send calls. 00498 * 00499 * @param handle Socket handle. 00500 * @param callback Function to call on state change. 00501 * @param data Argument to pass to callback. 00502 */ 00503 virtual void socket_attach(nsapi_socket_t handle, void (*callback)(void *), 00504 void *data); 00505 00506 /** Listen for connections on a TCP socket. 00507 * 00508 * Marks the socket as a passive socket that can be used to accept 00509 * incoming connections. 00510 * 00511 * @param handle Socket handle. 00512 * @param backlog Number of pending connections that can be queued 00513 * simultaneously, defaults to 1. 00514 * @return 0 on success, negative error code on failure. 00515 */ 00516 virtual nsapi_error_t socket_listen(nsapi_socket_t handle, int backlog); 00517 00518 /** Accepts a connection on a TCP socket. 00519 * 00520 * The server socket must be bound and set to listen for connections. 00521 * On a new connection, creates a network socket and stores it in the 00522 * specified handle. The handle must be passed to following calls on 00523 * the socket. 00524 * 00525 * A stack may have a finite number of sockets, in this case 00526 * NSAPI_ERROR_NO_SOCKET is returned if no socket is available. 00527 * 00528 * This call is non-blocking. If accept would block, 00529 * NSAPI_ERROR_WOULD_BLOCK is returned immediately. 00530 * 00531 * @param server Socket handle to server to accept from. 00532 * @param handle Destination for a handle to the newly created socket. 00533 * @param address Destination for the remote address or NULL. 00534 * @return 0 on success, negative error code on failure. 00535 */ 00536 virtual nsapi_error_t socket_accept(nsapi_socket_t server, 00537 nsapi_socket_t *handle, 00538 SocketAddress *address = 0); 00539 00540 /** Set stack-specific socket options. 00541 * 00542 * The setsockopt allow an application to pass stack-specific hints 00543 * to the underlying stack. For unsupported options, 00544 * NSAPI_ERROR_UNSUPPORTED is returned and the socket is unmodified. 00545 * 00546 * @param handle Socket handle. 00547 * @param level Stack-specific protocol level. 00548 * @param optname Stack-specific option identifier. 00549 * @param optval Option value. 00550 * @param optlen Length of the option value. 00551 * @return 0 on success, negative error code on failure. 00552 */ 00553 virtual nsapi_error_t setsockopt(nsapi_socket_t handle, int level, 00554 int optname, const void *optval, 00555 unsigned optlen); 00556 00557 /** Get stack-specific socket options. 00558 * 00559 * The getstackopt allow an application to retrieve stack-specific hints 00560 * from the underlying stack. For unsupported options, 00561 * NSAPI_ERROR_UNSUPPORTED is returned and optval is unmodified. 00562 * 00563 * @param handle Socket handle. 00564 * @param level Stack-specific protocol level. 00565 * @param optname Stack-specific option identifier. 00566 * @param optval Destination for option value. 00567 * @param optlen Length of the option value. 00568 * @return 0 on success, negative error code on failure. 00569 */ 00570 virtual nsapi_error_t getsockopt(nsapi_socket_t handle, int level, 00571 int optname, void *optval, 00572 unsigned *optlen); 00573 00574 private: 00575 00576 // u_ added to namespace us somewhat as this darned macro 00577 // is defined by everyone and their dog 00578 #define u_stringify(a) str(a) 00579 #define str(a) #a 00580 00581 int _localListenPort; 00582 00583 bool _sim_pin_check_change_pending; 00584 bool _sim_pin_check_change_pending_enabled_value; 00585 bool _sim_pin_change_pending; 00586 const char *_sim_pin_change_pending_new_pin_value; 00587 Thread event_thread; 00588 void handle_event(); 00589 SockCtrl * find_socket(int modem_handle = SOCKET_UNUSED); 00590 void clear_socket(SockCtrl * socket); 00591 bool check_socket(SockCtrl * socket); 00592 00593 nsapi_size_or_error_t receivefrom(int socketId, SocketAddress *address, int length, char *buf); 00594 nsapi_size_or_error_t sendto(SockCtrl *socket, const SocketAddress &address, const char *buf, int size); 00595 bool sendATChopped(const char *); 00596 00597 char hex_char(char c); 00598 int hex_to_bin(const char* s, char * buff, int length); 00599 void bin_to_hex(const char *buff, unsigned int length, char *output); 00600 00601 Callback<void(nsapi_error_t)> _connection_status_cb; 00602 void NSONMI_URC(); 00603 }; 00604 00605 #endif // _UBLOX_AT_CELLULAR_INTERFACE_ 00606
Generated on Thu Jul 14 2022 07:10:25 by
