void TTinyTP::TTPHandleDataIndication ( TTPBuf *userData) // data read { int credit; Boolean m; check(userData); { int position, bufsize; position = BufUsed(userData); // should be zero bufsize = BufSize(userData); // amount read XTRACE(kHandleDataIndication, position, bufsize); } ttp_pdu_data_parse(userData, &m, &credit); // strips out ttp overhead byte this->SendCredit += credit; if (SendCredit > 30) SendCredit = 30; // FIXME: temp workaround for HP runaway credits // WARNING: HP tells us that Microsoft believes in // extending lots and lots of credits, and relies on // lap-layer flow control to survive. if (credit > 0) // if we've been given more credits from IrLan box TTPBackEnable(); // then tell clients flow-control state has changed if (BufSize(userData) > 0) { XTRACE(kHandleDataIndication, m, credit); // log what we parsed this->RemoteCredit--; if (m == false) // if no More data this->AppendTail(&(this->RxQueue), TTP_Segment_Last, 0, userData); else // else have More data this->AppendTail(&(this->RxQueue), TTP_Segment, 0, userData); } else { XTRACE(kDataLessPacket, m, credit); // log we received a dataless packet BufFree(userData); // we're done with it now... } // Make sure a read is pending at all times .... this could // use a better model. Only post if connected. if( this->Connected ) { CBufferSegment *getBuf; getBuf = BufAlloc(2048+5); // need up to max lap size require(getBuf, NoMem); this->DataGet(getBuf); } NoMem: return; }
void KeithleyDeviceImp::defineDigitalServReq(DL_ServiceRequest* ServReq) { // // read all digital channels // // // request group settings // ServReq->hWnd = GetDesktopWindow(); ServReq->device = 0; ServReq->subsystem = DI; ServReq->mode = POLLED; ServReq->operation = START; // // results group setttings // -none specified // // events group settings // // these are all DLEVENT structures ServReq->timing.typeEvent = NULLEVENT; ServReq->start.typeEvent = COMMAND; ServReq->stop.typeEvent = TCEVENT; // // select group setttings // ServReq->channels.nChannels = 2; ServReq->channels.numberFormat = tNATIVE; ServReq->channels.chanGain[0].channel = 0; ServReq->channels.chanGain[1].channel = NUM_DIGITAL_CHANNELS-1; ServReq->lpBuffers = (DL_BUFFERLIST*) new BYTE[DL_BufferListBytes(1)]; // create a list of buffers; in this case just one ServReq->lpBuffers->nBuffers = 1; ServReq->lpBuffers->bufferSize = Samples2Bytes(0,DI,0,NUM_DIGITAL_CHANNELS); // allocate enough memory in the buffer for the number of samples ServReq->lpBuffers->BufferAddr[0] = BufAlloc(GBUF_INT, ServReq->lpBuffers->bufferSize); // point at the data buffer so we can extract values digitalValues = (BYTE*)ServReq->lpBuffers->BufferAddr[0]; return; }
void TTinyTP::TTPHandleConnectConfirm ( TTPSAP sap, // calling TTP SAP TIrQOS *ourQOS, // our QoS TIrQOS *peerQOS, // peer QoS TTPBuf *userData) // calling UserData { unsigned char plist[100]; // enough for me ... int p; // parameters? int n; // initial credit XTRACE(kHandleConnectConfirm, 0, 0); ttp_pdu_connect_parse(userData, &p, &n, &plist[0]); // strips out ttp pdu params this->SendCredit = n; this->TxMaxSduSize = 0; //this->MaxSegSize = MaxTxIrLapDataSize - 3; this->MaxSegSize = peerQOS->GetDataSize() - 3; // get max send pkt size if (p == 1) { UInt32 value; if (ttp_pdu_connect_get_max_sdu_size(plist, &value)) this->TxMaxSduSize = value; XTRACE(kHandleConnectConfirm, 1, value); } this->Connected = true; // change state before my callback does more work! // this is a rather different ... as soon as the TTP session is open, hang a read // on the connection. every time a read completes, pass the buffer up, allocate // a new one, and hang another read out. TTP Client is responsible for eventually // freeing the buffers passed to it via DataIndication(). { CBufferSegment *getBuf; getBuf = BufAlloc(2048+5); // need up to max lap size require(getBuf, NoMem); // not a lot I can do w/out a read buffer this->DataGet(getBuf); // start the read } // Now that the read is pending, tell the client .... (was in other order) TTPConnectConfirm(sap, ourQOS, peerQOS, this->TxMaxSduSize, userData); // virtual callback to ttp client BufFree(userData); // free the connect buffer allocated by PDU Connect NoMem: return; }
void KeithleyDeviceImp::defineAnalogServReq(DL_ServiceRequest* ServReq) { // // setup a multi channel, polled AI task // // request group settings // ServReq->hWnd = GetDesktopWindow(); ServReq->device = 0; ServReq->subsystem = AI; ServReq->mode = POLLED; ServReq->operation = START; // // results group settings // -none specified // // events group settings // // these are all DLEVENT structures ServReq->timing.typeEvent = NULLEVENT; ServReq->start.typeEvent = COMMAND; ServReq->stop.typeEvent = TCEVENT; // // select group setttings // // start and stop channel range ServReq->channels.nChannels = 2; ServReq->channels.numberFormat = tNATIVE; // chanGain specifies the starting and ending channels and gain // start on channel 0, stop on channel NUM_ANALOG_CHANNELS-1 ServReq->channels.chanGain[0].channel = 0; ServReq->channels.chanGain[1].channel = NUM_ANALOG_CHANNELS-1; // setup channel gains using Gain2Code(device,subsystem,gain) // negative gain means bipolar gain, positive mean unipolar ServReq->channels.chanGain[0].gainOrRange = Gain2Code(0,AI,-1); ServReq->channels.chanGain[1].gainOrRange = Gain2Code(0,AI,-1); // need a buffer for data // polled mode tasks can scan the channels one time // the buffer MUST be a multiple of the channels // create a buffer list pointer for one buffer ServReq->lpBuffers = (DL_BUFFERLIST*) new BYTE[DL_BufferListBytes(1)]; // set number of buffers in the list ServReq->lpBuffers->nBuffers = 1; // specify the size of each buffer in bytes // Sample2Bytes converts the given number of samples to bytes // Sample2Bytes(device,subsystem,channel,samples) ServReq->lpBuffers->bufferSize = Samples2Bytes(0,AI,0,NUM_ANALOG_CHANNELS); // specify the memory address of each of the nBuffers // allocate memory suitable for POLLED data acquisition tasks ServReq->lpBuffers->BufferAddr[0] = BufAlloc(GBUF_POLLED, ServReq->lpBuffers->bufferSize); // // fill out DATA_CONVERT structure // // specify index of the data-acquisition buffer in the Buffer List (DL_BUFFERLIST) ServReq->start.u.dataConvert.wBuffer = 0; // specify the index of the starting sample in the data-acquisition buffer to convert ServReq->start.u.dataConvert.startIndex = 0; // specify the number of samples in the data-acquisition buffer to convert ServReq->start.u.dataConvert.nSamples = NUM_ANALOG_CHANNELS; // point to the applications data buffer ServReq->start.u.dataConvert.lpBuffer = analogValues; // specifies the data format of the applications data buffer ServReq->start.u.dataConvert.numberFormat = tSINGLE; // specifies a factor by which every converted sample will be multiplied // 0.0 means that it is ignored ServReq->start.u.dataConvert.scaling = 0.0f; // specifies a term which will be added to every converted sample ServReq->start.u.dataConvert.offset = 0.0f; return; }