How make use of the Voice API to make calls using Huawei 3g Modems?

Kunal Deo picture Kunal Deo · Dec 3, 2011 · Viewed 10.4k times · Source

Some Huawei 3g modems like mine (E1752) has ability to make and receive calls. I believe onboard there is PCM channel that can be used while making or receiving the calls but I do not have any more information on that.

I am using their app called the Mobile Partner which is a fairly complete app which supports making and receiving calls. But I want to build my own app which will run on Mac OS X. But I am not able to locate any documents detailing the Voice API and the onboard PCM channel. If anybody is aware of this please let me know.

Mobile Partner app with support for Voice Calls

Answer

Sai Chaitanya picture Sai Chaitanya · Dec 14, 2011

Voice is implemented as follows:- Your Modem registers total of 5 devices.The audio is sent through the serial port named "Huawei Mobile Connect - Application Interface".

Format of voice (in|out) data:

  wFormatTag = WAVE_FORMAT_PCM;
  nChannels = 1;
  nSamplesPerSec = 8000;
  nAvgBytesPerSec = 16000;
  nBlockAlign = 2;
  wBitsPerSample = 16;
  cbSize = 0;

Block size of voice data in ReadFile or WriteFile operations (for COM port) must be set in 320 bytes. After each ReadFile must be WriteFile operation (in other choice buffers will be overflow and modem will restart after some time). Sample:

//   BlockSize - size of buff for wave in|out operations (in my case 320*4 bytes)

   while (!bAllRead) {
    if (cInfo->hCom == INVALID_HANDLE_VALUE) {
     SetVoiceClosed(cInfo);//exit from thread
     return 0;
    }

    BOOL isRead = ReadFile(cInfo->hCom, cInfo->Header[counter].lpData + currBlocLength, 320, &nActualRead, &cInfo->o);
    if (isRead || (GetLastError() == ERROR_IO_PENDING && GetOverlappedResult(cInfo->hCom, &cInfo->o, &nActualRead, TRUE))) {
     if (nActualRead > 0) {
      // обратка
      nActualWrite = 0;
      int nActualWriteAll = 0;
      BOOL isWrite = WriteFile(cInfo->hCom, CurrBuffPtr + currBlocLength, nActualRead, &nActualWrite, &cInfo->oVoiceOut);
      while (isWrite || (GetLastError() == ERROR_IO_PENDING && GetOverlappedResult(cInfo->hCom, &cInfo->oVoiceOut, &nActualWrite, TRUE))) {
       nActualWriteAll += nActualWrite;
       if (nActualWriteAll >= nActualRead)
        break;
      }
      currBlocLength += nActualRead;
      if (currBlocLength >= BlockSize)
       bAllRead = true;
     }
     else {
      Sleep(25);// wait for voice data (resync)
      PurgeComm(cInfo->hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
     }
    }
    else {
     bAllRead = true;// there are no active call
     PurgeComm(cInfo->hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
    }
   }

Something like that))). I do not find any useful info in Internet, so all that recommendation based on my experiments. I hope that was useful.

PS: I hope wave in|out operations will not be a problem for you.

PS2: Sorry for my English, I'm from Ukraine.