EMW3162 driver for NSAPI
Fork of emw3162-driver by
emw3162/EMW3162.cpp
- Committer:
- Maggie17
- Date:
- 2017-04-06
- Revision:
- 3:a1d89edf0749
- Parent:
- 2:fb6251306b21
File content as of revision 3:a1d89edf0749:
/* EMW3162 Example * Copyright (c) 2015 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "EMW3162.h" EMW3162::EMW3162(PinName tx, PinName rx, bool debug) : _serial(tx, rx, 1024), _parser(_serial) , _packets(0), _packets_end(&_packets) { _serial.baud(115200); _parser.debugOn(debug); } bool EMW3162::startup(void) { bool success = reset("FACTORY"); _parser.oob("+EVENT=SOCKET", this, &EMW3162::_packet_handler); return success; } bool EMW3162::reset(const char *reset) { for (int i = 0; i < 2; i++) { if (_parser.send("AT+%s", reset) && _parser.recv("+OK")) { return true; } } return false; } bool EMW3162::dhcp(bool enabled) { return _parser.send("AT+DHCP=%s", enabled ? "ON":"OFF") && _parser.recv("+OK"); } bool EMW3162::connect(const char *ap, const char *passPhrase) { return _parser.send("AT+WSTA=%s,%s", ap, passPhrase) && _parser.recv("+OK") && _parser.send("AT+EVENT=ON") && _parser.recv("+OK") && _parser.recv("+EVENT=WIFI_LINK,STATION_UP"); } bool EMW3162::disconnect(void) { return _parser.send("AT+WLANF=STA,OFF") && _parser.recv("+OK") && _parser.recv("+EVENT=WIFI_LINK,STATION_DOWN") && _parser.send("AT+EVENT=OFF") && _parser.recv("+OK"); } const char *EMW3162::getIPAddress(void) { if (!(_parser.send("AT+IPCONFIG") && _parser.recv("%*[^,],%*[^,],%*[^,],%[^,]%*[^#]#", _ip_buffer))) { return 0; } return _ip_buffer; } const char *EMW3162::getMACAddress(void) { if (!(_parser.send("AT+WMAC") && _parser.recv("%*[^=]=%[^#]#", _mac_buffer))) { return 0; } return _mac_buffer; } bool EMW3162::isConnected(void) { return getIPAddress() != 0; } int EMW3162::open(const char *type, int id, const char* addr, int port) { int state1 = 0, state2 = 0; state1 = _parser.send("AT+CON1=%s,%d,%d,%s", type, id, port, addr) && _parser.recv("+OK") && _parser.send("AT+SAVE") && _parser.recv("+OK") && reset("REBOOT") && _parser.recv("+EVENT=REBOOT"); wait(3); char conType[10]; // UDP/TCP connection type: SERVER, CLIENT, BROADCAST, UNICAST int socketId; // UDP/TCP socket id // Receive wifi connect event state2 = _parser.recv("+EVENT=WIFI_LINK,STATION_UP") && _parser.recv("+EVENT=%[^,],CONNECT,%d", conType, &socketId); if (state1 && state2) return socketId; else return -1; } bool EMW3162::send(int id, const void *data, uint32_t amount) { //May take a second try if device is busy for (unsigned i = 0; i < 2; i++) { if (_parser.send("AT+SSEND=%d,%d", id, amount) && _parser.recv(">") && _parser.write((char*)data, (int)amount) >= 0 && _parser.recv("+OK")) { //wait(3); return true; } } return false; } void EMW3162::_packet_handler() { int id; uint32_t amount; // parse out the packet if (!_parser.recv(",%d,%d,", &id, &amount)) { return; } struct packet *packet = (struct packet*)malloc( sizeof(struct packet) + amount); if (!packet) { return; } packet->id = id; packet->len = amount; packet->next = 0; if (!(_parser.read((char*)(packet + 1), amount))) { free(packet); return; } // append to packet list *_packets_end = packet; _packets_end = &packet->next; } int32_t EMW3162::recv(int id, void *data, uint32_t amount) { while (true) { // check if any packets are ready for us for (struct packet **p = &_packets; *p; p = &(*p)->next) { if ((*p)->id == id) { struct packet *q = *p; if (q->len <= amount) { // Return and remove full packet memcpy(data, q+1, q->len); if (_packets_end == &(*p)->next) { _packets_end = p; } *p = (*p)->next; uint32_t len = q->len; free(q); return len; } else { // return only partial packet memcpy(data, q+1, amount); q->len -= amount; memmove(q+1, (uint8_t*)(q+1) + amount, q->len); return amount; } } } // Wait for inbound packet if (!_parser.recv("#")) { return -1; } } } bool EMW3162::close(int id) { //May take a second try if device is busy for (unsigned i = 0; i < 2; i++) { if (_parser.send("AT+CONF=1,OFF") && _parser.recv("+OK")) { char conType[10]; // Used for UDP/TCP connection type: SERVER, CLIENT, BROADCAST, UNICAST int socketId; // Used for UDP/TCP socket id _parser.recv("+EVENT=%[^,],DISCONNECT,%d", conType, &socketId); return true; } } return false; } void EMW3162::setTimeout(uint32_t timeout_ms) { _parser.setTimeout(timeout_ms); } bool EMW3162::readable() { return _serial.readable(); } bool EMW3162::writeable() { return _serial.writeable(); } void EMW3162::attach(Callback<void()> func) { _serial.attach(func); }