Fixed VPB plug in build under linux
[opal.git] / plugins / LID / VPB / vpb.cpp
blob18fbd8ba918cc1def82fae1b20aa2aa872007363
1 /*
2 * Voicetronix VPB Plugin LID for OPAL
4 * Copyright (C) 2006 Post Increment, All Rights Reserved
6 * The contents of this file are subject to the Mozilla Public License
7 * Version 1.0 (the "License"); you may not use this file except in
8 * compliance with the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS"
12 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
13 * the License for the specific language governing rights and limitations
14 * under the License.
16 * The Original Code is OPAL.
18 * The Initial Developer of the Original Code is Post Increment
20 * Contributor(s): ______________________________________.
22 * $Log$
23 * Revision 1.2 2006/10/04 04:21:16 rjongbloed
24 * Fixed VPB plug in build under linux
26 * Revision 1.1 2006/10/02 13:30:53 rjongbloed
27 * Added LID plug ins
31 #define PLUGIN_DLL_EXPORTS
32 #include <lids/lidplugin.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <iostream>
37 #include <fstream>
39 #include "vpbapi.h"
41 #if defined(_MSC_VER)
42 #pragma comment(lib, "libvpb.lib")
43 #endif
46 static const struct {
47 const char * mediaFormat;
48 unsigned short mode;
49 } CodecInfo[] = {
50 { "PCM-16", VPB_LINEAR },
51 { "G.711-uLaw-64k", VPB_MULAW },
52 { "G.711-ALaw-64k", VPB_ALAW },
56 class Context
58 protected:
59 unsigned m_uiLineCount;
60 enum { MaxLineCount = 12 };
62 struct LineState
64 PluginLID_Boolean Open(unsigned cardNumber, unsigned lineNumber)
66 /* +1 is used for driver 2.4.8*/
67 handle = vpb_open(cardNumber, lineNumber);
68 if (handle < 0)
69 return FALSE;
70 readFrameSize = writeFrameSize = 480;
71 currentHookState = FALSE;
72 vpb_sethook_sync(handle, VPB_ONHOOK);
73 vpb_set_event_mask(handle, VPB_MRING | VPB_MTONEDETECT );
74 return TRUE;
77 PluginLID_Boolean SetLineOffHook(PluginLID_Boolean newState)
79 try {
80 if (vpb_sethook_sync(handle, newState ? VPB_OFFHOOK : VPB_ONHOOK) < 0)
81 return FALSE;
83 // clear DTMF buffer and event queue after changing hook state.
84 vpb_flush_digits(handle);
86 VPB_EVENT event;
87 while (vpb_get_event_ch_async(handle, &event) == VPB_OK)
91 catch (VpbException v) {
92 std::cerr << "VPB\tSetLineOffHook " << v.code << ", s = " << v.s << ", api func = " << v.api_function << std::endl;
93 return FALSE;
96 currentHookState = newState;
97 return TRUE;
100 int handle;
101 PluginLID_Boolean currentHookState;
102 const char * readFormat;
103 const char * writeFormat;
104 size_t readFrameSize, writeFrameSize;
105 } lineState[MaxLineCount];
107 public:
108 PLUGIN_LID_CTOR()
110 m_uiLineCount = 0;
111 memset(lineState, 0, sizeof(lineState));
114 PLUGIN_LID_DTOR()
116 Close();
120 PLUGIN_FUNCTION_ARG3(GetDeviceName,unsigned,index, char *,name, unsigned,size)
122 if (name == NULL || size < 2)
123 return PluginLID_InvalidParameter;
125 try {
126 int iHandle = vpb_open(index, 1 /* 0 for driver 3.01*/);
127 if (iHandle >= 0) {
128 int lineCount = vpb_get_ports_per_card(/*getCardNumber()*/);
129 vpb_close(iHandle);
130 if (lineCount > 0) {
131 snprintf(name, size, "%u", index);
132 return PluginLID_NoError;
136 catch (VpbException v) {
137 std::cerr << "VPB\tOpalVpbDevice::GetLineCount Error code = " << v.code << ", s = " << v.s << " api func = " << v.api_function << std::endl;
139 return PluginLID_NoMoreNames;
143 PLUGIN_FUNCTION_ARG1(Open,const char *,device)
145 Close();
147 int cardNumber = atoi(device);
148 int iHandle = vpb_open(cardNumber, /* 0 for driver 3.01*/1);
149 /* get the number of ports for this card */
150 m_uiLineCount = vpb_get_ports_per_card(/*cardNumber*/);
151 vpb_close(iHandle);
153 if (m_uiLineCount == 0)
154 return PluginLID_NoSuchDevice;
156 try {
157 for(unsigned uiLineCount = 0; uiLineCount < m_uiLineCount; uiLineCount++)
158 lineState[uiLineCount].Open(cardNumber, uiLineCount);
160 catch (VpbException v) {
161 std::cerr << "VPB\tOpalVpbDevice::Open Error code = " << v.code << ", s = " << v.s << " api func = " << v.api_function << std::endl;
162 m_uiLineCount = 0;
163 return PluginLID_DeviceOpenFailed;
166 return PluginLID_NoError;
170 PLUGIN_FUNCTION_ARG0(Close)
172 if (m_uiLineCount == 0)
173 return PluginLID_NoError;
175 try {
176 for(unsigned uiLineCount = 0; uiLineCount < m_uiLineCount; uiLineCount++) {
177 SetLineOffHook(uiLineCount, FALSE);
178 vpb_close(lineState[uiLineCount].handle);
181 catch (VpbException v) {
182 std::cerr << "VPB\tOpalVpbDevice::Close Error code = " << v.code << ", s = " << v.s << ", api func = " << v.api_function << std::endl;
185 m_uiLineCount = 0;
186 return PluginLID_NoError;
190 PLUGIN_FUNCTION_ARG1(GetLineCount, unsigned *,count)
192 if (count == NULL)
193 return PluginLID_InvalidParameter;
195 if (m_uiLineCount == 0)
196 return PluginLID_DeviceNotOpen;
198 *count = m_uiLineCount;
199 return PluginLID_NoError;
203 PLUGIN_FUNCTION_ARG2(IsLineTerminal, unsigned,line, PluginLID_Boolean *,isTerminal)
205 if (isTerminal == NULL)
206 return PluginLID_InvalidParameter;
208 if (m_uiLineCount == 0)
209 return PluginLID_DeviceNotOpen;
211 if (line >= m_uiLineCount)
212 return PluginLID_NoSuchLine;
214 *isTerminal = FALSE;
215 return PluginLID_NoError;
219 PLUGIN_FUNCTION_ARG3(IsLinePresent, unsigned,line, PluginLID_Boolean,forceTest, PluginLID_Boolean *,present)
221 if (present == NULL)
222 return PluginLID_InvalidParameter;
224 if (m_uiLineCount == 0)
225 return PluginLID_DeviceNotOpen;
227 if (line >= m_uiLineCount)
228 return PluginLID_NoSuchLine;
230 *present = TRUE;
231 return PluginLID_NoError;
235 PLUGIN_FUNCTION_ARG2(IsLineOffHook, unsigned,line, PluginLID_Boolean *,offHook)
237 if (offHook == NULL)
238 return PluginLID_InvalidParameter;
240 if (m_uiLineCount == 0)
241 return PluginLID_DeviceNotOpen;
243 if (line >= m_uiLineCount)
244 return PluginLID_NoSuchLine;
246 *offHook = lineState[line].currentHookState;
247 return PluginLID_NoError;
251 PLUGIN_FUNCTION_ARG2(SetLineOffHook, unsigned,line, PluginLID_Boolean,newState)
253 if (m_uiLineCount == 0)
254 return PluginLID_DeviceNotOpen;
256 if (line >= m_uiLineCount)
257 return PluginLID_NoSuchLine;
259 return lineState[line].SetLineOffHook(newState) ? PluginLID_NoError : PluginLID_InternalError;
263 //PLUGIN_FUNCTION_ARG2(HookFlash, unsigned,line, unsigned,flashTime)
264 //PLUGIN_FUNCTION_ARG2(HasHookFlash, unsigned,line, PluginLID_Boolean *,flashed)
266 PLUGIN_FUNCTION_ARG2(IsLineRinging, unsigned,line, unsigned long *,cadence)
268 if (cadence == NULL)
269 return PluginLID_InvalidParameter;
271 if (m_uiLineCount == 0)
272 return PluginLID_DeviceNotOpen;
274 if (line >= m_uiLineCount)
275 return PluginLID_NoSuchLine;
277 *cadence = 0; // Not ringing
279 if (!lineState[line].currentHookState) {
280 // DR 13/1/02 - Dont look at event queue here if off hook, as we will steal events
281 // that IsToneDetected may be looking for.
282 VPB_EVENT event;
283 if (vpb_get_event_ch_async(lineState[line].handle, &event) == VPB_OK && event.type == VPB_RING)
284 *cadence = 1;
286 return PluginLID_NoError;
289 //PLUGIN_FUNCTION_ARG3(RingLine, unsigned,line, unsigned,nCadence, unsigned *,pattern)
290 //PLUGIN_FUNCTION_ARG3(IsLineConnected, unsigned,line, PluginLID_Boolean,checkForWink, PluginLID_Boolean *,connected)
291 //PLUGIN_FUNCTION_ARG3(SetLineToLineDirect, unsigned,line1, unsigned,line2, PluginLID_Boolean,connect)
292 //PLUGIN_FUNCTION_ARG3(IsLineToLineDirect, unsigned,line1, unsigned,line2, PluginLID_Boolean *,connected)
295 PLUGIN_FUNCTION_ARG3(GetSupportedFormat, unsigned,index, char *,mediaFormat, unsigned,size)
297 if (mediaFormat == NULL || size < 2)
298 return PluginLID_InvalidParameter;
300 if (index >= sizeof(CodecInfo)/sizeof(CodecInfo))
301 return PluginLID_NoMoreNames;
303 strncpy(mediaFormat, CodecInfo[index].mediaFormat, size-1);
304 mediaFormat[size-1] = '\0';
305 return PluginLID_NoError;
309 PLUGIN_FUNCTION_ARG2(SetReadFormat, unsigned,line, const char *,mediaFormat)
311 if (mediaFormat == NULL)
312 return PluginLID_InvalidParameter;
314 if (m_uiLineCount == 0)
315 return PluginLID_DeviceNotOpen;
317 if (line >= m_uiLineCount)
318 return PluginLID_NoSuchLine;
320 for (int i = 0; i < sizeof(CodecInfo)/sizeof(CodecInfo); i++) {
321 if (strcmp(mediaFormat, CodecInfo[i].mediaFormat) == 0) {
322 if (vpb_record_buf_start(lineState[line].handle, CodecInfo[i].mode) < 0)
323 return PluginLID_InternalError;
324 lineState[line].readFormat = CodecInfo[i].mediaFormat;
325 return PluginLID_NoError;
329 return PluginLID_UnsupportedMediaFormat;
333 PLUGIN_FUNCTION_ARG2(SetWriteFormat, unsigned,line, const char *,mediaFormat)
335 if (mediaFormat == NULL)
336 return PluginLID_InvalidParameter;
338 if (m_uiLineCount == 0)
339 return PluginLID_DeviceNotOpen;
341 if (line >= m_uiLineCount)
342 return PluginLID_NoSuchLine;
344 for (int i = 0; i < sizeof(CodecInfo)/sizeof(CodecInfo); i++) {
345 if (strcmp(mediaFormat, CodecInfo[i].mediaFormat) == 0) {
346 if (vpb_play_buf_start(lineState[line].handle, CodecInfo[i].mode) < 0)
347 return PluginLID_InternalError;
348 lineState[line].writeFormat = CodecInfo[i].mediaFormat;
349 return PluginLID_NoError;
353 return PluginLID_UnsupportedMediaFormat;
357 PLUGIN_FUNCTION_ARG3(GetReadFormat, unsigned,line, char *,mediaFormat, unsigned,size)
359 if (mediaFormat == NULL || size == 0)
360 return PluginLID_InvalidParameter;
362 if (m_uiLineCount == 0)
363 return PluginLID_DeviceNotOpen;
365 if (line >= m_uiLineCount)
366 return PluginLID_NoSuchLine;
368 strncpy(mediaFormat, lineState[line].readFormat, size-1);
369 mediaFormat[size-1] = '\0';
370 return PluginLID_NoError;
374 PLUGIN_FUNCTION_ARG3(GetWriteFormat, unsigned,line, char *,mediaFormat, unsigned,size)
376 if (mediaFormat == NULL || size == 0)
377 return PluginLID_InvalidParameter;
379 if (m_uiLineCount == 0)
380 return PluginLID_DeviceNotOpen;
382 if (line >= m_uiLineCount)
383 return PluginLID_NoSuchLine;
385 strncpy(mediaFormat, lineState[line].writeFormat, size-1);
386 mediaFormat[size-1] = '\0';
387 return PluginLID_NoError;
391 PLUGIN_FUNCTION_ARG1(StopReading, unsigned,line)
393 if (m_uiLineCount == 0)
394 return PluginLID_DeviceNotOpen;
396 if (line >= m_uiLineCount)
397 return PluginLID_NoSuchLine;
399 vpb_record_terminate(lineState[line].handle);
400 vpb_record_buf_finish(lineState[line].handle);
401 return PluginLID_NoError;
405 PLUGIN_FUNCTION_ARG1(StopWriting, unsigned,line)
407 if (m_uiLineCount == 0)
408 return PluginLID_DeviceNotOpen;
410 if (line >= m_uiLineCount)
411 return PluginLID_NoSuchLine;
413 vpb_play_terminate(lineState[line].handle);
414 vpb_play_buf_finish(lineState[line].handle);
415 return PluginLID_NoError;
419 PLUGIN_FUNCTION_ARG2(SetReadFrameSize, unsigned,line, unsigned,frameSize)
421 if (m_uiLineCount == 0)
422 return PluginLID_DeviceNotOpen;
424 if (line >= m_uiLineCount)
425 return PluginLID_NoSuchLine;
427 lineState[line].readFrameSize = frameSize;
428 return PluginLID_NoError;
432 PLUGIN_FUNCTION_ARG2(SetWriteFrameSize, unsigned,line, unsigned,frameSize)
434 if (m_uiLineCount == 0)
435 return PluginLID_DeviceNotOpen;
437 if (line >= m_uiLineCount)
438 return PluginLID_NoSuchLine;
440 lineState[line].writeFrameSize = frameSize;
441 return PluginLID_NoError;
445 PLUGIN_FUNCTION_ARG2(GetReadFrameSize, unsigned,line, unsigned *,frameSize)
447 if (frameSize == NULL)
448 return PluginLID_InvalidParameter;
450 if (m_uiLineCount == 0)
451 return PluginLID_DeviceNotOpen;
453 if (line >= m_uiLineCount)
454 return PluginLID_NoSuchLine;
456 *frameSize = lineState[line].readFrameSize;
457 return PluginLID_NoError;
461 PLUGIN_FUNCTION_ARG2(GetWriteFrameSize, unsigned,line, unsigned *,frameSize)
463 if (frameSize == NULL)
464 return PluginLID_InvalidParameter;
466 if (m_uiLineCount == 0)
467 return PluginLID_DeviceNotOpen;
469 if (line >= m_uiLineCount)
470 return PluginLID_NoSuchLine;
472 *frameSize = lineState[line].writeFrameSize;
473 return PluginLID_NoError;
477 PLUGIN_FUNCTION_ARG3(ReadFrame, unsigned,line, void *,buffer, unsigned *,count)
479 if (buffer == NULL || count == NULL)
480 return PluginLID_InvalidParameter;
482 if (m_uiLineCount == 0)
483 return PluginLID_DeviceNotOpen;
485 if (line >= m_uiLineCount)
486 return PluginLID_NoSuchLine;
488 *count = lineState[line].readFrameSize;
489 vpb_record_buf_sync(lineState[line].handle, (char *)buffer, (unsigned short)*count);
490 return PluginLID_NoError;
494 PLUGIN_FUNCTION_ARG4(WriteFrame, unsigned,line, const void *,buffer, unsigned,count, unsigned *,written)
496 if (buffer == NULL || written == NULL)
497 return PluginLID_InvalidParameter;
499 if (m_uiLineCount == 0)
500 return PluginLID_DeviceNotOpen;
502 if (line >= m_uiLineCount)
503 return PluginLID_NoSuchLine;
505 *written = count;
506 vpb_play_buf_sync(lineState[line].handle, (char *)buffer, (unsigned short)count);
507 return PluginLID_NoError;
512 //PLUGIN_FUNCTION_ARG3(GetAverageSignalLevel, unsigned,line, PluginLID_Boolean,playback, unsigned *,signal)
513 //PLUGIN_FUNCTION_ARG2(EnableAudio, unsigned,line, PluginLID_Boolean,enable)
514 //PLUGIN_FUNCTION_ARG2(IsAudioEnabled, unsigned,line, PluginLID_Boolean *,enable)
517 PLUGIN_FUNCTION_ARG2(SetRecordVolume, unsigned,line, unsigned,volume)
519 if (m_uiLineCount == 0)
520 return PluginLID_DeviceNotOpen;
522 if (line >= m_uiLineCount)
523 return PluginLID_NoSuchLine;
525 return vpb_record_set_gain(lineState[line].handle, (float)(volume/100.0*24.0-12.0)) >= 0 ? PluginLID_NoError : PluginLID_InternalError;
529 PLUGIN_FUNCTION_ARG2(SetPlayVolume, unsigned,line, unsigned,volume)
531 if (m_uiLineCount == 0)
532 return PluginLID_DeviceNotOpen;
534 if (line >= m_uiLineCount)
535 return PluginLID_NoSuchLine;
537 return vpb_play_set_gain(lineState[line].handle, (float)(volume/100.0*24.0-12.0)) >= 0 ? PluginLID_NoError : PluginLID_InternalError;
541 PLUGIN_FUNCTION_ARG2(GetRecordVolume, unsigned,line, unsigned *,volume)
543 if (volume == NULL)
544 return PluginLID_InvalidParameter;
546 if (m_uiLineCount == 0)
547 return PluginLID_DeviceNotOpen;
549 if (line >= m_uiLineCount)
550 return PluginLID_NoSuchLine;
552 float gain;
553 if (vpb_record_get_gain(lineState[line].handle, &gain) < 0)
554 return PluginLID_InternalError;
556 *volume = (unsigned)((gain+12.0)/24.0*100.0);
557 return PluginLID_NoError;
561 PLUGIN_FUNCTION_ARG2(GetPlayVolume, unsigned,line, unsigned *,volume)
563 if (volume == NULL)
564 return PluginLID_InvalidParameter;
566 if (m_uiLineCount == 0)
567 return PluginLID_DeviceNotOpen;
569 if (line >= m_uiLineCount)
570 return PluginLID_NoSuchLine;
572 float gain;
573 if (vpb_play_get_gain(lineState[line].handle, &gain) < 0)
574 return PluginLID_InternalError;
576 *volume = (unsigned)((gain+12.0)/24.0*100.0);
577 return PluginLID_NoError;
582 //PLUGIN_FUNCTION_ARG2(GetAEC, unsigned,line, unsigned *,level)
583 //PLUGIN_FUNCTION_ARG2(SetAEC, unsigned,line, unsigned,level)
584 //PLUGIN_FUNCTION_ARG2(GetVAD, unsigned,line, PluginLID_Boolean *,enable)
585 //PLUGIN_FUNCTION_ARG2(SetVAD, unsigned,line, PluginLID_Boolean,enable)
586 //PLUGIN_FUNCTION_ARG4(GetCallerID, unsigned,line, char *,idString, unsigned,size, PluginLID_Boolean,full)
587 //PLUGIN_FUNCTION_ARG2(SetCallerID, unsigned,line, const char *,idString)
588 //PLUGIN_FUNCTION_ARG2(SendCallerIDOnCallWaiting, unsigned,line, const char *,idString)
589 //PLUGIN_FUNCTION_ARG2(SendVisualMessageWaitingIndicator, unsigned,line, PluginLID_Boolean,on)
591 PLUGIN_FUNCTION_ARG4(PlayDTMF, unsigned,line, const char *,digits, unsigned,onTime, unsigned,offTime)
593 if (digits == NULL)
594 return PluginLID_InvalidParameter;
596 if (m_uiLineCount == 0)
597 return PluginLID_DeviceNotOpen;
599 if (line >= m_uiLineCount)
600 return PluginLID_NoSuchLine;
602 try {
603 vpb_dial_sync(lineState[line].handle, (char *)digits);
604 vpb_dial_sync(lineState[line].handle, ",");
606 catch(VpbException v) {
607 std::cerr << "VPB\tPlayDTMF Error code = " << v.code << ", s = " << v.s << " api func = " << v.api_function << std::endl;
608 return PluginLID_InternalError;
611 return PluginLID_NoError;
615 PLUGIN_FUNCTION_ARG2(ReadDTMF, unsigned,line, char *,digit)
617 return PluginLID_NoError;
621 PLUGIN_FUNCTION_ARG2(GetRemoveDTMF, unsigned,line, PluginLID_Boolean *,removeTones)
623 return PluginLID_NoError;
627 PLUGIN_FUNCTION_ARG2(SetRemoveDTMF, unsigned,line, PluginLID_Boolean,removeTones)
629 return PluginLID_NoError;
634 PLUGIN_FUNCTION_ARG2(IsToneDetected, unsigned,line, unsigned *,tone)
636 if (tone == NULL)
637 return PluginLID_InvalidParameter;
639 if (m_uiLineCount == 0)
640 return PluginLID_DeviceNotOpen;
642 if (line >= m_uiLineCount)
643 return PluginLID_NoSuchLine;
645 *tone = PluginLID_NoTone;
647 VPB_EVENT event;
648 try {
649 if (vpb_get_event_ch_async(lineState[line].handle, &event) == VPB_NO_EVENTS)
650 return PluginLID_NoError;
652 catch (VpbException v) {
653 std::cerr << "VPB\tOpalVpbDevice::Open Error code = " << v.code << ", s = " << v.s << " api func = " << v.api_function << std::endl;
654 return PluginLID_InternalError;
657 if (event.type == VPB_RING) {
658 *tone = PluginLID_RingTone;
659 return PluginLID_NoError;
662 if (event.type != VPB_TONEDETECT)
663 return PluginLID_NoError;
665 switch (event.data) {
666 case VPB_DIAL :
667 *tone = PluginLID_DialTone;
668 break;
669 case VPB_RINGBACK :
670 *tone = PluginLID_RingTone;
671 break;
672 case VPB_BUSY :
673 *tone = PluginLID_BusyTone;
674 break;
675 #ifdef VPB_FASTBUSY
676 case VPB_FASTBUSY :
677 *tone = PluginLID_FastBusyTone;
678 break;
679 #endif
680 case VPB_GRUNT :
681 break;
682 #ifdef VPB_MWI
683 case VPB_MWI :
684 *tone = PluginLID_MwiTone;
685 break;
686 #endif
687 default:
688 std::cerr << "VPB\tTone Detect: no a known tone." << event.data<< std::endl;
689 return PluginLID_InternalError;
692 return PluginLID_NoError;
696 //PLUGIN_FUNCTION_ARG3(WaitForToneDetect, unsigned,line, unsigned,timeout, unsigned *,tone)
697 //PLUGIN_FUNCTION_ARG3(WaitForTone, unsigned,line, unsigned,tone, unsigned,timeout)
698 //PLUGIN_FUNCTION_ARG7(SetToneFilterParameters, unsigned ,line,
699 // unsigned ,tone,
700 // unsigned ,lowFrequency,
701 // unsigned ,highFrequency,
702 // unsigned ,numCadences,
703 // const unsigned *,onTimes,
704 // const unsigned *,offTimes)
705 //PLUGIN_FUNCTION_ARG2(PlayTone, unsigned,line, unsigned,tone)
706 //PLUGIN_FUNCTION_ARG2(IsTonePlaying, unsigned,line, PluginLID_Boolean *,playing)
707 //PLUGIN_FUNCTION_ARG1(StopTone, unsigned,line)
708 //PLUGIN_FUNCTION_ARG4(DialOut, unsigned,line, const char *,number, PluginLID_Boolean,requireTones, unsigned,uiDialDelay)
709 //PLUGIN_FUNCTION_ARG2(GetWinkDuration, unsigned,line, unsigned *,winkDuration)
710 //PLUGIN_FUNCTION_ARG2(SetWinkDuration, unsigned,line, unsigned,winkDuration)
711 //PLUGIN_FUNCTION_ARG1(SetCountryCode, unsigned,country)
712 //PLUGIN_FUNCTION_ARG2(GetSupportedCountry, unsigned,index, unsigned *,countryCode)
717 /////////////////////////////////////////////////////////////////////////////
719 static struct PluginLID_Definition definition[1] =
723 // encoder
724 PLUGIN_LID_VERSION, // API version
726 1083666706, // timestamp = Tue 04 May 2004 10:31:46 AM UTC =
728 "VPB", // LID name text
729 "Voicetronix VPB-4", // LID description text
730 "Voicetronix", // LID manufacturer name
731 "VPB", // LID model name
732 "1.0", // LID hardware revision number
733 "peter@voicetronix.com.au", // LID email contact information
734 "http://www.voicetronix.com.au", // LID web site
736 "Robert Jongbloed, Post Increment", // source code author
737 "robertj@postincrement.com", // source code email
738 "http://www.postincrement.com", // source code URL
739 "Copyright (C) 2006 by Post Increment, All Rights Reserved", // source code copyright
740 "MPL 1.0", // source code license
741 "1.0", // source code version
743 NULL, // user data value
745 Context::Create,
746 Context::Destroy,
747 Context::GetDeviceName,
748 Context::Open,
749 Context::Close,
750 Context::GetLineCount,
751 Context::IsLineTerminal,
752 Context::IsLinePresent,
753 Context::IsLineOffHook,
754 Context::SetLineOffHook,
755 NULL, //Context::HookFlash,
756 NULL, //Context::HasHookFlash,
757 Context::IsLineRinging,
758 NULL, //Context::RingLine,
759 NULL, //Context::IsLineConnected,
760 NULL, //Context::SetLineToLineDirect,
761 NULL, //Context::IsLineToLineDirect,
762 Context::GetSupportedFormat,
763 Context::SetReadFormat,
764 Context::SetWriteFormat,
765 Context::GetReadFormat,
766 Context::GetWriteFormat,
767 Context::StopReading,
768 Context::StopWriting,
769 Context::SetReadFrameSize,
770 Context::SetWriteFrameSize,
771 Context::GetReadFrameSize,
772 Context::GetWriteFrameSize,
773 Context::ReadFrame,
774 Context::WriteFrame,
775 NULL,//Context::GetAverageSignalLevel,
776 NULL,//Context::EnableAudio,
777 NULL,//Context::IsAudioEnabled,
778 Context::SetRecordVolume,
779 Context::SetPlayVolume,
780 Context::GetRecordVolume,
781 Context::GetPlayVolume,
782 NULL,//Context::GetAEC,
783 NULL,//Context::SetAEC,
784 NULL,//Context::GetVAD,
785 NULL,//Context::SetVAD,
786 NULL,//Context::GetCallerID,
787 NULL,//Context::SetCallerID,
788 NULL,//Context::SendCallerIDOnCallWaiting,
789 NULL,//Context::SendVisualMessageWaitingIndicator,
790 Context::PlayDTMF,
791 Context::ReadDTMF,
792 Context::GetRemoveDTMF,
793 Context::SetRemoveDTMF,
794 Context::IsToneDetected,
795 NULL,//Context::WaitForToneDetect,
796 NULL,//Context::WaitForTone,
797 NULL,//Context::SetToneFilterParameters,
798 NULL,//Context::PlayTone,
799 NULL,//Context::IsTonePlaying,
800 NULL,//Context::StopTone,
801 NULL,//Context::DialOut,
802 NULL,//Context::GetWinkDuration,
803 NULL,//Context::SetWinkDuration,
804 NULL,//Context::SetCountryCode,
805 NULL,//Context::GetSupportedCountry
810 PLUGIN_LID_IMPLEMENTATION(definition);
812 /////////////////////////////////////////////////////////////////////////////