This is an example based on mbed-os cellular APIs that demonstrates a TCP or UDP echo transaction with a public echo server. Included TPB23 NB-IoT module which is can use LGU+ in Korea.
This example is showing how to use the NB-IoT(SECOM TPB23 module) of LGU plus network in Korea. The NB-IoT module' seller provided a document on how to start based on Mbed OS 5.11. (Created by CodeZoo) This guide has been supported to the latest os version which included 5.12 ~ 5.15.
- if you need specific version of Mbed OS, please revision of TPB23_Driver and check it out.
- Pelion ready example code is here!
Requirement
- Need to check CodeZoo's s hardware a guide.
- Need a CodeZoo's NBIoT board and development board.
- Board picture & Jumper configure
- And also can use with mbed application shield, as shown below.
Tested with
- DISCO_L475VG_IOT01A - If you are in Korea, can buy here !
- NUCLEO_F429ZI - If you are in Korea, can buy here !
1. Import the application into your desktop
mbed import http://os.mbed.com/users/Daniel_Lee/code/mbed-os-example-cellular-TPB23/ cd mbed-os-example-cellular-TPB23
2. Compile and program
mbed compile -t <toolchain> -m <TARGET_BOARD>
(supported toolchains : GCC_ARM / ARM / IAR)
3. Download binary to a target board
4. Result
mbed-os-example-cellular Built: Aug 7 2019, 06:10:47 [MAIN], plmn: NULL Establishing connection [00000001ms][INFO][CELL]: New CellularContext (20000a08) [00000002ms][INFO][CELL]: CellularContext plmn NULL [00000003ms][INFO][CELL]: CellularContext connect [00000036ms][INFO][CELL]: RSSI -69 dBm [00000036ms][INFO][CELL]: Start connecting (timeout 1 s) [00000087ms][INFO][CELL]: RSSI -69 dBm [00000116ms][INFO][CELL]: Modem ready [00000146ms][INFO][CELL]: RSSI -69 dBm [00000146ms][INFO][CELL]: Setup SIM (timeout 1 s) [00001233ms][INFO][CELL]: Looked up APN internet [00001362ms][ERR ][CELL]: AT error code 50 [00001362ms][WARN][CELL]: Packet domain event reporting set failed! [00001393ms][INFO][CELL]: RSSI -65 dBm [00001393ms][INFO][CELL]: Network registration (timeout 180 s) [00001443ms][INFO][CELL]: Registering network => Attaching network [00001473ms][INFO][CELL]: RSSI -65 dBm [00001473ms][INFO][CELL]: Attaching network (timeout 60 s) [00001601ms][INFO][CELL]: Found PDP context 1 [00001649ms][INFO][CELL]: Activate PDP context 1 Connection Established. [00001671ms][INFO][CELL]: Socket 0 open [00001707ms][INFO][CELL]: Socket 1 open [00001748ms][INFO][CELL]: Socket create id: 1 [00001883ms][INFO][CELL]: Socket 1 sent 43 bytes to 8.8.8.8 port 53 [00004311ms][INFO][CELL]: Socket 1 recv 59 bytes from 8.8.8.8 port 53 [00004331ms][INFO][CELL]: Close socket: 1 error: 0 [00004331ms][INFO][CELL]: Socket 1 closed [00004373ms][INFO][CELL]: Socket create id: 1 TCP: connected with echo.mbedcloudtesting.com server [00004448ms][INFO][CELL]: Socket 0 sent 4 bytes to 52.215.34.155 port 7 TCP: Sent 4 Bytes to echo.mbedcloudtesting.com [00007560ms][INFO][CELL]: Socket 0 recv 4 bytes [00007580ms][INFO][CELL]: Close socket: 1 error: 0 [00007580ms][INFO][CELL]: Socket 0 closed Received from echo server 4 Bytes [00007581ms][INFO][CELL]: CellularContext disconnect() [00007630ms][INFO][CELL]: cb: CellularContext disconnected Success. Exiting
SERCOMM/TPB23/SERCOMM_TPB23_CellularStack.cpp@45:63eba30af193, 2019-08-07 (annotated)
- Committer:
- Daniel_Lee
- Date:
- Wed Aug 07 06:31:31 2019 +0000
- Revision:
- 45:63eba30af193
Update for Mbed OS 5.12.x; This code was tested on Mbed OS 5.12.2, please check code revision!
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Daniel_Lee | 45:63eba30af193 | 1 | /* |
Daniel_Lee | 45:63eba30af193 | 2 | * Copyright (c) 2017, Arm Limited and affiliates. |
Daniel_Lee | 45:63eba30af193 | 3 | * SPDX-License-Identifier: Apache-2.0 |
Daniel_Lee | 45:63eba30af193 | 4 | * |
Daniel_Lee | 45:63eba30af193 | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
Daniel_Lee | 45:63eba30af193 | 6 | * you may not use this file except in compliance with the License. |
Daniel_Lee | 45:63eba30af193 | 7 | * You may obtain a copy of the License at |
Daniel_Lee | 45:63eba30af193 | 8 | * |
Daniel_Lee | 45:63eba30af193 | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
Daniel_Lee | 45:63eba30af193 | 10 | * |
Daniel_Lee | 45:63eba30af193 | 11 | * Unless required by applicable law or agreed to in writing, software |
Daniel_Lee | 45:63eba30af193 | 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
Daniel_Lee | 45:63eba30af193 | 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
Daniel_Lee | 45:63eba30af193 | 14 | * See the License for the specific language governing permissions and |
Daniel_Lee | 45:63eba30af193 | 15 | * limitations under the License. |
Daniel_Lee | 45:63eba30af193 | 16 | */ |
Daniel_Lee | 45:63eba30af193 | 17 | |
Daniel_Lee | 45:63eba30af193 | 18 | #include "SERCOMM_TPB23_CellularStack.h" |
Daniel_Lee | 45:63eba30af193 | 19 | #include "CellularUtil.h" |
Daniel_Lee | 45:63eba30af193 | 20 | #include "CellularLog.h" |
Daniel_Lee | 45:63eba30af193 | 21 | |
Daniel_Lee | 45:63eba30af193 | 22 | #define PACKET_SIZE_MAX 1500 //TPB23 Range is 12-1500 |
Daniel_Lee | 45:63eba30af193 | 23 | |
Daniel_Lee | 45:63eba30af193 | 24 | using namespace mbed; |
Daniel_Lee | 45:63eba30af193 | 25 | using namespace mbed_cellular_util; |
Daniel_Lee | 45:63eba30af193 | 26 | |
Daniel_Lee | 45:63eba30af193 | 27 | SERCOMM_TPB23_CellularStack::SERCOMM_TPB23_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type) : AT_CellularStack(atHandler, cid, stack_type) |
Daniel_Lee | 45:63eba30af193 | 28 | { |
Daniel_Lee | 45:63eba30af193 | 29 | _at.set_urc_handler("+NSONMI:", mbed::Callback<void()>(this, &SERCOMM_TPB23_CellularStack::urc_nsonmi)); |
Daniel_Lee | 45:63eba30af193 | 30 | } |
Daniel_Lee | 45:63eba30af193 | 31 | |
Daniel_Lee | 45:63eba30af193 | 32 | SERCOMM_TPB23_CellularStack::~SERCOMM_TPB23_CellularStack() |
Daniel_Lee | 45:63eba30af193 | 33 | { |
Daniel_Lee | 45:63eba30af193 | 34 | } |
Daniel_Lee | 45:63eba30af193 | 35 | |
Daniel_Lee | 45:63eba30af193 | 36 | nsapi_error_t SERCOMM_TPB23_CellularStack::socket_listen(nsapi_socket_t handle, int backlog) |
Daniel_Lee | 45:63eba30af193 | 37 | { |
Daniel_Lee | 45:63eba30af193 | 38 | return NSAPI_ERROR_UNSUPPORTED; |
Daniel_Lee | 45:63eba30af193 | 39 | } |
Daniel_Lee | 45:63eba30af193 | 40 | |
Daniel_Lee | 45:63eba30af193 | 41 | nsapi_error_t SERCOMM_TPB23_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr) |
Daniel_Lee | 45:63eba30af193 | 42 | { |
Daniel_Lee | 45:63eba30af193 | 43 | return NSAPI_ERROR_UNSUPPORTED; |
Daniel_Lee | 45:63eba30af193 | 44 | } |
Daniel_Lee | 45:63eba30af193 | 45 | |
Daniel_Lee | 45:63eba30af193 | 46 | nsapi_error_t SERCOMM_TPB23_CellularStack::socket_connect(nsapi_socket_t handle, const SocketAddress &address) |
Daniel_Lee | 45:63eba30af193 | 47 | { |
Daniel_Lee | 45:63eba30af193 | 48 | CellularSocket *socket = (CellularSocket *)handle; |
Daniel_Lee | 45:63eba30af193 | 49 | |
Daniel_Lee | 45:63eba30af193 | 50 | _at.lock(); |
Daniel_Lee | 45:63eba30af193 | 51 | if (!socket->created) { |
Daniel_Lee | 45:63eba30af193 | 52 | const nsapi_error_t error_create = create_socket_impl(socket); |
Daniel_Lee | 45:63eba30af193 | 53 | if (error_create != NSAPI_ERROR_OK) { |
Daniel_Lee | 45:63eba30af193 | 54 | return error_create; |
Daniel_Lee | 45:63eba30af193 | 55 | } |
Daniel_Lee | 45:63eba30af193 | 56 | } |
Daniel_Lee | 45:63eba30af193 | 57 | |
Daniel_Lee | 45:63eba30af193 | 58 | _at.cmd_start("AT+NSOCO="); |
Daniel_Lee | 45:63eba30af193 | 59 | _at.write_int(socket->id); |
Daniel_Lee | 45:63eba30af193 | 60 | _at.write_string(address.get_ip_address(), false); |
Daniel_Lee | 45:63eba30af193 | 61 | _at.write_int(address.get_port()); |
Daniel_Lee | 45:63eba30af193 | 62 | _at.cmd_stop(); |
Daniel_Lee | 45:63eba30af193 | 63 | _at.resp_start(); |
Daniel_Lee | 45:63eba30af193 | 64 | _at.resp_stop(); |
Daniel_Lee | 45:63eba30af193 | 65 | _at.unlock(); |
Daniel_Lee | 45:63eba30af193 | 66 | |
Daniel_Lee | 45:63eba30af193 | 67 | if (_at.get_last_error() == NSAPI_ERROR_OK) { |
Daniel_Lee | 45:63eba30af193 | 68 | socket->remoteAddress = address; |
Daniel_Lee | 45:63eba30af193 | 69 | socket->connected = true; |
Daniel_Lee | 45:63eba30af193 | 70 | return NSAPI_ERROR_OK; |
Daniel_Lee | 45:63eba30af193 | 71 | } |
Daniel_Lee | 45:63eba30af193 | 72 | |
Daniel_Lee | 45:63eba30af193 | 73 | return NSAPI_ERROR_NO_CONNECTION; |
Daniel_Lee | 45:63eba30af193 | 74 | } |
Daniel_Lee | 45:63eba30af193 | 75 | |
Daniel_Lee | 45:63eba30af193 | 76 | void SERCOMM_TPB23_CellularStack::urc_nsonmi() |
Daniel_Lee | 45:63eba30af193 | 77 | { |
Daniel_Lee | 45:63eba30af193 | 78 | int sock_id = _at.read_int(); |
Daniel_Lee | 45:63eba30af193 | 79 | |
Daniel_Lee | 45:63eba30af193 | 80 | for (int i = 0; i < get_max_socket_count(); i++) { |
Daniel_Lee | 45:63eba30af193 | 81 | CellularSocket *sock = _socket[i]; |
Daniel_Lee | 45:63eba30af193 | 82 | if (sock && sock->id == sock_id) { |
Daniel_Lee | 45:63eba30af193 | 83 | if (sock->_cb) { |
Daniel_Lee | 45:63eba30af193 | 84 | sock->_cb(sock->_data); |
Daniel_Lee | 45:63eba30af193 | 85 | } |
Daniel_Lee | 45:63eba30af193 | 86 | break; |
Daniel_Lee | 45:63eba30af193 | 87 | } |
Daniel_Lee | 45:63eba30af193 | 88 | } |
Daniel_Lee | 45:63eba30af193 | 89 | } |
Daniel_Lee | 45:63eba30af193 | 90 | |
Daniel_Lee | 45:63eba30af193 | 91 | int SERCOMM_TPB23_CellularStack::get_max_socket_count() |
Daniel_Lee | 45:63eba30af193 | 92 | { |
Daniel_Lee | 45:63eba30af193 | 93 | return TPB23_SOCKET_MAX; |
Daniel_Lee | 45:63eba30af193 | 94 | } |
Daniel_Lee | 45:63eba30af193 | 95 | |
Daniel_Lee | 45:63eba30af193 | 96 | bool SERCOMM_TPB23_CellularStack::is_protocol_supported(nsapi_protocol_t protocol) |
Daniel_Lee | 45:63eba30af193 | 97 | { |
Daniel_Lee | 45:63eba30af193 | 98 | return (protocol == NSAPI_UDP || protocol == NSAPI_TCP); |
Daniel_Lee | 45:63eba30af193 | 99 | } |
Daniel_Lee | 45:63eba30af193 | 100 | |
Daniel_Lee | 45:63eba30af193 | 101 | nsapi_error_t SERCOMM_TPB23_CellularStack::socket_close_impl(int sock_id) |
Daniel_Lee | 45:63eba30af193 | 102 | { |
Daniel_Lee | 45:63eba30af193 | 103 | _at.cmd_start("AT+NSOCL="); |
Daniel_Lee | 45:63eba30af193 | 104 | _at.write_int(sock_id); |
Daniel_Lee | 45:63eba30af193 | 105 | _at.cmd_stop_read_resp(); |
Daniel_Lee | 45:63eba30af193 | 106 | |
Daniel_Lee | 45:63eba30af193 | 107 | tr_info("Close socket: %d error: %d", sock_id, _at.get_last_error()); |
Daniel_Lee | 45:63eba30af193 | 108 | |
Daniel_Lee | 45:63eba30af193 | 109 | return _at.get_last_error(); |
Daniel_Lee | 45:63eba30af193 | 110 | } |
Daniel_Lee | 45:63eba30af193 | 111 | |
Daniel_Lee | 45:63eba30af193 | 112 | nsapi_error_t SERCOMM_TPB23_CellularStack::create_socket_impl(CellularSocket *socket) |
Daniel_Lee | 45:63eba30af193 | 113 | { |
Daniel_Lee | 45:63eba30af193 | 114 | int sock_id = -1; |
Daniel_Lee | 45:63eba30af193 | 115 | bool socketOpenWorking = false; |
Daniel_Lee | 45:63eba30af193 | 116 | |
Daniel_Lee | 45:63eba30af193 | 117 | if (socket->proto == NSAPI_UDP) { |
Daniel_Lee | 45:63eba30af193 | 118 | _at.cmd_start("AT+NSOCR=DGRAM,17,"); |
Daniel_Lee | 45:63eba30af193 | 119 | } else if (socket->proto == NSAPI_TCP) { |
Daniel_Lee | 45:63eba30af193 | 120 | _at.cmd_start("AT+NSOCR=STREAM,6,"); |
Daniel_Lee | 45:63eba30af193 | 121 | } else { |
Daniel_Lee | 45:63eba30af193 | 122 | return NSAPI_ERROR_PARAMETER; |
Daniel_Lee | 45:63eba30af193 | 123 | } |
Daniel_Lee | 45:63eba30af193 | 124 | _at.write_int(socket->localAddress.get_port()); |
Daniel_Lee | 45:63eba30af193 | 125 | _at.write_int(1); |
Daniel_Lee | 45:63eba30af193 | 126 | _at.cmd_stop(); |
Daniel_Lee | 45:63eba30af193 | 127 | _at.resp_start(); |
Daniel_Lee | 45:63eba30af193 | 128 | sock_id = _at.read_int(); |
Daniel_Lee | 45:63eba30af193 | 129 | _at.resp_stop(); |
Daniel_Lee | 45:63eba30af193 | 130 | |
Daniel_Lee | 45:63eba30af193 | 131 | socketOpenWorking = (_at.get_last_error() == NSAPI_ERROR_OK); |
Daniel_Lee | 45:63eba30af193 | 132 | |
Daniel_Lee | 45:63eba30af193 | 133 | if (!socketOpenWorking) { |
Daniel_Lee | 45:63eba30af193 | 134 | _at.cmd_start("AT+NSOCL=0"); |
Daniel_Lee | 45:63eba30af193 | 135 | _at.cmd_stop_read_resp(); |
Daniel_Lee | 45:63eba30af193 | 136 | |
Daniel_Lee | 45:63eba30af193 | 137 | if (socket->proto == NSAPI_UDP) { |
Daniel_Lee | 45:63eba30af193 | 138 | _at.cmd_start("AT+NSOCR=DGRAM,17,"); |
Daniel_Lee | 45:63eba30af193 | 139 | } else if (socket->proto == NSAPI_TCP) { |
Daniel_Lee | 45:63eba30af193 | 140 | _at.cmd_start("AT+NSOCR=STREAM,6,"); |
Daniel_Lee | 45:63eba30af193 | 141 | } |
Daniel_Lee | 45:63eba30af193 | 142 | _at.write_int(socket->localAddress.get_port()); |
Daniel_Lee | 45:63eba30af193 | 143 | _at.write_int(1); |
Daniel_Lee | 45:63eba30af193 | 144 | _at.cmd_stop(); |
Daniel_Lee | 45:63eba30af193 | 145 | _at.resp_start(); |
Daniel_Lee | 45:63eba30af193 | 146 | sock_id = _at.read_int(); |
Daniel_Lee | 45:63eba30af193 | 147 | _at.resp_stop(); |
Daniel_Lee | 45:63eba30af193 | 148 | |
Daniel_Lee | 45:63eba30af193 | 149 | socketOpenWorking = (_at.get_last_error() == NSAPI_ERROR_OK); |
Daniel_Lee | 45:63eba30af193 | 150 | } |
Daniel_Lee | 45:63eba30af193 | 151 | |
Daniel_Lee | 45:63eba30af193 | 152 | if (!socketOpenWorking || (sock_id == -1)) { |
Daniel_Lee | 45:63eba30af193 | 153 | tr_error("Socket create failed!"); |
Daniel_Lee | 45:63eba30af193 | 154 | return NSAPI_ERROR_NO_SOCKET; |
Daniel_Lee | 45:63eba30af193 | 155 | } |
Daniel_Lee | 45:63eba30af193 | 156 | |
Daniel_Lee | 45:63eba30af193 | 157 | // Check for duplicate socket id delivered by modem |
Daniel_Lee | 45:63eba30af193 | 158 | for (int i = 0; i < TPB23_SOCKET_MAX; i++) { |
Daniel_Lee | 45:63eba30af193 | 159 | CellularSocket *sock = _socket[i]; |
Daniel_Lee | 45:63eba30af193 | 160 | if (sock && sock->created && sock->id == sock_id) { |
Daniel_Lee | 45:63eba30af193 | 161 | tr_error("Duplicate socket index: %d created:%d, sock_id: %d", i, sock->created, sock_id); |
Daniel_Lee | 45:63eba30af193 | 162 | return NSAPI_ERROR_NO_SOCKET; |
Daniel_Lee | 45:63eba30af193 | 163 | } |
Daniel_Lee | 45:63eba30af193 | 164 | } |
Daniel_Lee | 45:63eba30af193 | 165 | |
Daniel_Lee | 45:63eba30af193 | 166 | tr_info("Socket create id: %d", sock_id); |
Daniel_Lee | 45:63eba30af193 | 167 | |
Daniel_Lee | 45:63eba30af193 | 168 | socket->id = sock_id; |
Daniel_Lee | 45:63eba30af193 | 169 | socket->created = true; |
Daniel_Lee | 45:63eba30af193 | 170 | |
Daniel_Lee | 45:63eba30af193 | 171 | return NSAPI_ERROR_OK; |
Daniel_Lee | 45:63eba30af193 | 172 | } |
Daniel_Lee | 45:63eba30af193 | 173 | |
Daniel_Lee | 45:63eba30af193 | 174 | nsapi_size_or_error_t SERCOMM_TPB23_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address, |
Daniel_Lee | 45:63eba30af193 | 175 | const void *data, nsapi_size_t size) |
Daniel_Lee | 45:63eba30af193 | 176 | { |
Daniel_Lee | 45:63eba30af193 | 177 | int sent_len = 0; |
Daniel_Lee | 45:63eba30af193 | 178 | |
Daniel_Lee | 45:63eba30af193 | 179 | if (size > PACKET_SIZE_MAX) { |
Daniel_Lee | 45:63eba30af193 | 180 | return NSAPI_ERROR_PARAMETER; |
Daniel_Lee | 45:63eba30af193 | 181 | } |
Daniel_Lee | 45:63eba30af193 | 182 | |
Daniel_Lee | 45:63eba30af193 | 183 | char *hexstr = new char[size * 2 + 1]; |
Daniel_Lee | 45:63eba30af193 | 184 | int hexlen = char_str_to_hex_str((const char *)data, size, hexstr); |
Daniel_Lee | 45:63eba30af193 | 185 | // NULL terminated for write_string |
Daniel_Lee | 45:63eba30af193 | 186 | hexstr[hexlen] = 0; |
Daniel_Lee | 45:63eba30af193 | 187 | |
Daniel_Lee | 45:63eba30af193 | 188 | if (socket->proto == NSAPI_UDP) { |
Daniel_Lee | 45:63eba30af193 | 189 | _at.cmd_start("AT+NSOST="); |
Daniel_Lee | 45:63eba30af193 | 190 | _at.write_int(socket->id); |
Daniel_Lee | 45:63eba30af193 | 191 | _at.write_string(address.get_ip_address(), false); |
Daniel_Lee | 45:63eba30af193 | 192 | _at.write_int(address.get_port()); |
Daniel_Lee | 45:63eba30af193 | 193 | _at.write_int(size); |
Daniel_Lee | 45:63eba30af193 | 194 | } else if (socket->proto == NSAPI_TCP) { |
Daniel_Lee | 45:63eba30af193 | 195 | _at.cmd_start("AT+NSOSD="); |
Daniel_Lee | 45:63eba30af193 | 196 | _at.write_int(socket->id); |
Daniel_Lee | 45:63eba30af193 | 197 | _at.write_int(size); |
Daniel_Lee | 45:63eba30af193 | 198 | } else { |
Daniel_Lee | 45:63eba30af193 | 199 | delete [] hexstr; |
Daniel_Lee | 45:63eba30af193 | 200 | return NSAPI_ERROR_PARAMETER; |
Daniel_Lee | 45:63eba30af193 | 201 | } |
Daniel_Lee | 45:63eba30af193 | 202 | |
Daniel_Lee | 45:63eba30af193 | 203 | _at.write_string(hexstr, false); |
Daniel_Lee | 45:63eba30af193 | 204 | _at.cmd_stop(); |
Daniel_Lee | 45:63eba30af193 | 205 | _at.resp_start(); |
Daniel_Lee | 45:63eba30af193 | 206 | // skip socket id |
Daniel_Lee | 45:63eba30af193 | 207 | _at.skip_param(); |
Daniel_Lee | 45:63eba30af193 | 208 | sent_len = _at.read_int(); |
Daniel_Lee | 45:63eba30af193 | 209 | _at.resp_stop(); |
Daniel_Lee | 45:63eba30af193 | 210 | |
Daniel_Lee | 45:63eba30af193 | 211 | delete [] hexstr; |
Daniel_Lee | 45:63eba30af193 | 212 | |
Daniel_Lee | 45:63eba30af193 | 213 | if (_at.get_last_error() == NSAPI_ERROR_OK) { |
Daniel_Lee | 45:63eba30af193 | 214 | return sent_len; |
Daniel_Lee | 45:63eba30af193 | 215 | } |
Daniel_Lee | 45:63eba30af193 | 216 | |
Daniel_Lee | 45:63eba30af193 | 217 | return _at.get_last_error(); |
Daniel_Lee | 45:63eba30af193 | 218 | } |
Daniel_Lee | 45:63eba30af193 | 219 | |
Daniel_Lee | 45:63eba30af193 | 220 | nsapi_size_or_error_t SERCOMM_TPB23_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, |
Daniel_Lee | 45:63eba30af193 | 221 | void *buffer, nsapi_size_t size) |
Daniel_Lee | 45:63eba30af193 | 222 | { |
Daniel_Lee | 45:63eba30af193 | 223 | nsapi_size_or_error_t recv_len = 0; |
Daniel_Lee | 45:63eba30af193 | 224 | int port; |
Daniel_Lee | 45:63eba30af193 | 225 | char ip_address[NSAPI_IP_SIZE]; |
Daniel_Lee | 45:63eba30af193 | 226 | |
Daniel_Lee | 45:63eba30af193 | 227 | _at.cmd_start("AT+NSORF="); |
Daniel_Lee | 45:63eba30af193 | 228 | _at.write_int(socket->id); |
Daniel_Lee | 45:63eba30af193 | 229 | _at.write_int(size <= PACKET_SIZE_MAX ? size : PACKET_SIZE_MAX); |
Daniel_Lee | 45:63eba30af193 | 230 | _at.cmd_stop(); |
Daniel_Lee | 45:63eba30af193 | 231 | _at.resp_start(); |
Daniel_Lee | 45:63eba30af193 | 232 | // receiving socket id |
Daniel_Lee | 45:63eba30af193 | 233 | _at.skip_param(); |
Daniel_Lee | 45:63eba30af193 | 234 | _at.read_string(ip_address, sizeof(ip_address)); |
Daniel_Lee | 45:63eba30af193 | 235 | port = _at.read_int(); |
Daniel_Lee | 45:63eba30af193 | 236 | recv_len = _at.read_int(); |
Daniel_Lee | 45:63eba30af193 | 237 | int hexlen = _at.read_hex_string((char *)buffer, size); |
Daniel_Lee | 45:63eba30af193 | 238 | // remaining length |
Daniel_Lee | 45:63eba30af193 | 239 | _at.skip_param(); |
Daniel_Lee | 45:63eba30af193 | 240 | _at.resp_stop(); |
Daniel_Lee | 45:63eba30af193 | 241 | |
Daniel_Lee | 45:63eba30af193 | 242 | if (!recv_len || (recv_len == -1) || (_at.get_last_error() != NSAPI_ERROR_OK)) { |
Daniel_Lee | 45:63eba30af193 | 243 | return NSAPI_ERROR_WOULD_BLOCK; |
Daniel_Lee | 45:63eba30af193 | 244 | } |
Daniel_Lee | 45:63eba30af193 | 245 | |
Daniel_Lee | 45:63eba30af193 | 246 | if (address) { |
Daniel_Lee | 45:63eba30af193 | 247 | address->set_ip_address(ip_address); |
Daniel_Lee | 45:63eba30af193 | 248 | address->set_port(port); |
Daniel_Lee | 45:63eba30af193 | 249 | } |
Daniel_Lee | 45:63eba30af193 | 250 | |
Daniel_Lee | 45:63eba30af193 | 251 | if (recv_len != hexlen) { |
Daniel_Lee | 45:63eba30af193 | 252 | tr_error("Not received as much data as expected. Should receive: %d bytes, received: %d bytes", recv_len, hexlen); |
Daniel_Lee | 45:63eba30af193 | 253 | } |
Daniel_Lee | 45:63eba30af193 | 254 | return recv_len; |
Daniel_Lee | 45:63eba30af193 | 255 | } |