This program connects to a few sensors via I2C and sends the data collected to a WNC Cellular Module which is located on an Avnet WNC-Shield card.

Dependencies:   FXOS8700CQ MODSERIAL mbed

/media/uploads/kevinkeryk/avnet_logo_tagline_rgb.png

Avnet Cellular IoT Instructions

  • One problematic area is setting the MY_SERVER_URL. When you copy the URL from the flow, you must make sure the MY_SERVER_URL is also set to the appropriate server. It can be either "run-east.att.io" or "run-west.att.io".

Useful Links

Adding Additional Sensors

The FLOW_DEVICE_NAME field must contain the name of the instance of the Virtual Starter Kit in FLOW you will be communicating with. Usually this is "vstarterkit001", but if you have problems communicating you can verify this is correct. Note: This device will not be created until you click the “Initialize” input on the Virtual Device tab of the Starter Kit project in FLOW. At that point, it becomes available in M2X and you can see it as the DEVICE SERIAL field under Devices as in the image below. /media/uploads/JMF/vstarterkit.png

Sensors: When executing, the FRDM-K64F board uploads sensor measurements to AT&T’s Flow environment every 5 seconds, using the Cellular shield board. You can adjust how often you want to do this by editing the SENSOR_UPDATE_INTERVAL_MS value in the header file.

Temperature and humidity: By default, the board reports readings from the HTS221 temperature and humidity sensor. These two values are sent to the HTTP IN /climate port in FLOW with field names “temp” and “humidity”. Temperature is in degrees Fahrenheit and humidity is a %. This default assignment is: iSensorsToReport = TEMP_HUMIDITY_ONLY;

Accelerometer: If you want to expand and use the onboard motion sensor, you can also send 3-axis accelerometer information from the board as “accelX”, “accelY”, and “accelZ”. This is useful if you want to know the stationary position of the board with regards to gravity, or whether it is in motion. These readings are in g’s. To send these values, change the assignment to: iSensorsToReport = TEMP_HUMIDITY_ACCELEROMETER;

PMOD Sensors: If you have a Silicon Labs sensor module that can plug into the PMOD connector on the Cellular shield, you are able to measure proximity, UV light, ambient visible and infrared light from the Si1145 sensor. This PMOD also has a temperature and humidity sensor, but in this case it is redundant. When enabled, the fields “proximity”, “light_uv”, “light_vis” and “light_ir” are also sent. To enable all these sensors, change the assignment to: iSensorsToReport = TEMP_HUMIDITY_ACCELEROMETER_PMODSENSORS;

Connecting the PMOD sensors: Because the pinouts do not align, the SiLabs PMOD sensor board cannot be plugged into the J10 PMOD receptacle on the shield directly. The following wiring instructions must be followed:

SignalJ10ShieldPMOD Color in the image below
VCCPin 6Pin 6Red
GNDPin 5Pin 5Black
SDAPin4Pin 3Green
SCLPin3Pin 2Yellow

/media/uploads/JMF/xyz.jpg

AT&T M2X and FLOW Instructions

M2X & FLOW Instructions

Link to AT&T M2X

M2X

Link to AT&T Flow

FLOW

Avnet WNC-Shield Information

Getting Started with the Avnet WNC-Shield Software

  • This project uses Revision 119 of the MBED library because of I2C implementation differences with the tip (Revision 121).
  • This project uses Revision 4 of the FXOS8700CQ library for sensors.

Easily Modifiable Parameters

Inside the mbed Avnet_ATT_Cellular_IOT project, the parameters needed to customize your board are in the config_me.h file.

  • FLOW parameters: This project assumes you are using a fork of the Starter Kit Base project, which is a reference design created using AT&T’s FLOW (https://flow.att.com) that allows the creation of online virtualization and other IoT functionality. The default parameters in the config_me.h file are done for a specific instance of this project. When you fork the original project, you get your own instance and it will have its own base address. At the bottom of the FLOW environment, when you click on the Endpoints tab, URL information that is specific to your instance is displayed. Of note is the Base URL. In the example below (as in the default mbed project), the Base URL is: https://run-west.att.io/1e464b19cdcde/774c88d68202/86694923d5bf28a/in/flow You have to take note of two parts of this address. The run-west.att.io part is the server URL, and you have to make sure the
  • MY_SERVER_URL field in config_me.h matches this. The rest of the base URL, in green above, needs to be pasted into the FLOW_BASE_URL field.

There is also a FLOW_INPUT_NAME field. This should match the name of the HTTP IN port in the FLOW project that you want to send sensor data to. The default is "/climate", as in the FLOW image below.

/media/uploads/JMF/sf.png

Where is the Binary I compiled

When the COMPILE button is pressed, it compiles your project and links it. The result is placed in the DOWNLOAD folder you use when downloading files from the Internet. It will be called AvnetATT_shape_hackathon_K64F.bin.

Additional Information on Compiling/Configuring

Comprehensive instructions can be found at: Quick Start Instructions

Committer:
fkellermavnet
Date:
Sun Jul 24 16:58:17 2016 +0000
Revision:
43:6821a9c78c4b
Parent:
42:be4b9ee3a615
Child:
44:c95a85b5cf92
Put back in 1ms between chars sent to WNC.; FIXED: exception error due to sockread on no response and string search results not checked!

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JMF 2:0e2ef866af95 1 #include "mbed.h"
JMF 2:0e2ef866af95 2 #include <cctype>
JMF 2:0e2ef866af95 3 #include <string>
JMF 2:0e2ef866af95 4 #include "config_me.h"
JMF 2:0e2ef866af95 5 #include "SerialBuffered.h"
JMF 2:0e2ef866af95 6 #include "wnc_control.h"
JMF 2:0e2ef866af95 7
JMF 2:0e2ef866af95 8 extern Serial pc;
JMF 2:0e2ef866af95 9 extern Serial mdm;
JMF 2:0e2ef866af95 10 extern string MyServerIpAddress;
JMF 2:0e2ef866af95 11 extern string MySocketData;
JMF 2:0e2ef866af95 12
JMF 2:0e2ef866af95 13 int reinitialize_mdm(void);
JMF 2:0e2ef866af95 14
JMF 2:0e2ef866af95 15 enum WNC_ERR_e {
JMF 2:0e2ef866af95 16 WNC_OK =0,
JMF 2:0e2ef866af95 17 WNC_CMD_ERR = -1,
JMF 2:0e2ef866af95 18 WNC_NO_RESPONSE = -2
JMF 2:0e2ef866af95 19 };
JMF 2:0e2ef866af95 20
JMF 2:0e2ef866af95 21 // Contains result of last call to send_wnc_cmd(..)
JMF 2:0e2ef866af95 22 WNC_ERR_e WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 23
JMF 2:0e2ef866af95 24 // Contains the RAW WNC UART responses
JMF 2:0e2ef866af95 25 static string wncStr;
fkellermavnet 10:df54436ecd38 26 static int socketOpen = 0;
JMF 2:0e2ef866af95 27
JMF 2:0e2ef866af95 28 void software_init_mdm(void)
JMF 2:0e2ef866af95 29 {
fkellermavnet 42:be4b9ee3a615 30 static bool reportStatus = true;
JMF 2:0e2ef866af95 31 do
JMF 2:0e2ef866af95 32 {
fkellermavnet 42:be4b9ee3a615 33 if (check_wnc_ready() == 0)
fkellermavnet 42:be4b9ee3a615 34 {
fkellermavnet 42:be4b9ee3a615 35 if (reportStatus == false)
fkellermavnet 42:be4b9ee3a615 36 {
fkellermavnet 42:be4b9ee3a615 37 puts("Re-connected to cellular network!\n\r");
fkellermavnet 42:be4b9ee3a615 38 reportStatus = true;
fkellermavnet 42:be4b9ee3a615 39 }
fkellermavnet 42:be4b9ee3a615 40
fkellermavnet 42:be4b9ee3a615 41 // WNC has SIM and registered on network
fkellermavnet 42:be4b9ee3a615 42 do
fkellermavnet 42:be4b9ee3a615 43 {
fkellermavnet 42:be4b9ee3a615 44 WNC_MDM_ERR = WNC_OK;
fkellermavnet 42:be4b9ee3a615 45 at_init_wnc();
fkellermavnet 42:be4b9ee3a615 46 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
fkellermavnet 42:be4b9ee3a615 47 {
fkellermavnet 42:be4b9ee3a615 48 reinitialize_mdm();
fkellermavnet 42:be4b9ee3a615 49 at_init_wnc(true); // Hard reset occurred so make it go through the software init();
fkellermavnet 42:be4b9ee3a615 50 }
fkellermavnet 42:be4b9ee3a615 51 } while (WNC_MDM_ERR != WNC_OK);
fkellermavnet 42:be4b9ee3a615 52 }
fkellermavnet 42:be4b9ee3a615 53 else
fkellermavnet 42:be4b9ee3a615 54 {
fkellermavnet 42:be4b9ee3a615 55 if (reportStatus == true)
fkellermavnet 42:be4b9ee3a615 56 {
fkellermavnet 42:be4b9ee3a615 57 puts("Not connected to cellular network!\n\r");
fkellermavnet 42:be4b9ee3a615 58 reportStatus = false;
fkellermavnet 42:be4b9ee3a615 59 }
fkellermavnet 42:be4b9ee3a615 60 // Atempt to re-register
fkellermavnet 42:be4b9ee3a615 61 // string * pRespStr;
fkellermavnet 42:be4b9ee3a615 62 // pc.puts("Force re-register!\r\n");
fkellermavnet 42:be4b9ee3a615 63 // at_send_wnc_cmd("AT+CFUN=0,0", &pRespStr, WNC_TIMEOUT_MS);
fkellermavnet 42:be4b9ee3a615 64 // wait_ms(31000);
fkellermavnet 42:be4b9ee3a615 65 // at_send_wnc_cmd("AT+CFUN=1,0", &pRespStr, WNC_TIMEOUT_MS);
fkellermavnet 42:be4b9ee3a615 66 // wait_ms(31000);
fkellermavnet 42:be4b9ee3a615 67 WNC_MDM_ERR = WNC_NO_RESPONSE;
fkellermavnet 42:be4b9ee3a615 68 }
fkellermavnet 42:be4b9ee3a615 69 } while (WNC_MDM_ERR != WNC_OK);
JMF 2:0e2ef866af95 70 }
JMF 2:0e2ef866af95 71
JMF 2:0e2ef866af95 72 void resolve_mdm(void)
JMF 2:0e2ef866af95 73 {
JMF 2:0e2ef866af95 74 do
JMF 2:0e2ef866af95 75 {
JMF 2:0e2ef866af95 76 WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 77 at_dnsresolve_wnc(MY_SERVER_URL, &MyServerIpAddress);
JMF 2:0e2ef866af95 78 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 79 {
JMF 2:0e2ef866af95 80 software_init_mdm();
JMF 2:0e2ef866af95 81 }
JMF 2:0e2ef866af95 82 else if (WNC_MDM_ERR == WNC_CMD_ERR)
JMF 2:0e2ef866af95 83 {
JMF 2:0e2ef866af95 84 pc.puts("Bad URL!!!!!!\r\n");
JMF 2:0e2ef866af95 85 MyServerIpAddress = "192.168.0.1";
JMF 2:0e2ef866af95 86 WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 87 }
JMF 2:0e2ef866af95 88 } while (WNC_MDM_ERR != WNC_OK);
JMF 2:0e2ef866af95 89
fkellermavnet 30:33be8e2992f3 90 pc.printf("My Server IP: %s\r\n", MyServerIpAddress.c_str());
JMF 2:0e2ef866af95 91 }
JMF 2:0e2ef866af95 92
JMF 2:0e2ef866af95 93 void sockopen_mdm(void)
JMF 2:0e2ef866af95 94 {
JMF 2:0e2ef866af95 95 do
JMF 2:0e2ef866af95 96 {
JMF 2:0e2ef866af95 97 WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 98 at_sockopen_wnc(MyServerIpAddress, MY_PORT_STR);
JMF 2:0e2ef866af95 99 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 100 {
JMF 2:0e2ef866af95 101 software_init_mdm();
JMF 2:0e2ef866af95 102 }
JMF 2:0e2ef866af95 103 else if (WNC_MDM_ERR == WNC_CMD_ERR)
JMF 2:0e2ef866af95 104 pc.puts("Socket open fail!!!!\r\n");
fkellermavnet 10:df54436ecd38 105 else
fkellermavnet 10:df54436ecd38 106 socketOpen = 1;
JMF 2:0e2ef866af95 107 } while (WNC_MDM_ERR != WNC_OK);
JMF 2:0e2ef866af95 108 }
JMF 2:0e2ef866af95 109
JMF 2:0e2ef866af95 110 void sockwrite_mdm(const char * s)
JMF 2:0e2ef866af95 111 {
fkellermavnet 10:df54436ecd38 112 if (socketOpen == 1)
fkellermavnet 10:df54436ecd38 113 {
JMF 2:0e2ef866af95 114 do
JMF 2:0e2ef866af95 115 {
JMF 2:0e2ef866af95 116 WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 117 at_sockwrite_wnc(s);
JMF 2:0e2ef866af95 118 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 119 {
fkellermavnet 42:be4b9ee3a615 120 pc.puts("Sock write no response!\r\n");
JMF 2:0e2ef866af95 121 software_init_mdm();
JMF 2:0e2ef866af95 122 }
JMF 2:0e2ef866af95 123 else if (WNC_MDM_ERR == WNC_CMD_ERR)
JMF 2:0e2ef866af95 124 {
JMF 2:0e2ef866af95 125 pc.puts("Socket Write fail!!!\r\n");
JMF 2:0e2ef866af95 126 software_init_mdm();
JMF 2:0e2ef866af95 127 }
JMF 2:0e2ef866af95 128 } while (WNC_MDM_ERR != WNC_OK);
fkellermavnet 10:df54436ecd38 129 }
fkellermavnet 10:df54436ecd38 130 else
fkellermavnet 10:df54436ecd38 131 puts("Socket is closed for write!\r\n");
JMF 2:0e2ef866af95 132 }
JMF 2:0e2ef866af95 133
fkellermavnet 30:33be8e2992f3 134 unsigned sockread_mdm(string * sockData, int len, int retries)
JMF 2:0e2ef866af95 135 {
fkellermavnet 30:33be8e2992f3 136 unsigned n = 0;
fkellermavnet 30:33be8e2992f3 137
fkellermavnet 30:33be8e2992f3 138 // Clean slate:
fkellermavnet 30:33be8e2992f3 139 sockData->erase();
fkellermavnet 30:33be8e2992f3 140
fkellermavnet 10:df54436ecd38 141 if (socketOpen == 1)
fkellermavnet 10:df54436ecd38 142 {
JMF 2:0e2ef866af95 143 do
JMF 2:0e2ef866af95 144 {
JMF 2:0e2ef866af95 145 WNC_MDM_ERR = WNC_OK;
fkellermavnet 30:33be8e2992f3 146 n = at_sockread_wnc(sockData, len, retries);
JMF 2:0e2ef866af95 147 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 148 {
fkellermavnet 30:33be8e2992f3 149 if (n == 0)
fkellermavnet 30:33be8e2992f3 150 software_init_mdm();
fkellermavnet 30:33be8e2992f3 151 else
fkellermavnet 30:33be8e2992f3 152 puts("Sock read partial data!!!\r\n");
JMF 2:0e2ef866af95 153 }
JMF 2:0e2ef866af95 154 else if (WNC_MDM_ERR == WNC_CMD_ERR)
JMF 2:0e2ef866af95 155 puts("Sock read fail!!!!\r\n");
fkellermavnet 30:33be8e2992f3 156 } while (WNC_MDM_ERR == WNC_NO_RESPONSE);
fkellermavnet 10:df54436ecd38 157 }
fkellermavnet 10:df54436ecd38 158 else
fkellermavnet 10:df54436ecd38 159 puts("Socket is closed for read\r\n");
fkellermavnet 30:33be8e2992f3 160
fkellermavnet 30:33be8e2992f3 161 return (n);
JMF 2:0e2ef866af95 162 }
JMF 2:0e2ef866af95 163
JMF 2:0e2ef866af95 164 void sockclose_mdm(void)
JMF 2:0e2ef866af95 165 {
JMF 2:0e2ef866af95 166 do
JMF 2:0e2ef866af95 167 {
JMF 2:0e2ef866af95 168 WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 169 at_sockclose_wnc();
fkellermavnet 10:df54436ecd38 170 // Assume close happened even if it went bad
fkellermavnet 10:df54436ecd38 171 // going bad will result in a re-init anyways and if close
fkellermavnet 10:df54436ecd38 172 // fails we're pretty much in bad state and not much can do
fkellermavnet 10:df54436ecd38 173 socketOpen = 0;
JMF 2:0e2ef866af95 174 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 175 {
JMF 2:0e2ef866af95 176 software_init_mdm();
JMF 2:0e2ef866af95 177 }
JMF 2:0e2ef866af95 178 else if (WNC_MDM_ERR == WNC_CMD_ERR)
JMF 2:0e2ef866af95 179 puts("Sock close fail!!!\r\n");
JMF 2:0e2ef866af95 180 } while (WNC_MDM_ERR != WNC_OK);
JMF 2:0e2ef866af95 181 }
JMF 2:0e2ef866af95 182
JMF 2:0e2ef866af95 183 /**
JMF 2:0e2ef866af95 184 * C++ version 0.4 char* style "itoa":
JMF 2:0e2ef866af95 185 * Written by Lukás Chmela
JMF 2:0e2ef866af95 186 * Released under GPLv3.
JMF 2:0e2ef866af95 187 */
JMF 2:0e2ef866af95 188
JMF 2:0e2ef866af95 189 char* itoa(int value, char* result, int base)
JMF 2:0e2ef866af95 190 {
JMF 2:0e2ef866af95 191 // check that the base if valid
JMF 2:0e2ef866af95 192 if ( base < 2 || base > 36 ) {
JMF 2:0e2ef866af95 193 *result = '\0';
JMF 2:0e2ef866af95 194 return result;
JMF 2:0e2ef866af95 195 }
JMF 2:0e2ef866af95 196
JMF 2:0e2ef866af95 197 char* ptr = result, *ptr1 = result, tmp_char;
JMF 2:0e2ef866af95 198 int tmp_value;
JMF 2:0e2ef866af95 199
JMF 2:0e2ef866af95 200 do {
JMF 2:0e2ef866af95 201 tmp_value = value;
JMF 2:0e2ef866af95 202 value /= base;
JMF 2:0e2ef866af95 203 *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)];
JMF 2:0e2ef866af95 204 } while ( value );
JMF 2:0e2ef866af95 205
JMF 2:0e2ef866af95 206 // Apply negative sign
JMF 2:0e2ef866af95 207 if ( tmp_value < 0 )
JMF 2:0e2ef866af95 208 *ptr++ = '-';
JMF 2:0e2ef866af95 209 *ptr-- = '\0';
JMF 2:0e2ef866af95 210
JMF 2:0e2ef866af95 211 while ( ptr1 < ptr ) {
JMF 2:0e2ef866af95 212 tmp_char = *ptr;
JMF 2:0e2ef866af95 213 *ptr-- = *ptr1;
JMF 2:0e2ef866af95 214 *ptr1++ = tmp_char;
JMF 2:0e2ef866af95 215 }
JMF 2:0e2ef866af95 216
JMF 2:0e2ef866af95 217 return result;
JMF 2:0e2ef866af95 218 }
JMF 2:0e2ef866af95 219
JMF 2:0e2ef866af95 220 extern int mdm_sendAtCmdRsp(const char *cmd, const char **rsp_list, int timeout_ms, string * rsp, int * len);
JMF 2:0e2ef866af95 221
fkellermavnet 42:be4b9ee3a615 222 int check_wnc_ready(void)
fkellermavnet 42:be4b9ee3a615 223 {
fkellermavnet 43:6821a9c78c4b 224 string * pRespStr;
fkellermavnet 43:6821a9c78c4b 225 size_t pos;
fkellermavnet 43:6821a9c78c4b 226 int regSts;
fkellermavnet 42:be4b9ee3a615 227
fkellermavnet 43:6821a9c78c4b 228 pc.puts("<-------- Begin Cell Status ------------\r\n");
fkellermavnet 42:be4b9ee3a615 229
fkellermavnet 43:6821a9c78c4b 230 at_send_wnc_cmd("AT+CSQ", &pRespStr, WNC_TIMEOUT_MS); // Check RSSI,BER
fkellermavnet 43:6821a9c78c4b 231 at_send_wnc_cmd("AT+CPIN?", &pRespStr, WNC_TIMEOUT_MS); // Check if SIM locked
fkellermavnet 42:be4b9ee3a615 232
fkellermavnet 43:6821a9c78c4b 233 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
fkellermavnet 43:6821a9c78c4b 234 {
fkellermavnet 43:6821a9c78c4b 235 pc.puts("------------ WNC No Response! --------->\r\n");
fkellermavnet 43:6821a9c78c4b 236 return (-2);
fkellermavnet 43:6821a9c78c4b 237 }
fkellermavnet 42:be4b9ee3a615 238
fkellermavnet 43:6821a9c78c4b 239 // If SIM Card not ready don't bother with commands!
fkellermavnet 43:6821a9c78c4b 240 if (pRespStr->find("CPIN: READY") == string::npos)
fkellermavnet 43:6821a9c78c4b 241 {
fkellermavnet 43:6821a9c78c4b 242 pc.puts("------------ WNC SIM Problem! --------->\r\n");
fkellermavnet 43:6821a9c78c4b 243 return (-1);
fkellermavnet 43:6821a9c78c4b 244 }
fkellermavnet 43:6821a9c78c4b 245
fkellermavnet 43:6821a9c78c4b 246 // SIM card OK, now check for signal and cellular network registration
fkellermavnet 42:be4b9ee3a615 247 at_send_wnc_cmd("AT+CREG?", &pRespStr, WNC_TIMEOUT_MS); // Check if registered on network
fkellermavnet 42:be4b9ee3a615 248 pos = pRespStr->find("CREG: ");
fkellermavnet 42:be4b9ee3a615 249 if (pos != string::npos)
fkellermavnet 42:be4b9ee3a615 250 {
fkellermavnet 43:6821a9c78c4b 251 // The registration is the 2nd arg in the comma separated list
fkellermavnet 43:6821a9c78c4b 252 *pRespStr = pRespStr->substr(pos+8, 1);
fkellermavnet 43:6821a9c78c4b 253 regSts = atoi(pRespStr->c_str());
fkellermavnet 43:6821a9c78c4b 254 // 1 - registered home, 5 - registered roaming
fkellermavnet 43:6821a9c78c4b 255 if ((regSts != 1) && (regSts != 5))
fkellermavnet 43:6821a9c78c4b 256 {
fkellermavnet 43:6821a9c78c4b 257 pc.puts("------------ WNC Cell Link Down! ------>\r\n");
fkellermavnet 43:6821a9c78c4b 258 return (-2);
fkellermavnet 43:6821a9c78c4b 259 }
fkellermavnet 42:be4b9ee3a615 260 }
fkellermavnet 43:6821a9c78c4b 261
fkellermavnet 43:6821a9c78c4b 262 pc.puts("------------ WNC Ready ---------------->\r\n");
fkellermavnet 42:be4b9ee3a615 263
fkellermavnet 43:6821a9c78c4b 264 return (0);
fkellermavnet 42:be4b9ee3a615 265 }
fkellermavnet 42:be4b9ee3a615 266
JMF 2:0e2ef866af95 267 // Sets a global with failure or success, assumes 1 thread all the time
JMF 2:0e2ef866af95 268 int send_wnc_cmd(const char * s, string ** r, int ms_timeout)
JMF 2:0e2ef866af95 269 {
fkellermavnet 42:be4b9ee3a615 270 if (check_wnc_ready() < 0)
fkellermavnet 42:be4b9ee3a615 271 {
fkellermavnet 42:be4b9ee3a615 272 string truncStr(s, 50);
fkellermavnet 42:be4b9ee3a615 273 pc.puts("FAIL send cmd: ");
fkellermavnet 42:be4b9ee3a615 274 pc.puts(truncStr.c_str());
fkellermavnet 42:be4b9ee3a615 275 pc.puts("\r\n");
fkellermavnet 42:be4b9ee3a615 276 WNC_MDM_ERR = WNC_NO_RESPONSE;
fkellermavnet 42:be4b9ee3a615 277 return (-2);
fkellermavnet 42:be4b9ee3a615 278 }
fkellermavnet 42:be4b9ee3a615 279
fkellermavnet 42:be4b9ee3a615 280 // If WNC ready, send user command
fkellermavnet 42:be4b9ee3a615 281 return (at_send_wnc_cmd(s, r, ms_timeout));
fkellermavnet 42:be4b9ee3a615 282 }
fkellermavnet 42:be4b9ee3a615 283
fkellermavnet 42:be4b9ee3a615 284 int at_send_wnc_cmd(const char * s, string ** r, int ms_timeout)
fkellermavnet 42:be4b9ee3a615 285 {
JMF 2:0e2ef866af95 286 static const char * rsp_lst[] = { "OK", "ERROR", NULL };
JMF 2:0e2ef866af95 287 int len;
fkellermavnet 42:be4b9ee3a615 288 if (strlen(s) > 60)
fkellermavnet 42:be4b9ee3a615 289 {
fkellermavnet 42:be4b9ee3a615 290 string truncStr(s,57);
fkellermavnet 42:be4b9ee3a615 291 truncStr += "...";
fkellermavnet 42:be4b9ee3a615 292 pc.printf("Send: <<%s>>\r\n",truncStr.c_str());
fkellermavnet 42:be4b9ee3a615 293 }
fkellermavnet 42:be4b9ee3a615 294 else
fkellermavnet 42:be4b9ee3a615 295 pc.printf("Send: <<%s>>\r\n",s);
fkellermavnet 42:be4b9ee3a615 296
JMF 2:0e2ef866af95 297 int res = mdm_sendAtCmdRsp(s, rsp_lst, ms_timeout, &wncStr, &len);
JMF 2:0e2ef866af95 298 *r = &wncStr; // Return a pointer to the static string
JMF 2:0e2ef866af95 299
JMF 2:0e2ef866af95 300 if (res >= 0)
fkellermavnet 42:be4b9ee3a615 301 {
JMF 2:0e2ef866af95 302 pc.puts("[");
fkellermavnet 42:be4b9ee3a615 303 if (wncStr.size() < 51)
fkellermavnet 42:be4b9ee3a615 304 pc.puts(wncStr.c_str());
fkellermavnet 42:be4b9ee3a615 305 else
fkellermavnet 42:be4b9ee3a615 306 {
fkellermavnet 42:be4b9ee3a615 307 string truncStr = wncStr.substr(0,50) + "...";
fkellermavnet 42:be4b9ee3a615 308 pc.puts(truncStr.c_str());
fkellermavnet 42:be4b9ee3a615 309 }
JMF 2:0e2ef866af95 310 pc.puts("]\n\r");
fkellermavnet 42:be4b9ee3a615 311
JMF 2:0e2ef866af95 312 if (res > 0)
JMF 2:0e2ef866af95 313 {
JMF 2:0e2ef866af95 314 if (WNC_MDM_ERR != WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 315 WNC_MDM_ERR = WNC_CMD_ERR;
JMF 2:0e2ef866af95 316 return -1;
JMF 2:0e2ef866af95 317 }
JMF 2:0e2ef866af95 318 else
JMF 2:0e2ef866af95 319 return 0;
JMF 2:0e2ef866af95 320 }
JMF 2:0e2ef866af95 321 else
JMF 2:0e2ef866af95 322 {
JMF 2:0e2ef866af95 323 WNC_MDM_ERR = WNC_NO_RESPONSE;
JMF 2:0e2ef866af95 324 pc.puts("No response from WNC!\n\r");
JMF 2:0e2ef866af95 325 return -2;
JMF 2:0e2ef866af95 326 }
JMF 2:0e2ef866af95 327 }
JMF 2:0e2ef866af95 328
fkellermavnet 42:be4b9ee3a615 329
fkellermavnet 19:f89baed3bd6f 330 void at_at_wnc(void)
fkellermavnet 19:f89baed3bd6f 331 {
fkellermavnet 19:f89baed3bd6f 332 string * pRespStr;
fkellermavnet 19:f89baed3bd6f 333 send_wnc_cmd("AT", &pRespStr, WNC_TIMEOUT_MS); // Heartbeat?
fkellermavnet 19:f89baed3bd6f 334 }
fkellermavnet 19:f89baed3bd6f 335
fkellermavnet 42:be4b9ee3a615 336 void at_init_wnc(bool hardReset)
JMF 2:0e2ef866af95 337 {
fkellermavnet 36:d4782eabff43 338 static bool pdnSet = false;
fkellermavnet 42:be4b9ee3a615 339 static bool intSet = false;
fkellermavnet 42:be4b9ee3a615 340 static bool sockDialSet = false;
fkellermavnet 42:be4b9ee3a615 341 string * pRespStr;
fkellermavnet 36:d4782eabff43 342
fkellermavnet 42:be4b9ee3a615 343 if (hardReset == true)
fkellermavnet 42:be4b9ee3a615 344 {
fkellermavnet 43:6821a9c78c4b 345 pc.puts("Hard Reset!\r\n");
fkellermavnet 42:be4b9ee3a615 346 pdnSet = false;
fkellermavnet 42:be4b9ee3a615 347 intSet = false;
fkellermavnet 42:be4b9ee3a615 348 sockDialSet = false;
fkellermavnet 42:be4b9ee3a615 349 }
fkellermavnet 42:be4b9ee3a615 350
fkellermavnet 43:6821a9c78c4b 351 WNC_MDM_ERR = WNC_OK; // Below commands will re-establish error state
fkellermavnet 36:d4782eabff43 352 pc.puts("Start AT init of WNC:\r\n");
fkellermavnet 43:6821a9c78c4b 353 // Quick commands below do not need to check cellular connectivity
fkellermavnet 43:6821a9c78c4b 354 at_send_wnc_cmd("AT", &pRespStr, WNC_TIMEOUT_MS); // Heartbeat?
fkellermavnet 43:6821a9c78c4b 355 at_send_wnc_cmd("ATE0", &pRespStr, WNC_TIMEOUT_MS); // Echo Off
fkellermavnet 43:6821a9c78c4b 356 at_send_wnc_cmd("AT+CMEE=2", &pRespStr, WNC_TIMEOUT_MS); // 2 - verbose error, 1 - numeric error, 0 - just ERROR
fkellermavnet 43:6821a9c78c4b 357
fkellermavnet 43:6821a9c78c4b 358 // If the simple commands are not working no chance of more complex.
fkellermavnet 43:6821a9c78c4b 359 // I have seen re-trying commands make it worse.
fkellermavnet 43:6821a9c78c4b 360 if (WNC_MDM_ERR != WNC_OK)
fkellermavnet 43:6821a9c78c4b 361 return ;
fkellermavnet 42:be4b9ee3a615 362
fkellermavnet 42:be4b9ee3a615 363 if ((WNC_MDM_ERR == WNC_OK) && (intSet == false))
fkellermavnet 42:be4b9ee3a615 364 send_wnc_cmd("AT@INTERNET=1", &pRespStr, WNC_TIMEOUT_MS);
fkellermavnet 42:be4b9ee3a615 365
fkellermavnet 42:be4b9ee3a615 366 if (WNC_MDM_ERR == WNC_OK)
fkellermavnet 42:be4b9ee3a615 367 intSet = true;
fkellermavnet 42:be4b9ee3a615 368 else
fkellermavnet 42:be4b9ee3a615 369 return ;
fkellermavnet 42:be4b9ee3a615 370
fkellermavnet 36:d4782eabff43 371 if (pdnSet == false)
fkellermavnet 36:d4782eabff43 372 {
fkellermavnet 36:d4782eabff43 373 string cmd_str("AT%PDNSET=1,");
fkellermavnet 36:d4782eabff43 374 cmd_str += MY_APN_STR;
fkellermavnet 36:d4782eabff43 375 cmd_str += ",IP";
fkellermavnet 36:d4782eabff43 376 send_wnc_cmd(cmd_str.c_str(), &pRespStr, 4*WNC_TIMEOUT_MS); // Set APN, cmd seems to take a little longer sometimes
fkellermavnet 42:be4b9ee3a615 377 }
fkellermavnet 42:be4b9ee3a615 378
fkellermavnet 42:be4b9ee3a615 379 if (WNC_MDM_ERR == WNC_OK)
fkellermavnet 42:be4b9ee3a615 380 pdnSet = true;
fkellermavnet 42:be4b9ee3a615 381 else
fkellermavnet 42:be4b9ee3a615 382 return ;
fkellermavnet 42:be4b9ee3a615 383
fkellermavnet 42:be4b9ee3a615 384 if (sockDialSet == false)
fkellermavnet 36:d4782eabff43 385 send_wnc_cmd("AT@SOCKDIAL=1", &pRespStr, WNC_TIMEOUT_MS);
fkellermavnet 42:be4b9ee3a615 386
fkellermavnet 42:be4b9ee3a615 387 if (WNC_MDM_ERR == WNC_OK)
fkellermavnet 42:be4b9ee3a615 388 sockDialSet = true;
fkellermavnet 42:be4b9ee3a615 389 else
fkellermavnet 42:be4b9ee3a615 390 return ;
fkellermavnet 42:be4b9ee3a615 391
fkellermavnet 42:be4b9ee3a615 392 pc.puts("SUCCESS: AT init of WNC!\r\n");
JMF 2:0e2ef866af95 393 }
JMF 2:0e2ef866af95 394
JMF 2:0e2ef866af95 395 void at_sockopen_wnc(const string & ipStr, const char * port )
JMF 2:0e2ef866af95 396 {
JMF 2:0e2ef866af95 397 string * pRespStr;
JMF 2:0e2ef866af95 398 send_wnc_cmd("AT@SOCKCREAT=1", &pRespStr, WNC_TIMEOUT_MS);
JMF 2:0e2ef866af95 399 string cmd_str("AT@SOCKCONN=1,\"");
JMF 2:0e2ef866af95 400 cmd_str += ipStr;
JMF 2:0e2ef866af95 401 cmd_str += "\",";
JMF 2:0e2ef866af95 402 cmd_str += port;
fkellermavnet 38:564b312a719f 403 cmd_str += ",30";
fkellermavnet 39:1996eaec02d6 404 send_wnc_cmd(cmd_str.c_str(), &pRespStr, 31000);
JMF 2:0e2ef866af95 405 }
JMF 2:0e2ef866af95 406
JMF 2:0e2ef866af95 407 void at_sockclose_wnc(void)
JMF 2:0e2ef866af95 408 {
JMF 2:0e2ef866af95 409 string * pRespStr;
JMF 2:0e2ef866af95 410 send_wnc_cmd("AT@SOCKCLOSE=1", &pRespStr, WNC_TIMEOUT_MS);
JMF 2:0e2ef866af95 411 }
JMF 2:0e2ef866af95 412
JMF 2:0e2ef866af95 413 int at_dnsresolve_wnc(const char * s, string * ipStr)
JMF 2:0e2ef866af95 414 {
JMF 2:0e2ef866af95 415 string * pRespStr;
JMF 2:0e2ef866af95 416 string str(s);
fkellermavnet 43:6821a9c78c4b 417 str = "AT@DNSRESVDON=\"" + str + "\"";
fkellermavnet 30:33be8e2992f3 418 if (send_wnc_cmd(str.c_str(), &pRespStr, WNC_TIMEOUT_MS) == 0)
JMF 2:0e2ef866af95 419 {
JMF 2:0e2ef866af95 420 size_t pos_start = pRespStr->find(":\"") + 2;
fkellermavnet 43:6821a9c78c4b 421 size_t pos_end = pRespStr->rfind("\"") - 1;
fkellermavnet 43:6821a9c78c4b 422 if ((pos_start != string::npos) && (pos_end != string::npos))
JMF 2:0e2ef866af95 423 {
JMF 2:0e2ef866af95 424 if (pos_end > pos_start)
JMF 2:0e2ef866af95 425 {
JMF 2:0e2ef866af95 426 // Make a copy for use later (the source string is re-used)
JMF 2:0e2ef866af95 427 *ipStr = pRespStr->substr(pos_start, pos_end - pos_start + 1);
JMF 2:0e2ef866af95 428 return 1;
JMF 2:0e2ef866af95 429 }
JMF 2:0e2ef866af95 430 else
JMF 2:0e2ef866af95 431 pc.puts("URL Resolve fail, substr Err\r\n");
JMF 2:0e2ef866af95 432 }
JMF 2:0e2ef866af95 433 else
JMF 2:0e2ef866af95 434 pc.puts("URL Resolve fail, no quotes\r\n");
JMF 2:0e2ef866af95 435 }
JMF 2:0e2ef866af95 436 else
JMF 2:0e2ef866af95 437 pc.puts("URL Resolve fail, WNC cmd fail\r\n");
JMF 2:0e2ef866af95 438
fkellermavnet 43:6821a9c78c4b 439 *ipStr = "192.168.0.1";
fkellermavnet 43:6821a9c78c4b 440
JMF 2:0e2ef866af95 441 return -1;
JMF 2:0e2ef866af95 442 }
JMF 2:0e2ef866af95 443
JMF 2:0e2ef866af95 444 void at_sockwrite_wnc(const char * s)
JMF 2:0e2ef866af95 445 {
JMF 2:0e2ef866af95 446 string * pRespStr;
JMF 2:0e2ef866af95 447 char num2str[6];
JMF 2:0e2ef866af95 448 size_t sLen = strlen(s);
fkellermavnet 39:1996eaec02d6 449 if (sLen <= 1500)
JMF 2:0e2ef866af95 450 {
JMF 2:0e2ef866af95 451 string cmd_str("AT@SOCKWRITE=1,");
JMF 2:0e2ef866af95 452 itoa(sLen, num2str, 10);
JMF 2:0e2ef866af95 453 cmd_str += num2str;
JMF 2:0e2ef866af95 454 cmd_str += ",\"";
JMF 2:0e2ef866af95 455 while(*s != '\0')
JMF 2:0e2ef866af95 456 {
JMF 2:0e2ef866af95 457 itoa((int)*s++, num2str, 16);
JMF 2:0e2ef866af95 458 // Always 2-digit ascii hex:
JMF 2:0e2ef866af95 459 if (strlen(num2str) == 1)
JMF 2:0e2ef866af95 460 {
JMF 2:0e2ef866af95 461 num2str[2] = '\0';
JMF 2:0e2ef866af95 462 num2str[1] = num2str[0];
JMF 2:0e2ef866af95 463 num2str[0] = '0';
JMF 2:0e2ef866af95 464 }
JMF 2:0e2ef866af95 465 cmd_str += num2str;
JMF 2:0e2ef866af95 466 }
JMF 2:0e2ef866af95 467 cmd_str += "\"";
fkellermavnet 42:be4b9ee3a615 468 send_wnc_cmd(cmd_str.c_str(), &pRespStr, 120000);
JMF 2:0e2ef866af95 469 }
JMF 2:0e2ef866af95 470 else
JMF 2:0e2ef866af95 471 pc.puts("sockwrite Err, string to long\r\n");
JMF 2:0e2ef866af95 472 }
JMF 2:0e2ef866af95 473
JMF 2:0e2ef866af95 474 unsigned at_sockread_wnc(string * pS, unsigned n, unsigned retries = 0)
JMF 2:0e2ef866af95 475 {
fkellermavnet 34:1a4498e3580e 476 unsigned i, numBytes = 0;
JMF 2:0e2ef866af95 477 string * pRespStr;
JMF 2:0e2ef866af95 478 string cmd_str("AT@SOCKREAD=1,");
fkellermavnet 30:33be8e2992f3 479
JMF 2:0e2ef866af95 480 if (n <= 1500)
JMF 2:0e2ef866af95 481 {
JMF 2:0e2ef866af95 482 char num2str[6];
fkellermavnet 22:41e6c417ace1 483
JMF 2:0e2ef866af95 484 itoa(n, num2str, 10);
JMF 2:0e2ef866af95 485 cmd_str += num2str;
JMF 2:0e2ef866af95 486 retries += 1;
JMF 2:0e2ef866af95 487 while (retries--)
JMF 2:0e2ef866af95 488 {
fkellermavnet 22:41e6c417ace1 489 // Assuming someone is sending then calling this to receive response, invoke
fkellermavnet 22:41e6c417ace1 490 // a pause to give the response some time to come back and then also
fkellermavnet 22:41e6c417ace1 491 // between each retry.
fkellermavnet 22:41e6c417ace1 492 wait_ms(10);
fkellermavnet 22:41e6c417ace1 493
fkellermavnet 30:33be8e2992f3 494 send_wnc_cmd(cmd_str.c_str(), &pRespStr, WNC_TIMEOUT_MS);
fkellermavnet 43:6821a9c78c4b 495
JMF 2:0e2ef866af95 496 size_t pos_start = pRespStr->find("\"") + 1;
JMF 2:0e2ef866af95 497 size_t pos_end = pRespStr->rfind("\"") - 1;
fkellermavnet 43:6821a9c78c4b 498
fkellermavnet 43:6821a9c78c4b 499 // Make sure search finds what it's looking for!
fkellermavnet 43:6821a9c78c4b 500 if (pos_start != string::npos && pos_end != string::npos)
fkellermavnet 43:6821a9c78c4b 501 i = (pos_end - pos_start + 1); // Num hex chars, 2 per byte
fkellermavnet 43:6821a9c78c4b 502 else
fkellermavnet 43:6821a9c78c4b 503 i = 0;
fkellermavnet 43:6821a9c78c4b 504
JMF 2:0e2ef866af95 505 if (i > 0)
JMF 2:0e2ef866af95 506 {
fkellermavnet 34:1a4498e3580e 507 retries = 1; // If any data found retry 1 more time to catch data that might be in another
fkellermavnet 34:1a4498e3580e 508 // WNC payload
JMF 2:0e2ef866af95 509 string byte;
JMF 2:0e2ef866af95 510 while (pos_start < pos_end)
JMF 2:0e2ef866af95 511 {
JMF 2:0e2ef866af95 512 byte = pRespStr->substr(pos_start, 2);
fkellermavnet 30:33be8e2992f3 513 *pS += (char)strtol(byte.c_str(), NULL, 16);
JMF 2:0e2ef866af95 514 pos_start += 2;
JMF 2:0e2ef866af95 515 }
fkellermavnet 34:1a4498e3580e 516 numBytes += i/2;
JMF 2:0e2ef866af95 517 }
JMF 2:0e2ef866af95 518 }
JMF 2:0e2ef866af95 519 }
JMF 2:0e2ef866af95 520 else
JMF 2:0e2ef866af95 521 pc.puts("sockread Err, to many to read\r\n");
JMF 2:0e2ef866af95 522
fkellermavnet 43:6821a9c78c4b 523 return (numBytes);
JMF 2:0e2ef866af95 524 }