Example of AWS IoT connection and Web Dashboard thru STM32 Nucleo evaluation board and mbed OS.
Dependencies: X_NUCLEO_IKS01A1 mbed FP MQTTPacket DnsQuery ATParser
Introduction
The demo is aimed to STM32 Nucleo board with WiFi and sensors expansions. The board is a "thing" for the AWS IoT service. It updates IoT service shadow with sensors data every second and checks subscription messages.
Hardware Configuration
- NUCLEO-F401RE - Nucleo Development Board
- X-NUCLEO-IDW01M1 - Wi-Fi expansion board for STM32 Nucleo
- X-NUCLEO-IKS01A1 - Motion MEMS and environmental sensor expansion board for STM32 Nucleo
Software Configuration
- Import this Project to mbed online compiler
- Find the next part of code in main.cpp file ...
WiFi network credential
#include "mbed.h" // WiFi network credential #define SSID "" // Network must be visible otherwise it can't connect #define PASSW "" #error "Wifi SSID & password empty"
- ... And set it to your Network Name and Password. Do not forget to remove "#error" pragma line.
Information
Nucleo WiFi module is not the same as your smartphone or laptope - it is based on demo board. To avoid connection problems:
- Place Nucleo as close to WiFi hot spot as possible. Or...
- Turn on mobile hot spot in your laptop as close to the device as possible.
- Make sure that hot spot permits 2.4 GHz band communications
- Setup BackEnd and store certificates using this backend setup instruction
- Find AWS_IOT_MQTT_HOST define and change it to HTTPS point mentioned in your AWS IoT thing properties named "interact"
#define AWS_IOT_MQTT_HOST "xxxxxxxxxx.iot.us-east-1.amazonaws.com" //Use your own host.
- Find the certificate defines clientCRT and clientKey in main.cpp file and change it to ones provided by Amazon.
/********************************************************************************************** *********************************************************************************************** Device Identity Certificates: Modify for your AWS IoT Thing *********************************************************************************************** ***********************************************************************************************/ /**************************************** (somecode)-certificate.pem.crt - Amazon signed PEM sertificate. *****************************************/ //This Client cert is example. Use own instead. const uint8_t clientCRT[] = "\ -----BEGIN CERTIFICATE-----\n\ MIIDBjCCAe6gAwIBAgIUVph856omeIxW3UPioq+UrX1DbwowDQYJKoZIhvcNAQEL\ BQAwTTFLMEkGA1UECwxCQW1hem9uIFdlYiBTZXJ2aWNlcyBPPUFtYXpvbi5jb20g\ SW5jLiBMPVNlYXR0bGUgU1Q9V2FzaGluZ3RvbiBDPVVTMB4XDTE3MDUyNTExNTEy\ OVoXDTQ5MTIzMTIzNTk1OVowgZUxCzAJBgNVBAYTAkJZMQ4wDAYDVQQIDAVNaW5z\ azEOMAwGA1UEBwwFTWluc2sxFzAVBgNVBAoMDktsaWthLVRlY2ggTExDMRcwFQYD\ VQQLDA5LbGlrYS1UZWNoIExMQzEMMAoGA1UEAwwDUm5EMSYwJAYJKoZIhvcNAQkB\ FhdtdmF0YWxldUBrbGlrYS10ZWNoLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEH\ A0IABCJgOQJmoTBJVPfli9Hm/JVixaxkY5rtlgrYO3hSl633A2hg0P/ue0wXDbF3\ aQ0X57IRFE4k4FEbr3UXjT/IczKjYDBeMB8GA1UdIwQYMBaAFK3YzTUPlYB2Li75\ i/z8rEogr1d6MB0GA1UdDgQWBBT18HXBaXFJuAR/0SwegnxJ+pyJ6TAMBgNVHRMB\ Af8EAjAAMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAb0Ux1aH5\ RLxjrfGqXN6rPVqh8QQRS+AyBfzmaQN8HaPZMkX5WxXLvcn0A3uWlwQxPPkcZ4zf\ 51GHtFFQWB4YZ8dx8mUQ0v/j7onHjCJgZ8iDgwOyKMGtnsDZWCakQw+a6cj+NrMZ\ tzhjwCzEEP6ePcbXwErI5OOzLuWns2L/JEr2wWNkokgRuS8ewr/SQ9OLWIWa2rFM\ ahPNTb3y/qBeWdjeJmhI+TOxdqIpsF8roWP25zwo/zkzCHCjXFBrL+0CA4MpxIl9\ x02i7aAhlJ6ys80lDxdeWeeQJXRKkGknP8mcmKn3iEqqJ5s1dQePj2b5d3ldatya\ wsxQBqqZXzIWEw==\ \n\ -----END CERTIFICATE-----\n"; /********************************************************************************************** *********************************************************************************************** Private Key: Modify for your AWS IoT Thing *********************************************************************************************** ***********************************************************************************************/ /********************************************************************8**************************************** nucleo.key.pem - client key generated according to readme. **************************************************************************************************************/ //This Client Key is example. Use own instead. const uint8_t clientKey[] ="\ -----BEGIN EC PARAMETERS-----\n\ BggqhkjOPQMBBw==\ -----END EC PARAMETERS-----\n\ -----BEGIN EC PRIVATE KEY-----\n\ MHcCAQEEIHPRfWSC8/k/BsqDWKuP15dXsI9fGwpkTIsLZe6mIrAAoAoGCCqGSM49\ AwEHoUQDQgAEImA5AmahMElU9+WL0eb8lWLFrGRjmu2WCtg7eFKXrfcDaGDQ/+57\ TBcNsXdpDRfnshEUTiTgURuvdReNP8hzMg==\ -----END EC PRIVATE KEY-----\n";
Build and Check
- Plugin your board to USB of your PC. USB Disk Drive and USB COM Port should appear in your system.
- Open any Serial Console, connect it to your USB Serial Port and setup speed equal to 115200.
- Compile this Project and save .bin file to USB Disk Drive
- After board reset you should see next log in serial console:
X-NUCLEO-IDW01M1 mbed Application connecting to AP LOG: int main() L#361 Connected to WiFI. LOG: int connect(MQTT::Client<MQTTWiFi, Countdown, 350, 5> *, MQTTWiFi *) L#186 ===================================== LOG: int connect(MQTT::Client<MQTTWiFi, Countdown, 350, 5> *, MQTTWiFi *) L#187 Connecting WiFi. LOG: int connect(MQTT::Client<MQTTWiFi, Countdown, 350, 5> *, MQTTWiFi *) L#188 Nucleo IP ADDRESS: X.X.X.X LOG: int connect(MQTT::Client<MQTTWiFi, Countdown, 350, 5> *, MQTTWiFi *) L#189 Nucleo MAC ADDRESS: 00:11:22:33:44:55 LOG: int connect(MQTT::Client<MQTTWiFi, Countdown, 350, 5> *, MQTTWiFi *) L#190 Server Hostname: xxxxxxxx.iot.us-east-1.amazonaws.com port: 8883 LOG: int connect(MQTT::Client<MQTTWiFi, Countdown, 350, 5> *, MQTTWiFi *) L#191 Client ID: Nucleo LOG: int connect(MQTT::Client<MQTTWiFi, Countdown, 350, 5> *, MQTTWiFi *) L#194 ===================================== LOG: int MQTTSocket::getNTPtime(int) L#58 Success receiving time from ntp server. Tick from 1 Jan 1970 is equal to 1505399292. --->TCP Connected --->MQTT Connected --->>>MQTT subscribed to: Nucleo/test Length - 245, Publishing {"state": {"reported": {"temperature": 23.690001, "humidity": 98.190002, "pressure": 982.869141, "accelerometer": [-0.009000, 0.030000, 0.971000], "gyroscope": [0.420000, -2.660000, 1.750000], "magnetometer": [-3.600000, -7.100000, 53.300000]}}} Length - 245, Publishing {"state": {"reported": {"temperature": 23.660000, "humidity": 98.010002, "pressure": 982.770264, "accelerometer": [-0.009000, 0.030000, 0.971000], "gyroscope": [0.770000, -2.310000, 1.470000], "magnetometer": [-3.100000, -8.300000, 54.200000]}}} Length - 245, Publishing {"state": {"reported": {"temperature": 23.670000, "humidity": 98.129997, "pressure": 982.724121, "accelerometer": [-0.008000, 0.029000, 0.971000], "gyroscope": [0.630000, -2.380000, 1.400000], "magnetometer": [-3.100000, -7.900000, 53.400000]}}} Length - 245, Publishing {"state": {"reported": {"temperature": 23.690001, "humidity": 98.019997, "pressure": 982.840088, "accelerometer": [-0.009000, 0.030000, 0.972000], "gyroscope": [0.700000, -2.450000, 1.540000], "magnetometer": [-3.700000, -7.900000, 53.400000]}}} Length - 245, Publishing {"state": {"reported": {"temperature": 23.709999, "humidity": 98.040001, "pressure": 982.828613, "accelerometer": [-0.009000, 0.030000, 0.971000], "gyroscope": [0.630000, -2.520000, 1.470000], "magnetometer": [-2.900000, -7.400000, 52.400000]}}} Length - 245, Publishing {"state": {"reported": {"temperature": 23.719999, "humidity": 97.860001, "pressure": 982.917236, "accelerometer": [-0.026000, 0.103000, 0.891000], "gyroscope": [1.050000, -2.310000, 1.260000], "magnetometer": [-3.300000, -7.100000, 53.500000]}}}
Information
Device connection state might be checked by Green Led on the board. Green light means that device is connected and transferring data to cloud.
- Configure and start your dashboard using instruction and corresponding sources from github
- Use Blue button to set up markers to charts.
- Use AWS IoT console MQTT Client to test device subscription to "Nucleo/test". Just publish any message to this topic and serial port output.
- PROFIT!
X_NUCLEO_IDW01M1v2/SPWF01SA/SPWFSA01.cpp@0:4cdaf9b1e7d0, 2017-09-27 (annotated)
- Committer:
- PavelSavyhin
- Date:
- Wed Sep 27 14:40:52 2017 +0300
- Revision:
- 0:4cdaf9b1e7d0
- Child:
- 1:042ca9148926
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
PavelSavyhin | 0:4cdaf9b1e7d0 | 1 | /* SPWFInterface Example |
PavelSavyhin | 0:4cdaf9b1e7d0 | 2 | * Copyright (c) 2015 ARM Limited |
PavelSavyhin | 0:4cdaf9b1e7d0 | 3 | * |
PavelSavyhin | 0:4cdaf9b1e7d0 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 5 | * you may not use this file except in compliance with the License. |
PavelSavyhin | 0:4cdaf9b1e7d0 | 6 | * You may obtain a copy of the License at |
PavelSavyhin | 0:4cdaf9b1e7d0 | 7 | * |
PavelSavyhin | 0:4cdaf9b1e7d0 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
PavelSavyhin | 0:4cdaf9b1e7d0 | 9 | * |
PavelSavyhin | 0:4cdaf9b1e7d0 | 10 | * Unless required by applicable law or agreed to in writing, software |
PavelSavyhin | 0:4cdaf9b1e7d0 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
PavelSavyhin | 0:4cdaf9b1e7d0 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
PavelSavyhin | 0:4cdaf9b1e7d0 | 13 | * See the License for the specific language governing permissions and |
PavelSavyhin | 0:4cdaf9b1e7d0 | 14 | * limitations under the License. |
PavelSavyhin | 0:4cdaf9b1e7d0 | 15 | */ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 16 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 17 | #include "SPWFSA01.h" |
PavelSavyhin | 0:4cdaf9b1e7d0 | 18 | #include "mbed_debug.h" |
PavelSavyhin | 0:4cdaf9b1e7d0 | 19 | #include "stdint.h" |
PavelSavyhin | 0:4cdaf9b1e7d0 | 20 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 21 | #define SPWFSA01_CONNECT_TIMEOUT 15000 |
PavelSavyhin | 0:4cdaf9b1e7d0 | 22 | #define SPWFSA01_SEND_TIMEOUT 500 |
PavelSavyhin | 0:4cdaf9b1e7d0 | 23 | #define SPWFSA01_RECV_TIMEOUT 1500//some commands like AT&F/W takes some time to get the result back! |
PavelSavyhin | 0:4cdaf9b1e7d0 | 24 | #define SPWFSA01_MISC_TIMEOUT 500 |
PavelSavyhin | 0:4cdaf9b1e7d0 | 25 | #define SPWFSA01_SOCKQ_TIMEOUT 3000 |
PavelSavyhin | 0:4cdaf9b1e7d0 | 26 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 27 | #define EPOCH_TIME 1453727657//Human time (GMT): Mon, 25 Jan 2016 13:14:17 GMT |
PavelSavyhin | 0:4cdaf9b1e7d0 | 28 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 29 | SPWFSA01::SPWFSA01(PinName tx, PinName rx, PinName reset, PinName wakeup, bool debug) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 30 | : _serial(tx, rx, 1024), _parser(_serial,"\r\n", 2048), |
PavelSavyhin | 0:4cdaf9b1e7d0 | 31 | _wakeup(wakeup, PIN_OUTPUT, PullNone, 0), |
PavelSavyhin | 0:4cdaf9b1e7d0 | 32 | _reset(reset, PIN_OUTPUT, PullNone, 1), |
PavelSavyhin | 0:4cdaf9b1e7d0 | 33 | dbg_on(debug) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 34 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 35 | _serial.baud(115200); // LICIO FIXME increase the speed |
PavelSavyhin | 0:4cdaf9b1e7d0 | 36 | _parser.debugOn(debug); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 37 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 38 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 39 | bool SPWFSA01::startup(int mode) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 40 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 41 | _parser.setTimeout(SPWFSA01_MISC_TIMEOUT); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 42 | /*Test module before reset*/ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 43 | waitSPWFReady(); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 44 | /*Reset module*/ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 45 | reset(); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 46 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 47 | /*set local echo to 0*/ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 48 | if(!(_parser.send("AT+S.SCFG=localecho1,%d\r", 0) && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 49 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 50 | debug_if(dbg_on, "SPWF> error local echo set\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 51 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 52 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 53 | /*reset factory settings*/ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 54 | if(!(_parser.send("AT&F") && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 55 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 56 | debug_if(dbg_on, "SPWF> error AT&F\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 57 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 58 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 59 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 60 | /*set Wi-Fi mode and rate to b/g*/ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 61 | if(!(_parser.send("AT+S.SCFG=wifi_ht_mode,%d\r", 0) && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 62 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 63 | debug_if(dbg_on, "SPWF> error setting ht_mode\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 64 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 65 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 66 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 67 | //if(!(_parser.send("AT+S.SCFG=wifi_opr_rate_mask,0x003FFFCF\r") && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 68 | if(!(_parser.send("AT+S.SCFG=wifi_opr_rate_mask,0x00000001\r") && _parser.recv("OK")))// set most effective speed for such kind of device |
PavelSavyhin | 0:4cdaf9b1e7d0 | 69 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 70 | debug_if(dbg_on, "SPWF> error setting operational rates\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 71 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 72 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 73 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 74 | if(!(_parser.send("AT+S.SCFG=wifi_bas_rate_mask,0x0000000F\r") && _parser.recv("OK")))// set most effective speed for such kind of device |
PavelSavyhin | 0:4cdaf9b1e7d0 | 75 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 76 | debug_if(dbg_on, "SPWF> error setting basic rates\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 77 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 78 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 79 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 80 | if(!(_parser.send("AT+S.SCFG=wifi_powersave,0\r") && _parser.recv("OK")))// set most effective speed for such kind of device |
PavelSavyhin | 0:4cdaf9b1e7d0 | 81 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 82 | debug_if(dbg_on, "SPWF> error setting power save mode\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 83 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 84 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 85 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 86 | if(!(_parser.send("AT+S.SCFG=sleep_enabled,0\r") && _parser.recv("OK")))// set most effective speed for such kind of device |
PavelSavyhin | 0:4cdaf9b1e7d0 | 87 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 88 | debug_if(dbg_on, "SPWF> error setting sleep mode\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 89 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 90 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 91 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 92 | if(!(_parser.send("AT+S.SCFG=wifi_tx_power,18\r") && _parser.recv("OK")))// set most effective speed for such kind of device |
PavelSavyhin | 0:4cdaf9b1e7d0 | 93 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 94 | debug_if(dbg_on, "SPWF> error setting transmit power\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 95 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 96 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 97 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 98 | if(!(_parser.send("AT+S.SCFG=ip_use_dhcp,1\r") && _parser.recv("OK")))// set most effective speed for such kind of device |
PavelSavyhin | 0:4cdaf9b1e7d0 | 99 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 100 | debug_if(dbg_on, "SPWF> error setting dhcp on\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 101 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 102 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 103 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 104 | if(!(_parser.send("AT+S.SCFG=ip_dhcp_timeout,20\r") && _parser.recv("OK")))// set most effective speed for such kind of device |
PavelSavyhin | 0:4cdaf9b1e7d0 | 105 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 106 | debug_if(dbg_on, "SPWF> error setting dhcp timeout\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 107 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 108 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 109 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 110 | /*set idle mode (0->idle, 1->STA,3->miniAP, 2->IBSS)*/ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 111 | if(!(_parser.send("AT+S.SCFG=wifi_mode,%d\r", mode) && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 112 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 113 | debug_if(dbg_on, "SPWF> error wifi mode set\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 114 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 115 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 116 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 117 | /* save current setting in flash */ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 118 | if(!(_parser.send("AT&W") && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 119 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 120 | debug_if(dbg_on, "SPWF> error AT&W\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 121 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 122 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 123 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 124 | /*reset again and send AT command and check for result (AT->OK)*/ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 125 | reset(); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 126 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 127 | return true; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 128 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 129 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 130 | bool SPWFSA01::hw_reset(void) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 131 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 132 | if (_reset.is_connected()) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 133 | /* reset the pin PC12 */ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 134 | _reset.write(0); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 135 | wait_ms(200); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 136 | _reset.write(1); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 137 | wait_ms(100); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 138 | return 1; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 139 | } else { return 0; } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 140 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 141 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 142 | bool SPWFSA01::reset(void) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 143 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 144 | if(!_parser.send("AT+CFUN=1")) return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 145 | while(1) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 146 | if (_parser.recv("+WIND:32:WiFi Hardware Started\r")) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 147 | return true; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 148 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 149 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 150 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 151 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 152 | void SPWFSA01::waitSPWFReady(void) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 153 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 154 | //wait_ms(200); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 155 | while(1) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 156 | if(_parser.send("AT") && _parser.recv("OK")) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 157 | //till we get OK from AT command |
PavelSavyhin | 0:4cdaf9b1e7d0 | 158 | //printf("\r\nwaiting for reset to complete..\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 159 | return; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 160 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 161 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 162 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 163 | /* Security Mode |
PavelSavyhin | 0:4cdaf9b1e7d0 | 164 | None = 0, |
PavelSavyhin | 0:4cdaf9b1e7d0 | 165 | WEP = 1, |
PavelSavyhin | 0:4cdaf9b1e7d0 | 166 | WPA_Personal = 2, |
PavelSavyhin | 0:4cdaf9b1e7d0 | 167 | */ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 168 | bool SPWFSA01::connect(const char *ap, const char *passPhrase, int securityMode) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 169 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 170 | uint32_t n1, n2, n3, n4; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 171 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 172 | _parser.setTimeout(SPWFSA01_CONNECT_TIMEOUT); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 173 | //AT+S.SCFG=wifi_wpa_psk_text,%s\r |
PavelSavyhin | 0:4cdaf9b1e7d0 | 174 | if(!(_parser.send("AT+S.SCFG=wifi_wpa_psk_text,%s", passPhrase) && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 175 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 176 | debug_if(dbg_on, "SPWF> error pass set\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 177 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 178 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 179 | //AT+S.SSIDTXT=%s\r |
PavelSavyhin | 0:4cdaf9b1e7d0 | 180 | if(!(_parser.send("AT+S.SSIDTXT=%s", ap) && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 181 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 182 | debug_if(dbg_on, "SPWF> error ssid set\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 183 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 184 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 185 | //AT+S.SCFG=wifi_priv_mode,%d\r |
PavelSavyhin | 0:4cdaf9b1e7d0 | 186 | if(!(_parser.send("AT+S.SCFG=wifi_priv_mode,%d", securityMode) && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 187 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 188 | debug_if(dbg_on, "SPWF> error security mode set\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 189 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 190 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 191 | //"AT+S.SCFG=wifi_mode,%d\r" |
PavelSavyhin | 0:4cdaf9b1e7d0 | 192 | /*set idle mode (0->idle, 1->STA,3->miniAP, 2->IBSS)*/ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 193 | if(!(_parser.send("AT+S.SCFG=wifi_mode,%d\r", 1) && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 194 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 195 | debug_if(dbg_on, "SPWF> error wifi mode set\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 196 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 197 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 198 | //AT&W |
PavelSavyhin | 0:4cdaf9b1e7d0 | 199 | /* save current setting in flash */ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 200 | if(!(_parser.send("AT&W") && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 201 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 202 | debug_if(dbg_on, "SPWF> error AT&W\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 203 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 204 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 205 | //reset module |
PavelSavyhin | 0:4cdaf9b1e7d0 | 206 | reset(); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 207 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 208 | while(1) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 209 | if((_parser.recv("+WIND:24:WiFi Up:%u.%u.%u.%u",&n1, &n2, &n3, &n4))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 210 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 211 | break; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 212 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 213 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 214 | return true; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 215 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 216 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 217 | bool SPWFSA01::disconnect(void) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 218 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 219 | //"AT+S.SCFG=wifi_mode,%d\r" |
PavelSavyhin | 0:4cdaf9b1e7d0 | 220 | /*set idle mode (0->idle, 1->STA,3->miniAP, 2->IBSS)*/ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 221 | if(!(_parser.send("AT+S.SCFG=wifi_mode,%d\r", 0) && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 222 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 223 | debug_if(dbg_on, "SPWF> error wifi mode set\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 224 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 225 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 226 | //AT&W |
PavelSavyhin | 0:4cdaf9b1e7d0 | 227 | /* save current setting in flash */ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 228 | if(!(_parser.send("AT&W") && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 229 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 230 | debug_if(dbg_on, "SPWF> error AT&W\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 231 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 232 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 233 | //reset module |
PavelSavyhin | 0:4cdaf9b1e7d0 | 234 | reset(); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 235 | return true; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 236 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 237 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 238 | bool SPWFSA01::dhcp(int mode) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 239 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 240 | //only 3 valid modes |
PavelSavyhin | 0:4cdaf9b1e7d0 | 241 | //0->off(ip_addr must be set by user), 1->on(auto set by AP), 2->on&customize(miniAP ip_addr can be set by user) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 242 | if(mode < 0 || mode > 2) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 243 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 244 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 245 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 246 | return _parser.send("AT+S.SCFG=ip_use_dhcp,%d\r", mode) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 247 | && _parser.recv("OK"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 248 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 249 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 250 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 251 | const char *SPWFSA01::getIPAddress(void) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 252 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 253 | uint32_t n1, n2, n3, n4; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 254 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 255 | if (!(_parser.send("AT+S.STS=ip_ipaddr") |
PavelSavyhin | 0:4cdaf9b1e7d0 | 256 | && _parser.recv("# ip_ipaddr = %u.%u.%u.%u", &n1, &n2, &n3, &n4) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 257 | && _parser.recv("OK"))) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 258 | debug_if(dbg_on, "SPWF> getIPAddress error\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 259 | return 0; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 260 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 261 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 262 | sprintf((char*)_ip_buffer,"%u.%u.%u.%u", n1, n2, n3, n4); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 263 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 264 | return _ip_buffer; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 265 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 266 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 267 | const char *SPWFSA01::getMACAddress(void) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 268 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 269 | uint32_t n1, n2, n3, n4, n5, n6; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 270 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 271 | if (!(_parser.send("AT+S.GCFG=nv_wifi_macaddr") |
PavelSavyhin | 0:4cdaf9b1e7d0 | 272 | && _parser.recv("# nv_wifi_macaddr = %x:%x:%x:%x:%x:%x", &n1, &n2, &n3, &n4, &n5, &n6) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 273 | && _parser.recv("OK"))) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 274 | debug_if(dbg_on, "SPWF> getMACAddress error\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 275 | return 0; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 276 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 277 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 278 | sprintf((char*)_mac_buffer,"%02X:%02X:%02X:%02X:%02X:%02X", n1, n2, n3, n4, n5, n6); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 279 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 280 | return _mac_buffer; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 281 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 282 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 283 | bool SPWFSA01::isConnected(void) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 284 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 285 | return getIPAddress() != 0; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 286 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 287 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 288 | bool SPWFSA01::open(const char *type, int* id, const char* addr, int port) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 289 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 290 | Timer timer; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 291 | timer.start(); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 292 | socket_closed = 0; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 293 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 294 | if(!_parser.send("AT+S.SOCKON=%s,%d,%s,ind", addr, port, type)) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 295 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 296 | debug_if(dbg_on, "SPWF> error opening socket\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 297 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 298 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 299 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 300 | while(1) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 301 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 302 | if( _parser.recv(" ID: %d", id) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 303 | && _parser.recv("OK")) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 304 | break; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 305 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 306 | if (timer.read_ms() > SPWFSA01_CONNECT_TIMEOUT) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 307 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 308 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 309 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 310 | //TODO:implement time-out functionality in case of no response |
PavelSavyhin | 0:4cdaf9b1e7d0 | 311 | //if(timeout) return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 312 | //TODO: deal with errors like "ERROR: Failed to resolve name" |
PavelSavyhin | 0:4cdaf9b1e7d0 | 313 | //TODO: deal with errors like "ERROR: Data mode not available" |
PavelSavyhin | 0:4cdaf9b1e7d0 | 314 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 315 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 316 | return true; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 317 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 318 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 319 | bool SPWFSA01::send(int id, const void *data, uint32_t amount) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 320 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 321 | char _buf[18]; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 322 | _parser.setTimeout(SPWFSA01_SEND_TIMEOUT); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 323 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 324 | sprintf((char*)_buf,"AT+S.SOCKW=%d,%d\r", id, amount); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 325 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 326 | //May take a second try if device is busy |
PavelSavyhin | 0:4cdaf9b1e7d0 | 327 | for (unsigned i = 0; i < 2; i++) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 328 | if (_parser.write((char*)_buf, strlen(_buf)) >=0 |
PavelSavyhin | 0:4cdaf9b1e7d0 | 329 | && _parser.write((char*)data, (int)amount) >= 0 |
PavelSavyhin | 0:4cdaf9b1e7d0 | 330 | && _parser.recv("OK")) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 331 | return true; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 332 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 333 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 334 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 335 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 336 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 337 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 338 | int32_t SPWFSA01::recv(int id, void *data, uint32_t amount) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 339 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 340 | uint32_t recv_amount=0; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 341 | int wind_id; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 342 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 343 | if (socket_closed) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 344 | socket_closed = 0; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 345 | return -3; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 346 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 347 | if(!(_parser.send("AT+S.SOCKQ=%d", id) //send a query (will be required for secure sockets) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 348 | && _parser.recv(" DATALEN: %u", &recv_amount) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 349 | && _parser.recv("OK"))) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 350 | return -2; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 351 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 352 | if (recv_amount==0) { return -1; } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 353 | if(recv_amount > amount) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 354 | recv_amount = amount; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 355 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 356 | int par_timeout = _parser.getTimeout(); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 357 | _parser.setTimeout(0); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 358 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 359 | while(_parser.recv("+WIND:%d:", &wind_id)) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 360 | // printf("Wind received: %d\n\r", wind_id); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 361 | if (wind_id == 58) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 362 | socket_closed = 1; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 363 | _parser.flush(); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 364 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 365 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 366 | _parser.setTimeout(par_timeout); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 367 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 368 | _parser.flush(); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 369 | if(!(_parser.send("AT+S.SOCKR=%d,%d", id, recv_amount))){ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 370 | return -2; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 371 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 372 | if(!((_parser.read((char*)data, recv_amount) >0) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 373 | && _parser.recv("OK"))) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 374 | return -2; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 375 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 376 | return recv_amount; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 377 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 378 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 379 | bool SPWFSA01::close(int id) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 380 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 381 | uint32_t recv_amount=0; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 382 | void * data = NULL; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 383 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 384 | _parser.setTimeout(SPWFSA01_MISC_TIMEOUT); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 385 | _parser.flush(); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 386 | /* socket flush */ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 387 | if(!(_parser.send("AT+S.SOCKQ=%d", id) //send a query (will be required for secure sockets) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 388 | && _parser.recv(" DATALEN: %u", &recv_amount) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 389 | && _parser.recv("OK"))) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 390 | return -2; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 391 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 392 | if (recv_amount>0) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 393 | data = malloc (recv_amount+4); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 394 | if(!(_parser.send("AT+S.SOCKR=%d,%d", id, recv_amount))) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 395 | free (data); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 396 | return -2; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 397 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 398 | // printf ("--->>>Close flushing recv_amount: %d \n\r",recv_amount); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 399 | if(!((_parser.read((char*)data, recv_amount) >0) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 400 | && _parser.recv("OK"))) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 401 | free (data); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 402 | return -2; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 403 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 404 | free (data); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 405 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 406 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 407 | //May take a second try if device is busy or error is returned |
PavelSavyhin | 0:4cdaf9b1e7d0 | 408 | for (unsigned i = 0; i < 2; i++) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 409 | if (_parser.send("AT+S.SOCKC=%d", id) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 410 | && _parser.recv("OK")) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 411 | socket_closed = 1; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 412 | return true; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 413 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 414 | else |
PavelSavyhin | 0:4cdaf9b1e7d0 | 415 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 416 | if(_parser.recv("ERROR: Pending data")) { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 417 | debug_if(dbg_on, "SPWF> ERROR!!!!\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 418 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 419 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 420 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 421 | //TODO: Deal with "ERROR: Pending data" (Closing a socket with pending data) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 422 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 423 | return false; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 424 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 425 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 426 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 427 | bool SPWFSA01::readable() |
PavelSavyhin | 0:4cdaf9b1e7d0 | 428 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 429 | return _serial.readable(); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 430 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 431 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 432 | bool SPWFSA01::writeable() |
PavelSavyhin | 0:4cdaf9b1e7d0 | 433 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 434 | return _serial.writeable(); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 435 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 436 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 437 | int SPWFSA01::setSocketClientSecurity(uint8_t* tls_mode, uint8_t* root_ca_server, uint8_t* client_cert, uint8_t* client_key, uint8_t* client_domain, uint32_t tls_epoch_time) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 438 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 439 | int err = 0; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 440 | unsigned long epoch_time; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 441 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 442 | if(!(_parser.send("AT+S.TLSCERT2=clean,all\r", 0) && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 443 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 444 | debug_if(dbg_on, "SPWF> TLSCERT2 cleared\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 445 | return -1; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 446 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 447 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 448 | if(tls_epoch_time==0) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 449 | epoch_time = EPOCH_TIME; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 450 | else |
PavelSavyhin | 0:4cdaf9b1e7d0 | 451 | epoch_time = tls_epoch_time; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 452 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 453 | if(!(_parser.send("AT+S.SETTIME=%lu\r", (unsigned long)epoch_time) && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 454 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 455 | debug_if(dbg_on, "SPWF> time is set to %d\r\n", epoch_time); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 456 | return -1; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 457 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 458 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 459 | /*AT+S.TLSCERT=f_ca,<size><CR><data>*/ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 460 | if(!(_parser.send("AT+S.TLSCERT=f_ca,%d\r%s\r", strlen((const char *)root_ca_server) - 1, root_ca_server) && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 461 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 462 | debug_if(dbg_on, "SPWF> error TLSCERT=f_ca set\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 463 | return -1; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 464 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 465 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 466 | /*AT+S.TLSCERT=f_cert,<size><CR><data>*/ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 467 | if(tls_mode[0]=='m') |
PavelSavyhin | 0:4cdaf9b1e7d0 | 468 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 469 | if(!(_parser.send("AT+S.TLSCERT=f_cert,%d\r%s", strlen((const char *)client_cert) - 1, client_cert) && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 470 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 471 | debug_if(dbg_on, "SPWF> error TLSCERT=f_cert set\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 472 | return -1; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 473 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 474 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 475 | /*AT+S.TLSCERT=f_key,<size><CR><data>*/ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 476 | if(!(_parser.send("AT+S.TLSCERT=f_key,%d\r%s", strlen((const char *)client_key) - 1, client_key) && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 477 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 478 | debug_if(dbg_on, "SPWF> error TLSCERT=f_key set\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 479 | return -1; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 480 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 481 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 482 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 483 | /*AT+S.TLSDOMAIN=f_domain,<server domain>*/ |
PavelSavyhin | 0:4cdaf9b1e7d0 | 484 | if(!(_parser.send("AT+S.TLSDOMAIN=f_domain,%s\r", client_domain) && _parser.recv("OK"))) |
PavelSavyhin | 0:4cdaf9b1e7d0 | 485 | { |
PavelSavyhin | 0:4cdaf9b1e7d0 | 486 | debug_if(dbg_on, "SPWF> error TLSDOMAIN=f_domain set\r\n"); |
PavelSavyhin | 0:4cdaf9b1e7d0 | 487 | return -1; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 488 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 489 | |
PavelSavyhin | 0:4cdaf9b1e7d0 | 490 | return err; |
PavelSavyhin | 0:4cdaf9b1e7d0 | 491 | } |
PavelSavyhin | 0:4cdaf9b1e7d0 | 492 |