Example program that uses the mbed UbloxATCellularInterface or OnboardCellularInterface classes to perform simple sockets operations. This program can be used on the C027 and C030 boards, including the C030 N2xx version with a little editing.

Dependencies:   ublox-at-cellular-interface ublox-cellular-base ublox-cellular-base-n2xx ublox-at-cellular-interface-n2xx

Committer:
RobMeades
Date:
Wed Jun 14 09:28:20 2017 +0000
Revision:
8:3e170c40a284
Parent:
5:bf352de1d3e5
Child:
10:1f35371d572d
Example now encompasses PPP cellular interface as well as AT cellular interface.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rob.meades@u-blox.com 1:581335dbdd60 1 /* mbed Microcontroller Library
rob.meades@u-blox.com 1:581335dbdd60 2 * Copyright (c) 2017 u-blox
rob.meades@u-blox.com 1:581335dbdd60 3 *
rob.meades@u-blox.com 1:581335dbdd60 4 * Licensed under the Apache License, Version 2.0 (the "License");
rob.meades@u-blox.com 1:581335dbdd60 5 * you may not use this file except in compliance with the License.
rob.meades@u-blox.com 1:581335dbdd60 6 * You may obtain a copy of the License at
rob.meades@u-blox.com 1:581335dbdd60 7 *
rob.meades@u-blox.com 1:581335dbdd60 8 * http://www.apache.org/licenses/LICENSE-2.0
rob.meades@u-blox.com 1:581335dbdd60 9 *
rob.meades@u-blox.com 1:581335dbdd60 10 * Unless required by applicable law or agreed to in writing, software
rob.meades@u-blox.com 1:581335dbdd60 11 * distributed under the License is distributed on an "AS IS" BASIS,
rob.meades@u-blox.com 1:581335dbdd60 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rob.meades@u-blox.com 1:581335dbdd60 13 * See the License for the specific language governing permissions and
rob.meades@u-blox.com 1:581335dbdd60 14 * limitations under the License.
rob.meades@u-blox.com 1:581335dbdd60 15 */
rob.meades@u-blox.com 1:581335dbdd60 16
rob.meades@u-blox.com 1:581335dbdd60 17 #include "mbed.h"
rob.meades@u-blox.com 1:581335dbdd60 18 #include "UbloxATCellularInterface.h"
RobMeades 8:3e170c40a284 19 #include "UbloxPPPCellularInterface.h"
RobMeades 8:3e170c40a284 20
RobMeades 8:3e170c40a284 21 // If you wish to use LWIP and the PPP cellular interface, select
RobMeades 8:3e170c40a284 22 // the line UbloxPPPCellularInterface, otherwise select the line
RobMeades 8:3e170c40a284 23 // UbloxATCellularInterface. Using the AT cellular interface does not
RobMeades 8:3e170c40a284 24 // require LWIP and hence uses less RAM (significant on C027. It also
RobMeades 8:3e170c40a284 25 // allows other AT command operations (e.g. sending an SMS) to happen
RobMeades 8:3e170c40a284 26 // during a data transfer.
RobMeades 8:3e170c40a284 27 #define INTERFACE_CLASS UbloxATCellularInterface
RobMeades 8:3e170c40a284 28 //#define INTERFACE_CLASS UbloxPPPCellularInterface
rob.meades@u-blox.com 1:581335dbdd60 29
rob.meades@u-blox.com 1:581335dbdd60 30 // The credentials of the SIM in the board. If PIN checking is enabled
rob.meades@u-blox.com 1:581335dbdd60 31 // for your SIM card you must set this to the required PIN.
rob.meades@u-blox.com 1:581335dbdd60 32 #define PIN "0000"
rob.meades@u-blox.com 1:581335dbdd60 33
rob.meades@u-blox.com 1:581335dbdd60 34 // Network credentials. You should set this according to your
rob.meades@u-blox.com 1:581335dbdd60 35 // network/SIM card. For C030 boards, leave the parameters as NULL
rob.meades@u-blox.com 1:581335dbdd60 36 // otherwise, if you do not know the APN for your network, you may
rob.meades@u-blox.com 1:581335dbdd60 37 // either try the fairly common "internet" for the APN (and leave the
rob.meades@u-blox.com 1:581335dbdd60 38 // username and password NULL), or you may leave all three as NULL and then
rob.meades@u-blox.com 1:581335dbdd60 39 // a lookup will be attempted for a small number of known networks
rob.meades@u-blox.com 1:581335dbdd60 40 // (see APN_db.h in mbed-os/features/netsocket/cellular/utils).
rob.meades@u-blox.com 1:581335dbdd60 41 #define APN NULL
rob.meades@u-blox.com 1:581335dbdd60 42 #define USERNAME NULL
rob.meades@u-blox.com 1:581335dbdd60 43 #define PASSWORD NULL
rob.meades@u-blox.com 1:581335dbdd60 44
rob.meades@u-blox.com 1:581335dbdd60 45 // LEDs
rob.meades@u-blox.com 1:581335dbdd60 46 DigitalOut ledRed(LED1, 1);
rob.meades@u-blox.com 1:581335dbdd60 47 DigitalOut ledGreen(LED2, 1);
rob.meades@u-blox.com 1:581335dbdd60 48 DigitalOut ledBlue(LED3, 1);
rob.meades@u-blox.com 1:581335dbdd60 49
rob.meades@u-blox.com 1:581335dbdd60 50 // The user button
rob.meades@u-blox.com 1:581335dbdd60 51 volatile bool buttonPressed = false;
rob.meades@u-blox.com 1:581335dbdd60 52
rob.meades@u-blox.com 1:581335dbdd60 53 static void good() {
rob.meades@u-blox.com 1:581335dbdd60 54 ledGreen = 0;
rob.meades@u-blox.com 1:581335dbdd60 55 ledBlue = 1;
rob.meades@u-blox.com 1:581335dbdd60 56 ledRed = 1;
rob.meades@u-blox.com 1:581335dbdd60 57 }
rob.meades@u-blox.com 1:581335dbdd60 58
rob.meades@u-blox.com 1:581335dbdd60 59 static void bad() {
rob.meades@u-blox.com 1:581335dbdd60 60 ledRed = 0;
rob.meades@u-blox.com 1:581335dbdd60 61 ledGreen = 1;
rob.meades@u-blox.com 1:581335dbdd60 62 ledBlue = 1;
rob.meades@u-blox.com 1:581335dbdd60 63 }
rob.meades@u-blox.com 1:581335dbdd60 64
rob.meades@u-blox.com 1:581335dbdd60 65 static void event() {
rob.meades@u-blox.com 1:581335dbdd60 66 ledBlue = 0;
rob.meades@u-blox.com 1:581335dbdd60 67 ledRed = 1;
rob.meades@u-blox.com 1:581335dbdd60 68 ledGreen = 1;
rob.meades@u-blox.com 1:581335dbdd60 69 }
rob.meades@u-blox.com 1:581335dbdd60 70
rob.meades@u-blox.com 1:581335dbdd60 71 static void pulseEvent() {
rob.meades@u-blox.com 1:581335dbdd60 72 event();
rob.meades@u-blox.com 1:581335dbdd60 73 wait_ms(500);
rob.meades@u-blox.com 1:581335dbdd60 74 good();
rob.meades@u-blox.com 1:581335dbdd60 75 }
rob.meades@u-blox.com 1:581335dbdd60 76
rob.meades@u-blox.com 1:581335dbdd60 77 static void ledOff() {
rob.meades@u-blox.com 1:581335dbdd60 78 ledBlue = 1;
rob.meades@u-blox.com 1:581335dbdd60 79 ledRed = 1;
rob.meades@u-blox.com 1:581335dbdd60 80 ledGreen = 1;
rob.meades@u-blox.com 1:581335dbdd60 81 }
rob.meades@u-blox.com 1:581335dbdd60 82
rob.meades@u-blox.com 1:581335dbdd60 83 static void printNtpTime(char * buf, int len)
rob.meades@u-blox.com 1:581335dbdd60 84 {
rob.meades@u-blox.com 1:581335dbdd60 85 time_t timestamp = 0;
rob.meades@u-blox.com 1:581335dbdd60 86 struct tm *localTime;
rob.meades@u-blox.com 1:581335dbdd60 87 char timeString[25];
rob.meades@u-blox.com 1:581335dbdd60 88 time_t TIME1970 = 2208988800U;
rob.meades@u-blox.com 1:581335dbdd60 89
rob.meades@u-blox.com 1:581335dbdd60 90 if (len >= 43) {
rob.meades@u-blox.com 1:581335dbdd60 91 timestamp |= ((int) *(buf + 40)) << 24;
rob.meades@u-blox.com 1:581335dbdd60 92 timestamp |= ((int) *(buf + 41)) << 16;
rob.meades@u-blox.com 1:581335dbdd60 93 timestamp |= ((int) *(buf + 42)) << 8;
rob.meades@u-blox.com 1:581335dbdd60 94 timestamp |= ((int) *(buf + 43));
rob.meades@u-blox.com 1:581335dbdd60 95 timestamp -= TIME1970;
rob.meades@u-blox.com 1:581335dbdd60 96 localTime = localtime(&timestamp);
rob.meades@u-blox.com 1:581335dbdd60 97 if (localTime) {
rob.meades@u-blox.com 1:581335dbdd60 98 if (strftime(timeString, sizeof(timeString), "%a %b %d %H:%M:%S %Y", localTime) > 0) {
rob.meades@u-blox.com 1:581335dbdd60 99 printf("NTP timestamp is %s.\n", timeString);
rob.meades@u-blox.com 1:581335dbdd60 100 }
rob.meades@u-blox.com 1:581335dbdd60 101 }
rob.meades@u-blox.com 1:581335dbdd60 102 }
rob.meades@u-blox.com 1:581335dbdd60 103 }
rob.meades@u-blox.com 1:581335dbdd60 104
rob.meades@u-blox.com 1:581335dbdd60 105 static void cbButton()
rob.meades@u-blox.com 1:581335dbdd60 106 {
rob.meades@u-blox.com 1:581335dbdd60 107 buttonPressed = true;
rob.meades@u-blox.com 1:581335dbdd60 108 pulseEvent();
rob.meades@u-blox.com 1:581335dbdd60 109 }
rob.meades@u-blox.com 1:581335dbdd60 110
rob.meades@u-blox.com 1:581335dbdd60 111 /* This example program for the u-blox C030 and C027 boards instantiates
rob.meades@u-blox.com 1:581335dbdd60 112 * the UbloxAtCellularInterface and uses it to make a simple sockets
rob.meades@u-blox.com 1:581335dbdd60 113 * connection to a server, using 2.pool.ntp.org for UDP and developer.mbed.org
rob.meades@u-blox.com 1:581335dbdd60 114 * for TCP. For a more comprehensive example, where higher layer protocols
rob.meades@u-blox.com 1:581335dbdd60 115 * make use of the same sockets interface, see example-ublox-mbed-client.
rob.meades@u-blox.com 1:581335dbdd60 116 * Progress may be monitored with a serial terminal running at 9600 baud.
rob.meades@u-blox.com 1:581335dbdd60 117 * The LED on the C030 board will turn green when this program is
rob.meades@u-blox.com 1:581335dbdd60 118 * operating correctly, pulse blue when a sockets operation is completed
rob.meades@u-blox.com 1:581335dbdd60 119 * and turn red if there is a failure.
rob.meades@u-blox.com 1:581335dbdd60 120 */
rob.meades@u-blox.com 1:581335dbdd60 121
rob.meades@u-blox.com 1:581335dbdd60 122 int main()
rob.meades@u-blox.com 1:581335dbdd60 123 {
RobMeades 8:3e170c40a284 124 INTERFACE_CLASS *interface = new UbloxATCellularInterface();
RobMeades 5:bf352de1d3e5 125 // If you need to debug the cellular interface, comment out the
RobMeades 5:bf352de1d3e5 126 // instantiation above and uncomment the one below.
RobMeades 8:3e170c40a284 127 // INTERFACE_CLASS *interface = new INTERFACE_CLASS(MDMTXD, MDMRXD,
RobMeades 8:3e170c40a284 128 // MBED_CONF_UBLOX_CELL_BAUD_RATE,
RobMeades 8:3e170c40a284 129 // true);
rob.meades@u-blox.com 1:581335dbdd60 130 TCPSocket sockTcp;
rob.meades@u-blox.com 1:581335dbdd60 131 UDPSocket sockUdp;
rob.meades@u-blox.com 1:581335dbdd60 132 SocketAddress udpServer;
rob.meades@u-blox.com 1:581335dbdd60 133 SocketAddress udpSenderAddress;
rob.meades@u-blox.com 1:581335dbdd60 134 SocketAddress tcpServer;
rob.meades@u-blox.com 1:581335dbdd60 135 char buf[1024];
rob.meades@u-blox.com 1:581335dbdd60 136 int x;
RobMeades 4:3e2b789c3adc 137 #ifdef TARGET_UBLOX_C027
RobMeades 4:3e2b789c3adc 138 // No user button on C027
RobMeades 4:3e2b789c3adc 139 InterruptIn userButton(NC);
RobMeades 4:3e2b789c3adc 140 #else
rob.meades@u-blox.com 1:581335dbdd60 141 InterruptIn userButton(SW0);
RobMeades 4:3e2b789c3adc 142 #endif
rob.meades@u-blox.com 1:581335dbdd60 143
rob.meades@u-blox.com 1:581335dbdd60 144 // Attach a function to the user button
rob.meades@u-blox.com 1:581335dbdd60 145 userButton.rise(&cbButton);
rob.meades@u-blox.com 1:581335dbdd60 146
rob.meades@u-blox.com 1:581335dbdd60 147 good();
rob.meades@u-blox.com 1:581335dbdd60 148 printf("Starting up, please wait up to 180 seconds for network registration to complete...\n");
rob.meades@u-blox.com 1:581335dbdd60 149 if (interface->init(PIN)) {
rob.meades@u-blox.com 1:581335dbdd60 150 pulseEvent();
RobMeades 3:7ca70581ef20 151 interface->set_credentials(APN, USERNAME, PASSWORD);
rob.meades@u-blox.com 1:581335dbdd60 152 printf("Registered, connecting to the packet network...\n");
RobMeades 3:7ca70581ef20 153 for (x = 0; interface->connect() != 0; x++) {
rob.meades@u-blox.com 1:581335dbdd60 154 if (x > 0) {
rob.meades@u-blox.com 1:581335dbdd60 155 bad();
rob.meades@u-blox.com 1:581335dbdd60 156 printf("Retrying (have you checked that an antenna is plugged in and your APN is correct?)...\n");
rob.meades@u-blox.com 1:581335dbdd60 157 }
rob.meades@u-blox.com 1:581335dbdd60 158 }
rob.meades@u-blox.com 1:581335dbdd60 159 pulseEvent();
rob.meades@u-blox.com 1:581335dbdd60 160
rob.meades@u-blox.com 1:581335dbdd60 161 printf("Getting the IP address of \"developer.mbed.org\" and \"2.pool.ntp.org\"...\n");
rob.meades@u-blox.com 1:581335dbdd60 162 if ((interface->gethostbyname("2.pool.ntp.org", &udpServer) == 0) &&
rob.meades@u-blox.com 1:581335dbdd60 163 (interface->gethostbyname("developer.mbed.org", &tcpServer) == 0)) {
rob.meades@u-blox.com 1:581335dbdd60 164 pulseEvent();
rob.meades@u-blox.com 1:581335dbdd60 165 udpServer.set_port(123);
rob.meades@u-blox.com 1:581335dbdd60 166 tcpServer.set_port(80);
rob.meades@u-blox.com 1:581335dbdd60 167 printf("\"2.pool.ntp.org\" address: %s on port %d.\n", udpServer.get_ip_address(), udpServer.get_port());
rob.meades@u-blox.com 1:581335dbdd60 168 printf("\"developer.mbed.org\" address: %s on port %d.\n", tcpServer.get_ip_address(), tcpServer.get_port());
rob.meades@u-blox.com 1:581335dbdd60 169
RobMeades 4:3e2b789c3adc 170 printf("Performing socket operations in a loop (until the user button is pressed on C030 or forever on C027)...\n");
rob.meades@u-blox.com 1:581335dbdd60 171 while (!buttonPressed) {
rob.meades@u-blox.com 1:581335dbdd60 172 // UDP Sockets
rob.meades@u-blox.com 1:581335dbdd60 173 printf("=== UDP ===\n");
rob.meades@u-blox.com 1:581335dbdd60 174 printf("Opening a UDP socket...\n");
rob.meades@u-blox.com 1:581335dbdd60 175 if (sockUdp.open(interface) == 0) {
rob.meades@u-blox.com 1:581335dbdd60 176 pulseEvent();
rob.meades@u-blox.com 1:581335dbdd60 177 printf("UDP socket open.\n");
rob.meades@u-blox.com 1:581335dbdd60 178 sockUdp.set_timeout(10000);
rob.meades@u-blox.com 1:581335dbdd60 179 printf("Sending time request to \"2.pool.ntp.org\" over UDP socket...\n");
rob.meades@u-blox.com 1:581335dbdd60 180 memset (buf, 0, sizeof(buf));
rob.meades@u-blox.com 1:581335dbdd60 181 *buf = '\x1b';
rob.meades@u-blox.com 1:581335dbdd60 182 if (sockUdp.sendto(udpServer, (void *) buf, 48) == 48) {
rob.meades@u-blox.com 1:581335dbdd60 183 pulseEvent();
rob.meades@u-blox.com 1:581335dbdd60 184 printf("Socket send completed, waiting for UDP response...\n");
rob.meades@u-blox.com 1:581335dbdd60 185 x = sockUdp.recvfrom(&udpSenderAddress, buf, sizeof (buf));
rob.meades@u-blox.com 1:581335dbdd60 186 if (x > 0) {
rob.meades@u-blox.com 1:581335dbdd60 187 pulseEvent();
rob.meades@u-blox.com 1:581335dbdd60 188 printf("Received %d byte response from server %s on UDP socket:\n"
rob.meades@u-blox.com 1:581335dbdd60 189 "-------------------------------------------------------\n",
rob.meades@u-blox.com 1:581335dbdd60 190 x, udpSenderAddress.get_ip_address());
rob.meades@u-blox.com 1:581335dbdd60 191 printNtpTime(buf, x);
rob.meades@u-blox.com 1:581335dbdd60 192 printf("-------------------------------------------------------\n");
rob.meades@u-blox.com 1:581335dbdd60 193 }
rob.meades@u-blox.com 1:581335dbdd60 194 }
rob.meades@u-blox.com 1:581335dbdd60 195 printf("Closing socket...\n");
rob.meades@u-blox.com 1:581335dbdd60 196 sockUdp.close();
rob.meades@u-blox.com 1:581335dbdd60 197 pulseEvent();
rob.meades@u-blox.com 1:581335dbdd60 198 printf("Socket closed.\n");
rob.meades@u-blox.com 1:581335dbdd60 199 }
rob.meades@u-blox.com 1:581335dbdd60 200
rob.meades@u-blox.com 1:581335dbdd60 201 // TCP Sockets
rob.meades@u-blox.com 1:581335dbdd60 202 printf("=== TCP ===\n");
rob.meades@u-blox.com 1:581335dbdd60 203 printf("Opening a TCP socket...\n");
rob.meades@u-blox.com 1:581335dbdd60 204 if (sockTcp.open(interface) == 0) {
rob.meades@u-blox.com 1:581335dbdd60 205 pulseEvent();
rob.meades@u-blox.com 1:581335dbdd60 206 printf("TCP socket open.\n");
rob.meades@u-blox.com 1:581335dbdd60 207 sockTcp.set_timeout(10000);
rob.meades@u-blox.com 1:581335dbdd60 208 printf("Connecting socket to %s on port %d...\n", tcpServer.get_ip_address(), tcpServer.get_port());
rob.meades@u-blox.com 1:581335dbdd60 209 if (sockTcp.connect(tcpServer) == 0) {
RobMeades 2:dbf7dd3da592 210 pulseEvent();
rob.meades@u-blox.com 1:581335dbdd60 211 printf("Connected, sending HTTP GET request to \"developer.mbed.org\" over socket...\n");
rob.meades@u-blox.com 1:581335dbdd60 212 strcpy (buf, "GET /media/uploads/mbed_official/hello.txt HTTP/1.0\r\n\r\n");
rob.meades@u-blox.com 1:581335dbdd60 213 // Note: since this is a short string we can send it in one go as it will
rob.meades@u-blox.com 1:581335dbdd60 214 // fit within the default buffer sizes. Normally you should call sock.send()
rob.meades@u-blox.com 1:581335dbdd60 215 // in a loop until your entire buffer has been sent.
rob.meades@u-blox.com 1:581335dbdd60 216 if (sockTcp.send((void *) buf, strlen(buf)) == (int) strlen(buf)) {
rob.meades@u-blox.com 1:581335dbdd60 217 pulseEvent();
rob.meades@u-blox.com 1:581335dbdd60 218 printf("Socket send completed, waiting for response...\n");
rob.meades@u-blox.com 1:581335dbdd60 219 x = sockTcp.recv(buf, sizeof (buf));
rob.meades@u-blox.com 1:581335dbdd60 220 if (x > 0) {
rob.meades@u-blox.com 1:581335dbdd60 221 pulseEvent();
rob.meades@u-blox.com 1:581335dbdd60 222 printf("Received %d byte response from server on TCP socket:\n"
rob.meades@u-blox.com 1:581335dbdd60 223 "----------------------------------------------------\n%.*s"
rob.meades@u-blox.com 1:581335dbdd60 224 "----------------------------------------------------\n",
rob.meades@u-blox.com 1:581335dbdd60 225 x, x, buf);
rob.meades@u-blox.com 1:581335dbdd60 226 }
rob.meades@u-blox.com 1:581335dbdd60 227 }
rob.meades@u-blox.com 1:581335dbdd60 228 }
rob.meades@u-blox.com 1:581335dbdd60 229 printf("Closing socket...\n");
rob.meades@u-blox.com 1:581335dbdd60 230 sockTcp.close();
rob.meades@u-blox.com 1:581335dbdd60 231 pulseEvent();
rob.meades@u-blox.com 1:581335dbdd60 232 printf("Socket closed.\n");
rob.meades@u-blox.com 1:581335dbdd60 233 }
rob.meades@u-blox.com 1:581335dbdd60 234 wait_ms(5000);
RobMeades 3:7ca70581ef20 235 printf("[Checking if user button has been pressed]\n");
rob.meades@u-blox.com 1:581335dbdd60 236 }
rob.meades@u-blox.com 1:581335dbdd60 237
rob.meades@u-blox.com 1:581335dbdd60 238 pulseEvent();
rob.meades@u-blox.com 1:581335dbdd60 239 printf("User button was pressed, stopping...\n");
rob.meades@u-blox.com 1:581335dbdd60 240 interface->disconnect();
rob.meades@u-blox.com 1:581335dbdd60 241 interface->deinit();
rob.meades@u-blox.com 1:581335dbdd60 242 ledOff();
rob.meades@u-blox.com 1:581335dbdd60 243 printf("Stopped.\n");
rob.meades@u-blox.com 1:581335dbdd60 244 } else {
rob.meades@u-blox.com 1:581335dbdd60 245 bad();
RobMeades 2:dbf7dd3da592 246 printf("Unable to get IP address of \"developer.mbed.org\" or \"2.pool.ntp.org\".\n");
rob.meades@u-blox.com 1:581335dbdd60 247 }
rob.meades@u-blox.com 1:581335dbdd60 248 } else {
rob.meades@u-blox.com 1:581335dbdd60 249 bad();
rob.meades@u-blox.com 1:581335dbdd60 250 printf("Unable to initialise the interface.\n");
rob.meades@u-blox.com 1:581335dbdd60 251 }
rob.meades@u-blox.com 1:581335dbdd60 252 }
rob.meades@u-blox.com 1:581335dbdd60 253
rob.meades@u-blox.com 1:581335dbdd60 254 // End Of File