Пример #1
0
/**
 * Send data to the partner.
 * The return is the number of bytes actually transmitted which may also be
 * 0 to indicate no bytes sent or -1 to indicate an error.  For the ESP8266 implementation we
 * will return 0 if the socket is not connected or we are in the `SOCKET_STATE_TRANSMITTING`
 * state.
 */
int net_ESP8266_BOARD_send(
    JsNetwork *net,  //!< The Network we are going to use to create the socket.
    int sckt,        //!< The socket over which we will send data.
    const void *buf, //!< The buffer containing the data to be sent.
    size_t len       //!< The length of data in the buffer to send.
) {
    //DBG("%s:send\n", DBG_LIB);
    struct socketData *pSocketData = getSocketData(sckt);
    assert(pSocketData->state != SOCKET_STATE_UNUSED);

    // If the socket is in error or it is closing return -1
    switch (pSocketData->state) {
    case SOCKET_STATE_CLOSED:
    case SOCKET_STATE_DISCONNECTING:
        return pSocketData->errorCode != 0 ? pSocketData->errorCode : SOCKET_ERR_CLOSED;
    case SOCKET_STATE_ABORTING:
        return pSocketData->errorCode;
    case SOCKET_STATE_TO_ABORT:
        espconn_abort(pSocketData->pEspconn);
        return pSocketData->errorCode;
    default:
        break;
    }

    // Unless we are in the idle state, we can't send more shtuff
    if (pSocketData->state != SOCKET_STATE_IDLE) {
        return 0;
    }

    // Log the content of the data we are sending.
    //esp8266_board_writeString(buf, len);
    //os_printf("\n");

    // Copy the data to be sent into a transmit buffer we hand off to espconn
    assert(pSocketData->currentTx == NULL);
    pSocketData->currentTx = (uint8_t *)os_malloc(len);
    if (pSocketData->currentTx == NULL) {
        DBG("%s: Out of memory sending %d on socket %d\n", DBG_LIB, len, sckt);
        setSocketInError(pSocketData, ESPCONN_MEM);
        espconn_abort(pSocketData->pEspconn);
        pSocketData->state = SOCKET_STATE_ABORTING;
        return pSocketData->errorCode;
    }
    memcpy(pSocketData->currentTx, buf, len);

    // Send the data over the ESP8266 SDK.
    int rc = espconn_send(pSocketData->pEspconn, pSocketData->currentTx, len);
    if (rc < 0) {
        setSocketInError(pSocketData, rc);
        os_free(pSocketData->currentTx);
        pSocketData->currentTx = NULL;
        espconn_abort(pSocketData->pEspconn);
        pSocketData->state = SOCKET_STATE_ABORTING;
        return rc;
    }

    pSocketData->state = SOCKET_STATE_TRANSMITTING;
    //DBG("%s: socket %d JS send %d\n", DBG_LIB, sckt, len);
    return len;
}
Пример #2
0
/**
 * Perform an actual closure of the socket by calling the ESP8266 disconnect API.
 */
static void doClose(
    struct socketData *pSocketData //!< The socket to be closed.
) {
    if (pSocketData == NULL) return; // just in case

    // if we're already closing, then don't do anything
    if (pSocketData->state == SOCKET_STATE_CLOSED ||
            pSocketData->state == SOCKET_STATE_DISCONNECTING)
    {
        return;
    }

    // if we're in the name resolution phase, we don't have much to do
    // if we're in aborting ditto
    if (pSocketData->state == SOCKET_STATE_HOST_RESOLVING ||
            pSocketData->state == SOCKET_STATE_ABORTING)
    {
        pSocketData->state = SOCKET_STATE_DISCONNECTING;
        return;
    }

    // if we need to abort, then do that
    if (pSocketData->state == SOCKET_STATE_TO_ABORT) {
        espconn_abort(pSocketData->pEspconn);
        pSocketData->state = SOCKET_STATE_DISCONNECTING;
        return;
    }

    // Tell espconn to disconnect/delete the connection
    if (pSocketData->creationType == SOCKET_CREATED_SERVER) {
        //dumpEspConn(pSocketData->pEspconn);
        int rc = espconn_delete(pSocketData->pEspconn);
        if (rc != 0) {
            setSocketInError(pSocketData, rc);
        }
        // FIXME: do we get a disconnected callback or is this it? If we don't get a callback we can
        // go straight to SOCKET_STATE_CLOSED
        pSocketData->state = SOCKET_STATE_DISCONNECTING;

    } else {
        int rc = espconn_disconnect(pSocketData->pEspconn);
        if (rc == 0) {
            pSocketData->state = SOCKET_STATE_DISCONNECTING;
        } else {
            setSocketInError(pSocketData, rc);
            pSocketData->state = SOCKET_STATE_CLOSED; // don't expect a callback
        }
    }
}
Пример #3
0
/**
  * @brief  Delete tcp client and free all memory
  * @param  mqttClient: The mqtt client which contain TCP client
  * @retval None
  */
void ICACHE_FLASH_ATTR mqtt_tcpclient_delete(MQTT_Client * mqttClient) {
    if (mqttClient->pCon != NULL) {
	MQTT_INFO("TCP: Free memory\r\n");
	// Force abort connections
	espconn_abort(mqttClient->pCon);
	// Delete connections
	espconn_delete(mqttClient->pCon);

	if (mqttClient->pCon->proto.tcp) {
	    os_free(mqttClient->pCon->proto.tcp);
	    mqttClient->pCon->proto.tcp = NULL;
	}
	os_free(mqttClient->pCon);
	mqttClient->pCon = NULL;
    }
}
Пример #4
0
/**
 * Receive data from the network device.
 * Returns the number of bytes received which may be 0 and <0 if there was an error.
 */
int net_ESP8266_BOARD_recv(
    JsNetwork *net, //!< The Network we are going to use to create the socket.
    int sckt,       //!< The socket from which we are to receive data.
    void *buf,      //!< The storage buffer into which we will receive data.
    size_t len      //!< The length of the buffer.
) {
    //DBG("%s:recv\n", DBG_LIB);
    struct socketData *pSocketData = getSocketData(sckt);
    assert(pSocketData);
    assert(pSocketData->state != SOCKET_STATE_UNUSED);

    // handle socket that needs aborting
    if (pSocketData->state == SOCKET_STATE_TO_ABORT) {
        espconn_abort(pSocketData->pEspconn);
        return pSocketData->errorCode;
    }

    // If there is no data in the receive buffer, then all we need do is return
    // 0 bytes as the length of data moved or -1 if the socket is actually closed.
    if (pSocketData->rxBufQ == NULL) {
        switch (pSocketData->state) {
        case SOCKET_STATE_CLOSED:
            return pSocketData->errorCode != 0 ? pSocketData->errorCode : SOCKET_ERR_CLOSED;
        case SOCKET_STATE_DISCONNECTING:
        case SOCKET_STATE_ABORTING:
            return pSocketData->errorCode;
        case SOCKET_STATE_HOST_RESOLVING:
        case SOCKET_STATE_CONNECTING:
            return SOCKET_ERR_NO_CONN;
        default:
            return 0; // we just have no data
        }
    }
    PktBuf *rxBuf = pSocketData->rxBufQ;

    // If the receive buffer is able to completely fit in the buffer
    // passed into us then we can copy all the data and the receive buffer will be clear.
    if (rxBuf->filled <= len) {
        os_memcpy(buf, rxBuf->data, rxBuf->filled);
        int retLen = rxBuf->filled;
        pSocketData->rxBufQ = PktBuf_ShiftFree(rxBuf);
        // if we now have exactly one buffer enqueued we need to re-enable the flood
        if (pSocketData->rxBufQ != NULL && pSocketData->rxBufQ->next == NULL)
            espconn_recv_unhold(pSocketData->pEspconn);
        //DBG("%s: socket %d JS recv %d\n", DBG_LIB, sckt, retLen);
        return retLen;
    }

    // If we are here, then we have more data in the receive buffer than is available
    // to be returned in this request for data.  So we have to copy the amount of data
    // that is allowed to be returned and then strip that from the beginning of the
    // receive buffer.

    // First we copy the data we are going to return.
    os_memcpy(buf, rxBuf->data, len);
    // Next we shift up the remaining data
    uint16_t newLen = rxBuf->filled - len;
    os_memmove(rxBuf->data, rxBuf->data + len, newLen);
    rxBuf->filled = newLen;
    //DBG("%s: socket %d JS recv %d\n", DBG_LIB, sckt, len);
    return len;
}