Ejemplo n.º 1
0
	int MsgQueueConnection::send(uint num_bytes, const char *src, bool immediate_send_hint)
	{
		if (!is_connected())
		{
			LOG("SKYPE ERROR - LocalServerConnection::send(), not connected");
			return -1;
		}

		// message is copied because STTester modifies the buffer and needs a non-const
		//SEString msg = message;
		//STTester_ON_OUTGOING_EVENT(msg);

		message_buf msg_buf;

		//loop through msg 
		//
		int tot = num_bytes;
		int offset = 0;

		do
		{
			//send msg to queue in chunks
			msg_buf.len = min(tot, KMaxQueueSlotSize);
			Mem::Copy(msg_buf.buf, (const char*)src+offset, msg_buf.len);
			TInt err = GetOutQueue().Send( msg_buf );
			LOG("TRANSPORT: MsgQueueConnection::send - Buffer sent, err: " + SEString::from(err));

			// If we hit exactly the maximum slot size, skypekit expects more data and will "hang".
			// To prevent this we send a terminating message with length 0. (AAAXL-115).
			if ( tot == KMaxQueueSlotSize )
			{
				message_buf emptyBuf;
				emptyBuf.len = 0;
				TInt err = GetOutQueue().Send( emptyBuf );
				LOG("TRANSPORT: MsgQueueConnection::send - Empty buffer sent, err: " + SEString::from(err));
			}

			tot -= msg_buf.len;
			offset += msg_buf.len;
		}
		while (tot>0);

#if 0
		if (debug)
			LOG("TRANSPORT: Wrote message \"" + msg + "\"");
#endif

		return offset;
	}
Ejemplo n.º 2
0
VOID VIOSerialReclaimConsumedBuffers(IN PVIOSERIAL_PORT Port)
{
    WDFREQUEST request;
    PSINGLE_LIST_ENTRY iter;
    PVOID buffer;
    UINT len;
    struct virtqueue *vq = GetOutQueue(Port);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_QUEUEING, "--> %s\n", __FUNCTION__);

    if (vq)
    {
        while ((buffer = virtqueue_get_buf(vq, &len)) != NULL)
        {
            if (Port->PendingWriteRequest != NULL)
            {
                request = Port->PendingWriteRequest;
                Port->PendingWriteRequest = NULL;

                if (WdfRequestUnmarkCancelable(request) != STATUS_CANCELLED)
                {
                    WdfRequestCompleteWithInformation(request, STATUS_SUCCESS,
                                                      (size_t)WdfRequestGetInformation(request));
                }
                else
                {
                    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_QUEUEING,
                                "Request %p was cancelled.\n", request);
                }
            }

            iter = &Port->WriteBuffersList;
            while (iter->Next != NULL)
            {
                PWRITE_BUFFER_ENTRY entry = CONTAINING_RECORD(iter->Next,
                                            WRITE_BUFFER_ENTRY, ListEntry);

                if (buffer == entry->Buffer)
                {
                    iter->Next = entry->ListEntry.Next;

                    ExFreePoolWithTag(buffer, VIOSERIAL_DRIVER_MEMORY_TAG);
                    ExFreePoolWithTag(entry, VIOSERIAL_DRIVER_MEMORY_TAG);
                }
                else
                {
                    iter = iter->Next;
                }
            };

            Port->OutVqFull = FALSE;
        }
    }

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_QUEUEING, "<-- %s Full: %d\n",
                __FUNCTION__, Port->OutVqFull);
}
Ejemplo n.º 3
0
//////////////////////////////////////////////////////////////////////////
// Worker thread polls QAudioOutput device to see if there is room
// to put more data into it and then calls GetOutQueue(..) to get more data.
// This thread was needed because the normal "pull" mechanism of Qt does
// not work very well since it depends on the main process signal-slot event
// queue and you get dropouts if the GUI gets busy.
//////////////////////////////////////////////////////////////////////////
void CSoundOut::run()
{
	while(!m_ThreadQuit )	//execute loop until quit flag set
	{
		if( (QAudio::IdleState == m_pAudioOutput->state() ) ||
			(QAudio::ActiveState == m_pAudioOutput->state() ) )
		{	//Process sound data while soundcard is active and no errors
			unsigned int len =  m_pAudioOutput->bytesFree();	//in bytes
			if( len>0 )
			{
				//limit size to SOUND_WRITEBUFSIZE
				if(len > SOUND_WRITEBUFSIZE)
					len = SOUND_WRITEBUFSIZE;
				if(m_StereoOut)
				{
					len &= ~(0x03);	//keep on 4 byte chunks
					GetOutQueue( len/4, (TYPESTEREO16*)m_pData );
				}
				else
				{
					len &= ~(0x01);	//keep on 2 byte chunks
					GetOutQueue( len/2, (TYPEMONO16*)m_pData );
				}
				m_pOutput->write((char*)m_pData,len);
			}
			else	//no room in sound card output buffer so wait
			{		//not good but no other wait or blocking mechanism available
				msleep(m_BlockTime);
			}
		}
		else
		{	//bail out if error occurs
			qDebug()<<"SoundOut Error";
#if 0 //RRK
			if(m_pParent)
				((CSdrInterface*)m_pParent)->SendIOStatus(CSdrInterface::ERROR);
#endif
			m_ThreadQuit = true;
		}
	}
	qDebug()<<"sound thread exit";
}
Ejemplo n.º 4
0
size_t VIOSerialSendBuffers(IN PVIOSERIAL_PORT Port,
                            IN PVOID Buffer,
                            IN size_t Length)
{
    struct virtqueue *vq = GetOutQueue(Port);
    struct VirtIOBufferDescriptor sg[QUEUE_DESCRIPTORS];
    PVOID buffer = Buffer;
    size_t length = Length;
    int out = 0;
    int ret;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "--> %s Buffer: %p Length: %d\n", __FUNCTION__, Buffer, Length);

    if (BYTES_TO_PAGES(Length) > QUEUE_DESCRIPTORS)
    {
        return 0;
    }

    while (length > 0)
    {
        sg[out].physAddr = MmGetPhysicalAddress(buffer);
        sg[out].length = min(length, PAGE_SIZE);

        buffer = (PVOID)((LONG_PTR)buffer + sg[out].length);
        length -= sg[out].length;
        out += 1;
    }

    WdfSpinLockAcquire(Port->OutVqLock);

    ret = virtqueue_add_buf(vq, sg, out, 0, Buffer, NULL, 0);
    virtqueue_kick(vq);

    if (ret >= 0)
    {
        Port->OutVqFull = (ret == 0);
    }
    else
    {
        Length = 0;
        TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE,
                    "Error adding buffer to queue (ret = %d)\n", ret);
    }

    WdfSpinLockRelease(Port->OutVqLock);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "<-- %s\n", __FUNCTION__);

    return Length;
}