ublox-at-cellular-interface-n2xx
Diff: UbloxATCellularInterfaceN2xx.cpp
- Revision:
- 6:658419981430
- Parent:
- 4:2bf3875a13f1
- Child:
- 7:69e676f4af84
- Child:
- 9:f6d022f5c4f5
diff -r 85605f239696 -r 658419981430 UbloxATCellularInterfaceN2xx.cpp --- a/UbloxATCellularInterfaceN2xx.cpp Tue Aug 22 16:37:41 2017 +0100 +++ b/UbloxATCellularInterfaceN2xx.cpp Wed Sep 13 15:57:06 2017 +0100 @@ -299,49 +299,59 @@ nsapi_size_or_error_t UbloxATCellularInterfaceN2xx::sendto(SockCtrl *socket, const SocketAddress &address, const char *buf, int size) { nsapi_size_or_error_t sent = NSAPI_ERROR_DEVICE_ERROR; int id; - - tr_debug("Malloc %d * 2 + 1 bytes", size); - char *str = (char *) malloc((size * 2) + 1); - if (str == NULL) { - tr_error("Nope, could allocate it!"); + + char *dataStr = (char *) malloc((size * 2) + 1); + if (dataStr == NULL) { + tr_error("Couldn't allocate memory for hex string conversion."); return NSAPI_ERROR_NO_MEMORY; } tr_debug("Converting byte array to hex string"); - bin_to_hex(buf, size, str); + bin_to_hex(buf, size, dataStr); tr_debug("Got hex string"); - LOCK(); + // AT+NSOSTF= socket, remote_addr, remote_port, length, data - tr_debug("Writing AT+NSOSTF=<sktid>,<ipaddr>,<port>,<flags>,<size>,<hex string> command..."); - char cmd[50]; - int cmdsize = sprintf(cmd, "AT+NSOSTF=%d,%s,%d,0x0,%d,", socket->modem_handle, address.get_ip_address(), address.get_port(), size); - if (_at->write(cmd, cmdsize+1) && sendATChopped(str)) { - tr_debug("Reading back the Sent Size..."); + tr_debug("Writing AT+NSOSTF=<sktid>,<ipaddr>,<port>,<flags>,<size>,<hex string> command..."); + char *cmdStr = (char *) malloc(50); + if (cmdStr == NULL) { + tr_error("Couldn't allocate memory for AT cmd string."); + return NSAPI_ERROR_NO_MEMORY; + } + + int cmdsize = sprintf(cmdStr, "AT+NSOSTF=%d,%s,%d,0x0,%d,", socket->modem_handle, address.get_ip_address(), address.get_port(), size); + tr_debug("%s", cmdStr); + + LOCK(); + if (_at->write(cmdStr, cmdsize) && sendATChopped(dataStr)) + { + tr_debug("Finished sending AT+NSOST comamnd, reading back the 'sent' size..."); if (_at->recv("%d,%d\n", &id, &sent) && _at->recv("OK")) { - tr_debug("Received %d bytes on socket %d", sent, id); + tr_debug("Sent %d bytes on socket %d", sent, id); } else { tr_error("Didn't get the Sent size or OK"); } } else { tr_error("Didn't send the AT command!"); } + UNLOCK(); - UNLOCK(); - free(str); - + free(cmdStr); + free(dataStr); + return sent; } bool UbloxATCellularInterfaceN2xx::sendATChopped(const char *cmd) { char buff[SENDTO_CHUNK_SIZE]; + tr_debug("Chopping up large AT text of %d characters.", strlen(cmd)); + while (*cmd != '\0') { int i=0; - tr_debug("Copying up to 50 chars... "); for (i=0; i<SENDTO_CHUNK_SIZE; i++) { buff[i] = *cmd; @@ -352,14 +362,15 @@ // still more characters to copy, so move along cmd++; } - tr_debug("Copied %d chars. ", i); - + + // if we are at the end of the line, use the send command to + // provide the \r\n terminator for the AT command if (*cmd == '\0') { - tr_debug("send()\n"); + tr_debug("send(%d): %s", i, buff); if (!_at->send(buff)) return false; } else { - tr_debug("write()\n"); + tr_debug("write(50): %s", buff); if (!_at->write(buff, 50)) return false; } @@ -404,32 +415,32 @@ char *buf = (char *) data; nsapi_size_t read_blk; nsapi_size_t count = 0; - char ipAddress[NSAPI_IP_SIZE]; - + int at_timeout = _at_timeout; + char * tmpBuf = NULL; Timer timer; SockCtrl *socket = (SockCtrl *) handle; - int at_timeout = _at_timeout; - tr_debug("socket_recvfrom(0x%08x, 0x%08x, %d)", (unsigned int) handle, - (unsigned int) data, size); + tr_debug("socket_recvfrom(0x%08x, 0x%08x, SIZE=%d)", (unsigned int) handle, (unsigned int) data, size); MBED_ASSERT (check_socket(socket)); - timer.start(); while (success && (size > 0)) { LOCK(); + at_timeout = _at_timeout; at_set_timeout(1000); - - read_blk = socket->pending; - if (read_blk > MAX_READ_SIZE) { - read_blk = MAX_READ_SIZE; + + read_blk = MAX_READ_SIZE; + if (read_blk > size) { + read_blk = size; } - if (read_blk > 0) { - memset (ipAddress, 0, sizeof (ipAddress)); // Ensure terminator - + + if (socket->pending > 0) { + tr_debug("Socket 0x%08x: modem handle %d has %d byte(s) pending", + (unsigned int) socket, socket->modem_handle, socket->pending); + tmpBuf = (char *) malloc(read_blk); if (tmpBuf == NULL) { return NSAPI_ERROR_NO_MEMORY; @@ -437,48 +448,62 @@ // call the AT helper function to get the bytes nsapi_error_size = receivefrom(socket->modem_handle, address, read_blk, tmpBuf); - + if (nsapi_error_size >= 0) { memcpy(buf, tmpBuf, nsapi_error_size); - socket->pending -= read_blk; - tr_debug("Socket 0x%08x: modem handle %d now has only %d byte(s) pending", - (unsigned int) socket, socket->modem_handle, socket->pending); - + if (read_blk != (uint) nsapi_error_size) + tr_error("Requested size is not the same as the returned size!"); + + socket->pending -= nsapi_error_size; count += nsapi_error_size; buf += nsapi_error_size; - size = 0; // A UDP packet arrives in one piece, so this means DONE. + size -= nsapi_error_size; + + if (((uint)nsapi_error_size < read_blk) || (nsapi_error_size == MAX_READ_SIZE)) + size = 0; // If we've received less than we asked for, or + // the max size, then a whole UDP packet has arrived and + // this means DONE. } else { - // Should never fail to read when there is pending data + // Should never fail to read when there is pending data success = false; } } else if (timer.read_ms() < SOCKET_TIMEOUT) { // Wait for URCs + tr_debug("Waiting for URC..."); _at->recv(UNNATURAL_STRING); } else { - // Timeout with nothing received - nsapi_error_size = NSAPI_ERROR_WOULD_BLOCK; - success = false; + tr_debug("Nothing pending..."); + if (count == 0) { + tr_debug("Nothing received, so timeout with block"); + // Timeout with nothing received + nsapi_error_size = NSAPI_ERROR_WOULD_BLOCK; + success = false; + } + + // quit while loop + break; } - + at_set_timeout(at_timeout); UNLOCK(); } timer.stop(); if (success) { + tr_debug("socket_recvfrom: %d SUCCESS!", count); nsapi_error_size = count; + } else { + tr_debug("socket_recvfrom: FAILED"); } - - tr_debug("socket_recvfrom: %d \"%*.*s\"", count, count, count, buf - count); - + return nsapi_error_size; } nsapi_size_or_error_t UbloxATCellularInterfaceN2xx::receivefrom(int modem_handle, SocketAddress *address, int length, char *buf) { char ipAddress[NSAPI_IP_SIZE]; nsapi_size_or_error_t size; - + memset (ipAddress, 0, sizeof (ipAddress)); // Ensure terminator if (length > MAX_READ_SIZE) { @@ -489,9 +514,14 @@ if (tmpBuf == NULL) return NSAPI_ERROR_NO_MEMORY; - LOCK(); + int remaining; + + _at->debug_on(false); // ABSOLUTELY no time for debug here if you want to + // be able to read packets of any size without + // losing characters in UARTSerial // Ask for x bytes from Socket + tr_debug("Requesting to read back %d bytes from socket %d", length, modem_handle); if (_at->send("AT+NSORF=%d,%d", modem_handle, length)) { unsigned int id, port; @@ -508,22 +538,24 @@ // convert to bytes hex_to_bin(tmpBuf, buf, size); - // read the "remaining" value - char remaining[4]; - if (!_at->recv(",%3[^\n]\n", remaining)) { + // read the "remaining" value + if (!_at->recv(",%d\n", &remaining)) { + tr_error("Failed reading the 'remaining' value after the received data."); size = NSAPI_ERROR_DEVICE_ERROR; } } } // we should get the OK (even if there is no data to read) - if (!_at->recv("OK")) { + if (_at->recv("OK")) { + tr_debug("Socket RecvFrom: Read %d bytes, %d bytes remaining.", size, remaining); + } else { + tr_error("Socket RecvFrom: Didn't receive OK from AT+NSORF command."); size = NSAPI_ERROR_DEVICE_ERROR; } } - UNLOCK(); - + _at->debug_on(_debug_trace_on); free(tmpBuf); return size;