Exemple #1
0
static AJ_Status AuthAdvance(AJ_SASL_Context* context, AJ_IOBuffer* rxBuf, AJ_IOBuffer* txBuf)
{
    AJ_Status status = AJ_OK;

    AJ_InfoPrintf(("AuthAdvance(context=0x%p, rxBuf=0x%p, txBuf=0x%p)\n", context, rxBuf, txBuf));

    if (context->state != AJ_SASL_SEND_AUTH_REQ) {
        /*
         * All the authentication messages end in a CR/LF so read until we get a newline
         */
        while ((AJ_IO_BUF_AVAIL(rxBuf) == 0) || (*(rxBuf->writePtr - 1) != '\n')) {
            status = rxBuf->recv(rxBuf, AJ_IO_BUF_SPACE(rxBuf), 3500);
            if (status != AJ_OK) {
                break;
            }
        }
    }
    if (status == AJ_OK) {
        uint32_t inLen = AJ_IO_BUF_AVAIL(rxBuf);
        *rxBuf->writePtr = '\0';
        status = AJ_SASL_Advance(context, (char*)rxBuf->readPtr, (char*)txBuf->writePtr, AJ_IO_BUF_SPACE(txBuf));
        if (status == AJ_OK) {
            rxBuf->readPtr += inLen;
            txBuf->writePtr += strlen((char*)txBuf->writePtr);
            status = txBuf->send(txBuf);
        }
    }
    return status;
}
Exemple #2
0
AJ_Status AJ_Net_RecvFrom(AJ_IOBuffer* buf, uint32_t len, uint32_t timeout)
{
    AJ_InfoPrintf(("AJ_Net_RecvFrom(buf=0x%p, len=%d., timeout=%d.)\n", buf, len, timeout));

    AJ_Status status = AJ_OK;
    int ret;
    uint32_t rx = AJ_IO_BUF_SPACE(buf);
    unsigned long Recv_lastCall = millis();

    AJ_InfoPrintf(("AJ_Net_RecvFrom(): len %d, rx %d, timeout %d\n", len, rx, timeout));

    rx = min(rx, len);

    while ((g_clientUDP.parsePacket() == 0) && (millis() - Recv_lastCall < timeout)) {
        delay(10); // wait for data or timeout
    }

    AJ_InfoPrintf(("AJ_Net_RecvFrom(): millis %d, Last_call %d, timeout %d, Avail %d\n", millis(), Recv_lastCall, timeout, g_clientUDP.available()));
    ret = g_clientUDP.read(buf->writePtr, rx);
    AJ_InfoPrintf(("AJ_Net_RecvFrom(): read() returns %d, rx %d\n", ret, rx));

    if (ret == -1) {
        AJ_InfoPrintf(("AJ_Net_RecvFrom(): read() fails. status=AJ_ERR_READ\n"));
        status = AJ_ERR_READ;
    } else {
        if (ret != -1) {
            AJ_DumpBytes("AJ_Net_RecvFrom", buf->writePtr, ret);
        }
        buf->writePtr += ret;
        AJ_InfoPrintf(("AJ_Net_RecvFrom(): status=AJ_OK\n"));
        status = AJ_OK;
    }
    AJ_InfoPrintf(("AJ_Net_RecvFrom(): status=%s\n", AJ_StatusText(status)));
    return status;
}
Exemple #3
0
static AJ_Status ComposeWhoHas(AJ_IOBuffer* txBuf, const char* prefix)
{
    size_t preLen = strlen(prefix);
    NSHeader* hdr = (NSHeader*)txBuf->writePtr;
    uint8_t* p = txBuf->writePtr + 6;
    size_t outLen = (6 + preLen + 2);

    AJ_InfoPrintf(("ComposeWhoHas(txbuf=0x%p, prefix=\"%s\")\n", txBuf, prefix));

    if (outLen > AJ_IO_BUF_SPACE(txBuf)) {
        AJ_ErrPrintf(("ComposeWhoHas(): AJ_ERR_RESOURCES\n"));
        return AJ_ERR_RESOURCES;
    }
    hdr->version = MSG_V1 | NSV_V1;
    hdr->qCount = 1;
    hdr->aCount = 0;
    hdr->ttl = 0;
    hdr->flags = WHO_HAS_MSG;
    hdr->nameCount = 1;
    *p++ = (uint8_t)(preLen + 1);
    memcpy(p, prefix, preLen);
    /*
     * Tack wild-card onto the end of the name to indicate it's prefix
     */
    p[preLen] = '*';
    txBuf->writePtr += outLen;
    return AJ_OK;
}
Exemple #4
0
static AJ_Status EncryptMessage(AJ_Message* msg)
{
    AJ_IOBuffer* ioBuf = &msg->bus->sock.tx;
    AJ_Status status;
    uint8_t key[16];
    uint8_t nonce[5];
    uint8_t role = AJ_ROLE_KEY_UNDEFINED;
    uint32_t mlen = MessageLen(msg);
    uint32_t hlen = mlen - msg->hdr->bodyLen;

    /*
     * Check there is room to append the MAC
     */
    if (AJ_IO_BUF_SPACE(ioBuf) < MAC_LENGTH) {
        return AJ_ERR_RESOURCES;
    }
    msg->hdr->bodyLen += MAC_LENGTH;
    ioBuf->writePtr += MAC_LENGTH;
    /*
     * Use the group key for multicast and broadcast signals the session key otherwise.
     */
    if ((msg->hdr->msgType == AJ_MSG_SIGNAL) && !msg->destination) {
        status = AJ_GetGroupKey(NULL, key);
    } else {
        status = AJ_GetSessionKey(msg->destination, key, &role);
    }
    if (status != AJ_OK) {
        AJ_ErrPrintf(("Encryption required but peer %s is not authenticated", msg->destination));
        status = AJ_ERR_SECURITY;
    } else {
        InitNonce(msg, role, nonce);
        status = AJ_Encrypt_CCM(key, ioBuf->bufStart, mlen, hlen, MAC_LENGTH, nonce, sizeof(nonce));
    }
    return status;
}
Exemple #5
0
/*
 * Write bytes to an I/O buffer
 */
static AJ_Status WriteBytes(AJ_Message* msg, const void* data, size_t numBytes, size_t pad)
{
    AJ_Status status = AJ_OK;
    AJ_IOBuffer* ioBuf = &msg->bus->sock.tx;
    if (numBytes && !data) {
        return AJ_ERR_NULL;
    }
    while (numBytes + pad) {
        size_t canWrite = AJ_IO_BUF_SPACE(ioBuf);
        if ((numBytes + pad) > canWrite) {
            /*
             * If we have already marshaled the header we can write what we have in the buffer
             */
            if (msg->hdr) {
                status = AJ_ERR_RESOURCES;
            } else {
                //#pragma calls = AJ_Net_Send
                status = ioBuf->send(ioBuf);
            }
            if (status != AJ_OK) {
                break;
            }
            canWrite = AJ_IO_BUF_SPACE(ioBuf);
        }
        /*
         * Write pad bytes
         */
        while (pad) {
            *ioBuf->writePtr++ = 0;
            --canWrite;
            --pad;
        }
        if (numBytes < canWrite) {
            canWrite = numBytes;
        }
        memcpy(ioBuf->writePtr, data, canWrite);
        ioBuf->writePtr += canWrite;
        numBytes -= canWrite;
    }
    return status;
}
Exemple #6
0
static AJ_Status ReadLine(AJ_IOBuffer* rxBuf) {
    /*
     * All the authentication messages end in a CR/LF so read until we get a newline
     */
    AJ_Status status = AJ_OK;
    while ((AJ_IO_BUF_AVAIL(rxBuf) == 0) || (*(rxBuf->writePtr - 1) != '\n')) {
        status = rxBuf->recv(rxBuf, AJ_IO_BUF_SPACE(rxBuf), 3500);
        if (status != AJ_OK) {
            break;
        }
    }
    return status;
}
Exemple #7
0
AJ_Status AJ_Net_RecvFrom(AJ_IOBuffer* buf, uint32_t len, uint32_t timeout)
{
    //AJ_InfoPrintf(("AJ_Net_RecvFrom(buf=0x%p, len=%d., timeout=%d.)\n", buf, len, timeout));

    AJ_Status status = AJ_OK;
    int ret;
    uint32_t rx = AJ_IO_BUF_SPACE(buf);
    unsigned long Recv_lastCall = millis();

  //  printf("AJ_Net_RecvFrom(): len %d, rx %d, timeout %d\n", len, rx, timeout);
	
  //  rx = min(rx, len);

   while ((sock_rx_state==0) && (millis() - Recv_lastCall < timeout))
    {
		//printf("millis() - Recv_lastCall = %d \n", (millis() - Recv_lastCall));
		recv(rx_socket, udp_data_rx, MAIN_WIFI_M2M_BUFFER_SIZE, 0);
		m2m_wifi_handle_events(NULL);
		
   }
   ret=sock_rx_state;
  // printf("AJ_Net_RecvFrom(): millis %d, Last_call %d, timeout %d, Avail %d\n", millis(), Recv_lastCall, timeout, g_clientUDP.available());
    //ret = g_clientUDP.read(buf->writePtr, rx);
	
    //AJ_InfoPrintf(("AJ_Net_RecvFrom(): read() returns %d, rx %d\n", ret, rx));

    if (ret == -1) 
	{
        printf("AJ_Net_RecvFrom(): read() fails. status=AJ_ERR_READ\n");
        status = AJ_ERR_READ;
    }
	else
	{
        if (ret != -1) 
		{
            AJ_DumpBytes("AJ_Net_RecvFrom", buf->writePtr, ret);
        }
        buf->writePtr += ret;
     //   printf("AJ_Net_RecvFrom(): status=AJ_OK\n");
        status = AJ_OK;
    }
    printf("AJ_Net_RecvFrom(): status=%s\n", AJ_StatusText(status));
    return /*sock_rx_state;*/status;
}
Exemple #8
0
AJ_Status RxFunc(AJ_IOBuffer* buf, uint32_t len, uint32_t timeout)
{
    size_t rx = AJ_IO_BUF_SPACE(buf);

    rx = min(len, rx);
    rx = min(wireBytes, rx);
    if (!rx) {
        return AJ_ERR_READ;
    } else {
        memcpy(buf->writePtr, wireBuffer, rx);
        /*
         * Shuffle the remaining data to the front of the buffer
         */
        memmove(wireBuffer, wireBuffer + rx, wireBytes - rx);
        wireBytes -= rx;
        buf->writePtr += rx;
        return AJ_OK;
    }
}
Exemple #9
0
AJ_Status AJ_Net_Recv(AJ_IOBuffer* buf, uint32_t len, uint32_t timeout)
{
    AJ_Status status = AJ_ERR_READ;
    uint32_t ret;
    uint32_t rx = AJ_IO_BUF_SPACE(buf);
    uint32_t recvd = 0;
    unsigned long Recv_lastCall = millis();

    // first we need to clear out our buffer
    uint32_t M = 0;
	//printf("AJ_Net_Recv(buf=0x%p, len=%d., timeout=%d.)\n", buf, len, timeout);
    if (rxLeftover != 0)
	{
	// there was something leftover from before,
	//    printf("AJ_NetRecv(): leftover was: %d\n", rxLeftover);
		M = min(rx, rxLeftover);
		memcpy(buf->writePtr, rxDataStash, M);  // copy leftover into buffer.
		buf->writePtr += M;  // move the data pointer over
		memmove(rxDataStash, rxDataStash + M, rxLeftover - M); // shift left-overs toward the start.
		rxLeftover -= M;
		recvd += M;
		// we have read as many bytes as we can
		// higher level isn't requesting any more
		if (recvd == rx)
		{
	//		printf("AJ_Net_Recv(): status=AJ_OK\n");
			return AJ_OK;
		}
	}
	if ((M != 0) && (rxLeftover != 0)) 
	{
	   printf("AJ_Net_REcv(): M was: %d, rxLeftover was: %d\n", M, rxLeftover);
	}
	//printf("NetRecv before while: tcp_data_rx[0]= %d\n", tcp_data_rx[0]);
	while ((tcp_rx_ready==0) && (millis() - Recv_lastCall < timeout))
	{
	//	recv(tcp_client_socket, gau8SocketTestBuffer, sizeof(gau8SocketTestBuffer), 0);
		recv(tcp_client_socket, tcp_data_rx, sizeof(tcp_data_rx), 0);
	//	recv(tcp_client_socket, buf->writePtr, sizeof(tcp_data_rx), 0);
		
		m2m_wifi_handle_events(NULL);
	}
//	printf("NetRecv: tcp_data_rx[0]= %d\n", tcp_data_rx[0]);
    if (tcp_rx_ready==0) 
	{
		printf("AJ_Net_Recv(): timeout. status=AJ_ERR_TIMEOUT\n");
        status = AJ_ERR_TIMEOUT;
    } 
	else
	{    
	   memcpy(AJ_in_data_tcp, tcp_data_rx,tcp_rx_ready);
	   uint32_t askFor = rx;
	   askFor -= M;
	   ret=tcp_rx_ready;
	 //  printf("AJ_Net_Recv(): ask for: %d\n", askFor);
	   if (askFor < ret) 
	   {
		   printf("AJ_Net_Recv(): BUFFER OVERRUN: askFor=%u, ret=%u\n", askFor, ret);
	   }
       if (ret == -1) 
	   {
	        printf("AJ_Net_Recv(): read() failed. status=AJ_ERR_READ\n");
	        status = AJ_ERR_READ;
	   } 
	   else
	   {
	    //    printf("AJ_Net_Recv(): ret now %d\n", ret);
	        AJ_DumpBytes("Recv", buf->writePtr, ret);

	        if (ret > askFor) 
			{
		        printf("AJ_Net_Recv(): new leftover %d\n", ret - askFor);
		        // now shove the extra into the stash
		        memcpy(rxDataStash + rxLeftover, buf->writePtr + askFor, ret - askFor);
		        rxLeftover += (ret - askFor);
		        buf->writePtr += rx;
		    }
			else
			{
		        buf->writePtr += ret;
	        }
	        status = AJ_OK;
        }
    }
  //  printf("!!!!!!!!!!!!!!!buf->writePtr=%x\n",buf->writePtr);
    tcp_rx_ready=0;
    return status;
}
Exemple #10
0
AJ_Status AJ_Net_Recv(AJ_IOBuffer* buf, uint32_t len, uint32_t timeout)
{
    AJ_Status status = AJ_ERR_READ;
    uint32_t ret;
    uint32_t rx = AJ_IO_BUF_SPACE(buf);
    uint32_t recvd = 0;
    unsigned long Recv_lastCall = millis();

    // first we need to clear out our buffer
    uint32_t M = 0;

    AJ_InfoPrintf(("AJ_Net_Recv(buf=0x%p, len=%d., timeout=%d.)\n", buf, len, timeout));

    if (rxLeftover != 0) {
        // there was something leftover from before,
        AJ_InfoPrintf(("AJ_NetRecv(): leftover was: %d\n", rxLeftover));
        M = min(rx, rxLeftover);
        memcpy(buf->writePtr, rxDataStash, M);  // copy leftover into buffer.
        buf->writePtr += M;  // move the data pointer over
        memmove(rxDataStash, rxDataStash + M, rxLeftover - M); // shift left-overs toward the start.
        rxLeftover -= M;
        recvd += M;

        // we have read as many bytes as we can
        // higher level isn't requesting any more
        if (recvd == rx) {
            AJ_InfoPrintf(("AJ_Net_Recv(): status=AJ_OK\n"));
            return AJ_OK;
        }
    }

    if ((M != 0) && (rxLeftover != 0)) {
        AJ_InfoPrintf(("AJ_Net_REcv(): M was: %d, rxLeftover was: %d\n", M, rxLeftover));
    }

    // wait for data to become available
    // time out if nothing arrives
    while (g_client.connected() &&
           g_client.available() == 0 &&
           (millis() - Recv_lastCall < timeout)) {
        delay(50); // wait for data or timeout
    }

    // return timeout if nothing is available
    AJ_InfoPrintf(("AJ_Net_Recv(): millis %d, Last_call %d timeout %d Avail: %d\n", millis(), Recv_lastCall, timeout, g_client.available()));
    if (g_client.connected() && (millis() - Recv_lastCall >= timeout) && (g_client.available() == 0)) {
        AJ_InfoPrintf(("AJ_Net_Recv(): timeout. status=AJ_ERR_TIMEOUT\n"));
        return AJ_ERR_TIMEOUT;
    }

    if (g_client.connected()) {
        uint32_t askFor = rx;
        askFor -= M;
        AJ_InfoPrintf(("AJ_Net_Recv(): ask for: %d\n", askFor));
        ret = g_client.read(buf->writePtr, askFor);
        AJ_InfoPrintf(("AJ_Net_Recv(): read(): ret %d  askfor %d\n", ret, askFor));

        if (askFor < ret) {
            AJ_InfoPrintf(("AJ_Net_Recv(): BUFFER OVERRUN: askFor=%u, ret=%u\n", askFor, ret));
        }

        if (ret == -1) {
            AJ_ErrPrintf(("AJ_Net_Recv(): read() failed. status=AJ_ERR_READ\n"));
            status = AJ_ERR_READ;
        } else {
            AJ_InfoPrintf(("AJ_Net_Recv(): ret now %d\n", ret));
            AJ_DumpBytes("Recv", buf->writePtr, ret);

            if (ret > askFor) {
                AJ_InfoPrintf(("AJ_Net_Recv(): new leftover %d\n", ret - askFor));
                // now shove the extra into the stash
                memcpy(rxDataStash + rxLeftover, buf->writePtr + askFor, ret - askFor);
                rxLeftover += (ret - askFor);
                buf->writePtr += rx;
            } else {
                buf->writePtr += ret;
            }
            status = AJ_OK;
        }
    }

    return status;
}
Exemple #11
0
static AJ_Status AJ_Net_RecvFrom(AJ_IOBuffer* buf, uint32_t len, uint32_t timeout)
{
    AJ_Status status;
    DWORD ret;
    DWORD rx = AJ_IO_BUF_SPACE(buf);
    fd_set fds;
    size_t rc = 0;
    size_t i;
    const struct timeval tv = { timeout / 1000, 1000 * (timeout % 1000) };
    SOCKET sock;
    int numSocks = 0;

    AJ_InfoPrintf(("AJ_Net_RecvFrom(buf=0x%p, len=%d., timeout=%d.)\n", buf, len, timeout));

    assert(buf->direction == AJ_IO_BUF_RX);
    assert(NumMcastSocks > 0);

    // we sent the discovery requests out on ALL broadcast and multicast interfaces
    // now we need to listen on the NS version 1 sockets and the mDNS recv sockets
    FD_ZERO(&fds);
    for (i = 0; i < NumMcastSocks; ++i) {
        if (!McastSocks[i].is_mdns || McastSocks[i].is_mdnsrecv) {
            SOCKET sock = McastSocks[i].sock;
            FD_SET(sock, &fds);
            numSocks++;
        }
    }

    // wait for discovery response
    rc = select(numSocks, &fds, NULL, NULL, &tv);
    if (rc == 0) {
        AJ_InfoPrintf(("AJ_Net_RecvFrom(): select() timed out. status=AJ_ERR_TIMEOUT\n"));
        return AJ_ERR_TIMEOUT;
    } else if (rc < 0) {
        AJ_ErrPrintf(("AJ_Net_RecvFrom(): select() failed. WSAGetLastError()=0x%x, status=AJ_ERR_READ\n", WSAGetLastError()));
        return AJ_ERR_READ;
    }

    // ignore multiple replies; only consider the first one to arrive
    rx = min(rx, len);
    for (i = 0; i < NumMcastSocks; ++i) {
        if (!McastSocks[i].is_mdns || McastSocks[i].is_mdnsrecv) {
            if (FD_ISSET(McastSocks[i].sock, &fds)) {
                sock = McastSocks[i].sock;
                if (McastSocks[i].is_mdnsrecv) {
                    buf->flags |= AJ_IO_BUF_MDNS;
                } else {
                    buf->flags |= AJ_IO_BUF_AJ;
                }
                break;
            }
        }
    }

    if (sock != INVALID_SOCKET) {
        ret = recvfrom(sock, buf->writePtr, rx, 0, NULL, 0);
        if (ret == SOCKET_ERROR) {
            AJ_ErrPrintf(("AJ_Net_RecvFrom(): recvfrom() failed. WSAGetLastError()=0x%x, status=AJ_ERR_READ\n", WSAGetLastError()));
            status = AJ_ERR_READ;
        } else {
            buf->writePtr += ret;
            status = AJ_OK;
        }
    } else {
        AJ_ErrPrintf(("AJ_Net_RecvFrom(): invalid socket.  status=AJ_ERR_READ\n"));
        status = AJ_ERR_READ;
    }

    AJ_InfoPrintf(("AJ_Net_RecvFrom(): status=%s\n", AJ_StatusText(status)));
    return status;
}
Exemple #12
0
static AJ_Status AJ_Net_Recv(AJ_IOBuffer* buf, uint32_t len, uint32_t timeout)
{
    AJ_Status status = AJ_ERR_READ;
    WSAEVENT events[2];
    DWORD rx = AJ_IO_BUF_SPACE(buf);
    DWORD flags = 0;
    DWORD ret = SOCKET_ERROR;
    NetContext* ctx = (NetContext*) buf->context;

    AJ_InfoPrintf(("AJ_Net_Recv(buf=0x%p, len=%d, timeout=%d)\n", buf, len, timeout));

    assert(buf->direction == AJ_IO_BUF_RX);

    rx = min(rx, len);
    if (!rx) {
        return AJ_OK;
    }
    /*
     * Overlapped receives cannot be cancelled. We are relying the fact that a timedout or
     * interrupted receive will be eventually reposted with the same buffer.
     */
    if (wsaOverlapped.hEvent == INVALID_HANDLE_VALUE) {
        wsbuf.len = rx;
        wsbuf.buf = buf->writePtr;
        memset(&wsaOverlapped, 0, sizeof(WSAOVERLAPPED));
        wsaOverlapped.hEvent = recvEvent;
        ret = WSARecv(ctx->tcpSock, &wsbuf, 1, NULL, &flags, &wsaOverlapped, NULL);
        if ((ret == SOCKET_ERROR) && (WSAGetLastError() != WSA_IO_PENDING)) {
            AJ_ErrPrintf(("WSARecv(): failed WSAGetLastError()=%d\n", WSAGetLastError()));
            return AJ_ERR_READ;
        }
    }
    /*
     * Assert that the buffer and length are the same in the case where this is a reposting of the
     * receive after an timeout or interrupt.
     */
    AJ_ASSERT(wsbuf.buf == buf->writePtr);
    AJ_ASSERT(wsbuf.len == rx);

    events[0] = wsaOverlapped.hEvent;
    events[1] = interruptEvent;
    ret = WSAWaitForMultipleEvents(2, events, FALSE, timeout, TRUE);
    if (ret == WSA_WAIT_EVENT_0) {
        if (WSAGetOverlappedResult(ctx->tcpSock, &wsaOverlapped, &rx, TRUE, &flags)) {
            status = AJ_OK;
        }
    } else if (ret == WSA_WAIT_TIMEOUT) {
        status = AJ_ERR_TIMEOUT;
    } else if (ret == (WSA_WAIT_EVENT_0 + 1)) {
        WSAResetEvent(interruptEvent);
        status = AJ_ERR_INTERRUPTED;
    } else {
        AJ_ErrPrintf(("AJ_Net_Recv(): WSAGetLastError()=%d\n", WSAGetLastError()));
    }
    if (status == AJ_OK) {
        /*
         * Reset recv event and clear overlapped struct for the next call
         */
        WSAResetEvent(wsaOverlapped.hEvent);
        wsaOverlapped.hEvent = INVALID_HANDLE_VALUE;
        buf->writePtr += rx;
        AJ_InfoPrintf(("AJ_Net_Recv(): read %d bytes\n", rx));
    }
    return status;
}