Example program running mbedClient over UbloxATCellularInterface or OnboardCellularInterface for the C030 platform.
Dependencies: ublox-cellular-base ublox-at-cellular-interface ublox-ppp-cellular-interface ublox-at-cellular-interface-n2xx ublox-cellular-base-n2xx
main.cpp@8:f341bfe37797, 2017-07-31 (annotated)
- Committer:
- rob.meades@u-blox.com
- Date:
- Mon Jul 31 13:22:44 2017 +0100
- Revision:
- 8:f341bfe37797
- Parent:
- 5:d81fdd2c89f2
- Child:
- 12:78e41b0a374f
Point mbed-os at ARMmbed mbed-os master, update all other library versions, remove compiler warnings in main.cpp and add mbed-trace to mbed_app.json (but set to false).
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
rob.meades@u-blox.com | 1:9f355da25904 | 1 | /* mbed Microcontroller Library |
rob.meades@u-blox.com | 1:9f355da25904 | 2 | * Copyright (c) 2017 u-blox |
rob.meades@u-blox.com | 1:9f355da25904 | 3 | * |
rob.meades@u-blox.com | 1:9f355da25904 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
rob.meades@u-blox.com | 1:9f355da25904 | 5 | * you may not use this file except in compliance with the License. |
rob.meades@u-blox.com | 1:9f355da25904 | 6 | * You may obtain a copy of the License at |
rob.meades@u-blox.com | 1:9f355da25904 | 7 | * |
rob.meades@u-blox.com | 1:9f355da25904 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
rob.meades@u-blox.com | 1:9f355da25904 | 9 | * |
rob.meades@u-blox.com | 1:9f355da25904 | 10 | * Unless required by applicable law or agreed to in writing, software |
rob.meades@u-blox.com | 1:9f355da25904 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
rob.meades@u-blox.com | 1:9f355da25904 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
rob.meades@u-blox.com | 1:9f355da25904 | 13 | * See the License for the specific language governing permissions and |
rob.meades@u-blox.com | 1:9f355da25904 | 14 | * limitations under the License. |
rob.meades@u-blox.com | 1:9f355da25904 | 15 | */ |
rob.meades@u-blox.com | 1:9f355da25904 | 16 | |
rob.meades@u-blox.com | 1:9f355da25904 | 17 | #define __STDC_FORMAT_MACROS |
rob.meades@u-blox.com | 1:9f355da25904 | 18 | #include <inttypes.h> |
rob.meades@u-blox.com | 1:9f355da25904 | 19 | #include <string> |
rob.meades@u-blox.com | 1:9f355da25904 | 20 | #include <sstream> |
rob.meades@u-blox.com | 1:9f355da25904 | 21 | #include <vector> |
rob.meades@u-blox.com | 1:9f355da25904 | 22 | |
rob.meades@u-blox.com | 1:9f355da25904 | 23 | #include "mbed.h" |
rob.meades@u-blox.com | 1:9f355da25904 | 24 | #include "mbedtls/entropy_poll.h" |
rob.meades@u-blox.com | 1:9f355da25904 | 25 | #include "UbloxATCellularInterface.h" |
RobMeades | 3:5b8623c17906 | 26 | #include "UbloxPPPCellularInterface.h" |
rob.meades@u-blox.com | 1:9f355da25904 | 27 | #include "simpleclient.h" |
rob.meades@u-blox.com | 1:9f355da25904 | 28 | #include "security.h" |
rob.meades@u-blox.com | 1:9f355da25904 | 29 | #include "mbed_trace.h" |
rob.meades@u-blox.com | 1:9f355da25904 | 30 | #include "mbed.h" |
rob.meades@u-blox.com | 1:9f355da25904 | 31 | |
RobMeades | 3:5b8623c17906 | 32 | // If you wish to use LWIP and the PPP cellular interface, select |
RobMeades | 3:5b8623c17906 | 33 | // the line UbloxPPPCellularInterface, otherwise select the line |
RobMeades | 3:5b8623c17906 | 34 | // UbloxATCellularInterface. Using the AT cellular interface does not |
rob.meades@u-blox.com | 5:d81fdd2c89f2 | 35 | // require LWIP and hence uses less RAM. It also allows other AT command |
rob.meades@u-blox.com | 5:d81fdd2c89f2 | 36 | // operations (e.g. sending an SMS) to happen during a data transfer. |
RobMeades | 3:5b8623c17906 | 37 | #define INTERFACE_CLASS UbloxATCellularInterface |
RobMeades | 3:5b8623c17906 | 38 | //#define INTERFACE_CLASS UbloxPPPCellularInterface |
RobMeades | 3:5b8623c17906 | 39 | |
rob.meades@u-blox.com | 1:9f355da25904 | 40 | // The credentials of the SIM in the board. If PIN checking is enabled |
rob.meades@u-blox.com | 1:9f355da25904 | 41 | // for your SIM card you must set this to the required PIN. |
rob.meades@u-blox.com | 1:9f355da25904 | 42 | #define PIN "0000" |
rob.meades@u-blox.com | 1:9f355da25904 | 43 | |
rob.meades@u-blox.com | 1:9f355da25904 | 44 | // Network credentials. You should set this according to your |
rob.meades@u-blox.com | 1:9f355da25904 | 45 | // network/SIM card. For C030 boards, leave the parameters as NULL |
rob.meades@u-blox.com | 1:9f355da25904 | 46 | // otherwise, if you do not know the APN for your network, you may |
rob.meades@u-blox.com | 1:9f355da25904 | 47 | // either try the fairly common "internet" for the APN (and leave the |
rob.meades@u-blox.com | 1:9f355da25904 | 48 | // username and password NULL), or you may leave all three as NULL and then |
rob.meades@u-blox.com | 1:9f355da25904 | 49 | // a lookup will be attempted for a small number of known networks |
rob.meades@u-blox.com | 1:9f355da25904 | 50 | // (see APN_db.h in mbed-os/features/netsocket/cellular/utils). |
rob.meades@u-blox.com | 1:9f355da25904 | 51 | #define APN NULL |
rob.meades@u-blox.com | 1:9f355da25904 | 52 | #define USERNAME NULL |
rob.meades@u-blox.com | 1:9f355da25904 | 53 | #define PASSWORD NULL |
rob.meades@u-blox.com | 1:9f355da25904 | 54 | |
rob.meades@u-blox.com | 1:9f355da25904 | 55 | // LEDs |
rob.meades@u-blox.com | 1:9f355da25904 | 56 | DigitalOut ledRed(LED1, 1); |
rob.meades@u-blox.com | 1:9f355da25904 | 57 | DigitalOut ledGreen(LED2, 1); |
rob.meades@u-blox.com | 1:9f355da25904 | 58 | DigitalOut ledBlue(LED3, 1); |
rob.meades@u-blox.com | 1:9f355da25904 | 59 | |
rob.meades@u-blox.com | 1:9f355da25904 | 60 | // The user button |
rob.meades@u-blox.com | 1:9f355da25904 | 61 | volatile bool buttonPressed = false; |
rob.meades@u-blox.com | 1:9f355da25904 | 62 | |
rob.meades@u-blox.com | 1:9f355da25904 | 63 | static void good() { |
rob.meades@u-blox.com | 1:9f355da25904 | 64 | ledGreen = 0; |
rob.meades@u-blox.com | 1:9f355da25904 | 65 | ledBlue = 1; |
rob.meades@u-blox.com | 1:9f355da25904 | 66 | ledRed = 1; |
rob.meades@u-blox.com | 1:9f355da25904 | 67 | } |
rob.meades@u-blox.com | 1:9f355da25904 | 68 | |
rob.meades@u-blox.com | 1:9f355da25904 | 69 | static void bad() { |
rob.meades@u-blox.com | 1:9f355da25904 | 70 | ledRed = 0; |
rob.meades@u-blox.com | 1:9f355da25904 | 71 | ledGreen = 1; |
rob.meades@u-blox.com | 1:9f355da25904 | 72 | ledBlue = 1; |
rob.meades@u-blox.com | 1:9f355da25904 | 73 | } |
rob.meades@u-blox.com | 1:9f355da25904 | 74 | |
rob.meades@u-blox.com | 1:9f355da25904 | 75 | static void event() { |
rob.meades@u-blox.com | 1:9f355da25904 | 76 | ledBlue = 0; |
rob.meades@u-blox.com | 1:9f355da25904 | 77 | ledRed = 1; |
rob.meades@u-blox.com | 1:9f355da25904 | 78 | ledGreen = 1; |
rob.meades@u-blox.com | 1:9f355da25904 | 79 | } |
rob.meades@u-blox.com | 1:9f355da25904 | 80 | |
rob.meades@u-blox.com | 1:9f355da25904 | 81 | static void pulseEvent() { |
rob.meades@u-blox.com | 1:9f355da25904 | 82 | event(); |
rob.meades@u-blox.com | 1:9f355da25904 | 83 | wait_ms(500); |
rob.meades@u-blox.com | 1:9f355da25904 | 84 | good(); |
rob.meades@u-blox.com | 1:9f355da25904 | 85 | } |
rob.meades@u-blox.com | 1:9f355da25904 | 86 | |
rob.meades@u-blox.com | 1:9f355da25904 | 87 | static void ledOff() { |
rob.meades@u-blox.com | 1:9f355da25904 | 88 | ledBlue = 1; |
rob.meades@u-blox.com | 1:9f355da25904 | 89 | ledRed = 1; |
rob.meades@u-blox.com | 1:9f355da25904 | 90 | ledGreen = 1; |
rob.meades@u-blox.com | 1:9f355da25904 | 91 | } |
rob.meades@u-blox.com | 1:9f355da25904 | 92 | |
rob.meades@u-blox.com | 1:9f355da25904 | 93 | // Resource values for the Device Object |
rob.meades@u-blox.com | 1:9f355da25904 | 94 | struct MbedClientDevice device = { |
rob.meades@u-blox.com | 1:9f355da25904 | 95 | "Manufacturer", // Manufacturer |
rob.meades@u-blox.com | 1:9f355da25904 | 96 | "Type", // Type |
rob.meades@u-blox.com | 1:9f355da25904 | 97 | "ModelNumber", // ModelNumber |
rob.meades@u-blox.com | 1:9f355da25904 | 98 | "SerialNumber" // SerialNumber |
rob.meades@u-blox.com | 1:9f355da25904 | 99 | }; |
rob.meades@u-blox.com | 1:9f355da25904 | 100 | |
rob.meades@u-blox.com | 1:9f355da25904 | 101 | class LedResource { |
rob.meades@u-blox.com | 1:9f355da25904 | 102 | public: |
rob.meades@u-blox.com | 1:9f355da25904 | 103 | LedResource() { |
rob.meades@u-blox.com | 1:9f355da25904 | 104 | ledObject = M2MInterfaceFactory::create_object("3311"); |
rob.meades@u-blox.com | 1:9f355da25904 | 105 | M2MObjectInstance *inst = ledObject->create_object_instance(); |
rob.meades@u-blox.com | 1:9f355da25904 | 106 | |
rob.meades@u-blox.com | 1:9f355da25904 | 107 | // An observable resource |
rob.meades@u-blox.com | 1:9f355da25904 | 108 | M2MResource *onResource = inst->create_dynamic_resource("5850", "On/Off", M2MResourceInstance::BOOLEAN, true); |
rob.meades@u-blox.com | 1:9f355da25904 | 109 | onResource->set_operation(M2MBase::GET_PUT_ALLOWED); |
rob.meades@u-blox.com | 1:9f355da25904 | 110 | onResource->set_value(false); |
rob.meades@u-blox.com | 1:9f355da25904 | 111 | |
rob.meades@u-blox.com | 1:9f355da25904 | 112 | // An multi-valued resource |
rob.meades@u-blox.com | 1:9f355da25904 | 113 | M2MResource *dimmerResource = inst->create_dynamic_resource("5851", "Dimmer", M2MResourceInstance::BOOLEAN, false); |
rob.meades@u-blox.com | 1:9f355da25904 | 114 | dimmerResource->set_operation(M2MBase::GET_PUT_ALLOWED); |
rob.meades@u-blox.com | 1:9f355da25904 | 115 | dimmerResource->set_value(false); |
rob.meades@u-blox.com | 1:9f355da25904 | 116 | } |
rob.meades@u-blox.com | 1:9f355da25904 | 117 | |
rob.meades@u-blox.com | 1:9f355da25904 | 118 | ~LedResource() { |
rob.meades@u-blox.com | 1:9f355da25904 | 119 | } |
rob.meades@u-blox.com | 1:9f355da25904 | 120 | |
rob.meades@u-blox.com | 1:9f355da25904 | 121 | M2MObject *get_object() { |
rob.meades@u-blox.com | 1:9f355da25904 | 122 | return ledObject; |
rob.meades@u-blox.com | 1:9f355da25904 | 123 | } |
rob.meades@u-blox.com | 1:9f355da25904 | 124 | |
rob.meades@u-blox.com | 1:9f355da25904 | 125 | private: |
rob.meades@u-blox.com | 1:9f355da25904 | 126 | M2MObject *ledObject; |
rob.meades@u-blox.com | 1:9f355da25904 | 127 | }; |
rob.meades@u-blox.com | 1:9f355da25904 | 128 | |
rob.meades@u-blox.com | 1:9f355da25904 | 129 | static void cbButton() |
rob.meades@u-blox.com | 1:9f355da25904 | 130 | { |
rob.meades@u-blox.com | 1:9f355da25904 | 131 | buttonPressed = true; |
rob.meades@u-blox.com | 1:9f355da25904 | 132 | pulseEvent(); |
rob.meades@u-blox.com | 1:9f355da25904 | 133 | } |
rob.meades@u-blox.com | 1:9f355da25904 | 134 | |
rob.meades@u-blox.com | 5:d81fdd2c89f2 | 135 | /* This example program for the u-blox C030 board instantiates mbedClient |
rob.meades@u-blox.com | 5:d81fdd2c89f2 | 136 | * and runs it over a UbloxATCellularInterface or a UbloxPPPCellularInterface to |
rob.meades@u-blox.com | 1:9f355da25904 | 137 | * the mbed connector. |
rob.meades@u-blox.com | 1:9f355da25904 | 138 | * Progress may be monitored with a serial terminal running at 9600 baud. |
rob.meades@u-blox.com | 1:9f355da25904 | 139 | * The LED on the C030 board will turn green when this program is |
rob.meades@u-blox.com | 1:9f355da25904 | 140 | * operating correctly, pulse blue when an mbedClient operation is completed |
rob.meades@u-blox.com | 1:9f355da25904 | 141 | * and turn red if there is a failure. |
rob.meades@u-blox.com | 1:9f355da25904 | 142 | * |
rob.meades@u-blox.com | 5:d81fdd2c89f2 | 143 | * Note: mbedClient malloc's around 34 kbytes of RAM, more than is available on |
rob.meades@u-blox.com | 5:d81fdd2c89f2 | 144 | * the C027 platform, hence this example will not run on the C027 platform. |
rob.meades@u-blox.com | 5:d81fdd2c89f2 | 145 | * |
rob.meades@u-blox.com | 1:9f355da25904 | 146 | * IMPORTANT to use this example you must first register with the mbed Connector: |
rob.meades@u-blox.com | 1:9f355da25904 | 147 | * |
rob.meades@u-blox.com | 1:9f355da25904 | 148 | * https://connector.mbed.com/ |
rob.meades@u-blox.com | 1:9f355da25904 | 149 | * |
rob.meades@u-blox.com | 1:9f355da25904 | 150 | * ...using your mbed developer credentials and generate your own copy of the file |
rob.meades@u-blox.com | 1:9f355da25904 | 151 | * security.h, replacing the empty one in this directory with yours and |
rob.meades@u-blox.com | 1:9f355da25904 | 152 | * recompiling/downloading the code to your board. |
rob.meades@u-blox.com | 1:9f355da25904 | 153 | */ |
rob.meades@u-blox.com | 1:9f355da25904 | 154 | |
rob.meades@u-blox.com | 1:9f355da25904 | 155 | int main() |
rob.meades@u-blox.com | 1:9f355da25904 | 156 | { |
RobMeades | 3:5b8623c17906 | 157 | INTERFACE_CLASS *interface = new INTERFACE_CLASS(); |
RobMeades | 3:5b8623c17906 | 158 | // If you need to debug the cellular interface, comment out the |
RobMeades | 3:5b8623c17906 | 159 | // instantiation above and uncomment the one below. |
RobMeades | 3:5b8623c17906 | 160 | // INTERFACE_CLASS *interface = new INTERFACE_CLASS(MDMTXD, MDMRXD, |
RobMeades | 3:5b8623c17906 | 161 | // MBED_CONF_UBLOX_CELL_BAUD_RATE, |
RobMeades | 3:5b8623c17906 | 162 | // true); |
rob.meades@u-blox.com | 1:9f355da25904 | 163 | MbedClient *mbedClient = new MbedClient(device); |
rob.meades@u-blox.com | 1:9f355da25904 | 164 | M2MObjectList objectList; |
rob.meades@u-blox.com | 1:9f355da25904 | 165 | M2MSecurity *registerObject; |
rob.meades@u-blox.com | 1:9f355da25904 | 166 | M2MDevice *deviceObject; |
rob.meades@u-blox.com | 1:9f355da25904 | 167 | LedResource ledResource; |
rob.meades@u-blox.com | 1:9f355da25904 | 168 | unsigned int seed; |
rob.meades@u-blox.com | 1:9f355da25904 | 169 | size_t len; |
rob.meades@u-blox.com | 1:9f355da25904 | 170 | InterruptIn userButton(SW0); |
rob.meades@u-blox.com | 1:9f355da25904 | 171 | |
rob.meades@u-blox.com | 1:9f355da25904 | 172 | // Attach a function to the user button |
rob.meades@u-blox.com | 1:9f355da25904 | 173 | userButton.rise(&cbButton); |
rob.meades@u-blox.com | 1:9f355da25904 | 174 | |
rob.meades@u-blox.com | 8:f341bfe37797 | 175 | #if MBED_CONF_MBED_TRACE_ENABLE |
rob.meades@u-blox.com | 1:9f355da25904 | 176 | mbed_trace_init(); |
rob.meades@u-blox.com | 8:f341bfe37797 | 177 | #endif |
rob.meades@u-blox.com | 1:9f355da25904 | 178 | srand(seed); |
rob.meades@u-blox.com | 1:9f355da25904 | 179 | |
rob.meades@u-blox.com | 1:9f355da25904 | 180 | // Randomize source port |
RobMeades | 3:5b8623c17906 | 181 | #ifdef MBEDTLS_TEST_NULL_ENTROPY |
RobMeades | 3:5b8623c17906 | 182 | mbedtls_null_entropy_poll(NULL, (unsigned char *) &seed, sizeof seed, &len); |
rob.meades@u-blox.com | 1:9f355da25904 | 183 | #else |
RobMeades | 3:5b8623c17906 | 184 | mbedtls_hardware_poll(NULL, (unsigned char *) &seed, sizeof seed, &len); |
rob.meades@u-blox.com | 1:9f355da25904 | 185 | #endif |
rob.meades@u-blox.com | 1:9f355da25904 | 186 | |
rob.meades@u-blox.com | 1:9f355da25904 | 187 | good(); |
rob.meades@u-blox.com | 1:9f355da25904 | 188 | printf("Starting up, please wait up to 180 seconds for network registration to complete...\n"); |
rob.meades@u-blox.com | 1:9f355da25904 | 189 | if (interface->init(PIN)) { |
rob.meades@u-blox.com | 1:9f355da25904 | 190 | pulseEvent(); |
rob.meades@u-blox.com | 1:9f355da25904 | 191 | printf("Registered with network.\n"); |
rob.meades@u-blox.com | 1:9f355da25904 | 192 | |
rob.meades@u-blox.com | 1:9f355da25904 | 193 | // Create endpoint interface to manage register and unregister |
rob.meades@u-blox.com | 1:9f355da25904 | 194 | mbedClient->create_interface("coap://api.connector.mbed.com:5684", interface); |
rob.meades@u-blox.com | 1:9f355da25904 | 195 | |
rob.meades@u-blox.com | 1:9f355da25904 | 196 | // Create objects of varying types, see simpleclient.h for more details on implementation. |
rob.meades@u-blox.com | 1:9f355da25904 | 197 | registerObject = mbedClient->create_register_object(); // Server object specifying connector info |
rob.meades@u-blox.com | 1:9f355da25904 | 198 | deviceObject = mbedClient->create_device_object(); // Device resources object |
rob.meades@u-blox.com | 1:9f355da25904 | 199 | |
rob.meades@u-blox.com | 1:9f355da25904 | 200 | // Add objects to list |
rob.meades@u-blox.com | 1:9f355da25904 | 201 | objectList.push_back(deviceObject); |
rob.meades@u-blox.com | 1:9f355da25904 | 202 | objectList.push_back(ledResource.get_object()); |
rob.meades@u-blox.com | 1:9f355da25904 | 203 | |
rob.meades@u-blox.com | 1:9f355da25904 | 204 | // Set endpoint registration object |
rob.meades@u-blox.com | 1:9f355da25904 | 205 | mbedClient->set_register_object(registerObject); |
rob.meades@u-blox.com | 1:9f355da25904 | 206 | |
rob.meades@u-blox.com | 1:9f355da25904 | 207 | printf("Updating object registration in a loop (with a 30 second refresh period) until the user button is presed...\n"); |
rob.meades@u-blox.com | 1:9f355da25904 | 208 | interface->set_credentials(APN, USERNAME, PASSWORD); |
rob.meades@u-blox.com | 1:9f355da25904 | 209 | while (!buttonPressed) { |
rob.meades@u-blox.com | 1:9f355da25904 | 210 | // Make sure cellular is connected |
rob.meades@u-blox.com | 1:9f355da25904 | 211 | if (interface->connect() == 0) { |
rob.meades@u-blox.com | 1:9f355da25904 | 212 | pulseEvent(); |
rob.meades@u-blox.com | 1:9f355da25904 | 213 | printf("[Still] connected to packet network.\n"); |
rob.meades@u-blox.com | 1:9f355da25904 | 214 | if (mbedClient->register_successful()) { |
rob.meades@u-blox.com | 1:9f355da25904 | 215 | printf("Updating registration (follow progress at https://connector.mbed.com/#home)...\n"); |
rob.meades@u-blox.com | 1:9f355da25904 | 216 | mbedClient->test_update_register(); |
rob.meades@u-blox.com | 1:9f355da25904 | 217 | } else { |
rob.meades@u-blox.com | 1:9f355da25904 | 218 | printf("Registering with connector (follow progress at https://connector.mbed.com/#home)...\n"); |
rob.meades@u-blox.com | 1:9f355da25904 | 219 | mbedClient->test_register(registerObject, objectList); |
rob.meades@u-blox.com | 1:9f355da25904 | 220 | } |
rob.meades@u-blox.com | 1:9f355da25904 | 221 | } else { |
rob.meades@u-blox.com | 1:9f355da25904 | 222 | bad(); |
rob.meades@u-blox.com | 1:9f355da25904 | 223 | printf("Failed to connect, will retry (have you checked that an antenna is plugged in and your APN is correct?)...\n"); |
rob.meades@u-blox.com | 1:9f355da25904 | 224 | } |
rob.meades@u-blox.com | 1:9f355da25904 | 225 | Thread::wait(30000); |
rob.meades@u-blox.com | 1:9f355da25904 | 226 | printf("[Checking if user button has been pressed]\n"); |
rob.meades@u-blox.com | 1:9f355da25904 | 227 | } |
rob.meades@u-blox.com | 1:9f355da25904 | 228 | |
rob.meades@u-blox.com | 1:9f355da25904 | 229 | pulseEvent(); |
rob.meades@u-blox.com | 1:9f355da25904 | 230 | printf("User button was pressed, stopping...\n"); |
rob.meades@u-blox.com | 1:9f355da25904 | 231 | mbedClient->test_unregister(); |
rob.meades@u-blox.com | 1:9f355da25904 | 232 | interface->disconnect(); |
rob.meades@u-blox.com | 1:9f355da25904 | 233 | interface->deinit(); |
rob.meades@u-blox.com | 1:9f355da25904 | 234 | ledOff(); |
rob.meades@u-blox.com | 1:9f355da25904 | 235 | printf("Stopped.\n"); |
rob.meades@u-blox.com | 1:9f355da25904 | 236 | M2MDevice::delete_instance(); |
rob.meades@u-blox.com | 1:9f355da25904 | 237 | } else { |
rob.meades@u-blox.com | 1:9f355da25904 | 238 | bad(); |
rob.meades@u-blox.com | 1:9f355da25904 | 239 | printf("Unable to initialise the interface.\n"); |
rob.meades@u-blox.com | 1:9f355da25904 | 240 | } |
rob.meades@u-blox.com | 1:9f355da25904 | 241 | } |
rob.meades@u-blox.com | 1:9f355da25904 | 242 | |
rob.meades@u-blox.com | 8:f341bfe37797 | 243 | // End Of File |